From 74d401d087803efa87b724a0d245b94a33f0bea6 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Wed, 8 Feb 2012 21:51:30 +0400 Subject: [PATCH] [issue #133] Writed draft of web editing. --- app/controllers/git/blobs_controller.rb | 8 ++++ app/helpers/git_helper.rb | 8 ++++ app/models/git/repository.rb | 54 ++++++++++++++++++++++++- app/views/git/blobs/_editor.html.haml | 39 ++++++++++++++++++ app/views/git/blobs/edit.html.haml | 20 +++++++++ app/views/git/blobs/show.html.haml | 2 +- config/routes.rb | 10 ++++- 7 files changed, 136 insertions(+), 5 deletions(-) create mode 100644 app/views/git/blobs/_editor.html.haml create mode 100644 app/views/git/blobs/edit.html.haml diff --git a/app/controllers/git/blobs_controller.rb b/app/controllers/git/blobs_controller.rb index 0bfe6b4b4..09bd74103 100644 --- a/app/controllers/git/blobs_controller.rb +++ b/app/controllers/git/blobs_controller.rb @@ -16,6 +16,14 @@ class Git::BlobsController < Git::BaseController end end + def edit + end + + def update + @git_repository.update_file(params[:path], params[:content], :message => params[:message], :actor => current_user, :ref => @treeish) + redirect_to :action => :show + end + def blame @blame = Grit::Blob.blame(@git_repository.repo, @commit.try(:id), @path) end diff --git a/app/helpers/git_helper.rb b/app/helpers/git_helper.rb index f302b5aed..fef549d7e 100644 --- a/app/helpers/git_helper.rb +++ b/app/helpers/git_helper.rb @@ -29,6 +29,14 @@ module GitHelper res.encode_to_default.html_safe end + def blob_file_path + if @commit_hash.present? + blob_commit_path(@project, @commit_hash, @path) + else + blob_path(@project, @treeish, @path) + end + end + def render_line_numbers(n) res = "" 1.upto(n) {|i| res += "#{i}\n" } diff --git a/app/models/git/repository.rb b/app/models/git/repository.rb index 4ed82b210..6b7c88661 100644 --- a/app/models/git/repository.rb +++ b/app/models/git/repository.rb @@ -2,16 +2,17 @@ class Git::Repository delegate :commits, :commit, :tree, :tags, :heads, :commit_count, :log, :branches, :to => :repo - attr_accessor :path, :name + attr_accessor :path, :name, :repo, :last_actor def initialize(path) @path = path + @update_callbacks = [] end def master commits('master', 1).first end - + def to_s name end @@ -20,6 +21,31 @@ class Git::Repository @repo ||= Grit::Repo.new(path) end + def after_update_file(&block) + @update_callbacks << block + end + + def update_file(path, data, options = {}) + ref = options[:ref].to_s || 'master' + actor = get_actor(options[:actor]) + message = options[:message] || "Updated file #{File.split(path).last}" + + # can not write to unexisted branch + return false if branches.select{|b| b.name == ref}.size != 1 + + parent = commits(ref).first + + index = repo.index + index.read_tree(parent.tree.id) + + index.add(path, data) + sha = index.commit(message, :parents => [parent], :actor => actor, :last_tree => parent.tree.id, :head => ref) + @update_callbacks.each do |cb| + cb.call(self, sha1) + end + sha + end + def self.create(path) repo = Grit::Repo.init_bare(path) repo.enable_daemon_serve @@ -38,4 +64,28 @@ class Git::Repository [commits(treeish, options[:per_page], skip), options[:page], last_page] end + # Pretty object inspection + def inspect + %Q{#} + end + + protected + + def get_actor(actor = nil) + @last_actor = case actor.class.to_s + when 'Grit::Actor' then options[:actor] + when 'Hash' then Grit::Actor.new(actor[:name], actor[:email]) + when 'String' then Grit::Actor.from_stirng(actor) + else begin + if actor.respond_to?(:name) and actor.respond_to?(:email) + Grit::Actor.new(actor.name, actor.email) + else + config = Grit::Config.new(repo) + Grit::Actor.new(config['user.name'], config['user.email']) + end + end + end + @last_actor + end + end diff --git a/app/views/git/blobs/_editor.html.haml b/app/views/git/blobs/_editor.html.haml new file mode 100644 index 000000000..7ef82f3ff --- /dev/null +++ b/app/views/git/blobs/_editor.html.haml @@ -0,0 +1,39 @@ +#gollum-editor.edit{:'data-escaped-name' => @path} + = form_tag blob_file_path, :name => 'blob-editor', :method => :put do + %fieldset#gollum-editor-fields + + = text_area_tag :content, @blob.data.encode_to_default, :id => "gollum-editor-body" + + #gollum-editor-edit-summary.singleline + = label_tag :message, t("layout.wiki.edit_commit_message"), :class => "jaws" + = text_field_tag :message, t("layout.wiki.commit_message_placeholder"), :id => "editor-commit-message-field" + + %span.jaws + %br + + = submit_tag t("layout.wiki.save_button"), :id => "gollum-editor-submit", :title => t("layout.wiki.save_changes") + = link_to t("layout.cancel"), blob_file_path, :class => 'minibutton', :id => 'gollum-editor-preview' + +:javascript + (function($) { + $.Editor = function() { + $.Editor.Placeholder.add($('#gollum-editor-edit-summary input')); + $('#gollum-editor form[name="blob-editor"]').submit(function( e ) { + e.preventDefault(); + $.Editor.Placeholder.clearAll(); + //debug('submitting'); + $(this).unbind('submit'); + $(this).submit(); + }); + }; + + $.Editor.Placeholder = $.GollumPlaceholder; + + $.Editor(); + })(jQuery); + +- content_for :javascripts do + = javascript_include_tag 'gollum/gollum.placeholder.js' + +- content_for :stylesheets do + = stylesheet_link_tag 'gollum/editor.css' diff --git a/app/views/git/blobs/edit.html.haml b/app/views/git/blobs/edit.html.haml new file mode 100644 index 000000000..0452cc04d --- /dev/null +++ b/app/views/git/blobs/edit.html.haml @@ -0,0 +1,20 @@ +.block + = render :partial => "git/shared/navigation" + + = render :partial => "git/shared/info" + +- if @commit + .block + .content + .inner + = render :partial => "git/commits/commits", :object => [@commit] + +.block + .content + .inner + %h3 #{render_path} (#{@blob.mime_type}) + + = render :partial => 'editor' + +- content_for :sidebar, render(:partial => 'git/shared/sidebar') + diff --git a/app/views/git/blobs/show.html.haml b/app/views/git/blobs/show.html.haml index 43127ac7e..95ba637a9 100644 --- a/app/views/git/blobs/show.html.haml +++ b/app/views/git/blobs/show.html.haml @@ -21,7 +21,7 @@ - if @commit_hash #{link_to "Raw", raw_commit_path(@project, @commit_hash, @path)} #{link_to "Blame", blame_commit_path(@project, @commit_hash, @path)} #{link_to "History", commits_path(@project, @treeish, @path)} - else - #{link_to "Raw", raw_path(@project, @treeish, @path)} #{link_to "Blame", blame_path(@project, @treeish, @path)} #{link_to "History", commits_path(@project, @treeish, @path)} + #{link_to(t("edit"), edit_blob_path(@project, @treeish, @path)) if choose_render_way(@blob) == :text} #{link_to "Raw", raw_path(@project, @treeish, @path)} #{link_to "Blame", blame_path(@project, @treeish, @path)} #{link_to "History", commits_path(@project, @treeish, @path)} .clear - case choose_render_way(@blob) - when :image diff --git a/config/routes.rb b/config/routes.rb index c26020d1e..18417db60 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -179,12 +179,18 @@ Rosa::Application.routes.draw do match '/projects/:project_id/git/commit/:commit_id/comments/:id(.:format)', :controller => "comments", :action => :update, :as => :project_commit_comment, :via => :put match '/projects/:project_id/git/commit/:commit_id/comments/:id(.:format)', :controller => "comments", :action => :destroy, :via => :delete match '/projects/:project_id/git/commit/:commit_id/comments(.:format)', :controller => "comments", :action => :create, :as => :project_commit_comments, :via => :post + # Commits subscribe match '/projects/:project_id/git/commit/:commit_id/subscribe', :controller => "commit_subscribes", :action => :create, :defaults => { :format => :html }, :as => :subscribe_commit, :via => :post match '/projects/:project_id/git/commit/:commit_id/unsubscribe', :controller => "commit_subscribes", :action => :destroy, :defaults => { :format => :html }, :as => :unsubscribe_commit, :via => :delete + + # Editing files + match '/projects/:project_id/git/blob/:treeish/*path/edit', :controller => "git/blobs", :action => :edit, :treeish => /[0-9a-zA-Z_.\-]*/, :defaults => { :treeish => :master }, :as => :edit_blob, :via => :get + match '/projects/:project_id/git/blob/:treeish/*path', :controller => "git/blobs", :action => :update, :treeish => /[0-9a-zA-Z_.\-]*/, :defaults => { :treeish => :master }, :via => :put + # Blobs - match '/projects/:project_id/git/blob/:treeish/*path', :controller => "git/blobs", :action => :show, :treeish => /[0-9a-zA-Z_.\-]*/, :defaults => { :treeish => :master }, :as => :blob - match '/projects/:project_id/git/commit/blob/:commit_hash/*path', :controller => "git/blobs", :action => :show, :project_name => /[0-9a-zA-Z_.\-]*/, :as => :blob_commit + match '/projects/:project_id/git/blob/:treeish/*path', :controller => "git/blobs", :action => :show, :treeish => /[0-9a-zA-Z_.\-]*/, :defaults => { :treeish => :master }, :as => :blob, :via => :get + match '/projects/:project_id/git/commit/blob/:commit_hash/*path', :controller => "git/blobs", :action => :show, :project_id => /[0-9a-zA-Z_.\-]*/, :as => :blob_commit, :via => :get # Blame match '/projects/:project_id/git/blame/:treeish/*path', :controller => "git/blobs", :action => :blame, :treeish => /[0-9a-zA-Z_.\-]*/, :defaults => { :treeish => :master }, :as => :blame