ascii_invoicer 2.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 186d774a2d826b6b83265d7597ebb7009a321d4f
4
+ data.tar.gz: f94639520acbbcee90c511f7539442dd7f7602f6
5
+ SHA512:
6
+ metadata.gz: 4e3d3887e9432fde377decb43b2a2e44383ee73ea04cbe0b75069cb5623a2f095ab95388f6633a676bba7e057f2c64bc63ca1c92f9dd4b3674bbe5aa6d7f49b3
7
+ data.tar.gz: 9865ad5aea22a6e4b8e6f42ffa73f571ae0410014da6c3286646409d55e415aeb8f3b8b81dca227fa9dc67287d8627c6e7e13a510a51d316739664b3316a0818
data/bin/ascii ADDED
@@ -0,0 +1,722 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pp'
4
+ require 'csv'
5
+ require 'yaml'
6
+ require 'thor'
7
+ require 'euro'
8
+ require 'paint'
9
+ require 'luigi'
10
+ require 'logger'
11
+ require 'textboxes'
12
+ require 'hash-graft'
13
+
14
+ #finding myself
15
+ $SCRIPT_PATH = File.split(File.expand_path(__FILE__))[0]
16
+ $GEM_PATH = File.split($SCRIPT_PATH)[0]
17
+
18
+ #require my libraries
19
+ require "#{$GEM_PATH}/lib/ascii_invoicer"
20
+
21
+ # initialize settings
22
+ settingsmanager = SettingsManager.new({
23
+ :homedir_path => File.join(Dir.home, ".ascii-invoicer.yml"),
24
+ :template_path => File.join($GEM_PATH, "/settings/settings_template.yml"),
25
+ :default_path => File.join($GEM_PATH, "/settings/default-settings.yml")
26
+ })
27
+ $SETTINGS = settingsmanager.settings
28
+
29
+ #initialize global logger
30
+ $logger = AsciiLogger.new "Ascii-Invoicer", $SETTINGS.log_file
31
+
32
+ ## path to the source code
33
+ $SETTINGS.script_path = $SCRIPT_PATH
34
+ $SETTINGS.gem_path = $GEM_PATH
35
+
36
+ ## Version of the software
37
+ $SETTINGS.version = $VERSION = AsciiInvoicer::VERSION
38
+
39
+ ## path to the project File, here we expand the "~"
40
+ $SETTINGS.path = File.expand_path $SETTINGS.path
41
+
42
+
43
+ ## "security"
44
+ #error "settings:editor is an elaborate string: \"#{$SETTINGS.editor}\"!\nDANGEROUS!" if $SETTINGS.editor.include? " "
45
+ $logger.error "settings:latex is an elaborate string: \"#{$SETTINGS.latex}\"!\nDANGEROUS!" if $SETTINGS.latex.include? " "
46
+ $logger.error "settings:output_path is an elaborate string: \"#{$SETTINGS.output_path}\"!\nDANGEROUS!" if $SETTINGS.output_path.include? " "
47
+
48
+
49
+ ## bootstraping the plumber, first run creates all folders
50
+ unless File.exists? $SETTINGS.path
51
+ $logger.fatal "path #{$SETTINGS.path} does not exists"
52
+ exit
53
+ end
54
+ $PLUMBER = Luigi.new $SETTINGS, InvoiceProject
55
+ $PLUMBER.create_dir :storage unless $PLUMBER.check_dir :storage
56
+ $PLUMBER.create_dir :working unless $PLUMBER.check_dir :working
57
+ $PLUMBER.create_dir :archive unless $PLUMBER.check_dir :archive
58
+ $PLUMBER.create_dir :templates unless $PLUMBER.check_dir :templates
59
+ $logger.error "template not found!\n#{$PLUMBER.dirs[:templates]}" unless $PLUMBER.check_dir :templates
60
+
61
+ $SETTINGS.plumber_dirs = $PLUMBER.dirs
62
+
63
+
64
+
65
+ ## here coms thor
66
+ class Commander < Thor
67
+ include Thor::Actions
68
+ include AsciiInvoicer
69
+ include AsciiMixins
70
+
71
+
72
+ package_name "ascii invoicer"
73
+ #argument :first, :type => :numeric
74
+ map "-l" => :list
75
+ map "l" => :list
76
+ map "o" => :offer
77
+ map "ls" => :list
78
+ map "dir" => :list
79
+ map "show" => :display
80
+ map "-d" => :display
81
+ map "close" => :archive
82
+ map "-i" => :invoice
83
+ map "-o" => :offer
84
+ map "-V" => :version
85
+ map "--version" => :version
86
+ map "config" => :settings
87
+ map "history" => :log
88
+ #map "-e" => :edit #depricated
89
+
90
+ class_option :verbose, :aliases=> "-v", :type => :boolean, :default => $SETTINGS.verbose, :desc => "Change default in #{$SETTINGS.settings_homedir_path}"
91
+ #class_option "keep-log", :aliases=> "-k", :type => :boolean
92
+
93
+ no_commands{
94
+ def open_projects(names, options)
95
+ $SETTINGS.verbose = true if options[:verbose]
96
+ if options[:file]
97
+ return [InvoiceProject.new({path => options[:file], settings => $SETTINGS})]
98
+
99
+ else
100
+ if options[:all]
101
+ available_projects = $PLUMBER.open_projects_all()
102
+ elsif options[:archive]
103
+ available_projects = $PLUMBER.open_projects_archive(options[:archive])
104
+ else
105
+ available_projects = $PLUMBER.open_projects_working()
106
+ end
107
+
108
+ projects = names.map{|name|
109
+ if name.class == String and name =~ /^\d*$/
110
+ available_projects[ (name.to_i - 1) ]
111
+ else
112
+ (available_projects.lookup_by_name name) + (available_projects.lookup_by_index name)
113
+ end
114
+ }.flatten.uniq
115
+ if projects.count < 1
116
+ $logger.error "Nothing found, containing #{names}."
117
+ #exit
118
+ end
119
+ return projects.select{|p|p}
120
+
121
+ end
122
+ end
123
+
124
+ def render_projects(projects, type, options)
125
+ projects.each{|project|
126
+ if project.validate type or options[:force]
127
+ puts "% RENDERING"
128
+ project.create_tex(type, options[:stdout]) unless project.nil?
129
+ else
130
+ $logger.error "Cannot create an #{type.to_s} from \"#{project.name}\". No valid #{type}: #{project.blockers(type).join ','})"
131
+ end
132
+ }
133
+ end
134
+ }
135
+
136
+
137
+ desc "new NAME", "Creating a new project"
138
+ method_option :dont_edit, :type=>:boolean, :aliases => "-d",
139
+ :lazy_default=> true, :required => false, :desc => "do not edit a new file after creation"
140
+ method_option :template, :type=>:string, :aliases => "-t",
141
+ :default => "default", :required => false, :desc => "specify a template"
142
+ method_option :editor, :type => :string, :aliases => '-e',
143
+ :default => $SETTINGS.editor, :desc => "specify which editor to use, see #{$SETTINGS.settings_homedir_path}"
144
+ def new(name)
145
+ template = options[:template].to_sym
146
+ unless $PLUMBER.templates.keys.include? template
147
+ $logger.fatal "There is not such template \"#{template}\" "
148
+ exit
149
+ end
150
+
151
+ project = $PLUMBER.new_project name, template
152
+ if project
153
+ puts project.path
154
+ puts "creating a new project name #{name}" if project
155
+ edit_files $PLUMBER.get_project_file_path name unless options[:dont_edit]
156
+ else
157
+ puts "was not able to create #{name}"
158
+ end
159
+ end
160
+
161
+
162
+ desc "edit NAMES", "Edit project"
163
+ method_option :settings, :type=>:boolean, :aliases => '-s',
164
+ :lazy_default=> true, :required => false, :desc => "edit settings"
165
+ method_option :archive,
166
+ :type=>:numeric, :aliases => "-a", :default => nil,
167
+ :lazy_default=> Date.today.year, :required => false, :desc => "Open File from archive YEAR"
168
+ method_option :editor, :type => :string, :aliases => '-e',
169
+ :default => $SETTINGS.editor, :desc => "specify which editor to use, see #{$SETTINGS.settings_homedir_path}"
170
+ method_option :template,
171
+ :type=>:string, :aliases => "-t", :default => nil,
172
+ :required => false, :desc => "Edit a template file"
173
+
174
+ def edit( *names )
175
+ if options[:settings]
176
+ paths = [ $SETTINGS.settings_homedir_path ]
177
+ elsif options[:template]
178
+ path = $PLUMBER.templates[ options[:template].to_sym ]
179
+ if not path.nil? and File.exists? path
180
+ paths = [path]
181
+ else
182
+ puts "no such template"
183
+ exit 1
184
+ end
185
+ else
186
+ projects = open_projects names, options
187
+ paths= projects.map{ |project| project.path }
188
+
189
+ if options[:archive]
190
+ map = $PLUMBER.map_project_files_archive(options[:archive])
191
+ else
192
+ map = $PLUMBER.map_project_files_working()
193
+ end
194
+ map.each{|k,v|
195
+ names.each{|name|
196
+ if k.downcase.include? name.downcase
197
+ paths += [v]
198
+ end
199
+ }
200
+ }
201
+ paths.uniq!
202
+
203
+ #pp paths
204
+ $logger.info "opening #{paths}", :stdo
205
+ end
206
+
207
+ if paths.size > 0
208
+ edit_files paths, options[:editor]
209
+ else
210
+ puts "nothing found (#{names})"
211
+ end
212
+ end
213
+
214
+
215
+
216
+ desc "list", "List current Projects"
217
+ method_option :archive,
218
+ :type=>:numeric, :aliases => "-a",
219
+ :lazy_default=> Date.today.year, :required => false, :desc => "list archived projects"
220
+ method_option :archives,
221
+ :type=>:boolean,
222
+ :lazy_default=> true, :required => false, :desc => "lists all years for which there are archives"
223
+ method_option :all, :type=>:boolean,
224
+ :lazy_default=> true, :required => false, :desc => "lists all projects, ever"
225
+ method_option :templates, :type=>:boolean,
226
+ :lazy_default=> true, :required => false, :desc => "lists all templates"
227
+ method_option :paths, :type=>:boolean, :aliases => '-p',
228
+ :lazy_default=> true, :required => false, :desc => "list paths to .yml files"
229
+
230
+
231
+ method_option :csv, :type=>:boolean,
232
+ :lazy_default=> true, :required => false, :desc => "output as csv"
233
+ method_option :sort, :type=>:string,
234
+ :required => false, :desc => "sort by [date | index | name | manager]",
235
+ :enum => ['date' , 'index', 'name', 'manager']
236
+
237
+ method_option :final, :type=>:boolean,
238
+ :lazy_default=> true, :required => false, :desc => "list shows final sum"
239
+
240
+ method_option :caterers, :type=>:boolean,
241
+ :lazy_default=> true, :required => false, :desc => "list caterers"
242
+
243
+ method_option :blockers, :type=>:boolean, :aliases => '-b',
244
+ :lazy_default=> true, :required => false, :desc => "list blockers"
245
+
246
+ method_option :errors, :type=>:boolean, :aliases => '-e',
247
+ :lazy_default=> true, :required => false, :desc => "list errors"
248
+
249
+ method_option :simple, :type=>:boolean, :aliases => '-s',
250
+ :lazy_default=> true, :required => false, :desc => "overrides the verbose setting"
251
+
252
+ method_option :colors, :type=>:boolean, :aliases => '-c', :default => $SETTINGS.colors,
253
+ :lazy_default=> true, :required => false, :desc => "overrides the colors setting"
254
+
255
+ method_option :filter, :type=>:hash, :aliases => '-f',
256
+ :required => false, :desc => "filter by manager, caterer etc (experimental)"
257
+
258
+ method_option :no_colors, :type=>:boolean, :aliases => '-n',
259
+ :lazy_default=> true, :required => false, :desc => "overrides the colors setting"
260
+
261
+ method_option :details, :type=>:array, :aliases => '-d',
262
+ :required => false, :desc => "adds details"
263
+
264
+ method_option :edit, :type=>:array,
265
+ :required => false, :desc => "open all listed files for edit"
266
+
267
+ def list
268
+ hash = {}
269
+ hash[:verbose] = (options[:verbose] and !options[:simple])
270
+ hash[:colors] = (options[:colors] and !options[:no_colors])
271
+ hash[:errors] = options[:errors]
272
+ hash[:blockers] = options[:blockers]
273
+ hash[:caterers] = options[:caterers]
274
+ hash[:details] = options[:details]
275
+
276
+ if options[:paths]
277
+ map = $PLUMBER.map_project_files_working()
278
+ map = $PLUMBER.map_project_files_archive(options[:archive]) if options[:archive]
279
+ table = Textboxes.new
280
+ map.each{|name, path| table.add_row [name, path] }
281
+ puts table
282
+ exit
283
+ end
284
+
285
+ if not options[:sort].nil? and [:date, :name, :index].include? options[:sort].to_sym
286
+ sort = options[:sort].to_sym
287
+ elsif $SETTINGS.list_sort?
288
+ sort = $SETTINGS.list_sort.to_sym
289
+ else
290
+ sort = :date
291
+ end
292
+
293
+ if options[:all]
294
+ projects = $PLUMBER.open_projects_all() #TODO
295
+ elsif options[:archives]
296
+ puts $PLUMBER.map_archive_years.keys
297
+ return
298
+ elsif options[:templates]
299
+ puts $PLUMBER.templates.keys
300
+ return
301
+ elsif options[:archive]
302
+ projects = $PLUMBER.open_projects_archive(options[:archive], sort)
303
+ else
304
+ projects = $PLUMBER.open_projects_working(sort)
305
+ end
306
+
307
+ if options[:filter]
308
+ projects = $PLUMBER.filter_by projects, options[:filter]
309
+ end
310
+
311
+ if options[:csv]
312
+ projects = $PLUMBER.sort_projects(projects, :index)
313
+ print_project_list_csv projects
314
+ elsif options[:yaml]
315
+ print_project_list_yaml projects
316
+ else
317
+ print_project_list(projects, hash)
318
+ end
319
+
320
+ if options[:edit]
321
+ all_paths= projects.map { |project| project.path }
322
+
323
+ paths = options[:edit].map{|index| all_paths[index.to_i-1] }
324
+ puts paths
325
+
326
+ if paths.size > 0
327
+ edit_files paths, options[:editor]
328
+ else
329
+ puts "nothing found (#{names})"
330
+ end
331
+ end
332
+ end
333
+
334
+ desc "templates", "List or add templates"
335
+ method_option :add, :type=>:boolean,
336
+ :lazy_default=> true, :required => false, :desc => "Adds template changes to index just like ascii add does to projects."
337
+
338
+ def templates
339
+ if options[:add]
340
+ path = $PLUMBER.dirs[:templates]
341
+ $PLUMBER.git_update_path(path) if $PLUMBER.open_git()
342
+ else
343
+ puts $PLUMBER.templates.keys
344
+ end
345
+ end
346
+
347
+ desc "csv", "Equal to: ascii list --all --csv --sort=index --filter event/date:#{Date.today.year}"
348
+ method_option :year,
349
+ :type=>:numeric, :aliases => "-y",
350
+ :default=> Date.today.year, :required => false, :desc => "Year to export"
351
+ def csv
352
+ invoke :list, [], csv:true, all:true, sort:"index", filter:{"event/date"=>options[:year].to_s}# where is this documented
353
+ end
354
+
355
+ desc "search QUERY", "Search everything, only one query currently"
356
+ def search *queries
357
+ queries.map!{|query|
358
+ path, term = query.split ?:
359
+ {path => term}
360
+ }
361
+ puts "#{queries[0].keys[0]}: #{queries[0].values[0]}"
362
+ invoke :list, [], all:true, filter:queries[0]#, details:queries[0].keys
363
+ end
364
+
365
+ desc "whoami", "Invoke settings --show manager_name"
366
+ def whoami
367
+ invoke :settings, [], show:"manager_name"
368
+ end
369
+
370
+ desc "calendar", "Create a calendar file from all caterings named \"invoicer.ics\""
371
+ def calendar
372
+ projects = $PLUMBER.open_projects_all()
373
+ valid = true
374
+ projects.each{|project|
375
+ unless project.validate(:calendar)
376
+ valid = false
377
+ $logger.error "error in event/date in \"#{project.name}\""
378
+ end
379
+
380
+ }
381
+ unless valid
382
+ $logger.error "Can't create Calendar."
383
+ exit
384
+ end
385
+ create_cal_file $PLUMBER.open_projects_all()
386
+ end
387
+
388
+
389
+
390
+ desc "archive NAME", "Move project to archive"
391
+ method_option :force,:type=>:boolean,
392
+ :lazy_default=> true, :required => false,
393
+ :desc => "Force archiving projects that are invalid."
394
+ def archive( *names )
395
+ projects = open_projects names, options
396
+ project = projects[0]
397
+ return false unless project
398
+
399
+ year = project.date.year
400
+ prefix = project.data[:invoice][:number]
401
+ prefix ||= ""
402
+ prefix += "canceled" if project.data[:canceled]
403
+
404
+ puts options
405
+
406
+ unless project.validate(:archive) or options[:force] or project.data[:canceled]
407
+ $logger.error "\"#{project.name}\" contains errors\n(#{project.errors.join(',')})"
408
+ else
409
+ new_path = $PLUMBER.archive_project project, Date.today.year, prefix
410
+ puts new_path
411
+ end
412
+ end
413
+
414
+ desc "reopen YEAR NAME", "reopen an archived project"
415
+ def reopen(year, name)
416
+ projects = $PLUMBER.open_projects_archive year
417
+ project = projects.lookup_by_name name
418
+ if project.count > 1
419
+ $logger.error "Ambigous results"
420
+ puts project
421
+ exit
422
+ else
423
+ project = project[0]
424
+ puts project.path
425
+ end
426
+
427
+ #unless $PLUMBER.unarchive_project project, year
428
+ # $logger.error "Can't unarchive #{name}, checks names of current projects for duplicates!"
429
+ #end
430
+ end
431
+
432
+
433
+
434
+
435
+
436
+
437
+ desc "display NAMES", "Shows information about a project in different ways"
438
+ method_option :archive,
439
+ :type=>:numeric, :aliases => "-a",
440
+ :default => nil,
441
+ :lazy_default=> Date.today.year,
442
+ :required => false,
443
+ :desc => "Select File from archive YEAR"
444
+ method_option :all, :type=>:boolean,
445
+ :default=> false, :lazy_default=> true, :required => false,
446
+ :desc => "Select File from any archive and current working directory "
447
+ method_option :name, :type=>:boolean,
448
+ :default=> false, :lazy_default=> true, :required => false,
449
+ :desc => "Display only the name"
450
+ method_option :offer, :type=>:boolean,
451
+ :default=> false, :lazy_default=> true, :required => false,
452
+ :desc => "Display the offer"
453
+ method_option :invoice, :type=>:boolean,
454
+ :default=> false, :lazy_default=> true, :required => false,
455
+ :desc => "Display the invoice"
456
+ method_option :csv, :type=>:boolean, :aliases => '-c',
457
+ :lazy_default=> true, :required => false, :desc => "show as csv"
458
+ method_option :errors, :type=>:boolean, :aliases => '-e',
459
+ :lazy_default=> true, :required => false, :desc => "show errors in footer"
460
+ method_option :products, :type=>:boolean,
461
+ :default=> false, :lazy_default=> true, :required => false,
462
+ :desc => "Display only the products for the --offer or --invoice"
463
+ method_option :caterers, :type=>:boolean,
464
+ :default=> false, :lazy_default=> true, :required => false,
465
+ :desc => "Display Caterers"
466
+ method_option :raw,:type=>:boolean,
467
+ :default=> false, :lazy_default=> true, :required => false,
468
+ :desc => ""
469
+ method_option :costs,:type=>:boolean,
470
+ :default=> false, :lazy_default=> true, :required => false,
471
+ :desc => ""
472
+ method_option :detail, :type=>:string, :banner => "key", :aliases =>"-d",
473
+ :default => nil, :lazy_default=> "", :required => false,
474
+ :desc => "output key or all with pp"
475
+ method_option :pp, :type=>:string, :banner => "key",
476
+ :default => nil, :lazy_default=> "", :required => false,
477
+ :desc => "output key or all with pp"
478
+ # method_option :yaml, :type=>:string, :banner => "key",
479
+ # :default => nil, :lazy_default=> "", :required => false,
480
+ # :desc => "output key or all as yaml"
481
+ method_option :cal, :type=>:boolean,
482
+ :default => nil, :lazy_default=> "", :required => false,
483
+ :desc => "output key or all as ical event[s]"
484
+ def display(*names)
485
+ projects = open_projects names, options
486
+
487
+ projects.each{ |project|
488
+ $logger.error("No project found!") if project.nil?
489
+ unless options[:cal] or options[:yaml] or options[:costs] or options[:caterers] or options[:invoice] or options[:offer] or options[:products]
490
+ fallback= true
491
+ end
492
+
493
+ if not options[:yaml].nil?
494
+ if options[:yaml] == ''
495
+ puts project.data.to_yaml
496
+ else
497
+ puts project.data.get_path(options[:yaml]).to_yaml
498
+ end
499
+ elsif options[:name]
500
+ puts project.name
501
+ elsif options[:csv]
502
+ display_products_csv project
503
+ elsif options[:raw]
504
+ raw = project.raw_data
505
+ raw.delete "cataloge"
506
+ puts raw.to_yaml
507
+ elsif not options[:detail].nil?
508
+ if options[:detail] == ''
509
+ puts project.data
510
+ else
511
+ puts project.data.get_path(options[:detail])
512
+ end
513
+ elsif not options[:pp].nil?
514
+ if options[:pp] == ''
515
+ pp project.data
516
+ else
517
+ pp project.data.get_path(options[:pp])
518
+ end
519
+ else
520
+ if options[:products]
521
+ puts display_products(project, :offer )
522
+ puts display_products(project, :invoice) if options[:invoice]
523
+ else
524
+ puts display_all(project, :offer , options[:errors]) if options[:offer ]
525
+ puts display_all(project, :invoice, options[:errors]) if options[:invoice] or fallback
526
+ end
527
+ if options[:cal]
528
+ project.data[:event][:calendaritems].each{|cal|
529
+ puts cal.to_ical
530
+ }
531
+ end
532
+ if options[:caterers]
533
+ print "#{project.name}:".ljust(35) if names.length > 1
534
+ if project.data[:hours][:caterers]
535
+ puts project.data[:hours][:caterers].map{|name, hours| "#{name} (#{hours})"}.join(", ")
536
+ else
537
+ puts "Caterers is empty"
538
+ end
539
+ end
540
+ end
541
+ }
542
+ end
543
+
544
+ desc "offer NAMES", "Create an offer from project"
545
+ method_option :archive,
546
+ :type=>:numeric, :aliases => "-a",
547
+ :default => nil,
548
+ :lazy_default=> Date.today.year,
549
+ :required => false,
550
+ :desc => "Open File from archive YEAR"
551
+ method_option :stdout,
552
+ :type=>:numeric, :aliases => "-s",
553
+ :lazy_default=> true,
554
+ :required => false,
555
+ :desc => "print tex to stdout"
556
+ method_option :force,:type=>:boolean,
557
+ :lazy_default=> true, :required => false,
558
+ :desc => "Ignore validator."
559
+ def offer(*names)
560
+ projects = open_projects names, options
561
+ render_projects projects, :offer, options
562
+ end
563
+
564
+ desc "invoice NAMES", "Create an invoice from project"
565
+ method_option :archive,
566
+ :type=>:numeric, :aliases => "-a",
567
+ :default => nil,
568
+ :lazy_default=> Date.today.year,
569
+ :required => false,
570
+ :desc => "Open File from archive YEAR"
571
+ method_option :stdout,
572
+ :type=>:numeric, :aliases => "-s",
573
+ :lazy_default=> true,
574
+ :required => false,
575
+ :desc => "print tex to stdout"
576
+ method_option :force,:type=>:boolean,
577
+ :lazy_default=> true, :required => false,
578
+ :desc => "Ignore validator."
579
+ def invoice( *names)
580
+ projects = open_projects names, options
581
+ render_projects projects, :invoice, options
582
+ end
583
+
584
+
585
+
586
+
587
+
588
+
589
+ desc "status", "Git Integration"
590
+ def status
591
+ $PLUMBER.git_status() if $PLUMBER.open_git()
592
+ end
593
+
594
+
595
+ desc "add NAMES", "Git Integration"
596
+ method_option :template,
597
+ :type=>:string, :aliases => "-t", :default => nil,
598
+ :required => false, :desc => "Adds a template file"
599
+ method_option :archive,
600
+ :type=>:numeric, :aliases => "-a",
601
+ :default => nil,
602
+ :lazy_default=> Date.today.year,
603
+ :required => false,
604
+ :desc => "Add File from archive YEAR"
605
+
606
+ def add *names
607
+ if options[:template]
608
+ path = $PLUMBER.templates[ options[:template].to_sym ]
609
+ if not path.nil? and File.exists? path
610
+ $PLUMBER.git_update_path(path) if $PLUMBER.open_git()
611
+ end
612
+ end
613
+
614
+ projects = open_projects names, options
615
+ projects.each {|project|
616
+ path = project.project_folder
617
+ if not path.nil? and File.exists? path
618
+ $PLUMBER.git_update_path(path) if $PLUMBER.open_git()
619
+ end
620
+ }
621
+ status()
622
+ end
623
+
624
+ desc "commit", "Git Integration"
625
+ method_option :message,
626
+ :type=>:string, :aliases => "-m", :default => nil,
627
+ :lazy_default=> Date.today.year, :required => true,
628
+ :desc => "Open File from archive YEAR"
629
+ def commit
630
+ $PLUMBER.git_commit(options[:message]) if $PLUMBER.open_git()
631
+ end
632
+
633
+ desc "push", "Git Integration"
634
+ def push
635
+ $PLUMBER.git_push() if $PLUMBER.open_git()
636
+ end
637
+
638
+ desc "pull", "Git Integration"
639
+ def pull
640
+ $PLUMBER.git_pull() if $PLUMBER.open_git()
641
+ end
642
+
643
+ desc "log", "Git Integration"
644
+ method_option :count,
645
+ :type=>:numeric, :aliases => "-c",
646
+ :default => 30,
647
+ :lazy_default=> 1000,
648
+ :required => false,
649
+ :desc => "Max count of history entries"
650
+ def log
651
+ $PLUMBER.git_log(options[:count]) if $PLUMBER.open_git()
652
+ end
653
+
654
+
655
+
656
+
657
+
658
+ desc "settings", "View settings"
659
+ method_option :edit,
660
+ :type=>:boolean, :aliases => "-e",
661
+ :lazy_default=> false,
662
+ :required => false,
663
+ :desc => "edit your settings"
664
+ method_option :show,
665
+ :type=>:string, :aliases => "-s",
666
+ :required => false,
667
+ :desc => "show a specific settings value"
668
+
669
+ def settings
670
+
671
+ if options[:edit]
672
+ edit_files $SETTINGS.settings_homedir_path
673
+ elsif options[:show]
674
+ value = $SETTINGS.get_path options[:show]
675
+ if value.class == Hash or value.class == Array
676
+ puts value.to_yaml
677
+ elsif value.class == Hashr
678
+ puts value.to_hash.to_yaml
679
+ else
680
+ puts value
681
+ end
682
+ else
683
+ puts $SETTINGS.to_hash.to_yaml
684
+ end
685
+ #pp $SETTINGS
686
+ end
687
+
688
+ desc "path", "Return projects storage path"
689
+ method_option :templates, :type=>:boolean, :aliases => '-t',
690
+ :lazy_default=> true, :required => false, :desc => "returns templates path"
691
+ method_option :output, :type=>:boolean, :aliases => '-o',
692
+ :lazy_default=> true, :required => false, :desc => "returns output path"
693
+ method_option :script, :type=>:boolean,
694
+ :lazy_default=> true, :required => false, :desc => "returns script path"
695
+ def path
696
+ if options[:script]
697
+ puts File.split($GEM_PATH)[0]
698
+ elsif options[:output]
699
+ puts File.expand_path File.join $SETTINGS.output_path
700
+ elsif options[:templates]
701
+ puts $PLUMBER.dirs[:templates]
702
+ else
703
+ puts File.join $SETTINGS.path, $SETTINGS.dirs.storage
704
+ end
705
+ end
706
+
707
+ desc "output", "Equal to: ascii path --output"
708
+ def output
709
+ invoke :path, [], output:true
710
+ end
711
+
712
+ desc "version", "Display version"
713
+ method_option :changed_files, :type=>:boolean, :aliases => '-c',
714
+ :lazy_default=> true, :required => false, :desc => "show changed files"
715
+ method_option :fetch, :type=>:boolean, :aliases => '-f',
716
+ :lazy_default=> true, :required => false, :desc => "update new code (FETCH ONLY != pull)"
717
+ def version
718
+ puts "ascii-invoicer v#{$VERSION}"
719
+ end
720
+ end
721
+
722
+ Commander.start