bin/things2thl in zzamboni-things2thl-0.7.0 vs bin/things2thl in zzamboni-things2thl-0.8.0
- old
+ new
@@ -2,20 +2,25 @@
# -*- coding: utf-8 -*-
require File.join(File.dirname(__FILE__), *%w".. lib Things2THL")
require "optparse"
require "ostruct"
+require "time"
options=Things2THL.default_options
opts = OptionParser.new do |opts|
opts.banner = "Usage: things2thl <mode of operation> [options]"
def opts.show_usage
puts self
exit
end
+
+ def yesno(v)
+ "(default: #{v ? 'yes' : 'no'})"
+ end
opts.separator ''
opts.separator("Modes of operation (required):")
opts.on("-L", "--projects-as-lists",
"Convert projects in Things to lists in THL" ) { options.structure = :projects_as_lists }
@@ -23,27 +28,34 @@
"Convert projects in Things to tasks in THL" ) { options.structure = :projects_as_tasks }
opts.on("-B", "--projects-areas-as-tasks",
"Convert both projects and areas in Things",
" to lists in THL. This implies that",
" projects are not nested inside areas.") { options.structure = :projects_areas_as_lists }
+ opts.on("-I", "--inbox", "Transfer only Inbox tasks." ) do
+ options.inboxonly = true
+ options.structure = :projects_as_lists
+ end
opts.separator ''
opts.separator("Options:")
- opts.on("--[no-]areas", "Transfer areas from Things (default: #{options.areas ? 'yes' : 'no'})") { |v| options.areas = v }
+ opts.on("--[no-]areas", "Transfer areas from Things #{yesno(options.areas)}") { |v| options.areas = v }
+ opts.on("--areas-as-tags", "Transfer areas as tags in THL.") { options.areas_as=:tags }
+ opts.on("--areas-as-contexts", "Transfer areas as contexts in THL.") { options.areas_as=:contexts }
opts.on('--[no-]time-tags',
'Consider tags of the form Xmin/Xsec/Xhr as',
' time estimates, set them in THL',
- " accordingly (default: #{options.timetags ? 'yes' : 'no'}).") do |value|
+ " accordingly #{yesno(options.timetags)}.") do |value|
options.timetags = value
end
opts.on('--[no-]context-tags [REGEX]',
'Regular expression to identify tags that',
' should be interpreted as contexts.',
" (default: #{options.contexttagsregex}).",
" Use with no- to disable this feature.") do |regex|
options.contexttagsregex = case regex; when false:nil; when "":options.contexttagsregex; else regex; end
end
+ opts.on("--sync", "Only transfer new items #{yesno(options.sync)}") { options.sync = true }
opts.on("--top-level-folder FOLDER", "Do the import inside the named folders,"," instead of the top level",
" (Inbox, etc. will also be created there"," instead of their corresponding places)") do |toplevel|
options.toplevel = toplevel
end
opts.on("--projects-top-level FOLDER",
@@ -63,15 +75,17 @@
options.areasfolder = areafolder
end
opts.on("-c", "--completed",
"Transfer also completed/canceled tasks",
- " and projects (default: #{options.completed ? 'yes' : 'no'})") { options.completed = true }
+ " and projects #{yesno(options.completed)}") { options.completed = true }
opts.on("--[no-]archive-completed",
"If transferring completed/canceled tasks,",
- " also mark them as archived (default: #{options.archivecompleted ? 'yes' : 'no'})") {|v| options.archivecompleted = v }
- opts.on("-q", "--quiet", "Do not print items as they are processed") { options.quiet = true }
+ " also mark them as archived #{yesno(options.archivecompleted)}") {|v| options.archivecompleted = v }
+ opts.on("-q", "--quiet",
+ "Do not print items as they are processed.",
+ "Twice: do not print stats at the end.") { options.quiet+=1 }
# opts.on("-n", "--dry-run", "Do not create anything in THL, just print the items that would be created") { options.dryrun = true }
# opts.on("-n", "--notes", "Shows only tasks with notes") { options[:tasks] = { :onlynotes => true } }
# opts.on("-a", "--all", 'Shows all tasks in the focus') { |f| options[:tasks] = { :children => false } }
opts.on("-h", "--help", "Shows this help message") { opts.show_usage }
@@ -98,57 +112,73 @@
######################################################################
# Main program
######################################################################
opts.parse!
-unless options.structure
+unless options.structure || options.inboxonly
puts "Error: you didn't specify the mode of operation to use."
puts ''
opts.show_usage
end
converter = Things2THL.new(options, options.thingsapp, options.thlapp)
things = converter.things
thl = converter.thl
-# Create top-level containers if needed
+# Start timing
+start=Time.new
-# First, traverse all areas
-if options.areas
- puts "Processing Areas of Responsibility" unless options.quiet
- things.areas.get.each do |area|
- converter.process(Things2THL::ThingsNode.new(area))
+unless options.inboxonly
+ # First, traverse all areas
+ if options.areas && !options.areas_as
+ puts "Processing Areas of Responsibility" unless options.quiet.nonzero?
+ things.areas.get.each do |area|
+ converter.process(Things2THL::ThingsNode.new(area))
+ end
end
-end
-# Next, traverse all projects, putting each one inside its corresponding area
-puts "Processing Projects" unless options.quiet
-if options.completed
- puts " (fetching all projects - this may take a while)" unless options.quiet
- projlist=things.projects.get
-else
- puts " (fetching only open projects - this may take a while)" unless options.quiet
- projlist=things.projects[its.status.eq(:open)].get
+ # Next, traverse all projects, putting each one inside its corresponding area
+ puts "Processing Projects" unless options.quiet.nonzero?
+ if options.completed
+ puts " (fetching all projects - this may take a while)" unless options.quiet.nonzero?
+ projlist=things.projects.get
+ else
+ puts " (fetching only open projects - this may take a while)" unless options.quiet.nonzero?
+ projlist=things.projects[its.status.eq(:open)].get
+ end
+ projlist.each do |project|
+ converter.process(Things2THL::ThingsNode.new(project))
+ end
end
-projlist.each do |project|
- converter.process(Things2THL::ThingsNode.new(project))
-end
# Now do the tasks
# This is more complicated because:
# - to_dos returns not only tasks, also projects (not areas)
# - to-dos returns tasks from all the views: Inbox, Today, Scheduled, Someday, and Next, so we have
# to separate them and create the appropriate containers as needed
-puts "Processing tasks" unless options.quiet
+puts "Processing tasks" unless options.quiet.nonzero?
+if options.inboxonly
+ queryobj=things.lists['Inbox']
+else
+ queryobj=things
+end
if options.completed
- puts " (fetching all tasks - this may take a while)" unless options.quiet
- tasklist=things.to_dos.get
+ puts " (fetching all tasks - this may take a while)" unless options.quiet.nonzero?
+ tasklist=queryobj.to_dos.get
else
- puts " (fetching only open tasks - this may take a while)" unless options.quiet
- tasklist=things.to_dos[its.status.eq(:open)].get
+ puts " (fetching only open tasks - this may take a while)" unless options.quiet.nonzero?
+ tasklist=queryobj.to_dos[its.status.eq(:open)].get
end
tasklist.each do |t|
task=Things2THL::ThingsNode.new(t)
next if task.type != :selected_to_do
converter.process(task)
end
+# End timing
+diff=Time.new-start
+
+# Print stats at the end
+unless options.quiet >= 2
+ puts "Conversion done in #{diff} seconds."
+ converter.created.each_pair { |key,val| puts " #{val} #{key}#{val!=1 ? 's' : ''} created" }
+end