Merge lp:~chromakode/boots/localization into lp:boots

Proposed by Max Goodhart
Status: Merged
Merged at revision: not available
Proposed branch: lp:~chromakode/boots/localization
Merge into: lp:boots
Diff against target: 1323 lines (+536/-96)
24 files modified
boots/api/__init__.py (+1/-0)
boots/api/api.py (+5/-4)
boots/api/constructors.py (+5/-3)
boots/api/errors.py (+4/-2)
boots/app/__init__.py (+1/-1)
boots/app/client_config.py (+19/-17)
boots/lib/__init__.py (+4/-0)
boots/lib/console.py (+20/-17)
boots/lib/lingos/bash_external.py (+2/-2)
boots/lib/lingos/lingo.py (+3/-1)
boots/lib/lingos/lisp/builtins.py (+5/-3)
boots/lib/lingos/lisp/lexer.py (+3/-1)
boots/lib/lingos/lisp/lisp.py (+7/-4)
boots/lib/lingos/lisp/objects.py (+12/-10)
boots/lib/lingos/lisp/parser.py (+5/-2)
boots/lib/lingos/piped_sql.py (+8/-6)
boots/lib/lingos/python.py (+2/-1)
boots/lib/lingos/sql.py (+2/-1)
boots/lib/ui/components/help.py (+6/-4)
boots/lib/ui/components/metacommands.py (+3/-2)
boots/lib/ui/plain.py (+24/-15)
po/README.txt (+16/-0)
po/boots.pot (+376/-0)
po/createpots.sh (+3/-0)
To merge this branch: bzr merge lp:~chromakode/boots/localization
Reviewer Review Type Date Requested Status
Boots Developers Pending
Review via email: mp+20850@code.launchpad.net

Description of the change

Ken's localization branch + updates and fixes

To post a comment you must log in.
lp:~chromakode/boots/localization updated
117. By Max Goodhart

Fix a couple translatable strings in client_config.py.

118. By Max Goodhart

Fix translatable strings again.

119. By Max Goodhart

Localize boots.api.

120. By Max Goodhart

Merge and localize latest updates to trunk.

121. By Max Goodhart

Update potfile.

122. By Max Goodhart

Update localization README.

123. By Max Goodhart

Fix another translatable string that slipped through.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'boots/api/__init__.py'
--- boots/api/__init__.py 2009-12-22 00:12:18 +0000
+++ boots/api/__init__.py 2010-03-07 09:23:22 +0000
@@ -0,0 +1,1 @@
1from boots.lib import _, n_
0\ No newline at end of file2\ No newline at end of file
13
=== modified file 'boots/api/api.py'
--- boots/api/api.py 2010-03-05 21:07:26 +0000
+++ boots/api/api.py 2010-03-07 09:23:22 +0000
@@ -31,6 +31,7 @@
31import time31import time
32from boots.api import errors32from boots.api import errors
33from boots.api.nodes.node import Status33from boots.api.nodes.node import Status
34from boots.api import _, n_
3435
35_server_classes = []36_server_classes = []
3637
@@ -85,7 +86,7 @@
85 try:86 try:
86 self._connection = self._connect()87 self._connection = self._connect()
87 except self.db.Error:88 except self.db.Error:
88 raise errors.ConnectionError("Could not connect to {0}".format(self))89 raise errors.ConnectionError(_("Could not connect to {0}").format(self))
8990
90 @property91 @property
91 def is_connected(self): 92 def is_connected(self):
@@ -97,7 +98,7 @@
97 def _check_connected(self):98 def _check_connected(self):
98 """Raise a ProgrammingError if the Connection has been closed."""99 """Raise a ProgrammingError if the Connection has been closed."""
99 if not self.is_connected:100 if not self.is_connected:
100 raise errors.ConnectionError("Connection closed")101 raise errors.ConnectionError(_("Connection closed"))
101102
102 def disconnect(self):103 def disconnect(self):
103 self._check_connected()104 self._check_connected()
@@ -120,7 +121,7 @@
120 except errors.LostConnectionError as lost_e:121 except errors.LostConnectionError as lost_e:
121 # FIXME: this is NOT thread safe122 # FIXME: this is NOT thread safe
122 # Attempt to reconnect and retry123 # Attempt to reconnect and retry
123 yield Status("Lost connection to {0}. Reconnecting...".format(self))124 yield Status(_("Lost connection to {0}. Reconnecting...").format(self))
124 125
125 if self.is_connected:126 if self.is_connected:
126 self.disconnect()127 self.disconnect()
@@ -132,7 +133,7 @@
132 lost_e.reconnect_exception = e133 lost_e.reconnect_exception = e
133 raise lost_e134 raise lost_e
134 else:135 else:
135 yield Status("Reconnected.")136 yield Status(_("Reconnected."))
136 137
137 if cursor.description:138 if cursor.description:
138 field_indexes = extract_field_indexes(cursor.description)139 field_indexes = extract_field_indexes(cursor.description)
139140
=== modified file 'boots/api/constructors.py'
--- boots/api/constructors.py 2010-03-07 07:24:29 +0000
+++ boots/api/constructors.py 2010-03-07 09:23:22 +0000
@@ -21,9 +21,11 @@
21#21#
22# ##### END LICENSE BLOCK #####22# ##### END LICENSE BLOCK #####
2323
24import re
25
24from boots.api.api import Rows, ResultInfo26from boots.api.api import Rows, ResultInfo
25from boots.api.nodes.node import NodeGraph, SyncNode, IteratorNode27from boots.api.nodes.node import NodeGraph, SyncNode, IteratorNode
26import re28from boots.api import _, n_
2729
28_constructors = {}30_constructors = {}
2931
@@ -31,7 +33,7 @@
31 """Allow the function constructor to be used from PipedSQL under name. constructor is a33 """Allow the function constructor to be used from PipedSQL under name. constructor is a
32 function that takes any number of strings as arguments and returns a node."""34 function that takes any number of strings as arguments and returns a node."""
33 if name in _constructors:35 if name in _constructors:
34 raise KeyError('A constructor with name ' + name + ' already exists')36 raise KeyError(_('A constructor with name {0} already exists').format(name))
3537
36 _constructors[name] = constructor38 _constructors[name] = constructor
3739
@@ -42,7 +44,7 @@
42def construct(name, *arguments):44def construct(name, *arguments):
43 """Contructs a node using the given name and arguments."""45 """Contructs a node using the given name and arguments."""
44 if name not in _constructors:46 if name not in _constructors:
45 raise KeyError('There is no constructor with the name' + ' {0}.'.format(name))47 raise KeyError(_('There is no constructor with the name {0}.').format(name))
46 48
47 return _constructors[name](*arguments)49 return _constructors[name](*arguments)
4850
4951
=== modified file 'boots/api/errors.py'
--- boots/api/errors.py 2010-03-05 22:13:28 +0000
+++ boots/api/errors.py 2010-03-07 09:23:22 +0000
@@ -24,6 +24,8 @@
24import exceptions24import exceptions
25import traceback25import traceback
2626
27from boots.api import _, n_
28
27class BootsError(exceptions.StandardError):29class BootsError(exceptions.StandardError):
28 """Base class of boots error exceptions."""30 """Base class of boots error exceptions."""
29 pass31 pass
@@ -48,11 +50,11 @@
48 if self.msg:50 if self.msg:
49 msg.append(self.msg)51 msg.append(self.msg)
50 else:52 else:
51 msg.append("Lost connection to {0}".format(self.server))53 msg.append(_("Lost connection to {0}").format(self.server))
5254
53 if self.reconnect_exception:55 if self.reconnect_exception:
54 exc_lines = traceback.format_exception_only(type(self.reconnect_exception), self.reconnect_exception)56 exc_lines = traceback.format_exception_only(type(self.reconnect_exception), self.reconnect_exception)
55 exc_text = ". ".join(line.strip() for line in exc_lines)57 exc_text = ". ".join(line.strip() for line in exc_lines)
56 msg.append("(Exception upon reconnect: {0})".format(exc_text))58 msg.append(_("(Exception upon reconnect: {0})").format(exc_text))
57 59
58 return " ".join(msg)60 return " ".join(msg)
5961
=== modified file 'boots/app/__init__.py'
--- boots/app/__init__.py 2009-12-23 20:58:28 +0000
+++ boots/app/__init__.py 2010-03-07 09:23:22 +0000
@@ -1,1 +1,1 @@
1__all__ = ["boots", "config", "info"]1from boots.lib import _, n_
2\ No newline at end of file2\ No newline at end of file
33
=== modified file 'boots/app/client_config.py'
--- boots/app/client_config.py 2010-03-01 08:03:27 +0000
+++ boots/app/client_config.py 2010-03-07 09:23:22 +0000
@@ -29,6 +29,8 @@
29import os, os.path29import os, os.path
30import info30import info
3131
32from boots.app import _, n_
33
32def find_executable(name):34def find_executable(name):
33 # Search algorithm adapted from os._execvpe 35 # Search algorithm adapted from os._execvpe
34 head, tail = os.path.split(name)36 head, tail = os.path.split(name)
@@ -88,71 +90,71 @@
88 action = "store",90 action = "store",
89 type = "string",91 type = "string",
90 dest = "command",92 dest = "command",
91 help = "Execute command and exit")93 help = _("Execute command and exit"))
92 self._cli_parser.add_option("-D", "--database",94 self._cli_parser.add_option("-D", "--database",
93 action = "store",95 action = "store",
94 type = "string",96 type = "string",
95 dest = "database",97 dest = "database",
96 help = "Use database")98 help = _("Use database"))
97 self._cli_parser.add_option("-f", "--script",99 self._cli_parser.add_option("-f", "--script",
98 action = "store",100 action = "store",
99 type = "string",101 type = "string",
100 dest = "script",102 dest = "script",
101 help = "Execute commands from file and exit")103 help = _("Execute commands from file and exit"))
102 self._cli_parser.add_option('-l', '--lingo',104 self._cli_parser.add_option('-l', '--lingo',
103 action = 'store',105 action = 'store',
104 type = 'string',106 type = 'string',
105 dest = 'lingo',107 dest = 'lingo',
106 help = 'Set the lingo to use')108 help = _('Set the lingo to use'))
107 self._cli_parser.add_option("-X", "--norc",109 self._cli_parser.add_option("-X", "--norc",
108 action = "store_true",110 action = "store_true",
109 dest = "norc",111 dest = "norc",
110 help = "Do not read user configuration file")112 help = _("Do not read user configuration file"))
111 self._cli_parser.add_option("-r", "--rc",113 self._cli_parser.add_option("-r", "--rc",
112 action = "store",114 action = "store",
113 type = "string",115 type = "string",
114 dest = "rcfile",116 dest = "rcfile",
115 help = "Filename of user configuration file")117 help = _("Filename of user configuration file"))
116 self._cli_parser.add_option("-H", "--host",118 self._cli_parser.add_option("-H", "--host",
117 action = "store",119 action = "store",
118 type = "string",120 type = "string",
119 dest = "host",121 dest = "host",
120 help = "Connect to host")122 help = _("Connect to host"))
121 self._cli_parser.add_option("-p", "--port",123 self._cli_parser.add_option("-p", "--port",
122 action = "store",124 action = "store",
123 type = "int",125 type = "int",
124 dest = "port",126 dest = "port",
125 help = "Use port number")127 help = _("Use port number"))
126 self._cli_parser.add_option("-u", "--user",128 self._cli_parser.add_option("-u", "--user",
127 action = "store",129 action = "store",
128 type = "string",130 type = "string",
129 dest = "username",131 dest = "username",
130 help = "Login with username")132 help = _("Login with username"))
131 self._cli_parser.add_option("-P", "--password",133 self._cli_parser.add_option("-P", "--password",
132 action = "store",134 action = "store",
133 type = "string",135 type = "string",
134 dest = "password",136 dest = "password",
135 help = "Connect using password. If none is given, query for password")137 help = _("Connect using password. If none is given, query for password"))
136 self._cli_parser.add_option("--pager",138 self._cli_parser.add_option("--pager",
137 action = "store",139 action = "store",
138 type = "string",140 type = "string",
139 dest = "pager",141 dest = "pager",
140 help = "Pipe query results to the specified pager.")142 help = _("Pipe query results to the specified pager."))
141 self._cli_parser.add_option("-t", "--terminatingchar",143 self._cli_parser.add_option("-t", "--terminatingchar",
142 action = "store",144 action = "store",
143 type = "string",145 type = "string",
144 dest = "terminating_char",146 dest = "terminating_char",
145 help = "Specify the SQL statement terminating character. Default is ';'.")147 help = _("Specify the SQL statement terminating character. Default is ';'."))
146 self._cli_parser.add_option("-F", "--historyfile",148 self._cli_parser.add_option("-F", "--historyfile",
147 action = "store",149 action = "store",
148 type = "string",150 type = "string",
149 dest = "history_file",151 dest = "history_file",
150 help = "Specify file to save history to")152 help = _("Specify file to save history to"))
151 self._cli_parser.add_option("-L", "--historylength",153 self._cli_parser.add_option("-L", "--historylength",
152 action = "store",154 action = "store",
153 type = "int",155 type = "int",
154 dest = "history_length",156 dest = "history_length",
155 help = "Specify max history file length")157 help = _("Specify max history file length"))
156 158
157 def __getitem__(self, key):159 def __getitem__(self, key):
158 """Allows one to use the [] operator to get config items."""160 """Allows one to use the [] operator to get config items."""
@@ -200,11 +202,11 @@
200 except IOError:202 except IOError:
201 if filepath != info.RCFILE:203 if filepath != info.RCFILE:
202 # Only print an error if a non-default rc file was specified.204 # Only print an error if a non-default rc file was specified.
203 print("rcfile {0} not found".format(filepath))205 print(_("rcfile {0} not found").format(filepath))
204 except SyntaxError:206 except SyntaxError:
205 print("rcfile {0} contains a syntax error".format(filepath))207 print(_("rcfile {0} contains a syntax error").format(filepath))
206 except Exception as e:208 except Exception as e:
207 print("rcfile {0} contains an error: {1}".format(filepath, e))209 print(_("rcfile {0} contains an error: {1}").format(filepath, e))
208 return file_dict210 return file_dict
209211
210 def get_cli_conf(self):212 def get_cli_conf(self):
211213
=== modified file 'boots/lib/__init__.py'
--- boots/lib/__init__.py 2009-12-22 00:12:18 +0000
+++ boots/lib/__init__.py 2010-03-07 09:23:22 +0000
@@ -0,0 +1,4 @@
1import gettext
2translation = gettext.translation("boots", fallback=True)
3_ = translation.lgettext
4n_ = translation.lngettext
0\ No newline at end of file5\ No newline at end of file
16
=== modified file 'boots/lib/console.py'
--- boots/lib/console.py 2010-03-07 06:42:10 +0000
+++ boots/lib/console.py 2010-03-07 09:23:22 +0000
@@ -24,6 +24,8 @@
24"""This module provides the boots Console class. This class is the core24"""This module provides the boots Console class. This class is the core
25driver of any boots client."""25driver of any boots client."""
2626
27import sys
28
27from boots.api import api29from boots.api import api
28from boots.api.errors import BootsError, BootsWarning, ConnectionError30from boots.api.errors import BootsError, BootsWarning, ConnectionError
29from boots.api.nodes.node import NodeGraph, IteratorNode, LinkStackNode31from boots.api.nodes.node import NodeGraph, IteratorNode, LinkStackNode
@@ -37,6 +39,7 @@
37from boots.lib.lingos import python39from boots.lib.lingos import python
38from boots.lib.lingos import piped_sql40from boots.lib.lingos import piped_sql
39from boots.lib.lingos import sql41from boots.lib.lingos import sql
42from boots.lib import _, n_
40try:43try:
41 from boots.lib.lingos.lisp import lisp44 from boots.lib.lingos.lisp import lisp
42except ImportError:45except ImportError:
@@ -63,7 +66,7 @@
63 self.exception = exception66 self.exception = exception
64 67
65 def __str__(self):68 def __str__(self):
66 return "Boots encountered an internal error: {0}".format(self.exception)69 return _("Boots encountered an internal error: {0}").format(self.exception)
6770
68class Console(object): 71class Console(object):
69 def __init__(self, config, welcome_msg=None):72 def __init__(self, config, welcome_msg=None):
@@ -113,20 +116,20 @@
113 self.hooks["load"].call()116 self.hooks["load"].call()
114117
115 def _init_help(self):118 def _init_help(self):
116 self.help = HelpTopic("boots", "Boots Help", "Help", """119 self.help = HelpTopic("boots", _("Boots Help"), _("Help"),
117 Boots is a flexible, extensible, and multilingual shell for working with databases. To read more about a subtopic, use `help <topic>`.""")120 description = _("Boots is a flexible, extensible, and multilingual shell for working with databases. To read more about a subtopic, use `help <topic>`."))
118 121
119 self.help["commands"] = QueryIndexTopic("commands", None, 122 self.help["commands"] = QueryIndexTopic("commands", None,
120 "List of Boots commands.",123 _("List of Boots commands."),
121 query=("commands",))124 query=("commands",))
122 125
123 self.help["commands"].add("\quit", "quit", "Quit boots.")126 self.help["commands"].add("\quit", _("quit"), _("Quit boots."))
124 self.help["commands"].add("\help", "help", "Show help for a topic.", """127 self.help["commands"].add("\help", _("help"), _("Show help for a topic."),
125 help <topic>128 description = _("help <topic>\n"
126 Show help for \"topic\".""")129 "Show help for \"topic\"."))
127 130
128 self.help.add("lingos", "Lingos", "Documentation for loaded lingos.", """131 self.help.add("lingos", _("Lingos"), _("Documentation for loaded lingos."),
129 A lingo is a command language usable within Boots.""")132 description = _("A lingo is a command language usable within Boots."))
130133
131 def input_complete(self, command, lingo):134 def input_complete(self, command, lingo):
132 if self.metacommands.get_metacommand(command) is not None:135 if self.metacommands.get_metacommand(command) is not None:
@@ -138,7 +141,7 @@
138 141
139 def run(self, command, lingo="sql"):142 def run(self, command, lingo="sql"):
140 if not lingo in self.lingos:143 if not lingo in self.lingos:
141 self._display_error(ConsoleError("Invalid lingo \"{0}\" specified.".format(lingo)))144 self._display_error(ConsoleError(_("Invalid lingo \"{0}\" specified.").format(lingo)))
142 return145 return
143 146
144 result_data = self.lingos[lingo].execute(command)147 result_data = self.lingos[lingo].execute(command)
@@ -167,7 +170,7 @@
167 self.servers.append(server)170 self.servers.append(server)
168 return True171 return True
169 else:172 else:
170 self._display_error(ConsoleError("Could not connect to {0}:{1}".format(host, port)))173 self._display_error(ConsoleError(_("Could not connect to {0}:{1}").format(host, port)))
171 return False174 return False
172175
173 def disconnect(self, host, port):176 def disconnect(self, host, port):
@@ -186,7 +189,7 @@
186 if self.welcome_msg and self.driver.is_interactive:189 if self.welcome_msg and self.driver.is_interactive:
187 server_lines = []190 server_lines = []
188 for server in self.servers:191 for server in self.servers:
189 line_format = "{0.hostname}:{0.port} (server v{0.server_version})"192 line_format = _("{0.hostname}:{0.port} (server v{0.server_version})")
190 server_lines.append(line_format.format(server))193 server_lines.append(line_format.format(server))
191 server_status = "\n".join(server_lines)194 server_status = "\n".join(server_lines)
192 195
@@ -221,7 +224,7 @@
221 224
222 def quit(self, exitcode=0):225 def quit(self, exitcode=0):
223 if self.driver.is_interactive:226 if self.driver.is_interactive:
224 self.presenter.presenter_graph.put("Boots quit.")227 self.presenter.presenter_graph.put(_("Boots quit."))
225 228
226 self.hooks["unload"].call()229 self.hooks["unload"].call()
227 self.disconnect(None, None)230 self.disconnect(None, None)
@@ -239,9 +242,9 @@
239 self.presenter.present(topic.format(include_index=True))242 self.presenter.present(topic.format(include_index=True))
240 else:243 else:
241 paths = ", ".join("\"{0}\"".format(" ".join(path)) for path in results)244 paths = ", ".join("\"{0}\"".format(" ".join(path)) for path in results)
242 self.presenter.present("Did you mean: {0}?".format(paths))245 self.presenter.present(_("Did you mean: {0}?").format(paths))
243 else:246 else:
244 self.presenter.present("No help found for \"{0}\".".format(" ".join(query)))247 self.presenter.present(_("No help found for \"{0}\".").format(" ".join(query)))
245248
246 def meta_connect(self, host=None, port=None, database=None):249 def meta_connect(self, host=None, port=None, database=None):
247 if host is None: 250 if host is None:
@@ -270,7 +273,7 @@
270 try:273 try:
271 script_driver = ScriptDriver(self, filepath, self.config["lingo"])274 script_driver = ScriptDriver(self, filepath, self.config["lingo"])
272 except IOError as e:275 except IOError as e:
273 self._display_error(ConsoleError("Could not open file {0}".format(filepath)))276 self._display_error(ConsoleError(_("Could not open file {0}").format(filepath)))
274 return277 return
275 278
276 self.driver_stack.push_input(script_driver.driver_graph.output_link)279 self.driver_stack.push_input(script_driver.driver_graph.output_link)
277280
=== modified file 'boots/lib/lingos/bash_external.py'
--- boots/lib/lingos/bash_external.py 2010-02-27 05:54:13 +0000
+++ boots/lib/lingos/bash_external.py 2010-03-07 09:23:22 +0000
@@ -25,12 +25,12 @@
25from boots.lib.lingos import external25from boots.lib.lingos import external
26from boots.lib.lingos import lingo26from boots.lib.lingos import lingo
27from boots.lib.ui.components.help import HelpTopic27from boots.lib.ui.components.help import HelpTopic
2828from boots.lib import _, n_
2929
30class ExternalBashInterpreter(external.ExternalInterpreter):30class ExternalBashInterpreter(external.ExternalInterpreter):
31 """Provides an interface to an external bash shell."""31 """Provides an interface to an external bash shell."""
32 32
33 help = HelpTopic("bash", "Bash Lingo", "External bash shell.") 33 help = HelpTopic("bash", _("Bash Lingo"), _("External bash shell."))
34 34
35 def __init__(self, *args, **kwargs):35 def __init__(self, *args, **kwargs):
36 super(ExternalBashInterpreter, self).__init__('bash', [], *args, **kwargs)36 super(ExternalBashInterpreter, self).__init__('bash', [], *args, **kwargs)
3737
=== modified file 'boots/lib/lingos/lingo.py'
--- boots/lib/lingos/lingo.py 2010-03-04 19:09:05 +0000
+++ boots/lib/lingos/lingo.py 2010-03-07 09:23:22 +0000
@@ -23,6 +23,8 @@
2323
24import sys24import sys
2525
26from boots.lib import _, n_
27
26class LingoRegistry(object):28class LingoRegistry(object):
27 def __init__(self):29 def __init__(self):
28 self._lingos = {}30 self._lingos = {}
@@ -31,7 +33,7 @@
31 """Registers a lingo with the given name and interpreter. Raises a KeyError if a lingo with33 """Registers a lingo with the given name and interpreter. Raises a KeyError if a lingo with
32 name is already registered."""34 name is already registered."""
33 if name in self._lingos:35 if name in self._lingos:
34 raise KeyError('A lingo with name {0} already exists'.format(name))36 raise KeyError(_('A lingo with name {0} already exists').format(name))
35 37
36 self._lingos[name] = interpreter38 self._lingos[name] = interpreter
37 39
3840
=== modified file 'boots/lib/lingos/lisp/builtins.py'
--- boots/lib/lingos/lisp/builtins.py 2010-02-27 05:40:10 +0000
+++ boots/lib/lingos/lisp/builtins.py 2010-03-07 09:23:22 +0000
@@ -21,8 +21,10 @@
21#21#
22# ##### END LICENSE BLOCK #####22# ##### END LICENSE BLOCK #####
2323
24import sys
25
24from boots.lib.lingos.lisp import objects26from boots.lib.lingos.lisp import objects
25import sys27from boots.lib import _, n_
2628
27nil = objects.Null()29nil = objects.Null()
28t = objects.T()30t = objects.T()
@@ -57,7 +59,7 @@
57 elif isinstance(s, objects.String):59 elif isinstance(s, objects.String):
58 return objects.Integer(len(s.python_string()))60 return objects.Integer(len(s.python_string()))
59 else:61 else:
60 raise TypeError('Expected a cons, nil or a string')62 raise TypeError(_('Expected a cons, nil or a string'))
6163
62def elt_function(s, i):64def elt_function(s, i):
63 """Returns the ith element of the sequence s."""65 """Returns the ith element of the sequence s."""
@@ -66,7 +68,7 @@
66 elif isinstance(s, objects.String):68 elif isinstance(s, objects.String):
67 return s.python_string()[i.python_integer()]69 return s.python_string()[i.python_integer()]
68 else:70 else:
69 raise TypeError('Expected a cons or string')71 raise TypeError(_('Expected a cons or string'))
7072
71def gensym_function():73def gensym_function():
72 """Returns a unique symbol that will never be the same as any other symbol even if it has the same name."""74 """Returns a unique symbol that will never be the same as any other symbol even if it has the same name."""
7375
=== modified file 'boots/lib/lingos/lisp/lexer.py'
--- boots/lib/lingos/lisp/lexer.py 2010-02-27 05:40:10 +0000
+++ boots/lib/lingos/lisp/lexer.py 2010-03-07 09:23:22 +0000
@@ -23,6 +23,8 @@
2323
24import ply.lex as lex24import ply.lex as lex
2525
26from boots.lib import _, n_
27
26tokens = ('INTEGER', 'STRING', 'SYMBOL', 'QUOTE', 'LEFT_PAREN', 'RIGHT_PAREN')28tokens = ('INTEGER', 'STRING', 'SYMBOL', 'QUOTE', 'LEFT_PAREN', 'RIGHT_PAREN')
2729
28t_INTEGER = r'[0-9]+'30t_INTEGER = r'[0-9]+'
@@ -34,7 +36,7 @@
34t_ignore = ' \t\n'36t_ignore = ' \t\n'
3537
36def t_error(t):38def t_error(t):
37 print('illegal character {0} found'.format(t.value))39 print(_('illegal character {0} found').format(t.value))
38 token.lexer.skip(1)40 token.lexer.skip(1)
3941
40lexer = lex.lex()42lexer = lex.lex()
4143
=== modified file 'boots/lib/lingos/lisp/lisp.py'
--- boots/lib/lingos/lisp/lisp.py 2010-03-07 06:59:29 +0000
+++ boots/lib/lingos/lisp/lisp.py 2010-03-07 09:23:22 +0000
@@ -35,13 +35,16 @@
35if __name__ == '__main__':35if __name__ == '__main__':
36 sys.path.append('../../../../')36 sys.path.append('../../../../')
3737
38import re
39import readline
40
38from boots.lib.lingos import lingo41from boots.lib.lingos import lingo
39from boots.lib.lingos.lisp import builtins42from boots.lib.lingos.lisp import builtins
40from boots.lib.lingos.lisp import lexer43from boots.lib.lingos.lisp import lexer
41from boots.lib.lingos.lisp import objects44from boots.lib.lingos.lisp import objects
42from boots.lib.lingos.lisp import parser45from boots.lib.lingos.lisp import parser
43import re46from boots.lib import _, n_
44import readline47
4548
46def input_complete(string):49def input_complete(string):
47 """Returns string if string is a complete lisp expression. Otherwise, None is returned."""50 """Returns string if string is a complete lisp expression. Otherwise, None is returned."""
@@ -52,7 +55,7 @@
52 paren_level = left_parens - right_parens55 paren_level = left_parens - right_parens
5356
54 if paren_level < 0:57 if paren_level < 0:
55 raise SyntaxError('unmatched closing ")"')58 raise SyntaxError(_('unmatched closing ")"'))
56 elif paren_level > 0:59 elif paren_level > 0:
57 return None60 return None
58 else:61 else:
@@ -71,7 +74,7 @@
71 if isinstance(stream, file):74 if isinstance(stream, file):
72 stream = stream.readline75 stream = stream.readline
73 elif not callable(stream):76 elif not callable(stream):
74 raise TypeError('{0} is not a stream or a callable'.format(stream))77 raise TypeError(_('{0} is not a stream or a callable').format(stream))
75 # Read lines until all open lisp expressions have been closed.78 # Read lines until all open lisp expressions have been closed.
76 while True:79 while True:
77 line = stream()80 line = stream()
7881
=== modified file 'boots/lib/lingos/lisp/objects.py'
--- boots/lib/lingos/lisp/objects.py 2010-02-27 05:40:10 +0000
+++ boots/lib/lingos/lisp/objects.py 2010-03-07 09:23:22 +0000
@@ -25,6 +25,8 @@
25import copy25import copy
26import sys26import sys
2727
28from boots.lib import _, n_
29
28_gensym_count = 130_gensym_count = 1
29_symbols = {}31_symbols = {}
3032
@@ -96,7 +98,7 @@
96 else_expression = car(cdr(cdr(cdr(self))))98 else_expression = car(cdr(cdr(cdr(self))))
9799
98 if then_expression is Null() or cdr(cdr(cdr(cdr(self)))) is not Null():100 if then_expression is Null() or cdr(cdr(cdr(cdr(self)))) is not Null():
99 raise SyntaxError('wrong number of arguments for if special form {0}'.format(self))101 raise SyntaxError(_('Wrong number of arguments for if special form {0}').format(self))
100102
101 if condition_expression.evaluate(environment) != Null():103 if condition_expression.evaluate(environment) != Null():
102 return then_expression.evaluate(environment)104 return then_expression.evaluate(environment)
@@ -115,7 +117,7 @@
115 values = arguments[2::2]117 values = arguments[2::2]
116118
117 if len(symbols) != len(values) or len(symbols) == 0:119 if len(symbols) != len(values) or len(symbols) == 0:
118 raise SyntaxError('The number of symbols must equal the number of values and must be non-zero')120 raise SyntaxError(_('The number of symbols must equal the number of values and must be non-zero'))
119121
120 for symbol, value in zip(symbols, values):122 for symbol, value in zip(symbols, values):
121 value = value.evaluate(environment)123 value = value.evaluate(environment)
@@ -129,7 +131,7 @@
129 else: # Handle function calls.131 else: # Handle function calls.
130 function = self.car.evaluate(environment)132 function = self.car.evaluate(environment)
131 if not isinstance(function, Lambda):133 if not isinstance(function, Lambda):
132 raise TypeError('Expected a function')134 raise TypeError(_('Expected a function'))
133 else:135 else:
134 return function.call((argument.evaluate(environment) for argument in self.python_list()[1:]), environment)136 return function.call((argument.evaluate(environment) for argument in self.python_list()[1:]), environment)
135137
@@ -165,18 +167,18 @@
165 def __getitem__(self, symbol):167 def __getitem__(self, symbol):
166 """Returns the value of symbol in the environment."""168 """Returns the value of symbol in the environment."""
167 if not isinstance(symbol, Symbol):169 if not isinstance(symbol, Symbol):
168 raise TypeError('Expected a symbol')170 raise TypeError(_('Expected a symbol'))
169171
170 try:172 try:
171 return self._environment[symbol][-1]173 return self._environment[symbol][-1]
172 except KeyError:174 except KeyError:
173 raise KeyError('No binding for {0} exists in the current environment'.format(symbol))175 raise KeyError(_('No binding for {0} exists in the current environment').format(symbol))
174176
175 def __setitem__(self, symbol, value):177 def __setitem__(self, symbol, value):
176 """Sets symbol to value in the environment. If no binding for symbol exists, a binding is created at the innermost178 """Sets symbol to value in the environment. If no binding for symbol exists, a binding is created at the innermost
177 scope."""179 scope."""
178 if not isinstance(symbol, Symbol):180 if not isinstance(symbol, Symbol):
179 raise TypeError('Expected a symbol')181 raise TypeError(_('Expected a symbol'))
180182
181 if symbol not in self._environment:183 if symbol not in self._environment:
182 self._environment[symbol] = [value]184 self._environment[symbol] = [value]
@@ -188,7 +190,7 @@
188 # def __delitem__(self, symbol):190 # def __delitem__(self, symbol):
189 # """Removes the first binding found for symbol. Returns True if the symbol is found and False otherwise."""191 # """Removes the first binding found for symbol. Returns True if the symbol is found and False otherwise."""
190 # if not isinstance(symbol, Symbol):192 # if not isinstance(symbol, Symbol):
191 # raise TypeError('Expected a symbol')193 # raise TypeError(_('Expected a symbol'))
192 194
193 # if symbol in self._environment:195 # if symbol in self._environment:
194 # self._environment[symbol].pop()196 # self._environment[symbol].pop()
@@ -202,7 +204,7 @@
202 # return False204 # return False
203205
204 def push(self, symbol_values):206 def push(self, symbol_values):
205 """Adds a new innermost lexical scope as determined by symbol_values. symbol_values is a dictionary mapping Symbols207 """Adds a new innermost lexical scope as determined by symbol_values. symbol_values is a dictionary mapping Symbols
206 to Objects and describes bindings in the current scope."""208 to Objects and describes bindings in the current scope."""
207 self._scopes.append(set(symbol_values.keys()))209 self._scopes.append(set(symbol_values.keys()))
208210
@@ -215,7 +217,7 @@
215 def pop(self):217 def pop(self):
216 """Removes the innermost scope and returns a dictionary that corresponds to its bindings."""218 """Removes the innermost scope and returns a dictionary that corresponds to its bindings."""
217 if len(self._scopes) <= 1:219 if len(self._scopes) <= 1:
218 raise RuntimeError('Cannot pop the innermost scope because then no scopes would remain')220 raise RuntimeError(_('Cannot pop the innermost scope because then no scopes would remain'))
219 symbols = self._scopes.pop()221 symbols = self._scopes.pop()
220 222
221 for symbol in symbols:223 for symbol in symbols:
222224
=== modified file 'boots/lib/lingos/lisp/parser.py'
--- boots/lib/lingos/lisp/parser.py 2010-03-07 06:54:29 +0000
+++ boots/lib/lingos/lisp/parser.py 2010-03-07 09:23:22 +0000
@@ -22,9 +22,12 @@
22# ##### END LICENSE BLOCK #####22# ##### END LICENSE BLOCK #####
2323
24from lexer import tokens24from lexer import tokens
25import ply.yacc as yacc
26
25from boots.lib.lingos.lisp import builtins27from boots.lib.lingos.lisp import builtins
26from boots.lib.lingos.lisp import objects28from boots.lib.lingos.lisp import objects
27import ply.yacc as yacc29from boots.lib import _, n_
30
2831
29def p_expression_integer(p):32def p_expression_integer(p):
30 'expression : INTEGER'33 'expression : INTEGER'
@@ -59,7 +62,7 @@
59 p[0] = objects.Cons(p[1], p[2])62 p[0] = objects.Cons(p[1], p[2])
6063
61def p_error(p):64def p_error(p):
62 raise SyntaxError('syntax error')65 raise SyntaxError(_('syntax error'))
6366
64# Disable debugging output and caching of parse tables.67# Disable debugging output and caching of parse tables.
65parser = yacc.yacc(debug = 0, write_tables = 0)68parser = yacc.yacc(debug = 0, write_tables = 0)
6669
=== modified file 'boots/lib/lingos/piped_sql.py'
--- boots/lib/lingos/piped_sql.py 2010-03-07 07:24:29 +0000
+++ boots/lib/lingos/piped_sql.py 2010-03-07 09:23:22 +0000
@@ -21,12 +21,14 @@
21#21#
22# ##### END LICENSE BLOCK #####22# ##### END LICENSE BLOCK #####
2323
24import re
25
24from boots.api.nodes.node import NodeGraph, SyncNode, IteratorNode26from boots.api.nodes.node import NodeGraph, SyncNode, IteratorNode
25from boots.api.constructors import construct, csv_output_file_node, sink_node27from boots.api.constructors import construct, csv_output_file_node, sink_node
26from boots.lib.ui.components.help import HelpTopic28from boots.lib.ui.components.help import HelpTopic
27from boots.lib.lingos import lingo29from boots.lib.lingos import lingo
28from boots.lib.lingos import sql30from boots.lib.lingos import sql
29import re31from boots.lib import _, n_
3032
31# Set this to another node constructor to change the default constructor used for output files.33# Set this to another node constructor to change the default constructor used for output files.
32output_file_node = csv_output_file_node34output_file_node = csv_output_file_node
@@ -42,7 +44,7 @@
42string_re = re.compile('^(?P<text>(\'[^\']*\')|("[^"]*"))')44string_re = re.compile('^(?P<text>(\'[^\']*\')|("[^"]*"))')
4345
44class PipedSQLInterpreter(sql.SQLInterpreter):46class PipedSQLInterpreter(sql.SQLInterpreter):
45 help = HelpTopic("pipedsql", "Piped SQL Lingo", "Enhanced SQL query language supporting pipes.")47 help = HelpTopic("pipedsql", _("Piped SQL Lingo"), _("Enhanced SQL query language supporting pipes."))
46 48
47 def __init__(self, *args, **kwargs):49 def __init__(self, *args, **kwargs):
48 super(PipedSQLInterpreter, self).__init__(*args, **kwargs)50 super(PipedSQLInterpreter, self).__init__(*args, **kwargs)
@@ -54,7 +56,7 @@
54 match = clause_re.match(clause_string)56 match = clause_re.match(clause_string)
5557
56 if not match:58 if not match:
57 raise SyntaxError('{0} is not in the correct function call syntax'.format(clause_string))59 raise SyntaxError(_('{0} is not in the correct function call syntax').format(clause_string))
5860
59 constructor_call = match.group('constructor_call').strip()61 constructor_call = match.group('constructor_call').strip()
60 output_file = match.group('output_file')62 output_file = match.group('output_file')
@@ -65,7 +67,7 @@
65 match = constructor_call_re.match(constructor_string)67 match = constructor_call_re.match(constructor_string)
6668
67 if not match:69 if not match:
68 raise SyntaxError('{0} is not in the correct function call syntax'.format(constructor_string))70 raise SyntaxError(_('{0} is not in the correct function call syntax').format(constructor_string))
69 71
70 name = match.group('name')72 name = match.group('name')
71 arguments = match.group('arguments')73 arguments = match.group('arguments')
@@ -92,7 +94,7 @@
92 constructor_call, output_file = self._parse_clause(clause)94 constructor_call, output_file = self._parse_clause(clause)
93 except SyntaxError as e:95 except SyntaxError as e:
94 print(e)96 print(e)
95 print 'error1'97 print _('error1')
96 return [] # Return an empty list to avoid printing None.98 return [] # Return an empty list to avoid printing None.
9799
98 try:100 try:
@@ -104,7 +106,7 @@
104 # SQL is only allowed for the first node.106 # SQL is only allowed for the first node.
105 if sql:107 if sql:
106 if not first_node:108 if not first_node:
107 raise SyntaxError('SQL is only permitted for the first clause')109 raise SyntaxError(_('SQL is only permitted for the first clause'))
108 110
109 # FIXME: Add support for multiple servers here. Currently only the first server111 # FIXME: Add support for multiple servers here. Currently only the first server
110 # is used.112 # is used.
111113
=== modified file 'boots/lib/lingos/python.py'
--- boots/lib/lingos/python.py 2010-03-05 22:13:28 +0000
+++ boots/lib/lingos/python.py 2010-03-07 09:23:22 +0000
@@ -27,12 +27,13 @@
27from boots.api import errors27from boots.api import errors
28from boots.lib.lingos import lingo28from boots.lib.lingos import lingo
29from boots.lib.ui.components.help import HelpTopic29from boots.lib.ui.components.help import HelpTopic
30from boots.lib import _, n_
3031
31class PythonInterpreter(lingo.Interpreter):32class PythonInterpreter(lingo.Interpreter):
32 """Implements a python interpreter that will send commands to the python interpreter that runs33 """Implements a python interpreter that will send commands to the python interpreter that runs
33 boots."""34 boots."""
34 35
35 help = HelpTopic("python", "Python Lingo", "Integrated Python interpreter using the Boots API.") 36 help = HelpTopic("python", _("Python Lingo"), _("Integrated Python interpreter using the Boots API."))
36 37
37 def __init__(self, *args, **kwargs):38 def __init__(self, *args, **kwargs):
38 super(PythonInterpreter, self).__init__(*args, **kwargs)39 super(PythonInterpreter, self).__init__(*args, **kwargs)
3940
=== modified file 'boots/lib/lingos/sql.py'
--- boots/lib/lingos/sql.py 2010-02-27 05:54:13 +0000
+++ boots/lib/lingos/sql.py 2010-03-07 09:23:22 +0000
@@ -24,9 +24,10 @@
24from boots.api.nodes.node import NodeGraph, SyncNode, IteratorNode24from boots.api.nodes.node import NodeGraph, SyncNode, IteratorNode
25from boots.lib.ui.components.help import HelpTopic25from boots.lib.ui.components.help import HelpTopic
26from boots.lib.lingos import lingo26from boots.lib.lingos import lingo
27from boots.lib import _, n_
2728
28class SQLInterpreter(lingo.Interpreter):29class SQLInterpreter(lingo.Interpreter):
29 help = HelpTopic("sql", "SQL Lingo", "Raw SQL commands sent to a server.")30 help = HelpTopic("sql", _("SQL Lingo"), _("Raw SQL commands sent to a server."))
30 31
31 def __init__(self, *args, **kwargs):32 def __init__(self, *args, **kwargs):
32 super(SQLInterpreter, self).__init__(*args, **kwargs)33 super(SQLInterpreter, self).__init__(*args, **kwargs)
3334
=== modified file 'boots/lib/ui/components/help.py'
--- boots/lib/ui/components/help.py 2010-02-27 05:54:13 +0000
+++ boots/lib/ui/components/help.py 2010-03-07 09:23:22 +0000
@@ -21,6 +21,8 @@
21#21#
22# ##### END LICENSE BLOCK #####22# ##### END LICENSE BLOCK #####
2323
24from boots.lib import _, n_
25
24def issubseq(subseq, seq):26def issubseq(subseq, seq):
25 """Determines if the elements the sequence subseq form a subsequence of the sequence seq."""27 """Determines if the elements the sequence subseq form a subsequence of the sequence seq."""
26 for start in range(len(seq) - len(subseq) + 1):28 for start in range(len(seq) - len(subseq) + 1):
@@ -63,11 +65,11 @@
63 template += "{0.description}"65 template += "{0.description}"
64 66
65 if self.see_also:67 if self.see_also:
66 template += "\n\nSee also: {0.see_also}"68 template += "\n\n"+_("See also: {0.see_also}")
67 69
68 output = template.format(self)70 output = template.format(self)
69 if include_index and self._subtopics:71 if include_index and self._subtopics:
70 output += "\n--- Subtopics ---\n" + self.format_index()72 output += "\n--- "+_("Subtopics")+" ---\n" + self.format_index()
71 73
72 return output74 return output
73 75
@@ -101,7 +103,7 @@
101 assert isinstance(item, str)103 assert isinstance(item, str)
102 return query104 return query
103 else:105 else:
104 raise TypeError('query object {0} is not a string or tuple of strings'.format(query))106 raise TypeError(_('query object {0} is not a string or tuple of strings').format(query))
105 107
106 def _ensure_key(self, key):108 def _ensure_key(self, key):
107 """Creates a new subtopic that key maps to if none exists."""109 """Creates a new subtopic that key maps to if none exists."""
@@ -198,4 +200,4 @@
198 subtopics = self._subtopics.copy()200 subtopics = self._subtopics.copy()
199 for path in self.root.search(self.query):201 for path in self.root.search(self.query):
200 subtopics.update(self.root[path]._subtopics)202 subtopics.update(self.root[path]._subtopics)
201 return subtopics
202\ No newline at end of file203\ No newline at end of file
204 return subtopics
203205
=== modified file 'boots/lib/ui/components/metacommands.py'
--- boots/lib/ui/components/metacommands.py 2010-03-07 05:03:00 +0000
+++ boots/lib/ui/components/metacommands.py 2010-03-07 09:23:22 +0000
@@ -26,6 +26,7 @@
26import types26import types
2727
28from boots.api.errors import BootsError, BootsWarning28from boots.api.errors import BootsError, BootsWarning
29from boots.lib import _, n_
2930
30class MetaCommandError(BootsError):31class MetaCommandError(BootsError):
31 """Errors related to metacommands."""32 """Errors related to metacommands."""
@@ -68,7 +69,7 @@
68 # FIXME: Issue warning through the UI using ui.print69 # FIXME: Issue warning through the UI using ui.print
69 # FIXME: Determine the offending command(s) (set.intersect?)70 # FIXME: Determine the offending command(s) (set.intersect?)
70 # FIXME: Print offending commands71 # FIXME: Print offending commands
71 return MetaCommandConflictWarning("Conflicts between metacommands detected.")72 return MetaCommandConflictWarning(_("Conflicts between metacommands detected."))
72 self.names |= newnames73 self.names |= newnames
7374
74class MetaCommands(object):75class MetaCommands(object):
@@ -105,7 +106,7 @@
105 name, func, args = metacommand106 name, func, args = metacommand
106 expected_arg_count = argument_count(func)107 expected_arg_count = argument_count(func)
107 if expected_arg_count is not None and len(args) != expected_arg_count:108 if expected_arg_count is not None and len(args) != expected_arg_count:
108 raise InvalidArgumentError("{0} takes {1} arguments ({2} given)".format(109 raise InvalidArgumentError(_("{0} takes {1} arguments ({2} given)").format(
109 name, expected_arg_count, len(args)))110 name, expected_arg_count, len(args)))
110 else:111 else:
111 func(*args)112 func(*args)
112113
=== modified file 'boots/lib/ui/plain.py'
--- boots/lib/ui/plain.py 2010-03-05 22:13:28 +0000
+++ boots/lib/ui/plain.py 2010-03-07 09:23:22 +0000
@@ -30,12 +30,13 @@
30import readline30import readline
31import subprocess31import subprocess
32import threading32import threading
33 33
34from boots.api.api import Rows, ResultInfo34from boots.api.api import Rows, ResultInfo
35from boots.api.nodes.node import Status, NodeGraph, SyncNode, filter_none35from boots.api.nodes.node import Status, NodeGraph, SyncNode, filter_none
36from boots.lib.ui.components.help import HelpTopic36from boots.lib.ui.components.help import HelpTopic
37from boots.lib.ui.components.metacommands import MetaCommandError, MetaCommands, parse_metacommand37from boots.lib.ui.components.metacommands import MetaCommandError, MetaCommands, parse_metacommand
38from boots.lib.ui.generic import StdinDriver, StdoutPresenter38from boots.lib.ui.generic import StdinDriver, StdoutPresenter
39from boots.lib import _, n_
3940
40class PlainUI(StdinDriver, StdoutPresenter):41class PlainUI(StdinDriver, StdoutPresenter):
41 """Class that provides a 'plain' UI for boots. Input is taken on stdin,42 """Class that provides a 'plain' UI for boots. Input is taken on stdin,
@@ -43,11 +44,11 @@
43 results are printed to stdout. These results are printed as tables when44 results are printed to stdout. These results are printed as tables when
44 they are Server packets and as string interpretations otherwise."""45 they are Server packets and as string interpretations otherwise."""
45 46
46 help = HelpTopic("plain", "Plain UI", "Plain UI documentation.", """47 help = HelpTopic("plain", _("Plain UI"), _("Plain UI documentation."),
47 A simple, minimal user interface for Boots.""")48 _("A simple, minimal user interface for Boots."))
48 49
49 help.add("commands", None, "List of Plain UI commands.")50 help.add("commands", None, _("List of Plain UI commands."))
50 help["commands"].add("\use", "use", "Switch to a different lingo.")51 help["commands"].add("\use", _("use"), _("Switch to a different lingo."))
51 52
52 def __init__(self, console):53 def __init__(self, console):
53 """Initialize a UI giving it its parent console, primary prompt,54 """Initialize a UI giving it its parent console, primary prompt,
@@ -133,7 +134,7 @@
133 shell=False,134 shell=False,
134 stdin=subprocess.PIPE)135 stdin=subprocess.PIPE)
135 except:136 except:
136 sys.stdout.write("Unable to run pager command \"{0}\". Pager disabled.\n"137 sys.stdout.write(_("Unable to run pager command \"{0}\". Pager disabled.\n")
137 .format(self.pager_command))138 .format(self.pager_command))
138 self.pager_command = None139 self.pager_command = None
139 return False140 return False
@@ -156,7 +157,7 @@
156 def padded(fields, widths):157 def padded(fields, widths):
157 """Utility function used to convert rows from tuples to table rows.158 """Utility function used to convert rows from tuples to table rows.
158 Results are returned as strings."""159 Results are returned as strings."""
159 return "| {0} |\n".format(" | ".join(map(str.ljust, fields, widths)))160 return "| {0} |".format(" | ".join(map(str.ljust, fields, widths)))
160 161
161 def show_NULL(value):162 def show_NULL(value):
162 """There is a 'bug' in the dbapi that does not convert NULL objects163 """There is a 'bug' in the dbapi that does not convert NULL objects
@@ -168,7 +169,7 @@
168 if self.buffer:169 if self.buffer:
169 max_widths = map(max, [(len(column[0]), column[2]) for column in info["description"]])170 max_widths = map(max, [(len(column[0]), column[2]) for column in info["description"]])
170 dashes = map(lambda x: "-"*(x+2), max_widths)171 dashes = map(lambda x: "-"*(x+2), max_widths)
171 sep_line = "+" + "+".join(dashes) + "+\n"172 sep_line = "+" + "+".join(dashes) + "+"
172 names = (column[0] for column in info["description"])173 names = (column[0] for column in info["description"])
173 yield sep_line174 yield sep_line
174 yield padded(names, max_widths)175 yield padded(names, max_widths)
@@ -182,9 +183,13 @@
182 elapsed = info["end_time"] - info["begin_time"]183 elapsed = info["end_time"] - info["begin_time"]
183 noun = "row" if info["row_count"] == 1 else "rows"184 noun = "row" if info["row_count"] == 1 else "rows"
184 if info["description"] is not None:185 if info["description"] is not None:
185 info_line = "{count} {noun} in set ({elapsed:.2f} seconds)\n"186 info_line = n_("{count} row in set ({elapsed:.2f} seconds)",
187 "{count} rows in set ({elapsed:.2f} seconds)",
188 info["row_count"])
186 else:189 else:
187 info_line = "{count} {noun} affected ({elapsed:.2f} seconds)\n"190 info_line = n_("{count} row affected ({elapsed:.2f} seconds)",
191 "{count} rows affected ({elapsed:.2f} seconds)",
192 info["row_count"])
188 193
189 yield info_line.format(count=info["row_count"],194 yield info_line.format(count=info["row_count"],
190 noun=noun,195 noun=noun,
@@ -196,25 +201,29 @@
196 printed = False201 printed = False
197 output = _gen_table(result.value)202 output = _gen_table(result.value)
198 if self.pager_command and self.console.driver.is_interactive:203 if self.pager_command and self.console.driver.is_interactive:
199 printed = self.print_with_pager("".join(output))204 printed = self.print_with_pager("\n".join(output))
200 205
201 # Fallback if no pager set, or paging fails.206 # Fallback if no pager set, or paging fails.
202 if not printed:207 if not printed:
203 for line in output:208 for line in output:
204 sys.stdout.write(line)209 sys.stdout.write(line)
210 sys.stdout.write("\n")
205 211
206 # Reset values for next result set.212 # Reset values for next result set.
207 self.buffer = []213 self.buffer = []
208 elif isinstance(result, Status):214 elif isinstance(result, Status):
209 sys.stdout.write("Status :: ")215 sys.stdout.write(_("Status"))
216 sys.stdout.write(" :: ")
210 sys.stdout.write(str(result))217 sys.stdout.write(str(result))
211 sys.stdout.write("\n")218 sys.stdout.write("\n")
212 elif isinstance(result, Warning):219 elif isinstance(result, Warning):
213 sys.stderr.write("WARNING :: ")220 sys.stderr.write(_("WARNING"))
221 sys.stderr.write(" :: ")
214 sys.stderr.write(str(result))222 sys.stderr.write(str(result))
215 sys.stderr.write("\n")223 sys.stderr.write("\n")
216 elif isinstance(result, Exception):224 elif isinstance(result, Exception):
217 sys.stderr.write("ERROR :: ")225 sys.stderr.write(_("ERROR"))
226 sys.stderr.write(" :: ")
218 sys.stderr.write(str(result))227 sys.stderr.write(str(result))
219 sys.stderr.write("\n")228 sys.stderr.write("\n")
220 elif result is not None:229 elif result is not None:
@@ -234,4 +243,4 @@
234 if lingo in self.console.lingos:243 if lingo in self.console.lingos:
235 self.lingo = lingo244 self.lingo = lingo
236 else:245 else:
237 self.present("The specified lingo \"{0}\" does not exist.".format(lingo))246 self.present(_("The specified lingo \"{0}\" does not exist.").format(lingo))
238247
=== added directory 'po'
=== added file 'po/README.txt'
--- po/README.txt 1970-01-01 00:00:00 +0000
+++ po/README.txt 2010-03-07 09:23:22 +0000
@@ -0,0 +1,16 @@
1====== When adding code that outputs a string ======
21) Add (if not present already) to the import section of the .py file:
3
4Depending on the package the file is in:
5from boots.app import _, n_
6from boots.api import _, n_
7from boots.lib import _, n_
8
9Then, wrap all output strings with _("...").
10
11Example:
12help = "Execute commands from file and exit")
13should be wrapped as such:
14help = _("Execute commands from file and exit"))
15
162) Generate the updated .pot file by running the /boots/po/createpots.sh script. This will overwrite the existing pot.cms file. Any prevously generated .po .mo files can then be updated from this new file.
0\ No newline at end of file17\ No newline at end of file
118
=== added file 'po/boots.pot'
--- po/boots.pot 1970-01-01 00:00:00 +0000
+++ po/boots.pot 2010-03-07 09:23:22 +0000
@@ -0,0 +1,376 @@
1# SOME DESCRIPTIVE TITLE.
2# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3# This file is distributed under the same license as the PACKAGE package.
4# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
5#
6#, fuzzy
7msgid ""
8msgstr ""
9"Project-Id-Version: boots\n"
10"Report-Msgid-Bugs-To: http://translations.launchpad.net/boots\n"
11"POT-Creation-Date: 2010-03-07 01:23-0800\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"
15"MIME-Version: 1.0\n"
16"Content-Type: text/plain; charset=CHARSET\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
19
20#: ../boots/api/api.py:89
21msgid "Could not connect to {0}"
22msgstr ""
23
24#: ../boots/api/api.py:101
25msgid "Connection closed"
26msgstr ""
27
28#: ../boots/api/api.py:124
29msgid "Lost connection to {0}. Reconnecting..."
30msgstr ""
31
32#: ../boots/api/api.py:136
33msgid "Reconnected."
34msgstr ""
35
36#: ../boots/api/constructors.py:36
37msgid "A constructor with name {0} already exists"
38msgstr ""
39
40#: ../boots/api/constructors.py:47
41msgid "There is no constructor with the name {0}."
42msgstr ""
43
44#: ../boots/api/errors.py:53
45msgid "Lost connection to {0}"
46msgstr ""
47
48#: ../boots/api/errors.py:58
49msgid "(Exception upon reconnect: {0})"
50msgstr ""
51
52#: ../boots/app/client_config.py:93
53msgid "Execute command and exit"
54msgstr ""
55
56#: ../boots/app/client_config.py:98
57msgid "Use database"
58msgstr ""
59
60#: ../boots/app/client_config.py:103
61msgid "Execute commands from file and exit"
62msgstr ""
63
64#: ../boots/app/client_config.py:108
65msgid "Set the lingo to use"
66msgstr ""
67
68#: ../boots/app/client_config.py:112
69msgid "Do not read user configuration file"
70msgstr ""
71
72#: ../boots/app/client_config.py:117
73msgid "Filename of user configuration file"
74msgstr ""
75
76#: ../boots/app/client_config.py:122
77msgid "Connect to host"
78msgstr ""
79
80#: ../boots/app/client_config.py:127
81msgid "Use port number"
82msgstr ""
83
84#: ../boots/app/client_config.py:132
85msgid "Login with username"
86msgstr ""
87
88#: ../boots/app/client_config.py:137
89msgid "Connect using password. If none is given, query for password"
90msgstr ""
91
92#: ../boots/app/client_config.py:142
93msgid "Pipe query results to the specified pager."
94msgstr ""
95
96#: ../boots/app/client_config.py:147
97msgid "Specify the SQL statement terminating character. Default is ';'."
98msgstr ""
99
100#: ../boots/app/client_config.py:152
101msgid "Specify file to save history to"
102msgstr ""
103
104#: ../boots/app/client_config.py:157
105msgid "Specify max history file length"
106msgstr ""
107
108#: ../boots/app/client_config.py:205
109msgid "rcfile {0} not found"
110msgstr ""
111
112#: ../boots/app/client_config.py:207
113msgid "rcfile {0} contains a syntax error"
114msgstr ""
115
116#: ../boots/app/client_config.py:209
117msgid "rcfile {0} contains an error: {1}"
118msgstr ""
119
120#: ../boots/lib/lingos/lisp/builtins.py:62
121msgid "Expected a cons, nil or a string"
122msgstr ""
123
124#: ../boots/lib/lingos/lisp/builtins.py:71
125msgid "Expected a cons or string"
126msgstr ""
127
128#: ../boots/lib/lingos/lisp/lexer.py:39
129msgid "illegal character {0} found"
130msgstr ""
131
132#: ../boots/lib/lingos/lisp/lisp.py:58
133msgid "unmatched closing \")\""
134msgstr ""
135
136#: ../boots/lib/lingos/lisp/lisp.py:77
137msgid "{0} is not a stream or a callable"
138msgstr ""
139
140#: ../boots/lib/lingos/lisp/objects.py:101
141msgid "Wrong number of arguments for if special form {0}"
142msgstr ""
143
144#: ../boots/lib/lingos/lisp/objects.py:120
145msgid ""
146"The number of symbols must equal the number of values and must be non-zero"
147msgstr ""
148
149#: ../boots/lib/lingos/lisp/objects.py:134
150msgid "Expected a function"
151msgstr ""
152
153#: ../boots/lib/lingos/lisp/objects.py:170
154#: ../boots/lib/lingos/lisp/objects.py:181
155msgid "Expected a symbol"
156msgstr ""
157
158#: ../boots/lib/lingos/lisp/objects.py:175
159msgid "No binding for {0} exists in the current environment"
160msgstr ""
161
162#: ../boots/lib/lingos/lisp/objects.py:220
163msgid "Cannot pop the innermost scope because then no scopes would remain"
164msgstr ""
165
166#: ../boots/lib/lingos/lisp/parser.py:65
167msgid "syntax error"
168msgstr ""
169
170#: ../boots/lib/lingos/bash_external.py:33
171msgid "Bash Lingo"
172msgstr ""
173
174#: ../boots/lib/lingos/bash_external.py:33
175msgid "External bash shell."
176msgstr ""
177
178#: ../boots/lib/lingos/lingo.py:36
179msgid "A lingo with name {0} already exists"
180msgstr ""
181
182#: ../boots/lib/lingos/sql.py:30
183msgid "SQL Lingo"
184msgstr ""
185
186#: ../boots/lib/lingos/sql.py:30
187msgid "Raw SQL commands sent to a server."
188msgstr ""
189
190#: ../boots/lib/lingos/python.py:36
191msgid "Python Lingo"
192msgstr ""
193
194#: ../boots/lib/lingos/python.py:36
195msgid "Integrated Python interpreter using the Boots API."
196msgstr ""
197
198#: ../boots/lib/lingos/piped_sql.py:47
199msgid "Piped SQL Lingo"
200msgstr ""
201
202#: ../boots/lib/lingos/piped_sql.py:47
203msgid "Enhanced SQL query language supporting pipes."
204msgstr ""
205
206#: ../boots/lib/lingos/piped_sql.py:59 ../boots/lib/lingos/piped_sql.py:70
207msgid "{0} is not in the correct function call syntax"
208msgstr ""
209
210#: ../boots/lib/lingos/piped_sql.py:97
211msgid "error1"
212msgstr ""
213
214#: ../boots/lib/lingos/piped_sql.py:109
215msgid "SQL is only permitted for the first clause"
216msgstr ""
217
218#: ../boots/lib/ui/components/help.py:68
219msgid "See also: {0.see_also}"
220msgstr ""
221
222#: ../boots/lib/ui/components/help.py:72
223msgid "Subtopics"
224msgstr ""
225
226#: ../boots/lib/ui/components/help.py:106
227msgid "query object {0} is not a string or tuple of strings"
228msgstr ""
229
230#: ../boots/lib/ui/components/metacommands.py:72
231msgid "Conflicts between metacommands detected."
232msgstr ""
233
234#: ../boots/lib/ui/components/metacommands.py:109
235msgid "{0} takes {1} arguments ({2} given)"
236msgstr ""
237
238#: ../boots/lib/ui/plain.py:47
239msgid "Plain UI"
240msgstr ""
241
242#: ../boots/lib/ui/plain.py:47
243msgid "Plain UI documentation."
244msgstr ""
245
246#: ../boots/lib/ui/plain.py:48
247msgid "A simple, minimal user interface for Boots."
248msgstr ""
249
250#: ../boots/lib/ui/plain.py:50
251msgid "List of Plain UI commands."
252msgstr ""
253
254#: ../boots/lib/ui/plain.py:51
255msgid "use"
256msgstr ""
257
258#: ../boots/lib/ui/plain.py:51
259msgid "Switch to a different lingo."
260msgstr ""
261
262#: ../boots/lib/ui/plain.py:137
263msgid "Unable to run pager command \"{0}\". Pager disabled.\n"
264msgstr ""
265
266#: ../boots/lib/ui/plain.py:186
267msgid "{count} row in set ({elapsed:.2f} seconds)"
268msgid_plural "{count} rows in set ({elapsed:.2f} seconds)"
269msgstr[0] ""
270msgstr[1] ""
271
272#: ../boots/lib/ui/plain.py:190
273msgid "{count} row affected ({elapsed:.2f} seconds)"
274msgid_plural "{count} rows affected ({elapsed:.2f} seconds)"
275msgstr[0] ""
276msgstr[1] ""
277
278#: ../boots/lib/ui/plain.py:215
279msgid "Status"
280msgstr ""
281
282#: ../boots/lib/ui/plain.py:220
283msgid "WARNING"
284msgstr ""
285
286#: ../boots/lib/ui/plain.py:225
287msgid "ERROR"
288msgstr ""
289
290#: ../boots/lib/ui/plain.py:246
291msgid "The specified lingo \"{0}\" does not exist."
292msgstr ""
293
294#: ../boots/lib/console.py:69
295msgid "Boots encountered an internal error: {0}"
296msgstr ""
297
298#: ../boots/lib/console.py:119
299msgid "Boots Help"
300msgstr ""
301
302#: ../boots/lib/console.py:119
303msgid "Help"
304msgstr ""
305
306#: ../boots/lib/console.py:120
307msgid ""
308"Boots is a flexible, extensible, and multilingual shell for working with "
309"databases. To read more about a subtopic, use `help <topic>`."
310msgstr ""
311
312#: ../boots/lib/console.py:123
313msgid "List of Boots commands."
314msgstr ""
315
316#: ../boots/lib/console.py:126
317msgid "quit"
318msgstr ""
319
320#: ../boots/lib/console.py:126
321msgid "Quit boots."
322msgstr ""
323
324#: ../boots/lib/console.py:127
325msgid "help"
326msgstr ""
327
328#: ../boots/lib/console.py:127
329msgid "Show help for a topic."
330msgstr ""
331
332#: ../boots/lib/console.py:128
333msgid ""
334"help <topic>\n"
335"Show help for \"topic\"."
336msgstr ""
337
338#: ../boots/lib/console.py:131
339msgid "Lingos"
340msgstr ""
341
342#: ../boots/lib/console.py:131
343msgid "Documentation for loaded lingos."
344msgstr ""
345
346#: ../boots/lib/console.py:132
347msgid "A lingo is a command language usable within Boots."
348msgstr ""
349
350#: ../boots/lib/console.py:144
351msgid "Invalid lingo \"{0}\" specified."
352msgstr ""
353
354#: ../boots/lib/console.py:173
355msgid "Could not connect to {0}:{1}"
356msgstr ""
357
358#: ../boots/lib/console.py:192
359msgid "{0.hostname}:{0.port} (server v{0.server_version})"
360msgstr ""
361
362#: ../boots/lib/console.py:227
363msgid "Boots quit."
364msgstr ""
365
366#: ../boots/lib/console.py:245
367msgid "Did you mean: {0}?"
368msgstr ""
369
370#: ../boots/lib/console.py:247
371msgid "No help found for \"{0}\"."
372msgstr ""
373
374#: ../boots/lib/console.py:276
375msgid "Could not open file {0}"
376msgstr ""
0377
=== added file 'po/createpots.sh'
--- po/createpots.sh 1970-01-01 00:00:00 +0000
+++ po/createpots.sh 2010-03-07 09:23:22 +0000
@@ -0,0 +1,3 @@
1#!/bin/bash
2find ../boots/ -name *.py | xargs xgettext --language=Python --keyword="n_:1,2" --output=boots.pot --package-name="boots" --msgid-bugs-address="http://translations.launchpad.net/boots"
3

Subscribers

People subscribed via source and target branches

to status/vote changes: