actic 0.0.2 → 0.0.2.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 +1 -1
- data/README.rdoc +3 -0
- data/Rakefile +26 -1
- data/lib/actic.rb +1 -177
- data/lib/actic/engine.rb +3 -3
- data/lib/app/models/alarm.rb +10 -0
- data/lib/app/models/calendar.rb +40 -0
- data/lib/app/models/component.rb +99 -0
- data/lib/app/models/event.rb +58 -0
- data/lib/app/models/free_busy.rb +3 -0
- data/lib/app/models/inspectable.rb +2 -0
- data/lib/app/models/journal.rb +4 -0
- data/lib/app/models/pattern.rb +7 -0
- data/lib/app/models/patterns/ex_date.rb +5 -0
- data/lib/app/models/patterns/ex_rule.rb +5 -0
- data/lib/app/models/patterns/r_date.rb +5 -0
- data/lib/app/models/patterns/r_rule.rb +5 -0
- data/lib/app/models/sub_calendar.rb +3 -0
- data/lib/app/models/todo.rb +5 -0
- data/lib/migrate/20101217173535_create_components.rb +87 -0
- data/lib/migrate/20101218062739_create_inspectables.rb +12 -0
- metadata +43 -38
- data/.DS_Store +0 -0
- data/.idea/.rakeTasks +0 -7
- data/.idea/actic.iml +0 -33
- data/.idea/encodings.xml +0 -5
- data/.idea/misc.xml +0 -8
- data/.idea/modules.xml +0 -9
- data/.idea/vcs.xml +0 -8
- data/.idea/workspace.xml +0 -373
- data/Gemfile +0 -29
- data/Gemfile.lock +0 -21
- data/README +0 -52
- data/actic.gemspec +0 -23
- data/lib/actic/models/actic_calendar.rb +0 -8
- data/lib/actic/models/event.rb +0 -5
- data/lib/actic/models/sub_component.rb +0 -5
- data/lib/actic/railtie.rb +0 -62
- data/lib/actic/version.rb +0 -3
- data/lib/generators/actic/USAGE +0 -8
- data/lib/generators/actic/actic_generator.rb +0 -3
- data/lib/generators/actic_calendar/USAGE +0 -8
- data/lib/generators/actic_calendar/actic_calendar_generator.rb +0 -51
- data/lib/generators/actic_calendar/templates/actic_calendar.rb.txt +0 -4
- data/lib/generators/actic_calendar/templates/migration.rb.txt +0 -20
- data/lib/generators/actic_subcomponent/USAGE +0 -8
- data/lib/generators/actic_subcomponent/actic_subcomponent_generator.rb +0 -13
- data/lib/generators/actic_subcomponent/templates/event.rb.txt +0 -2
- data/lib/generators/actic_subcomponent/templates/journal.rb.txt +0 -2
data/MIT-LICENSE
CHANGED
data/README.rdoc
ADDED
data/Rakefile
CHANGED
@@ -1,2 +1,27 @@
|
|
1
|
-
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'rubygems'
|
3
|
+
begin
|
4
|
+
require 'bundler/setup'
|
5
|
+
rescue LoadError
|
6
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
7
|
+
end
|
8
|
+
|
2
9
|
Bundler::GemHelper.install_tasks
|
10
|
+
|
11
|
+
require 'rake'
|
12
|
+
require 'rake/rdoctask'
|
13
|
+
|
14
|
+
require 'rspec/core'
|
15
|
+
require 'rspec/core/rake_task'
|
16
|
+
|
17
|
+
RSpec::Core::RakeTask.new(:spec)
|
18
|
+
|
19
|
+
task :default => :spec
|
20
|
+
|
21
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
22
|
+
rdoc.rdoc_dir = 'rdoc'
|
23
|
+
rdoc.title = 'Actic'
|
24
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
25
|
+
rdoc.rdoc_files.include('README.rdoc')
|
26
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
27
|
+
end
|
data/lib/actic.rb
CHANGED
@@ -1,180 +1,4 @@
|
|
1
|
-
# Every active record model that implements the interface must
|
2
|
-
# have a string variable either in the DB or initialized in memory called "ical"
|
3
|
-
|
4
|
-
|
5
|
-
require 'active_support/dependencies'
|
6
|
-
require 'set'
|
7
|
-
#require 'actic/models/calendar'
|
8
|
-
#require 'actic/railtie'
|
9
1
|
module Actic
|
10
|
-
require 'actic/railtie' if defined?(Rails)
|
11
2
|
require 'actic/engine' if defined?(Rails)
|
12
|
-
require 'ri_cal'
|
13
|
-
def ic_respond
|
14
|
-
true
|
15
|
-
end
|
16
|
-
module Event
|
17
|
-
|
18
|
-
def ic_component
|
19
|
-
true
|
20
|
-
end
|
21
|
-
|
22
|
-
module ClassMethods; end
|
23
|
-
|
24
|
-
def self.included(base)
|
25
|
-
base.extend(ClassMethods)
|
26
|
-
base.send :after_initialize, :si
|
27
|
-
end
|
28
|
-
|
29
|
-
def ievent
|
30
|
-
@ic ? @ic : @ic = RiCal.parse_string(self.ical).first
|
31
|
-
end
|
32
|
-
|
33
|
-
def description=(desc)
|
34
|
-
ievent.description=desc; si(@ic)
|
35
|
-
end
|
36
|
-
|
37
|
-
def description
|
38
|
-
ievent.description
|
39
|
-
end
|
40
|
-
|
41
|
-
def start_time=(start)
|
42
|
-
ievent.dtstart=start; si(@ic)
|
43
|
-
end
|
44
|
-
|
45
|
-
def start_time
|
46
|
-
ievent.start_time
|
47
|
-
end
|
48
|
-
|
49
|
-
def end_time=(endt)
|
50
|
-
ievent.dtend=endt; si(@ic)
|
51
|
-
end
|
52
|
-
|
53
|
-
def end_time
|
54
|
-
ievent.end_time
|
55
|
-
end
|
56
|
-
|
57
|
-
def recurrence=(rec)
|
58
|
-
ievent.rrule=rec; si(@ic)
|
59
|
-
end
|
60
|
-
|
61
|
-
## e.recurs :freq => :daily, :count => 10
|
62
|
-
## e.recurs :string => "FREQ=WEEKLY;COUNT=10;"
|
63
|
-
## NOTE - if specifying :string, all other options are overridden
|
64
|
-
def recurs(opts = {})
|
65
|
-
rec = ""
|
66
|
-
|
67
|
-
unless opts[:freq].nil?
|
68
|
-
#p "Frequency Present"
|
69
|
-
rec += "FREQ=#{opts[:freq].to_s.upcase};"
|
70
|
-
end
|
71
|
-
unless opts[:count].nil?
|
72
|
-
#p "Count Present"
|
73
|
-
rec += "COUNT=#{opts[:count].to_i};"
|
74
|
-
end
|
75
|
-
unless opts[:string].nil?
|
76
|
-
#p "String Present"
|
77
|
-
rec = opts[:string]
|
78
|
-
end
|
79
|
-
ievent.rrule=rec; si(@ic)
|
80
|
-
#rec
|
81
|
-
end
|
82
|
-
|
83
|
-
def occurrences(*oc)
|
84
|
-
ievent.occurrences(*oc);
|
85
|
-
end
|
86
|
-
|
87
|
-
private
|
88
|
-
|
89
|
-
def set_ievent(ic = nil)
|
90
|
-
if !ical.nil? && ic.nil?
|
91
|
-
if @ic
|
92
|
-
@ic
|
93
|
-
else
|
94
|
-
@ic = RiCal.parse_string(self.ical).first
|
95
|
-
end
|
96
|
-
elsif ic.nil?
|
97
|
-
self.ical = RiCal.Event.to_rfc2445_string
|
98
|
-
else
|
99
|
-
@ic = ic; self.ical = @ic.to_rfc2445_string
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
alias si set_ievent
|
104
|
-
end
|
105
|
-
|
106
|
-
module Calendar
|
107
|
-
module ClassMethods; end
|
108
|
-
|
109
|
-
def self.included(base)
|
110
|
-
base.extend(ClassMethods)
|
111
|
-
base.send :after_initialize, :si
|
112
|
-
end
|
113
|
-
|
114
|
-
def icalendar
|
115
|
-
@ic ? @ic : @ic = RiCal.parse_string(self.ical).first
|
116
|
-
end
|
117
|
-
|
118
|
-
## Can add a subcomponent as a String, Actic enabled Model, or a RiCal component
|
119
|
-
## If the argument is a Actic Model, attempt to create an association (currently only works with has_many)
|
120
|
-
def add_subcomponent(comp)
|
121
|
-
i = icalendar
|
122
|
-
if comp.is_a? String
|
123
|
-
i.add_subcomponent(RiCal.parse_string(comp).first)
|
124
|
-
elsif comp.respond_to? "ic_component"
|
125
|
-
#p "Item is a subcomponent"
|
126
|
-
assoc = comp.class.to_s.downcase.pluralize.to_sym
|
127
|
-
if self.class.reflect_on_association assoc
|
128
|
-
#p "Item has association - #{assoc.to_s} on #{self.class.to_s} "
|
129
|
-
eval "#{assoc.to_s} << comp"
|
130
|
-
else
|
131
|
-
p "Item has no association on self"
|
132
|
-
end
|
133
|
-
i.add_subcomponent(RiCal.parse_string(comp.ievent.to_rfc2445_string).first)
|
134
|
-
else
|
135
|
-
i.add_subcomponent(RiCal.parse_string(comp.to_rfc2445_string).first)
|
136
|
-
end
|
137
|
-
si(@ic)
|
138
|
-
end
|
139
|
-
|
140
|
-
# def add_subcomponent(comp)
|
141
|
-
# i = icalendar
|
142
|
-
# if comp.is_a? String
|
143
|
-
# i.add_subcomponent(RiCal.parse_string(comp).first)
|
144
|
-
# ## This is not dry enough, possibly make a method specifically as a tag,
|
145
|
-
# # which all actic Model objects implement
|
146
|
-
# elsif comp.respond_to? "ic_component"
|
147
|
-
# i.add_subcomponent(RiCal.parse_string(comp.ievent.to_rfc2445_string).first)
|
148
|
-
# else
|
149
|
-
# i.add_subcomponent(RiCal.parse_string(comp.to_rfc2445_string).first)
|
150
|
-
# end
|
151
|
-
# si(@ic)
|
152
|
-
# end
|
153
|
-
|
154
|
-
def events
|
155
|
-
icalendar.events
|
156
|
-
end
|
157
|
-
|
158
|
-
# alias event= add_subcomponent
|
159
|
-
#def events=(events)
|
160
|
-
# icalendar.events
|
161
|
-
#end
|
162
|
-
|
163
|
-
private
|
164
|
-
def set_ical(ic = nil)
|
165
|
-
if !ical.nil? && ic.nil?
|
166
|
-
if @ic
|
167
|
-
@ic
|
168
|
-
else
|
169
|
-
@ic = RiCal.parse_string(self.ical).first
|
170
|
-
end
|
171
|
-
elsif ic.nil?
|
172
|
-
self.ical = RiCal.Calendar.to_rfc2445_string
|
173
|
-
else
|
174
|
-
@ic = ic; self.ical = @ic.to_rfc2445_string
|
175
|
-
end
|
176
|
-
end
|
177
3
|
|
178
|
-
|
179
|
-
end
|
180
|
-
end
|
4
|
+
end
|
data/lib/actic/engine.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
+
|
1
2
|
module Actic
|
2
3
|
class Engine < Rails::Engine
|
3
|
-
|
4
|
-
|
5
|
-
config.autoload_paths << File.expand_path("../models", __FILE__)
|
4
|
+
config.autoload_paths << File.expand_path("../../app/models", __FILE__)
|
5
|
+
config.autoload_paths << File.expand_path("../../migrate", __FILE__)
|
6
6
|
end
|
7
7
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class Alarm < Component
|
2
|
+
belongs_to :component, :polymorphic => true
|
3
|
+
#scope :events, where("components.type == 'Event'")
|
4
|
+
#has_many :components, :as => :parent
|
5
|
+
|
6
|
+
def owner_type=(sType)
|
7
|
+
super(sType.to_s.classify.constantize.base_class.to_s)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class Calendar < Component
|
2
|
+
has_many :events, :after_add => :add_component, :after_remove => :reset_component
|
3
|
+
has_many :free_busies, :after_add => :add_component, :after_remove => :reset_component
|
4
|
+
has_many :journals, :after_add => :add_component, :after_remove => :reset_component
|
5
|
+
has_many :todos, :after_add => :add_component, :after_remove => :reset_component
|
6
|
+
has_many :alarms, :as => :owner, :after_add => :add_component, :after_remove => :reset_component
|
7
|
+
#has_many :components
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
=begin
|
12
|
+
class Calendar < Component
|
13
|
+
#scope :events, where("components.type == 'Event'")
|
14
|
+
has_many :components, :as => :parent, :before_add => :validate_component_type do
|
15
|
+
|
16
|
+
end
|
17
|
+
has_many :events, :as => :parent
|
18
|
+
has_many :todos, :as => :parent
|
19
|
+
has_many :journals, :as => :parent
|
20
|
+
has_many :freebusys, :as => :parent
|
21
|
+
|
22
|
+
def validate_component_type(component)
|
23
|
+
begin
|
24
|
+
component.type != "Calendar" ? true : (raise Exception)
|
25
|
+
rescue
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
=end
|
30
|
+
|
31
|
+
|
32
|
+
=begin
|
33
|
+
@calendar = Calendar.new
|
34
|
+
|
35
|
+
@calendar.events
|
36
|
+
|
37
|
+
@calendar.events << Event.new
|
38
|
+
@calendar.todos << Todo.new
|
39
|
+
|
40
|
+
=end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
class Component < ActiveRecord::Base
|
2
|
+
attr_accessor :component
|
3
|
+
after_initialize :set_component
|
4
|
+
|
5
|
+
def set_component
|
6
|
+
@component = self.ical if (self.ical != nil)
|
7
|
+
if self.is_a? Calendar
|
8
|
+
@component ||= RiCal.Calendar
|
9
|
+
elsif self.is_a? Event
|
10
|
+
@component ||= RiCal.Event
|
11
|
+
elsif self.is_a? Todo
|
12
|
+
@component ||= RiCal.Todo
|
13
|
+
elsif self.is_a? Journal
|
14
|
+
@component ||= RiCal.Journal
|
15
|
+
elsif self.is_a? Alarm
|
16
|
+
@component ||= RiCal.Alarm
|
17
|
+
elsif self.is_a? FreeBusy
|
18
|
+
@component ||= RiCal.Freebusy
|
19
|
+
end
|
20
|
+
self.ical = @component.to_rfc2445_string if self.ical.nil?
|
21
|
+
@component
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_component(sub_component)
|
25
|
+
if sub_component.is_a? Event
|
26
|
+
self.component.events << sub_component.component
|
27
|
+
elsif component.is_a? Todo
|
28
|
+
self.component.todos << sub_component.component
|
29
|
+
elsif component.is_a? Journal
|
30
|
+
self.component.journals << sub_component.component
|
31
|
+
elsif component.is_a? Alarm
|
32
|
+
self.component.alarms << sub_component.component
|
33
|
+
elsif component.is_a? FreeBusy
|
34
|
+
self.component.freebusys << sub_component.component
|
35
|
+
end
|
36
|
+
self.ical = self.component.to_rfc2445_string
|
37
|
+
end
|
38
|
+
|
39
|
+
def component_names
|
40
|
+
self.class.reflect_on_all_associations.map do |a|
|
41
|
+
a.name if a.klass.ancestors.include? Component
|
42
|
+
end.compact
|
43
|
+
end
|
44
|
+
|
45
|
+
def components
|
46
|
+
component_names.map {|co| self.send(co).map {|d| d.component }}.flatten
|
47
|
+
end
|
48
|
+
|
49
|
+
def reset_component
|
50
|
+
self.ical = nil
|
51
|
+
self.component = nil
|
52
|
+
set_component
|
53
|
+
self.components.each {|co|
|
54
|
+
self.component.add_subcomponent(co)
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
#These methods override ActiveRecords methods
|
59
|
+
class << self
|
60
|
+
def table_name
|
61
|
+
reset_table_name
|
62
|
+
end
|
63
|
+
|
64
|
+
def reset_table_name #:nodoc:
|
65
|
+
self.table_name = compute_table_name
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
def compute_table_name
|
70
|
+
base = base_class
|
71
|
+
if self == base
|
72
|
+
if parent < Component && !parent.abstract_class?
|
73
|
+
contained = parent.table_name
|
74
|
+
contained = contained.singularize if parent.pluralize_table_names
|
75
|
+
contained << '_'
|
76
|
+
end
|
77
|
+
"#{full_table_name_prefix}#{contained}#{undecorated_table_name(name)}#{table_name_suffix}"
|
78
|
+
else
|
79
|
+
base.table_name
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def base_class
|
84
|
+
class_of_active_record_descendant(self)
|
85
|
+
end
|
86
|
+
|
87
|
+
def class_of_active_record_descendant(klass)
|
88
|
+
if klass.superclass == Component || klass.superclass.abstract_class?
|
89
|
+
klass
|
90
|
+
elsif klass.superclass.nil?
|
91
|
+
raise ActiveRecordError, "#{name} doesn't belong in a hierarchy descending from ActiveRecord"
|
92
|
+
else
|
93
|
+
class_of_active_record_descendant(klass.superclass)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
@@ -0,0 +1,58 @@
|
|
1
|
+
class Event < Component
|
2
|
+
acts_as_recurring
|
3
|
+
|
4
|
+
belongs_to :calendar
|
5
|
+
has_many :alarms, :as => :owner
|
6
|
+
has_many :patterns, :as => :owner
|
7
|
+
has_many :r_rules, :as => :owner, :class_name => "Patterns::RRule", :dependent => :destroy
|
8
|
+
has_many :r_dates, :as => :owner, :class_name => "Patterns::RDate", :dependent => :destroy
|
9
|
+
has_many :ex_rules, :as => :owner, :class_name => "Patterns::ExRule", :dependent => :destroy
|
10
|
+
has_many :ex_dates, :as => :owner, :class_name => "Patterns::ExDate", :dependent => :destroy
|
11
|
+
|
12
|
+
def add_rrule_with_unsafe(repeats, args ={})
|
13
|
+
_rrule = Patterns::RRule.new(:rule => add_rule(repeats, args))
|
14
|
+
self.r_rules << _rrule
|
15
|
+
map_rrules
|
16
|
+
end
|
17
|
+
alias_method_chain :add_rrule, :unsafe
|
18
|
+
|
19
|
+
def add_exrule_with_unsafe(repeats, args ={})
|
20
|
+
_exrule = Patterns::ExRule.new(:rule => add_rule(repeats, args))
|
21
|
+
self.ex_rules << _exrule
|
22
|
+
map_exrules
|
23
|
+
end
|
24
|
+
alias_method_chain :add_exrule, :unsafe
|
25
|
+
|
26
|
+
|
27
|
+
def add_rdate_with_unsafe(args)
|
28
|
+
_rdate = Patterns::RDate.new(:rule => add_rdate_without_unsafe(args))
|
29
|
+
self.r_dates << _rdate
|
30
|
+
map_rdates
|
31
|
+
end
|
32
|
+
alias_method_chain :add_rdate, :unsafe
|
33
|
+
|
34
|
+
|
35
|
+
def add_exdate_with_unsafe(args)
|
36
|
+
_exdate = Patterns::ExDate.new(:rule => add_exdate_without_unsafe(args))
|
37
|
+
self.ex_dates << _exdate
|
38
|
+
map_exdates
|
39
|
+
end
|
40
|
+
alias_method_chain :add_exdate, :unsafe
|
41
|
+
|
42
|
+
def map_rrules
|
43
|
+
self.component.rrules= self.r_rules.map {|rr| rr.rule }
|
44
|
+
end
|
45
|
+
|
46
|
+
def map_exrules
|
47
|
+
self.component.exrules= self.ex_rules.map {|ex| ex.rule }
|
48
|
+
end
|
49
|
+
|
50
|
+
def map_rdates
|
51
|
+
self.component.rdates= self.r_dates.map {|rd| rd.rule }
|
52
|
+
end
|
53
|
+
|
54
|
+
def map_exdates
|
55
|
+
self.component.exdates= self.ex_dates.map {|exd| exd.rule }
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|