radiant-event_calendar-extension 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. data/.gitmodules +0 -0
  2. data/README.md +198 -0
  3. data/Rakefile +139 -0
  4. data/VERSION +1 -0
  5. data/app/controllers/admin/calendars_controller.rb +18 -0
  6. data/app/controllers/admin/event_venues_controller.rb +3 -0
  7. data/app/controllers/admin/events_controller.rb +9 -0
  8. data/app/controllers/admin/icals_controller.rb +26 -0
  9. data/app/controllers/events_controller.rb +201 -0
  10. data/app/models/calendar.rb +57 -0
  11. data/app/models/event.rb +409 -0
  12. data/app/models/event_calendar_page.rb +138 -0
  13. data/app/models/event_occurrence.rb +89 -0
  14. data/app/models/event_recurrence_rule.rb +85 -0
  15. data/app/models/event_venue.rb +17 -0
  16. data/app/models/ical.rb +132 -0
  17. data/app/views/admin/calendars/_actions.html.haml +6 -0
  18. data/app/views/admin/calendars/_form.html.haml +56 -0
  19. data/app/views/admin/calendars/edit.html.haml +11 -0
  20. data/app/views/admin/calendars/help.html.erb +22 -0
  21. data/app/views/admin/calendars/index.html.haml +60 -0
  22. data/app/views/admin/calendars/new.html.haml +10 -0
  23. data/app/views/admin/calendars/show.html.haml +36 -0
  24. data/app/views/admin/event_venues/_event_venue.html.haml +18 -0
  25. data/app/views/admin/event_venues/_form.html.haml +44 -0
  26. data/app/views/admin/event_venues/edit.html.haml +32 -0
  27. data/app/views/admin/event_venues/index.html.haml +33 -0
  28. data/app/views/admin/event_venues/new.html.haml +32 -0
  29. data/app/views/admin/event_venues/remove.html.haml +17 -0
  30. data/app/views/admin/events/_event.html.haml +47 -0
  31. data/app/views/admin/events/_form.html.haml +116 -0
  32. data/app/views/admin/events/_list_head.html.haml +18 -0
  33. data/app/views/admin/events/edit.html.haml +6 -0
  34. data/app/views/admin/events/index.html.haml +23 -0
  35. data/app/views/admin/events/new.html.haml +6 -0
  36. data/app/views/admin/events/remove.html.haml +17 -0
  37. data/app/views/admin/icals/refresh.html.haml +11 -0
  38. data/app/views/admin/icals/refresh_all.html.haml +0 -0
  39. data/app/views/events/_defacet.html.haml +2 -0
  40. data/app/views/events/_event.html.haml +29 -0
  41. data/app/views/events/_event_postscript.html.haml +0 -0
  42. data/app/views/events/_faceting.html.haml +27 -0
  43. data/app/views/events/_minicalendar.html.haml +49 -0
  44. data/app/views/events/_other_page_parts.html.haml +0 -0
  45. data/app/views/events/_views.html.haml +6 -0
  46. data/app/views/events/index.html.haml +56 -0
  47. data/app/views/events/index.ics.erb +7 -0
  48. data/app/views/events/index.rss.builder +20 -0
  49. data/config/routes.rb +13 -0
  50. data/db/migrate/001_create_calendar_and_events.rb +21 -0
  51. data/db/migrate/002_calendar_add_ical_url.rb +9 -0
  52. data/db/migrate/003_add_calendar_category.rb +9 -0
  53. data/db/migrate/004_add_slug.rb +9 -0
  54. data/db/migrate/005_add_subscription_refresh_history.rb +11 -0
  55. data/db/migrate/006_create_icals.rb +13 -0
  56. data/db/migrate/007_move_subscriptions_to_ical.rb +15 -0
  57. data/db/migrate/008_clean_out_calendar.rb +12 -0
  58. data/db/migrate/009_basic_authentication.rb +12 -0
  59. data/db/migrate/010_refresh_interval.rb +9 -0
  60. data/db/migrate/011_more_properties.rb +8 -0
  61. data/db/migrate/20090818133511_simpler_ical_columns.rb +17 -0
  62. data/db/migrate/20090819130919_ownership.rb +17 -0
  63. data/db/migrate/20090820073805_site_scope.rb +13 -0
  64. data/db/migrate/20091118100725_event_status.rb +9 -0
  65. data/db/migrate/20100216080944_more_event_data.rb +31 -0
  66. data/db/migrate/20100218131410_recurrence_parts.rb +19 -0
  67. data/db/migrate/20100219102227_venues_and_categories.rb +23 -0
  68. data/db/migrate/20100221180539_recurrence_rules.rb +34 -0
  69. data/db/migrate/20100222182112_occurrences.rb +13 -0
  70. data/event_calendar_extension.rb +32 -0
  71. data/lib/calendar_period.rb +151 -0
  72. data/lib/event_calendar_admin_ui.rb +78 -0
  73. data/lib/event_calendar_tags.rb +1021 -0
  74. data/lib/event_search.rb +22 -0
  75. data/lib/event_statuses.rb +24 -0
  76. data/lib/tasks/event_calendar_extension_tasks.rake +29 -0
  77. data/pkg/radiant-event_calendar-extension-1.0.0.gem +0 -0
  78. data/public/icals/blank +0 -0
  79. data/public/images/admin/calendar.png +0 -0
  80. data/public/images/event_calendar/calendarlinkbg.png +0 -0
  81. data/public/images/event_calendar/event_shadow.png +0 -0
  82. data/public/images/event_calendar/ical16.png +0 -0
  83. data/public/images/event_calendar/maplinkbg.png +0 -0
  84. data/public/images/event_calendar/one_event.png +0 -0
  85. data/public/images/event_calendar/several_events.png +0 -0
  86. data/public/javascripts/admin/event_calendar.js +240 -0
  87. data/public/stylesheets/sass/admin/event_calendar.sass +266 -0
  88. data/public/stylesheets/sass/admin/modules/_grid.sass +56 -0
  89. data/public/stylesheets/sass/constants.sass +80 -0
  90. data/public/stylesheets/sass/event_calendar.sass +203 -0
  91. data/radiant-event_calendar-extension.gemspec +166 -0
  92. data/spec/datasets/calendar_events_dataset.rb +43 -0
  93. data/spec/datasets/calendar_pages_dataset.rb +8 -0
  94. data/spec/datasets/calendar_sites_dataset.rb +6 -0
  95. data/spec/datasets/calendars_dataset.rb +34 -0
  96. data/spec/datasets/recurrence_dataset.rb +7 -0
  97. data/spec/files/dummy.ics +59 -0
  98. data/spec/files/ny.ics +36 -0
  99. data/spec/lib/event_calendar_page_spec.rb +24 -0
  100. data/spec/models/calendar_spec.rb +11 -0
  101. data/spec/models/event_spec.rb +98 -0
  102. data/spec/models/ical_spec.rb +63 -0
  103. data/spec/models/recurrence_rule_spec.rb +82 -0
  104. data/spec/spec.opts +6 -0
  105. data/spec/spec_helper.rb +36 -0
  106. metadata +238 -0
