周五内容

This commit is contained in:
huang 2017-03-03 18:49:56 +08:00
parent c14840ef83
commit 8d54187e04
35 changed files with 798 additions and 50 deletions

View File

@ -0,0 +1,3 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

View File

@ -0,0 +1,3 @@
// Place all the styles related to the codes controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

View File

@ -430,6 +430,8 @@ class ApplicationController < ActionController::Base
def find_project_by_project_id
if params[:project_id]
@project = Project.find(params[:project_id])
elsif params[:shixun_id]
@shixun = Shixun.find(params[:shixun_id])
elsif params[:course_id]
@course = Course.find(params[:course_id])
elsif params[:org_subfield_id]

View File

@ -0,0 +1,2 @@
class CodesController < ApplicationController
end

View File

@ -35,13 +35,17 @@ class RepositoriesController < ApplicationController
before_filter :find_project_by_project_id, :only => [:new, :create, :newrepo, :stats, :quality_analysis]
before_filter :find_repository, :only => [:edit, :update, :destroy, :committers]
before_filter :find_project_repository, :except => [:new, :create, :newcreate, :edit, :update, :destroy, :committers, :newrepo, :to_gitlab, :forked, :export_rep_static, :training_project_extend]
before_filter :find_project_repository, :except => [:commits, :shixun_show, :new, :create, :newcreate, :edit, :update, :destroy, :committers, :newrepo, :to_gitlab, :forked, :export_rep_static, :training_project_extend]
# 实训项目新增
before_filter :find_project_and_repository, :only => [:commits, :shixun_show]
# 连接gitlab
# before_filter :connect_gitlab, :only => [:quality_analysis, :commit_diff]
before_filter :find_changeset, :only => [:revision, :add_related_issue, :remove_related_issue]
# before_filter :authorize , :except => [:newrepo,:newcreate,:fork, :to_gitlab, :forked, :project_archive, :quality_analysis, :commit_diff]
before_filter :authorize_visible , :except => [:newrepo,:newcreate,:fork, :to_gitlab, :forked, :project_archive, :quality_analysis, :commit_diff]
before_filter :authorize_visible , :except => [:shixun_show, :newrepo,:newcreate,:fork, :to_gitlab, :forked, :project_archive, :quality_analysis, :commit_diff]
# 版本库新增权限
# before_filter :show_rep, :only => [:show, :stats, :revisions, :revision, :diff, :commit_diff ]
accept_rss_auth :revisions
@ -346,30 +350,24 @@ update
}
def create
# 判断版本库创建者是否有同名版本库,避免版本库路径一致问题
unless is_sigle_identifier?(@project.user_id, params[:repository].first[1])
flash[:notice] = l(:project_gitlab_create_double_message)
redirect_to settings_project_url(@project, :tab => 'repositories')
else
attrs = pickup_extra_info
@repository = Repository.factory('Git')
@repository.safe_attributes = params[:repository]
if attrs[:attrs_extra].keys.any?
@repository.merge_extra_info(attrs[:attrs_extra])
end
@repository.project = @project
# 实训项目
if @shixun
# REDO:报错信息处理
@repository = Repository.new
@repository.shixun = @shixun
@repository.type = 'Repository::Gitlab'
@repository.identifier = @repository.identifier.downcase
@repository.identifier = params[:repository][:identifier].downcase
@repository.url = @repository.identifier
@repository.project_id = -1
ActiveRecord::Base.transaction do
begin
if request.post? && @repository.save
s = Trustie::Gitlab::Sync.new
s.create_project(@project, @repository)
raise "sync failed" if @project.gpid.blank?
redirect_to(:controller => 'repositories', :action => 'show', :id => @project, :repository_id => gitlab_repository(@project).try(:identifier))
s.create_shixun(@shixun, @repository)
raise "sync failed" if @shixun.gpid.blank?
redirect_to(:controller => 'repositories', :action => 'show', :shixun_id => @shixun, :identifier => @repository.try(:identifier))
else
redirect_to settings_project_url(@project, :tab => 'repositories',:repository_error_message=>@repository.errors.full_messages)
redirect_to settings_shixun_url(@shixun, :tab => 'repositories',:repository_error_message => @repository.errors.full_messages)
end
rescue Gitlab::Error::Forbidden => e
@message = l(:label_pull_request_forbidden)
@ -379,6 +377,41 @@ update
puts e
end
end
elsif @project
# 判断版本库创建者是否有同名版本库,避免版本库路径一致问题
unless is_sigle_identifier?(@project.user_id, params[:repository].first[1])
flash[:notice] = l(:project_gitlab_create_double_message)
redirect_to settings_project_url(@project, :tab => 'repositories')
else
attrs = pickup_extra_info
@repository = Repository.factory('Git')
@repository.safe_attributes = params[:repository]
if attrs[:attrs_extra].keys.any?
@repository.merge_extra_info(attrs[:attrs_extra])
end
@repository.project = @project
@repository.type = 'Repository::Gitlab'
@repository.identifier = @repository.identifier.downcase
@repository.url = @repository.identifier
ActiveRecord::Base.transaction do
begin
if request.post? && @repository.save
s = Trustie::Gitlab::Sync.new
s.create_project(@project, @repository)
raise "sync failed" if @project.gpid.blank?
redirect_to(:controller => 'repositories', :action => 'show', :id => @project, :repository_id => gitlab_repository(@project).try(:identifier))
else
redirect_to settings_project_url(@project, :tab => 'repositories',:repository_error_message=>@repository.errors.full_messages)
end
rescue Gitlab::Error::Forbidden => e
@message = l(:label_pull_request_forbidden)
rescue Gitlab::Error::NotFound => e
@message = l(:label_pull_request_notfound)
rescue Exception => e
puts e
end
end
end
end
end
@ -486,6 +519,40 @@ update
redirect_to :controller => 'repositories', :action => 'show', :id => @project.id, to: 'gitlab'
end
def shixun_show
# 顶部导航
@project_menu_type = 5
@entries = @repository.entries(@path, @rev)
if request.xhr?
@entries ? render(:partial => 'dir_list_content') : render(:nothing => true)
else
@changesets_latest_coimmit = @g.rep_last_changes(@shixun.gpid, :rev => @rev, :path => @path)
# @g.rep_last_changes(@project.gpid, :rev => @rev, :path => @path)
# 总的提交数
@changesets_all_count = @g.user_static(@shixun.gpid, :rev => @rev).count
# 获取默认分支
@g_default_branch = @g_project.default_branch.nil? ? "master" : @g_project.default_branch
@creator = @shixun.owner.to_s
gitlab_address = Redmine::Configuration['gitlab_address']
gitlab_token = Gitlab.private_token
# token值加密解密
token = aes_encrypt("priEn3UwXfJs3Pmy", gitlab_token)
# token值解密
# gitlab_token = aes_dicrypt("priEn3UwXfJs3Pmy", token)
@zip_path = Gitlab.endpoint.to_s + "/projects/" + @shixun.gpid.to_s + "/repository/archive?&private_token=" + token
@creator = @shixun.owner.to_s
gitlab_address = Redmine::Configuration['gitlab_address']
@repos_url = gitlab_address.to_s+"/" + @creator + "/" + @repository.identifier+"."+"git"
# 提交总数同步更新
@shixun.update_attribute(:changeset_num, @changesets_all_count)
render :layout => 'base_shixun'
end
end
# 权限:
# 如果项目隐藏了版本库,则非项目成员及项目报告人员不能够访问版本库
# 如果没有隐藏版本库,只要项目公开,其它成员都可以看到版本库
@ -545,6 +612,20 @@ update
end
def commits
# 顶部导航
@project_menu_type = 5
@entry = @repository.entry(@path, @rev)
(show_error_not_found; return) unless @entry
limit = 10
# 每次页面的换回值从1开始,但是gitlab的页面查询是从0开始,所以先改变page的类型减一在改回来
@commits = @g.commits(@shixun.gpid, page:(params[:page].to_i - 1).to_s, ref_name:@rev)
@commits_count = params[:commit_count].nil? ? @g.user_static(@shixun.gpid, :rev => @rev).count : params[:commit_count].to_i
@commits_pages = Paginator.new @commits_count, limit, params[:page]
render :layout => 'base_shixun'
end
# 注由于考虑到性能所以commits api每次返回20条记录
def changes
# 顶部导航
@ -699,6 +780,21 @@ update
render :layout => 'base_projects'
end
# 实训项目
# 每次提交对应的文件差异
def commit
# 顶部导航
@project_menu_type = 5
@commit_diff = @g.commit_diff(@project.gpid, params[:changeset])
diff = ActiveSupport::JSON.decode(@commit_diff.to_json).first
diff = OpenStruct.new(diff)
@diff_file = Trustie::Gitlab::Diff::File.new(diff)
@commit_details = @g.commit(@project.gpid, params[:changeset])
render :layout => 'base_projects'
end
def diff
if params[:format] == 'diff'
@diff = @repository.diff(@path, @rev, @rev_to)
@ -786,6 +882,29 @@ update
end
end
def find_project_and_repository
@shixun = Shixun.find(params[:id])
@repository = @shixun.repository
render_404 if @shixun.gpid.nil?
@path = params[:path].is_a?(Array) ? params[:path].join('/') : params[:path].to_s
@g = Gitlab.client
@g_project = @g.project(@shixun.gpid)
@branchs = @g.branches(@shixun.gpid)
@g_default_branch = @g_project.default_branch
# gitlab端获取默认分支
@rev = params[:rev].blank? ? @g_default_branch : params[:rev].to_s.strip
@rev_to = params[:rev_to]
unless @rev.to_s.match(REV_PARAM_RE) && @rev_to.to_s.match(REV_PARAM_RE)
if @branchs.blank?
raise InvalidRevisionParam
end
end
rescue ActiveRecord::RecordNotFound
render_404
rescue InvalidRevisionParam
show_error_not_found
end
def authorize_visible
allowed = authorize_allowed(params[:controller], params[:action], global = false)
if allowed || User.current.admin? || (@project.hidden_repo && User.current.member_of?(@project) && !role_of_members_in_project(@project.id, User.current.id) == "Reporter")

