Merge lp:~tony-badwolf/quickly/modular_add into lp:quickly

Proposed by Tony Byrne
Status: Merged
Merged at revision: 562
Proposed branch: lp:~tony-badwolf/quickly/modular_add
Merge into: lp:quickly
Diff against target: 449 lines (+248/-147)
5 files modified
data/templates/ubuntu-application/add.py (+33/-146)
data/templates/ubuntu-application/store/__init__.py (+15/-0)
data/templates/ubuntu-application/store/dialog.py (+125/-0)
data/templates/ubuntu-application/store/indicator.py (+68/-0)
data/templates/ubuntu-application/test/add.sh (+7/-1)
To merge this branch: bzr merge lp:~tony-badwolf/quickly/modular_add
Reviewer Review Type Date Requested Status
Michael Terry (community) Needs Fixing
Review via email: mp+40387@code.launchpad.net

Description of the change

Modular version of add which makes it easier to add files to a template. Added test for unknown parameter i.e. quickly add foo reports failure.

To post a comment you must log in.
Revision history for this message
Michael Terry (mterry) wrote :

Neat, thanks Tony! This does seem easier to work with for the future.

77 + help_list = ['Add something to your project\n']
78 + for module in addable:
79 + try:
80 + help_list.append(getattr(store, module).help_text)
81 + except AttributeError:
82 + # ignore files in store that have no help for us
83 + pass
84 + help_text = ''.join(help_list)
85 + print _(help_text)

I would make this '\n\n\n'.join(help_list) and remove the surrounding endlines from the help strings in the store. This is more 'defensive' because it doesn't rely on the cooperation of items from the store.

Also, the translation call _() should go around the source strings (including the ones in the store), not the final "print help_text". Like so:
help_list = [_('Add something to your project')]

204 + templatetools.usage_error(_('Cannot add %s: it is not in the store' % argv[1]), cmd=cmd, template='ubuntu-application')

I would make this a little more user-friendly, like "Did not recognize %s" or something. A user isn't going to know what the store is.

23 +from store import *

Do you need this line?

24 +import store

It feels a bit odd using the store directory for this. What do you think about a new directory/submodule called 'add' or 'add_items' or something?

255 +abs_template_path = templatetools.get_template_path_from_project()

This line causes an error when I do this in the toplevel of the quickly branch due to loadConfig() eventually being called with can_stop=True:
PATH=./bin:$PATH quickly help ubuntu-application add

review: Needs Fixing
lp:~tony-badwolf/quickly/modular_add updated
553. By Tony Byrne <email address hidden>

Fixed translation calls and clarified help message. Prevented
quickly help ubuntu-application add triggering a call to
templatetools.get_template_path_from_project() which causes an error.

Revision history for this message
Tony Byrne (tony-badwolf) wrote :

Hi Michael
 I think my last email might have disappeared because it doesn't show
in my sent mail so here is a summary.

Applied '\n\n'.join(...) fix in help. Applied your suggestions for the
translation code.

from store import *
import store
I need both, I'm aware its weird so I'll give it some thought.

abs_template_path = templatetools.get_template_path_from_project()
This call appears in the original add.py , I tried everything with it
but it always errors for me. The variable abs_template_path is used
inside the store.<module>.add(...) command so I moved this command
inside the add(...) function where quickly help ubuntu-application add
does not trigger it. The help command works now but I cannot tell if
the add.py script/module needs to contain this variable for
introspection.

Using store like this is similar to a debian repository where the
install script is bundled with the source code.

I submitted code yesterday with
quickly add
# ERROR: Cannot add, no plugin name provided.

quickly add foo
# ERROR: Cannot add, did not recognize plugin name: foo

I now think addon is better than plugin. If we don't use the
repository analogy the install scripts can go into addons directory.

