vpim 0.695 → 13.11.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/{README → README.rdoc} +2 -13
- data/lib/vpim.rb +1 -0
- data/lib/vpim/address.rb +3 -2
- data/lib/vpim/agent/atomize.rb +4 -0
- data/lib/vpim/agent/base.rb +74 -0
- data/lib/vpim/agent/calendars.rb +1 -0
- data/lib/vpim/agent/handler.rb +27 -0
- data/lib/vpim/agent/ics.rb +162 -0
- data/lib/vpim/attachment.rb +1 -0
- data/lib/vpim/date.rb +3 -2
- data/lib/vpim/dirinfo.rb +5 -4
- data/lib/vpim/duration.rb +1 -0
- data/lib/vpim/enumerator.rb +1 -0
- data/lib/vpim/field.rb +3 -2
- data/lib/vpim/icalendar.rb +9 -5
- data/lib/vpim/maker/vcard.rb +1 -0
- data/lib/vpim/property/base.rb +1 -0
- data/lib/vpim/property/common.rb +1 -0
- data/lib/vpim/property/location.rb +10 -0
- data/lib/vpim/property/priority.rb +2 -1
- data/lib/vpim/property/recurrence.rb +1 -0
- data/lib/vpim/property/resources.rb +1 -2
- data/lib/vpim/repo.rb +2 -1
- data/lib/vpim/rfc2425.rb +32 -24
- data/lib/vpim/rrule.rb +9 -8
- data/lib/vpim/time.rb +1 -0
- data/lib/vpim/vcard.rb +13 -11
- data/lib/vpim/version.rb +2 -2
- data/lib/vpim/vevent.rb +3 -1
- data/lib/vpim/view.rb +3 -2
- data/lib/vpim/vjournal.rb +1 -0
- data/lib/vpim/vpim.rb +2 -1
- data/lib/vpim/vtodo.rb +1 -0
- data/samples/agent.ru +10 -0
- data/test/test_all.rb +2 -0
- data/test/test_date.rb +6 -5
- data/test/test_dur.rb +1 -0
- data/test/test_field.rb +3 -2
- data/test/test_ical.rb +12 -2
- data/test/test_misc.rb +13 -0
- data/test/test_repo.rb +22 -2
- data/test/test_rrule.rb +1 -0
- data/test/test_vcard.rb +53 -1
- metadata +36 -46
- data/lib/vpim/agent/app.rb +0 -194
- data/lib/vpim/agent/main.rb +0 -327
- data/lib/vpim/agent/scraps.rb +0 -292
- data/test/test_agent_app.rb +0 -74
- data/test/test_agent_atomize.rb +0 -84
- data/test/test_agent_calendars.rb +0 -128
- data/test/test_view.rb +0 -79
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 097fd14cb6df0e01acccdc8b8724ce42b3b0a6ff
|
4
|
+
data.tar.gz: d6f031737c9c3c5fb4ba0676644f01c8db8966cb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cfb7b213e0094b6e9a3e2819b777325ff4e8454bebc8c981b8747e56119e311d58b10573b8bf4054c02a62982344eaa08b9b635d56833948e809fd776adc52b3
|
7
|
+
data.tar.gz: 1ebc4da3ad5a487425ed74c76437371537d5df8e264953f3de0c4ae11cc8d344f5f881872f61c77770a0e3b469860660d77d34818a02aa2979c0afdca853ddc6
|
data/{README → README.rdoc}
RENAMED
@@ -2,8 +2,7 @@ Author:: Sam Roberts <vieuxtech@gmail.com>
|
|
2
2
|
Copyright:: Copyright (C) 2008 Sam Roberts
|
3
3
|
License:: May be distributed under the same terms as Ruby
|
4
4
|
Homepage:: http://vpim.rubyforge.org
|
5
|
-
|
6
|
-
Install:: sudo gem install vpim
|
5
|
+
Install:: gem install vpim
|
7
6
|
|
8
7
|
vPim provides calendaring, scheduling, and contact support for Ruby through the
|
9
8
|
standard iCalendar and vCard data formats for "personal information" exchange.
|
@@ -18,17 +17,7 @@ standard iCalendar and vCard data formats for "personal information" exchange.
|
|
18
17
|
|
19
18
|
There is a vPim package installable using ruby-gems:
|
20
19
|
|
21
|
-
#
|
22
|
-
|
23
|
-
It is also installable in the standard way. Untar the package, and do:
|
24
|
-
|
25
|
-
$ ruby setup.rb --help
|
26
|
-
|
27
|
-
or do:
|
28
|
-
|
29
|
-
$ ruby setup.rb config
|
30
|
-
$ ruby setup.rb setup
|
31
|
-
# ruby setup.rb install (may require root privilege)
|
20
|
+
# gem install vpim (may require root privilege)
|
32
21
|
|
33
22
|
= Overview
|
34
23
|
|
data/lib/vpim.rb
CHANGED
data/lib/vpim/address.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
=begin
|
2
3
|
Copyright (C) 2008 Sam Roberts
|
3
4
|
|
@@ -139,7 +140,7 @@ module Vpim
|
|
139
140
|
if partstat
|
140
141
|
adr.partstat = partstat.first.strip.upcase
|
141
142
|
end
|
142
|
-
|
143
|
+
|
143
144
|
rsvp = field.param('RSVP')
|
144
145
|
|
145
146
|
if rsvp
|
@@ -163,7 +164,7 @@ module Vpim
|
|
163
164
|
value = uri.to_str.strip
|
164
165
|
|
165
166
|
if value.empty?
|
166
|
-
raise
|
167
|
+
raise Unencodeable, "Address#uri is zero-length"
|
167
168
|
end
|
168
169
|
|
169
170
|
params = {}
|
data/lib/vpim/agent/atomize.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
=begin
|
2
3
|
Copyright (C) 2009 Sam Roberts
|
3
4
|
|
@@ -52,6 +53,9 @@ module Vpim
|
|
52
53
|
if caluri
|
53
54
|
# This is maybe better described as :via, but with :alternate being
|
54
55
|
# an html view of this feed.
|
56
|
+
#
|
57
|
+
# TODO should I change the scheme to be webcal?
|
58
|
+
# TODO should I extend URI to support webcal?
|
55
59
|
f.links << Atom::Link.new do |l|
|
56
60
|
l.href = caluri
|
57
61
|
l.type = "text/calendar"
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
=begin
|
3
|
+
Copyright (C) 2009 Sam Roberts
|
4
|
+
|
5
|
+
This library is free software; you can redistribute it and/or modify it
|
6
|
+
under the same terms as the ruby language itself, see the file COPYING for
|
7
|
+
details.
|
8
|
+
=end
|
9
|
+
|
10
|
+
require 'cgi'
|
11
|
+
|
12
|
+
require 'sinatra/base'
|
13
|
+
|
14
|
+
# TODO Pasting of webcal links, conversion to webcal links?
|
15
|
+
|
16
|
+
module Vpim
|
17
|
+
module Agent
|
18
|
+
|
19
|
+
class Base < Sinatra::Base
|
20
|
+
# Ensure that this happens...
|
21
|
+
set :haml, :format=>:html4 # Appears to do nothing, but maybe it will some day...
|
22
|
+
|
23
|
+
def css(template)
|
24
|
+
render :css, template, {}
|
25
|
+
end
|
26
|
+
|
27
|
+
def render_css(template, data, options) # :nodoc:
|
28
|
+
data
|
29
|
+
end
|
30
|
+
|
31
|
+
# Complete path, as requested by the client. Take care about CGI path rewriting.
|
32
|
+
def request_path
|
33
|
+
# Using .to_s because rack/request.rb does, though I think the Rack
|
34
|
+
# spec requires these to be strings already.
|
35
|
+
begin
|
36
|
+
URI.parse(env["SCRIPT_URI"].to_s).path
|
37
|
+
rescue
|
38
|
+
env["SCRIPT_NAME"].to_s + env["PATH_INFO"].to_s
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Complete path, as requested by the client, without the env's PATH_INFO.
|
43
|
+
# This is the path to whatever is "handling" the request.
|
44
|
+
#
|
45
|
+
# Recent discussions on how PATH_INFO must be decoded leads me to think
|
46
|
+
# this might not work if the path had any URL encoded characters in it.
|
47
|
+
def script_path
|
48
|
+
request_path.sub(/#{env["PATH_INFO"]}$/, "")
|
49
|
+
end
|
50
|
+
|
51
|
+
# URL-ready form of the host and port, where the port isn't specified if
|
52
|
+
# it is the default for the URL scheme.
|
53
|
+
def host_port
|
54
|
+
r = request
|
55
|
+
host_port = r.host
|
56
|
+
|
57
|
+
if r.scheme == "https" && r.port != 443 ||
|
58
|
+
r.scheme == "http" && r.port != 80
|
59
|
+
host_port << ":#{r.port}"
|
60
|
+
end
|
61
|
+
|
62
|
+
host_port
|
63
|
+
end
|
64
|
+
|
65
|
+
# URL to the script
|
66
|
+
def script_url
|
67
|
+
request.scheme + "://" + host_port + script_path
|
68
|
+
end
|
69
|
+
|
70
|
+
end # Base
|
71
|
+
|
72
|
+
end # Agent
|
73
|
+
end # Vpim
|
74
|
+
|
data/lib/vpim/agent/calendars.rb
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
=begin
|
3
|
+
Copyright (C) 2009 Sam Roberts
|
4
|
+
|
5
|
+
This library is free software; you can redistribute it and/or modify it
|
6
|
+
under the same terms as the ruby language itself, see the file COPYING for
|
7
|
+
details.
|
8
|
+
=end
|
9
|
+
|
10
|
+
require 'sinatra/base'
|
11
|
+
|
12
|
+
# Auto-choose our handler based on the environment.
|
13
|
+
# TODO Code should be in Sinatra, and should handle Thin, Mongrel, etc.
|
14
|
+
Sinatra::Base.configure do
|
15
|
+
server = Sinatra::Base.server
|
16
|
+
Sinatra::Base.set :server, Proc.new {
|
17
|
+
if ENV.include?("PHP_FCGI_CHILDREN")
|
18
|
+
break "fastcgi" # Must NOT be the correct class name!
|
19
|
+
elsif ENV.include?("REQUEST_METHOD")
|
20
|
+
break "cgi" # Must NOT be the correct class name!
|
21
|
+
else
|
22
|
+
# Fall back on whatever it was going to be.
|
23
|
+
server
|
24
|
+
end
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,162 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
=begin
|
3
|
+
Copyright (C) 2009 Sam Roberts
|
4
|
+
|
5
|
+
This library is free software; you can redistribute it and/or modify it
|
6
|
+
under the same terms as the ruby language itself, see the file COPYING for
|
7
|
+
details.
|
8
|
+
=end
|
9
|
+
|
10
|
+
require 'cgi'
|
11
|
+
|
12
|
+
require 'vpim/agent/base'
|
13
|
+
require 'vpim/agent/atomize'
|
14
|
+
require 'vpim/repo'
|
15
|
+
require 'vpim/view'
|
16
|
+
|
17
|
+
require 'sinatra/base'
|
18
|
+
|
19
|
+
module Vpim
|
20
|
+
module Agent
|
21
|
+
|
22
|
+
class Ics < Base
|
23
|
+
use_in_file_templates!
|
24
|
+
|
25
|
+
def atomize(caluri, feeduri)
|
26
|
+
repo = Vpim::Repo::Uri.new(caluri)
|
27
|
+
cal = repo.find{true}
|
28
|
+
cal = View.week(cal)
|
29
|
+
feed = Agent::Atomize.calendar(cal, feeduri, caluri, cal.name)
|
30
|
+
return feed.to_xml, Agent::Atomize::MIME
|
31
|
+
end
|
32
|
+
|
33
|
+
## Route handlers:
|
34
|
+
def get_base(from)
|
35
|
+
@url_base = script_url # agent mount point
|
36
|
+
@url_ics = from # ics from here
|
37
|
+
@url_atom = nil # atom feed from here, if ics is accessible
|
38
|
+
@url_error= nil # error message, if is is not accessible
|
39
|
+
|
40
|
+
if not from.empty?
|
41
|
+
begin
|
42
|
+
atomize(from, "http://example.com")
|
43
|
+
@url_atom = @url_base + "/atom" + "?" + from
|
44
|
+
rescue
|
45
|
+
@url_error = CGI.escapeHTML($!.to_s)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
haml :"vpim/agent/ics/view"
|
50
|
+
end
|
51
|
+
|
52
|
+
# When we support other forms..
|
53
|
+
#get '/ics/:form' do
|
54
|
+
# form = params[:form]
|
55
|
+
def get_atom(caluri)
|
56
|
+
if caluri.empty?
|
57
|
+
redirect script_url
|
58
|
+
end
|
59
|
+
|
60
|
+
feeduri = script_url + "/atom?" + caluri
|
61
|
+
|
62
|
+
begin
|
63
|
+
xml, xmltype = atomize(caluri, feeduri)
|
64
|
+
content_type xmltype
|
65
|
+
body xml
|
66
|
+
rescue
|
67
|
+
redirect script_url + "?" + caluri
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def get_style
|
72
|
+
content_type 'text/css'
|
73
|
+
css :"vpim/agent/ics/style"
|
74
|
+
end
|
75
|
+
|
76
|
+
## Sinatra routing:
|
77
|
+
get '/?' do
|
78
|
+
get_base(env['QUERY_STRING'])
|
79
|
+
end
|
80
|
+
|
81
|
+
post "/?" do
|
82
|
+
redirect script_url + "?" + (params[:url] || "")
|
83
|
+
end
|
84
|
+
|
85
|
+
get "/atom" do
|
86
|
+
get_atom(env['QUERY_STRING'])
|
87
|
+
end
|
88
|
+
|
89
|
+
get '/style.css' do
|
90
|
+
get_style
|
91
|
+
end
|
92
|
+
|
93
|
+
end # Ics
|
94
|
+
|
95
|
+
end # Agent
|
96
|
+
end # Vpim
|
97
|
+
|
98
|
+
__END__
|
99
|
+
@@vpim/agent/ics/style
|
100
|
+
body {
|
101
|
+
background-color: gray;
|
102
|
+
}
|
103
|
+
h1 {
|
104
|
+
border-bottom: 3px solid #8B0000;
|
105
|
+
font-size: large;
|
106
|
+
}
|
107
|
+
form {
|
108
|
+
margin-left: 10%;
|
109
|
+
}
|
110
|
+
input.text {
|
111
|
+
width: 80%;
|
112
|
+
}
|
113
|
+
a {
|
114
|
+
color: black;
|
115
|
+
}
|
116
|
+
a:hover {
|
117
|
+
color: #8B0000;
|
118
|
+
}
|
119
|
+
tt {
|
120
|
+
margin-left: 10%;
|
121
|
+
}
|
122
|
+
.footer {
|
123
|
+
border-top: 3px solid #8B0000;
|
124
|
+
}
|
125
|
+
@@vpim/agent/ics/view
|
126
|
+
!!! strict
|
127
|
+
%html
|
128
|
+
%head
|
129
|
+
%title Subscribe to calendar feeds as atom feeds
|
130
|
+
%link{:href => script_url + "/style.css", :media => "screen", :type => "text/css"}
|
131
|
+
%meta{:"http-equiv" => "Content-Type", :content => "text/html;charset=utf-8"}
|
132
|
+
%body
|
133
|
+
%h1 Subscribe to calendar feeds as atom feeds
|
134
|
+
%p
|
135
|
+
Calendar feeds are great, but when you want a reminder of what's coming up
|
136
|
+
in the next week, you might want those events as an atom feed.
|
137
|
+
%p
|
138
|
+
Paste the URL of the calendar below, submit it, and subscribe.
|
139
|
+
%form{:method => 'POST', :action => script_url}
|
140
|
+
%p
|
141
|
+
%input.text{:type => 'text', :name => 'url', :value => @url_ics}
|
142
|
+
%input{:type => 'submit', :value => 'Submit'}
|
143
|
+
- if @url_atom
|
144
|
+
%p
|
145
|
+
Subscribe to
|
146
|
+
%a{:href => @url_ics}= @url_ics
|
147
|
+
as:
|
148
|
+
%ul.feed
|
149
|
+
%li
|
150
|
+
%a{:href => @url_atom}= @url_atom
|
151
|
+
(atom feed)
|
152
|
+
- if @url_error
|
153
|
+
%p
|
154
|
+
Sorry, trying to access
|
155
|
+
%tt=@url_ics
|
156
|
+
resulted in:
|
157
|
+
%p
|
158
|
+
%tt= @url_error
|
159
|
+
.footer
|
160
|
+
:textile
|
161
|
+
Brought from the "Octet Cloud":http://octetcloud.com/ using "vPim":http://vpim.rubyforge.org/, by cloud monkey "Sam Roberts":mailto:vieuxtech@gmail.com.
|
162
|
+
|
data/lib/vpim/attachment.rb
CHANGED
data/lib/vpim/date.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
=begin
|
2
3
|
Copyright (C) 2008 Sam Roberts
|
3
4
|
|
@@ -40,7 +41,7 @@ class Date
|
|
40
41
|
# February
|
41
42
|
# Date.bywday(2004, 2, Date.str2wday(2)) => the same day, but notice
|
42
43
|
# that a valid wday integer can be passed right through.
|
43
|
-
#
|
44
|
+
#
|
44
45
|
def Date.str2wday(wdaystr)
|
45
46
|
return wdaystr unless wdaystr.respond_to? :to_str
|
46
47
|
|
@@ -56,7 +57,7 @@ class Date
|
|
56
57
|
raise ArgumentError, 'wday #{wdaystr} was not a recognizable weekday name'
|
57
58
|
end
|
58
59
|
|
59
|
-
|
60
|
+
|
60
61
|
# Create a new Date object for the date specified by year +year+, month
|
61
62
|
# +mon+, and day-of-the-week +wday+.
|
62
63
|
#
|
data/lib/vpim/dirinfo.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
=begin
|
2
3
|
Copyright (C) 2008 Sam Roberts
|
3
4
|
|
@@ -94,7 +95,7 @@ module Vpim
|
|
94
95
|
f.push Field.create('END', p)
|
95
96
|
fields = f
|
96
97
|
end
|
97
|
-
|
98
|
+
|
98
99
|
new(fields, profile)
|
99
100
|
end
|
100
101
|
|
@@ -157,7 +158,7 @@ module Vpim
|
|
157
158
|
# Examples:
|
158
159
|
#
|
159
160
|
# Print all the nicknames in a card:
|
160
|
-
#
|
161
|
+
#
|
161
162
|
# card.enum_by_name('NICKNAME') { |f| puts f.value }
|
162
163
|
#
|
163
164
|
# Print an Array of the preferred email addresses in the card:
|
@@ -178,7 +179,7 @@ module Vpim
|
|
178
179
|
# end
|
179
180
|
#
|
180
181
|
# or to get an array of all the fields in group 'AGROUP', you could do:
|
181
|
-
#
|
182
|
+
#
|
182
183
|
# card.enum_by_group('AGROUP').to_a
|
183
184
|
def enum_by_group(group)
|
184
185
|
Enumerator.new(self, Proc.new { |field| field.group?(group) })
|
@@ -250,7 +251,7 @@ module Vpim
|
|
250
251
|
alias to_s encode
|
251
252
|
|
252
253
|
# Check that the DirectoryInfo object is correctly delimited by a BEGIN
|
253
|
-
# and END, that their profile values match, and if +profile+ is specified, that
|
254
|
+
# and END, that their profile values match, and if +profile+ is specified, that
|
254
255
|
# they are the specified profile.
|
255
256
|
def check_begin_end(profile=nil) #:nodoc:
|
256
257
|
unless @fields.first
|
data/lib/vpim/duration.rb
CHANGED
data/lib/vpim/enumerator.rb
CHANGED
data/lib/vpim/field.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
=begin
|
2
3
|
Copyright (C) 2008 Sam Roberts
|
3
4
|
|
@@ -50,7 +51,7 @@ module Vpim
|
|
50
51
|
if group
|
51
52
|
line << group << '.'
|
52
53
|
end
|
53
|
-
|
54
|
+
|
54
55
|
line << name
|
55
56
|
|
56
57
|
params.each do |pname, pvalues|
|
@@ -141,7 +142,7 @@ module Vpim
|
|
141
142
|
# v2.1 params have no '=' sign, figure out what kind of param it
|
142
143
|
# is (either its a known encoding, or we treat it as a 'TYPE'
|
143
144
|
# param).
|
144
|
-
|
145
|
+
|
145
146
|
if $2 == ""
|
146
147
|
params = $1
|
147
148
|
case $1
|