vpim 0.695 → 13.11.11
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.
- 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
|