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