zzamboni-things2thl 0.2.2 → 0.3.0
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.
- data/VERSION +1 -1
- data/bin/things2thl +14 -30
- data/lib/Things2THL.rb +14 -3
- data/things2thl.gemspec +1 -1
- metadata +1 -1
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/bin/things2thl
CHANGED
@@ -14,6 +14,7 @@ options.areas = true
|
|
14
14
|
options.quiet = false
|
15
15
|
options.archivecompleted = true
|
16
16
|
options.projectsfolder = nil
|
17
|
+
options.contexttagsregex = '^@'
|
17
18
|
opts = OptionParser.new do |opts|
|
18
19
|
opts.separator ''
|
19
20
|
opts.separator 'Options:'
|
@@ -28,6 +29,10 @@ opts = OptionParser.new do |opts|
|
|
28
29
|
opts.on("--projects-as-lists", "Convert projects in Things to lists in THL (default)") { options.structure = :projects_as_lists }
|
29
30
|
opts.on("--projects-as-tasks", "Convert projects in Things to tasks in THL") { options.structure = :projects_as_tasks }
|
30
31
|
opts.on("--no-areas", "Ignore areas in Things") { options.areas = false }
|
32
|
+
opts.on('-C REGEX', '--context-tags-regex REGEX', 'Regular expression to identify tags that should be interpreted as contexts.',
|
33
|
+
" (default: #{options.contexttagsregex})") do |regex|
|
34
|
+
options.contexttagsregex = regex
|
35
|
+
end
|
31
36
|
|
32
37
|
opts.on("--top-level-folder FOLDER", "If specified, do the import inside the named folders, instead of the top level",
|
33
38
|
" (Inbox, etc. will also be created there instead of their corresponding places)") do |toplevel|
|
@@ -78,15 +83,21 @@ thl = converter.thl
|
|
78
83
|
# Create top-level containers if needed
|
79
84
|
|
80
85
|
# First, traverse all areas
|
81
|
-
|
86
|
+
if options.areas
|
87
|
+
things.areas.get.each do |area|
|
88
|
+
converter.process(Things2THL::ThingsNode.new(area))
|
89
|
+
end
|
90
|
+
end
|
82
91
|
|
83
92
|
# Next, traverse all projects, putting each one inside its corresponding area
|
84
|
-
things.projects.get.each
|
93
|
+
things.projects.get.each do |project|
|
94
|
+
converter.process(Things2THL::ThingsNode.new(project))
|
95
|
+
end
|
85
96
|
|
86
97
|
# Now do the tasks
|
87
98
|
# This is more complicated because:
|
88
99
|
# - to_dos returns not only tasks, also projects (not areas)
|
89
|
-
# - to-dos returns tasks from all the views: Inbox, Scheduled, Someday, and Next, so we have
|
100
|
+
# - to-dos returns tasks from all the views: Inbox, Today, Scheduled, Someday, and Next, so we have
|
90
101
|
# to separate them and create the appropriate containers as needed
|
91
102
|
things.to_dos.get.each do |t|
|
92
103
|
task=Things2THL::ThingsNode.new(t)
|
@@ -94,30 +105,3 @@ things.to_dos.get.each do |t|
|
|
94
105
|
converter.process(task)
|
95
106
|
end
|
96
107
|
|
97
|
-
# # First traverse areas
|
98
|
-
# puts "Areas:"
|
99
|
-
# things.areas.each { |n| converter.traverse(n, 0, thl.folders_group.get) }
|
100
|
-
# # Then traverse area-less projects
|
101
|
-
# puts "\nProjects without an area:"
|
102
|
-
# parent = thl.folders_group.get
|
103
|
-
# if (options.structure == :projects_as_tasks)
|
104
|
-
# parent = converter.find_or_create_list(parent, "Projects")
|
105
|
-
# end
|
106
|
-
# things.projects.each { |n| converter.traverse(n, 0, parent) unless n.parent_area? }
|
107
|
-
# Then tasks without a project
|
108
|
-
#puts "\nTasks without a project:"
|
109
|
-
#things.focus(:next).children.each { |n| traverse(n, 0, options) unless n.parent? }
|
110
|
-
|
111
|
-
#############
|
112
|
-
|
113
|
-
# thl.folders_group.end.make(:new => :folder, :with_properties => {:name => 'test folder'})
|
114
|
-
# app("/Applications/The Hit List.app").folders_group.folders.ID("1B98A3855A3C79DE").end.make(:new => :list, :with_properties => {:name => 'test list'})
|
115
|
-
# task=app("/Applications/The Hit List.app").folders_group.folders.ID("1B98A3855A3C79DE").lists.ID("43B3187E6D90AB8D").end.make(:new => :task, :with_properties => {:title => 'test
|
116
|
-
# task', :notes => 'test notes' })
|
117
|
-
# task.end.make(:new => :task, :with_properties => {:title => 'test subtask'})
|
118
|
-
# task.set(:title => 'new title')
|
119
|
-
# task.set(title => 'new title')
|
120
|
-
# task.title = 'new title'
|
121
|
-
# thl.set(task.title, :to => 'new title')
|
122
|
-
# task.title.set('another title')
|
123
|
-
# task.title.get
|
data/lib/Things2THL.rb
CHANGED
@@ -11,8 +11,8 @@ require 'appscript'; include Appscript
|
|
11
11
|
module Things2THL
|
12
12
|
module Version
|
13
13
|
MAJOR = 0
|
14
|
-
MINOR =
|
15
|
-
PATCH =
|
14
|
+
MINOR = 3
|
15
|
+
PATCH = 0
|
16
16
|
|
17
17
|
STRING = [MAJOR, MINOR, PATCH].join(".")
|
18
18
|
end
|
@@ -228,6 +228,9 @@ module Things2THL
|
|
228
228
|
exit(1)
|
229
229
|
end
|
230
230
|
|
231
|
+
# Regular expression to match context tags. Compile it here to avoid
|
232
|
+
# repetition later on.
|
233
|
+
options.contexttagsregex_compiled = Regexp.compile(options.contexttagsregex)
|
231
234
|
# Structure to keep track of already create items
|
232
235
|
# These hashes are indexed by Things node ID (node.id_). Each element
|
233
236
|
# contains a hash with two elements:
|
@@ -634,7 +637,15 @@ module Things2THL
|
|
634
637
|
tasktags |= node.area.tags.map {|t| t.name }
|
635
638
|
end
|
636
639
|
unless tasktags.empty?
|
637
|
-
prop[:title] = [prop[:title], tasktags.map
|
640
|
+
prop[:title] = [prop[:title], tasktags.map do |t|
|
641
|
+
if options.contexttagsregex_compiled &&
|
642
|
+
options.contexttagsregex_compiled.match(t)
|
643
|
+
# Contexts cannot have spaces, we also remove any initial @'s before adding our own.
|
644
|
+
"@" + t.gsub(/^@+/, "").gsub(/ /, '_')
|
645
|
+
else
|
646
|
+
"/" + t + (t.index(" ")?"/":"")
|
647
|
+
end
|
648
|
+
end].join(' ')
|
638
649
|
end
|
639
650
|
end
|
640
651
|
|
data/things2thl.gemspec
CHANGED