Merge lp:~tony-badwolf/quickly/modular_add into lp:quickly
- modular_add
- Merge into trunk
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michael Terry (community) | Needs Fixing | ||
Review via email: mp+40387@code.launchpad.net |
Commit message
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.
- 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.
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.
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.<
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.
> 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'
> 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.
> argv[1]), cmd=cmd, template=
>
> 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.
>
> 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:/
> You are the owner of lp:~tony-badwolf/quickly/modular_add.
>
Preview Diff
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 |
Neat, thanks Tony! This does seem easier to work with for the future.
77 + help_list = ['Add something to your project\n'] append( getattr( store, module).help_text)
78 + for module in addable:
79 + try:
80 + help_list.
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