zzamboni-things2thl 0.4.4 → 0.5.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/ChangeLog +33 -0
- data/README +16 -13
- data/VERSION +1 -1
- data/bin/things2thl +29 -12
- data/lib/Things2THL.rb +52 -9
- data/things2thl.gemspec +1 -1
- metadata +1 -1
data/ChangeLog
CHANGED
|
@@ -1,3 +1,36 @@
|
|
|
1
|
+
2009-05-19 Diego Zamboni <diego@zzamboni.org>
|
|
2
|
+
|
|
3
|
+
* lib/Things2THL.rb: Version bump to 0.5.0
|
|
4
|
+
|
|
5
|
+
2009-05-19 Diego Zamboni <diego@zzamboni.org>
|
|
6
|
+
|
|
7
|
+
* bin/things2thl, lib/Things2THL.rb: Made it mandatory to specify
|
|
8
|
+
the mode of operation (--projects-as-lists or --projects-as-tasks).
|
|
9
|
+
|
|
10
|
+
2009-05-19 Diego Zamboni <diego@zzamboni.org>
|
|
11
|
+
|
|
12
|
+
* bin/things2thl, lib/Things2THL.rb: Added --[no-]time-tags option,
|
|
13
|
+
which allows time-estimate tags in Things for the form Xsec/Xmin/Xhr
|
|
14
|
+
(e.g. I use "10min", "30min", "60min") to be converted to the
|
|
15
|
+
appropriate time estimate attribute of the tasks in THL. For now the
|
|
16
|
+
format of the time-estimate tags is fixed, but I might add
|
|
17
|
+
customization if I someone asks for it. This option is disabled by
|
|
18
|
+
default. Also changed the --context-tags-regex option to be
|
|
19
|
+
--[no-]context-tags, which allows both specifying the regex and
|
|
20
|
+
(with --no-) disabling the feature in a single option.
|
|
21
|
+
|
|
22
|
+
2009-05-19 Diego Zamboni <diego@zzamboni.org>
|
|
23
|
+
|
|
24
|
+
* things2thl.gemspec: Regenerated gemspec for version 0.4.4
|
|
25
|
+
|
|
26
|
+
2009-05-19 Diego Zamboni <diego@zzamboni.org>
|
|
27
|
+
|
|
28
|
+
* VERSION: Version bump to 0.4.4
|
|
29
|
+
|
|
30
|
+
2009-05-19 Diego Zamboni <diego@zzamboni.org>
|
|
31
|
+
|
|
32
|
+
* ChangeLog, lib/Things2THL.rb: Updated ChangeLog
|
|
33
|
+
|
|
1
34
|
2009-05-19 Diego Zamboni <diego@zzamboni.org>
|
|
2
35
|
|
|
3
36
|
* things2thl.gemspec: Regenerated gemspec for version 0.4.3
|
data/README
CHANGED
|
@@ -7,8 +7,9 @@ Conversion program to transfer data from Things
|
|
|
7
7
|
|
|
8
8
|
Written by Diego Zamboni <diego@zzamboni.org>
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
|
|
11
|
+
INSTALLATION:
|
|
12
|
+
------------
|
|
12
13
|
|
|
13
14
|
You need Things 1.1.1 or later, since things2thl requires Applescript
|
|
14
15
|
support.
|
|
@@ -25,21 +26,26 @@ don't have it already, it will be automatically installed by gem.
|
|
|
25
26
|
USAGE:
|
|
26
27
|
-----
|
|
27
28
|
|
|
28
|
-
Usage: things2thl [options]
|
|
29
|
+
Usage: things2thl <mode of operation> [options]
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
Modes of operation (required):
|
|
31
32
|
-L, --projects-as-lists Convert projects in Things to lists in THL
|
|
32
|
-
(default)
|
|
33
33
|
-T, --projects-as-tasks Convert projects in Things to tasks in THL
|
|
34
|
+
|
|
35
|
+
Options:
|
|
34
36
|
--[no-]areas Transfer areas from Things (default: yes)
|
|
35
|
-
|
|
37
|
+
--[no-]time-tags Consider tags of the form Xmin/Xsec/Xhr as
|
|
38
|
+
time estimates, set them in THL
|
|
39
|
+
accordingly (default: no).
|
|
40
|
+
--[no-]context-tags [REGEX] Regular expression to identify tags that
|
|
36
41
|
should be interpreted as contexts.
|
|
37
|
-
(default: ^@)
|
|
42
|
+
(default: ^@).
|
|
43
|
+
Use with no- to disable this feature.
|
|
38
44
|
--top-level-folder FOLDER Do the import inside the named folders,
|
|
39
45
|
instead of the top level
|
|
40
46
|
(Inbox, etc. will also be created there
|
|
41
47
|
instead of their corresponding places)
|
|
42
|
-
--projects-
|
|
48
|
+
--projects-top-level FOLDER The named folder will be created to
|
|
43
49
|
contain all projects when
|
|
44
50
|
--projects-as-lists is used (otherwise
|
|
45
51
|
they will be in the top folders group).
|
|
@@ -74,11 +80,6 @@ Functionality still missing:
|
|
|
74
80
|
|
|
75
81
|
Not sure how to transfer this to THL. Ideas are welcome.
|
|
76
82
|
|
|
77
|
-
- Handle "time estimate" tags.
|
|
78
|
-
|
|
79
|
-
Plan: Allow specifying certain Things tags (e.g. I use "10min",
|
|
80
|
-
"30min", "60min") that should be used to set the time estimate for
|
|
81
|
-
the task in THL.
|
|
82
83
|
|
|
83
84
|
Known issues:
|
|
84
85
|
-------------
|
|
@@ -92,3 +93,5 @@ Known issues:
|
|
|
92
93
|
scheduling itself is not transferred, because this information is
|
|
93
94
|
not accessible through AS from either Things not THL.
|
|
94
95
|
|
|
96
|
+
- The format of time estimate tags is fixed for the moment. May add
|
|
97
|
+
customization if I get any requests for it.
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.5.0
|
data/bin/things2thl
CHANGED
|
@@ -7,29 +7,42 @@ require "ostruct"
|
|
|
7
7
|
|
|
8
8
|
options=Things2THL.default_options
|
|
9
9
|
opts = OptionParser.new do |opts|
|
|
10
|
-
|
|
11
|
-
opts.
|
|
12
|
-
|
|
13
|
-
opts.banner = "Usage: things2thl [options]"
|
|
10
|
+
|
|
11
|
+
opts.banner = "Usage: things2thl <mode of operation> [options]"
|
|
14
12
|
|
|
15
13
|
def opts.show_usage
|
|
16
14
|
puts self
|
|
17
15
|
exit
|
|
18
16
|
end
|
|
19
17
|
|
|
20
|
-
opts.
|
|
21
|
-
opts.
|
|
18
|
+
opts.separator ''
|
|
19
|
+
opts.separator("Modes of operation (required):")
|
|
20
|
+
opts.on("-L", "--projects-as-lists",
|
|
21
|
+
"Convert projects in Things to lists in THL" ) { options.structure = :projects_as_lists }
|
|
22
|
+
opts.on("-T", "--projects-as-tasks",
|
|
23
|
+
"Convert projects in Things to tasks in THL" ) { options.structure = :projects_as_tasks }
|
|
24
|
+
|
|
25
|
+
opts.separator ''
|
|
26
|
+
opts.separator("Options:")
|
|
22
27
|
opts.on("--[no-]areas", "Transfer areas from Things (default: #{options.areas ? 'yes' : 'no'})") { |v| options.areas = v }
|
|
23
|
-
opts.on('
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
opts.on('--[no-]time-tags',
|
|
29
|
+
'Consider tags of the form Xmin/Xsec/Xhr as',
|
|
30
|
+
' time estimates, set them in THL',
|
|
31
|
+
" accordingly (default: #{options.timetags ? 'yes' : 'no'}).") do |value|
|
|
32
|
+
options.timetags = value
|
|
33
|
+
end
|
|
34
|
+
opts.on('--[no-]context-tags [REGEX]',
|
|
35
|
+
'Regular expression to identify tags that',
|
|
36
|
+
' should be interpreted as contexts.',
|
|
37
|
+
" (default: #{options.contexttagsregex}).",
|
|
38
|
+
" Use with no- to disable this feature.") do |regex|
|
|
39
|
+
options.contexttagsregex = case regex; when false:nil; when "":options.contexttagsregex; else regex; end
|
|
26
40
|
end
|
|
27
|
-
|
|
28
41
|
opts.on("--top-level-folder FOLDER", "Do the import inside the named folders,"," instead of the top level",
|
|
29
42
|
" (Inbox, etc. will also be created there"," instead of their corresponding places)") do |toplevel|
|
|
30
43
|
options.toplevel = toplevel
|
|
31
44
|
end
|
|
32
|
-
opts.on("--projects-
|
|
45
|
+
opts.on("--projects-top-level FOLDER",
|
|
33
46
|
"The named folder will be created to",
|
|
34
47
|
" contain all projects when",
|
|
35
48
|
" --projects-as-lists is used (otherwise",
|
|
@@ -78,7 +91,11 @@ end
|
|
|
78
91
|
######################################################################
|
|
79
92
|
|
|
80
93
|
opts.parse!
|
|
81
|
-
|
|
94
|
+
unless options.structure
|
|
95
|
+
puts "Error: you didn't specify the mode of operation to use."
|
|
96
|
+
puts ''
|
|
97
|
+
opts.show_usage
|
|
98
|
+
end
|
|
82
99
|
|
|
83
100
|
converter = Things2THL.new(options, options.thingsapp, options.thlapp)
|
|
84
101
|
things = converter.things
|
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 = 5
|
|
15
|
+
PATCH = 0
|
|
16
16
|
|
|
17
17
|
STRING = [MAJOR, MINOR, PATCH].join(".")
|
|
18
18
|
end
|
|
@@ -73,7 +73,7 @@ module Things2THL
|
|
|
73
73
|
Proc.new {|node,prop,obj|
|
|
74
74
|
obj.fix_completed_canceled(node, prop)
|
|
75
75
|
obj.archive_completed(prop)
|
|
76
|
-
obj.
|
|
76
|
+
obj.process_tags(node, prop, true, true)
|
|
77
77
|
obj.check_today(node, prop)
|
|
78
78
|
}
|
|
79
79
|
]
|
|
@@ -99,7 +99,7 @@ module Things2THL
|
|
|
99
99
|
Proc.new {|node,prop,obj|
|
|
100
100
|
obj.fix_completed_canceled(node, prop)
|
|
101
101
|
obj.archive_completed(prop)
|
|
102
|
-
obj.
|
|
102
|
+
obj.process_tags(node, prop, false, true)
|
|
103
103
|
}
|
|
104
104
|
],
|
|
105
105
|
:selected_to_do => [:task,
|
|
@@ -118,7 +118,7 @@ module Things2THL
|
|
|
118
118
|
Proc.new {|node,prop,obj|
|
|
119
119
|
obj.fix_completed_canceled(node, prop)
|
|
120
120
|
obj.archive_completed(prop)
|
|
121
|
-
obj.
|
|
121
|
+
obj.process_tags(node, prop, false, true)
|
|
122
122
|
obj.check_today(node, prop)
|
|
123
123
|
}
|
|
124
124
|
]
|
|
@@ -132,6 +132,14 @@ module Things2THL
|
|
|
132
132
|
:task => :title
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
# Time units for time-estimate tags
|
|
136
|
+
TIMEUNITS = {
|
|
137
|
+
"sec" => 1,
|
|
138
|
+
"min" => 60,
|
|
139
|
+
"hr" => 60*60,
|
|
140
|
+
"hour" => 60*60,
|
|
141
|
+
}
|
|
142
|
+
|
|
135
143
|
end ### module Constants
|
|
136
144
|
|
|
137
145
|
####################################################################
|
|
@@ -230,7 +238,10 @@ module Things2THL
|
|
|
230
238
|
|
|
231
239
|
# Regular expression to match context tags. Compile it here to avoid
|
|
232
240
|
# repetition later on.
|
|
233
|
-
options.contexttagsregex_compiled = Regexp.compile(options.contexttagsregex)
|
|
241
|
+
options.contexttagsregex_compiled = Regexp.compile(options.contexttagsregex) if options.contexttagsregex
|
|
242
|
+
# Regular expression to match time-estimate tags. Compile it here to avoid
|
|
243
|
+
# repetition later on.
|
|
244
|
+
options.timetagsregex_compiled = Regexp.compile(options.timetagsregex) if options.timetagsregex
|
|
234
245
|
# Structure to keep track of already create items
|
|
235
246
|
# These hashes are indexed by Things node ID (node.id_). Each element
|
|
236
247
|
# contains a hash with two elements:
|
|
@@ -621,8 +632,8 @@ module Things2THL
|
|
|
621
632
|
prop[:archived] = true if options.archivecompleted && (prop[:completed] || prop[:canceled])
|
|
622
633
|
end
|
|
623
634
|
|
|
624
|
-
#
|
|
625
|
-
def
|
|
635
|
+
# Process tags
|
|
636
|
+
def process_tags(node, prop, inherit_project_tags, inherit_area_tags)
|
|
626
637
|
tasktags = node.tags.map {|t| t.name }
|
|
627
638
|
if inherit_project_tags
|
|
628
639
|
# Merge project and area tags
|
|
@@ -637,6 +648,36 @@ module Things2THL
|
|
|
637
648
|
tasktags |= node.area.tags.map {|t| t.name }
|
|
638
649
|
end
|
|
639
650
|
unless tasktags.empty?
|
|
651
|
+
# First process time-estimate tags if needed
|
|
652
|
+
if options.timetags
|
|
653
|
+
# Valid time tags will be deleted from the tags list
|
|
654
|
+
tasktags=tasktags.delete_if do |t|
|
|
655
|
+
if data=options.timetagsregex_compiled.match(t)
|
|
656
|
+
timeestimate = nil
|
|
657
|
+
# If the regex includes only one group, it is assumed to be
|
|
658
|
+
# the time in minutes. If it includes two groups, the second
|
|
659
|
+
# group specifies the time unit, as defined in Constants::TIMEUNITS
|
|
660
|
+
case data.size
|
|
661
|
+
when 0
|
|
662
|
+
puts "Invalid time tags regex, does not return any groups: #{options.timetagsregex_compiled.to_s}"
|
|
663
|
+
when 1
|
|
664
|
+
# Assumed to be in minutes, timeestimate is in seconds
|
|
665
|
+
timeestimate = data[1].to_i * 60
|
|
666
|
+
else
|
|
667
|
+
# Second one is the units - the rest are ignored
|
|
668
|
+
timeunit=Constants::TIMEUNITS[data[2]]
|
|
669
|
+
if !timeunit
|
|
670
|
+
puts "Invalid time estimate tag, I could not match the time unit: '#{t}'"
|
|
671
|
+
else
|
|
672
|
+
timeestimate = data[1].to_i * timeunit
|
|
673
|
+
end
|
|
674
|
+
end
|
|
675
|
+
if timeestimate
|
|
676
|
+
prop[:estimated_time] = timeestimate
|
|
677
|
+
end
|
|
678
|
+
end
|
|
679
|
+
end
|
|
680
|
+
end
|
|
640
681
|
prop[:title] = [prop[:title], tasktags.map do |t|
|
|
641
682
|
if options.contexttagsregex_compiled &&
|
|
642
683
|
options.contexttagsregex_compiled.match(t)
|
|
@@ -709,12 +750,14 @@ module Things2THL
|
|
|
709
750
|
options=OpenStruct.new
|
|
710
751
|
options.completed = false
|
|
711
752
|
options.database = nil
|
|
712
|
-
options.structure =
|
|
753
|
+
options.structure = nil
|
|
713
754
|
options.areas = true
|
|
714
755
|
options.quiet = false
|
|
715
756
|
options.archivecompleted = true
|
|
716
757
|
options.projectsfolder = nil
|
|
717
758
|
options.contexttagsregex = '^@'
|
|
759
|
+
options.timetagsregex = '^(\d+)(min|sec|hr)$'
|
|
760
|
+
options.timetags = false
|
|
718
761
|
return options
|
|
719
762
|
end
|
|
720
763
|
|
data/things2thl.gemspec
CHANGED