Merge lp:~ken-brotherton/boots/local2 into lp:boots

Proposed by KenBrotherton
Status: Merged
Merged at revision: not available
Proposed branch: lp:~ken-brotherton/boots/local2
Merge into: lp:boots
Diff against target: 1026 lines (+467/-58) (has conflicts)
18 files modified
boots/api/nodes/node.py (+2/-0)
boots/app/client_config.py (+20/-15)
boots/lib/console.py (+22/-13)
boots/lib/lingos/lingo.py (+3/-1)
boots/lib/lingos/lisp/builtins.py (+4/-2)
boots/lib/lingos/lisp/lexer.py (+2/-1)
boots/lib/lingos/lisp/lisp.py (+4/-2)
boots/lib/lingos/lisp/objects.py (+10/-8)
boots/lib/lingos/lisp/parser.py (+3/-1)
boots/lib/lingos/piped_sql.py (+7/-5)
boots/lib/ui/components/help.py (+6/-4)
boots/lib/ui/components/metacommands.py (+2/-1)
boots/lib/ui/plain.py (+37/-5)
boots/util.py (+27/-0)
localizations/README.txt (+22/-0)
localizations/boots.pot (+281/-0)
localizations/createpots.sh (+3/-0)
localizations/potfiles.txt (+12/-0)
Text conflict in boots/app/client_config.py
Text conflict in boots/lib/console.py
Text conflict in boots/lib/ui/plain.py
To merge this branch: bzr merge lp:~ken-brotherton/boots/local2
Reviewer Review Type Date Requested Status
Max Goodhart Needs Fixing
Review via email: mp+20415@code.launchpad.net
To post a comment you must log in.
Revision history for this message
KenBrotherton (ken-brotherton) wrote :

Tested and working. Forced to remerged the app and lib data as the domain for the two is the same. No found way to distinguish between the two at run time.

Revision history for this message
Max Goodhart (chromakode) wrote :

The module boots.util appears to be missing. Did you forget to add the file?

review: Needs Fixing
Revision history for this message
KenBrotherton (ken-brotherton) wrote :

Corrected. Please rereview.

On Tue, 2010-03-02 at 00:58 +0000, Chromakode wrote:
> Review: Needs Fixing
> The module boots.util appears to be missing. Did you forget to add the file?

--

*You can find me on IM as well
bedlamoid (Yahoo,AIM, MSN)
ken.brotherton@gmail (GTalk)
http://www.myspace.com/broken_broken
http://www.facebook.com/people/Ken-Brotherton/691662047

lp:~ken-brotherton/boots/local2 updated
92. By Ken Brotherton <kennyb@capstone14>

Tested Full app Localizations

Revision history for this message
Max Goodhart (chromakode) wrote :

Still working on merging. I think expressions like...

return ConsoleError(_("Invalid lingo")+" \"{0}\" "+_("specified.").format(lingo))

...need the sting formatting operators inside the localized strings. See:

http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'boots/api/nodes/node.py'
2--- boots/api/nodes/node.py 2010-02-27 05:40:10 +0000
3+++ boots/api/nodes/node.py 2010-03-02 01:07:12 +0000
4@@ -25,6 +25,8 @@
5 from itertools import chain, tee, repeat
6 from threading import Thread, Event, Lock
7 from types import GeneratorType
8+import gettext
9+gettext.install("boots",localedir=None,unicode=1)
10
11 def catch_exceptions(iterable):
12 try:
13
14=== modified file 'boots/app/client_config.py'
15--- boots/app/client_config.py 2010-03-01 08:03:27 +0000
16+++ boots/app/client_config.py 2010-03-02 01:07:12 +0000
17@@ -28,6 +28,7 @@
18 import optparse
19 import os, os.path
20 import info
21+from boots.util import set_gettext
22
23 def find_executable(name):
24 # Search algorithm adapted from os._execvpe
25@@ -88,71 +89,75 @@
26 action = "store",
27 type = "string",
28 dest = "command",
29- help = "Execute command and exit")
30+ help = _("Execute command and exit"))
31 self._cli_parser.add_option("-D", "--database",
32 action = "store",
33 type = "string",
34 dest = "database",
35- help = "Use database")
36+ help = _("Use database"))
37 self._cli_parser.add_option("-f", "--script",
38 action = "store",
39 type = "string",
40 dest = "script",
41- help = "Execute commands from file and exit")
42+ help = _("Execute commands from file and exit"))
43 self._cli_parser.add_option('-l', '--lingo',
44 action = 'store',
45 type = 'string',
46 dest = 'lingo',
47- help = 'Set the lingo to use')
48+ help = _('Set the lingo to use'))
49 self._cli_parser.add_option("-X", "--norc",
50 action = "store_true",
51 dest = "norc",
52- help = "Do not read user configuration file")
53+ help = _("Do not read user configuration file"))
54 self._cli_parser.add_option("-r", "--rc",
55 action = "store",
56 type = "string",
57 dest = "rcfile",
58- help = "Filename of user configuration file")
59+ help = _("Filename of user configuration file"))
60 self._cli_parser.add_option("-H", "--host",
61 action = "store",
62 type = "string",
63 dest = "host",
64- help = "Connect to host")
65+ help = _("Connect to host"))
66 self._cli_parser.add_option("-p", "--port",
67 action = "store",
68 type = "int",
69 dest = "port",
70- help = "Use port number")
71+ help = _("Use port number"))
72 self._cli_parser.add_option("-u", "--user",
73 action = "store",
74 type = "string",
75 dest = "username",
76- help = "Login with username")
77+ help = _("Login with username"))
78 self._cli_parser.add_option("-P", "--password",
79 action = "store",
80 type = "string",
81 dest = "password",
82+<<<<<<< TREE
83 help = "Connect using password. If none is given, query for password")
84 self._cli_parser.add_option("--pager",
85 action = "store",
86 type = "string",
87 dest = "pager",
88 help = "Pipe query results to the specified pager.")
89+=======
90+ help = _("Connect using password. If none is given, query for password"))
91+>>>>>>> MERGE-SOURCE
92 self._cli_parser.add_option("-t", "--terminatingchar",
93 action = "store",
94 type = "string",
95 dest = "terminating_char",
96- help = "Specify the SQL statement terminating character. Default is ';'.")
97+ help = _("Specify the SQL statement terminating character. Default is ';'."))
98 self._cli_parser.add_option("-F", "--historyfile",
99 action = "store",
100 type = "string",
101 dest = "history_file",
102- help = "Specify file to save history to")
103+ help = _("Specify file to save history to"))
104 self._cli_parser.add_option("-L", "--historylength",
105 action = "store",
106 type = "int",
107 dest = "history_length",
108- help = "Specify max history file length")
109+ help = _("Specify max history file length"))
110
111 def __getitem__(self, key):
112 """Allows one to use the [] operator to get config items."""
113@@ -200,11 +205,11 @@
114 except IOError:
115 if filepath != info.RCFILE:
116 # Only print an error if a non-default rc file was specified.
117- print("rcfile {0} not found".format(filepath))
118+ print("rcfile {0} "+_("not found").format(filepath))
119 except SyntaxError:
120- print("rcfile {0} contains a syntax error".format(filepath))
121+ print("rcfile {0} "+_("contains a syntax error").format(filepath))
122 except Exception as e:
123- print("rcfile {0} contains an error: {1}".format(filepath, e))
124+ print("rcfile {0} "+_("contains an error:")+" {1}".format(filepath, e))
125 return file_dict
126
127 def get_cli_conf(self):
128
129=== modified file 'boots/lib/console.py'
130--- boots/lib/console.py 2010-02-28 22:37:03 +0000
131+++ boots/lib/console.py 2010-03-02 01:07:12 +0000
132@@ -38,8 +38,10 @@
133 from boots.lib.lingos import python
134 from boots.lib.lingos import piped_sql
135 from boots.lib.lingos import sql
136+from boots.util import set_gettext
137 import sys
138
139+
140 # Utility function.
141 def iterable(obj):
142 """Returns True if obj is iterable; otherwise, False is returned."""
143@@ -91,20 +93,20 @@
144 self.hooks["load"].call()
145
146 def _init_help(self):
147- self.help = HelpTopic("boots", "Boots Help", "Help", """
148- Boots is a flexible, extensible, and multilingual shell for working with databases. To read more about a subtopic, use `help <topic>`.""")
149+ self.help = HelpTopic("boots", "Boots Help", "Help", _("""
150+ Boots is a flexible, extensible, and multilingual shell for working with databases. To read more about a subtopic, use `help <topic>`."""))
151
152 self.help["commands"] = QueryIndexTopic("commands", None,
153- "List of Boots commands.",
154+ _("List of Boots commands."),
155 query=("commands",))
156
157- self.help["commands"].add("\quit", "quit", "Quit boots.")
158- self.help["commands"].add("\help", "help", "Show help for a topic.", """
159+ self.help["commands"].add("\quit", "quit", _("Quit boots."))
160+ self.help["commands"].add("\help", "help", _("Show help for a topic."), _("""
161 help <topic>
162- Show help for \"topic\".""")
163+ Show help for \"topic\"."""))
164
165- self.help.add("lingos", "Lingos", "Documentation for loaded lingos.", """
166- A lingo is a command language usable within Boots.""")
167+ self.help.add("lingos", "Lingos", _("Documentation for loaded lingos."), _("""
168+ A lingo is a command language usable within Boots."""))
169
170 def input_complete(self, command, lingo):
171 if self.metacommands.get_metacommand(command) is not None:
172@@ -115,6 +117,7 @@
173 return command
174
175 def run(self, command, lingo="sql"):
176+<<<<<<< TREE
177 if not lingo in self.lingos:
178 return ConsoleError("Invalid lingo \"{0}\" specified.".format(lingo))
179
180@@ -130,6 +133,12 @@
181 result_graph.link_output(self.presenter.presenter_graph)
182 result_graph.start()
183 result_graph.run()
184+=======
185+ if lingo in self.lingos:
186+ return self.lingos[lingo].execute(command)
187+ else:
188+ return ConsoleError(_("Invalid lingo")+" \"{0}\" "+_("specified.").format(lingo))
189+>>>>>>> MERGE-SOURCE
190
191 def connect(self, host, port, database):
192 try:
193@@ -142,7 +151,7 @@
194 self.servers.append(server)
195 return True
196 else:
197- error = ConsoleError("Could not connect to {0}:{1}".format(host, port))
198+ error = ConsoleError(_("Could not connect to")+" {0}:{1}".format(host, port))
199 self.presenter.presenter_graph.put(error)
200 return False
201
202@@ -162,7 +171,7 @@
203 if self.welcome_msg and self.driver.is_interactive:
204 server_lines = []
205 for server in self.servers:
206- line_format = "{0.hostname}:{0.port} (server v{0.server_version})"
207+ line_format = "{0.hostname}:{0.port} ("+_("server")+" v{0.server_version})"
208 server_lines.append(line_format.format(server))
209 server_status = "\n".join(server_lines)
210
211@@ -182,7 +191,7 @@
212
213 def quit(self, exitcode = 0):
214 if self.driver.is_interactive:
215- self.presenter.presenter_graph.put("Boots quit.")
216+ self.presenter.presenter_graph.put(_("Boots quit."))
217
218 self.hooks["unload"].call()
219 self.disconnect(None, None)
220@@ -200,9 +209,9 @@
221 self.presenter.present(topic.format(include_index=True))
222 else:
223 paths = ", ".join("\"{0}\"".format(" ".join(path)) for path in results)
224- self.presenter.present("Did you mean: {0}?".format(paths))
225+ self.presenter.present(_("Did you mean:")+" {0}?".format(paths))
226 else:
227- self.presenter.present("No help found for \"{0}\".".format(" ".join(query)))
228+ self.presenter.present(_("No help found for")+" \"{0}\".".format(" ".join(query)))
229
230 def meta_connect(self, host=None, port=None, database=None):
231 if host is None:
232
233=== modified file 'boots/lib/lingos/lingo.py'
234--- boots/lib/lingos/lingo.py 2010-02-27 05:40:10 +0000
235+++ boots/lib/lingos/lingo.py 2010-03-02 01:07:12 +0000
236@@ -23,6 +23,8 @@
237
238 import sys
239
240+from boots.util import set_gettext
241+
242 class LingoRegistry(object):
243 def __init__(self):
244 self._lingos = {}
245@@ -31,7 +33,7 @@
246 """Registers a lingo with the given name and interpreter. Raises a KeyError if a lingo with
247 name is already registered."""
248 if name in self._lingos:
249- raise KeyError('A lingo with name {0} already exists'.format(name))
250+ raise KeyError(_('A lingo with name')+' {0} '+_('already exists').format(name))
251
252 self._lingos[name] = interpreter
253
254
255=== modified file 'boots/lib/lingos/lisp/builtins.py'
256--- boots/lib/lingos/lisp/builtins.py 2010-02-27 05:40:10 +0000
257+++ boots/lib/lingos/lisp/builtins.py 2010-03-02 01:07:12 +0000
258@@ -22,8 +22,10 @@
259 # ##### END LICENSE BLOCK #####
260
261 from boots.lib.lingos.lisp import objects
262+from boots.util import set_gettext
263 import sys
264
265+
266 nil = objects.Null()
267 t = objects.T()
268
269@@ -57,7 +59,7 @@
270 elif isinstance(s, objects.String):
271 return objects.Integer(len(s.python_string()))
272 else:
273- raise TypeError('Expected a cons, nil or a string')
274+ raise TypeError(_('Expected a cons, nil or a string'))
275
276 def elt_function(s, i):
277 """Returns the ith element of the sequence s."""
278@@ -66,7 +68,7 @@
279 elif isinstance(s, objects.String):
280 return s.python_string()[i.python_integer()]
281 else:
282- raise TypeError('Expected a cons or string')
283+ raise TypeError(_('Expected a cons or string'))
284
285 def gensym_function():
286 """Returns a unique symbol that will never be the same as any other symbol even if it has the same name."""
287
288=== modified file 'boots/lib/lingos/lisp/lexer.py'
289--- boots/lib/lingos/lisp/lexer.py 2010-02-27 05:40:10 +0000
290+++ boots/lib/lingos/lisp/lexer.py 2010-03-02 01:07:12 +0000
291@@ -22,6 +22,7 @@
292 # ##### END LICENSE BLOCK #####
293
294 import ply.lex as lex
295+from boots.util import set_gettext
296
297 tokens = ('INTEGER', 'STRING', 'SYMBOL', 'QUOTE', 'LEFT_PAREN', 'RIGHT_PAREN')
298
299@@ -34,7 +35,7 @@
300 t_ignore = ' \t\n'
301
302 def t_error(t):
303- print('illegal character {0} found'.format(t.value))
304+ print(_('illegal character {0} found').format(t.value))
305 token.lexer.skip(1)
306
307 lexer = lex.lex()
308
309=== modified file 'boots/lib/lingos/lisp/lisp.py'
310--- boots/lib/lingos/lisp/lisp.py 2010-02-27 05:40:10 +0000
311+++ boots/lib/lingos/lisp/lisp.py 2010-03-02 01:07:12 +0000
312@@ -44,9 +44,11 @@
313 from boots.lib.lingos.lisp import lexer
314 from boots.lib.lingos.lisp import objects
315 from boots.lib.lingos.lisp import parser
316+from boots.util import set_gettext
317 import re
318 import readline
319
320+
321 def input_complete(string):
322 """Returns string if string is a complete lisp expression. Otherwise, None is returned."""
323 # Remove strings as they may contain parentheses.
324@@ -56,7 +58,7 @@
325 paren_level = left_parens - right_parens
326
327 if paren_level < 0:
328- raise SyntaxError('unmatched closing ")"')
329+ raise SyntaxError(_('unmatched closing ")"'))
330 elif paren_level > 0:
331 return None
332 else:
333@@ -75,7 +77,7 @@
334 if isinstance(stream, file):
335 stream = stream.readline
336 elif not callable(stream):
337- raise TypeError('{0} is not a stream or a callable'.format(stream))
338+ raise TypeError('{0} '+_('is not a stream or a callable').format(stream))
339 # Read lines until all open lisp expressions have been closed.
340 while True:
341 line = stream()
342
343=== modified file 'boots/lib/lingos/lisp/objects.py'
344--- boots/lib/lingos/lisp/objects.py 2010-02-27 05:40:10 +0000
345+++ boots/lib/lingos/lisp/objects.py 2010-03-02 01:07:12 +0000
346@@ -25,6 +25,8 @@
347 import copy
348 import sys
349
350+from boots.util import set_gettext
351+
352 _gensym_count = 1
353 _symbols = {}
354
355@@ -96,7 +98,7 @@
356 else_expression = car(cdr(cdr(cdr(self))))
357
358 if then_expression is Null() or cdr(cdr(cdr(cdr(self)))) is not Null():
359- raise SyntaxError('wrong number of arguments for if special form {0}'.format(self))
360+ raise SyntaxError(_('wrong number of arguments for if special form')+' {0}'.format(self))
361
362 if condition_expression.evaluate(environment) != Null():
363 return then_expression.evaluate(environment)
364@@ -115,7 +117,7 @@
365 values = arguments[2::2]
366
367 if len(symbols) != len(values) or len(symbols) == 0:
368- raise SyntaxError('The number of symbols must equal the number of values and must be non-zero')
369+ raise SyntaxError(_('The number of symbols must equal the number of values and must be non-zero'))
370
371 for symbol, value in zip(symbols, values):
372 value = value.evaluate(environment)
373@@ -129,7 +131,7 @@
374 else: # Handle function calls.
375 function = self.car.evaluate(environment)
376 if not isinstance(function, Lambda):
377- raise TypeError('Expected a function')
378+ raise TypeError(_('Expected a function'))
379 else:
380 return function.call((argument.evaluate(environment) for argument in self.python_list()[1:]), environment)
381
382@@ -165,18 +167,18 @@
383 def __getitem__(self, symbol):
384 """Returns the value of symbol in the environment."""
385 if not isinstance(symbol, Symbol):
386- raise TypeError('Expected a symbol')
387+ raise TypeError(_('Expected a symbol'))
388
389 try:
390 return self._environment[symbol][-1]
391 except KeyError:
392- raise KeyError('No binding for {0} exists in the current environment'.format(symbol))
393+ raise KeyError(_('No binding for')+' {0} '+_('exists in the current environment').format(symbol))
394
395 def __setitem__(self, symbol, value):
396 """Sets symbol to value in the environment. If no binding for symbol exists, a binding is created at the innermost
397 scope."""
398 if not isinstance(symbol, Symbol):
399- raise TypeError('Expected a symbol')
400+ raise TypeError(_('Expected a symbol'))
401
402 if symbol not in self._environment:
403 self._environment[symbol] = [value]
404@@ -188,7 +190,7 @@
405 # def __delitem__(self, symbol):
406 # """Removes the first binding found for symbol. Returns True if the symbol is found and False otherwise."""
407 # if not isinstance(symbol, Symbol):
408- # raise TypeError('Expected a symbol')
409+ # raise TypeError(_('Expected a symbol'))
410
411 # if symbol in self._environment:
412 # self._environment[symbol].pop()
413@@ -215,7 +217,7 @@
414 def pop(self):
415 """Removes the innermost scope and returns a dictionary that corresponds to its bindings."""
416 if len(self._scopes) <= 1:
417- raise RuntimeError('Cannot pop the innermost scope because then no scopes would remain')
418+ raise RuntimeError(_('Cannot pop the innermost scope because then no scopes would remain'))
419 symbols = self._scopes.pop()
420
421 for symbol in symbols:
422
423=== modified file 'boots/lib/lingos/lisp/parser.py'
424--- boots/lib/lingos/lisp/parser.py 2010-02-27 05:40:10 +0000
425+++ boots/lib/lingos/lisp/parser.py 2010-03-02 01:07:12 +0000
426@@ -24,8 +24,10 @@
427 from lexer import tokens
428 from boots.lib.lingos.lisp import builtins
429 from boots.lib.lingos.lisp import objects
430+from boots.util import set_gettext
431 import ply.yacc as yacc
432
433+
434 def p_expression_integer(p):
435 'expression : INTEGER'
436 p[0] = objects.Integer(int(p[1]))
437@@ -59,7 +61,7 @@
438 p[0] = objects.Cons(p[1], p[2])
439
440 def p_error(p):
441- print('syntax error')
442+ print(_('syntax error'))
443
444 # Disable debugging output and caching of parse tables.
445 parser = yacc.yacc(debug = 0, write_tables = 0)
446
447=== modified file 'boots/lib/lingos/piped_sql.py'
448--- boots/lib/lingos/piped_sql.py 2010-02-27 05:54:13 +0000
449+++ boots/lib/lingos/piped_sql.py 2010-03-02 01:07:12 +0000
450@@ -26,8 +26,10 @@
451 from boots.lib.ui.components.help import HelpTopic
452 from boots.lib.lingos import lingo
453 from boots.lib.lingos import sql
454+from boots.util import set_gettext
455 import re
456
457+
458 # Set this to another node constructor to change the default constructor used for output files.
459 output_file_node = csv_output_file_node
460
461@@ -40,7 +42,7 @@
462 constructor_call_re = re.compile('^(?P<name>[a-zA-Z_]+)\((?P<arguments>([^,\(\)]+,)*[^,\(\)]+)?\)$')
463
464 class PipedSQLInterpreter(sql.SQLInterpreter):
465- help = HelpTopic("pipedsql", "Piped SQL Lingo", "Enhanced SQL query language supporting pipes.")
466+ help = HelpTopic("pipedsql", "Piped SQL Lingo", _("Enhanced SQL query language supporting pipes."))
467
468 def __init__(self, *args, **kwargs):
469 super(PipedSQLInterpreter, self).__init__(*args, **kwargs)
470@@ -52,7 +54,7 @@
471 match = clause_re.match(clause_string)
472
473 if not match:
474- raise SyntaxError('{0} is not in the correct function call syntax'.format(clause_string))
475+ raise SyntaxError('{0} '+_('is not in the correct function call syntax').format(clause_string))
476
477 constructor_call = match.group('constructor_call').strip()
478 output_file = match.group('output_file')
479@@ -63,7 +65,7 @@
480 match = constructor_call_re.match(constructor_string)
481
482 if not match:
483- raise SyntaxError('{0} is not in the correct function call syntax'.format(constructor_string))
484+ raise SyntaxError('{0} '+_('is not in the correct function call syntax').format(constructor_string))
485
486 name = match.group('name')
487 arguments = match.group('arguments')
488@@ -90,7 +92,7 @@
489 constructor_call, output_file = self._parse_clause(clause)
490 except SyntaxError as e:
491 print(e)
492- print 'error1'
493+ print _('error1')
494 return [] # Return an empty list to avoid printing None.
495
496 try:
497@@ -102,7 +104,7 @@
498 # SQL is only allowed for the first node.
499 if sql:
500 if not first_node:
501- raise SyntaxError('SQL is only permitted for the first clause')
502+ raise SyntaxError(_('SQL is only permitted for the first clause'))
503
504 # FIXME: Add support for multiple servers here. Currently only the first server
505 # is used.
506
507=== modified file 'boots/lib/ui/components/help.py'
508--- boots/lib/ui/components/help.py 2010-02-27 05:54:13 +0000
509+++ boots/lib/ui/components/help.py 2010-03-02 01:07:12 +0000
510@@ -21,6 +21,8 @@
511 #
512 # ##### END LICENSE BLOCK #####
513
514+from boots.util import set_gettext
515+
516 def issubseq(subseq, seq):
517 """Determines if the elements the sequence subseq form a subsequence of the sequence seq."""
518 for start in range(len(seq) - len(subseq) + 1):
519@@ -63,11 +65,11 @@
520 template += "{0.description}"
521
522 if self.see_also:
523- template += "\n\nSee also: {0.see_also}"
524+ template += "\n\n"+_("See also:")+" {0.see_also}"
525
526 output = template.format(self)
527 if include_index and self._subtopics:
528- output += "\n--- Subtopics ---\n" + self.format_index()
529+ output += "\n--- "+_("Subtopics")+" ---\n" + self.format_index()
530
531 return output
532
533@@ -101,7 +103,7 @@
534 assert isinstance(item, str)
535 return query
536 else:
537- raise TypeError('query object {0} is not a string or tuple of strings'.format(query))
538+ raise TypeError(_('query object')+' {0} '+_('is not a string or tuple of strings').format(query))
539
540 def _ensure_key(self, key):
541 """Creates a new subtopic that key maps to if none exists."""
542@@ -198,4 +200,4 @@
543 subtopics = self._subtopics.copy()
544 for path in self.root.search(self.query):
545 subtopics.update(self.root[path]._subtopics)
546- return subtopics
547\ No newline at end of file
548+ return subtopics
549
550=== modified file 'boots/lib/ui/components/metacommands.py'
551--- boots/lib/ui/components/metacommands.py 2010-02-27 05:54:13 +0000
552+++ boots/lib/ui/components/metacommands.py 2010-03-02 01:07:12 +0000
553@@ -22,6 +22,7 @@
554 # ##### END LICENSE BLOCK #####
555
556 import warnings
557+from boots.util import set_gettext
558
559 def parse_metacommand(commandstring):
560 """This function wraps str.split() for metacommands
561@@ -43,7 +44,7 @@
562 # FIXME: Issue warning through the UI using ui.print
563 # FIXME: Determine the offending command(s) (set.intersect?)
564 # FIXME: Print offending commands
565- warnings.warn("Conflicts between metacommands detected.")
566+ warnings.warn(_("Conflicts between metacommands detected."))
567 self.names |= newnames
568
569 class MetaCommands(object):
570
571=== modified file 'boots/lib/ui/plain.py'
572--- boots/lib/ui/plain.py 2010-03-01 08:21:05 +0000
573+++ boots/lib/ui/plain.py 2010-03-02 01:07:12 +0000
574@@ -28,13 +28,18 @@
575 import os
576 import time
577 import readline
578+<<<<<<< TREE
579 import subprocess
580 import threading
581+=======
582+
583+>>>>>>> MERGE-SOURCE
584
585 from boots.api.nodes.node import NodeGraph, SyncNode
586 from boots.lib.ui.components.help import HelpTopic
587 from boots.lib.ui.components.metacommands import MetaCommands, parse_metacommand
588 from boots.lib.ui.generic import StdinDriver, StdoutPresenter
589+from boots.util import set_gettext
590
591 class PlainUI(StdinDriver, StdoutPresenter):
592 """Class that provides a 'plain' UI for boots. Input is taken on stdin,
593@@ -42,11 +47,11 @@
594 results are printed to stdout. These results are printed as tables when
595 they are Server packets and as string interpretations otherwise."""
596
597- help = HelpTopic("plain", "Plain UI", "Plain UI documentation.", """
598- A simple, minimal user interface for Boots.""")
599+ help = HelpTopic("plain", "Plain UI", _("Plain UI documentation."), _("""
600+ A simple, minimal user interface for Boots."""))
601
602- help.add("commands", None, "List of Plain UI commands.")
603- help["commands"].add("\use", "use", "Switch to a different lingo.")
604+ help.add("commands", None, _("List of Plain UI commands."))
605+ help["commands"].add("\use", "use", _("Switch to a different lingo."))
606
607 def __init__(self, console):
608 """Initialize a UI giving it its parent console, primary prompt,
609@@ -183,6 +188,7 @@
610 self.last_desc = result["info"]
611 if result["result"]:
612 self.buffer.extend(result["result"])
613+<<<<<<< TREE
614 elif self.buffer:
615 printed = False
616 if self.pager_command and self.console.driver.is_interactive:
617@@ -201,6 +207,32 @@
618 sys.stdout.write("\n")
619 elif result is not None:
620 sys.stdout.write(str(result))
621+=======
622+ else:
623+ if self.buffer:
624+ max_widths = map(max, [(len(column[0]), column[2]) for column in self.last_desc])
625+ dashes = map(lambda x: "-"*(x+2), max_widths)
626+ sep_line = "+" + "+".join(dashes) + "+\n"
627+ current_time = time.time()
628+ info_line = "{0} "+_("rows in set")+" ({1:.2f} "+_("seconds")+").\n".format(len(self.buffer),
629+ current_time - result["begin_time"])
630+ names = (column[0] for column in self.last_desc)
631+ sys.stdout.write(sep_line)
632+ sys.stdout.write(padded(names, max_widths))
633+ sys.stdout.write(sep_line)
634+ for row in self.buffer:
635+ sys.stdout.write(padded(map(show_NULL, row), max_widths))
636+ sys.stdout.write(sep_line)
637+ sys.stdout.write(info_line)
638+ # Reset values for next result set.
639+ self.buffer = []
640+ else:
641+ if isinstance(result, Exception):
642+ sys.stdout.write(_("ERROR "))
643+ sys.stdout.write(" :: ".join(map(str, result.args)))
644+ else:
645+ sys.stdout.write(str(result))
646+>>>>>>> MERGE-SOURCE
647 sys.stdout.write("\n")
648
649 @property
650@@ -216,4 +248,4 @@
651 if lingo in self.console.lingos:
652 self.lingo = lingo
653 else:
654- self.present("The specified lingo \"{0}\" does not exist.".format(lingo))
655+ self.present(_("The specified lingo")+" \"{0}\" "+_("does not exist.").format(lingo))
656
657=== added file 'boots/util.py'
658--- boots/util.py 1970-01-01 00:00:00 +0000
659+++ boots/util.py 2010-03-02 01:07:12 +0000
660@@ -0,0 +1,27 @@
661+# Boots Client Project
662+# www.launchpad.net/boots
663+#
664+# ##### BEGIN LICENSE BLOCK #####
665+#
666+# Copyright (C) 2009-2010 Clark Boylan, Ken Brotherton, Max Goodman,
667+# Victoria Lewis, David Rosenbaum, and Andreas Turriff
668+#
669+# This program is free software: you can redistribute it and/or modify
670+# it under the terms of the GNU General Public License as published by
671+# the Free Software Foundation, either version 3 of the License, or
672+# (at your option) any later version.
673+#
674+# This program is distributed in the hope that it will be useful,
675+# but WITHOUT ANY WARRANTY; without even the implied warranty of
676+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
677+# GNU General Public License for more details.
678+#
679+# You should have received a copy of the GNU General Public License
680+# along with this program. If not, see <http://www.gnu.org/licenses/>.
681+#
682+# ##### END LICENSE BLOCK #####
683+
684+import locale, gettext
685+def set_gettext(mo_location='/usr/share/locale'):
686+ locale.setlocale(locale.LC_ALL)
687+ gettext.install('boots', mo_location)
688
689=== added directory 'localizations'
690=== added file 'localizations/README.txt'
691--- localizations/README.txt 1970-01-01 00:00:00 +0000
692+++ localizations/README.txt 2010-03-02 01:07:12 +0000
693@@ -0,0 +1,22 @@
694+========When adding code that outputs a string========
695+1) Add (if not present already) to the import section of the .py file
696+#=========
697+import gettext
698+gettext.bindtextdomain("fslint", "/usr/share/locale") #sys default used if localedir=None
699+gettext.textdomain("fslint")
700+_ = gettext.gettext
701+#=========
702+And then wrap all output strings with _("...").
703+You should do this so that if you are using dynamicly created content, that created content is not part of the wrapped string.
704+Ex:
705+help = "Execute commands from file and exit")
706+should be wrapped as such:
707+help = _("Execute commands from file and exit"))
708+Ex:
709+print("rcfile {0} contains a syntax error".format(filepath))
710+should be wrapped as such:
711+print(_("rcfile ")+"{0} "+_("contains a syntax error").format(filepath))
712+
713+2) Add your file path to the /boots/localizations/potfiles.txt file.
714+3) Generate the updated .pot file by running the /boots/localization/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.
715+4) Upload new pot file to the launchpad localization section for creation or updating of .po files. (more on this later --ken)
716
717=== added file 'localizations/boots.pot'
718--- localizations/boots.pot 1970-01-01 00:00:00 +0000
719+++ localizations/boots.pot 2010-03-02 01:07:12 +0000
720@@ -0,0 +1,281 @@
721+# SOME DESCRIPTIVE TITLE.
722+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
723+# This file is distributed under the same license as the PACKAGE package.
724+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
725+#
726+#, fuzzy
727+msgid ""
728+msgstr ""
729+"Project-Id-Version: PACKAGE VERSION\n"
730+"Report-Msgid-Bugs-To: \n"
731+"POT-Creation-Date: 2010-03-01 16:40-0800\n"
732+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
733+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
734+"Language-Team: LANGUAGE <LL@li.org>\n"
735+"MIME-Version: 1.0\n"
736+"Content-Type: text/plain; charset=CHARSET\n"
737+"Content-Transfer-Encoding: 8bit\n"
738+
739+#: ../boots/lib/console.py:96
740+msgid ""
741+"\n"
742+" Boots is a flexible, extensible, and multilingual shell for "
743+"working with databases. To read more about a subtopic, use `help <topic>`."
744+msgstr ""
745+
746+#: ../boots/lib/console.py:100
747+msgid "List of Boots commands."
748+msgstr ""
749+
750+#: ../boots/lib/console.py:103
751+msgid "Quit boots."
752+msgstr ""
753+
754+#: ../boots/lib/console.py:104
755+msgid "Show help for a topic."
756+msgstr ""
757+
758+#: ../boots/lib/console.py:104
759+msgid ""
760+"\n"
761+" help <topic>\n"
762+" Show help for \"topic\"."
763+msgstr ""
764+
765+#: ../boots/lib/console.py:108
766+msgid "Documentation for loaded lingos."
767+msgstr ""
768+
769+#: ../boots/lib/console.py:108
770+msgid ""
771+"\n"
772+" A lingo is a command language usable within Boots."
773+msgstr ""
774+
775+#: ../boots/lib/console.py:123
776+msgid "Invalid lingo"
777+msgstr ""
778+
779+#: ../boots/lib/console.py:123
780+msgid "specified."
781+msgstr ""
782+
783+#: ../boots/lib/console.py:136
784+msgid "Could not connect to"
785+msgstr ""
786+
787+#: ../boots/lib/console.py:156
788+msgid "server"
789+msgstr ""
790+
791+#: ../boots/lib/console.py:189
792+msgid "Boots quit."
793+msgstr ""
794+
795+#: ../boots/lib/console.py:207
796+msgid "Did you mean:"
797+msgstr ""
798+
799+#: ../boots/lib/console.py:209
800+msgid "No help found for"
801+msgstr ""
802+
803+#: ../boots/lib/ui/plain.py:45
804+msgid "Plain UI documentation."
805+msgstr ""
806+
807+#: ../boots/lib/ui/plain.py:45
808+msgid ""
809+"\n"
810+" A simple, minimal user interface for Boots."
811+msgstr ""
812+
813+#: ../boots/lib/ui/plain.py:48
814+msgid "List of Plain UI commands."
815+msgstr ""
816+
817+#: ../boots/lib/ui/plain.py:49
818+msgid "Switch to a different lingo."
819+msgstr ""
820+
821+#: ../boots/lib/ui/plain.py:156
822+msgid "rows in set"
823+msgstr ""
824+
825+#: ../boots/lib/ui/plain.py:156
826+msgid "seconds"
827+msgstr ""
828+
829+#: ../boots/lib/ui/plain.py:170
830+msgid "ERROR "
831+msgstr ""
832+
833+#: ../boots/lib/ui/plain.py:189
834+msgid "The specified lingo"
835+msgstr ""
836+
837+#: ../boots/lib/ui/plain.py:189
838+msgid "does not exist."
839+msgstr ""
840+
841+#: ../boots/lib/ui/components/metacommands.py:47
842+msgid "Conflicts between metacommands detected."
843+msgstr ""
844+
845+#: ../boots/lib/ui/components/help.py:68
846+msgid "See also:"
847+msgstr ""
848+
849+#: ../boots/lib/ui/components/help.py:72
850+msgid "Subtopics"
851+msgstr ""
852+
853+#: ../boots/lib/ui/components/help.py:106
854+msgid "query object"
855+msgstr ""
856+
857+#: ../boots/lib/ui/components/help.py:106
858+msgid "is not a string or tuple of strings"
859+msgstr ""
860+
861+#: ../boots/lib/lingos/lingo.py:36
862+msgid "A lingo with name"
863+msgstr ""
864+
865+#: ../boots/lib/lingos/lingo.py:36
866+msgid "already exists"
867+msgstr ""
868+
869+#: ../boots/lib/lingos/piped_sql.py:45
870+msgid "Enhanced SQL query language supporting pipes."
871+msgstr ""
872+
873+#: ../boots/lib/lingos/piped_sql.py:57 ../boots/lib/lingos/piped_sql.py:68
874+msgid "is not in the correct function call syntax"
875+msgstr ""
876+
877+#: ../boots/lib/lingos/piped_sql.py:95
878+msgid "error1"
879+msgstr ""
880+
881+#: ../boots/lib/lingos/piped_sql.py:107
882+msgid "SQL is only permitted for the first clause"
883+msgstr ""
884+
885+#: ../boots/lib/lingos/lisp/builtins.py:62
886+msgid "Expected a cons, nil or a string"
887+msgstr ""
888+
889+#: ../boots/lib/lingos/lisp/builtins.py:71
890+msgid "Expected a cons or string"
891+msgstr ""
892+
893+#: ../boots/lib/lingos/lisp/lexer.py:38
894+msgid "illegal character {0} found"
895+msgstr ""
896+
897+#: ../boots/lib/lingos/lisp/lisp.py:61
898+msgid "unmatched closing \")\""
899+msgstr ""
900+
901+#: ../boots/lib/lingos/lisp/lisp.py:80
902+msgid "is not a stream or a callable"
903+msgstr ""
904+
905+#: ../boots/lib/lingos/lisp/objects.py:101
906+msgid "wrong number of arguments for if special form"
907+msgstr ""
908+
909+#: ../boots/lib/lingos/lisp/objects.py:120
910+msgid ""
911+"The number of symbols must equal the number of values and must be non-zero"
912+msgstr ""
913+
914+#: ../boots/lib/lingos/lisp/objects.py:134
915+msgid "Expected a function"
916+msgstr ""
917+
918+#: ../boots/lib/lingos/lisp/objects.py:170
919+#: ../boots/lib/lingos/lisp/objects.py:181
920+msgid "Expected a symbol"
921+msgstr ""
922+
923+#: ../boots/lib/lingos/lisp/objects.py:175
924+msgid "No binding for"
925+msgstr ""
926+
927+#: ../boots/lib/lingos/lisp/objects.py:175
928+msgid "exists in the current environment"
929+msgstr ""
930+
931+#: ../boots/lib/lingos/lisp/objects.py:220
932+msgid "Cannot pop the innermost scope because then no scopes would remain"
933+msgstr ""
934+
935+#: ../boots/lib/lingos/lisp/parser.py:64
936+msgid "syntax error"
937+msgstr ""
938+
939+#: ../boots/app/client_config.py:68
940+msgid "Execute command and exit"
941+msgstr ""
942+
943+#: ../boots/app/client_config.py:73
944+msgid "Use database"
945+msgstr ""
946+
947+#: ../boots/app/client_config.py:78
948+msgid "Execute commands from file and exit"
949+msgstr ""
950+
951+#: ../boots/app/client_config.py:83
952+msgid "Set the lingo to use"
953+msgstr ""
954+
955+#: ../boots/app/client_config.py:87
956+msgid "Do not read user configuration file"
957+msgstr ""
958+
959+#: ../boots/app/client_config.py:92
960+msgid "Filename of user configuration file"
961+msgstr ""
962+
963+#: ../boots/app/client_config.py:97
964+msgid "Connect to host"
965+msgstr ""
966+
967+#: ../boots/app/client_config.py:102
968+msgid "Use port number"
969+msgstr ""
970+
971+#: ../boots/app/client_config.py:107
972+msgid "Login with username"
973+msgstr ""
974+
975+#: ../boots/app/client_config.py:112
976+msgid "Connect using password. If none is given, query for password"
977+msgstr ""
978+
979+#: ../boots/app/client_config.py:117
980+msgid "Specify the SQL statement terminating character. Default is ';'."
981+msgstr ""
982+
983+#: ../boots/app/client_config.py:122
984+msgid "Specify file to save history to"
985+msgstr ""
986+
987+#: ../boots/app/client_config.py:127
988+msgid "Specify max history file length"
989+msgstr ""
990+
991+#: ../boots/app/client_config.py:167
992+msgid "not found"
993+msgstr ""
994+
995+#: ../boots/app/client_config.py:169
996+msgid "contains a syntax error"
997+msgstr ""
998+
999+#: ../boots/app/client_config.py:171
1000+msgid "contains an error:"
1001+msgstr ""
1002
1003=== added file 'localizations/createpots.sh'
1004--- localizations/createpots.sh 1970-01-01 00:00:00 +0000
1005+++ localizations/createpots.sh 2010-03-02 01:07:12 +0000
1006@@ -0,0 +1,3 @@
1007+#!/bin/bash
1008+xgettext --from-code=utf-8 --keyword=tr --default-domain=cms --output=boots.pot --files-from=potfiles.txt
1009+
1010
1011=== added file 'localizations/potfiles.txt'
1012--- localizations/potfiles.txt 1970-01-01 00:00:00 +0000
1013+++ localizations/potfiles.txt 2010-03-02 01:07:12 +0000
1014@@ -0,0 +1,12 @@
1015+../boots/lib/console.py
1016+../boots/lib/ui/plain.py
1017+../boots/lib/ui/components/metacommands.py
1018+../boots/lib/ui/components/help.py
1019+../boots/lib/lingos/lingo.py
1020+../boots/lib/lingos/piped_sql.py
1021+../boots/lib/lingos/lisp/builtins.py
1022+../boots/lib/lingos/lisp/lexer.py
1023+../boots/lib/lingos/lisp/lisp.py
1024+../boots/lib/lingos/lisp/objects.py
1025+../boots/lib/lingos/lisp/parser.py
1026+../boots/app/client_config.py

Subscribers

People subscribed via source and target branches

to status/vote changes: