Commit b0ed2ff1 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'atom-feeds-everywhere' into 'master'

Add project activity atom feed and show atom feed buttons everywhere where applicable.

See merge request !555
parents 160799ca a12d50c5
...@@ -10,6 +10,8 @@ v 7.11.0 (unreleased) ...@@ -10,6 +10,8 @@ v 7.11.0 (unreleased)
- Fix bug causing `@whatever` inside an issue's first code block to be picked up as a user mention. - Fix bug causing `@whatever` inside an issue's first code block to be picked up as a user mention.
- Fix bug causing `@whatever` inside an inline code snippet (backtick-style) to be picked up as a user mention. - Fix bug causing `@whatever` inside an inline code snippet (backtick-style) to be picked up as a user mention.
- -
- Show Atom feed buttons everywhere where applicable.
- Add project activity atom feed.
- -
- -
- -
......
...@@ -66,8 +66,6 @@ class ProjectsController < ApplicationController ...@@ -66,8 +66,6 @@ class ProjectsController < ApplicationController
return return
end end
limit = (params[:limit] || 20).to_i
@show_star = !(current_user && current_user.starred?(@project)) @show_star = !(current_user && current_user.starred?(@project))
respond_to do |format| respond_to do |format|
...@@ -85,11 +83,14 @@ class ProjectsController < ApplicationController ...@@ -85,11 +83,14 @@ class ProjectsController < ApplicationController
end end
format.json do format.json do
@events = @project.events.recent load_events
@events = event_filter.apply_filter(@events).with_associations
@events = @events.limit(limit).offset(params[:offset] || 0)
pager_json('events/_events', @events.count) pager_json('events/_events', @events.count)
end end
format.atom do
load_events
render layout: false
end
end end
end end
...@@ -167,6 +168,13 @@ class ProjectsController < ApplicationController ...@@ -167,6 +168,13 @@ class ProjectsController < ApplicationController
current_user ? 'projects' : 'public_projects' current_user ? 'projects' : 'public_projects'
end 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 def project_params
params.require(:project).permit( params.require(:project).permit(
:name, :path, :description, :issues_tracker, :tag_list, :name, :path, :description, :issues_tracker, :tag_list,
......
= render "events/event_last_push", event: @last_push = render "events/event_last_push", event: @last_push
- if current_user
%ul.nav.nav-pills.event_filter.pull-right
%li.pull-right
= link_to dashboard_path(:atom, { private_token: current_user.private_token }), class: 'rss-btn' do
%i.fa.fa-rss
Activity Feed
= render 'shared/event_filter' = render 'shared/event_filter'
%hr
.content_list .content_list
= spinner = spinner
xml.instruct! xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
xml.title "#{current_user.name} issues" xml.title "#{current_user.name} issues"
xml.link href: issues_dashboard_url(:atom, private_token: current_user.private_token), rel: "self", type: "application/atom+xml" xml.link href: issues_dashboard_url(format: :atom, private_token: current_user.private_token), rel: "self", type: "application/atom+xml"
xml.link href: issues_dashboard_url(private_token: current_user.private_token), rel: "alternate", type: "text/html" xml.link href: issues_dashboard_url, rel: "alternate", type: "text/html"
xml.id issues_dashboard_url(private_token: current_user.private_token) xml.id issues_dashboard_url
xml.updated @issues.first.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") if @issues.any? xml.updated @issues.first.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") if @issues.any?
@issues.each do |issue| @issues.each do |issue|
......
= content_for :meta_tags do
- if current_user
= auto_discovery_link_tag(:atom, issues_dashboard_url(format: :atom, private_token: current_user.private_token), title: "#{current_user.name} issues")
%h3.page-title %h3.page-title
Issues Issues
...@@ -6,5 +10,11 @@ ...@@ -6,5 +10,11 @@
%hr %hr
.append-bottom-20 .append-bottom-20
.pull-right
- if current_user
.hidden-xs.pull-left
= link_to issues_dashboard_url(format: :atom, private_token: current_user.private_token), class: 'btn' do
%i.fa.fa-rss
= render 'shared/issuable_filter' = render 'shared/issuable_filter'
= render 'shared/issues' = render 'shared/issues'
xml.instruct! xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
xml.title "Dashboard feed#{" - #{current_user.name}" if current_user.name.present?}" xml.title "Activity"
xml.link href: dashboard_url(:atom), rel: "self", type: "application/atom+xml" xml.link href: dashboard_url(format: :atom, private_token: current_user.private_token), rel: "self", type: "application/atom+xml"
xml.link href: dashboard_url, rel: "alternate", type: "text/html" xml.link href: dashboard_url, rel: "alternate", type: "text/html"
xml.id projects_url xml.id dashboard_url
xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any? xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any?
@events.each do |event| @events.each do |event|
......
= content_for :meta_tags do
- if current_user
= auto_discovery_link_tag(:atom, dashboard_url(format: :atom, private_token: current_user.private_token), title: "All activity")
- if @projects.any? - if @projects.any?
.dashboard.row .dashboard.row
%section.activities.col-md-8 %section.activities.col-md-8
......
xml.instruct! xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
xml.title "#{@user.name} issues" xml.title "#{@user.name} issues"
xml.link :href => issues_dashboard_url(:atom, :private_token => @user.private_token), :rel => "self", :type => "application/atom+xml" xml.link href: issues_dashboard_url(format: :atom, private_token: @user.private_token), rel: "self", type: "application/atom+xml"
xml.link :href => issues_dashboard_url(:private_token => @user.private_token), :rel => "alternate", :type => "text/html" xml.link href: issues_dashboard_url, rel: "alternate", type: "text/html"
xml.id issues_dashboard_url(:private_token => @user.private_token) xml.id issues_dashboard_url
xml.updated @issues.first.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") if @issues.any? xml.updated @issues.first.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") if @issues.any?
@issues.each do |issue| @issues.each do |issue|
......
= content_for :meta_tags do
- if current_user
= auto_discovery_link_tag(:atom, issues_group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} issues")
%h3.page-title %h3.page-title
Issues Issues
...@@ -10,5 +14,11 @@ ...@@ -10,5 +14,11 @@
%hr %hr
.append-bottom-20 .append-bottom-20
.pull-right
- if current_user
.hidden-xs.pull-left
= link_to issues_group_url(@group, format: :atom, private_token: current_user.private_token), class: 'btn' do
%i.fa.fa-rss
= render 'shared/issuable_filter' = render 'shared/issuable_filter'
= render 'shared/issues' = render 'shared/issues'
xml.instruct! xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
xml.title "Group feed - #{@group.name}" xml.title "#{@group.name} activity"
xml.link href: group_path(@group, :atom), rel: "self", type: "application/atom+xml" xml.link href: group_url(@group, format: :atom, private_token: current_user.private_token), rel: "self", type: "application/atom+xml"
xml.link href: group_path(@group), rel: "alternate", type: "text/html" xml.link href: group_url(@group), rel: "alternate", type: "text/html"
xml.id projects_url xml.id group_url(@group)
xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any? xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any?
@events.each do |event| @events.each do |event|
......
= content_for :meta_tags do
- if current_user
= auto_discovery_link_tag(:atom, group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} activity")
.dashboard .dashboard
.header-with-avatar.clearfix .header-with-avatar.clearfix
= image_tag group_icon(@group), class: "avatar group-avatar s90" = image_tag group_icon(@group), class: "avatar group-avatar s90"
...@@ -13,7 +17,17 @@ ...@@ -13,7 +17,17 @@
%section.activities.col-md-8 %section.activities.col-md-8
- if current_user - if current_user
= render "events/event_last_push", event: @last_push = render "events/event_last_push", event: @last_push
- if current_user
%ul.nav.nav-pills.event_filter.pull-right
%li
= link_to group_path(@group, { format: :atom, private_token: current_user.private_token }), title: "Feed", class: 'rss-btn' do
%i.fa.fa-rss
Activity Feed
= render 'shared/event_filter' = render 'shared/event_filter'
%hr
.content_list .content_list
= spinner = spinner
%aside.side.col-md-4 %aside.side.col-md-4
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
%title %title
= "#{title} | " if defined?(title) = "#{title} | " if defined?(title)
GitLab GitLab
= favicon_link_tag 'favicon.ico' = favicon_link_tag 'favicon.ico'
= stylesheet_link_tag "application", :media => "all" = stylesheet_link_tag "application", :media => "all"
= stylesheet_link_tag "print", :media => "print" = stylesheet_link_tag "print", :media => "print"
...@@ -14,16 +15,8 @@ ...@@ -14,16 +15,8 @@
%meta{name: 'viewport', content: 'width=device-width, initial-scale=1, maximum-scale=1'} %meta{name: 'viewport', content: 'width=device-width, initial-scale=1, maximum-scale=1'}
%meta{name: 'theme-color', content: '#474D57'} %meta{name: 'theme-color', content: '#474D57'}
= yield(:meta_tags)
= render 'layouts/google_analytics' if extra_config.has_key?('google_analytics_id') = render 'layouts/google_analytics' if extra_config.has_key?('google_analytics_id')
= render 'layouts/piwik' if extra_config.has_key?('piwik_url') && extra_config.has_key?('piwik_site_id') = render 'layouts/piwik' if extra_config.has_key?('piwik_url') && extra_config.has_key?('piwik_site_id')
= render 'layouts/bootlint' if Rails.env.development? = render 'layouts/bootlint' if Rails.env.development?
-# Atom feed
- if current_user
- if controller_name == 'projects' && action_name == 'index'
= auto_discovery_link_tag :atom, projects_url(:atom, private_token: current_user.private_token), title: "Dashboard feed"
- if @project && !@project.new_record?
- if current_controller?(:tree, :commits)
= auto_discovery_link_tag(:atom, namespace_project_commits_url(@project.namespace, @project, @ref, format: :atom, private_token: current_user.private_token), title: "Recent commits to #{@project.name}:#{@ref}")
- if current_controller?(:issues)
= auto_discovery_link_tag(:atom, namespace_project_issues_url(@project.namespace, @project, :atom, private_token: current_user.private_token), title: "#{@project.name} issues")
xml.instruct! xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
xml.title "Recent commits to #{@project.name}:#{@ref}" xml.title "#{@project.name}:#{@ref} commits"
xml.link :href => namespace_project_commits_url(@project.namespace, @project, @ref, format: :atom), :rel => "self", :type => "application/atom+xml" xml.link href: namespace_project_commits_url(@project.namespace, @project, @ref, format: :atom, private_token: current_user.private_token), rel: "self", type: "application/atom+xml"
xml.link :href => namespace_project_commits_url(@project.namespace, @project, @ref), :rel => "alternate", :type => "text/html" xml.link href: namespace_project_commits_url(@project.namespace, @project, @ref), rel: "alternate", type: "text/html"
xml.id namespace_project_commits_url(@project.namespace, @project, @ref) xml.id namespace_project_commits_url(@project.namespace, @project, @ref)
xml.updated @commits.first.committed_date.strftime("%Y-%m-%dT%H:%M:%SZ") if @commits.any? xml.updated @commits.first.committed_date.strftime("%Y-%m-%dT%H:%M:%SZ") if @commits.any?
@commits.each do |commit| @commits.each do |commit|
xml.entry do xml.entry do
xml.id namespace_project_commit_url(@project.namespace, @project, :id => commit.id) xml.id namespace_project_commit_url(@project.namespace, @project, id: commit.id)
xml.link :href => namespace_project_commit_url(@project.namespace, @project, :id => commit.id) xml.link href: namespace_project_commit_url(@project.namespace, @project, id: commit.id)
xml.title truncate(commit.title, :length => 80) xml.title truncate(commit.title, length: 80)
xml.updated commit.committed_date.strftime("%Y-%m-%dT%H:%M:%SZ") xml.updated commit.committed_date.strftime("%Y-%m-%dT%H:%M:%SZ")
xml.media :thumbnail, :width => "40", :height => "40", :url => avatar_icon(commit.author_email) xml.media :thumbnail, width: "40", height: "40", url: avatar_icon(commit.author_email)
xml.author do |author| xml.author do |author|
xml.name commit.author_name xml.name commit.author_name
xml.email commit.author_email xml.email commit.author_email
......
= content_for :meta_tags do
- if current_user
= auto_discovery_link_tag(:atom, namespace_project_commits_url(@project.namespace, @project, @ref, format: :atom, private_token: current_user.private_token), title: "#{@project.name}:#{@ref} commits")
= render "head" = render "head"
.tree-ref-holder .tree-ref-holder
......
xml.instruct! xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
xml.title "#{@project.name} issues" xml.title "#{@project.name} issues"
xml.link :href => namespace_project_issues_url(@project.namespace, @project, :atom), :rel => "self", :type => "application/atom+xml" xml.link href: namespace_project_issues_url(@project.namespace, @project, format: :atom, private_token: current_user.private_token), rel: "self", type: "application/atom+xml"
xml.link :href => namespace_project_issues_url(@project.namespace, @project), :rel => "alternate", :type => "text/html" xml.link href: namespace_project_issues_url(@project.namespace, @project), rel: "alternate", type: "text/html"
xml.id namespace_project_issues_url(@project.namespace, @project) xml.id namespace_project_issues_url(@project.namespace, @project)
xml.updated @issues.first.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") if @issues.any? xml.updated @issues.first.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") if @issues.any?
......
= content_for :meta_tags do
- if current_user
= auto_discovery_link_tag(:atom, namespace_project_issues_url(@project.namespace, @project, :atom, private_token: current_user.private_token), title: "#{@project.name} issues")
.append-bottom-10 .append-bottom-10
.pull-right .pull-right
.pull-left .pull-left
......
xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
xml.title "#{@project.name} activity"
xml.link href: namespace_project_url(@project.namespace, @project, format: :atom, private_token: current_user.private_token), rel: "self", type: "application/atom+xml"
xml.link href: namespace_project_url(@project.namespace, @project), rel: "alternate", type: "text/html"
xml.id namespace_project_url(@project.namespace, @project)
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
= 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: "#{@project.name} activity")
- if current_user && can?(current_user, :download_code, @project) - if current_user && can?(current_user, :download_code, @project)
= render 'shared/no_ssh' = render 'shared/no_ssh'
= render 'shared/no_password' = render 'shared/no_password'
...@@ -39,7 +43,16 @@ ...@@ -39,7 +43,16 @@
%i.fa.fa-angle-left %i.fa.fa-angle-left
%section.col-md-9 %section.col-md-9
= render "events/event_last_push", event: @last_push = 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
Activity Feed
= render 'shared/event_filter' = render 'shared/event_filter'
%hr
.content_list .content_list
= spinner = spinner
%aside.col-md-3.project-side %aside.col-md-3.project-side
......
= content_for :meta_tags do
- if current_user
= auto_discovery_link_tag(:atom, namespace_project_commits_url(@project.namespace, @project, @ref, format: :atom, private_token: current_user.private_token), title: "#{@project.name}:#{@ref} commits")
.tree-ref-holder .tree-ref-holder
= render 'shared/ref_switcher', destination: 'tree', path: @path = render 'shared/ref_switcher', destination: 'tree', path: @path
......
...@@ -3,17 +3,3 @@ ...@@ -3,17 +3,3 @@
= event_filter_link EventFilter.merged, 'Merge events' = event_filter_link EventFilter.merged, 'Merge events'
= event_filter_link EventFilter.comments, 'Comments' = event_filter_link EventFilter.comments, 'Comments'
= event_filter_link EventFilter.team, 'Team' = event_filter_link EventFilter.team, 'Team'
- if current_user
- if current_controller?(:dashboard)
%li.pull-right
= link_to dashboard_path(:atom, { private_token: current_user.private_token }), class: 'rss-btn' do
%i.fa.fa-rss
News Feed
- if current_controller?(:groups)
%li.pull-right
= link_to group_path(@group, { format: :atom, private_token: current_user.private_token }), title: "Feed", class: 'rss-btn' do
%i.fa.fa-rss
News Feed
%hr
xml.instruct! xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
xml.title "Activity feed for #{@user.name}" xml.title "#{@user.name} activity"
xml.link href: user_url(@user, :atom), rel: "self", type: "application/atom+xml" xml.link href: user_url(@user, :atom), rel: "self", type: "application/atom+xml"
xml.link href: user_url(@user), rel: "alternate", type: "text/html" xml.link href: user_url(@user), rel: "alternate", type: "text/html"
xml.id projects_url xml.id user_url(@user)
xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any? xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any?
@events.each do |event| @events.each do |event|
......
= content_for :meta_tags do
= auto_discovery_link_tag(:atom, user_url(@user, format: :atom), title: "#{@user.name} activity")
.row .row
= link_to '#aside', class: 'show-aside' do = link_to '#aside', class: 'show-aside' do
%i.fa.fa-angle-left %i.fa.fa-angle-left
......
...@@ -236,7 +236,7 @@ Gitlab::Application.routes.draw do ...@@ -236,7 +236,7 @@ Gitlab::Application.routes.draw do
constraints: { username: /.*/ } constraints: { username: /.*/ }
get '/u/:username' => 'users#show', as: :user, get '/u/:username' => 'users#show', as: :user,
constraints: { username: /(?:[^.]|\.(?!atom$))+/, format: /atom/ } constraints: { username: /[a-zA-Z.0-9_\-]+(?<!\.atom)/ }
# #
# Dashboard Area # Dashboard Area
...@@ -263,7 +263,7 @@ Gitlab::Application.routes.draw do ...@@ -263,7 +263,7 @@ Gitlab::Application.routes.draw do
# #
# Groups Area # Groups Area
# #
resources :groups, constraints: { id: /(?:[^.]|\.(?!atom$))+/, format: /atom/ } do resources :groups, constraints: { id: /[a-zA-Z.0-9_\-]+(?<!\.atom)/ } do
member do member do
get :issues get :issues
get :merge_requests get :merge_requests
...@@ -295,7 +295,7 @@ Gitlab::Application.routes.draw do ...@@ -295,7 +295,7 @@ Gitlab::Application.routes.draw do
# Project Area # Project Area
# #
resources :namespaces, path: '/', constraints: { id: /[a-zA-Z.0-9_\-]+/ }, only: [] do 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 [:new, :create, :index], path: "/") do
member do member do
put :transfer put :transfer
......
...@@ -18,7 +18,7 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps ...@@ -18,7 +18,7 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps
step 'I see commits atom feed' do step 'I see commits atom feed' do
commit = @project.repository.commit commit = @project.repository.commit
response_headers['Content-Type'].should have_content("application/atom+xml") response_headers['Content-Type'].should have_content("application/atom+xml")
body.should have_selector("title", text: "Recent commits to #{@project.name}") body.should have_selector("title", text: "#{@project.name}:master commits")
body.should have_selector("author email", text: commit.author_email) body.should have_selector("author email", text: commit.author_email)
body.should have_selector("entry summary", text: commit.description[0..10]) body.should have_selector("entry summary", text: commit.description[0..10])
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment