ncal2gcal 0.1.3

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/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009, 2010 Elias Kugler
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,75 @@
1
+ =ncal2gcal
2
+
3
+ This lib/tool syncs your IBM Lotus Notes calendar with your (private) Google calendar. The synchronisation is only one-way: Lotus Notes events are pushed to your Google Calendar. All types of events (including recurring events like anniversaries) are supported.
4
+
5
+ == Installation Instructions
6
+
7
+ gem install ncal2gcal
8
+
9
+ ==Usage
10
+
11
+ Usage: ncal2gcal <command> <opts>
12
+
13
+ Commands: sync
14
+
15
+ Specific options:
16
+ -u, --notes-username USERNAME Lotus Notes user name
17
+ -p, --notes-password PASSWORD Lotus Notes password
18
+ -d, --notes-database DATABASE Lotus Notes database (.nsf file)
19
+ -U, --gmail-username USERNAME Google user name
20
+ -P, --gmail-password PASSWORD Google user password
21
+ -C, --gmail-calendar CALENDAR Google calendar (default: 'LotusNotes')
22
+ -D, --days DAYS Do not sync events older then DAYS days
23
+ --sync-desc Do sync the event description (default: no)
24
+
25
+ Example:
26
+ ncal2gcal sync -u user123 -p secret123 -d mail123.nsf -U username@gmail.com -P 123secret -C LotusNotes -D 14
27
+
28
+ Common options:
29
+ -?, --help Show this message
30
+
31
+ == Prerequisites
32
+
33
+ 1. Ruby 1.8.6 or later
34
+ 2. Lotus Notes
35
+ * your .nsf file must be a local copy (replica) of your mail database stored in the data-folder
36
+ of your lotus notes installation.
37
+ 3. Google Account
38
+ * use your gmail-account or create a new one
39
+ * create an additional calendar for your LotusNotes Calender entries. Name it as you like
40
+ (i.e. LotusNotes) but do not use whitespaces or any other special characters.
41
+
42
+ == Supported Platforms
43
+
44
+ This library is supported on Windows 2000 or later.
45
+
46
+ ==Used libs:
47
+ * gcal4ruby
48
+ * win32ole
49
+ * datamapper
50
+ * do_sqlite3
51
+ * log4r
52
+ ...
53
+
54
+ == Licence/Copyright
55
+
56
+ Copyright (c) 2009, 2010 Elias Kugler
57
+
58
+ Permission is hereby granted, free of charge, to any person obtaining
59
+ a copy of this software and associated documentation files (the
60
+ "Software"), to deal in the Software without restriction, including
61
+ without limitation the rights to use, copy, modify, merge, publish,
62
+ distribute, sublicense, and/or sell copies of the Software, and to
63
+ permit persons to whom the Software is furnished to do so, subject to
64
+ the following conditions:
65
+
66
+ The above copyright notice and this permission notice shall be
67
+ included in all copies or substantial portions of the Software.
68
+
69
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
70
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
71
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
72
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
73
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
74
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
75
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/bin/ncal2gcal ADDED
@@ -0,0 +1,66 @@
1
+ #$:.unshift '../test/mock/win32ole','../test/mock/gcal4ruby','../lib' #<< '../lib'
2
+ #$:.unshift '../test/mock/win32ole','../lib' #<< '../lib'
3
+ #$:.unshift '../lib' #<< '../lib'
4
+
5
+ require 'rubygems'
6
+ require 'optparse'
7
+ require 'ncal2gcal/sync'
8
+
9
+ conf = {}
10
+ opts = OptionParser.new do |opts|
11
+ opts.banner = "Usage: ncal2gcal <command> <opts> "
12
+ opts.separator ""
13
+ opts.separator "Commands: sync"
14
+ opts.separator ""
15
+ opts.separator "Specific options:"
16
+ opts.on("-u", "--notes-username USERNAME", "Lotus Notes user name") { |conf[:notes_user]| }
17
+ opts.on("-p", "--notes-password PASSWORD", "Lotus Notes password") { |conf[:notes_password]| }
18
+ opts.on("-d", "--notes-database DATABASE", "Lotus Notes database (.nsf file)") { |conf[:notes_db]| }
19
+ opts.on("-U", "--gmail-username USERNAME", "Google mail user name") { |conf[:gmail_user]| }
20
+ opts.on("-P", "--gmail-password PASSWORD", "Google mail password") { |conf[:gmail_password]| }
21
+ opts.on("-C", "--gmail-calendar CALENDAR", "Google calendar (default: 'LotusNotes')") { |conf[:gmail_calendar]| }
22
+ opts.on("-D", "--days DAYS", "Do not sync events older then DAYS days (default: no limit)") { |days| conf[:days]=days.to_i }
23
+ opts.on("--sync-desc", "Do sync event description (default: no)") { conf[:sync_desc] }
24
+ opts.separator ""
25
+ opts.separator "Example:"
26
+ opts.separator " ncal2gcal sync -u user123 -p secret123 -d mail123.nsf -U username@gmail.com -P top123secret -C LotusNotes -D 14"
27
+ opts.separator ""
28
+ opts.separator "Common options:"
29
+
30
+ # No argument, shows at tail. This will print an options summary.
31
+ opts.on_tail("-?", "--help", "Show this message") do
32
+ puts opts
33
+ exit
34
+ end
35
+
36
+ opts.on_tail("-v", "--version", "Show version") do
37
+ puts "ncal2gcal 0.1.0"
38
+ exit
39
+ end
40
+
41
+ opts.on_tail "\n(c) 2009, 2010 Elias Kugler"
42
+
43
+ end
44
+
45
+ opts.parse! ARGV
46
+
47
+ if defined?Ocra
48
+ exit
49
+ else
50
+ if ARGV.length != 1
51
+ puts opts
52
+ exit
53
+ end
54
+ conf[:command] = ARGV[0]
55
+ end
56
+
57
+ # --------------------------------------------------
58
+ #
59
+ # --------------------------------------------------
60
+ if conf[:command] == 'sync'
61
+ ngsync = NCal2GCal::NotesGoogleSync.new(conf)
62
+ ngsync.sync_events
63
+ else
64
+ puts opts
65
+ exit
66
+ end
@@ -0,0 +1,33 @@
1
+ require 'rubygems'
2
+ require 'gcal4ruby'
3
+
4
+ module NCal2GCal
5
+
6
+ class GoogleCalendar
7
+ attr_accessor :user, :password, :calendar
8
+ attr_reader :events
9
+ def initialize(params)
10
+ @user = params[:gmail_user]
11
+ @password = params[:gmail_password]
12
+ @calendar = params[:gmail_calendar] || "LotusNotes"
13
+
14
+ service = GCal4Ruby::Service.new
15
+ service.authenticate(@user, @password )
16
+ @cal = GCal4Ruby::Calendar.find(service, @calendar, {:scope => :first})
17
+ end
18
+ def find_event(id)
19
+ return GCal4Ruby::Event.find(@cal, id)
20
+ end
21
+ def new_event
22
+ return GCal4Ruby::Event.new(@cal)
23
+ end
24
+ def del_event(id)
25
+ event = find_event(id)
26
+ if event
27
+ return event.delete unless event == []
28
+ end
29
+ return false
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,136 @@
1
+ require 'win32ole'
2
+
3
+ module NCal2GCal
4
+ class EventRepeat
5
+ attr_accessor :start_time, :end_time
6
+ def initialize
7
+ end
8
+ end
9
+ class LotusNotesCalendar
10
+ attr_accessor :server, :user, :password, :db
11
+ attr_reader :events
12
+ def initialize(params)
13
+ @server = params[:notes_server] || '' # local
14
+ @user = params[:notes_user]
15
+ @password = params[:notes_password]
16
+ @db = params[:notes_db]
17
+
18
+ session = WIN32OLE.new 'Lotus.NotesSession'
19
+ session.Initialize(@password)
20
+ db = session.GetDatabase(@server, @db)
21
+ raise "unable to open database: #{db}" unless db.isOpen
22
+
23
+ @events = LotusNotesEvents.new(db.GetView("$Calendar"))
24
+ raise "$Calendar View not found" unless @events
25
+ end
26
+ end
27
+ class LotusNotesEvents
28
+ def initialize(view)
29
+ @calendar_view = view
30
+ end
31
+ def each
32
+ max = 2000
33
+ count = 0
34
+
35
+ uid_list = {}
36
+ entry = @calendar_view.GetLastDocument
37
+ while entry #and count < max
38
+ begin
39
+ count +=1
40
+ if !entry.IsDeleted
41
+ event = LotusNotesEvent.new(entry)
42
+ if !uid_list[event.uid]
43
+ if event.supported?
44
+ yield(event)
45
+ else
46
+ $logger.warn "not supported appointmenttype: " + (event.appointmenttype.to_s || "appointmenttype missing")
47
+ end
48
+ uid_list[event.uid]=true
49
+ end
50
+ end
51
+ rescue StandardError => e
52
+ print 'X'
53
+ $logger.error DateTime.now.to_s
54
+ $logger.error e
55
+ $logger.error entry
56
+ end
57
+ entry = @calendar_view.GetPrevDocument(entry)
58
+ end
59
+ end
60
+ end
61
+ class LotusNotesEvent
62
+ APPOINTMENTTYPE = {'0' =>:appointment,
63
+ '1' => :anniversary,
64
+ '2' => :all_day_event,
65
+ '3' => :meeting,
66
+ '4' => :reminder}
67
+ attr_accessor :uid,
68
+ :subject,
69
+ :where,
70
+ :start_time, :end_time,
71
+ :last_modified, #
72
+ :appointmenttype,
73
+ :content,
74
+ :repeats
75
+
76
+ def initialize(notes_event)
77
+ @uid = notes_event.UniversalID
78
+ if notes_event.GetFirstItem("Subject")
79
+ @subject = notes_event.GetFirstItem("Subject").Values[0]
80
+ else
81
+ @subject = ''
82
+ $logger.warn 'no subject. uid: '+@uid
83
+ end
84
+ if notes_event.GetFirstItem("ROOM")
85
+ @where = notes_event.GetFirstItem("ROOM").Values[0]
86
+ elsif notes_event.GetFirstItem("Location")
87
+ @where = notes_event.GetFirstItem("Location").Values[0]
88
+ else
89
+ @where = ''
90
+ end
91
+ @start_time = notes_event.GetFirstItem("Startdatetime").Values[0] if notes_event.GetFirstItem("Startdatetime")
92
+ @end_time = notes_event.GetFirstItem("EndDatetime").Values[0] if notes_event.GetFirstItem("EndDatetime")
93
+ if notes_event.GetFirstItem("APPOINTMENTTYPE")
94
+ @appointmenttype = APPOINTMENTTYPE[notes_event.GetFirstItem("APPOINTMENTTYPE").Values[0]]
95
+ end
96
+ @last_modified = DateTime.parse(notes_event.LastModified)
97
+ @content = ''
98
+ body = notes_event.GetFirstItem("Body")
99
+ if body
100
+ @content = body.Values unless body.Values.is_a? Array
101
+ end
102
+
103
+ fill_repeats(notes_event)
104
+ end
105
+ def all_day?
106
+ @appointmenttype and (@appointmenttype == :all_day_event or @appointmenttype == :anniversary)
107
+ end
108
+ def supported?
109
+ # anniversaries are now (v.0.0.7) supported
110
+ @appointmenttype #and (@appointmenttype != :anniversary)
111
+ end
112
+ def repeats?
113
+ @repeats.size > 1
114
+ end
115
+ def fill_repeats(notes_event)
116
+ @repeats = []
117
+ sdts = notes_event.GetFirstItem("Startdatetime")
118
+ edts = notes_event.GetFirstItem("EndDatetime")
119
+ return unless sdts
120
+ sdts.Values.each_with_index do |val, idx |
121
+ r = EventRepeat.new
122
+ r.start_time = val
123
+ if edts
124
+ r.end_time = edts.Values[idx]
125
+ else
126
+ $logger.warn "EndDatetime default"
127
+ $logger.warn @subject
128
+ $logger.warn r.start_time
129
+
130
+ r.end_time = r.start_time
131
+ end
132
+ @repeats << r
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,262 @@
1
+ require 'rubygems'
2
+ require 'log4r'
3
+ require 'uri'
4
+ require 'date'
5
+ require 'dm-core'
6
+ require 'fileutils'
7
+ require 'ncal2gcal/lotus_notes_calendar'
8
+ require 'ncal2gcal/google_calendar'
9
+
10
+ class String
11
+ def asciify()
12
+ str = self
13
+ # ----------------------------------------------------------------
14
+ # Sonderzeichenbehandlung
15
+ # ----------------------------------------------------------------
16
+ str = str.gsub(/\334/,"Ü") # �
17
+ str = str.gsub(/\374/,"ü") # �
18
+ str = str.gsub(/\326/,"Ö") # �
19
+ str = str.gsub(/\366/,"ö") # �
20
+ str = str.gsub(/\304/,"Ä") # �
21
+ str = str.gsub(/\344/,"ä") # �
22
+ str = str.gsub(/\337/,"ß") # �
23
+ # bez_neu = Iconv.conv('UTF-8','CP850', bez_neu)
24
+ #str = str.gsub(/([^\d\w\s\.\[\]-])/, '')
25
+ return str
26
+ end
27
+ end
28
+
29
+
30
+ module NCal2GCal
31
+ raise "environment variable %APPDATA% not set" unless ENV['APPDATA']
32
+ FileUtils::cd(ENV['APPDATA'])
33
+ FileUtils::mkdir_p('ncal2gcal')
34
+
35
+ db_file = "#{Dir.pwd}/ncal2gcal/ncal2gcal.sqlite"
36
+ DataMapper::setup(:default, "sqlite3://#{db_file}")
37
+
38
+ class Counter
39
+ attr_accessor :updates, :inserts, :deletes, :selects, :ignored, :t_start, :t_end
40
+
41
+ def initialize
42
+ @updates = 0
43
+ @inserts = 0
44
+ @deletes = 0
45
+ @selects = 0
46
+ @ignored = 0
47
+ start
48
+ end
49
+ def runtime
50
+ @t_end - @t_start
51
+ end
52
+ def start
53
+ @t_start = Time.now
54
+ end
55
+ def end
56
+ @t_end = Time.now
57
+ end
58
+ def show
59
+ puts "\nStatistics:"
60
+ puts "-"*20
61
+ puts sprintf("Inserts : %05d", @inserts)
62
+ puts sprintf("Updates : %05d", @updates)
63
+ puts sprintf("Deletes : %05d", @deletes)
64
+ puts sprintf("Ingored : %05d", @ignored)
65
+ puts "-"*20
66
+ puts sprintf("Total : %05d", @selects)
67
+ puts "Runtime : #{runtime} sec"
68
+ end
69
+ end
70
+
71
+ class NotesGoogleSync
72
+ def initialize(params)
73
+ @notes_calendar = NCal2GCal::LotusNotesCalendar.new(params)
74
+ @google_calendar = NCal2GCal::GoogleCalendar.new(params)
75
+
76
+ @sync_time = nil
77
+ if params[:days]
78
+ @min_sync_time = DateTime.now-params[:days] #*86400
79
+ end
80
+ if params[:days_max]
81
+ @max_sync_time = DateTime.now+params[:days_max] #*86400
82
+ else
83
+ @max_sync_time = DateTime.now+400 #*86400
84
+ end
85
+ @max_time = DateTime.parse("2038-01-18")
86
+ # do not sync the description unless the users wants to
87
+ @sync_desc = params[:sync_desc] # || true
88
+
89
+ init_logger
90
+ end
91
+ def init_logger
92
+ FileUtils::mkdir_p('ncal2gcal')
93
+ $logger = Log4r::Logger.new("sync_logger")
94
+ Log4r::FileOutputter.new('logfile',
95
+ :filename=>"#{Dir.pwd}/ncal2gcal/ncal2gcal.log",
96
+ :trunc=>false,
97
+ :level=>Log4r::WARN)
98
+ $logger.add('logfile')
99
+ end
100
+ def sync_events
101
+ @counter = Counter.new
102
+ @sync_time = DateTime.now
103
+ sleep(1)
104
+
105
+ @notes_calendar.events.each do |notes_event|
106
+ @counter.selects += 1
107
+ if notes_event.repeats?
108
+ notes_event.repeats.each do |r|
109
+ sync_event(notes_event, r.start_time, r.end_time, notes_event.uid+'_'+r.start_time)
110
+ end
111
+ else
112
+ #p notes_event.repeats
113
+ sync_event(notes_event, notes_event.start_time, notes_event.end_time, notes_event.uid)
114
+ end
115
+ end
116
+ del_events()
117
+ @counter.end
118
+ return @counter
119
+ end
120
+
121
+ def sync_event(notes_event, start_time, end_time, key)
122
+ sdt = DateTime.parse(start_time)
123
+ return unless sdt < @max_time # workaround
124
+
125
+ if end_time
126
+ edt = DateTime.parse(end_time)
127
+ return unless edt < @max_time # workaround
128
+ end
129
+
130
+ #puts DateTime.parse(notes_event.end_time)
131
+
132
+ if (@min_sync_time and end_time and
133
+ @min_sync_time > DateTime.parse(end_time)) or
134
+ (@max_sync_time and start_time and
135
+ @max_sync_time < DateTime.parse(start_time))
136
+ then
137
+ @counter.ignored +=1
138
+ else
139
+ #p key
140
+ sync_entry = NCal2GCal::SyncEntry.first(:lotus_notes_uid => key)
141
+ if sync_entry
142
+ then
143
+ #puts DateTime.parse(notes_event.end_time)
144
+ #p sync_entry.lotus_notes_last_modified.to_s
145
+ #p notes_event.last_modified
146
+ if sync_entry.lotus_notes_last_modified < notes_event.last_modified
147
+ then
148
+ #!!insert_update(sync_entry,notes_event)
149
+ insert_update(sync_entry,notes_event, start_time, end_time, key)
150
+ else
151
+ print "."
152
+ @counter.ignored +=1
153
+ sync_entry.sync_time = @sync_time
154
+ sync_entry.sync_action = 'N' # none
155
+ sync_entry.save
156
+ end
157
+ else
158
+ add_event(notes_event, start_time, end_time, key)
159
+ end
160
+ end
161
+ end
162
+
163
+ def del_events
164
+ NCal2GCal::SyncEntry.all(:sync_time.lt => @sync_time).each do |sync_entry|
165
+ @counter.deletes += 1
166
+ if @google_calendar.del_event(sync_entry.gcal_id)
167
+ print "D"
168
+ sync_entry.destroy
169
+ else
170
+ sync_entry.sync_time = @sync_time
171
+ sync_entry.sync_action = 'E'
172
+ sync_entry.save
173
+ print "E"
174
+ end
175
+ end
176
+ end
177
+ def init_google_event(notes_event,start_time,end_time)
178
+ event = @google_calendar.new_event
179
+ google_event= set_google_event_attrs(notes_event, event,start_time,end_time )
180
+ google_event.start = start_time
181
+ google_event.end = end_time
182
+ return google_event
183
+ end
184
+ def set_google_event_attrs(notes_event, google_event,start_time=nil,end_time=nil)
185
+ google_event.title = notes_event.subject.asciify if notes_event.subject
186
+ if start_time
187
+ google_event.start = start_time
188
+ else
189
+ google_event.start = notes_event.start_time
190
+ end
191
+ if end_time
192
+ google_event.end = end_time
193
+ else
194
+ google_event.end = notes_event.end_time
195
+ end
196
+ google_event.where = notes_event.where.asciify if notes_event.where
197
+ google_event.all_day = notes_event.all_day?
198
+ google_event.content = notes_event.content.asciify if @sync_desc
199
+
200
+ return google_event
201
+ end
202
+ def get_sync_entry_by_notes_uid(uid)
203
+ e1 = NCal2GCal::SyncEntry.first(:lotus_notes_uid => uid)
204
+ return e1
205
+ end
206
+ def insert_update(sync_entry,notes_event, start_time, end_time, key)
207
+ gcal_event = @google_calendar.find_event(sync_entry.gcal_id)
208
+ if gcal_event == []
209
+ $logger.warn "Event not found for update"
210
+ add_event(notes_event,start_time, end_time,key)
211
+ else
212
+ update_event(sync_entry, notes_event, gcal_event, start_time, end_time)
213
+ end
214
+ end
215
+
216
+ def add_event(notes_event, start_time, end_time, key)
217
+ print "I"
218
+ google_event=init_google_event(notes_event, start_time, end_time)
219
+ ret = google_event.save
220
+ $logger.fatal "insert: cannot save gcal event" unless ret
221
+ raise "cannot save gcal event" unless ret
222
+ @counter.inserts +=1
223
+ sync_entry = NCal2GCal::SyncEntry.new
224
+ sync_entry.lotus_notes_uid = key #notes_event.uid
225
+ sync_entry.sync_time = @sync_time
226
+ sync_entry.lotus_notes_last_modified = notes_event.last_modified
227
+ sync_entry.gcal_id = google_event.id
228
+ sync_entry.sync_action = 'I' # insert
229
+ sync_entry.save
230
+ end
231
+ def update_event(sync_entry, notes_event, gcal_event, start_time, end_time)
232
+ print "U"
233
+ @counter.updates +=1
234
+ set_google_event_attrs(notes_event, gcal_event, start_time, end_time)
235
+ ret = gcal_event.save
236
+ $logger.fatal "update: cannot save gcal event" unless ret
237
+ raise "cannot save gcal event" unless ret
238
+ sync_entry.sync_time = @sync_time
239
+ sync_entry.gcal_id = gcal_event.id
240
+ sync_entry.lotus_notes_last_modified = notes_event.last_modified
241
+ sync_entry.sync_action = 'U' # none
242
+ sync_entry.save
243
+ end
244
+ end
245
+
246
+ class SyncEntry
247
+ include DataMapper::Resource
248
+ #storage_names[:repo] = 'ncal2gal_sync_entries'
249
+
250
+ property :id, Serial
251
+ property :sync_time, DateTime
252
+ property :sync_action, String
253
+
254
+ property :lotus_notes_uid, Text, :index=>true
255
+ property :lotus_notes_last_modified, DateTime
256
+ property :gcal_id, Text
257
+
258
+ end
259
+
260
+ # automatically create the SyncEntry table
261
+ SyncEntry.auto_migrate! unless File.exists?(db_file) #SyncEntry.table_exists?
262
+ end
data/ncal2gcal.gemspec ADDED
@@ -0,0 +1,31 @@
1
+ require "rubygems"
2
+
3
+ spec = Gem::Specification.new do |s|
4
+ s.name = %q{ncal2gcal}
5
+ s.version = "0.1.3"
6
+ s.authors = ["Elias Kugler"]
7
+ s.email = %q{groesser3@gmail.com}
8
+ s.files = Dir["lib/**/*"] + Dir["bin/**/*"] + Dir["*.rb"] + ["MIT-LICENSE","ncal2gcal.gemspec"]
9
+ s.platform = Gem::Platform::RUBY
10
+ s.has_rdoc = true
11
+ s.extra_rdoc_files = ["README.rdoc"]
12
+ s.require_paths = ["lib"]
13
+ s.summary = %q{Sync your Lotus Notes calendar with your Google calendar}
14
+ s.files.reject! { |fn| fn.include? "CVS" }
15
+ s.require_path = "lib"
16
+ s.default_executable = %q{ncal2gcal}
17
+ s.executables = ["ncal2gcal"]
18
+ s.homepage = %q{http://ncal2gcal.rubyforge.org}
19
+ s.rubyforge_project = %q{ncal2gcal}
20
+ s.add_dependency("dm-core", ">= 0.10.0")
21
+ s.add_dependency("do_sqlite3", ">= 0.10.0")
22
+ s.add_dependency("gcal4ruby", ">=0.2.8")
23
+ s.add_dependency("log4r", ">=1.0.5")
24
+
25
+ end
26
+
27
+
28
+ if $0 == __FILE__
29
+ Gem.manage_gems
30
+ Gem::Builder.new(spec).build
31
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ncal2gcal
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.3
5
+ platform: ruby
6
+ authors:
7
+ - Elias Kugler
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-29 00:00:00 +01:00
13
+ default_executable: ncal2gcal
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: dm-core
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.10.0
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: do_sqlite3
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.10.0
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: gcal4ruby
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 0.2.8
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: log4r
47
+ type: :runtime
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 1.0.5
54
+ version:
55
+ description:
56
+ email: groesser3@gmail.com
57
+ executables:
58
+ - ncal2gcal
59
+ extensions: []
60
+
61
+ extra_rdoc_files:
62
+ - README.rdoc
63
+ files:
64
+ - lib/ncal2gcal/google_calendar.rb
65
+ - lib/ncal2gcal/lotus_notes_calendar.rb
66
+ - lib/ncal2gcal/sync.rb
67
+ - bin/ncal2gcal
68
+ - MIT-LICENSE
69
+ - ncal2gcal.gemspec
70
+ - README.rdoc
71
+ has_rdoc: true
72
+ homepage: http://ncal2gcal.rubyforge.org
73
+ licenses: []
74
+
75
+ post_install_message:
76
+ rdoc_options: []
77
+
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: "0"
85
+ version:
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: "0"
91
+ version:
92
+ requirements: []
93
+
94
+ rubyforge_project: ncal2gcal
95
+ rubygems_version: 1.3.5
96
+ signing_key:
97
+ specification_version: 3
98
+ summary: Sync your Lotus Notes calendar with your Google calendar
99
+ test_files: []
100
+