Add some copyright notices
[gitorious:taladars-gitorious-saltation.git] / app / controllers / projects_controller.rb
1 # encoding: utf-8
2 #--
3 #   Copyright (C) 2010 Marko Peltola <marko@markopeltola.com>
4 #   Copyright (C) 2010 Tero Hänninen <tero.j.hanninen@jyu.fi>
5 #   Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
6 #   Copyright (C) 2007, 2008 Johan Sørensen <johan@johansorensen.com>
7 #   Copyright (C) 2008 David A. Cuadrado <krawek@gmail.com>
8 #   Copyright (C) 2008 Tor Arne Vestbø <tavestbo@trolltech.com>
9 #   Copyright (C) 2008 Cairo Noleto <caironoleto@gmail.com>
10 #   Copyright (C) 2009 Fabio Akita <fabio.akita@gmail.com>
11 #
12 #   This program is free software: you can redistribute it and/or modify
13 #   it under the terms of the GNU Affero General Public License as published by
14 #   the Free Software Foundation, either version 3 of the License, or
15 #   (at your option) any later version.
16 #
17 #   This program is distributed in the hope that it will be useful,
18 #   but WITHOUT ANY WARRANTY; without even the implied warranty of
19 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 #   GNU Affero General Public License for more details.
21 #
22 #   You should have received a copy of the GNU Affero General Public License
23 #   along with this program.  If not, see <http://www.gnu.org/licenses/>.
24 #++
25
26 class ProjectsController < ApplicationController
27   before_filter :login_required,
28     :only => [:create, :update, :destroy, :new, :edit, :confirm_delete]
29   before_filter :check_if_only_site_admins_can_create, :only => [:new, :create]
30   before_filter :find_project,
31     :only => [:show, :clones, :edit, :update, :preview, :confirm_delete, :edit_slug]
32   before_filter :assure_adminship, :only => [:edit, :update, :edit_slug]
33   before_filter :require_view_right_to_project, 
34                 :except => [:new, :create, :index, :destroy]
35   before_filter :require_user_has_ssh_keys, :only => [:new, :create]
36   renders_in_site_specific_context :only => [:show, :edit, :update, :confirm_delete]
37   renders_in_global_context :except => [:show, :edit, :update, :confirm_delete, :clones]
38
39   def index
40     @projects = Project.visibility_publics_or_all(logged_in?).paginate(:all, :order => "projects.created_at desc",
41                   :page => params[:page], :include => [:tags, { :repositories => :project } ])
42
43     @atom_auto_discovery_url = projects_path(:format => :atom)
44     respond_to do |format|
45       format.html {
46         @active_recently = Project.most_active_recently(logged_in?)
47         @tags = Project.top_tags
48       }
49       format.xml  { render :xml => @projects }
50       format.atom { }
51     end
52   end
53
54   def category
55     tags = params[:id].to_s.gsub(/,\ ?/, " ")
56     @projects = Project.paginate_by_tag(tags, :order => 'created_at desc',
57                   :page => params[:page])
58     @atom_auto_discovery_url = projects_category_path(params[:id], :format => :atom)
59     respond_to do |format|
60       format.html do
61         @tags = Project.tag_counts
62         render :action => "index"
63       end
64       format.xml  { render :xml => @projects }
65       format.atom { render :action => "index"}
66     end
67   end
68
69   def show
70     @owner = @project
71     @root = @project
72     @repositories = @project.repositories_viewable_by(current_user)
73     @events = Rails.cache.fetch("paginated-project-events:#{@project.id}:#{params[:page] || 1}", :expires_in => 10.minutes) do
74       events_finder_options = {}
75       events_finder_options.merge!(@project.events.top.proxy_options)
76       events_finder_options.merge!({:per_page => Event.per_page, :page => params[:page]})
77       (@project.events.delete_if { |e| !e.can_be_viewed_by?(current_user) }).paginate(events_finder_options)
78     end
79     @group_clones = @project.recently_updated_group_repository_clones(current_user)
80     @user_clones = @project.recently_updated_user_repository_clones(current_user)
81     @atom_auto_discovery_url = project_path(@project, :format => :atom)
82     respond_to do |format|
83       format.html
84       format.xml  { render :xml => @project }
85       format.atom { }
86     end
87   end
88
89   def clones
90     @owner = @project
91     @group_clones = @project.repositories.by_groups.delete_if { |r| !r.can_be_viewed_by?(current_user) }
92     @user_clones = @project.repositories.by_users.delete_if { |r| !r.can_be_viewed_by?(current_user) }
93     respond_to do |format|
94       format.js { render :partial => "repositories" }
95     end
96   end
97
98   def new
99     @project = Project.new
100     @project.owner = current_user
101     @root = Breadcrumb::NewProject.new
102   end
103
104   def create
105     @project = Project.new(params[:project])
106     @root = Breadcrumb::NewProject.new
107     @project.user = current_user
108     @project.owner = case params[:project][:owner_type]
109       when "User"
110         current_user
111       when "Group"
112         current_user.groups.find(params[:project][:owner_id])
113       end
114
115     if @project.save
116       @project.create_event(Action::CREATE_PROJECT, @project, current_user)
117       redirect_to new_project_repository_path(@project)
118     else
119       render :action => 'new'
120     end
121   end
122
123   def edit
124     @groups = current_user.groups.select{|g| g.admin?(current_user) }
125     @root = Breadcrumb::EditProject.new(@project)
126   end
127
128   def edit_slug
129     @root = Breadcrumb::EditProject.new(@project)
130     if request.put?
131       @project.slug = params[:project][:slug]
132       if @project.save
133         @project.create_event(Action::UPDATE_PROJECT, @project, current_user)
134         flash[:success] = "Project slug updated"
135         redirect_to :action => :show, :id => @project.slug and return
136       end
137     end
138   end
139
140   def update
141     @groups = current_user.groups.select{|g| g.admin?(current_user) }
142     @root = Breadcrumb::EditProject.new(@project)
143
144     # change group, if requested
145     unless params[:project][:owner_id].blank?
146       @project.change_owner_to(current_user.groups.find(params[:project][:owner_id]))
147     end
148
149     @project.attributes = params[:project]
150     changed = @project.changed? # Dirty attr tracking is cleared after #save
151     if @project.save && @project.wiki_repository.save
152       @project.create_event(Action::UPDATE_PROJECT, @project, current_user) if changed
153       flash[:success] = "Project details updated"
154       redirect_to project_path(@project)
155     else
156       render :action => 'edit'
157     end
158   end
159
160   def preview
161     @project = Project.new
162     @project.description = params[:project][:description]
163     respond_to do |wants|
164       wants.js
165     end
166   end
167
168   def confirm_delete
169     @project = Project.find_by_slug!(params[:id])
170   end
171
172   def destroy
173     @project = Project.find_by_slug!(params[:id])
174     if @project.can_be_deleted_by?(current_user)
175       project_title = @project.title
176       @project.destroy
177 #       Event.create(:action => Action::DELETE_PROJECT, :user => current_user, :data => project_title) # FIXME: project_id cannot be null
178     else
179       flash[:error] = I18n.t "projects_controller.destroy_error"
180     end
181     redirect_to projects_path
182   end
183
184   protected
185     def find_project
186       @project = Project.find_by_slug!(params[:id], :include => [:repositories])
187     end
188
189     def assure_adminship
190       if !@project.admin?(current_user)
191         flash[:error] = I18n.t "projects_controller.update_error"
192         redirect_to(project_path(@project)) and return
193       end
194     end
195
196     def check_if_only_site_admins_can_create
197       if GitoriousConfig["only_site_admins_can_create_projects"]
198         unless current_user.site_admin?
199           flash[:error] = I18n.t("projects_controller.create_only_for_site_admins")
200           redirect_to projects_path
201           return false
202         end
203       end
204     end
205 end