droom 0.2.1 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. data/app/assets/images/droom/Untitled-1.png +0 -0
  2. data/app/assets/images/droom/asterisk.png +0 -0
  3. data/app/assets/images/droom/dropbox_small.png +0 -0
  4. data/app/assets/images/droom/handle.png +0 -0
  5. data/app/assets/images/droom/minisymbols.png +0 -0
  6. data/app/assets/images/droom/revoke_small.png +0 -0
  7. data/app/assets/images/droom/toggle.png +0 -0
  8. data/app/assets/javascripts/droom.js.coffee +4 -4
  9. data/app/assets/javascripts/droom/actions.js.coffee +16 -5
  10. data/app/assets/javascripts/droom/lib/wysihtml5.js +18 -0
  11. data/app/assets/javascripts/droom/widgets.js.coffee +72 -111
  12. data/app/assets/stylesheets/droom.css.sass +195 -119
  13. data/app/assets/stylesheets/{_definitions.css.sass → droom/_mixins.css.sass} +28 -43
  14. data/app/assets/stylesheets/{lib → droom}/_popups.css.sass +0 -0
  15. data/app/assets/stylesheets/{lib → droom}/_toolbar.css.sass +2 -4
  16. data/app/assets/stylesheets/droom/_variables.css.sass +46 -0
  17. data/app/assets/stylesheets/lib/_kalendae.css.sass +2 -2
  18. data/app/controllers/droom/engine_controller.rb +5 -1
  19. data/app/controllers/droom/events_controller.rb +9 -6
  20. data/app/controllers/droom/groups_controller.rb +1 -1
  21. data/app/controllers/droom/organisations_controller.rb +1 -1
  22. data/app/controllers/droom/people_controller.rb +18 -18
  23. data/app/controllers/droom/suggestions_controller.rb +0 -1
  24. data/app/controllers/droom/user_confirmations_controller.rb +55 -0
  25. data/app/controllers/droom/users_controller.rb +1 -2
  26. data/app/controllers/droom/youtube_controller.rb +4 -1
  27. data/app/helpers/droom/droom_helper.rb +3 -3
  28. data/app/models/droom/document.rb +3 -27
  29. data/app/models/droom/event.rb +0 -12
  30. data/app/models/droom/folder.rb +9 -10
  31. data/app/models/droom/group.rb +0 -7
  32. data/app/models/droom/person.rb +13 -20
  33. data/app/models/droom/scrap.rb +2 -12
  34. data/app/models/droom/user.rb +29 -5
  35. data/app/models/droom/venue.rb +0 -17
  36. data/app/views/{droom/users/unwelcome.en.html.haml → devise/confirmations/failure.en.html.haml} +5 -2
  37. data/app/views/devise/confirmations/new.html.haml +25 -0
  38. data/app/views/devise/confirmations/show.html.haml +32 -0
  39. data/app/views/droom/dashboard/_documents.html.haml +9 -0
  40. data/app/views/droom/dashboard/_folders.html.haml +1 -1
  41. data/app/views/droom/dashboard/_groups.html.haml +9 -0
  42. data/app/views/droom/documents/_document.html.haml +1 -1
  43. data/app/views/droom/documents/_table_document.html.haml +1 -1
  44. data/app/views/droom/events/_event.html.haml +0 -1
  45. data/app/views/droom/events/edit.html.haml +1 -1
  46. data/app/views/droom/events/index.html.haml +6 -4
  47. data/app/views/droom/events/new.html.haml +1 -1
  48. data/app/views/droom/events/show.html.haml +1 -1
  49. data/app/views/droom/folders/_folder.html.haml +2 -2
  50. data/app/views/droom/folders/edit.html.haml +1 -1
  51. data/app/views/droom/folders/index.html.haml +3 -1
  52. data/app/views/droom/folders/new.html.haml +1 -1
  53. data/app/views/droom/groups/_group.html.haml +6 -3
  54. data/app/views/droom/groups/edit.html.haml +1 -1
  55. data/app/views/droom/groups/index.html.haml +20 -1
  56. data/app/views/droom/groups/new.html.haml +1 -1
  57. data/app/views/droom/organisations/_action_menu.html.haml +3 -1
  58. data/app/views/droom/organisations/_organisation.html.haml +0 -1
  59. data/app/views/droom/organisations/edit.html.haml +1 -1
  60. data/app/views/droom/organisations/new.html.haml +1 -1
  61. data/app/views/droom/panels/_dropbox.html.haml +1 -1
  62. data/app/views/droom/panels/{_search.html.haml → _suggestions.html.haml} +3 -4
  63. data/app/views/droom/people/_form.html.haml +15 -19
  64. data/app/views/droom/people/_listing.html.haml +1 -1
  65. data/app/views/droom/people/_person.html.haml +3 -3
  66. data/app/views/droom/people/_suggested.html.haml +1 -1
  67. data/app/views/droom/people/edit.html.haml +1 -1
  68. data/app/views/droom/people/new.html.haml +1 -1
  69. data/app/views/droom/people/show.html.haml +31 -1
  70. data/app/views/droom/scraps/full/_document.html.haml +1 -1
  71. data/app/views/droom/scraps/thumbs/_document.html.haml +2 -2
  72. data/app/views/droom/shared/{_search_form.html.haml → _suggestion_form.html.haml} +1 -1
  73. data/app/views/droom/users/_extra_columns.html.haml +0 -0
  74. data/app/views/droom/users/_extra_columns_header.html.haml +0 -0
  75. data/app/views/droom/users/_extra_columns_note.html.haml +0 -0
  76. data/app/views/droom/users/_form.html.haml +5 -12
  77. data/app/views/droom/users/_user_or_person.html.haml +24 -15
  78. data/app/views/droom/users/_users_table.html.haml +24 -6
  79. data/app/views/droom/users/edit.html.haml +1 -1
  80. data/app/views/droom/users/index.html.haml +2 -5
  81. data/config/locales/devise.en.yml +1 -1
  82. data/config/locales/en.yml +22 -7
  83. data/config/routes.rb +4 -3
  84. data/lib/droom.rb +28 -14
  85. data/lib/droom/engine.rb +2 -0
  86. data/lib/droom/version.rb +1 -1
  87. data/spec/dummy/log/dav.log +1 -0
  88. data/spec/dummy/log/development.log +2 -0
  89. data/spec/dummy/log/test.log +1 -0
  90. metadata +29 -33
  91. data/app/controllers/droom/confirmations_controller.rb +0 -38
  92. data/app/controllers/droom/search_controller.rb +0 -66
  93. data/app/views/cropper/uploads/_crop.html.haml +0 -46
  94. data/app/views/devise/mailer/confirmation_instructions.en.html.haml +0 -24
  95. data/app/views/devise/mailer/reset_password_instructions.en.html.haml +0 -21
  96. data/app/views/droom/shared/_search_results.html.haml +0 -9
  97. data/app/views/droom/shared/search.html.haml +0 -18
