Merge pull request #213 from abf/rosa-build:82-show-content-of-platforms

#82: Show content of platform on ABF
This commit is contained in:
avokhmin 2013-07-12 12:21:04 +04:00
commit e0f247ac1e
18 changed files with 405 additions and 12 deletions

View File

@ -2036,3 +2036,26 @@ a.button.reject_publish, a.button.create_container {
height: 16px;
padding: 3px 20px 5px 20px;
}
#contents {
.path {
a {
margin-right: 20px;
}
.text {
padding: 5px 10px;
background-color: #dcecfa;
float: left;
height: 14px;
}
.arrow-right {
content: '';
width: 0;
height: 0;
border: 12px solid transparent;
border-left: 12px solid #dcecfa;
float: left;
}
}
}

View File

@ -1,5 +1,6 @@
# -*- encoding : utf-8 -*-
class Api::V1::BaseController < ApplicationController
include PaginateHelper
#respond_to :json
helper_method :member_path
@ -72,15 +73,6 @@ class Api::V1::BaseController < ApplicationController
end
end
def paginate_params
per_page = params[:per_page].to_i
per_page = 20 if per_page < 1
per_page = 100 if per_page >100
page = params[:page].to_i
page = nil if page == 0
{:page => page, :per_page => per_page}
end
def render_json_response(subject, message, status = 200)
id = status != 200 ? nil : subject.id

View File

@ -0,0 +1,17 @@
class Platforms::ContentsController < Platforms::BaseController
include PaginateHelper
before_filter :authenticate_user!
skip_before_filter :authenticate_user! if APP_CONFIG['anonymous_access']
load_and_authorize_resource :platform
def index
@path = params[:path].to_s
@term = params[:term]
@contents = PlatformContent.find_by_platform(@platform, @path, @term)
.paginate(paginate_params)
end
end

View File

@ -0,0 +1,26 @@
# -*- encoding : utf-8 -*-
module ContentsHelper
def build_content_paths(platform, path)
paths = ['/']
paths |= path.split('/').select(&:present?)
paths.uniq!
compound_path = ''
paths.map do |p|
compound_path << p << '/' if p != '/'
link_to(platform_content_path(platform, compound_path), {:remote => true}) do
content_tag(:span, p, {:class => 'text'}) +
content_tag(:span, '', {:class => 'arrow-right'})
end
end.join.html_safe
end
def platform_content_path(platform, path, name = nil)
full_path = platform_contents_path(platform)
full_path << '/' << path if path.present?
full_path << ('/' << name) if name.present?
full_path
end
end

View File

@ -0,0 +1,13 @@
# -*- encoding : utf-8 -*-
module PaginateHelper
def paginate_params
per_page = params[:per_page].to_i
per_page = 20 if per_page < 1
per_page = 100 if per_page >100
page = params[:page].to_i
page = nil if page == 0
{:page => page, :per_page => per_page}
end
end

View File

@ -1,7 +1,7 @@
# -*- encoding : utf-8 -*-
class Platform < ActiveRecord::Base
VISIBILITIES = %w(open hidden)
NAME_PATTERN = /[a-zA-Z0-9_\-\.]+/
NAME_PATTERN = /[\w\-\.]+/
belongs_to :parent, :class_name => 'Platform', :foreign_key => 'parent_platform_id'
belongs_to :owner, :polymorphic => true

View File

