zzamboni-things2thl 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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