@@ -11,19 +11,11 @@ module Droom
11
11
  has_many :dropbox_documents
12
12
  has_attached_file :file
13
13
 
14
- after_create :read_and_reindex
15
-
16
14
  after_save :update_dropbox_documents
17
15
  after_destroy :mark_dropbox_documents_deleted
18
16
 
19
17
  validates :file, :presence => true
20
18
 
21
- searchable :auto_index => false, :auto_remove => true do
22
- text :name, :boost => 10, :stored => true
23
- text :description, :stored => true
24
- text :extracted_text, :stored => true
25
- end
26
-
27
19
  scope :all_private, where("private = 1")
28
20
  scope :not_private, where("private <> 1 OR private IS NULL")
29
21
  scope :all_public, where("public = 1 AND private <> 1 OR private IS NULL")
@@ -53,9 +45,9 @@ module Droom
53
45
 
54
46
  scope :by_date, order("droom_documents.updated_at DESC, droom_documents.created_at DESC")
55
47
 
56
- def self.highlight_fields
57
- [:name, :description, :extracted_text]
58
- end
48
+ scope :latest, lambda {|limit|
49
+ order("droom_documents.updated_at DESC, droom_documents.created_at DESC").limit(limit)
50
+ }
59
51
 
60
52
  def attach_to(holder)
61
53
  self.folder = holder.folder
@@ -111,22 +103,6 @@ module Droom
111
103
  dropbox_documents.create(:person_id => user.person.id)
112
104
  end
113
105
 
114
- def read_and_reindex
115
- temp = Paperclip.io_adapters.for(self.file)
116
- data = File.read(temp.path)
117
- begin
118
- self.extracted_text = Yomu.read :text, data
119
- self.extracted_metadata = Yomu.read :metadata, data
120
- rescue Exception => e
121
- Rails.logger.warn "Failed to parse document text or metadata from #{file_file_name}: #{e}"
122
- end
123
- if self.extracted_text or self.extracted_metadata
124
- solr_index
125
- end
126
- save
127
- end
128
- handle_asynchronously :read_and_reindex, :priority => 20
129
-
130
106
  def mark_dropbox_documents_deleted
131
107
  dropbox_documents.each do |dd|
132
108
  dd.mark_deleted(true)
@@ -43,22 +43,10 @@ module Droom
43
43
  before_validation :set_uuid
44
44
  before_save :ensure_slug
45
45
  after_save :update_occurrences
46
- after_save :index
47
46
 
48
47
  scope :primary, where("master_id IS NULL")
49
48
  scope :recurrent, where(:conditions => "master_id IS NOT NULL")
50
49
 
51
- searchable do
52
- text :name, :boost => 10, :stored => true
53
- text :description, :stored => true
54
- end
55
-
56
- handle_asynchronously :solr_index
57
-
58
- def self.highlight_fields
59
- [:name, :description]
60
- end
61
-
62
50
  ## Event retrieval in various ways
63
51
  #
64
52
  # Events differ from other models in that they are visible to all unless marked 'private'.
@@ -24,22 +24,21 @@ module Droom
24
24
  scope :not_public, where("#{table_name}.public <> 1 OR #{table_name}.private = 1)")
25
25
  scope :by_name, order("#{table_name}.name ASC")
26
26
  scope :visible_to, lambda { |person|
27
- # if person
28
- # select('droom_folders.*')
29
- # .joins('LEFT OUTER JOIN droom_personal_folders AS dpf ON droom_folders.id = dpf.folder_id')
30
- # .where(["(droom_folders.public = 1 OR dpf.person_id = ?)", person.id])
31
- # .group('droom_folders.id')
32
- # else
33
- # all_public
34
- # end
35
- not_private
27
+ if person
28
+ select('droom_folders.*')
29
+ .joins('LEFT OUTER JOIN droom_personal_folders AS dpf ON droom_folders.id = dpf.folder_id')
30
+ .where(["(droom_folders.public = 1 OR dpf.person_id = ?)", person.id])
31
+ .group('droom_folders.id')
32
+ else
33
+ all_public
34
+ end
36
35
  }
37
36
 
38
37
  def visible_to?(person)
39
38
  true
40
39
  end
41
40
 
42
- # A root folders is created automatically for each class that has_folder,
41
+ # A root folder is created automatically for each class that has_folders,
43
42
  # the first time something in that class asks for its folder.
44
43
  # scope :roots, where('droom_folders.holder_type IS NULL AND droom_folders.parent_id IS NULL')
45
44
 
@@ -19,13 +19,6 @@ module Droom
19
19
  validates :slug, :uniqueness => true, :presence => true
20
20
  validates :mailing_list_name, :uniqueness => true, :presence => true
21
21
 
22
- searchable do
23
- text :name, :boost => 10, :stored => true
24
- text :description, :stored => true
25
- end
26
-
27
- handle_asynchronously :solr_index
28
-
29
22
  def self.highlight_fields
30
23
  [:name, :description]
31
24
  end
@@ -117,8 +117,8 @@ module Droom
117
117
  :geometry => "520x520#",
118
118
  :styles => {
119
119
  :icon => "32x32#",
120
- :thumb => "120x120#",
121
- :precrop => "1200x1200^"
120
+ :thumb => "130x130#",
121
+ :precrop => "1200x1200<"
122
122
  }
123
123
 
124
124
  ## Scopes
@@ -130,18 +130,6 @@ module Droom
130
130
  scope :all_public, where("public = 1 AND private <> 1 OR private IS NULL")
131
131
  scope :not_public, where("public <> 1 OR private = 1)")
132
132
 
