jtag 0.1.7 → 0.1.15

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
+ SHA256:
3
+ metadata.gz: 3e151ce3931cae97e33b988fbb68d8f11d061b6082533675c9d77523a4a8f0d5
4
+ data.tar.gz: 4533ce25468f2c79e6a847656a60d73e6bd5c262339604d7be95932cf60e6f29
5
+ SHA512:
6
+ metadata.gz: afe50224a4bd699348a3fe249030b2b7cd990c0a3862fa8362be80ee27bf1a59b348af3fa4e451ec24a021a4a8278fd8cae55a1dac46abfdacad14773b461cfb
7
+ data.tar.gz: 2298a87e7d680f2a9a2f411af69106095ca3c9d2c5b181d8ca8eb96cb467911e9ed8efe0cb70a1c51bdf80f9d1f62a47e8ca8f48fd29c6c457af885ba6e258bd
data/bin/jtag CHANGED
@@ -22,19 +22,33 @@ end
22
22
  desc 'Debug level'
23
23
  default_value '0'
24
24
  arg_name 'debug_level'
25
- flag [:d,:debug]
25
+ flag [:d,:debug], :must_match => /\d+/, :type => Integer, :default_value => 0
26
26
 
27
27
  desc 'Run silently'
28
- switch [:s,'silent']
28
+ switch [:s,:silent]
29
29
 
30
- desc "Test (Dry run, don't update files)"
30
+ desc 'Perform case-insensitive matches and searches'
31
+ switch [:i,:case_insensitive]
32
+
33
+ desc "Test (dry run, don't update files)"
31
34
  long_desc "Run all commands and show results on the command line, but don't overwrite/update any files"
32
35
  default_value false
33
- switch [:t,'test']
36
+ switch [:t,:test]
34
37
 
35
38
  def console_log(msg="", options={})
36
- return if @silent
37
39
  err = options[:err] || false
40
+ options[:log] ||= false
41
+
42
+ if options[:log]
43
+ if err
44
+ @log.warn(msg)
45
+ else
46
+ @log.info(msg)
47
+ end
48
+ end
49
+
50
+ return if @silent
51
+
38
52
  unless err
39
53
  $stdout.puts msg
40
54
  else
@@ -93,10 +107,10 @@ desc 'List tags, optionally filter for keywords/regular expressions (OR)'
93
107
  long_desc 'This command can be used to find the exact format for a given tag to keep spaces, underscores, capitalization and pluralization consistent'
94
108
  arg_name 'keyword', :multiple
95
109
  command :search do |c|
96
- c.desc 'Format to use when outputting tags to console: list, json, csv or yaml. Defaults to yaml.'
110
+ c.desc 'Format to use when outputting tags to console: list, json, plist, csv or yaml. Defaults to yaml.'
97
111
  c.arg_name 'output_format'
98
112
  c.default_value 'yaml'
99
- c.flag [:f,:format], :must_match => /^(csv|list|yaml|json)$/i, :type => String
113
+ c.flag [:f,:format], :must_match => /^(csv|list|yaml|json|plist)$/i, :type => String
100
114
 
101
115
  c.desc 'Include tag counts'
102
116
  c.arg_name 'counts'
@@ -106,8 +120,8 @@ command :search do |c|
106
120
  c.action do |global_options,options,args|
107
121
  tags = @jt.get_tags({:counts => true})
108
122
  if args.length > 0
123
+ re = args.join("|")
109
124
  tags.delete_if {|tag|
110
- re = args.join("|")
111
125
  if tag && tag['name'] =~ /(#{re})/i
112
126
  false
113
127
  else
@@ -119,7 +133,7 @@ command :search do |c|
119
133
  else
120
134
  tags.map! {|tag| tag['name'] }
121
135
  end
122
- output_tags(tags,options[:format])
136
+ output_tags(tags,{ :format => options[:format] })
123
137
  else
124
138
  tags.delete_if {|tag| !tag }
125
139
  if options[:c]
@@ -127,18 +141,199 @@ command :search do |c|
127
141
  else
128
142
  tags.map! {|tag| tag['name'] }
129
143
  end
130
- output_tags(tags,options[:format])
144
+ output_tags(tags,{ :format => options[:format] })
131
145
  end
132
146
  end
133
147
  end
134
148
 
149
+ desc 'List posts with tag(s)'
150
+ arg_name 'tags', :multiple
151
+ command :posts_tagged do |c|
152
+ c.desc 'Boolean operator for multiple tags (AND/OR/NOT)'
153
+ c.arg_name 'bool'
154
+ c.default_value 'OR'
155
+ c.flag [:b,:bool], :must_match => /(AND|OR|NOT)/i, :type => String
156
+
157
+ c.desc 'Format to use when outputting file list: list, json, plist, csv or yaml. Defaults to list.'
158
+ c.arg_name 'output_format'
159
+ c.default_value 'list'
160
+ c.flag [:f,:format], :must_match => /^(csv|list|yaml|json|plist)$/, :type => String
161
+
162
+ c.desc 'If output format is list, print without newlines.'
163
+ c.switch [:print0]
164
+
165
+ c.action do |global_options,options,args|
166
+ bool = options[:bool].upcase
167
+ files = []
168
+ tags = []
169
+ matches = []
170
+ args.length.times do
171
+ arg = args.pop
172
+ if File.exists?(arg)
173
+ files.push(arg)
174
+ else
175
+ tags.push(arg)
176
+ end
177
+ end
178
+ if files.empty?
179
+ if @jt.default_post_location && File.exists?(File.dirname(@jt.default_post_location))
180
+ files = Dir.glob(@jt.default_post_location)
181
+ end
182
+ end
183
+ exit_now! "No valid filename in arguments" if files.empty?
184
+ files.each {|file|
185
+ if File.exists?(file)
186
+ post_tags = @jt.post_tags(file)
187
+
188
+ if bool == "AND"
189
+ matched = 0
190
+ tags.each {|tag|
191
+ matched += 1 if post_tags.include?(tag)
192
+ }
193
+ matches.push(file) if matched == tags.length
194
+ elsif bool == "NOT"
195
+ matched = false
196
+ tags.each {|tag|
197
+ matched = true if post_tags.include?(tag)
198
+ }
199
+ matches.push(file) unless matched
200
+ else
201
+ tags.each {|tag|
202
+ if post_tags.include?(tag)
203
+ matches.push(file) unless matches.include?(file)
204
+ end
205
+ }
206
+ end
207
+ else
208
+ raise "File not found: #{file}"
209
+ end
210
+ }
211
+
212
+ search_string = tags.join(" #{bool} ")
213
+ if matches.empty?
214
+ console_log "No matching files found for #{search_string}"
215
+ else
216
+ console_log "(#{search_string})", {:err => true}
217
+ output_tags(matches, { :format => options[:format], :print0 => options[:print0], :grouping => "files" })
218
+ end
219
+ end
220
+ end
221
+
222
+ desc 'Show tags with fewer than X posts attached to them, optionally removing them from specified posts'
223
+ arg_name 'file_pattern', :multiple
224
+ command :loners do |c|
225
+ c.desc 'Format to use when outputting tags to console: list, json, plist, csv or yaml. Defaults to yaml.'
226
+ c.arg_name 'output_format'
227
+ c.default_value 'yaml'
228
+ c.flag [:f,:format], :must_match => /^(csv|list|yaml|json|plist)$/, :type => String
229
+
230
+ c.desc 'Upper limit for how many posts a tag can be attached to and still be a loner'
231
+ c.arg_name 'max'
232
+ c.default_value '2'
233
+ c.flag [:m,:max], :default_value => 2, :must_match => /^\d+$/
234
+
235
+ c.desc "Remove tags with fewer than X posts attached"
236
+ c.switch [:r,:remove], :default_value => false
237
+
238
+ c.desc "Display output without attached occurence counts"
239
+ c.switch [:no_counts], :default_value => false
240
+
241
+ c.desc 'Output a file list of tags that can be edited and passed back in for removing'
242
+ c.arg_name 'filename'
243
+ c.flag [:e,:edit], :default_value => false, :type => String
244
+
245
+ c.action do |global_options,options,args|
246
+ max = options[:m].to_i
247
+ loner_tags = @jt.get_tags({:counts => true})
248
+ loner_tags.delete_if { |tag|
249
+ tag.class == FalseClass || tag['count'] > max
250
+ }
251
+ loner_tags.sort_by! {|tag| tag['count']}
252
+
253
+ exit_now! "No tags matched the criteria" if loner_tags.empty? || loner_tags.nil?
254
+
255
+ if options[:e]
256
+ path = File.expand_path(options[:e])
257
+ while File.exists?(path)
258
+ if path =~ /(\d+)(\.[^\.]+?)?$/
259
+ path.sub!(/(\d+)(\.[^\.]+?)?$/) do |m|
260
+ $1.next! + $2
261
+ end
262
+ else
263
+ path.sub!(/(\.[^\.]+?)?$/,'01\1')
264
+ end
265
+ end
266
+ File.open(path, 'w+') do |f|
267
+ f.puts "# Edit this file to remove tags you want to keep,"
268
+ f.puts "# then run `jtag remove -p '#{path}' [/path/to/posts/*.md]`"
269
+ f.puts "# to remove any tags left in the file."
270
+ f.puts "#"
271
+ f.puts "# The post counts are included for your convenience, and will"
272
+ f.puts "# be automatically ignored when reading the list back in."
273
+ f.puts "#"
274
+ f.puts "# Lines beginning with a # are comments (ignored), but you probably figured that out."
275
+ loner_tags.each{ |t|
276
+ f.printf "% 3d |\t%s\n", t['count'], t['name']
277
+ }
278
+ end
279
+
280
+ console_log "A list of results and instructions for use have been written to #{path}."
281
+ if ENV['EDITOR']
282
+ console_log
283
+ print "Would you like to open the file in #{ENV['EDITOR']} now? (y/N) "
284
+ input = STDIN.gets
285
+ if input =~ /^y/i
286
+ system "#{ENV['EDITOR']} '#{path}'"
287
+ end
288
+ end
289
+ elsif options[:r]
290
+ files = []
291
+ args.length.times do
292
+ arg = args.pop
293
+ files.push(arg) if File.exists?(arg)
294
+ end
295
+ if files.empty?
296
+ if @jt.default_post_location && File.exists?(File.dirname(@jt.default_post_location))
297
+ files = Dir.glob(@jt.default_post_location)
298
+ end
299
+ end
300
+ exit_now! "No valid filename in arguments" if files.empty?
301
+ files.each {|file|
302
+ tags = @jt.post_tags(file)
303
+ loner_tags.each { |d|
304
+ tags.delete_if { |tag|
305
+ if global_options[:i]
306
+ tag.downcase == d.downcase
307
+ else
308
+ tag == d
309
+ end
310
+ }
311
+ }
312
+ unless global_options[:t]
313
+ @jt.update_file_tags(file,tags)
314
+ console_log "Updated tags for #{file}", :log => true
315
+ end
316
+
317
+ console_log
318
+ console_log File.basename(file) + ":"
319
+ output_tags(tags, :format => options[:format], :filename => file )
320
+ }
321
+ else
322
+ output_tags(loner_tags.map{|tag|
323
+ count = options[:no_counts] ? "" : " (#{tag['count']})"
324
+ "#{tag['name']}#{count}"}, :format => options[:format] )
325
+ end
326
+ end
327
+ end
328
+
329
+
135
330
  desc 'Show the current tags for posts'
136
- arg_name 'filenames', :multiple
331
+ arg_name 'file_pattern', :multiple
137
332
  command :tags do |c|
138
- c.desc 'Format to use when outputting tags to console: list, json, csv or yaml. Defaults to yaml.'
333
+ c.desc 'Format to use when outputting tags to console: list, json, plist, csv or yaml. Defaults to yaml.'
139
334
  c.arg_name 'output_format'
140
335
  c.default_value 'yaml'
141
- c.flag [:f,:format], :must_match => /^(csv|list|yaml|json)$/, :type => String
336
+ c.flag [:f,:format], :must_match => /^(csv|list|yaml|json|plist)$/, :type => String
142
337
 
143
338
  c.action do |global_options,options,args|
144
339
 
@@ -151,7 +346,7 @@ command :tags do |c|
151
346
  if tags.empty? || tags.nil?
152
347
  console_log "No tags in post", {:err => true}
153
348
  else
154
- output_tags(tags,options[:format])
349
+ output_tags(tags,{ :format => options[:format] })
155
350
  end
156
351
  end
157
352
  args.each{|file|
@@ -164,7 +359,7 @@ command :tags do |c|
164
359
  if tags.empty? || tags.nil?
165
360
  console_log "No tags in post", {:err => true}
166
361
  else
167
- output_tags(tags,options[:format])
362
+ output_tags(tags,{ :format => options[:format], :filename => file })
168
363
  end
169
364
  else
170
365
  raise "File not found: #{file}"
@@ -175,12 +370,12 @@ end
175
370
 
176
371
 
177
372
  desc 'Sort the existing tags for posts'
178
- arg_name 'filenames', :multiple
373
+ arg_name 'file_pattern', :multiple
179
374
  command :sort do |c|
180
- c.desc 'Format to use when outputting tags to console: list, json, csv or yaml. Defaults to yaml.'
375
+ c.desc 'Format to use when outputting tags to console: list, json, plist, csv or yaml. Defaults to yaml.'
181
376
  c.arg_name 'output_format'
182
377
  c.default_value 'yaml'
183
- c.flag [:f,:format], :must_match => /^(csv|list|yaml|json)$/, :type => String
378
+ c.flag [:f,:format], :must_match => /^(csv|list|yaml|json|plist)$/, :type => String
184
379
 
185
380
  c.action do |global_options,options,args|
186
381
  args.each{|file|
@@ -190,14 +385,13 @@ command :sort do |c|
190
385
  unless global_options[:t]
191
386
  @jt.update_file_tags(file, tags)
192
387
  end
193
- if args.length > 1
194
- console_log
195
- console_log File.basename(file) + ":"
196
- end
388
+ console_log
389
+ console_log File.basename(file) + ":"
390
+
197
391
  if tags.empty? || tags.nil?
198
392
  console_log "No tags in post", {:err => true}
199
393
  else
200
- output_tags(tags,options[:format])
394
+ output_tags(tags,{ :format => options[:format], :filename => file })
201
395
  end
202
396
  }
203
397
  end
@@ -207,10 +401,10 @@ desc 'Merge multiple tags into one'
207
401
  long_desc 'Scans the specified posts for any of the tags, merging any found into the last one in the list'
208
402
  arg_name 'tags to merge merge_tag'
209
403
  command :merge do |c|
210
- c.desc 'Format to use when outputting tags to console: list, json, csv or yaml. Defaults to yaml.'
404
+ c.desc 'Format to use when outputting tags to console: list, json, plist, csv or yaml. Defaults to yaml.'
211
405
  c.arg_name 'output_format'
212
406
  c.default_value 'yaml'
213
- c.flag [:f,:format], :must_match => /^(csv|list|yaml|json)$/, :type => String
407
+ c.flag [:f,:format], :must_match => /^(csv|list|yaml|json|plist)$/, :type => String
214
408
 
215
409
  c.action do |global_options, options, args|
216
410
  files = []
@@ -220,11 +414,15 @@ command :merge do |c|
220
414
  if File.exists?(arg)
221
415
  files.push(arg)
222
416
  else
223
- exit_now! "No valid filename in arguments" if files.empty?
224
417
  tags.push(arg)
225
418
  end
226
419
  end
227
-
420
+ if files.empty?
421
+ if @jt.default_post_location && File.exists?(File.dirname(@jt.default_post_location))
422
+ files = Dir.glob(@jt.default_post_location)
423
+ end
424
+ end
425
+ exit_now! "No valid filename in arguments" if files.empty?
228
426
  exit_now! "Needs at least two tag inputs, one or more to merge, one to merge to" if tags.length < 2
229
427
  tags.reverse!
230
428
  merge_tag = tags.pop
@@ -235,11 +433,13 @@ command :merge do |c|
235
433
  unless global_options[:t]
236
434
  @jt.update_file_tags(file, new_tags)
237
435
  console_log
238
- console_log "Updated tags for #{file}"
436
+ console_log "Updated tags for #{file}", :log => true
239
437
  end
438
+
240
439
  console_log
241
440
  console_log File.basename(file) + ":"
242
- output_tags(new_tags,options[:format])
441
+ output_tags(new_tags,{ :format => options[:format], :filename => file })
442
+
243
443
  }
244
444
  end
245
445
  end
@@ -264,11 +464,12 @@ end
264
464
 
265
465
  desc 'Add tags to post(s)'
266
466
  arg_name 'tags', :multiple
467
+ arg_name 'file_pattern'
267
468
  command :add do |c|
268
- c.desc 'Format to use when outputting tags to console: list, json, csv or yaml. Defaults to yaml.'
469
+ c.desc 'Format to use when outputting tags to console: list, json, plist, csv or yaml. Defaults to yaml.'
269
470
  c.arg_name 'output_format'
270
471
  c.default_value 'yaml'
271
- c.flag [:f,:format], :must_match => /^(csv|list|yaml|json)$/, :type => String
472
+ c.flag [:f,:format], :must_match => /^(csv|list|yaml|json|plist)$/, :type => String
272
473
 
273
474
 
274
475
  c.action do |global_options,options,args|
@@ -279,11 +480,15 @@ command :add do |c|
279
480
  if File.exists?(arg)
280
481
  files.push(arg)
281
482
  else
282
- exit_now! "No valid filename in arguments" if files.empty?
283
483
  new_tags.push(arg)
284
484
  end
285
485
  end
286
-
486
+ if files.empty?
487
+ if @jt.default_post_location && File.exists?(File.dirname(@jt.default_post_location))
488
+ files = Dir.glob(@jt.default_post_location)
489
+ end
490
+ end
491
+ exit_now! "No valid filename in arguments" if files.empty?
287
492
  exit_now! "No tags found in arguments" if new_tags.empty?
288
493
 
289
494
  files.each {|file|
@@ -293,12 +498,12 @@ command :add do |c|
293
498
  tags.sort!
294
499
  unless global_options[:t]
295
500
  @jt.update_file_tags(file,tags)
296
- console_log "Updated tags for #{file}"
501
+ console_log "Updated tags for #{file}", :log => true
297
502
  end
298
503
 
299
504
  console_log
300
505
  console_log File.basename(file) + ":"
301
- output_tags(tags,options[:format])
506
+ output_tags(tags, :format => options[:format], :filename => file)
302
507
  }
303
508
  end
304
509
  end
@@ -306,10 +511,15 @@ end
306
511
  desc 'Remove tags from post(s)'
307
512
  arg_name 'tags', :multiple
308
513
  command :remove do |c|
309
- c.desc 'Format to use when outputting tags to console: list, json, csv or yaml. Defaults to yaml.'
514
+ c.desc 'Format to use when outputting tags to console: list, json, plist, csv or yaml. Defaults to yaml.'
310
515
  c.arg_name 'output_format'
311
516
  c.default_value 'yaml'
312
- c.flag [:f,:format], :must_match => /^(csv|list|yaml|json)$/, :type => String
517
+ c.flag [:f,:format], :must_match => /^(csv|list|yaml|json|plist)$/, :type => String
518
+
519
+ c.desc 'A filepath to a list of tags to be removed'
520
+ c.long_desc 'One tag per line, and leading numbers and pipes (|) will be ignored. This file format is generated automatically by the `loners` command, but any text file will do the trick.'
521
+ c.arg_name 'input_file'
522
+ c.flag [:p,:path], :type => String
313
523
 
314
524
  c.action do |global_options,options,args|
315
525
  files = []
@@ -319,37 +529,60 @@ command :remove do |c|
319
529
  if File.exists?(arg)
320
530
  files.push(arg)
321
531
  else
322
- exit_now! "No valid filename in arguments" if files.empty?
323
- remove_tags.push(arg)
532
+ remove_tags.push(arg) unless options[:p]
324
533
  end
325
534
  end
535
+ if files.empty?
536
+ if @jt.default_post_location && File.exists?(File.dirname(@jt.default_post_location))
537
+ files = Dir.glob(@jt.default_post_location)
538
+ end
539
+ end
540
+ exit_now! "No valid filename in arguments" if files.empty?
541
+
542
+ if options[:p]
543
+ path = File.expand_path(options[:p])
544
+ exit_now! "Input file does not appear to be where you think it is." unless File.exists?(path)
545
+ IO.read(path).each_line {|l|
546
+ next if l =~ /^\s*#/
547
+ if l =~ /^(?:[\s\d])*(?:\|\s*)?(\S.*?)$/
548
+ remove_tags.push($1.strip)
549
+ end
550
+ }
551
+ console_log "Found #{remove_tags.length} tags in #{File.basename(path)}..."
552
+ end
326
553
 
327
- exit_now! "No tags found in arguments" if remove_tags.empty?
554
+ exit_now! "No tags found in input, my work here is done" if remove_tags.empty?
328
555
 
329
556
  files.each {|file|
330
557
  tags = @jt.post_tags(file)
331
558
  remove_tags.each { |d|
332
- tags.delete_if { |tag| tag == d }
559
+ tags.delete_if { |tag|
560
+ if global_options[:i]
561
+ tag.downcase == d.downcase
562
+ else
563
+ tag == d
564
+ end
565
+ }
333
566
  }
334
567
  unless global_options[:t]
335
568
  @jt.update_file_tags(file,tags)
336
- console_log "Updated tags for #{file}"
569
+ console_log "Updated tags for #{file}", :log => true
337
570
  end
338
571
 
339
572
  console_log
340
573
  console_log File.basename(file) + ":"
341
- output_tags(tags,options[:format])
574
+ output_tags(tags,{ :format => options[:format], :filename => file })
342
575
  }
343
576
  end
344
577
  end
345
578
 
346
579
  desc 'Generate a list of recommended tags, optionally updating the file'
347
- arg_name 'filename', :multiple
580
+ arg_name 'file_pattern', :multiple
348
581
  command :tag do |c|
349
- c.desc 'Format to use when outputting tags to console: list, json, csv or yaml. Defaults to yaml.'
582
+ c.desc 'Format to use when outputting tags to console: list, json, plist, csv or yaml. Defaults to yaml.'
350
583
  c.arg_name 'output_format'
351
584
  c.default_value 'yaml'
352
- c.flag [:f,:format], :must_match => /^(csv|list|yaml|json)$/, :type => String
585
+ c.flag [:f,:format], :must_match => /^(csv|list|yaml|json|plist)$/, :type => String
353
586
 
354
587
  c.action do |global_options,options,args|
355
588
  if @piped_content
@@ -357,9 +590,9 @@ command :tag do |c|
357
590
  if !global_options[:s] || global_options[:t]
358
591
  if args.length > 1
359
592
  console_log
360
- console_log "STDIN:", {:err => true}
593
+ console_log "STDIN:", :err => true
361
594
  end
362
- output_tags(suggestions,options[:format])
595
+ output_tags(suggestions, :format => options[:format], :filename => file )
363
596
  end
364
597
  end
365
598
  args.each {|file|
@@ -370,18 +603,18 @@ command :tag do |c|
370
603
  unless global_options[:t]
371
604
  if @jt.update_file_tags(file, suggestions)
372
605
  console_log
373
- console_log "Updated file #{file} with:"
606
+ console_log "Updated file #{file} with:", :log => true
374
607
  else
375
608
  console_log
376
- console_log "Failed to update #{file} with:"
609
+ console_log "Failed to update #{file} with:", :log => true
377
610
  end
378
611
  end
379
612
  if !global_options[:s] || global_options[:t]
380
613
  if args.length > 1
381
614
  console_log
382
- console_log File.basename(file) + ":", {:err => true}
615
+ console_log File.basename(file) + ":", :err => true, :log => true
383
616
  end
384
- output_tags(suggestions,options[:format])
617
+ output_tags(suggestions, :format => options[:format], :filename => file )
385
618
  end
386
619
  suggestions = nil
387
620
  else
@@ -391,19 +624,38 @@ command :tag do |c|
391
624
  end
392
625
  end
393
626
 
394
- def output_tags(tags,format='yaml')
627
+ def output_tags(tags,options)
628
+ format = options[:format] || 'yaml'
629
+ print0 = options[:print0] || false
630
+ filename = options[:filename] || false
395
631
  case format
396
632
  when 'list'
397
- console_log tags.join("\n")
633
+ unless print0
634
+ console_log tags.join("\n")
635
+ else
636
+ console_log tags.map {|tag|
637
+ if tag.strip =~ /\b\s\b/
638
+ %Q{"#{tag.strip}"}
639
+ else
640
+ tag.strip
641
+ end
642
+ }.join(" ")
643
+ end
398
644
  when 'csv'
399
645
  console_log tags.to_csv
400
646
  when 'json'
401
647
  out = {}
402
648
  out['tags'] = tags
649
+ out['path'] = filename if filename
403
650
  console_log out.to_json
404
- else
651
+ when 'plist'
405
652
  out = {}
406
- out['tags'] = tags
653
+ out['path'] = filename if filename
654
+ console_log tags.to_plist
655
+ else
656
+ out = {}
657
+ options[:grouping] ||= "tags"
658
+ out[options[:grouping]] = tags
407
659
  console_log out.to_yaml
408
660
  end
409
661
  end
@@ -419,16 +671,17 @@ end
419
671
  # end
420
672
 
421
673
  pre do |global,command,options,args|
422
- # Pre logic here
423
- # Return true to proceed; false to abort and not call the
424
- # chosen command
425
674
  # Use skips_pre before a command to skip this block
426
675
  # on that command only
427
676
  @silent = global[:silent]
428
677
 
678
+ @logfile = File.open(File.join(Dir.tmpdir, "jtag_actions.log"), 'a')
679
+
680
+ @log = Logger.new(@logfile, shift_age = 7, shift_size = 1048576)
681
+
429
682
  unless config_files_complete?
430
683
  write_config
431
- console_log "Missing config files written to #{@config_target}. Please check your configuration."
684
+ console_log "Missing config files written to #{@config_target}. Please check your configuration.", {:err => true}
432
685
  return false
433
686
  end
434
687
 
data/lib/jtag.rb CHANGED
@@ -4,10 +4,10 @@ require 'fileutils'
4
4
  require 'yaml'
5
5
  require 'csv'
6
6
  require 'json'
7
+ require 'plist'
7
8
  require 'jtag/version.rb'
8
9
  require 'jtag/string.rb'
9
10
  require 'jtag/porter_stemming.rb'
10
11
  require 'jtag/jekylltag.rb'
11
-
12
- # Add requires for other files you add to your project here, so
13
- # you just need to require this one file in your bin file
12
+ require 'tmpdir'
13
+ require 'logger'
@@ -1,3 +1,5 @@
1
1
  ---
2
2
  tags_location: localhost/data/tags.json
3
3
  min_matches: 2
4
+ default_post_location:
5
+ tags_key: tags
@@ -1,13 +1,32 @@
1
1
  # encoding: utf-8
2
+
2
3
  class JTag
4
+ attr_reader :default_post_location
5
+ attr_accessor :tags_key
3
6
 
4
7
  def initialize(support_dir, config)
5
8
  @support = support_dir
6
- @min_matches = config["min_matches"] || 2
7
- @tags_loc = config["tags_location"]
8
- @blacklistfile = File.join(@support,"blacklist.txt")
9
+ begin
10
+ @tags_loc = config['tags_location']
11
+ @tags_loc.sub!(/^https?:\/\//,'')
12
+ rescue
13
+ raise "No tags location in configuration."
14
+ end
15
+ @min_matches = config['min_matches'] || 2
16
+ @tags_key = config['tags_key'] || 'tags'
17
+
18
+ if config.has_key? 'default_post_location'
19
+ @default_post_location = File.expand_path(config['default_post_location']) || false
20
+ else
21
+ console_log "#{color('yellow')}No #{color('boldyellow')}default_post_location#{color('yellow')} set.", :err => true
22
+ console_log "If you commonly work on the same posts you can add the path and *.ext", :err => true
23
+ console_log "to this key in ~/.jtag/config.yml. Then, if you don't specify files", :err => true
24
+ console_log "to act on in a command, it will fall back to those. Nice!#{color('default')}", :err => true
25
+ @default_post_location = false
26
+ end
27
+ @blacklistfile = File.join(@support,'blacklist.txt')
9
28
  @blacklist = IO.read(@blacklistfile).split("\n") || []
10
- @skipwords = IO.read(File.join(support_dir,"stopwords.txt")).split("\n") || []
29
+ @skipwords = IO.read(File.join(support_dir,'stopwords.txt')).split("\n") || []
11
30
  remote_tags = get_tags
12
31
  @tags = {}
13
32
  remote_tags.each {|tag| @tags[Text::PorterStemming.stem(tag).downcase] = tag if tag}
@@ -21,13 +40,14 @@ class JTag
21
40
  counts = options[:counts] || false
22
41
  host, path = @tags_loc.match(/^([^\/]+)(\/.*)/)[1,2]
23
42
  tags = ""
24
- http = Net::HTTP.new(host, 80)
25
- http.start do |http|
26
- request = Net::HTTP::Get.new(path)
27
- response = http.request(request)
28
- response.value
29
- tags = response.body
30
- end
43
+ # http = Net::HTTP.new(host, 80)
44
+ # http.start do |http|
45
+ # request = Net::HTTP::Get.new(path)
46
+ # response = http.request(request)
47
+ # response.value
48
+ # tags = response.body
49
+ # end
50
+ tags = `curl -sSL "#{@tags_loc}"`
31
51
  tags = JSON.parse(tags)
32
52
  if tags && tags.key?("tags")
33
53
  if counts
@@ -72,11 +92,11 @@ class JTag
72
92
  [yaml, after]
73
93
  end
74
94
 
75
- def post_tags(file,piped=false)
95
+ def post_tags(file, piped=false)
76
96
  begin
77
97
  input = piped ? file : IO.read(file)
78
98
  yaml = YAML::load(input)
79
- return yaml["tags"] || []
99
+ return yaml[@tags_key] || []
80
100
  rescue
81
101
  return []
82
102
  end
@@ -103,7 +123,7 @@ class JTag
103
123
  if parts.length >= 2
104
124
  begin
105
125
  yaml = YAML::load(parts[1])
106
- current_tags = yaml["tags"] || []
126
+ current_tags = yaml[@tags_key] || []
107
127
  title = yaml["title"] || ""
108
128
  rescue
109
129
  current_tags = []
@@ -175,7 +195,7 @@ class JTag
175
195
  begin
176
196
  if File.exists?(file)
177
197
  yaml, after = split_post(file)
178
- yaml["tags"] = tags
198
+ yaml[@tags_key] = tags
179
199
  File.open(file,'w+') do |f|
180
200
  f.puts yaml.to_yaml
181
201
  f.puts "---"
@@ -190,5 +210,52 @@ class JTag
190
210
  return false
191
211
  end
192
212
  end
193
- end
194
213
 
214
+ private
215
+
216
+ def color(name)
217
+ color = {}
218
+ color['black'] = "\033[0;30m"
219
+ color['red'] = "\033[0;31m"
220
+ color['green'] = "\033[0;32m"
221
+ color['yellow'] = "\033[0;33m"
222
+ color['blue'] = "\033[0;34m"
223
+ color['magenta'] = "\033[0;35m"
224
+ color['cyan'] = "\033[0;36m"
225
+ color['white'] = "\033[0;37m"
226
+ color['bgblack'] = "\033[0;40m"
227
+ color['bgred'] = "\033[0;41m"
228
+ color['bggreen'] = "\033[0;42m"
229
+ color['bgyellow'] = "\033[0;43m"
230
+ color['bgblue'] = "\033[0;44m"
231
+ color['bgmagenta'] = "\033[0;45m"
232
+ color['bgcyan'] = "\033[0;46m"
233
+ color['bgwhite'] = "\033[0;47m"
234
+ color['boldblack'] = "\033[1;30m"
235
+ color['boldred'] = "\033[1;31m"
236
+ color['boldgreen'] = "\033[1;32m"
237
+ color['boldyellow'] = "\033[1;33m"
238
+ color['boldblue'] = "\033[1;34m"
239
+ color['boldmagenta'] = "\033[1;35m"
240
+ color['boldcyan'] = "\033[1;36m"
241
+ color['boldwhite'] = "\033[1;37m"
242
+ color['boldbgblack'] = "\033[1;40m"
243
+ color['boldbgred'] = "\033[1;41m"
244
+ color['boldbggreen'] = "\033[1;42m"
245
+ color['boldbgyellow'] = "\033[1;43m"
246
+ color['boldbgblue'] = "\033[1;44m"
247
+ color['boldbgmagenta'] = "\033[1;45m"
248
+ color['boldbgcyan'] = "\033[1;46m"
249
+ color['boldbgwhite'] = "\033[1;47m"
250
+ color['default'] = "\033[0;39m"
251
+ color['warning'] = color['yellow']
252
+ color['warningb'] = color['boldyellow']
253
+ color['success'] = color['green']
254
+ color['successb'] = color['boldgreen']
255
+ color['neutral'] = color['white']
256
+ color['neutralb'] = color['boldwhite']
257
+ color['info'] = color['cyan']
258
+ color['infob'] = color['boldcyan']
259
+ color[name]
260
+ end
261
+ end
data/lib/jtag/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Jtag
2
- VERSION = '0.1.7'
2
+ VERSION = '0.1.15'
3
3
  end
metadata CHANGED
@@ -1,97 +1,100 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jtag
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
5
- prerelease:
4
+ version: 0.1.15
6
5
  platform: ruby
7
6
  authors:
8
7
  - Brett Terpstra
9
- autorequire:
8
+ autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-08-28 00:00:00.000000000 Z
11
+ date: 2021-05-14 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rake
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rdoc
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - ">="
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - ">="
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: aruba
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - ">="
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - ">="
60
53
  - !ruby/object:Gem::Version
61
54
  version: '0'
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: gli
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
- - - '='
59
+ - - "~>"
68
60
  - !ruby/object:Gem::Version
69
- version: 2.7.0
61
+ version: 2.20.0
70
62
  type: :runtime
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
- - - '='
66
+ - - "~>"
76
67
  - !ruby/object:Gem::Version
77
- version: 2.7.0
68
+ version: 2.20.0
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: json
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
- - - ! '>='
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 2.2.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 2.2.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: plist
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
84
88
  - !ruby/object:Gem::Version
85
89
  version: '0'
86
90
  type: :runtime
87
91
  prerelease: false
88
92
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
93
  requirements:
91
- - - ! '>='
94
+ - - ">="
92
95
  - !ruby/object:Gem::Version
93
96
  version: '0'
94
- description:
97
+ description:
95
98
  email: me@brettterpstra.com
96
99
  executables:
97
100
  - jtag
@@ -100,52 +103,43 @@ extra_rdoc_files:
100
103
  - README.rdoc
101
104
  - jtag.rdoc
102
105
  files:
106
+ - README.rdoc
103
107
  - bin/jtag
104
- - lib/jtag/version.rb
108
+ - jtag.rdoc
109
+ - lib/jtag.rb
105
110
  - lib/jtag/config_files/blacklist.txt
106
111
  - lib/jtag/config_files/config.yml
107
112
  - lib/jtag/config_files/stopwords.txt
108
113
  - lib/jtag/config_files/synonyms.yml
109
- - lib/jtag/porter_stemming.rb
110
114
  - lib/jtag/jekylltag.rb
115
+ - lib/jtag/porter_stemming.rb
111
116
  - lib/jtag/string.rb
112
- - lib/jtag.rb
113
- - README.rdoc
114
- - jtag.rdoc
117
+ - lib/jtag/version.rb
115
118
  homepage: http://brettterpstra.com
116
119
  licenses: []
117
- post_install_message:
120
+ metadata: {}
121
+ post_install_message:
118
122
  rdoc_options:
119
- - --title
123
+ - "--title"
120
124
  - jtag
121
- - --main
125
+ - "--main"
122
126
  - README.rdoc
123
- - -ri
124
127
  require_paths:
125
128
  - lib
126
129
  - lib
127
130
  required_ruby_version: !ruby/object:Gem::Requirement
128
- none: false
129
131
  requirements:
130
- - - ! '>='
132
+ - - ">="
131
133
  - !ruby/object:Gem::Version
132
134
  version: '0'
133
- segments:
134
- - 0
135
- hash: -591621506323502236
136
135
  required_rubygems_version: !ruby/object:Gem::Requirement
137
- none: false
138
136
  requirements:
139
- - - ! '>='
137
+ - - ">="
140
138
  - !ruby/object:Gem::Version
141
139
  version: '0'
142
- segments:
143
- - 0
144
- hash: -591621506323502236
145
140
  requirements: []
146
- rubyforge_project:
147
- rubygems_version: 1.8.25
148
- signing_key:
149
- specification_version: 3
141
+ rubygems_version: 3.2.16
142
+ signing_key:
143
+ specification_version: 4
150
144
  summary: Auto-tagging and tagging tools for Jekyll
151
145
  test_files: []