droom 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 +23 -0
- data/Rakefile +27 -0
- data/app/assets/images/droom/arrows.png +0 -0
- data/app/assets/images/droom/big_icons.png +0 -0
- data/app/assets/images/droom/blueblob.png +0 -0
- data/app/assets/images/droom/close.png +0 -0
- data/app/assets/images/droom/cross.png +0 -0
- data/app/assets/images/droom/download.png +0 -0
- data/app/assets/images/droom/greyblob.png +0 -0
- data/app/assets/images/droom/help/goodreader.jpg +0 -0
- data/app/assets/images/droom/ical.png +0 -0
- data/app/assets/images/droom/icons.png +0 -0
- data/app/assets/images/droom/medium_icons.png +0 -0
- data/app/assets/images/droom/medium_object_icons.png +0 -0
- data/app/assets/images/droom/minimonth.png +0 -0
- data/app/assets/images/droom/minisymbols.png +0 -0
- data/app/assets/images/droom/object_icons.png +0 -0
- data/app/assets/images/droom/pinkblob.png +0 -0
- data/app/assets/images/droom/place_busy.png +0 -0
- data/app/assets/images/droom/place_quiet.png +0 -0
- data/app/assets/images/droom/plus_bullet.png +0 -0
- data/app/assets/images/droom/search.png +0 -0
- data/app/assets/images/droom/setup.png +0 -0
- data/app/assets/images/droom/small_go.png +0 -0
- data/app/assets/images/droom/smallbullet.png +0 -0
- data/app/assets/images/droom/smallspinner.gif +0 -0
- data/app/assets/images/droom/spinner.gif +0 -0
- data/app/assets/images/droom/spr_toolbar_icons_r2.png +0 -0
- data/app/assets/images/droom/tablesort.png +0 -0
- data/app/assets/images/droom/tick.png +0 -0
- data/app/assets/images/droom/tinysymbols.png +0 -0
- data/app/assets/images/droom/twister.png +0 -0
- data/app/assets/images/droom/vcard.png +0 -0
- data/app/assets/images/droom/venue_bullet.png +0 -0
- data/app/assets/javascripts/droom.js.coffee +88 -0
- data/app/assets/javascripts/droom/calendar.js.coffee +121 -0
- data/app/assets/javascripts/droom/drag_sort.js.coffee +22 -0
- data/app/assets/javascripts/droom/forms.js.coffee +746 -0
- data/app/assets/javascripts/droom/lib/extensions.js.coffee +60 -0
- data/app/assets/javascripts/droom/lib/jquery.animate-colors.js +109 -0
- data/app/assets/javascripts/droom/lib/jquery.cookie.js +71 -0
- data/app/assets/javascripts/droom/lib/jquery.sortable.js +97 -0
- data/app/assets/javascripts/droom/lib/kalendae.js +1692 -0
- data/app/assets/javascripts/droom/lib/modernizr.js +4 -0
- data/app/assets/javascripts/droom/lib/parser_rules/advanced.js +553 -0
- data/app/assets/javascripts/droom/lib/parser_rules/simple.js +32 -0
- data/app/assets/javascripts/droom/lib/wysihtml5.js +9550 -0
- data/app/assets/javascripts/droom/map.js.coffee +123 -0
- data/app/assets/javascripts/droom/sort.js.coffee +126 -0
- data/app/assets/javascripts/droom/suggester.js.coffee +230 -0
- data/app/assets/stylesheets/droom.css.sass +1151 -0
- data/app/assets/stylesheets/lib/_kalendae.css.sass +142 -0
- data/app/assets/stylesheets/lib/_toolbar.css.sass +192 -0
- data/app/controllers/droom/dashboard_controller.rb +27 -0
- data/app/controllers/droom/document_attachments_controller.rb +19 -0
- data/app/controllers/droom/documents_controller.rb +116 -0
- data/app/controllers/droom/engine_controller.rb +43 -0
- data/app/controllers/droom/events_controller.rb +120 -0
- data/app/controllers/droom/group_invitations_controller.rb +47 -0
- data/app/controllers/droom/groups_controller.rb +67 -0
- data/app/controllers/droom/invitations_controller.rb +43 -0
- data/app/controllers/droom/memberships_controller.rb +47 -0
- data/app/controllers/droom/pages_controller.rb +61 -0
- data/app/controllers/droom/people_controller.rb +92 -0
- data/app/controllers/droom/suggestions_controller.rb +58 -0
- data/app/controllers/droom/venues_controller.rb +39 -0
- data/app/helpers/droom/droom_helper.rb +74 -0
- data/app/models/droom/agenda_category.rb +8 -0
- data/app/models/droom/category.rb +27 -0
- data/app/models/droom/document.rb +110 -0
- data/app/models/droom/document_attachment.rb +71 -0
- data/app/models/droom/document_link.rb +31 -0
- data/app/models/droom/event.rb +409 -0
- data/app/models/droom/event_set.rb +6 -0
- data/app/models/droom/group.rb +66 -0
- data/app/models/droom/group_invitation.rb +23 -0
- data/app/models/droom/invitation.rb +30 -0
- data/app/models/droom/membership.rb +27 -0
- data/app/models/droom/page.rb +26 -0
- data/app/models/droom/person.rb +302 -0
- data/app/models/droom/personal_document.rb +98 -0
- data/app/models/droom/recurrence_rule.rb +82 -0
- data/app/models/droom/venue.rb +125 -0
- data/app/views/droom/dashboard/_marginalia.html.haml +3 -0
- data/app/views/droom/dashboard/_my_future_events.html.haml +9 -0
- data/app/views/droom/dashboard/_my_group_documents.html.haml +6 -0
- data/app/views/droom/dashboard/_my_past_events.haml +6 -0
- data/app/views/droom/dashboard/index.html.haml +5 -0
- data/app/views/droom/documents/_created.html.haml +2 -0
- data/app/views/droom/documents/_document.html.haml +14 -0
- data/app/views/droom/documents/_document_line.html.haml +2 -0
- data/app/views/droom/documents/_documents_list.html.haml +31 -0
- data/app/views/droom/documents/_documents_table.html.haml +13 -0
- data/app/views/droom/documents/_event_document_form.html.haml +15 -0
- data/app/views/droom/documents/_form.html.haml +22 -0
- data/app/views/droom/documents/_listing.html.haml +8 -0
- data/app/views/droom/documents/_suggested.html.haml +9 -0
- data/app/views/droom/documents/_table_document.html.haml +31 -0
- data/app/views/droom/documents/edit.html.haml +1 -0
- data/app/views/droom/documents/index.html.haml +29 -0
- data/app/views/droom/documents/new.html.haml +1 -0
- data/app/views/droom/errors/bang.html.haml +12 -0
- data/app/views/droom/errors/not_allowed.html.haml +12 -0
- data/app/views/droom/errors/not_found.html.haml +12 -0
- data/app/views/droom/events/_attachment.html.haml +1 -0
- data/app/views/droom/events/_attachment_list.html.haml +4 -0
- data/app/views/droom/events/_calendar.html.haml +54 -0
- data/app/views/droom/events/_created.html.haml +2 -0
- data/app/views/droom/events/_event.html.haml +77 -0
- data/app/views/droom/events/_event_line.html.haml +13 -0
- data/app/views/droom/events/_events.html.haml +2 -0
- data/app/views/droom/events/_form.html.haml +35 -0
- data/app/views/droom/events/_invitations.html.haml +20 -0
- data/app/views/droom/events/_other_page_parts.html.haml +0 -0
- data/app/views/droom/events/_popup_event.html.haml +6 -0
- data/app/views/droom/events/_suggested.html.haml +12 -0
- data/app/views/droom/events/_views.html.haml +7 -0
- data/app/views/droom/events/edit.html.haml +1 -0
- data/app/views/droom/events/index.html.haml +12 -0
- data/app/views/droom/events/index.rss.builder +20 -0
- data/app/views/droom/events/new.html.haml +1 -0
- data/app/views/droom/events/show.html.haml +4 -0
- data/app/views/droom/group_invitations/_attending_groups.html.haml +8 -0
- data/app/views/droom/group_invitations/_created.html.haml +3 -0
- data/app/views/droom/group_invitations/_form.html.haml +4 -0
- data/app/views/droom/group_invitations/new.html.haml +1 -0
- data/app/views/droom/groups/_created.html.haml +3 -0
- data/app/views/droom/groups/_form.html.haml +12 -0
- data/app/views/droom/groups/_group.html.haml +11 -0
- data/app/views/droom/groups/_groups.html.haml +3 -0
- data/app/views/droom/groups/edit.html.haml +1 -0
- data/app/views/droom/groups/index.html.haml +7 -0
- data/app/views/droom/groups/show.html.haml +13 -0
- data/app/views/droom/invitations/_attending_people.html.haml +8 -0
- data/app/views/droom/invitations/_created.html.haml +3 -0
- data/app/views/droom/invitations/_form.html.haml +5 -0
- data/app/views/droom/invitations/new.html.haml +1 -0
- data/app/views/droom/memberships/_button.html.haml +11 -0
- data/app/views/droom/memberships/_created.html.haml +4 -0
- data/app/views/droom/memberships/_form.html.haml +7 -0
- data/app/views/droom/memberships/_member.html.haml +33 -0
- data/app/views/droom/memberships/_memberships.html.haml +4 -0
- data/app/views/droom/pages/_contents.html.haml +10 -0
- data/app/views/droom/pages/_form.html.haml +36 -0
- data/app/views/droom/pages/_full_page.html.haml +17 -0
- data/app/views/droom/pages/_page.html.haml +5 -0
- data/app/views/droom/pages/_pages.html.haml +2 -0
- data/app/views/droom/pages/admin.html.haml +24 -0
- data/app/views/droom/pages/edit.html.haml +1 -0
- data/app/views/droom/pages/index.html.haml +10 -0
- data/app/views/droom/pages/new.html.haml +4 -0
- data/app/views/droom/pages/show.html.haml +5 -0
- data/app/views/droom/people/_created.html.haml +6 -0
- data/app/views/droom/people/_form.html.haml +40 -0
- data/app/views/droom/people/_people.html.haml +29 -0
- data/app/views/droom/people/_person.html.haml +34 -0
- data/app/views/droom/people/_suggested.html.haml +9 -0
- data/app/views/droom/people/edit.html.haml +1 -0
- data/app/views/droom/people/index.html.haml +11 -0
- data/app/views/droom/people/new.html.haml +1 -0
- data/app/views/droom/people/show.html.haml +1 -0
- data/app/views/droom/shared/_calendar_and_search.html.haml +2 -0
- data/app/views/droom/shared/_calendar_holder.haml +3 -0
- data/app/views/droom/shared/_controls.html.haml +8 -0
- data/app/views/droom/shared/_navigation.html.haml +8 -0
- data/app/views/droom/shared/_search_form.html.haml +4 -0
- data/app/views/droom/shared/_suggestions.html.haml +11 -0
- data/app/views/droom/shared/_toolbar.html.haml +17 -0
- data/app/views/droom/venues/_suggested.html.haml +6 -0
- data/app/views/droom/venues/index.html.haml +6 -0
- data/app/views/droom/venues/show.html.haml +21 -0
- data/app/views/layouts/droom/application.html.haml +36 -0
- data/config/initializers/dav.rb +2 -0
- data/config/initializers/paperclip.rb +26 -0
- data/config/initializers/snail.rb +2 -0
- data/config/locales/en.yml +191 -0
- data/config/routes.rb +51 -0
- data/db/migrate/20120910075016_create_droom_data.rb +134 -0
- data/db/migrate/20120917095804_agenda_sections.rb +13 -0
- data/db/migrate/20120918121352_add_postal_address_to_people.rb +10 -0
- data/db/migrate/20121009075049_give_groups_descriptions.rb +5 -0
- data/db/migrate/20121009105244_more_names.rb +5 -0
- data/db/migrate/20121009145944_event_agenda_sections.rb +13 -0
- data/db/migrate/20121011091230_create_group_invitations.rb +10 -0
- data/db/migrate/20121012144720_give_people_positions.rb +5 -0
- data/db/migrate/20121012154558_help_pages.rb +13 -0
- data/db/migrate/20121012163201_category_slugs.rb +5 -0
- data/db/migrate/20121101160102_document_links.rb +14 -0
- data/db/migrate/20121101181247_people_visibility.rb +7 -0
- data/db/migrate/20121102094738_shy_people.rb +6 -0
- data/db/migrate/20121102095856_visibility_defaults.rb +8 -0
- data/lib/droom.rb +73 -0
- data/lib/droom/dav_resource.rb +36 -0
- data/lib/droom/engine.rb +8 -0
- data/lib/droom/helpers.rb +25 -0
- data/lib/droom/monkeys.rb +15 -0
- data/lib/droom/renderers.rb +13 -0
- data/lib/droom/validators.rb +5 -0
- data/lib/droom/version.rb +3 -0
- data/lib/generators/droom/dashboard/dashboard_generator.rb +16 -0
- data/lib/generators/droom/install/USAGE +9 -0
- data/lib/generators/droom/install/install_generator.rb +15 -0
- data/lib/generators/droom/install/templates/droom_initializer.rb +6 -0
- data/lib/generators/droom/views/views_generator.rb +9 -0
- data/lib/tasks/droom_tasks.rake +4 -0
- metadata +635 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
module Droom
|
|
2
|
+
class PersonalDocument < ActiveRecord::Base
|
|
3
|
+
attr_accessible :document_link, :person
|
|
4
|
+
|
|
5
|
+
belongs_to :document_link
|
|
6
|
+
|
|
7
|
+
has_attached_file :file, {
|
|
8
|
+
:storage => :filesystem,
|
|
9
|
+
:path => ":rails_root/:dav_root/:person/:category_and_slug/:filename",
|
|
10
|
+
:url => "/:dav_root/:person/:category_and_slug/:filename",
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
before_create :clone_file
|
|
14
|
+
|
|
15
|
+
scope :derived_from, lambda { |document|
|
|
16
|
+
select("droom_personal_documents.*")
|
|
17
|
+
.joins("INNER JOIN droom_document_links AS ddl ON droom_personal_documents.document_link_id = ddl.id")
|
|
18
|
+
.joins("INNER JOIN droom_document_attachments AS dda ON ddl.document_attachment_id = dda.id")
|
|
19
|
+
.where(["dda.document_id = ?", document.id])
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
scope :belonging_to, lambda { |person|
|
|
23
|
+
where(["person_id = ?", person.id])
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
# document properties we have to retrieve across quite a long chain,
|
|
27
|
+
# but it should be possible to rely on its existence. If not, we have
|
|
28
|
+
# other problems.
|
|
29
|
+
|
|
30
|
+
delegate :slug, :category, :person_id, :to => :document_link
|
|
31
|
+
|
|
32
|
+
def person
|
|
33
|
+
document_link.person
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def document
|
|
37
|
+
document_link.document
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def name
|
|
41
|
+
document.name
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def description
|
|
45
|
+
document.description
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def file_changed?
|
|
49
|
+
file_fingerprint != Digest::MD5.file(file.path).to_s
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def file_touched?
|
|
53
|
+
File.mtime(file.path) > Time.at(file.updated_at)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def file_path
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def url
|
|
61
|
+
file.url if file
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def file_extension
|
|
65
|
+
File.extname(file_file_name).sub(/^\./, '')
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def reclone_if_changed
|
|
69
|
+
reclone_file if document.version > self.version
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
protected
|
|
73
|
+
|
|
74
|
+
def clone_file
|
|
75
|
+
self.version = document.version
|
|
76
|
+
self.file = document.file
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def reclone_file
|
|
80
|
+
archive_file if file? && file_touched?
|
|
81
|
+
clone_file
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# If the previous file for some reason needs to be preserved - usually because it has been edited
|
|
85
|
+
# in some way by its owner - we archive it by interpolating _vX into the filename, where X is
|
|
86
|
+
# the current version of this personal document (which is the same as the old version of its
|
|
87
|
+
# document. Calling clone_file again will update our version as well as retrieving the new file.
|
|
88
|
+
# This way we can avoid storing all the files with redundant version suffixed (almost everything would
|
|
89
|
+
# be _v1), keep useful older versions in a comprebensible way and discard old versions that aren't special.
|
|
90
|
+
#
|
|
91
|
+
def archive_file
|
|
92
|
+
suffix = File.extname(file_file_name)
|
|
93
|
+
stem = File.basename(file_file_name, suffix)
|
|
94
|
+
dir = File.dirname(file.path)
|
|
95
|
+
FileUtils.move(file.path, "#{dir}/#{stem}_v#{version}#{suffix}")
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
module Droom
|
|
2
|
+
class RecurrenceRule < ActiveRecord::Base
|
|
3
|
+
|
|
4
|
+
belongs_to :created_by, :class_name => 'User'
|
|
5
|
+
belongs_to :event
|
|
6
|
+
|
|
7
|
+
attr_accessible :period, :interval, :basis, :limiting_count, :limiting_date
|
|
8
|
+
|
|
9
|
+
def active
|
|
10
|
+
new_record? ? false : read_attribute(:active)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def basis
|
|
14
|
+
basis = read_attribute(:basis)
|
|
15
|
+
return nil unless basis == 'count' || basis == 'limit'
|
|
16
|
+
basis
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def unbounded?
|
|
20
|
+
basis.nil?
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def single?
|
|
24
|
+
true if basis == 'limit' && limiting_count == 1
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def to_s
|
|
28
|
+
summary = []
|
|
29
|
+
if interval > 1
|
|
30
|
+
unit = period.downcase.sub(/ly$/, '')
|
|
31
|
+
unit = "day" if unit == 'dai'
|
|
32
|
+
summary << "every #{interval} #{unit.pluralize}"
|
|
33
|
+
else
|
|
34
|
+
summary << period.downcase
|
|
35
|
+
end
|
|
36
|
+
if unbounded?
|
|
37
|
+
summary.last << ","
|
|
38
|
+
summary << 'indefinitely'
|
|
39
|
+
elsif basis == 'limit' && limiting_date
|
|
40
|
+
summary << "until #{limiting_date.to_datetime.strftime('%d %B %Y')}" if limiting_date
|
|
41
|
+
elsif basis == 'count' && limiting_count
|
|
42
|
+
summary.last << ","
|
|
43
|
+
summary << "#{limiting_count} times"
|
|
44
|
+
end
|
|
45
|
+
summary.join(' ')
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def rule=(rule)
|
|
49
|
+
rule = RiCal::PropertyValue::RecurrenceRule.convert(nil, rule) unless rule.is_a? RiCal::PropertyValue::RecurrenceRule
|
|
50
|
+
self.period = rule.freq
|
|
51
|
+
self.interval = rule.interval
|
|
52
|
+
if rule.until
|
|
53
|
+
self.basis = 'limit'
|
|
54
|
+
self.limiting_date = rule.until.value
|
|
55
|
+
elsif rule.count
|
|
56
|
+
self.basis = 'count'
|
|
57
|
+
self.limiting_count = rule.count
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def rule
|
|
62
|
+
rule = RiCal::PropertyValue::RecurrenceRule.convert(nil, "") unless rule.is_a? RiCal::PropertyValue::RecurrenceRule
|
|
63
|
+
rule.freq = period.upcase
|
|
64
|
+
rule.until = limiting_date if basis == 'limit' && limiting_date
|
|
65
|
+
rule.count = limiting_count if basis == 'count' && limiting_count
|
|
66
|
+
rule.interval = interval
|
|
67
|
+
rule
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def self.from(rule) # ical string or RiCal::PropertyValue::RecurrenceRule
|
|
71
|
+
rrule = self.new
|
|
72
|
+
rrule.rule = rule
|
|
73
|
+
rrule.active = true
|
|
74
|
+
rrule
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def to_rical
|
|
78
|
+
rule.to_ical
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
require 'snail'
|
|
2
|
+
|
|
3
|
+
module Droom
|
|
4
|
+
class Venue < ActiveRecord::Base
|
|
5
|
+
attr_accessible :name, :lat, :lng, :post_line1, :post_line2, :post_city, :post_country, :post_code
|
|
6
|
+
|
|
7
|
+
belongs_to :created_by, :class_name => 'User'
|
|
8
|
+
has_many :events, :dependent => :nullify
|
|
9
|
+
acts_as_mappable
|
|
10
|
+
|
|
11
|
+
default_scope :order => 'name asc'
|
|
12
|
+
before_validation :geocode_and_get_address
|
|
13
|
+
|
|
14
|
+
scope :name_matching, lambda { |fragment|
|
|
15
|
+
fragment = "%#{fragment}%"
|
|
16
|
+
where('droom_venues.name like ?', fragment)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
# *for_selection* returns a set of [name, id] pairs suitable for use as select options.
|
|
20
|
+
def self.for_selection
|
|
21
|
+
self.all.map{|v| [v.proper_name, v.id] }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def proper_name
|
|
25
|
+
if prepend_article?
|
|
26
|
+
"the #{name}"
|
|
27
|
+
else
|
|
28
|
+
name
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def to_s
|
|
33
|
+
name
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def identifier
|
|
37
|
+
'venue'
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Snail is a library that abstracts away - as far as possible - the vagaries of international address formats. Here we map our data columns onto Snail's abstract representations so that they can be rendered into the correct format for their country.
|
|
41
|
+
def address
|
|
42
|
+
Snail.new(
|
|
43
|
+
:line_1 => post_line1,
|
|
44
|
+
:line_2 => post_line2,
|
|
45
|
+
:city => post_city,
|
|
46
|
+
:region => post_region,
|
|
47
|
+
:postal_code => post_code,
|
|
48
|
+
:country => post_country
|
|
49
|
+
)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def address?
|
|
53
|
+
post_line1? && post_city
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def as_json(options={})
|
|
57
|
+
json = {
|
|
58
|
+
:id => id,
|
|
59
|
+
:name => name,
|
|
60
|
+
:postcode => post_code,
|
|
61
|
+
:address => address.to_s,
|
|
62
|
+
:lat => lat,
|
|
63
|
+
:lng => lng,
|
|
64
|
+
:events => events.visible_to(options[:person]).as_json(options)
|
|
65
|
+
}
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def as_ri_cal_calendar
|
|
69
|
+
RiCal.Calendar do |cal|
|
|
70
|
+
events.primary.each do |event|
|
|
71
|
+
cal.add_subcomponent(event.to_ri_cal)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def to_ical
|
|
77
|
+
self.as_ri_cal_calendar.to_s
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# We only go back to google for a new map location if there has been a change of address, but there are many places in which that could happen.
|
|
81
|
+
#
|
|
82
|
+
def address_changed?
|
|
83
|
+
name_changed? || post_line1_changed? || post_line2_changed? || post_city_changed? || post_region_changed? || post_code_changed? || post_country_changed?
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
private
|
|
87
|
+
|
|
88
|
+
# This is the main geocoding routine, called before validation on every save. If there has been a significant change,
|
|
89
|
+
# it will trigger the goecoding mechanism with a block that updates our address when a match is found.
|
|
90
|
+
# It's fairly uncritical and probably needs to be more careful about overriding user-entered data.
|
|
91
|
+
#
|
|
92
|
+
def geocode_and_get_address(options={})
|
|
93
|
+
unless Rails.env.test?
|
|
94
|
+
if new_record? || address_changed? || options[:force]
|
|
95
|
+
geocode_with(:name) do |geo|
|
|
96
|
+
self.post_line1 = geo.street_address
|
|
97
|
+
self.post_city = geo.city
|
|
98
|
+
self.post_region = geo.province
|
|
99
|
+
self.post_country = geo.country
|
|
100
|
+
self.post_code = geo.zip
|
|
101
|
+
sleep(options[:delay].seconds) if options[:delay]
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# *geocode_with* does the actual lookup, passing the value of the specified column to the google geocoder service (with help from Geokit)
|
|
108
|
+
# and yielding to the supplied block as soon as a match is found.
|
|
109
|
+
#
|
|
110
|
+
def geocode_with(attribute, &block)
|
|
111
|
+
value = send(attribute)
|
|
112
|
+
found = false
|
|
113
|
+
unless value.blank?
|
|
114
|
+
geo = Geokit::Geocoders::GoogleGeocoder3.geocode(value, :bias => Droom.geocode_bias, :language => 'en')
|
|
115
|
+
if geo.success
|
|
116
|
+
self.lat, self.lng = geo.lat, geo.lng
|
|
117
|
+
yield geo if block_given?
|
|
118
|
+
found = true
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
found
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
end
|
|
125
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
- cssclasses = ["dl"]
|
|
2
|
+
- cssclasses << document.file_extension
|
|
3
|
+
- cssclasses << 'changed' if document.changed_since_creation?
|
|
4
|
+
|
|
5
|
+
%div.document.holder
|
|
6
|
+
%h2.name<
|
|
7
|
+
= link_to truncate(document.name, :length => 33), document_url(document), :class => cssclasses, :title => t(:click_to_download, :name => document.file_file_name)
|
|
8
|
+
- if admin?
|
|
9
|
+
= link_to t(:edit_document), edit_document_url(document), :class => 'admin edit minimal', :remote => true, :data => {:action => "overlay", :type => "html"}
|
|
10
|
+
|
|
11
|
+
- if document.description
|
|
12
|
+
- cssclasses = document.changed_since_creation? ? "description changed" : "description"
|
|
13
|
+
%p{:class => cssclasses}
|
|
14
|
+
= document.description
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
- event ||= @event
|
|
2
|
+
|
|
3
|
+
.documents{ :"data-url" => "#{event_documents_path(event)}.js", :"data-refreshable" => true}
|
|
4
|
+
|
|
5
|
+
%section.holder
|
|
6
|
+
|
|
7
|
+
- if event.document_attachments.any?
|
|
8
|
+
%h2
|
|
9
|
+
= t :attachments
|
|
10
|
+
= link_to t(:add_document), droom.new_event_document_url(event), :class => "add minimal admin", :remote => true, :data => {:action => "append_form", :type => "html", :affected => ".documents"}
|
|
11
|
+
/ %p
|
|
12
|
+
/ = link_to t(:download_attachments_as_zipfile), event_url(event, :format => :zip), :class => "download"
|
|
13
|
+
|
|
14
|
+
= render :partial => "droom/events/attachment_list", :object => event.document_attachments.unfiled, :locals => {:limit => 100}
|
|
15
|
+
|
|
16
|
+
- elsif admin?
|
|
17
|
+
.holder
|
|
18
|
+
= link_to t(:add_document), droom.new_event_document_url(event), :class => "add admin", :remote => true, :data => {:action => "append_form", :type => "html", :affected => ".documents"}
|
|
19
|
+
|
|
20
|
+
- attachments = event.attachments_by_category
|
|
21
|
+
- attachments.each_pair do |cat_name, category_attachments|
|
|
22
|
+
- if admin? || category_attachments.any?
|
|
23
|
+
- unless cat_name == "uncategorised"
|
|
24
|
+
%section.holder
|
|
25
|
+
%h3
|
|
26
|
+
= cat_name
|
|
27
|
+
- if admin?
|
|
28
|
+
= link_to t(:add_document), droom.new_event_document_url(event, :category_name => cat_name), :class => "add minimal admin", :remote => true, :data => {:action => "append_form", :type => "html", :affected => ".documents"}
|
|
29
|
+
|
|
30
|
+
= render :partial => "droom/events/attachment_list", :object => category_attachments, :locals => {:limit => 100}
|
|
31
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
%tbody{:"data-url" => "#{documents_path}.js", :"data-refreshable" => true }
|
|
2
|
+
- if @documents.any?
|
|
3
|
+
= render :partial => 'table_document', :collection => @documents
|
|
4
|
+
%tr
|
|
5
|
+
%td{:colspan => 6}
|
|
6
|
+
.pagination
|
|
7
|
+
= paginate @documents, :params => {:format => :js}
|
|
8
|
+
- else
|
|
9
|
+
%tr
|
|
10
|
+
%td{:colspan => 6}
|
|
11
|
+
%p.nothing_to_see
|
|
12
|
+
= t :no_documents
|
|
13
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
= form_for [@event, @document], :html => {:class => 'edit document'} do |f|
|
|
2
|
+
.filepicker
|
|
3
|
+
= link_to "choose file", "#", :class => "ul minimal #{@document.file_extension}"
|
|
4
|
+
= f.file_field :file, :class => "file"
|
|
5
|
+
.other
|
|
6
|
+
%p.name
|
|
7
|
+
= f.text_field :name, :class => 'name', :placeholder => t(:document_name)
|
|
8
|
+
%p.description
|
|
9
|
+
= f.text_area :description, :class => 'description', :placeholder => t(:document_description)
|
|
10
|
+
|
|
11
|
+
.buttons
|
|
12
|
+
= link_to t(:save_doc), '#', :class => 'submit'
|
|
13
|
+
/ = f.submit t(:save_doc)
|
|
14
|
+
= t :or
|
|
15
|
+
= link_to t(:cancel), "/", :class => 'cancel'
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
= form_for @document, :html => { :multipart => true, :class => 'edit document', :remote => true, :data => {:type => :html}} do |f|
|
|
2
|
+
- if @event
|
|
3
|
+
= f.hidden_field :event_id, :value => @event.id
|
|
4
|
+
- if @category
|
|
5
|
+
= f.hidden_field :attachment_category_id, :value => @category.id
|
|
6
|
+
|
|
7
|
+
.filepicker
|
|
8
|
+
= link_to "choose file", "#", :class => "ul minimal #{@document.file_extension}"
|
|
9
|
+
= f.file_field :file, :class => "file"
|
|
10
|
+
%p.tip
|
|
11
|
+
= t :click_to_choose_file
|
|
12
|
+
|
|
13
|
+
.metadata
|
|
14
|
+
%p.name
|
|
15
|
+
= f.text_field :name, :class => 'name', :placeholder => t(:document_name)
|
|
16
|
+
%p.description
|
|
17
|
+
= f.text_area :description, :class => 'description', :placeholder => t(:document_description)
|
|
18
|
+
|
|
19
|
+
.buttons
|
|
20
|
+
= f.submit t(:save_document)
|
|
21
|
+
= t :or
|
|
22
|
+
= link_to t(:cancel), "/", :class => 'cancel'
|