vigetlabs-dockit 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2007 Viget Labs
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/Manifest ADDED
@@ -0,0 +1,19 @@
1
+ config
2
+ config/users.yml
3
+ lib
4
+ lib/dockit.rb
5
+ lib/export.rb
6
+ lib/tony.pitale.ics
7
+ LICENSE
8
+ pkg
9
+ Rakefile
10
+ rawresponse.txt
11
+ README
12
+ script
13
+ script/destroy
14
+ script/generate
15
+ spec
16
+ spec/dockit_spec.rb
17
+ spec/spec_helper.rb
18
+ TODO
19
+ Manifest
data/README ADDED
@@ -0,0 +1,43 @@
1
+ dockit
2
+ =================
3
+
4
+ A rack application daemon that creates an iCal subscription file from exchange calendars.
5
+
6
+ Install
7
+ -----------------
8
+ sudo gem install dockit # if you've cloned from github
9
+
10
+ # else
11
+
12
+ sudo gem install vigetlabs-dockit -s http://gems.github.com
13
+
14
+ Configure
15
+ -----------------
16
+
17
+ Simply set up a file, .dockit, in your home directory with your username, domain, and the
18
+ url of your exchange server. Leave the domain blank if your login for exchange is NOT your
19
+ email address. If you leave domain blank, change the resulting url to simply reflect your
20
+ username, with the @domain.com. The port too, if not 2000, should be changed.
21
+
22
+ Example .dockit Configuration
23
+ -----------------
24
+
25
+ default:
26
+ username: john.doe
27
+ domain: example.com
28
+ password: password
29
+ remote_uri: http://mail.example.com/exchange/john.doe@example.com/
30
+ local_port: 2000
31
+ timezone: US/Eastern
32
+
33
+ The resulting url for subscribing in iCal when running this daemon on the localhost would be:
34
+ http://localhost:2000/john.doe.ics
35
+
36
+ Timezones are include US/ Eastern,Pacific,Mountain or any other standard format.
37
+ See iCal's options for timezones for a complete listing.
38
+
39
+ Starting the Daemon
40
+ -----------------
41
+ Given the yaml file defined example, the command would be:
42
+
43
+ dockit default (or in the case of default, just dockit)
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+
4
+ task :gem do
5
+ system('gem build dockit.gemspec')
6
+ end
7
+
8
+ task :install => [:package] do
9
+ sh %{sudo gem install pkg/#{GEM}-#{VERSION}}
10
+ end
data/TODO ADDED
@@ -0,0 +1,6 @@
1
+ TODO
2
+ -----------------
3
+ Start/Stop/Restart scripting
4
+ User selection from url
5
+ Include and configure todos, journals, free/busy time
6
+ Failed connection error handling
data/bin/dockit ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by RubyGems.
4
+ #
5
+ # The application 'dockit' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'rubygems'
10
+ require 'dockit'
11
+ # require "optparse"
12
+
13
+ config = ARGV.first || 'default'
14
+
15
+ Dockit.new(config).run
16
+
17
+ # TODO start/stop daemon
data/lib/dockit.rb ADDED
@@ -0,0 +1,35 @@
1
+ require 'rubygems'
2
+ require 'rack'
3
+ require 'yaml'
4
+ require 'activesupport'
5
+
6
+ require "export"
7
+ require "user"
8
+
9
+ class Dockit
10
+ include Export
11
+
12
+ attr_accessor :user, :pid
13
+
14
+ def initialize(config)
15
+ # Get configuration information
16
+ config_file = YAML.load_file(File.join(ENV['HOME'], ".dockit"))
17
+
18
+ user_config = config_file && config_file.has_key?(config) ?
19
+ config_file[config] : config_file['default']
20
+
21
+ raise "No .dockit file found with user section: #{config}!" unless user_config
22
+
23
+ @user = User.new(user_config)
24
+ end
25
+
26
+ def run
27
+ @pid = fork do
28
+ Rack::Handler::Mongrel.run(rack_process(@user), :Port => @user.local_port)
29
+ end
30
+
31
+ Process.detach(@pid)
32
+
33
+ puts "Use sudo kill #{@pid} to stop this process."
34
+ end
35
+ end
data/lib/event.rb ADDED
@@ -0,0 +1,22 @@
1
+ require 'event_collection'
2
+
3
+ class Event
4
+ def initialize(event)
5
+ @event = event
6
+ end
7
+
8
+ def dformat(t)
9
+ t.strftime('%Y%m%dT%H%M%S')
10
+ end
11
+
12
+ def method_missing(methodname, *args)
13
+ @event.send(methodname, *args)
14
+ end
15
+
16
+ def to_ics
17
+ filename = File.join(File.dirname(__FILE__), "templates", "event.ics.erb")
18
+ file = IO.read(filename)
19
+
20
+ ERB.new(file).result(binding)
21
+ end
22
+ end
@@ -0,0 +1,36 @@
1
+ class EventCollection
2
+ def initialize
3
+ @collection = []
4
+ end
5
+
6
+ def size
7
+ @collection.size
8
+ end
9
+
10
+ def <<(event)
11
+ @collection << event if event
12
+ end
13
+
14
+ def to_ics
15
+ filename = File.join(File.dirname(__FILE__), "templates", "event_collection.ics.erb")
16
+ file = IO.read(filename)
17
+ ERB.new(file).inspect
18
+ end
19
+
20
+ def self.user=(user)
21
+ @user = user ? user : @user || User.new({})
22
+ end
23
+
24
+ def self.user
25
+ @user ||= User.new({})
26
+ end
27
+
28
+ def self.all(&block)
29
+ self.user=(nil) unless @user
30
+ RExchange.open(@user.remote_uri, @user.email, @user.password) do |mailbox|
31
+ mailbox.calendar.each do |event|
32
+ @collection << Event.new(event)
33
+ end
34
+ end
35
+ end
36
+ end
data/lib/export.rb ADDED
@@ -0,0 +1,89 @@
1
+ require 'rexchange'
2
+ require 'chronic'
3
+
4
+ module Export
5
+ def rack_process(user)
6
+ lambda do |env|
7
+ # puts user.inspect
8
+ exchange(user)
9
+
10
+ Rack::File.new('.').call(env)
11
+ end
12
+ end
13
+
14
+ def exchange(user)
15
+ RExchange::open(user.remote_uri, user.email, user.password) do |mailbox|
16
+
17
+ # create ics file, clearing any old one
18
+ file = File.new("#{user.username}.ics", "w")
19
+ raise "Failed to create file #{user.username}.ics" unless file
20
+
21
+ file.puts "BEGIN:VCALENDAR"
22
+ file.puts "CALSCALE:GREGORIAN"
23
+ file.puts "PRODID:-//Apple Computer\, Inc//iCal 2.0//EN"
24
+ file.puts "VERSION:2.0"
25
+ file.puts "X-WR-CALNAME:#{user.title}"
26
+
27
+ # itemcount = 0
28
+
29
+ # Loop through all calendar events, making VEVENTS
30
+ mailbox.calendar.each do |event|
31
+
32
+ file.puts "BEGIN:VEVENT"
33
+
34
+ # Set some properties for this event
35
+ file.puts "DTSTAMP;TZID=#{user.timezone}:#{dformat(event.created_at)}"
36
+ file.puts "DTSTART;TZID=#{user.timezone}:#{dformat(event.start_at)}"
37
+ file.puts "DTEND;TZID=#{user.timezone}:#{dformat(event.end_at)}"
38
+ file.puts "LAST-MODIFIED;TZID=#{user.timezone}:#{dformat(event.modified_at)}"
39
+
40
+ file.puts "SUMMARY:" + (event.subject.blank? ? "Unknown Subject" : event.subject)
41
+
42
+ description = event.body.blank? ? "" : event.body.gsub!("\n","\\n").gsub("^\n","")
43
+ # ?? add event.href+"?Cmd=accept" or "decline" or "tentative"
44
+ # description += event.href+"?Cmd=accept"
45
+ # description += event.href+"?Cmd=decline"
46
+ # description += event.href+"?Cmd=tentative"
47
+
48
+ file.puts "DESCRIPTION:" + description
49
+
50
+ file.puts "UID:" + event.uid if event.uid
51
+
52
+ if event.reminder_offset && event.reminder_offset.to_i > 60
53
+ # ouput valarm details. reminder_offset is in seconds
54
+ ro_min = event.reminder_offset.to_i / 60
55
+ file.puts "BEGIN:VALARM"
56
+ file.puts "TRIGGER:-PT#{ro_min}M"
57
+ # item.puts "DESCRIPTION:Påminnelse om aktivitet"
58
+ file.puts "ACTION:DISPLAY"
59
+ file.puts "END:VALARM"
60
+ end
61
+
62
+ #add event to calendar
63
+ file.puts "END:VEVENT"
64
+
65
+ # itemcount += 1
66
+ end
67
+
68
+ # puts mailbox.inspect
69
+ # puts
70
+ # puts mailbox.methods
71
+
72
+ # Loop through all todos, creating VTODOS
73
+ # Loop through all journals, creating VJOURNAL
74
+ # Loop through all free/busy time, creating VFREEBUSY
75
+ # event.busy_status
76
+
77
+ #close ical file
78
+ file.puts "END:VCALENDAR"
79
+ file.close
80
+
81
+ # p "Done! Wrote #{itemcount} appointment items"
82
+
83
+ end
84
+ end
85
+
86
+ def dformat(t)
87
+ t.strftime('%Y%m%dT%H%M%S')
88
+ end
89
+ end
@@ -0,0 +1,21 @@
1
+ BEGIN:VEVENT
2
+ DTSTAMP;TZID=<%= EventCollection.user.timezone %>:<%= dformat(@event.created_at) %>
3
+ DTSTART;TZID=<%= EventCollection.user.timezone %>:<%= dformat(@event.start_at) %>
4
+ DTEND;TZID=<%= EventCollection.user.timezone %>:<%= dformat(@event.end_at) %>
5
+ LAST-MODIFIED;TZID=<%= EventCollection.user.timezone %>:<%= dformat(@event.modified_at) %>
6
+
7
+ SUMMARY:<%= (@event.subject.blank? ? "Unknown Subject" : @event.subject) %>
8
+ <% description = @event.body.blank? ? "" : @event.body.gsub("\n","\\n").gsub("^\n","") %>
9
+
10
+ DESCRIPTION: <%= description %>
11
+ UID:<%= @event.uid if @event.uid %>
12
+
13
+ <% if @event.reminder_offset && @event.reminder_offset.to_i > 60 %>
14
+ <% ro_min = @event.reminder_offset.to_i / 60 %>
15
+ BEGIN:VALARM
16
+ TRIGGER:-PT<%= ro_min %>M
17
+ ACTION:DISPLAY
18
+ END:VALARM
19
+ <% end %>
20
+
21
+ END:VEVENT
@@ -0,0 +1,11 @@
1
+ BEGIN:VCALENDAR
2
+ CALSCALE:GREGORIAN
3
+ PRODID:-//Apple Computer\, Inc//iCal 2.0//EN
4
+ VERSION:2.0
5
+ X-WR-CALNAME:<%= @user.title %>
6
+
7
+ <% for event in @collection do %>
8
+ <% event.to_ics %>
9
+ <% end %>
10
+
11
+ END:VCALENDAR
data/lib/user.rb ADDED
@@ -0,0 +1,35 @@
1
+ class User
2
+ attr_accessor :username,
3
+ :domain,
4
+ :email,
5
+ :password,
6
+ :timezone,
7
+ :remote_uri,
8
+ :local_port,
9
+ :title
10
+
11
+ def initialize(config)
12
+ config.symbolize_keys!
13
+
14
+ self.username = config.fetch(:username, ENV['USER'])
15
+ self.domain = config.fetch(:domain, 'localhost')
16
+ self.email = "#{self.username}"
17
+ self.email << "@#{self.domain}" unless self.domain.blank?
18
+ self.password = config.fetch(:password, "password")
19
+ self.timezone = config.fetch(:timezone, "US/Eastern")
20
+ self.remote_uri = config.fetch(:remote_uri, "http://localhost/#{self.email}/")
21
+ self.local_port = config.fetch(:local_port, 2000)
22
+ self.title = config.fetch(:title, self.username)
23
+ end
24
+
25
+ def to_hash
26
+ {:username => self.username,
27
+ :domain => self.domain,
28
+ :email => self.email,
29
+ :password => self.password,
30
+ :timezone => self.timezone,
31
+ :remote_uri => self.remote_uri,
32
+ :local_port => self.local_port,
33
+ :title => self.title}
34
+ end
35
+ end
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vigetlabs-dockit
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.1"
5
+ platform: ruby
6
+ authors:
7
+ - Tony Pitale @ Viget Labs
8
+ autorequire: dockit
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-05-14 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rexchange
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.3.4
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: rack
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: 0.3.0
32
+ version:
33
+ - !ruby/object:Gem::Dependency
34
+ name: chronic
35
+ version_requirement:
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.2.3
41
+ version:
42
+ - !ruby/object:Gem::Dependency
43
+ name: activesupport
44
+ version_requirement:
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ - !ruby/object:Gem::Dependency
52
+ name: erb
53
+ version_requirement:
54
+ version_requirements: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ description: A rack application daemon that creates an iCal subscription file from exchange calendars.
61
+ email: tony.pitale@viget.com
62
+ executables:
63
+ - dockit
64
+ extensions: []
65
+
66
+ extra_rdoc_files:
67
+ - README
68
+ - LICENSE
69
+ - TODO
70
+ files:
71
+ - LICENSE
72
+ - README
73
+ - Rakefile
74
+ - TODO
75
+ - Manifest
76
+ - lib/dockit.rb
77
+ - lib/export.rb
78
+ - lib/event_collection.rb
79
+ - lib/event.rb
80
+ - lib/user.rb
81
+ - lib/templates
82
+ - lib/templates/event_collection.ics.erb
83
+ - lib/templates/event.ics.erb
84
+ has_rdoc: false
85
+ homepage: http://www.viget.com/extend/
86
+ post_install_message:
87
+ rdoc_options: []
88
+
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: "0"
96
+ version:
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: "0"
102
+ version:
103
+ requirements: []
104
+
105
+ rubyforge_project:
106
+ rubygems_version: 1.0.1
107
+ signing_key:
108
+ specification_version: 2
109
+ summary: A rack application daemon that creates an iCal subscription file from exchange calendars.
110
+ test_files: []
111
+