# Redmine - project management software # Copyright (C) 2006-2013 Jean-Philippe Lang # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. class WatchersController < ApplicationController before_filter :require_login#, :find_watchables, :only => [:watch, :unwatch] helper :users def watch s = WatchesService.new watchables = s.watch params.merge(:current_user_id => User.current.id) if params[:action_name] == 'watch' limit = 10; query = User.watched_by(params[:target_id]); @obj_count = query.count(); @obj_pages = Paginator.new @obj_count,limit,params['page'] @list = query.order("#{Watcher.table_name}.id desc").limit(limit).offset(@obj_pages.offset).all(); @action = 'watch' elsif params[:action_name] == 'fans' limit = 10; query = User.find(params[:target_id]).watcher_users; @obj_count = query.count(); @obj_pages = Paginator.new @obj_count,limit,params['page'] @list = query.order("#{Watcher.table_name}.id desc").limit(limit).offset(@obj_pages.offset).all(); @action = 'fans' else end if params[:object_type] == 'project' @project = Project.find(params[:object_id]) respond_to do |format| format.js end else respond_to do |format| format.html { redirect_to_referer_or {render :text => (true ? 'Watcher added.' : 'Watcher removed.'), :layout => true}} format.js { render :partial => 'set_watcher', :locals => {:user => User.current, :watched => watchables,:params=>params,:opt=>'add',:list => @list,:action_name=>params[:action_name],:page=>params[:page],:count=>@obj_count} } end end rescue Exception => e if e.message == "404" render_404 else raise e end #set_watcher(@watchables, User.current, true) end def unwatch s = WatchesService.new watchables = s.unwatch params.merge(:current_user_id => User.current.id) if params[:action_name] == 'watch' limit = 10; query = User.watched_by(params[:target_id]); @obj_count = query.count(); @obj_pages = Paginator.new @obj_count,limit,params['page'] @list = query.order("#{Watcher.table_name}.id desc").limit(limit).offset(@obj_pages.offset).all(); @action = 'watch' elsif params[:action_name] == 'fans' limit = 10; query = User.find(params[:target_id]).watcher_users; @obj_count = query.count(); @obj_pages = Paginator.new @obj_count,limit,params['page'] @list = query.order("#{Watcher.table_name}.id desc").limit(limit).offset(@obj_pages.offset).all(); @action = 'fans' else end if params[:object_type] == 'project' @project = Project.find(params[:object_id]) respond_to do |format| format.js end else respond_to do |format| format.html { redirect_to_referer_or {render :text => (false ? 'Watcher added.' : 'Watcher removed.'), :layout => true}} format.js { render :partial => 'set_watcher', :locals => {:user => User.current, :watched => watchables,:params=>params,:opt=>'delete',:list=>@list,:action_name=>params[:action_name],:page=>params[:page],:count=>@obj_count} } end end rescue Exception => e if e.message == "404" render_404 else raise e end #set_watcher(@watchables, User.current, false) end def join if User.current.logged? course = Project.find(params[:object_id]) if params[:course_password] == '123' members = [] members << Member.new(:role_ids => [5], :user_id => User.current.id) course.members << members StudentsForCourse.create(:student_id => User.current.id, :course_id => params[:object_id]) else end end respond_to do |format| # format.html { redirect_to_referer_or {render :text => (watching ? 'Watcher added.' : 'Watcher removed.'), :layout => true}} format.js { render :partial => 'set_join', :locals => {:user => User.current, :course => Project.find(params[:object_id])} } end end def unjoin if User.current.logged? @member = Member.where('project_id = ? and user_id = ?', params[:object_id], User.current.id) @member.first.destroy joined = StudentsForCourse.where('student_id = ? and course_id = ?', User.current.id, params[:object_id]) joined.each do |join| join.delete end end respond_to do |format| # format.html { redirect_to_referer_or {render :text => (watching ? 'Watcher added.' : 'Watcher removed.'), :layout => true}} format.js { render :partial => 'set_join', :locals => {:user => User.current, :course => Project.find(params[:object_id])} } end end before_filter :find_project, :authorize, :only => [:new, :create, :append, :destroy, :autocomplete_for_user] accept_api_auth :create, :destroy def new end def create user_ids = [] if params[:watcher].is_a?(Hash) user_ids << (params[:watcher][:user_ids] || params[:watcher][:user_id]) else user_ids << params[:user_id] end user_ids.flatten.compact.uniq.each do |user_id| Watcher.create(:watchable => @watched, :user_id => user_id) end respond_to do |format| format.html { redirect_to_referer_or {render :text => 'Watcher added.', :layout => true}} format.js format.api { render_api_ok } end end def append if params[:watcher].is_a?(Hash) user_ids = params[:watcher][:user_ids] || [params[:watcher][:user_id]] @users = User.active.find_all_by_id(user_ids) end end def destroy @watched.set_watcher(User.find(params[:user_id]), false) respond_to do |format| format.html { redirect_to :back } format.js format.api { render_api_ok } end end def autocomplete_for_user @users = User.active.sorted.like(params[:q]).limit(100).all if @watched @users -= @watched.watcher_users end render :layout => false end private def find_project if params[:object_type] && params[:object_id] klass = Object.const_get(params[:object_type].camelcase) return false unless klass.respond_to?('watched_by') @watched = klass.find(params[:object_id]) @project = @watched.project elsif params[:project_id] @project = Project.visible.find_by_param(params[:project_id]) end rescue render_404 end def find_watchables #根据参数获取关注对象的类型(user、project) klass = Object.const_get(params[:object_type].camelcase) rescue nil #判断获取的对象类型能否响应‘watched_by’方法 if klass && klass.respond_to?('watched_by') @watchables = klass.find_all_by_id(Array.wrap(params[:object_id])) raise Unauthorized if @watchables.any? {|w| w.respond_to?(:visible?) && !w.visible?} end render_404 unless @watchables.present? end def set_watcher(watchables, user, watching) watchables.each do |watchable| watchable.set_watcher(user, watching) # @user = watchable # added by william if watching # 修改 user和project的状态 if watchable.instance_of?(User) #写user_statuses表 UserStatus.find_by_user_id(watchable.id).update_watchers_count(1) elsif watchable.instance_of?(Project) #写project_statuese表 ProjectStatus.find_by_project_id(watchable.id).update_watchers_count(1) end else # 修改 user和project的状态 if watchable.instance_of?(User) #写user_statuses表 UserStatus.find_by_user_id(watchable.id).update_watchers_count(-1) elsif watchable.instance_of?(Project) #写project_statuese表 :project_status ProjectStatus.find_by_project_id(watchable.id).update_watchers_count(-1) end end end respond_to do |format| format.html { redirect_to_referer_or {render :text => (watching ? 'Watcher added.' : 'Watcher removed.'), :layout => true}} format.js { render :partial => 'set_watcher', :locals => {:user => user, :watched => watchables} } end end end