@ -0,0 +1,90 @@
class PlatformContent
# ------------------
# *** ATTRIBUTES ***
# ------------------
attr_reader :path
# ---------------
# *** METHODS ***
# ---------------
def initialize(platform, path)
@platform, @path = platform, path
end
def build_list
return @build_list if !!@build_list
return nil if path !~ /\/(release|updates)+\/[\w\-\.]+$/
return nil unless repository_name = path.match(/\/[\w]+\/(release|updates)\//)
repository_name = repository_name[0].gsub(/\/(release|updates)\/$/, '').gsub('/', '')
repository = @platform.repositories.where(:name => repository_name).first
return nil unless repository
if @platform.main?
build_for_platform = @platform
else
bfp_name = path.match(/\/#{@platform.name}\/repository\/[\w]+\//)
return nil unless bfp_name
bfp_name = bfp_name[0].gsub(/\/#{@platform.name}\/repository\//, '').gsub('/', '')
build_for_platform = Platform.main.find_by_name bfp_name
return nil unless build_for_platform
end
@build_list = BuildList.for_status(BuildList::BUILD_PUBLISHED)
.for_platform(build_for_platform)
.scoped_to_save_platform(@platform)
.where(:save_to_repository_id => repository)
.where(:build_list_packages => {:fullname => name, :actual => true})
.joins(:packages)
.last
return @build_list
end
def name
@name ||= @path.gsub(/.*#{File::SEPARATOR}/, '')
end
def size
@size ||= File.size(@path)
end
def is_folder?
@is_folder.nil? ? (@is_folder = File.directory?(path)) : @is_folder
end
def download_url
suffix = path.gsub(/^#{@platform.path}/, '')
"#{APP_CONFIG['downloads_url']}/#{@platform.name}#{suffix}"
end
# ---------------------
# *** CLASS METHODS ***
# ---------------------
def self.find_by_platform(platform, path, term)
# Strip out the non-ascii character
term = (term || '').strip.gsub(/[\\\/]+/, '')
.gsub(/[^\w\-\+\.]/, '_')
path = path.split(File::SEPARATOR).map(&:strip).select(&:present?)
.map{ |p|
# Strip out the non-ascii character
p.gsub(/[\\\/]+/, '')
.gsub(/^[\.]+/, '')
.gsub(/[^\w\-\.]/, '_')
}
.join(File::SEPARATOR)
results = Dir.glob(File.join(platform.path, path, "*#{term}*"))
if term
results = results.sort_by(&:length)
else
results = results.sort
end
results.map{ |p| PlatformContent.new(platform, p) }
end
end

View File

@ -2,7 +2,7 @@
class Project < ActiveRecord::Base
VISIBILITIES = ['open', 'hidden']
MAX_OWN_PROJECTS = 32000
NAME_REGEXP = /[a-zA-Z0-9_\-\+\.]+/
NAME_REGEXP = /[\w\-\+\.]+/
belongs_to :owner, :polymorphic => true, :counter_cache => :own_projects_count
belongs_to :maintainer, :class_name => "User"

View File

@ -10,6 +10,8 @@
= link_to t("layout.platforms.about"), platform_path(@platform)
%li{:class => (contr == :repositories) ? 'active' : ''}
= link_to t("layout.repositories.list_header"), platform_repositories_path(@platform)
%li{:class => (contr == :contents) ? 'active' : ''}
= link_to t('layout.platforms.contents'), platform_contents_path(@platform)
- if can? :show, @platform
%li{:class => (act == :index && contr == :maintainers) ? 'active' : nil}
= link_to t("layout.platforms.maintainers"), platform_maintainers_path(@platform)

View File

@ -0,0 +1,34 @@
#contents
= form_for @platform, :url => platform_content_path(@platform, @path), :html => { :class => :form, :remote => true, :method => :get } do |f|
= tracker_search_field(:term, @term.present? ? @term : t('layout.platforms.search_contents'))
= f.submit t('layout.search.header')
%br
.path= build_content_paths(@platform, @path)
.both
%table.tablesorter.project{:cellpadding => "0", :cellspacing => "0"}
%tbody
- if @path.present?
%tr
%td= link_to '../', platform_content_path(@platform, @path, '../'), {:remote => true}
%td
%td
- (@contents.select(&:is_folder?) | @contents).each do |content|
%tr
%td
- options = {:class => 'files-see'}
- if content.is_folder?
- pic = 'folder.png'
- path = platform_content_path(@platform, @path, content.name)
- options[:remote] = true
.pic= image_tag pic || 'code.png'
.name= link_to(content.name, path || content.download_url, options)
%td= link_to t('activerecord.models.build_list'), content.build_list if content.build_list
%td= number_to_human_size(content.size) unless content.is_folder?
.both
= will_paginate @contents, {:remote => true}

View File

@ -0,0 +1,14 @@
- set_meta_tags :title => [title_object(@platform), t('layout.platforms.contents')]
= render 'platforms/base/submenu'
= render 'platforms/base/sidebar'
%h3
= t('layout.platforms.contents_of')
= @platform.name
= render 'contents'
:javascript
$(function(){
$('.pagination a').attr('data-remote', 'true');
});

View File

@ -0,0 +1,2 @@
$('#contents').html("#{escape_javascript(render 'contents')}");
$('.pagination a').attr('data-remote', 'true');

View File

@ -2,7 +2,9 @@
= render 'submenu'
= render 'sidebar'
%h3.fix= "#{t("layout.platforms.about")} #{@platform.name}"
%h3.fix
= t 'layout.platforms.about'
= link_to @platform.name, platform_contents_path(@platform)
%p= @platform.description

View File

@ -1,6 +1,9 @@
en:
layout:
platforms:
contents: Contents
contents_of: Contents of
search_contents: Search name of file/folder...
admin_id: Owner
build_all: Build all
list: List

View File

@ -1,6 +1,9 @@
ru:
layout:
platforms:
contents: Содержимое
contents_of: Содержимое
search_contents: Найти имя файла/папки...
admin_id: Владелец
build_all: Собрать все
list: Список

View File

@ -161,6 +161,9 @@ Rosa::Application.routes.draw do
get :advisories
end
resources :contents, :only => [:index]
match '/contents/*path' => 'contents#index', :format => false
resources :mass_builds, :only => [:create, :new, :index] do
member do
post :cancel

View File

@ -0,0 +1,98 @@
# -*- encoding : utf-8 -*-
require 'spec_helper'
shared_examples_for 'content platform user without show rights for hidden platform' do
it 'should not be able to perform index action' do
@platform.update_column(:visibility, 'hidden')
get :index, :platform_id => @platform
response.should_not be_success
end
end
shared_examples_for 'content platform user with show rights for hidden platform' do
it 'should be able to perform index action' do
@platform.update_column(:visibility, 'hidden')
get :index, :platform_id => @platform
response.should be_success
end
end
shared_examples_for 'content platform user with show rights' do
it 'should be able to perform index action for main platform' do
get :index, :platform_id => @platform
response.should be_success
end
it 'should be able to perform index action for personal platform' do
get :index, :platform_id => @personal_platform
response.should be_success
end
end
describe Platforms::ContentsController do
before do
stub_symlink_methods
@platform = FactoryGirl.create(:platform)
@personal_platform = FactoryGirl.create(:platform, :platform_type => 'personal')
@user = FactoryGirl.create(:user)
end
context 'for guest' do
it 'should not be able to perform index action for main platform', :anonymous_access => false do
get :index, :platform_id => @platform
response.should_not be_success
end
it 'should not be able to perform index action for personal platform', :anonymous_access => false do
get :index, :platform_id => @personal_platform
response.should_not be_success
end
it_should_behave_like 'content platform user with show rights' if APP_CONFIG['anonymous_access']
it_should_behave_like 'content platform user without show rights for hidden platform'
end
context 'for global admin' do
before do
http_login(FactoryGirl.create(:admin))
end
it_should_behave_like 'content platform user with show rights'
it_should_behave_like 'content platform user with show rights for hidden platform'
end
context 'for owner user' do
before do
http_login(@user)
@platform.owner = @user; @platform.save
@platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
end
it_should_behave_like 'content platform user with show rights'
it_should_behave_like 'content platform user with show rights for hidden platform'
end
context 'for member of platform' do
before do
http_login(@user)
@platform.add_member(@user)
@personal_platform.add_member(@user)
end
it_should_behave_like 'content platform user with show rights'
it_should_behave_like 'content platform user with show rights for hidden platform'
end
context 'for simple user' do
before do
http_login(@user)
end
it_should_behave_like 'content platform user with show rights'
it_should_behave_like 'content platform user without show rights for hidden platform'
end
end

View File

@ -0,0 +1,71 @@
# -*- encoding : utf-8 -*-
require 'spec_helper'
describe PlatformContent do
subject { PlatformContent }
before { stub_symlink_methods }
let!(:platform) { FactoryGirl.create(:platform) }
context '#find_by_platform' do
before do
File.open(File.join(platform.path, 'test001'), "w")
File.open(File.join(platform.path, 'test002'), "w")
end
it 'ensures that finds files' do
# + /repository folder
subject.find_by_platform(platform, '', '').should have(3).items
end
context 'ensures that finds files by name' do
it { subject.find_by_platform(platform, '', 'test').should have(2).items }
it { subject.find_by_platform(platform, '', 'test001').should have(1).item }
it { subject.find_by_platform(platform, 'repository', 'test').should have(:no).items }
end
end
context '#is_folder?' do
it 'ensures that returns true for folder' do
subject.find_by_platform(platform, '', 'repository').first.is_folder?
.should be_true
end
it 'ensures that returns false for file' do
File.open(File.join(platform.path, 'test001'), "w")
subject.find_by_platform(platform, '', 'test').first.is_folder?
.should be_false
end
end
context '#build_list' do
let!(:package) { FactoryGirl.create(:build_list_package, :actual => true) }
let(:platform) { package.build_list.save_to_platform }
let(:repository) { platform.repositories.first }
before do
File.open(File.join(platform.path, 'test001'), "w")
package.build_list.update_column(:status, BuildList::BUILD_PUBLISHED)
path = File.join platform.path, 'repository', 'SRPMS', repository.name, 'release'
FileUtils.mkdir_p path
File.open(File.join(path, package.fullname), "w")
path = File.join path, 'repodata'
FileUtils.mkdir_p path
File.open(File.join(path, package.fullname), "w")
end
context 'ensures that returns nil for simple file' do
it { subject.find_by_platform(platform, '', 'test').first.build_list.should be_nil }
it { subject.find_by_platform(platform, "repository/SRPMS/#{repository.name}/release/repodata", '').first.build_list.should be_nil }
end
it 'ensures that returns build_list for package' do
subject.find_by_platform(platform, "repository/SRPMS/#{repository.name}/release", package.fullname)
.first.build_list.should == package.build_list
end
end
end