Commit 6b030fd4 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

1.1pre1

parent 3a2b2733
v 1.1.0
- project dashboard
- wall redesigned
- feature: code snippets
- fixed horizontal scroll on file preview
- fixed app crash if commit message has invalid chars
- bugfix & code cleaning
v 1.0.2
- fixed bug with empty project
- added adv validation for project path & code
- feature: issues can be sortable
- bugfix
- username dispalyed on top panel
v 1.0.1
- fixed: with invalid source code for commit
- fixed: lose branch/tag selection when use tree navigateion
- when history clicked - display path
- bug fix & code cleaning
v 1.0.0
- bug fix
- projects preview mode
v 0.9.6
- css fix
- new repo empty tree until restart server - fixed
v 0.9.4
- security improved
- authorization improved
......@@ -24,6 +42,7 @@ v 0.9.1
- updated app name
- issue redesigned
- issue can be edit
v 0.8.0
- sytax highlight for main file types
- redesign
......
......@@ -15,7 +15,7 @@ gem 'therubyracer'
gem 'faker'
gem 'seed-fu', :git => 'git://github.com/mbleigh/seed-fu.git'
gem "inifile"
gem "albino", :git => "git://github.com/gitlabhq/albino.git"
gem "pygments.rb", "0.2.3"
gem "kaminari"
gem "thin"
gem "git"
......
......@@ -4,13 +4,6 @@ GIT
specs:
annotate (2.4.1.beta1)
GIT
remote: git://github.com/gitlabhq/albino.git
revision: 118380924969f3a856659f86ea1f40c1ba7bfcb1
specs:
albino (1.3.3)
posix-spawn (>= 0.3.6)
GIT
remote: git://github.com/gitlabhq/grit.git
revision: ff015074ef35bd94cba943f9c0f98e161ab5851c
......@@ -72,6 +65,7 @@ GEM
ZenTest (= 4.5)
awesome_print (0.4.0)
bcrypt-ruby (3.0.1)
blankslate (2.1.2.4)
builder (3.0.0)
capybara (1.0.1)
mime-types (>= 1.16)
......@@ -138,6 +132,8 @@ GEM
orm_adapter (0.0.5)
polyglot (0.3.2)
posix-spawn (0.3.6)
pygments.rb (0.2.3)
rubypython (>= 0.5.1)
rack (1.3.2)
rack-cache (1.0.3)
rack (>= 0.4)
......@@ -189,6 +185,9 @@ GEM
ruby-debug-base19 (>= 0.11.19)
ruby_core_source (0.1.5)
archive-tar-minitar (>= 0.5.2)
rubypython (0.5.1)
blankslate (>= 2.1.2.3)
ffi (~> 1.0.7)
rubyzip (0.9.4)
sass (3.1.7)
sass-rails (3.1.1)
......@@ -242,7 +241,6 @@ PLATFORMS
DEPENDENCIES
acts_as_list
albino!
annotate!
autotest
autotest-rails
......@@ -260,6 +258,7 @@ DEPENDENCIES
jquery-rails
kaminari
launchy
pygments.rb (= 0.2.3)
rails (= 3.1.0)
rails-footnotes (>= 3.7.5.rc4)
rspec-rails
......
......@@ -16,3 +16,7 @@ $(function(){
$('select#branch').selectmenu({style:'popup', width:200});
$('select#tag').selectmenu({style:'popup', width:200});
});
function updatePage(){
$.ajax({type: "GET", url: location.href, dataType: "script"});
}
$(document).ready(function(){
$("#snippets-table .snippet").live('click', function(e){
if(e.target.nodeName != "A" && e.target.nodeName != "INPUT") {
location.href = $(this).attr("url");
e.stopPropagation();
return false;
}
});
});
......@@ -22,8 +22,8 @@ td.linenos{
.highlight{
background:none;
padding:10px 0px 0px 0;
margin-left:10px;
padding:10px 0px 0px 10px;
margin-left:0px;
}
.highlight pre{
}
......@@ -43,7 +43,7 @@ td.linenos {
}
td.code .highlight {
overflow-x: scroll;
overflow: auto;
}
table.highlighttable pre{
padding:0;
......
......@@ -310,6 +310,7 @@ input.ssh_project_url {
}
#projects-list .project,
#snippets-table .snippet,
#issues-table .issue{
cursor:pointer;
......@@ -360,6 +361,8 @@ input.ssh_project_url {
.user_new,
.edit_user,
.new_project,
.new_snippet,
.edit_snippet,
.edit_project {
input[type='text'],
input[type='email'],
......@@ -488,8 +491,14 @@ tbody tr:nth-child(2n) td, tbody tr.even td {
background: white;
}
p {
margin-bottom: 3px;
font-size: 12px;
margin-bottom: 4px;
font-size: 13px;
color:#111;
}
}
cite {
&.ago {
color:#666;
}
}
}
......@@ -512,7 +521,7 @@ tbody tr:nth-child(2n) td, tbody tr.even td {
}
.note_content {
float:left;
width:750px;
width:650px;
}
.issue_notes {
......@@ -549,3 +558,83 @@ tbody tr:nth-child(2n) td, tbody tr.even td {
height: 12px;
padding: 10px;
}
.recent_message_parent {
img {
padding-right:10px;
}
float: left;
margin: 0 20px 20px 0px;
padding: 5px 0px;;
width: 420px;
&.dash_wall{
border-bottom: 2px solid orange;
span {
background: orange;
color:black;
}
}
&.dash_issue{
border-bottom: 2px solid #ffbbbb;
span {
background: #ffbbbb;
}
}
&.dash_commit{
border-bottom: 2px solid #bbbbff;
span{
background: #bbbbff;
}
}
&.dash_snippet{
border-bottom: 2px solid #bbffbb;
span{
background: #bbffbb;
}
}
span{
border: 1px solid #aaa;
color:black;
padding:1px 4px;
}
h4 {
margin-bottom:3px;
}
}
.commit,
.message,
#notes-list{
.author {
background: #eaeaea;
color: #333;
border: 1px solid #aaa;
padding:1px 2px;
margin-right:5px;
}
}
/* Note textare */
#note_note {
height:100px;
width:97%;
font-size:14px;
}
.wall_page {
#note_note {
height:25px;
}
.attach_holder {
display:none;
}
}
// Place all the styles related to the Snippets controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
......@@ -27,11 +27,15 @@ class ApplicationController < ActionController::Base
end
def authenticate_admin!
return redirect_to(new_user_session_path) unless current_user.is_admin?
return render_404 unless current_user.is_admin?
end
def authorize_project!(action)
return redirect_to(new_user_session_path) unless can?(current_user, action, project)
return render_404 unless can?(current_user, action, project)
end
def access_denied!
render_404
end
def method_missing(method_sym, *arguments, &block)
......
class IssuesController < ApplicationController
before_filter :authenticate_user!
before_filter :project
before_filter :issue, :only => [:edit, :update, :destroy, :show]
# Authorize
before_filter :add_project_abilities
before_filter :authorize_read_issue!
before_filter :authorize_write_issue!, :only => [:new, :create, :close, :edit, :update, :sort]
before_filter :authorize_admin_issue!, :only => [:destroy]
respond_to :js
......@@ -30,12 +30,10 @@ class IssuesController < ApplicationController
end
def edit
@issue = @project.issues.find(params[:id])
respond_with(@issue)
end
def show
@issue = @project.issues.find(params[:id])
@notes = @issue.notes
@note = @project.notes.new(:noteable => @issue)
end
......@@ -51,7 +49,6 @@ class IssuesController < ApplicationController
end
def update
@issue = @project.issues.find(params[:id])
@issue.update_attributes(params[:issue])
respond_to do |format|
......@@ -62,7 +59,8 @@ class IssuesController < ApplicationController
def destroy
@issue = @project.issues.find(params[:id])
return access_denied! unless can?(current_user, :admin_issue, @issue)
@issue.destroy
respond_to do |format|
......@@ -79,4 +77,10 @@ class IssuesController < ApplicationController
render :nothing => true
end
protected
def issue
@issue ||= @project.issues.find(params[:id])
end
end
......@@ -4,7 +4,6 @@ class NotesController < ApplicationController
# Authorize
before_filter :add_project_abilities
before_filter :authorize_write_note!, :only => [:create]
before_filter :authorize_admin_note!, :only => [:destroy]
respond_to :js
......@@ -25,6 +24,9 @@ class NotesController < ApplicationController
def destroy
@note = @project.notes.find(params[:id])
return access_denied! unless can?(current_user, :admin_note, @note)
@note.destroy
respond_to do |format|
......@@ -41,6 +43,8 @@ class NotesController < ApplicationController
Notify.note_commit_email(u, @note).deliver
when "Issue" then
Notify.note_issue_email(u, @note).deliver
when "Snippet"
true
else
Notify.note_wall_email(u, @note).deliver
end
......
......@@ -3,6 +3,12 @@ class ProfileController < ApplicationController
@user = current_user
end
def social_update
@user = current_user
@user.update_attributes(params[:user])
redirect_to [:profile]
end
def password
@user = current_user
end
......
......@@ -60,14 +60,21 @@ class ProjectsController < ApplicationController
end
def show
@repo = project.repo
@commit = @repo.commits.first
@tree = @commit.tree
@tree = @tree / params[:path] if params[:path]
rescue Grit::NoSuchPathError => ex
respond_to do |format|
format.html {render "projects/empty"}
return render "projects/empty" unless @project.repo_exists?
@date = case params[:view]
when "week" then Date.today - 7.days
when "day" then Date.today
else nil
end
if @date
@date = @date.at_beginning_of_day
@commits = @project.commits_since(@date)
@messages = project.notes.since(@date).order("created_at DESC")
else
@commits = @project.fresh_commits
@messages = project.notes.fresh.limit(10)
end
end
......@@ -76,8 +83,15 @@ class ProjectsController < ApplicationController
#
def wall
@notes = @project.common_notes
@note = Note.new
@notes = @project.common_notes.order("created_at DESC")
@notes = case params[:view]
when "week" then @notes.since((Date.today - 7.days).at_beginning_of_day)
when "all" then @notes.all
when "day" then @notes.since(Date.today.at_beginning_of_day)
else @notes.fresh.limit(10)
end
end
#
......
class SnippetsController < ApplicationController
before_filter :authenticate_user!
before_filter :project
# Authorize
before_filter :add_project_abilities
before_filter :authorize_read_snippet!
before_filter :authorize_write_snippet!, :only => [:new, :create, :close, :edit, :update, :sort]
respond_to :html
def index
@snippets = @project.snippets
end
def new
@snippet = @project.snippets.new
end
def create
@snippet = @project.snippets.new(params[:snippet])
@snippet.author = current_user
@snippet.save
if @snippet.valid?
redirect_to [@project, @snippet]
else
respond_with(@snippet)
end
end
def edit
@snippet = @project.snippets.find(params[:id])
end
def update
@snippet = @project.snippets.find(params[:id])
@snippet.update_attributes(params[:snippet])
if @snippet.valid?
redirect_to [@project, @snippet]
else
respond_with(@snippet)
end
end
def show
@snippet = @project.snippets.find(params[:id])
@notes = @snippet.notes
@note = @project.notes.new(:noteable => @snippet)
end
def destroy
@snippet = @project.snippets.find(params[:id])
return access_denied! unless can?(current_user, :admin_snippet, @snippet)
@snippet.destroy
redirect_to project_snippets_path(@project)
end
end
......@@ -3,8 +3,8 @@ class TeamMembersController < ApplicationController
# Authorize
before_filter :add_project_abilities
before_filter :authorize_read_team_member!
before_filter :authorize_admin_team_member!, :only => [:new, :create, :destroy, :update]
before_filter :authorize_read_project!
before_filter :authorize_admin_project!, :only => [:new, :create, :destroy, :update]
def show
@team_member = project.users_projects.find(params[:id])
......
......@@ -53,25 +53,4 @@ module ApplicationHelper
[projects, default_nav, project_nav].flatten.to_json
end
def handle_file_type(file_name, mime_type)
if file_name =~ /(\.rb|\.ru|\.rake|Rakefile|\.gemspec|\.rbx|Gemfile)$/
:ruby
elsif file_name =~ /\.py$/
:python
elsif file_name =~ /(\.pl|\.scala|\.c|\.cpp|\.java|\.haml|\.html|\.sass|\.scss|\.xml|\.php|\.erb)$/
$1[1..-1].to_sym
elsif file_name =~ /\.js$/
:javascript
elsif file_name =~ /\.sh$/
:bash
elsif file_name =~ /\.coffee$/
:coffeescript
elsif file_name =~ /\.yml$/
:yaml
elsif file_name =~ /\.md$/
:minid
else
:text
end
end
end
......@@ -21,4 +21,13 @@ module CommitsHelper
link_to "More", project_commits_path(@project, :offset => offset.to_i + limit.to_i, :limit => limit),
:remote => true, :class => "lite_button vm", :style => "text-align:center; width:930px; ", :id => "more-commits-link"
end
# Cause some errors with trucate & encoding use this method
def truncate_commit_message(commit, size = 60)
message = commit.message
message.length > size ? (message[0..(size - 1)] + "...") : message
# if special characters occurs
rescue
commit.message
end
end
......@@ -3,4 +3,16 @@ module ProjectsHelper
cookies["project_view"] ||= "tile"
cookies["project_view"] == type ? nil : "display:none"
end
def load_note_parent(id, type, project)
case type
when "Issue" then @project.issues.find(id)
when "Commit" then @project.repo.commits(id).first
when "Snippet" then @project.snippets.find(id)
else
true
end
rescue
nil
end
end
module SnippetsHelper
end
......@@ -2,6 +2,9 @@ class Ability
def self.allowed(object, subject)
case subject.class.name
when "Project" then project_abilities(object, subject)
when "Issue" then issue_abilities(object, subject)
when "Note" then note_abilities(object, subject)
when "Snippet" then snippet_abilities(object, subject)
else []
end
end
......@@ -12,6 +15,7 @@ class Ability
rules << [
:read_project,
:read_issue,
:read_snippet,
:read_team_member,
:read_note
] if project.readers.include?(user)
......@@ -19,16 +23,35 @@ class Ability
rules << [
:write_project,
:write_issue,
:write_snippet,
:write_note
] if project.writers.include?(user)
rules << [
:admin_project,
:admin_issue,
:admin_snippet,
:admin_team_member,
:admin_note
] if project.admins.include?(user)
rules.flatten
end
class << self
[:issue, :note, :snippet].each do |name|
define_method "#{name}_abilities" do |user, subject|
if subject.author == user
[
:"read_#{name}",
:"write_#{name}",
:"admin_#{name}"
]
else
subject.respond_to?(:project) ?
project_abilities(user, subject.project) : []
end
end
end
end
end
......@@ -37,5 +37,6 @@ end
# created_at :datetime
# updated_at :datetime
# closed :boolean default(FALSE), not null
# position :integer default(0)
#
......@@ -22,6 +22,10 @@ class Note < ActiveRecord::Base
scope :common, where(:noteable_id => nil)
scope :last_week, where("created_at >= :date", :date => (Date.today - 7.days))
scope :since, lambda { |day| where("created_at >= :date", :date => (day)) }
scope :fresh, order("created_at DESC")
mount_uploader :attachment, AttachmentUploader
end
# == Schema Information
......
......@@ -7,6 +7,7 @@ class Project < ActiveRecord::Base
has_many :users_projects, :dependent => :destroy
has_many :users, :through => :users_projects
has_many :notes, :dependent => :destroy
has_many :snippets, :dependent => :destroy
validates :name,
:uniqueness => true,
......@@ -125,6 +126,34 @@ class Project < ActiveRecord::Base
end
end
def heads
@heads ||= repo.heads
end
def fresh_commits
commits = heads.map do |h|
repo.commits(h.name, 10)
end.flatten.uniq { |c| c.id }
commits.sort! do |x, y|
y.committed_date <=> x.committed_date
end
commits[0..10]
end
def commits_since(date)
commits = heads.map do |h|
repo.log(h.name, nil, :since => date)
end.flatten.uniq { |c| c.id }
commits.sort! do |x, y|
y.committed_date <=> x.committed_date
end
commits
end
def tree(fcommit, path = nil)
fcommit = commit if fcommit == :head
tree = fcommit.tree
......
class Snippet < ActiveRecord::Base
include Utils::Colorize
belongs_to :project
belongs_to :author, :class_name => "User"
has_many :notes, :as => :noteable
attr_protected :author, :author_id, :project, :project_id
validates_presence_of :project_id