@@ -0,0 +1,6 @@
1
+ - calendar ||= @calendar
2
+ %span.calendar_actions
3
+ - if calendar.ical
4
+ = link_to_unless_current image('refresh', :alt => 'Refresh calendar'), refresh_admin_ical_url(calendar.ical.id), :method => :put
5
+ = link_to_unless_current image('edit', :alt => 'Edit calendar'), edit_admin_calendar_path(calendar)
6
+ = link_to_unless_current image('remove', :alt => 'Delete calendar'), admin_calendar_path(calendar), :confirm => "Are you sure you want to delete the #{calendar.name} calendar ?", :method => :delete
@@ -0,0 +1,56 @@
1
+ #calendar_form.form-area
2
+ = render_region :form_top
3
+ = error_messages_for :calendar
4
+
5
+ - render_region :form do |form|
6
+ - form.edit_name do
7
+ .title
8
+ %p.calendar_title
9
+ = f.label :name
10
+ = f.text_field :name, :class => "textbox"
11
+ %p.calendar_category
12
+ = f.label :category
13
+ = f.text_field :category, :class => "textbox"
14
+ %p.calendar_slug
15
+ = f.label :slug
16
+ = f.text_field :slug, :class => "textbox"
17
+ %p.note
18
+ The category and slug are used create a url in the form /[calendar page]/category/slug showing only the events of this calendar.
19
+
20
+ .description
21
+ %p.description
22
+ = f.label :description, "Description"
23
+ = f.text_area 'description', :size => '40x6', :class => "textarea"
24
+
25
+ - @calendar.build_ical unless @calendar.ical
26
+ - form.edit_ical do
27
+
28
+ - f.fields_for :ical do |ical_f|
29
+ .ical
30
+ %p.url
31
+ = ical_f.label :url, "Subscription url (optional)"
32
+ = ical_f.text_field :url, :class => "textbox"
33
+ = ical_f.check_box :refresh_interval
34
+ = ical_f.label :refresh_interval, 'Refresh automatically?', :class => 'minor'
35
+
36
+ %p.username
37
+ = ical_f.label :username
38
+ = ical_f.text_field :username, :class => "textbox"
39
+
40
+ %p.password
41
+ = ical_f.label :password
42
+ = ical_f.text_field :password, :class => "textbox"
43
+
44
+ %p.note
45
+ The url should be a complete http(s) address that works in your browser.
46
+
47
+ - render_region :form_bottom do |form_bottom|
48
+ - form_bottom.edit_timestamp do
49
+ = updated_stamp @calendar
50
+
51
+ - form_bottom.edit_buttons do
52
+ %p.buttons
53
+ = save_model_button @calendar
54
+ = save_model_and_continue_editing_button @calendar
55
+ or
56
+ = link_to "Cancel", admin_calendars_url
@@ -0,0 +1,11 @@
1
+ - include_stylesheet('admin/event_calendar')
2
+
3
+ - render_region :main do |main|
4
+ - main.edit_header do
5
+ %h1
6
+ Edit Calendar
7
+ = render :partial => 'actions'
8
+
9
+ - main.edit_form do
10
+ - form_for :calendar, @calendar, :url => admin_calendar_path(@calendar), :html => { :method => "put", :multipart => true } do |f|
11
+ = render :partial => 'form', :locals => { :f => f }
@@ -0,0 +1,22 @@
1
+ <%= render :partial => 'layouts/nav' %>
2
+
3
+ <h2>Help!</h2>
4
+ <ol>
5
+ <li>Click "Add a subscription"</li>
6
+ <li>Now in the "New iCal Subscription" form fill-in the name, *group and *name and iCal subscription URL</li>
7
+ </ol>
8
+ <p>
9
+ * The extension currently overrides the handling of all paths below the node where the Event Calendar Page type gets applied looking for a calendar "group" and then a "name". So if you create a page under Root > Calendar and apply the EventCalendar page type to it, then through admin create a calendar with the group of "master" and a name of "youth" you'll be able to access your calendar at http://yoursite.com/calendar/master/youth. You'll also be able to see events for all calendars with a group of "master" by navigating to http://yoursite.com/calendar/master/all.
10
+
11
+ press refresh
12
+ 3. Study the tags and display on page
13
+ 4. Setup cron job for "script/runner 'refresh_events.rb'"
14
+ 5. Monitor refreshing in Admin panel
15
+
16
+ + rake task to create "public/assets/calendars/Test.ics"
17
+ + add Radiant::Config params for ical_paths and event_calendar_root_node
18
+ + make grouping optional
19
+ + ical file link tag
20
+ + tests for: ical calendar receive, parsing, reoccurance parsing confirmation
21
+ + script/runner task and cron job instructions
22
+ </p>
@@ -0,0 +1,60 @@
1
+ - include_stylesheet 'admin/event_calendar'
2
+ = render_region :top
3
+
4
+ #calendars_table.outset
5
+ %table.index
6
+ %thead
7
+ %tr
8
+ - render_region :thead do |thead|
9
+ - thead.name_header do
10
+ %th Name
11
+
12
+ - thead.url_header do
13
+ %th URL (category/slug)
14
+
15
+ - thead.refresh_header do
16
+ %th Last Refresh
17
+ %th Refresh automatically?
18
+
19
+ - thead.action_header do
20
+ %th
21
+ %tbody
22
+ - @calendars.each do |calendar|
23
+ %tr{:class => "node level-1"}
24
+
25
+ - render_region :tbody do |tbody|
26
+ - tbody.name_cell do
27
+ %td.subscription-title
28
+ = link_to image('calendar', :alt => ''), admin_calendar_url(calendar)
29
+ = link_to calendar.name, admin_calendar_url(calendar)
30
+ = "(#{calendar.events.count || '0'} events)"
31
+
32
+ - tbody.url_cell do
33
+ %td.url
34
+ =h calendar.category.to_s.downcase
35
+ \/
36
+ =h calendar.slug.downcase
37
+
38
+ - tbody.refresh_cell do
39
+ %td.refreshed
40
+ - if calendar.ical
41
+ =h calendar.ical.last_refresh_date.strftime("%m/%d at %H:%M") unless calendar.ical.last_refresh_date.blank?
42
+ - else
43
+ n/a
44
+ %td.autorefresh
45
+ - if calendar.ical
46
+ = calendar.ical.refresh_automatically? ? "yes" : "no"
47
+ - else
48
+ n/a
49
+ - tbody.action_cell do
50
+ %td
51
+ = render :partial => 'actions', :locals => {:calendar => calendar}
52
+
53
+ - render_region :bottom do |bottom|
54
+ - bottom.buttons do
55
+ #actions
56
+ = pagination_for @calendars
57
+ %ul
58
+ %li= link_to image('plus') + " " + "new calendar", new_admin_calendar_url
59
+ %li= link_to "évent list", admin_events_url
60
+ %li= link_to "venue list", admin_event_venues_url
@@ -0,0 +1,10 @@
1
+ - include_stylesheet('admin/calendar')
2
+
3
+ - render_region :main do |main|
4
+ - main.edit_header do
5
+ %h1
6
+ New Calendar
7
+
8
+ - main.edit_form do
9
+ - form_for :calendar, @calendar, :url => admin_calendars_path do |f|
10
+ = render :partial => "form", :locals => { :f => f }
@@ -0,0 +1,36 @@
1
+ - include_stylesheet 'admin/calendar'
2
+
3
+ %h1
4
+ = @calendar.name
5
+ calendar
6
+ = render :partial => 'actions'
7
+
8
+ %div#calendar_help
9
+ %h3
10
+ subscribe to this calendar
11
+ %ul
12
+ %li
13
+ %strong
14
+ address:
15
+ = link_to @calendar.ical.url
16
+ %li
17
+ %strong
18
+ username:
19
+ = link_to @calendar.ical.username
20
+ %li
21
+ %strong
22
+ password:
23
+ = link_to @calendar.ical.password
24
+ %p
25
+ This may be part of a master calendar with several individual calendars. In that case there will be a different address that lets you access all the calendars at once. Consult your site administrator if unsure.
26
+
27
+ %table#events.index{:cellspacing=>"0", :border=>"0", :cellpadding=>"0"}
28
+ = render :partial => 'events/list_head'
29
+ %tbody
30
+ - if @calendar.events.any?
31
+ - @calendar.events.each do |event|
32
+ = render :partial => 'event', :object => event
33
+ - else
34
+ %tr
35
+ %td.note{:colspan => admin.event.index.tbody.length}
36
+ No Events
@@ -0,0 +1,18 @@
1
+ %tr{:class => ".node.level-1"}
2
+ - render_region :tbody do |tbody|
3
+ - tbody.title_cell do
4
+ %td.event_venue
5
+ %h3.title
6
+ = link_to event_venue.title, edit_admin_event_venue_url(event_venue)
7
+ %p.description
8
+ = truncate(event_venue.description, 128)
9
+ - tbody.location_cell do
10
+ %td.location
11
+ = event_venue.address
12
+ - tbody.url_cell do
13
+ %td.url
14
+ - if event_venue.url
15
+ = link_to event_venue.url
16
+ - tbody.modify_cell do
17
+ %td.remove
18
+ = link_to 'remove', remove_admin_event_venue_url(event_venue)
@@ -0,0 +1,44 @@
1
+ - include_stylesheet "admin/event_calendar"
2
+ - include_javascript "admin/event_calendar"
3
+ - if defined? TinyMceFilter
4
+ - include_javascript "tiny_mce/tiny_mce"
5
+ - include_javascript "tiny_mce/tiny_mce_settings"
6
+ - include_javascript "tiny_mce/application"
7
+
8
+ - or_choose ||= false
9
+ - event_venue ||= EventVenue.new
10
+
11
+ .title
12
+ %p.venue_title
13
+ = f.label :title, "Venue or location title"
14
+ = f.text_field :title, :class => 'textbox'
15
+ - if or_choose && @venues.any?
16
+ = link_to "choose an existing place", '#', :class => 'swapper', :rel => 'toggle[venue,new_venue]'
17
+
18
+ %p.note
19
+ - if or_choose && @venues.any?
20
+ If you've used this place before, please
21
+ = link_to "choose it from the list", '#', :class => 'swapper', :rel => 'toggle[venue,new_venue]'
22
+ so that you can update it globally
23
+ - else
24
+ Next time you add an event you'll be able to choose this venue from a list
25
+
26
+ %p.url
27
+ = f.label :url, "Venue website"
28
+ = f.text_field :url, :class => 'textbox'
29
+
30
+ %p.venue_location
31
+ = f.label :address, "Address or location"
32
+ = f.text_area :address, :class => 'textarea'
33
+
34
+ %p.venue_postcode
35
+ = f.label :postcode, "Postcode or grid reference"
36
+ = f.text_field :postcode, :class => 'textbox place'
37
+ %span.note
38
+ This is only required if your address is unusual or you want these events to show on a map in a particular place.
39
+
40
+ %p.venue_description
41
+ - if defined? TinyMceFilter
42
+ = link_to image('mce', :alt=> 'toolbar icon'), '#', :class => 'toggleMCE', :rel => "toggle[event_venue_#{event_venue.id}_description]"
43
+ = f.label :description, "Description"
44
+ = f.text_area :description, :class => 'textarea', :id => "event_venue_#{event_venue.id}_description"
@@ -0,0 +1,32 @@
1
+ - include_stylesheet "admin/calendar"
2
+
3
+ - render_region :main do |main|
4
+ - main.edit_header do
5
+ %h1
6
+ Edit Location
7
+ %p
8
+ Remember that changes you make here will affect the display of every event in this location.
9
+
10
+ - main.edit_form do
11
+ - form_for [:admin, @event_venue] do |f|
12
+
13
+ = f.hidden_field :lock_version
14
+ = render_region :form_top
15
+
16
+ = error_messages_for :event_venue
17
+
18
+ #venue_form.form-area
19
+ - render_region :form do |form|
20
+ - form.edit_event_venue do
21
+ .new_venue
22
+ = render :partial => 'form', :locals => {:f => f}
23
+
24
+ - render_region :form_bottom do |form_bottom|
25
+ - form_bottom.edit_timestamp do
26
+ = updated_stamp @event_venue
27
+ - form_bottom.edit_buttons do
28
+ %p.buttons
29
+ = f.submit "Update Venue", :name => "commit", :class => "button"
30
+ = save_model_and_continue_editing_button(@event_venue)
31
+ or
32
+ = link_to 'Cancel', admin_event_venues_url
@@ -0,0 +1,33 @@
1
+ - include_stylesheet "admin/event_calendar"
2
+
3
+ #event_venues_table.outset
4
+ %table#event_venues.index{:cellspacing=>"0", :border=>"0", :cellpadding=>"0"}
5
+ %thead
6
+ %tr
7
+ - render_region :thead do |thead|
8
+ - thead.title_header do
9
+ %th.event
10
+ %strong Place
11
+ - thead.location_header do
12
+ %th.location Address
13
+ - thead.url_header do
14
+ %th.keywords Website
15
+ - thead.modify_header do
16
+ %th.modify Modify
17
+ %tbody
18
+ - if @event_venues.any?
19
+ - @event_venues.each do |event_venue|
20
+ = render :partial => 'event_venue', :object => event_venue
21
+ - else
22
+ %tr
23
+ %td.note{:colspan => admin.event_venue.index.tbody.length}
24
+ No places in the system yet. You can create one here or when you add an event.
25
+
26
+ - render_region :bottom do |bottom|
27
+ - bottom.buttons do
28
+ #actions
29
+ = pagination_for @event_venues
30
+ %ul
31
+ %li= link_to image('plus') + " " + "new venue", new_admin_event_venue_url
32
+ %li= link_to "évent list", admin_events_url
33
+ %li= link_to "calendar list", admin_calendars_url
@@ -0,0 +1,32 @@
1
+ - include_stylesheet "admin/calendar"
2
+
3
+ - render_region :main do |main|
4
+ - main.edit_header do
5
+ %h1
6
+ Add an event location
7
+ %p
8
+ You can also do this whenever you enter a new event.
9
+
10
+ - main.edit_form do
11
+ - form_for [:admin, @event_venue] do |f|
12
+
13
+ = f.hidden_field :lock_version
14
+ = render_region :form_top
15
+
16
+ = error_messages_for :event_venue
17
+
18
+ #venue_form.form-area
19
+ - render_region :form do |form|
20
+ - form.edit_event_venue do
21
+ .new_venue
22
+ = render :partial => 'form', :locals => {:f => f}
23
+
24
+ - render_region :form_bottom do |form_bottom|
25
+ - form_bottom.edit_timestamp do
26
+ = updated_stamp @event_venue
27
+ - form_bottom.edit_buttons do
28
+ %p.buttons
29
+ = f.submit "Create Venue", :name => "commit", :class => "button"
30
+ = save_model_and_continue_editing_button(@event_venue)
31
+ or
32
+ = link_to 'Cancel', admin_event_venues_url
@@ -0,0 +1,17 @@
1
+ %h1 Remove event
2
+
3
+ %p
4
+ Are you sure you want to
5
+ %strong.warning
6
+ remove permanently
7
+ the following event?
8
+
9
+ %table.index#events
10
+ %tbody
11
+ = render :partial => 'event', :object => @event
12
+
13
+ - form_for [:admin, @event], :html => {:method => :delete} do
14
+ %p.buttons
15
+ %input.button{:type=>"submit", :value=>"Delete event"}/
16
+ or
17
+ = link_to 'Cancel', admin_events_url
@@ -0,0 +1,47 @@
1
+ - master_event = event.occurrence? ? event.master : event
2
+ - cssclass = "node level-1"
3
+ - cssclass << " continuing" if event.continuing?
4
+
5
+ %tr{:class => cssclass}
6
+ - render_region :tbody do |tbody|
7
+ - tbody.date_cell do
8
+ %td.datemark
9
+ - if event.editable?
10
+ %a{:href => admin_event_url(master_event), :class => event.occurrence? ? 'occurrence' : 'master'}
11
+ %span.month= Date::ABBR_MONTHNAMES[event.start_date.month]
12
+ %span.day= event.start_date.mday
13
+ - else
14
+ %span.month= Date::ABBR_MONTHNAMES[event.start_date.month]
15
+ %span.day= event.start_date.mday
16
+ - tbody.title_cell do
17
+ %td.event
18
+ %h3.title
19
+ - if event.editable?
20
+ = link_to event.title, edit_admin_event_url(master_event), :class => event.occurrence? ? 'occurrence' : 'master'
21
+ - else
22
+ = event.title
23
+ %p.description
24
+ = truncate(event.description, 128)
25
+ - unless event.keywords.blank?
26
+ %p.keywords
27
+ %strong
28
+ tags:
29
+ = event.keywords
30
+ - tbody.calendar_cell do
31
+ %td.calendar
32
+ = link_to event.calendar.name, admin_calendar_url(event.calendar) if event.calendar
33
+ - tbody.time_cell do
34
+ %td.time
35
+ = event.summarize_period
36
+ - tbody.location_cell do
37
+ %td.location
38
+ = event.location
39
+ - tbody.modify_cell do
40
+ %td.remove
41
+ - if event.editable?
42
+ - confirmation = "Are you sure you want to delete entirely the event '#{event.title}'"
43
+ - confirmation << " and all its recurrences" if event.recurs?
44
+ = link_to "remove", admin_event_url(event.master || event), :confirm => "#{confirmation}?", :method => 'delete'
45
+ - else
46
+ %span.ineditable{:title => "subscribed events can't be removed here"}
47
+ remove