View File

@ -1,10 +1,11 @@
# encoding: utf-8
class ShixunsController < ApplicationController
layout 'base_shixun'
before_filter :require_login
before_filter :find_shixun, :except => [ :index, :new, :create, :training_execute, :training_task_status]
before_filter :shixun_authorize, :only => [:show]
before_filter :require_manager, :only => [ :settings]
before_filter :require_manager, :only => [ :settings, :add_script]
include ApplicationHelper
@ -53,6 +54,87 @@ class ShixunsController < ApplicationController
end
def settings
@repository = Repository.where(:shixun_id => @shixun, :type => "Repository::Gitlab").first
unless @repository.nil?
gitlab_address = Redmine::Configuration['gitlab_address']
creator = @shixun.owner.try(:login)
@repos_url = gitlab_address+"/" + creator + "/" + @repository.identifier+"."+"git"
end
# scm = params[:repository_scm] || (Redmine::Scm::Base.all & Setting.enabled_scm).first
# @repository = Repository.factory(scm)
# @repository.is_default = @project.repository.nil?
# @repository.project = @project
# @gitlab_rep = Repository.where(:type => "Repository::Gitlab", :project_id => @project).first
# unless @project.gpid.nil?
# g = Gitlab.client
# @gitlab_branches = g.branches(@project.gpid)
# @branch_names = @gitlab_branches.map{|b| b.name}
# @gitlab_default_branch = g.project(@project.gpid).default_branch
# end
end
def rep_tree_changes
rev = params[:rev]
ent_path = params[:ent_path]
gpid = params[:gpid]
g = Gitlab.client
begin
result = g.rep_last_changes(gpid, :rev => rev, :path => ent_path)
result = {:message => result.message, :author_name => User.find_by_mail(result.author_email).nil? ? result.author_email : User.find_by_mail(result.author_email).show_name, :time => distance_of_time_in_words(result.time, Time.now)}
rescue Exception => e
puts e
end
render :json => result
end
# 添加实训脚本
def add_script
if User.current.admin? || User.current.member_of?(@project)
if @shixun.update_attribute(:script, params[:project_script])
@notice = "脚本添加成功"
else
@notice = "脚本添加失败"
end
else
return render_403
end
end
# 创建实训job
def shixun_job_create
if @project.training_tasks.count == 0
@notice = "实训开启失败:请先发布实训任务"
return
elsif Repository.where(:project_id => @project.id, :type => "Repository::Gitlab").count == 0
@notice = "实训开启失败:请先创建版本库"
return
end
jobName = "#{@project.id}"
pipeLine = "#{Base64.encode64(@project.script)}"
uri = URI("http://123.59.135.74:9999/jenkins-exec/api/createJob")
params = {jobName: jobName, pipeLine: pipeLine}
res = uri_exec uri, params
training_project_notice res
if res['code'] == 0
@project.update_attribute(:training_status, 1)
end
end
# 更新实训job
def shixun_job_update
jobName = "#{@project.id}"
pipeLine = "#{Base64.encode64(@project.script)}"
uri = URI("http://123.59.135.74:9999/jenkins-exec/api/updateJob")
params = {jobName: jobName, pipeLine: pipeLine}
res = uri_exec uri, params
training_project_notice res
if res['code'] == 0
@project.update_attribute(:training_status, 1)
end
end
# Find shixun of id params[:id]
def find_shixun
@shixun = Shixun.find(params[:id])
@ -69,8 +151,9 @@ class ShixunsController < ApplicationController
end
end
# 实训管理员或者超级管理员
def require_manager
User.current.manager_of_shixun?(@shixun)
render_403 unless User.current.manager_of_shixun?(@shixun)
end
end

View File

@ -1125,6 +1125,11 @@ module ApplicationHelper
rep = Repository.where("project_id =? and type =?", project.id,"Repository::Gitlab" ).first
end
# 获取单一gitlab项目
def shixun_repository(shixun)
rep = Repository.where(:shixun_id => shixun, :type => "Repository::Gitlab" ).first
end
# 判断当前用户是否为项目管理员
def is_project_manager?(user_id, project_id)
@result = false

View File

@ -0,0 +1,2 @@
module CodesHelper
end

View File

@ -1,2 +1,18 @@
module ShixunsHelper
#显示项目配置菜单
def show_project_memu user
if user.allowed_to?(:edit_project, @shixun)
result = "edit_project"
elsif user.allowed_to?(:manage_members, @shixun)
result = "training_task"
elsif user.allowed_to?(:manage_versions, @shixun)
result = "manage_versions"
elsif user.allowed_to?(:manage_repository, @shixun)
result = "manage_repository"
end
result
end
end

View File

@ -25,6 +25,8 @@ class Repository < ActiveRecord::Base
IDENTIFIER_MAX_LENGTH = 254
belongs_to :project
belongs_to :shixun
belongs_to :shixun
has_many :changesets, :order => "#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC"
has_many :filechanges, :class_name => 'Change', :through => :changesets
@ -106,8 +108,7 @@ class Repository < ActiveRecord::Base
def scm
unless @scm
@scm = self.scm_adapter.new(url, root_url,
login, password, path_encoding, project_id)
@scm = self.scm_adapter.new(url, root_url, login, password, path_encoding, project_id, shixun_id)
if root_url.blank? && @scm.root_url.present?
update_attribute(:root_url, @scm.root_url)
end

View File

@ -1,8 +1,9 @@
class Shixun < ActiveRecord::Base
attr_accessible :description, :is_public, :name, :parent_id
attr_accessible :description, :is_public, :name, :parent_id, :changeset_num
has_many :users, :through => :shixun_members
has_many :shixun_members
has_one :repository
def parent
shixun = Shixun.find_by_parent_id(self.parent_id)

View File

