Add /api/0.6/users to fetch multiple users
[rails.git] / app / controllers / diary_entry_controller.rb
1 class DiaryEntryController < ApplicationController
2   layout "site", :except => :rss
3
4   before_action :authorize_web
5   before_action :set_locale
6   before_action :require_user, :only => [:new, :edit, :comment, :hide, :hidecomment, :subscribe, :unsubscribe]
7   before_action :lookup_user, :only => [:view, :comments]
8   before_action :check_database_readable
9   before_action :check_database_writable, :only => [:new, :edit, :comment, :hide, :hidecomment, :subscribe, :unsubscribe]
10   before_action :require_administrator, :only => [:hide, :hidecomment]
11   before_action :allow_thirdparty_images, :only => [:new, :edit, :list, :view, :comments]
12
13   def new
14     @title = t "diary_entry.new.title"
15
16     if request.post?
17       @diary_entry = DiaryEntry.new(entry_params)
18       @diary_entry.user = current_user
19
20       if @diary_entry.save
21         default_lang = current_user.preferences.where(:k => "diary.default_language").first
22         if default_lang
23           default_lang.v = @diary_entry.language_code
24           default_lang.save!
25         else
26           current_user.preferences.create(:k => "diary.default_language", :v => @diary_entry.language_code)
27         end
28
29         # Subscribe user to diary comments
30         @diary_entry.subscriptions.create(:user => current_user)
31
32         redirect_to :action => "list", :display_name => current_user.display_name
33       else
34         render :action => "edit"
35       end
36     else
37       default_lang = current_user.preferences.where(:k => "diary.default_language").first
38       lang_code = default_lang ? default_lang.v : current_user.preferred_language
39       @diary_entry = DiaryEntry.new(entry_params.merge(:language_code => lang_code))
40       set_map_location
41       render :action => "edit"
42     end
43   end
44
45   def edit
46     @title = t "diary_entry.edit.title"
47     @diary_entry = DiaryEntry.find(params[:id])
48
49     if current_user != @diary_entry.user
50       redirect_to :action => "view", :id => params[:id]
51     elsif params[:diary_entry] && @diary_entry.update(entry_params)
52       redirect_to :action => "view", :id => params[:id]
53     end
54
55     set_map_location
56   rescue ActiveRecord::RecordNotFound
57     render :action => "no_such_entry", :status => :not_found
58   end
59
60   def comment
61     @entry = DiaryEntry.find(params[:id])
62     @diary_comment = @entry.comments.build(comment_params)
63     @diary_comment.user = current_user
64     if @diary_comment.save
65
66       # Notify current subscribers of the new comment
67       @entry.subscribers.visible.each do |user|
68         Notifier.diary_comment_notification(@diary_comment, user).deliver_now if current_user != user
69       end
70
71       # Add the commenter to the subscribers if necessary
72       @entry.subscriptions.create(:user => current_user) unless @entry.subscribers.exists?(current_user.id)
73
74       redirect_to :action => "view", :display_name => @entry.user.display_name, :id => @entry.id
75     else
76       render :action => "view"
77     end
78   rescue ActiveRecord::RecordNotFound
79     render :action => "no_such_entry", :status => :not_found
80   end
81
82   def subscribe
83     diary_entry = DiaryEntry.find(params[:id])
84
85     diary_entry.subscriptions.create(:user => current_user) unless diary_entry.subscribers.exists?(current_user.id)
86
87     redirect_to :action => "view", :display_name => diary_entry.user.display_name, :id => diary_entry.id
88   rescue ActiveRecord::RecordNotFound
89     render :action => "no_such_entry", :status => :not_found
90   end
91
92   def unsubscribe
93     diary_entry = DiaryEntry.find(params[:id])
94
95     diary_entry.subscriptions.where(:user => current_user).delete_all if diary_entry.subscribers.exists?(current_user.id)
96
97     redirect_to :action => "view", :display_name => diary_entry.user.display_name, :id => diary_entry.id
98   rescue ActiveRecord::RecordNotFound
99     render :action => "no_such_entry", :status => :not_found
100   end
101
102   def list
103     if params[:display_name]
104       @user = User.active.find_by(:display_name => params[:display_name])
105
106       if @user
107         @title = t "diary_entry.list.user_title", :user => @user.display_name
108         @entries = @user.diary_entries
109       else
110         render_unknown_user params[:display_name]
111         return
112       end
113     elsif params[:friends]
114       if current_user
115         @title = t "diary_entry.list.title_friends"
116         @entries = DiaryEntry.where(:user_id => current_user.friend_users)
117       else
118         require_user
119         return
120       end
121     elsif params[:nearby]
122       if current_user
123         @title = t "diary_entry.list.title_nearby"
124         @entries = DiaryEntry.where(:user_id => current_user.nearby)
125       else
126         require_user
127         return
128       end
129     else
130       @entries = DiaryEntry.joins(:user).where(:users => { :status => %w[active confirmed] })
131
132       if params[:language]
133         @title = t "diary_entry.list.in_language_title", :language => Language.find(params[:language]).english_name
134         @entries = @entries.where(:language_code => params[:language])
135       else
136         @title = t "diary_entry.list.title"
137       end
138     end
139
140     @params = params.permit(:display_name, :friends, :nearby, :language)
141
142     @page = (params[:page] || 1).to_i
143     @page_size = 20
144
145     @entries = @entries.visible
146     @entries = @entries.order("created_at DESC")
147     @entries = @entries.offset((@page - 1) * @page_size)
148     @entries = @entries.limit(@page_size)
149     @entries = @entries.includes(:user, :language)
150   end
151
152   def rss
153     if params[:display_name]
154       user = User.active.find_by(:display_name => params[:display_name])
155
156       if user
157         @entries = user.diary_entries
158         @title = t("diary_entry.feed.user.title", :user => user.display_name)
159         @description = t("diary_entry.feed.user.description", :user => user.display_name)
160         @link = url_for :controller => "diary_entry", :action => "list", :display_name => user.display_name, :host => SERVER_URL, :protocol => SERVER_PROTOCOL
161       else
162         head :not_found
163         return
164       end
165     else
166       @entries = DiaryEntry.joins(:user).where(:users => { :status => %w[active confirmed] })
167
168       if params[:language]
169         @entries = @entries.where(:language_code => params[:language])
170         @title = t("diary_entry.feed.language.title", :language_name => Language.find(params[:language]).english_name)
171         @description = t("diary_entry.feed.language.description", :language_name => Language.find(params[:language]).english_name)
172         @link = url_for :controller => "diary_entry", :action => "list", :language => params[:language], :host => SERVER_URL, :protocol => SERVER_PROTOCOL
173       else
174         @title = t("diary_entry.feed.all.title")
175         @description = t("diary_entry.feed.all.description")
176         @link = url_for :controller => "diary_entry", :action => "list", :host => SERVER_URL, :protocol => SERVER_PROTOCOL
177       end
178     end
179
180     @entries = @entries.visible.includes(:user).order("created_at DESC").limit(20)
181   end
182
183   def view
184     @entry = @user.diary_entries.visible.where(:id => params[:id]).first
185     if @entry
186       @title = t "diary_entry.view.title", :user => params[:display_name], :title => @entry.title
187     else
188       @title = t "diary_entry.no_such_entry.title", :id => params[:id]
189       render :action => "no_such_entry", :status => :not_found
190     end
191   end
192
193   def hide
194     entry = DiaryEntry.find(params[:id])
195     entry.update(:visible => false)
196     redirect_to :action => "list", :display_name => entry.user.display_name
197   end
198
199   def hidecomment
200     comment = DiaryComment.find(params[:comment])
201     comment.update(:visible => false)
202     redirect_to :action => "view", :display_name => comment.diary_entry.user.display_name, :id => comment.diary_entry.id
203   end
204
205   def comments
206     @comment_pages, @comments = paginate(:diary_comments,
207                                          :conditions => {
208                                            :user_id => @user,
209                                            :visible => true
210                                          },
211                                          :order => "created_at DESC",
212                                          :per_page => 20)
213     @page = (params[:page] || 1).to_i
214   end
215
216   private
217
218   ##
219   # return permitted diary entry parameters
220   def entry_params
221     params.require(:diary_entry).permit(:title, :body, :language_code, :latitude, :longitude)
222   rescue ActionController::ParameterMissing
223     ActionController::Parameters.new.permit(:title, :body, :language_code, :latitude, :longitude)
224   end
225
226   ##
227   # return permitted diary comment parameters
228   def comment_params
229     params.require(:diary_comment).permit(:body)
230   end
231
232   ##
233   # require that the user is a administrator, or fill out a helpful error message
234   # and return them to the user page.
235   def require_administrator
236     unless current_user.administrator?
237       flash[:error] = t("user.filter.not_an_administrator")
238       redirect_to :action => "view"
239     end
240   end
241
242   ##
243   # decide on a location for the diary entry map
244   def set_map_location
245     if @diary_entry.latitude && @diary_entry.longitude
246       @lon = @diary_entry.longitude
247       @lat = @diary_entry.latitude
248       @zoom = 12
249     elsif current_user.home_lat.nil? || current_user.home_lon.nil?
250       @lon = params[:lon] || -0.1
251       @lat = params[:lat] || 51.5
252       @zoom = params[:zoom] || 4
253     else
254       @lon = current_user.home_lon
255       @lat = current_user.home_lat
256       @zoom = 12
257     end
258   end
259 end