133
- searchable do
134
- text :name, :boost => 10, :stored => true
135
- text :forename, :boost => 10, :stored => true
136
- text :description, :stored => true
137
- end
138
-
139
- handle_asynchronously :solr_index
140
-
141
- def self.highlight_fields
142
- [:name, :forename, :description]
143
- end
144
-
145
133
  scope :matching, lambda { |fragment|
146
134
  fragment = "%#{fragment}%"
147
135
  where('droom_people.name LIKE :f OR droom_people.forename LIKE :f OR droom_people.email LIKE :f OR droom_people.phone LIKE :f OR CONCAT(droom_people.forename, " ", droom_people.name) LIKE :f', :f => fragment)
@@ -281,7 +269,7 @@ module Droom
281
269
  protected
282
270
 
283
271
  def invite_if_instructed
284
- invite_user if invite_on_creation
272
+ invite_user if invite_on_creation?
285
273
  end
286
274
 
287
275
  # ### Administration & callbacks
@@ -289,12 +277,17 @@ module Droom
289
277
  # At some point we may want to create a user to log in and look after this person.
290
278
  # This usually has the side effect of sending out a confirmation message.
291
279
  #
280
+
281
+ def invite_on_creation?
282
+ !!invite_on_creation && invite_on_creation != 0 && invite_on_creation != "0"
283
+ end
284
+
292
285
  def invite_user
293
- unless self.user
294
- if invitable?
295
- user = self.create_user(:forename => forename, :name => name, :email => email)
296
- self.save
297
- end
286
+ if self.user
287
+ self.user.send_confirmation_instructions
288
+ elsif invitable?
289
+ user = self.create_user(:forename => forename, :name => name, :email => email)
290
+ self.save
298
291
  end
299
292
  self.user
300
293
  end
@@ -15,16 +15,6 @@ module Droom
15
15
  :precrop => "1200x1200^"
16
16
  }
17
17
 
18
- searchable do
19
- text :name, :boost => 10, :stored => true
20
- text :body, :stored => true
21
- text :note
22
- end
23
-
24
- def self.highlight_fields
25
- [:name, :body]
26
- end
27
-
28
18
  attr_accessible :name, :body, :image, :description, :scraptype, :note, :created_by, :event, :event_attributes, :document, :document_attributes
29
19
  before_save :get_youtube_thumbnail
30
20
 
@@ -100,9 +90,9 @@ module Droom
100
90
  protected
101
91
 
102
92
  def get_youtube_thumbnail
103
- # youtube id is held in the 'note' column.
93
+ # youtube id is held in the 'body' column.
104
94
  if scraptype == "video" && body?
105
- self.image = URI.parse("http://img.youtube.com/vi/#{body}/0.jpg")
95
+ self.image = URI("http://img.youtube.com/vi/#{body}/0.jpg")
106
96
  end
107
97
  end
108
98
 
@@ -7,6 +7,11 @@ module Droom
7
7
  has_many :preferences, :foreign_key => "created_by_id"
8
8
  accepts_nested_attributes_for :preferences, :allow_destroy => true
9
9
 
10
+ validates :email, :uniqueness => true, :presence => true
11
+ validates_format_of :email, :with => /@/
12
+ validates :name, :presence => true
13
+ # validates :password, :presence => true, :length => { :minimum => 6 }, :confirmation => true, :if => :password_required?
14
+
10
15
  receives_messages# :groups => [:unconfirmed, :personed, :administrative]
11
16
 
12
17
  devise :database_authenticatable,
@@ -18,11 +23,10 @@ module Droom
18
23
  :token_authenticatable,
19
24
  :encryptor => :sha512
20
25
 
21
- before_create :ensure_authentication_token
26
+ before_create :ensure_authentication_token # provided by devise
22
27
 
23
28
  attr_accessor :newly_activated, :update_person_email, :confirm, :remove_person
24
29
 
25
- # validates :password, :length => { :minimum => 6 }, :if => :password_required?
26
30
 
27
31
  scope :unconfirmed, where("confirmed_at IS NULL")
28
32
  scope :administrative, where(:admin => true)
@@ -79,7 +83,6 @@ module Droom
79
83
  end
80
84
 
81
85
  def password_match?
82
- Rails.logger.warn ">>> password_match? '#{password}' == '#{password_confirmation}'"
83
86
  self.errors[:password] << "can't be blank" if password.blank?
84
87
  self.errors[:password_confirmation] << "can't be blank" if password_confirmation.blank?
85
88
  self.errors[:password_confirmation] << "does not match password" if password != password_confirmation
@@ -194,18 +197,39 @@ module Droom
194
197
  # If using `msg`, this defines the variables available in message templates.
195
198
  #
196
199
  def for_email
200
+ self.ensure_confirmation_token!
197
201
  {
198
202
  :informal_name => informal_name,
199
203
  :formal_name => formal_name,
200
204
  :forename => forename,
201
205
  :name => name,
202
206
  :email => email,
203
- :confirmation_url => Droom::Engine.routes.url_helpers.new_user_confirmation_url(self, :confirmation_token => self.confirmation_token, :host => ActionMailer::Base.default_url_options[:host]),
207
+ :confirmation_url => Droom::Engine.routes.url_helpers.welcome_url(:id => self.id, :confirmation_token => self.confirmation_token, :host => ActionMailer::Base.default_url_options[:host]),
204
208
  :sign_in_url => Droom::Engine.routes.url_helpers.new_user_session_path(:host => ActionMailer::Base.default_url_options[:host]),
205
- :password_reset_url => Droom::Engine.routes.url_helpers.new_user_password_path(self, :host => ActionMailer::Base.default_url_options[:host])
209
+ :password_reset_url => Droom::Engine.routes.url_helpers.edit_user_password_url(:reset_password_token => self.reset_password_token, :host => ActionMailer::Base.default_url_options[:host])
210
+ }
211
+ end
212
+
213
+ ## Omniauth package
214
+ #
215
+ # This is returned to the client application in the final stage of oauth authentication, and may be used to create
216
+ # a new local account.
217
+
218
+ def credentials(options={})
219
+ {
220
+ id: id,
221
+ title: title,
222
+ name: name,
223
+ forename: forename,
224
+ email: email,
225
+ admin: admin?,
226
+ image: thumbnail
206
227
  }
207
228
  end
208
229
 
230
+ def thumbnail
231
+ person.image.url(:icon) if person
232
+ end
209
233
 
210
234
  end
211
235
  end
@@ -14,23 +14,6 @@ module Droom
14
14
  before_validation :geocode
15
15
  # reverse_geocoded_by :lat, :lng
16
16
 
17
- searchable do
18
- text :name, :boost => 10, :stored => true
19
- text :description, :stored => true
20
- text :post_line1, :stored => true
21
- text :post_line2, :stored => true
22
- text :post_city, :stored => true
23
- text :post_region, :stored => true
24
- text :post_country, :stored => true
25
- text :post_code, :stored => true
26
- end
27
-
28
- handle_asynchronously :solr_index
29
-
30
- def self.highlight_fields
31
- [:name, :description, :post_line1, :post_line2, :post_city, :post_region, :post_country, :post_code]
32
- end
33
-
34
17
  scope :matching, lambda { |fragment|
35
18
  fragment = "%#{fragment}%"
36
19
  where('droom_venues.name like ?', fragment)
@@ -6,12 +6,15 @@
6
6
  =t :code_unknown
7
7
 
8
8
  %p
9
- This welcome address is not correct. Please check your invitation email and make sure that
9
+ This confirmation url is not correct. Have you already confirmed this account? In that case
10
+ you only need to
11
+ = link_to "sign in.", "/"
12
+ Otherwise, please check your invitation email and make sure that
10
13
  you are typing or pasting the right address. It may be that your email program has broken
11
14
  the address over two lines: in that case please make sure you enter the whole thing without
12
15
  any spaces.
13
16
 
14
17
  %p
15
- If you are seeing this message in error, please contact the site builder on
18
+ If you are seeing this message in error, please contact the chief builder on
16
19
  = mail_to "will@spanner.org"
17
20
  and he will sort it out for you right away.
@@ -0,0 +1,25 @@
1
+ #account
2
+ %h1.pagetitle
3
+ =t :resend_confirmation
4
+
5
+ = form_for(resource, :as => resource_name, :url => confirmation_path(resource_name), :html => { :method => :post }) do |f|
6
+ = devise_error_messages!
7
+
8
+ %p
9
+ Enter the email address you signed up with and we will send you the account confirmation instructions again.
10
+
11
+ %p
12
+ = f.label :email
13
+ %br
14
+ = f.email_field :email, :class => 'login'
15
+ %span.note
16
+ = t :email_note
17
+
18
+ .controls
19
+ .save.button
20
+ %p
21
+ = f.submit t(:send_me_instructions), :class => "submit"
22
+
23
+ %p.note
24
+ If you have already confirmed your account, this won't work but you can
25
+ = link_to "reset your password.", new_password_path(resource_name)
@@ -0,0 +1,32 @@
1
+ - content_for :title do
2
+ = t :welcome
3
+
4
+ #account
5
+ %p
6
+ %strong
7
+ = t :hello_name, :name => resource.informal_name
8
+ = t :welcome_preamble
9
+
10
+ = form_for resource, :url => confirm_password_path, :html => {:class => 'password'} do |f|
11
+ = f.hidden_field :confirmation_token
12
+
13
+ %p
14
+ = f.label :password
15
+ %br
16
+ = f.password_field :password, :autocomplete => "off", :class => 'preferences password required', :required => true, :pattern => ".{6,}"
17
+ %br
18
+ %span.note
19
+ = t :password_requirements
20
+
21
+ %p.confirmation
22
+ = f.label :password_confirmation
23
+ %br
24
+ = f.password_field :password_confirmation, :class => 'preferences password_confirmation required', :required => true, :pattern => ""
25
+
26
+ %p.note.password_notice
27
+
28
+ .controls
29
+ .save.button
30
+ = f.submit t(:continue), :class => "submit"
31
+
32
+
@@ -0,0 +1,9 @@
1
+ - documents = Droom::Document.visible_to(current_user.person).latest(5)
2
+
3
+ %h2.section
4
+ = link_to t(:latest_documents), droom.documents_url
5
+
6
+ - if documents.any?
7
+ = render :partial => "droom/documents/document", :collection => documents, :locals => {:closed => true}
8
+ - else
9
+ = t :no_documents
@@ -2,4 +2,4 @@
2
2
  - if folders.any?
3
3
  %h2.quiet
4
4
  = t :my_folders
5
- = render :partial => "droom/folders/folder", :collection => documents, :locals => {:closed => true}
5
+ = render :partial => "droom/folders/folder", :collection => folders, :locals => {:closed => true}
@@ -0,0 +1,9 @@
1
+ - groups = current_user.person.groups if current_user.person
2
+
3
+ %h2.section
4
+ = link_to t(:your_groups), droom.documents_url
5
+
6
+ - if groups.any?
7
+ = render :partial => "droom/groups/group", :collection => groups, :locals => {:closed => true}
8
+ - else
9
+ = t :no_groups
@@ -4,7 +4,7 @@
4
4
 
5
5
  %div.document.holder
6
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)
7
+ = link_to truncate(document.name, :length => 33), droom.folder_document_url(document.folder, document), :class => cssclasses, :title => t(:click_to_download, :name => document.file_file_name)
8
8
  - if admin?
9
9
  = link_to t(:edit_document), edit_document_url(document), :class => 'admin edit minimal', :remote => true, :data => {:action => "overlay", :type => "html"}
10
10
 
@@ -5,7 +5,7 @@
5
5
 
6
6
  %tr.document.holder{:id => "document_#{document.id}"}
7
7
  %th.name
8
- = link_to truncate(document.name, :length => 24), document_url(document), :class => cssclasses.join(' '), :title => t(:click_to_download, :name => document.file_file_name)
8
+ = link_to truncate(document.name, :length => 24), droom.folder_document_url(document.folder, document), :class => cssclasses.join(' '), :title => t(:click_to_download, :name => document.file_file_name)
9
9
  %td.filename.minor
10
10
  %span.note
11
11
  = truncate(document.file_file_name, :length => 18)
@@ -21,7 +21,6 @@
21
21
  - cssclasses << 'closed' if closed
22
22
  - cssclasses << 'invited' if event.attended_by?(current_person)
23
23
 
24
-
25
24
  - if show_header
26
25
  - header = month_header_for(event.start_date)
27
26
  - if header != @event_header