siri_cal 0.0.1
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 +20 -0
- data/README.md +155 -0
- data/Rakefile +37 -0
- data/lib/generators/install.rb +16 -0
- data/lib/generators/templates/siri_cal.rb +13 -0
- data/lib/generators/templates/siri_says/default.rb +3 -0
- data/lib/siri_cal.rb +41 -0
- data/lib/siri_cal/methods.rb +49 -0
- data/lib/siri_cal/say_proxy.rb +63 -0
- data/lib/siri_cal/version.rb +3 -0
- data/lib/tasks/siri_cal_tasks.rake +4 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +9 -0
- data/test/dummy/app/assets/stylesheets/application.css +7 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/models/movie.rb +2 -0
- data/test/dummy/app/models/user.rb +4 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +45 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +30 -0
- data/test/dummy/config/environments/production.rb +60 -0
- data/test/dummy/config/environments/test.rb +42 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +10 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +58 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/migrate/20111105175135_create_users.rb +11 -0
- data/test/dummy/db/migrate/20111108194230_create_movies.rb +11 -0
- data/test/dummy/db/schema.rb +31 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/lib/siri_says/default.rb +3 -0
- data/test/dummy/log/development.log +102 -0
- data/test/dummy/log/test.log +4932 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +26 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/dummy/test/fixtures/movies.yml +7 -0
- data/test/dummy/test/fixtures/users.yml +11 -0
- data/test/dummy/test/unit/movie_test.rb +7 -0
- data/test/dummy/test/unit/user_test.rb +7 -0
- data/test/fixtures/vcr_cassettes/invalid_credentials.yml +36 -0
- data/test/fixtures/vcr_cassettes/valid_credentials.yml +38 -0
- data/test/fixtures/vcr_cassettes/valid_credentials_with_events.yml +772 -0
- data/test/fixtures/vcr_cassettes/valid_credentials_with_events_to_delete.yml +948 -0
- data/test/generators/install_test.rb +13 -0
- data/test/siri_cal_test.rb +82 -0
- data/test/test_helper.rb +23 -0
- metadata +216 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2011 BOUNMY Stephane
|
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.md
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
SiriCal
|
2
|
+
=======
|
3
|
+
|
4
|
+
SiriCal is a simple limited solution to handle [iOS 5 Siri feature][s] in your Ruby app :
|
5
|
+
|
6
|
+
* provides Siri helpers to your ruby app by synchronizing google calendar events.
|
7
|
+
* an alternative limited solution before Apple release an API for Siri.
|
8
|
+
* relies on google_calendar gem : [google_calendar][gc].
|
9
|
+
|
10
|
+
This gem is much inspired by Tyson Tale's hack: [siri_says][ss].
|
11
|
+
|
12
|
+
Installation
|
13
|
+
------------
|
14
|
+
|
15
|
+
#### Rails app
|
16
|
+
|
17
|
+
You can use the latest Rails 3 gem with the latest SiriCal gem:
|
18
|
+
|
19
|
+
In your gemfile
|
20
|
+
|
21
|
+
gem 'siri_cal'
|
22
|
+
|
23
|
+
or using rubygems
|
24
|
+
|
25
|
+
gem install siri_cal
|
26
|
+
|
27
|
+
After you install SiriCal, you need to run the generator:
|
28
|
+
|
29
|
+
rails generate siri_cal:install
|
30
|
+
|
31
|
+
The generator will install:
|
32
|
+
|
33
|
+
* an initializer which describes most SiriCal’s configuration options.
|
34
|
+
* a step file which describe siri sayings
|
35
|
+
|
36
|
+
#### iPhone
|
37
|
+
|
38
|
+
Add the calendar:
|
39
|
+
|
40
|
+
1. Settings
|
41
|
+
2. "Mail, Contacts, Calendars"
|
42
|
+
3. "Add Account..."
|
43
|
+
4. "Other"
|
44
|
+
5. "Add CalDAV Account"
|
45
|
+
* Server: google.com
|
46
|
+
* Username: username@gmail.com
|
47
|
+
* Password: ___________
|
48
|
+
* Description: "sirical"
|
49
|
+
6. "Next"
|
50
|
+
|
51
|
+
Choose the calendar as default so Siri will add events to it:
|
52
|
+
|
53
|
+
1. Settings
|
54
|
+
1. "Mail, Contacts, Calendars"
|
55
|
+
2. "Default Calendar" --> sirical
|
56
|
+
|
57
|
+
Usage
|
58
|
+
-----
|
59
|
+
|
60
|
+
A model
|
61
|
+
|
62
|
+
class User < ActiveRecord::Base
|
63
|
+
siriable
|
64
|
+
has_many :movies
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
Be sure to have 2 fields containing your google calendar
|
69
|
+
|
70
|
+
* login (siriable_login here)
|
71
|
+
* password (siriable_password here)
|
72
|
+
|
73
|
+
db/schema.rb should look like:
|
74
|
+
|
75
|
+
create_table "users", :force => true do |t|
|
76
|
+
t.string "name"
|
77
|
+
t.string "siriable_login"
|
78
|
+
t.string "siriable_password"
|
79
|
+
t.datetime "created_at"
|
80
|
+
t.datetime "updated_at"
|
81
|
+
end
|
82
|
+
|
83
|
+
In lib/siri_says/default.rb
|
84
|
+
|
85
|
+
says /a movie (.+)/i do |movie_name|
|
86
|
+
puts "[Siri] Movie '#{movie_name}' scheduled by #{@object.name} at #{@event.start_time}"
|
87
|
+
end
|
88
|
+
|
89
|
+
* @object is the User instance "bob"
|
90
|
+
* @event is the Google::Event instance
|
91
|
+
|
92
|
+
Tell Siri:
|
93
|
+
|
94
|
+
"Schedule a movie transformers right now."
|
95
|
+
|
96
|
+
In your ruby code:
|
97
|
+
|
98
|
+
user = User.create :name => "bob", :siriable_login => "bob@gmail.com", :siriable_password => "bobibob"
|
99
|
+
user.execute_siri!
|
100
|
+
|
101
|
+
(seconds later)
|
102
|
+
|
103
|
+
[Siri] Movie 'transformers' scheduled by bob at 2010-11-08 12:20
|
104
|
+
|
105
|
+
Example of events
|
106
|
+
------------------
|
107
|
+
|
108
|
+
From [Siri Says][ss] :
|
109
|
+
|
110
|
+
#### Immediate events
|
111
|
+
|
112
|
+
To create an immediate event, you can either create an event "now" or "all-day tomorrow":
|
113
|
+
|
114
|
+
* "Schedule a movie right now"
|
115
|
+
* "Schedule an event right now: movie"
|
116
|
+
* "Schedule an appointment tomorrow, all-day: movie"
|
117
|
+
* "New appointment now: movie"
|
118
|
+
* Etc.
|
119
|
+
|
120
|
+
#### Scheduled events
|
121
|
+
|
122
|
+
Create events that fire later just like you would any other scheduled event:
|
123
|
+
|
124
|
+
* "New appointment for tomorrow at 4am: deploy"
|
125
|
+
* "Schedule a deploy tomorrow at 4am"
|
126
|
+
* "Schedule an event tomorrow at 4am: deploy"
|
127
|
+
* "Schedule an appointment tomorrow, at 4am: deploy"
|
128
|
+
* Etc.
|
129
|
+
|
130
|
+
Compatibility
|
131
|
+
-------------
|
132
|
+
|
133
|
+
Tested under Rails 3.X.
|
134
|
+
|
135
|
+
Contribute
|
136
|
+
----------
|
137
|
+
|
138
|
+
Pull requests for features and bug fix with tests are welcome.
|
139
|
+
|
140
|
+
This is my first gem so please consider this as beta version.
|
141
|
+
|
142
|
+
TODO
|
143
|
+
----
|
144
|
+
|
145
|
+
* Find an asynchronous way to get calendar events.
|
146
|
+
* Possibility to use different caldav servers, not only gmail.
|
147
|
+
|
148
|
+
License
|
149
|
+
-------
|
150
|
+
|
151
|
+
This project rocks and uses MIT-LICENSE.
|
152
|
+
|
153
|
+
[s]: http://www.apple.com/iphone/features/siri.html
|
154
|
+
[ss]: https://github.com/tysontate/siri_says
|
155
|
+
[gc]: https://github.com/northworld/google_calendar
|
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'SiriCal'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
Bundler::GemHelper.install_tasks
|
26
|
+
|
27
|
+
require 'rake/testtask'
|
28
|
+
|
29
|
+
Rake::TestTask.new(:test) do |t|
|
30
|
+
t.libs << 'lib'
|
31
|
+
t.libs << 'test'
|
32
|
+
t.pattern = 'test/**/*_test.rb'
|
33
|
+
t.verbose = false
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
task :default => :test
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module SiriCal
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base #:nodoc:
|
4
|
+
source_root File.expand_path("../templates", __FILE__)
|
5
|
+
desc "Copies siri says file"
|
6
|
+
|
7
|
+
def copy_siri_says_default
|
8
|
+
copy_file "siri_says/default.rb", "lib/siri_says/default.rb"
|
9
|
+
end
|
10
|
+
|
11
|
+
def copy_config
|
12
|
+
copy_file "siri_cal.rb", "config/initializers/siri_cal.rb"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
SiriCal.setup do |config|
|
2
|
+
# Configure the path containing the siri says files.
|
3
|
+
config.siri_says_path = "lib/siri_says"
|
4
|
+
|
5
|
+
# Set the delete event policy
|
6
|
+
# :success delete event only when event matches one of the siri says block
|
7
|
+
# :always delete event once it is fetched from calendar
|
8
|
+
# :none never delete event
|
9
|
+
config.delete_event = :success
|
10
|
+
|
11
|
+
# Set the calendar name to connect to. Default: "sirical"
|
12
|
+
# config.calendar_name = "sirical"
|
13
|
+
end
|
data/lib/siri_cal.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
Bundler.require
|
2
|
+
require 'active_support/concern'
|
3
|
+
require 'active_support/dependencies'
|
4
|
+
require 'rails/generators'
|
5
|
+
|
6
|
+
require 'generators/install'
|
7
|
+
require 'siri_cal/say_proxy'
|
8
|
+
require 'siri_cal/methods'
|
9
|
+
|
10
|
+
module SiriCal
|
11
|
+
extend ActiveSupport::Concern
|
12
|
+
class RedundantError < StandardError; end;
|
13
|
+
|
14
|
+
# Public: String path of the siri's says files. Default: "lib/siri_says"
|
15
|
+
mattr_accessor :siri_says_path
|
16
|
+
@@siri_says_path = "lib/siri_says"
|
17
|
+
|
18
|
+
# Public: String path of the siri's says files. Default: :success
|
19
|
+
mattr_accessor :delete_event
|
20
|
+
@@delete_event = :success
|
21
|
+
|
22
|
+
# Public: String name of the caldav calendar to connect to. Default: "sirical"
|
23
|
+
mattr_accessor :calendar_name
|
24
|
+
@@calendar_name = "sirical"
|
25
|
+
|
26
|
+
def self.setup
|
27
|
+
yield self
|
28
|
+
end
|
29
|
+
|
30
|
+
module StepMethods
|
31
|
+
def says(regexp=nil, &block)
|
32
|
+
@proxy = SayProxy
|
33
|
+
@proxy << Say.new(regexp, &block) if regexp && block
|
34
|
+
@proxy
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
ActiveRecord::Base.send :include, SiriCal
|
41
|
+
Object.send :include, SiriCal::StepMethods
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'google_calendar'
|
2
|
+
|
3
|
+
module SiriCal
|
4
|
+
module ClassMethods
|
5
|
+
# Public: Initialize a Siriable object.
|
6
|
+
#
|
7
|
+
# options - The Hash options used to redefine the config (default: {}):
|
8
|
+
# :login - The Symbol login field to sign in with (default: :login).
|
9
|
+
# :password - The Symbol login field to sign in with (default: :password).
|
10
|
+
#
|
11
|
+
# Examples
|
12
|
+
#
|
13
|
+
# siriable :login => :caldav_login, :password => :caldav_password
|
14
|
+
#
|
15
|
+
#
|
16
|
+
# Returns nothing.
|
17
|
+
|
18
|
+
def siriable options={}
|
19
|
+
config = {}
|
20
|
+
config[:login] = options.delete(:login) || :siriable_login
|
21
|
+
config[:password] = options.delete(:password) || :siriable_password
|
22
|
+
config.each do |key, value|
|
23
|
+
define_method "siri_cal_#{key}" do
|
24
|
+
self.send(value)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
module InstanceMethods
|
31
|
+
# Public: Initialize calendar
|
32
|
+
#
|
33
|
+
# Returns an instance of Google::Calendar.
|
34
|
+
def calendar
|
35
|
+
Google::Calendar.new :username => siri_cal_login, :password => siri_cal_password, :calendar => calendar_name
|
36
|
+
end
|
37
|
+
|
38
|
+
# Public: GET calendar's event and run then according to block defined in lib/siri_says.rb
|
39
|
+
#
|
40
|
+
# Returns nothing.
|
41
|
+
def execute_siri!
|
42
|
+
SayProxy.load_files
|
43
|
+
calendar.events.to_a.each do |event|
|
44
|
+
res = SayProxy.invoke_say(event, self)
|
45
|
+
event.delete if (res && delete_event == :success) || delete_event == :always
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module SiriCal
|
2
|
+
|
3
|
+
class Say
|
4
|
+
def initialize(regexp, &block)
|
5
|
+
self.regexp, self.block = regexp, block
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_accessor :regexp, :block, :captures
|
9
|
+
end
|
10
|
+
|
11
|
+
class SayProxy
|
12
|
+
class << self
|
13
|
+
def proxy
|
14
|
+
@proxy ||= []
|
15
|
+
end
|
16
|
+
|
17
|
+
def <<(say)
|
18
|
+
proxy << say
|
19
|
+
end
|
20
|
+
|
21
|
+
def count
|
22
|
+
proxy.count
|
23
|
+
end
|
24
|
+
|
25
|
+
def matches_says(name)
|
26
|
+
proxy.select { |say| !!(say.regexp =~ name and say.captures = $~.captures) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def invoke_say(event, object=nil)
|
30
|
+
matches = matches_says(event.title)
|
31
|
+
raise RedundantError, "You should have only one say step that matches \"#{name}\"" if matches.size > 1
|
32
|
+
if !matches.empty?
|
33
|
+
m = matches.first
|
34
|
+
@object, @event = object, event
|
35
|
+
self.instance_exec(*m.captures, &m.block)
|
36
|
+
return true
|
37
|
+
end
|
38
|
+
false
|
39
|
+
end
|
40
|
+
|
41
|
+
def clear
|
42
|
+
proxy.clear
|
43
|
+
end
|
44
|
+
|
45
|
+
# Internal : Load only once Siri says files
|
46
|
+
#
|
47
|
+
# Returns true on success
|
48
|
+
# Returns false if already loaded
|
49
|
+
def load_files
|
50
|
+
return false unless proxy.empty?
|
51
|
+
Dir.glob(File.join(SiriCal.siri_says_path, "*")).each do |filename|
|
52
|
+
load File.expand_path(filename)
|
53
|
+
end
|
54
|
+
true
|
55
|
+
end
|
56
|
+
|
57
|
+
def all
|
58
|
+
proxy
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
data/test/dummy/Rakefile
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
3
|
+
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
4
|
+
|
5
|
+
require File.expand_path('../config/application', __FILE__)
|
6
|
+
|
7
|
+
Dummy::Application.load_tasks
|
@@ -0,0 +1,9 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into including all the files listed below.
|
2
|
+
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
|
3
|
+
// be included in the compiled file accessible from http://example.com/assets/application.js
|
4
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
5
|
+
// the compiled file.
|
6
|
+
//
|
7
|
+
//= require jquery
|
8
|
+
//= require jquery_ujs
|
9
|
+
//= require_tree .
|
@@ -0,0 +1,7 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll automatically include all the stylesheets available in this directory
|
3
|
+
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
|
4
|
+
* the top of the compiled file, but it's generally better to create a new file per style scope.
|
5
|
+
*= require_self
|
6
|
+
*= require_tree .
|
7
|
+
*/
|