@ -898,12 +898,8 @@ class User < Principal
end
def manager_of_shixun?(shixun)
@result = false
mem = Member.where("user_id = ? and project_id = ?", self.id, shixun.id)
unless mem.blank?
@result = mem.first.roles.to_s.include?("Manager") ? true : false
end
return @result
member = ShixunMember.where(:user_id => self.id, :shixun_id => shixun.id, :role => 1)
(!member.blank? || User.current.admin?) ? true : false
end
def member_of_course?(course)

View File

@ -49,7 +49,7 @@
<script>
$(document).ready(function(){
$.ajax({
url:"<%= repository_tree_changes_project_path(@project, :rev => @rev, :ent_path => ent_path, :gpid => @project.gpid) %>",
url:"<%= rep_tree_changes_shixun_path(@shixun, :rev => @rev, :ent_path => ent_path, :gpid => @shixun.gpid) %>",
type: "GET",
data: "text",
success:function(data){

View File

@ -0,0 +1,27 @@
<div class="autoscroll">
<table class="list entries mt5" id="browser" style="table-layout: fixed;">
<% unless @path.blank? %>
<tbody>
<tr style="border: 1px solid #DDD; border-bottom:none;">
<td colspan="4">
<!--<a href="javascript:history.go(-1)" class="fl linkBlue2 mt3" >-->
<!--<span class="new_roadmap_icons_back mr5"></span>-->
<!--<span></span>返回上级目录-->
<%#= render :partial => 'breadcrumbs', :locals => {:path => @path, :kind => 'dir', :revision => @rev} %>
<!--</a>-->
</td>
</tr>
</tbody>
<% end %>
<tbody style="line-height: 1.9;">
<%= render :partial => 'dir_list_content' %>
</tbody>
</table>
</div>
<script>
// Load last commit log for each file in tree
$('#tree-slider').waitForImages(function() {
ajaxGet('#{@logs_path}');
});
</script>

View File

@ -0,0 +1,66 @@
<% @entries.each do |entry| %>
<% tr_id = Digest::MD5.hexdigest(entry.path)
depth = params[:depth].to_i %>
<% sub_path = entry.path[0] == "/" ? entry.path.sub("/", "") : entry.path %>
<% ent_path = Redmine::CodesetUtil.replace_invalid_utf8(sub_path) %>
<% ent_name = Redmine::CodesetUtil.replace_invalid_utf8(entry.name) %>
<%# latest_changes = get_trees_last_changes(@project.gpid, @rev, ent_path, @g) %>
<tr id="<%= tr_id %>" class="<%= h params[:parent_id] %> entry <%= entry.kind %>">
<td style="padding-left: <%=18 * depth%>px;" class="filename_no_report hidden">
<% if entry.is_dir? %>
<%# 展开文件目录 %>
<span class="expander" onclick="scmEntryClick('<%= tr_id %>', '<%= escape_javascript(url_for(
:action => 'show',
:id => @project,
:repository_id => @repository.identifier_param,
:path => to_path_param(ent_path),
:rev => @rev,
:depth => (depth + 1),
:parent_id => tr_id)) %>');">&nbsp;</span>
<% end %>
<%= link_to h(ent_name),
{:action => (entry.is_dir? ? 'show' : 'entry'), :id => @project, :repository_id => @repository.identifier_param, :path => to_path_param(ent_path), :rev => @rev},
:class => (entry.is_dir? ? 'old-icon old-icon-folder' : "old-icon old-icon-file #{Redmine::MimeType.css_class_of(ent_name)}")%>
</td>
<div id="children_tree">
<td class="tree-author c_grey">
<div class="hidden" id="changes_author_<%= tr_id %>">
<%#= (latest_changes.author_name) if latest_changes %>
</div>
</td>
<td class="tree-comments c_grey hidden">
<div class="hidden" id="changes_message_<%= tr_id %>">
<%#= (latest_changes.message) if latest_changes %>
</div>
</td>
<td class="tree-age c_grey">
<div class="hidden" id="changes_time_<%= tr_id %>">
<%# 为了转换UTC时间时差8小时 %>
<%#= distance_of_time_in_words(latest_changes.time, Time.now) if latest_changes %>
<%#= link_to "", repository_tree_changes_project_path(@project, :rev => @rev, :ent_name => ent_name) %>
</div>
</td>
</div>
</tr>
<script>
$(document).ready(function(){
$.ajax({
url:"<%= repository_tree_changes_project_path(@project, :rev => @rev, :ent_path => ent_path, :gpid => @project.gpid) %>",
type: "GET",
data: "text",
success:function(data){
$('#changes_message_<%=tr_id %>').html(data.message)
$('#changes_author_<%=tr_id %>').html(data.author_name)
$('#changes_time_<%=tr_id %>').html(data.time)
}
});
});
</script>
<% end %>

View File

@ -0,0 +1,34 @@
<!--<a href="javascript:void(0);" class="pic_stats fl ml20 mt3"></a>-->
<%#= link_to l(:label_statistics),
{:action => 'stats', :id => @project, :repository_id => @repository.identifier_param},
:class => 'mt3 c_blue fl' if @repository.supports_all_revisions? %>
<div class="repositorytitle mr15">
<% content_for :header_tags do %>
<%= javascript_include_tag 'repository_navigation' %>
<% end %>
<%= form_tag({:action => controller.action_name,
:id => @shixun,
:repository_id => @repository.identifier_param,
:path => to_path_param(@path),
:rev => nil},
{:method => :get, :id => 'revision_selector'}) do -%>
<!-- Branches Dropdown -->
<% if @branchs.count > 0 -%>
<label class="pro-fenzhi-label fl">分支</label>
<%= select_tag :branch, options_for_select(@branchs.map{|map| map.name}, @rev), :id => 'branch', :class => "pro-fenzhi-select fl" %>
<% end -%>
<%# if !@repository.tags.nil? && @repository.tags.length > 0 -%>
<%#= select_tag :tag, options_for_select([''] + @repository.tags, @rev), :id => 'tag', :style=>" display:none" %>
<%# end -%>
<% if @repository.supports_all_revisions? %>
<%= hidden_field_tag 'rev', @rev, :size => 8 %>
<% end %>
<% end -%>
</div>

View File

@ -0,0 +1,50 @@
<div class="new_roadmap_conbox mb10" >
<div class=" clear">
<ul class="reply-container-branch fl" >
<%= render :partial => 'shixun_navigation' %>
</ul>
</div>
<% @commits.chunk { |c| format_date(c.created_at).to_date }.each do |day, commits| %>
<div class="pullreques_pullbox">
<div class="pullreques_pull_top clear">
<p class="fl c_grey ml15"><%= day %></p>
<p class="fr c_green mr15">当前页<%= commits.count %>个提交</p>
</div>
<ul class="pullreques_pull_list">
<% commits.each do |commit| %>
<li class="clear">
<span class="fl c_grey ml15 "><%= time_tag(commit.created_at) %>前</span>
<%= link_to_user_mail(commit.author_email, "pullreques_pull_name fl ml10") %>
<p class="pullreques_pull_txt ml10 fl"><%= commit.title %></p>
<%= link_to truncate(commit.short_id, :length => 20), {:controller => 'repositories', :action => 'commits', :id => @shixun.id, :changeset_id => commit.id}, :target => "_blank", :class => "fr mr15 c_grey" %>
<% unless get_commit_issues(commit.short_id, @shixun.id, 0).nil? %>
<% get_commit_issues(commit.short_id, @shixun.id, 0).each do |issue_id| %>
<div class="btn-commit-issue btn-blue mb5 mr5 fr">
<% if issue_id == "more" %>
<%= link_to "更多", {:controller => 'repositories', :action => 'commit_diff', :id => @shixun.id, :changeset => commit.id}, :target => "_blank", :class => "commit_id_value mr5" %>
<% else %>
<%= link_to "##{issue_id}", issue_path(issue_id), :target => "_blank", :class => "commit_id_value mr5" %>
<% end %>
</div>
<% end %>
<% end %>
<div class="cl"></div>
</li>
<% end %>
</ul>
</div>
<% end %>
<div style="text-align:center;">
<div class="pages" style="width:auto; display:inline-block;">
<ul id="homework_pository_ref_pages">
<%= pagination_links_full @commits_pages, @commits_count, :per_page_links => false, :remote => false, :flag => true, :is_new => true %>
</ul>
<div class="cl"></div>
</div>
</div>
<div class="cl"></div>
<%= call_hook(:view_repositories_show_contextual, { :repository => @repository, :project => @shixun }) %>
<% html_title(l(:label_change_plural)) -%>
</div>

View File

@ -0,0 +1,45 @@
<div class="wrap-big">
<div class="repository_con" style="line-height:1.9;">
<ul class="clearfix pro-top-info mb10">
<li style="width: 459px;"><i class="icon-time mr5 c_grey02 f16 fb"></i>
<%=link_to "#{choise_commit_count(@changesets_all_count, @g_project.commit_count.to_i)}",
{:action => 'commits', :path => to_path_param(@path), :id => @shixun, :repository_id => @repository.identifier_param,
:rev => @rev, :page => 1 ,:commit_count =>"#{@changesets_all_count}"}, :class => "linkBlue fb" %> 提交
</li>
<li style="width: 459px;"><i class="icon-sitemap mr5 c_grey02 f16 fb"></i>
<a class="linkBlue fb "><%= @branchs.count %></a>分支
</li>
</ul>
<div class=" clearfix mb5">
<div class=" fl clearfix">
<%= render :partial => 'shixun_navigation' %>
</div>
<% if !@entries.blank? %>
<a href="<%= @zip_path %>" class="btn_zipdown fl ml10" onclick="">ZIP下载</a>
<% end %>
<div class="fr ">
<label class="pro-fenzhi-label fl">克隆网址</label>
<input type="text" id="copy_rep_content" class="pro-fenzhi-input fl" value="<%= @repos_url.to_s.lstrip %>"/>
<a href="javascript:void(0);" alt="点击复制版本库地址" onclick="jsCopy()" title="点击复制版本库地址" class="fl pro-fenzhi-a"><i class="icon-copy"></i></a>
</div>
</div>
<div class="cl"></div>
<%= render :partial => 'latest_commit' %>
<div class="cl"></div>
<% if !@entries.blank? && authorize_for('repositories', 'browse') %>
<%= render :partial => 'shixun_dir_list' %>
<% else %>
<%= render :partial => "projects/no_data" %>
<% end %>
<% memo = Memo.where(:id => 1232).first %>
<% unless memo.nil? %>
<a href="<%= Setting.protocol + "://" %><%=Setting.host_name %>/forums/1/memos/1232" class="linkBlue2" target="_blank">如何提交代码</a>
<% end %>
</div>
</div>
<% html_title(l(:label_repository)) -%>

View File

@ -0,0 +1,44 @@
<div id="training_project_exec_tip">
<%= render :partial => "shixuns/settings_challenges_result_tip" %>
</div>
<div class=" sy_new_tchbox clear ">
<div id="training_project_filter_tip">
<%= render :partial => "shixuns/settings_challenges_action_tip" %>
</div>
<div class="cl"></div>
<div class="clear">
<%= form_tag(url_for(:controller => 'shixuns', :action => 'add_script', :id => @shixun), :method => "post", :remote => true) do %>
<textarea id="shixun_script" name="shixun_script" style="width:746px; height:300px;border: 1px solid #c8c8c8; padding:5px;margin-bottom: 5px;" placeholder="请输入脚本"><%= @shixun.script %></textarea>
<span id ="shixun_script_tip" class="c_red" style="display: none">内容不能为空</span>
<a href="javascript:void(0)" class="fr btn btn-grey">取消</a>
<a href="javascript:void(0)" class="fr btn btn-blue mr5" onclick="project_script_commit()">确定</a>
<% end %>
</div>
</div>
<script>
function regex_pr_comment()
{
var comment = $.trim($("#shixun_script").val());
if(comment.length == 0)
{
$("#shixun_script_tip").show();
return false;
}
else
{
$("#shixun_script_tip").hide();
return true;
}
}
//提交pull request_comment
function project_script_commit()
{
if(regex_pr_comment())
{
$("#project_script_form").submit();
}
}
</script>

View File

@ -0,0 +1,7 @@
<% unless @shixun.script.blank? %>
<% if @shixun.training_status == 1 %>
<%= link_to "重启实训", training_project_update_project_path, :class => "fr sy_btn_green mb10", :remote => true %>
<% else %>
<%= link_to "开启实训", training_project_execute_project_path, :class => "fr sy_btn_green mb10", :remote => true %>
<% end %>
<% end %>

View File

@ -0,0 +1,3 @@
<% if @notice %>
<div class="alert alert-orange ml15 mr15 mb10"><p><%= @notice %></p></div>
<% end %>

View File

@ -0,0 +1 @@
bianji

View File

@ -0,0 +1,82 @@
<div class="pro_new_prompt ml15 mr15 mb10"><p>温馨提示:每个项目只能创建一个版本库</p></div>
<% if @repository.nil? %>
<div class="sy_new_tchbox clear">
<%= labelled_form_for :repository, @repository, :url => shixun_repositories_path(@shixun), :html => {:method => "post", :autocomplete => 'off'} do |f| %>
<ul class="pro_newsetting_con mb15">
<li>
<label class=" fl"><span class="c_red f12">*</span>&nbsp;版本库名称&nbsp;&nbsp;:&nbsp;</label>
<%= f.text_field :identifier, :no_label => true, :class => "w650 fl", :style => "height: 28px;", :id => "shixun_identifier" %>
<span style="display: none" class="c_orange ml100" id="valid_repository_name">版本库名是无效的</span>
</li>
<li class="clear">
<label class=" fl">&nbsp;&nbsp;</label>
<p class=" fl c_grey pro_new_grey">
1.长度必须在1到254个字符之间<br/>
2.仅限使用小写字母a-z、数字、破折号-和下划线_<br>
3.一旦保存,标识无法修改<br>
4.版本库名不能是纯数字
</p>
</li>
</ul>
<a href="javascript:void(0)" onclick="cancel_for_create();" class="fr sy_btn_grey"><%=l(:button_cancel)%></a>
<a href="javascript:void(0)" onclick="project_repository_commit();" class="fr sy_btn_blue mr5"><%=l(:lable_project_rep_create) %></a>
<% end %>
</div>
<% else %>
<div class=" clear ml15 mr15" >
<table class="sy_new_table clear mb15" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th class="w130 pl10 pr10 hidden fl">版本库名</th>
<th class="w90 pr10 hidden fl">管理系统</th>
<th class="w490 hidden fl">库路径</th>
<th class="w46 hidden fl">&nbsp;</th>
</tr>
</thead>
<tbody>
<tr>
<th class="w130 pl10 pr10 hidden fl"><%= @repository.identifier %></th>
<th class="w90 pr10 hidden fl">Git</th>
<th class="w490 hidden fl"><%=h @repos_url %></th>
</tr>
</tbody>
</table>
</div>
<% end %>
<script>
function pro_st_show_ku()
{
$("#pro_st_edit_ku").toggle();
}
function cancel_for_create()
{
$("#shixun_identifier").val('');
}
function project_repository_commit()
{
if(regex_repoistory_name())
{
$("#new_repository").submit();
}
}
function regex_repoistory_name()
{
var name = $.trim($("#shixun_identifier").val());
if(/^[a-zA-Z0-9_\-]*[a-zA-Z_\-]+[a-zA-Z0-9_\-]*$/.test(name))
{
$("#valid_repository_name").hide();
return true;
}
else
{
$("#valid_repository_name").show();
return false;
}
}
</script>

View File

@ -34,13 +34,16 @@
<%= link_to 1 > 0 ? "#{l(:project_module_boards)}<span class='issues_nav_tag ml5'>#{switch_integer_into_k 99999}</span>".html_safe : "#{l(:project_module_boards)}", project_boards_path(@shixun), :class => "pro_new_proname", :title => "#{99999}" %>
</li>
<!--版本库-->
<li id="project_menu_05"><%= link_to 1 > 0 ? "#{l(:project_module_repository)}<span class='issues_nav_tag ml5'>#{switch_integer_into_k 99999}</span>".html_safe : "#{l(:project_module_repository)}",({:controller => 'repositories', :action => 'show', :id => @shixun, :repository_id => gitlab_repository(@shixun).try(:identifier)}), :class => "pro_new_proname", :title => "#{99999}" %></li>
<li id="project_menu_010">
<%= link_to "#{l(:button_configure)}", settings_project_path(@shixun), :class => "pro_new_proname" %>
</li>
<% unless @shixun.repository.nil? %>
<li id="project_menu_05">
<%= link_to (1 > 0 ? "#{l(:project_module_repository)}<span class='issues_nav_tag ml5'>#{switch_integer_into_k 99999}</span>".html_safe : "#{l(:project_module_repository)}"),
({:controller => 'repositories', :action => 'show', :repository_id => shixun_repository(@shixun).try(:identifier)}),
:class => "pro_new_proname", :title => "#{99999}" %></li>
<% end %>
<li id="project_menu_010">
<%= link_to "#{l(:button_configure)}", settings_shixun_path(@shixun), :class => "pro_new_proname" %>
</li>
</ul>
</div>
</div>

View File

@ -0,0 +1,2 @@
$("#training_project_exec_tip").html('<%= escape_javascript(render :partial => 'shixuns/training_project_exec_tip') %>');
$("#training_project_filter_tip").html('<%= escape_javascript(render :partial => 'projects/settings/training_projects_filter_tip') %>');

View File

@ -0,0 +1,62 @@
<div class="pro_new_setting clear mb10">
<div class="pro_new_setting_leftnav fl">
<ul>
<% show_memu = show_project_memu User.current %>
<li><a href="javascript:void(0)" id="pro_st_tb_1" class="<%= show_memu == 'edit_project' ? 'active' : ''%>" onclick="project_setting(1);">信息</a></li>
<!--<li id="pro_st_tb_5" class="pro_st_normaltab" onclick="project_setting(5);">问题类别</li>-->
<li><a href="javascript:void(0)" id="pro_st_tb_6" class="<%= show_memu == 'manage_repository' ? 'active' : ''%>" onclick="project_setting(6);">版本库</a></li>
<li><a href="javascript:void(0)" id="pro_st_tb_7" class="<%= show_memu == 'trainig_task' ? 'active' : ''%>" onclick="project_setting(7);">实训任务</a></li>
</ul>
</div>
<div class="pro_new_setting_conbox fl ml10">
<div class="<%= show_memu == 'edit_project' ? 'pro_st_dis' : 'pro_st_undis'%>" id="pro_st_tbc_01">
<%= render :partial=>"shixuns/settings_edit" %>
</div><!--tbc_01 end-->
<div class="<%= show_memu == 'manage_repository' ? 'pro_st_dis' : 'pro_st_undis'%>" id="pro_st_tbc_06">
<%= render :partial=>"shixuns/settings_repository" %>
</div><!--tbc_06 end-->
<div class="<%= show_memu == 'training_task' ? 'pro_st_dis' : 'pro_st_undis'%>" id="pro_st_tbc_07">
<%= render :partial=>"shixuns/settings_challenges" %>
</div><!--tbc_06 end-->
</div>
</div>
<script type="text/javascript">
$(function(){
<%if @select_tab %>
<% if @select_tab == "modules" %>
project_setting(2);
<% elsif @select_tab == "members" %>
project_setting(3);
<% elsif @select_tab == "versions" %>
project_setting(4);
$("#pro_st_edit_ban").toggle();
<% elsif @select_tab == "repositories" %>
project_setting(6);
$("#pro_st_edit_ku").toggle();
<% else %>
project_setting(5);
<% end%>
<% end%>
$("div[nhname='pro_setting']").show();
// $(".project_r_h").parent().css({"width":"730px","background-color":"#fff","padding":"10px","margin-left":"10px","margin-bottom":"10px"});
});
var windowH = $(window).height();
var contentH = $(".pro_new_setting_conbox").height();
if(windowH > contentH + 329) {
$(".pro_new_setting_conbox").css("margin-bottom",windowH - 329 -contentH + "px");
}else{
$(".pro_new_setting_conbox").css("margin-bottom",0);
}
$(".pro_new_setting_leftnav ul li").live("click",function(){
var newContentH = $(".pro_new_setting_conbox").height();
if(windowH > newContentH + 329) {
$(".pro_new_setting_conbox").css("margin-bottom",windowH - 329 - newContentH + "px");
}else{
$(".pro_new_setting_conbox").css("margin-bottom",0);
}
});
</script>

View File

@ -30,11 +30,19 @@ RedmineApp::Application.routes.draw do
resources :shixuns do
member do
post 'add_script'
get 'settings(/:tab)', :action => 'settings', :as => 'settings'
get 'shixun_job_create'
get 'shixun_job_update'
get 'rep_tree_changes', :action => 'rep_tree_changes', :as => 'rep_tree_changes'
end
collection do
end
resources :repositories, :shallow => true, :except => [:index, :show] do
member do
match 'committers', :via => [:get, :post]
end
end
end
@ -1163,6 +1171,9 @@ RedmineApp::Application.routes.draw do
get 'projects/:id/repository/:repository_id/graph', :to => 'repositories#graph'
get 'projects/:id/repository/:repository_id/changes(/*path(.:ext))', :to => 'repositories#changes'
# shixun
get 'shixuns/:id/repository/:repository_id/commits(/*path(.:ext))', :to => 'repositories#commits'
get 'shixuns/:id/repository/:repository_id/commits/:changeset_id', :to => 'repositories#commits'
get 'projects/:id/repository/:repository_id/revisions/:rev', :to => 'repositories#revision'
get 'projects/:id/repository/:repository_id/revision', :to => 'repositories#revision'
@ -1209,6 +1220,9 @@ RedmineApp::Application.routes.draw do
:action => /(browse|show|entry|raw|changes|annotate|diff|commit_diff)/
get 'projects/:id/repository/:repository_id', :to => 'repositories#show', :path => nil
# shixun
get 'shixuns/:id/repository/:repository_id', :to => 'repositories#shixun_show', :path => nil
#
get 'projects/:id/repository', :to => 'repositories#show', :path => nil
get 'projects/:id/exit', :to => 'projects#exit_project', :as => 'exit_cur_project'

View File

@ -0,0 +1,5 @@
class AddShixunIdToRepositories < ActiveRecord::Migration
def change
add_column :repositories, :shixun_id, :integer
end
end

View File

@ -0,0 +1,5 @@
class AddChangesetNumToShixun < ActiveRecord::Migration
def change
add_column :shixuns, :changeset_num, :integer
end
end

View File

@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20170302032957) do
ActiveRecord::Schema.define(:version => 20170303071513) do
create_table "activities", :force => true do |t|
t.integer "act_id", :null => false
@ -1915,6 +1915,7 @@ ActiveRecord::Schema.define(:version => 20170302032957) do
t.string "identifier"
t.boolean "is_default", :default => false
t.boolean "hidden", :default => false
t.integer "shixun_id"
end
add_index "repositories", ["project_id"], :name => "index_repositories_on_project_id"
@ -2031,14 +2032,15 @@ ActiveRecord::Schema.define(:version => 20170302032957) do
t.string "name"
t.text "description"
t.text "script"
t.boolean "is_public", :default => true
t.boolean "is_public", :default => true
t.integer "parent_id"
t.integer "user_id"
t.integer "gpid"
t.integer "forked_count", :default => 0
t.integer "visits", :default => 0
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "forked_count", :default => 0
t.integer "visits", :default => 0
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "changeset_num"
end
create_table "softapplications", :force => true do |t|

View File

@ -80,7 +80,7 @@ module Redmine
end
def initialize(url, root_url=nil, login=nil, password=nil,
path_encoding=nil, project_id)
path_encoding=nil, project_id, shixun_id)
@url = url
@login = login if login && !login.empty?
@password = (password || "") if @login

View File

@ -13,11 +13,17 @@ module Redmine
attr_accessor :is_default
end
def initialize(url, root_url=nil, login=nil, password=nil, path_encoding=nil, project_id)
def initialize(url, root_url=nil, login=nil, password=nil, path_encoding=nil, project_id, shixun_id)
super
@g = Gitlab.client
r = Repository.where("url =? and project_id =?", url, project_id).first
@project = r.project.gpid
# shixun project
if project_id == -1
r = Repository.where("url =? and shixun_id =?", url, shixun_id).first
@shixun = r.shixun.gpid
else
r = Repository.where("url =? and project_id =?", url, project_id).first
@project = r.project.gpid
end
# @project = Repository.find_by_url(url).project.gpid
@path_encoding = path_encoding.blank? ? 'UTF-8' : path_encoding
end
@ -89,7 +95,11 @@ module Redmine
def entries(path=nil, identifier=nil, options={})
entries = Entries.new
trees = @g.trees(@project, path: path, ref_name: identifier)
if @project
trees = @g.trees(@project, path: path, ref_name: identifier)
else
trees = @g.trees(@shixun, path: path, ref_name: identifier)
end
trees.each do |tree|
entries << Entry.new({
:name => tree.name,

View File

@ -71,6 +71,19 @@ module Trustie
end
end
def shixun_gitlab_role m
case m
when 3
REPORTER
when 2
DEVELOPER
when 1
MASTER
else
GUEST
end
end
end
end
end

View File

@ -68,6 +68,41 @@ module Trustie
end
end
def create_shixun(shixun, repository)
gid = shixun.owner.gid
unless gid
gid = sync_user(shixun.owner).id
end
raise "unknow gid" unless gid
gshixun = g.create_project(repository.identifier,
path: repository.identifier,
description: false,
wiki_enabled: false,
wall_enabled: false,
issues_enabled: false,
snippets_enabled: false,
public: false,
user_id: gid,
visibility_level: shixun.is_public? ? UserLevel::PUBLIC : UserLevel::PRIVATE
)
shixun.gpid = gshixun.id
shixun.save!
# 创建的时候一并同步成员及角色
shixun.shixun_members.each do |m|
begin
gid = m.user.gid
unless gid
gid = sync_user(m.user).id
end
self.g.add_team_member(gshixun.id, gid, shixun_gitlab_role(m.role))
rescue => e
puts e
end
end
end
def sync_project(project, opt={})
gid = project.owner.gid
unless gid

View File

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe CodesController, :type => :controller do
end