On 11/9/10, Michael Terry <email address hidden> wrote:
> Review: Needs Fixing
> Neat, thanks Tony! This does seem easier to work with for the future.
>
> 77 + help_list = ['Add something to your project\n']
> 78 + for module in addable:
> 79 + try:
> 80 + help_list.append(getattr(store, module).help_text)
> 81 + except AttributeError:
> 82 + # ignore files in store that have no help for us
> 83 + pass
> 84 + help_text = ''.join(help_list)
> 85 + print _(help_text)
>
> I would make this '\n\n\n'.join(help_list) and remove the surrounding
> endlines from the help strings in the store. This is more 'defensive'
> because it doesn't rely on the cooperation of items from the store.
>
> Also, the translation call _() should go around the source strings
> (including the ones in the store), not the final "print help_text". Like
> so:
> help_list = [_('Add something to your project')]
>
> 204 + templatetools.usage_error(_('Cannot add %s: it is not in the store' %
> argv[1]), cmd=cmd, template='ubuntu-application')
>
> I would make this a little more user-friendly, like "Did not recognize %s"
> or something. A user isn't going to know what the store is.
>
> 23 +from store import *
>
> Do you need this line?
>
> 24 +import store
>
> It feels a bit odd using the store directory for this. What do you think
> about a new directory/submodule called 'add' or 'add_items' or something?
>
> 255 +abs_template_path = templatetools.get_template_path_from_project()
>
> This line causes an error when I do this in the toplevel of the quickly
> branch due to loadConfig() eventually being called with can_stop=True:
> PATH=./bin:$PATH quickly help ubuntu-application add
> --
> https://code.launchpad.net/~tony-badwolf/quickly/modular_add/+merge/40387
> You are the owner of lp:~tony-badwolf/quickly/modular_add.
>

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'data/templates/ubuntu-application/add.py'
2--- data/templates/ubuntu-application/add.py 2010-10-18 18:39:04 +0000
3+++ data/templates/ubuntu-application/add.py 2010-11-12 00:33:04 +0000
4@@ -16,10 +16,8 @@
5 #You should have received a copy of the GNU General Public License along
6 #with this program. If not, see <http://www.gnu.org/licenses/>.
7
8-import os
9 import sys
10-import internal.quicklyutils as quicklyutils
11-from quickly import configurationhandler, templatetools, commands
12+from quickly import templatetools, commands
13
14 import gettext
15 from gettext import gettext as _
16@@ -27,49 +25,34 @@
17 gettext.textdomain('quickly')
18
19 argv = sys.argv
20-options = {'dialog': _('quickly add dialog <dialog-name>'),
21- 'indicator': 'quickly add indicator'}
22+
23+from store import *
24+import store
25+
26+addable = [x for x in dir(store) if x[0] != '_']
27+
28+options = {}
29+for module in addable:
30+ try:
31+ options[module] = getattr(store, module).option
32+ except AttributeError:
33+ # ignore files in store that have no option for us
34+ pass
35
36 def usage():
37 templatetools.print_usage(options.values())
38+
39 def help():
40- print _("""Add something to your project
41-
42-
43-$ quickly add dialog <dialog-name>
44-
45-Here, dialog-name is one or more words separated with dash
46-
47-For instance $ quickly add dialog dialog-name will create:
48-1. A subclass of gtk.Dialog called DialogNameDialog in the module
49- DialogNameDialog.py
50-2. A glade file called DialogNameDialog.ui in the ui directory
51-3. A catalog file called dialog_name_dialog.xml also in the ui directory
52-
53-To edit the UI for the dialog, run:
54-$ quickly design
55-
56-To edit the behavior, run:
57-$ quickly edit
58-
59-To use the dialog you have to invoke it from another python file:
60-1. Import the dialog
61-import DialogNameDialog
62-
63-2. Create an instance of the dialog
64-dialog = DialogNameDialog.NewDialogNameDialog()
65-
66-3. Run the dialog and hide the dialog
67-result = dialog.run()
68-dialog.hide()
69-
70-
71-$ quickly add indicator
72-
73-This will add support for Ubuntu Application Indicator to you quickly project.
74-Next time you run your app, the Indicator will show up in the panel on top right.
75-You can add/remove/modify items from the indicator menu by editing indicator.py
76-""")
77+ help_list = [_('Add something to your project\n')]
78+ for module in addable:
79+ try:
80+ help_list.append(getattr(store, module).help_text)
81+ except AttributeError:
82+ # ignore files in store that have no help for us
83+ pass
84+ help_text = '\n\n'.join(help_list)
85+ print help_text
86+
87 def shell_completion(argv):
88 ''' Complete args '''
89 # option completion
90@@ -81,109 +64,13 @@
91 print ' '.join(rv)
92 templatetools.handle_additional_parameters(sys.argv, help, shell_completion, usage=usage)
93
94-abs_template_path = templatetools.get_template_path_from_project()
95-abs_command_path = os.path.abspath(os.path.dirname(sys.argv[0]))
96-
97-
98 if len(sys.argv) < 2:
99 cmd = commands.get_command('add', 'ubuntu-application')
100- templatetools.usage_error(_("No action name provided."), cmd=cmd, template='ubuntu-application')
101-
102-if argv[1] == "dialog":
103- if len(argv) != 3:
104- templatetools.print_usage(options['dialog'])
105- sys.exit(4)
106- else:
107- try:
108- dialog_name = templatetools.quickly_name(argv[2])
109- except templatetools.bad_project_name, e:
110- print(e)
111- sys.exit(1)
112-
113- path_and_project = sys.argv[0].split('/')
114-
115- if not configurationhandler.project_config:
116- configurationhandler.loadConfig()
117- project_name = configurationhandler.project_config['project']
118-
119- template_ui_dir = os.path.join(abs_template_path, 'store', 'data', 'ui')
120- template_python_dir = os.path.join(abs_template_path, 'store', 'python')
121- # take files from command directory if don't exist
122- origin_ui_file_list = [os.path.join(template_ui_dir,
123- 'dialog_camel_case_nameDialog.ui'),
124- os.path.join(template_ui_dir,
125- 'dialog_python_name_dialog.xml')]
126- python_file = os.path.join(template_ui_dir,
127- 'dialog_camel_case_nameDialog.py')
128- if len([file_exist for file_exist in origin_ui_file_list if
129- os.path.isfile(file_exist)]) != len(origin_ui_file_list):
130- template_ui_dir = os.path.join(abs_command_path, 'store', 'data',
131- 'ui')
132- if not os.path.isfile(python_file):
133- template_python_dir = os.path.join(abs_command_path, 'store',
134- 'python')
135-
136- target_ui_dir = os.path.join('data', 'ui')
137- python_name = templatetools.python_name(project_name)
138- target_python_dir = python_name
139-
140- dialog_python_name = templatetools.python_name(dialog_name)
141- dialog_sentence_name, dialog_camel_case_name = \
142- quicklyutils.conventional_names(dialog_name)
143- project_sentence_name, project_camel_case_name = \
144- quicklyutils.conventional_names(project_name)
145- dialog_name = dialog_name.replace('-','_')
146-
147- substitutions = (("project_name",project_name),
148- ("dialog_name",dialog_name),
149- ("dialog_python_name",dialog_python_name),
150- ("dialog_camel_case_name",dialog_camel_case_name),
151- ("project_camel_case_name",project_camel_case_name),
152- ("project_sentence_name",project_sentence_name),
153- ("dialog_sentence_name",dialog_sentence_name),
154- ("python_name",python_name))
155-
156- quicklyutils.file_from_template(template_ui_dir,
157- "dialog_camel_case_nameDialog.ui",
158- target_ui_dir,
159- substitutions)
160-
161- quicklyutils.file_from_template(template_ui_dir,
162- "dialog_python_name_dialog.xml",
163- target_ui_dir,
164- substitutions)
165-
166- quicklyutils.file_from_template(template_python_dir,
167- "dialog_camel_case_nameDialog.py",
168- target_python_dir,
169- substitutions)
170-
171-if argv[1] == "indicator":
172- if len(argv) != 2:
173- templatetools.print_usage(options['indicator'])
174- sys.exit(4)
175- else:
176-
177- if not configurationhandler.project_config:
178- configurationhandler.loadConfig()
179- project_name = configurationhandler.project_config['project']
180-
181- template_python_dir = os.path.join(abs_template_path, 'store', 'python')
182- # take files from command directory if don't exist
183- python_file = os.path.join(template_python_dir,
184- 'indicator.py')
185- python_name = templatetools.python_name(project_name)
186- target_python_dir = python_name
187-
188- project_sentence_name, project_camel_case_name = \
189- quicklyutils.conventional_names(project_name)
190-
191- substitutions = (("project_name",project_name),
192- ( "python_name",python_name))
193-
194- quicklyutils.file_from_template(template_python_dir,
195- "indicator.py",
196- target_python_dir,
197- substitutions)
198-
199-
200+ templatetools.usage_error(_("Cannot add, no plugin name provided."), cmd=cmd, template='ubuntu-application')
201+
202+if argv[1] in addable:
203+ getattr(store, argv[1]).add(options)
204+else:
205+ cmd = commands.get_command('add', 'ubuntu-application')
206+ templatetools.usage_error(_('Cannot add, did not recognize plugin name: %s' % argv[1]), cmd=cmd, template='ubuntu-application')
207+ sys.exit(4)
208
209=== added file 'data/templates/ubuntu-application/store/__init__.py'
210--- data/templates/ubuntu-application/store/__init__.py 1970-01-01 00:00:00 +0000
211+++ data/templates/ubuntu-application/store/__init__.py 2010-11-12 00:33:04 +0000
212@@ -0,0 +1,15 @@
213+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
214+### BEGIN LICENSE
215+# This file is in the public domain
216+### END LICENSE
217+
218+import glob as _glob
219+import os as _os
220+
221+_here = _os.path.dirname(__file__)
222+_paths = _glob.glob(_os.path.join(_here, '*.py'))
223+_filenames = [_os.path.basename(_x) for _x in _paths if _os.path.basename(_x)[0] != '_']
224+_no_ext = [_os.path.splitext(_x) for _x in _filenames]
225+
226+__all__ = [_x[0] for _x in _no_ext]
227+
228
229=== added file 'data/templates/ubuntu-application/store/dialog.py'
230--- data/templates/ubuntu-application/store/dialog.py 1970-01-01 00:00:00 +0000
231+++ data/templates/ubuntu-application/store/dialog.py 2010-11-12 00:33:04 +0000
232@@ -0,0 +1,125 @@
233+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
234+# Copyright 2009 Didier Roche
235+#
236+# This file is part of Quickly ubuntu-application template
237+#
238+#This program is free software: you can redistribute it and/or modify it
239+#under the terms of the GNU General Public License version 3, as published
240+#by the Free Software Foundation.
241+
242+#This program is distributed in the hope that it will be useful, but
243+#WITHOUT ANY WARRANTY; without even the implied warranties of
244+#MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
245+#PURPOSE. See the GNU General Public License for more details.
246+
247+#You should have received a copy of the GNU General Public License along
248+#with this program. If not, see <http://www.gnu.org/licenses/>.
249+
250+import os
251+import sys
252+argv = sys.argv
253+
254+import gettext
255+from gettext import gettext as _
256+# set domain text
257+gettext.textdomain('quickly')
258+
259+import internal.quicklyutils as quicklyutils
260+from quickly import configurationhandler, templatetools, commands
261+
262+option = 'quickly add dialog <dialog-name>'
263+
264+help_text= _("""Here, dialog-name is one or more words separated with dash
265+
266+For instance $ quickly add dialog dialog-name will create:
267+1. A subclass of gtk.Dialog called DialogNameDialog in the module
268+ DialogNameDialog.py
269+2. A glade file called DialogNameDialog.ui in the ui directory
270+3. A catalog file called dialog_name_dialog.xml also in the ui directory
271+
272+To edit the UI for the dialog, run:
273+$ quickly design
274+
275+To edit the behavior, run:
276+$ quickly edit
277+
278+To use the dialog you have to invoke it from another python file:
279+1. Import the dialog
280+import DialogNameDialog
281+
282+2. Create an instance of the dialog
283+dialog = DialogNameDialog.NewDialogNameDialog()
284+
285+3. Run the dialog and hide the dialog
286+result = dialog.run()
287+dialog.hide()""")
288+
289+def add(options):
290+ if len(argv) != 3:
291+ templatetools.print_usage(options['dialog'])
292+ sys.exit(4)
293+
294+ try:
295+ dialog_name = templatetools.quickly_name(argv[2])
296+ except templatetools.bad_project_name, e:
297+ print(e)
298+ sys.exit(1)
299+
300+ abs_template_path = templatetools.get_template_path_from_project()
301+ abs_command_path = os.path.abspath(os.path.dirname(sys.argv[0]))
302+
303+ if not configurationhandler.project_config:
304+ configurationhandler.loadConfig()
305+ project_name = configurationhandler.project_config['project']
306+
307+ template_ui_dir = os.path.join(abs_template_path, 'store', 'data', 'ui')
308+ template_python_dir = os.path.join(abs_template_path, 'store', 'python')
309+ # take files from command directory if don't exist
310+ origin_ui_file_list = [os.path.join(template_ui_dir,
311+ 'dialog_camel_case_nameDialog.ui'),
312+ os.path.join(template_ui_dir,
313+ 'dialog_python_name_dialog.xml')]
314+ python_file = os.path.join(template_ui_dir,
315+ 'dialog_camel_case_nameDialog.py')
316+ if len([file_exist for file_exist in origin_ui_file_list if
317+ os.path.isfile(file_exist)]) != len(origin_ui_file_list):
318+ template_ui_dir = os.path.join(abs_command_path, 'store', 'data',
319+ 'ui')
320+ if not os.path.isfile(python_file):
321+ template_python_dir = os.path.join(abs_command_path, 'store',
322+ 'python')
323+
324+ target_ui_dir = os.path.join('data', 'ui')
325+ python_name = templatetools.python_name(project_name)
326+ target_python_dir = python_name
327+
328+ dialog_python_name = templatetools.python_name(dialog_name)
329+ dialog_sentence_name, dialog_camel_case_name = \
330+ quicklyutils.conventional_names(dialog_name)
331+ project_sentence_name, project_camel_case_name = \
332+ quicklyutils.conventional_names(project_name)
333+ dialog_name = dialog_name.replace('-','_')
334+
335+ substitutions = (("project_name",project_name),
336+ ("dialog_name",dialog_name),
337+ ("dialog_python_name",dialog_python_name),
338+ ("dialog_camel_case_name",dialog_camel_case_name),
339+ ("project_camel_case_name",project_camel_case_name),
340+ ("project_sentence_name",project_sentence_name),
341+ ("dialog_sentence_name",dialog_sentence_name),
342+ ("python_name",python_name))
343+
344+ quicklyutils.file_from_template(template_ui_dir,
345+ "dialog_camel_case_nameDialog.ui",
346+ target_ui_dir,
347+ substitutions)
348+
349+ quicklyutils.file_from_template(template_ui_dir,
350+ "dialog_python_name_dialog.xml",
351+ target_ui_dir,
352+ substitutions)
353+
354+ quicklyutils.file_from_template(template_python_dir,
355+ "dialog_camel_case_nameDialog.py",
356+ target_python_dir,
357+ substitutions)
358
359=== added file 'data/templates/ubuntu-application/store/indicator.py'
360--- data/templates/ubuntu-application/store/indicator.py 1970-01-01 00:00:00 +0000
361+++ data/templates/ubuntu-application/store/indicator.py 2010-11-12 00:33:04 +0000
362@@ -0,0 +1,68 @@
363+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
364+# Copyright 2009 Didier Roche
365+#
366+# This file is part of Quickly ubuntu-application template
367+#
368+#This program is free software: you can redistribute it and/or modify it
369+#under the terms of the GNU General Public License version 3, as published
370+#by the Free Software Foundation.
371+
372+#This program is distributed in the hope that it will be useful, but
373+#WITHOUT ANY WARRANTY; without even the implied warranties of
374+#MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
375+#PURPOSE. See the GNU General Public License for more details.
376+
377+#You should have received a copy of the GNU General Public License along
378+#with this program. If not, see <http://www.gnu.org/licenses/>.
379+
380+import os
381+import sys
382+argv = sys.argv
383+
384+import gettext
385+from gettext import gettext as _
386+# set domain text
387+gettext.textdomain('quickly')
388+
389+import internal.quicklyutils as quicklyutils
390+from quickly import configurationhandler, templatetools, commands
391+
392+option = 'quickly add indicator'
393+
394+help_text=_("""
395+$ quickly add indicator
396+
397+This will add support for Ubuntu Application Indicator to you quickly project.
398+Next time you run your app, the Indicator will show up in the panel on top right.
399+You can add/remove/modify items from the indicator menu by editing indicator.py
400+""")
401+
402+def add(options):
403+ if len(argv) != 2:
404+ templatetools.print_usage(options['indicator'])
405+ sys.exit(4)
406+
407+ abs_template_path = templatetools.get_template_path_from_project()
408+ abs_command_path = os.path.abspath(os.path.dirname(sys.argv[0]))
409+
410+ if not configurationhandler.project_config:
411+ configurationhandler.loadConfig()
412+ project_name = configurationhandler.project_config['project']
413+
414+ template_python_dir = os.path.join(abs_template_path, 'store', 'python')
415+ # take files from command directory if don't exist
416+ python_file = os.path.join(template_python_dir,
417+ 'indicator.py')
418+ python_name = templatetools.python_name(project_name)
419+ target_python_dir = python_name
420+
421+ project_sentence_name, project_camel_case_name = \
422+ quicklyutils.conventional_names(project_name)
423+
424+ substitutions = (("project_name",project_name),
425+ ( "python_name",python_name))
426+
427+ quicklyutils.file_from_template(template_python_dir,
428+ "indicator.py",
429+ target_python_dir,
430+ substitutions)
431
432=== modified file 'data/templates/ubuntu-application/test/add.sh'
433--- data/templates/ubuntu-application/test/add.sh 2010-10-15 20:26:19 +0000
434+++ data/templates/ubuntu-application/test/add.sh 2010-11-12 00:33:04 +0000
435@@ -12,7 +12,13 @@
436 cd test-project
437
438 quickly add
439-# ERROR: No action name provided.
440+# ERROR: Cannot add, no plugin name provided.
441+# Usage:
442+# quickly add dialog <dialog-name>
443+# quickly add indicator
444+
445+quickly add foo
446+# ERROR: Cannot add, did not recognize plugin name: foo
447 # Usage:
448 # quickly add dialog <dialog-name>
449 # quickly add indicator

Subscribers

People subscribed via source and target branches