From a6dfd065ca9de2e421425a5126c68bf8949ce110 Mon Sep 17 00:00:00 2001
From: Douwe Maan <douwe@gitlab.com>
Date: Tue, 21 Apr 2015 16:57:01 +0200
Subject: [PATCH] Add atom feed for project activity.

---
 app/controllers/projects_controller.rb | 18 +++++++++++++-----
 app/views/projects/show.atom.builder   | 12 ++++++++++++
 app/views/projects/show.html.haml      | 12 ++++++++++++
 config/routes.rb                       |  6 +++---
 4 files changed, 40 insertions(+), 8 deletions(-)
 create mode 100644 app/views/projects/show.atom.builder

diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 1422f2b8a4c..883e5865a21 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -66,8 +66,6 @@ class ProjectsController < ApplicationController
       return
     end
 
-    limit = (params[:limit] || 20).to_i
-
     @show_star = !(current_user && current_user.starred?(@project))
 
     respond_to do |format|
@@ -85,11 +83,14 @@ class ProjectsController < ApplicationController
       end
 
       format.json do
-        @events = @project.events.recent
-        @events = event_filter.apply_filter(@events).with_associations
-        @events = @events.limit(limit).offset(params[:offset] || 0)
+        load_events
         pager_json('events/_events', @events.count)
       end
+
+      format.atom do
+        load_events
+        render layout: false
+      end
     end
   end
 
@@ -167,6 +168,13 @@ class ProjectsController < ApplicationController
     current_user ? 'projects' : 'public_projects'
   end
 
+  def load_events
+    @events = @project.events.recent
+    @events = event_filter.apply_filter(@events).with_associations
+    limit = (params[:limit] || 20).to_i
+    @events = @events.limit(limit).offset(params[:offset] || 0)
+  end
+
   def project_params
     params.require(:project).permit(
       :name, :path, :description, :issues_tracker, :tag_list,
diff --git a/app/views/projects/show.atom.builder b/app/views/projects/show.atom.builder
new file mode 100644
index 00000000000..c2d909d7ebd
--- /dev/null
+++ b/app/views/projects/show.atom.builder
@@ -0,0 +1,12 @@
+xml.instruct!
+xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
+  xml.title   "Project feed - #{@project.name}"
+  xml.link    href: namespace_project_path(@project.namespace, @project, :atom), rel: "self", type: "application/atom+xml"
+  xml.link    href: namespace_project_path(@project.namespace, @project), rel: "alternate", type: "text/html"
+  xml.id      projects_url
+  xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any?
+
+  @events.each do |event|
+    event_to_atom(xml, event)
+  end
+end
diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml
index 864bda359b6..e9d4fdc96e1 100644
--- a/app/views/projects/show.html.haml
+++ b/app/views/projects/show.html.haml
@@ -1,3 +1,7 @@
+= content_for :meta_tags do
+  - if current_user
+    = auto_discovery_link_tag(:atom, namespace_project_path(@project.namespace, @project, format: :atom, private_token: current_user.private_token), title: "#{@group.name} activity")
+
 - if current_user && can?(current_user, :download_code, @project)
   = render 'shared/no_ssh'
   = render 'shared/no_password'
@@ -39,6 +43,14 @@
         %i.fa.fa-angle-left
       %section.col-md-9
         = render "events/event_last_push", event: @last_push
+
+        - if current_user
+          %ul.nav.nav-pills.event_filter.pull-right
+            %li
+              = link_to namespace_project_path(@project.namespace, @project, format: :atom, private_token: current_user.private_token), title: "Feed", class: 'rss-btn' do
+                %i.fa.fa-rss
+                News Feed
+
         = render 'shared/event_filter'
         %hr
         .content_list
diff --git a/config/routes.rb b/config/routes.rb
index 86939a1d7ea..e059f5830f5 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -236,7 +236,7 @@ Gitlab::Application.routes.draw do
       constraints: { username: /.*/ }
 
   get '/u/:username' => 'users#show', as: :user,
-      constraints: { username: /(?:[^.]|\.(?!atom$))+/, format: /atom/ }
+      constraints: { username: /[a-zA-Z.0-9_\-]+(?<!\.atom)/ }
 
   #
   # Dashboard Area
@@ -263,7 +263,7 @@ Gitlab::Application.routes.draw do
   #
   # Groups Area
   #
-  resources :groups, constraints: { id: /(?:[^.]|\.(?!atom$))+/, format: /atom/ }  do
+  resources :groups, constraints: { id: /[a-zA-Z.0-9_\-]+(?<!\.atom)/ }  do
     member do
       get :issues
       get :merge_requests
@@ -295,7 +295,7 @@ Gitlab::Application.routes.draw do
   # Project Area
   #
   resources :namespaces, path: '/', constraints: { id: /[a-zA-Z.0-9_\-]+/ }, only: [] do
-    resources(:projects, constraints: { id: /[a-zA-Z.0-9_\-]+/ }, except:
+    resources(:projects, constraints: { id: /[a-zA-Z.0-9_\-]+(?<!\.atom)/ }, except:
               [:new, :create, :index], path: "/") do
       member do
         put :transfer
-- 
GitLab