fredit 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,62 +1,86 @@
1
- require 'shellwords'
1
+ require 'git'
2
2
 
3
3
  class FreditController < ::ApplicationController
4
4
 
5
- layout false
5
+ layout 'fredit'
6
+
7
+ before_filter :load_git
6
8
 
7
9
  CSS_DIR = Rails.root + 'public/stylesheets/**/*.css'
8
10
  JS_DIR = Rails.root + 'public/javascripts/**/*.js'
9
11
 
10
- def index
11
- @path ||= secure_path(params[:file] || params[:new_path] || Fredit.editables[:views].first)
12
- if !File.size?(@path)
13
- File.open(@path, 'w') {|f| f.write("REPLACE WITH CONTENT")}
14
- end
12
+ def show
13
+ @path ||= secure_path(params[:file] || Fredit.editables[:views].first)
14
+ load_git_log
15
15
  @source = File.read(Rails.root + @path)
16
16
  end
17
17
 
18
18
  def update
19
19
  @path = secure_path params[:file_path]
20
20
 
21
- edit_msg = !params[:edit_message].blank? ? Shellwords.shellescape(params[:edit_message].gsub(/["']/, '')) : "unspecified edit"
21
+ edit_msg = !params[:edit_message].blank? ? params[:edit_message] : "unspecified edit"
22
+ edit_msg_file = Tempfile.new('commit-message')
23
+ t.write(edit_msg) # we write this message to a file to protect against shell injection
24
+ t.cloase
25
+
26
+ session[:commit_author] = (params[:commit_author] || '')
27
+ # cleanup any shell injection attempt characters
28
+ author = session[:commit_author].gsub(/[^\w@<>. ]/, '')
22
29
 
23
- session[:commit_author] = (params[:commit_author] || '').gsub(/['"]/, '')
24
- author = session[:commit_author]
25
30
  if session[:commit_author].blank?
26
31
  flash.now[:notice] = "Edited By must not be blank"
27
32
  @source = params[:source]
28
- render :action => 'index'
33
+ render :action => 'show'
29
34
  return
30
35
  end
31
36
 
32
37
  if params[:commit] =~ /delete/i
33
38
  `git rm #@path`
34
39
  flash[:notice] = "#@path deleted"
35
- res = system %Q|git commit --author='#{author}' -m '#{edit_msg}' #{@path}|
40
+ res = system %Q|git commit --author='#{author}' --file '#{edit_msg_file}' #{@path}|
36
41
  @path = nil
37
42
  else
38
43
  n = params[:source].gsub(/\r\n/, "\n")
39
44
  File.open(@path, 'w') {|f| f.write(n)}
40
45
  system %Q|git add #{@path}|
41
46
  flash[:notice] = "#@path updated"
42
- res = system %Q|git commit --author='#{author}' -m '#{edit_msg}' #{@path}|
47
+ res = system %Q|git commit --author='#{author}' --file '#{edit_msg_file}' #{@path}|
43
48
  end
44
49
  if res == false
45
50
  flash[:notice] = "Something went wrong with git. Make sure you changed something and filled in required fields."
46
51
  end
47
- params.delete(:source)
48
-
49
- redirect_to :action => 'index', :file => @path
52
+ redirect_to fredit_path(:file => @path)
50
53
  end
51
54
 
52
55
  def create
53
- @path = secure_path params[:file]
56
+ @path = secure_path params[:new_file]
54
57
  FileUtils::mkdir_p File.dirname(@path)
55
58
  File.open(@path, 'w') {|f| f.write("REPLACE WITH CONTENT")}
59
+ flash[:notice] = "Created new file: #@path"
60
+ redirect_to fredit_path(:file => @path)
61
+ end
62
+
63
+ def revision
64
+ @path = secure_path params[:file]
65
+ load_git_log
66
+ @sha = params[:sha].gsub(/[^0-9a-z]/, '') # shell injection protection
67
+ @git_object = @git.object(@sha)
68
+ @diff = `git show #{@sha}`
56
69
  end
57
70
 
58
71
  private
59
72
 
73
+ def load_git
74
+ @git = Git.init Rails.root.to_s
75
+ end
76
+
77
+ def load_git_log
78
+ @git_log = @git.log(20).object(@path).to_a
79
+ rescue Git::GitExecuteError
80
+ @git_log = []
81
+ flash[:notice] = "You need to initialize a git repository or add this file to the path"
82
+ end
83
+
60
84
  def secure_path(path)
61
85
  path2 = File.expand_path(path.to_s)
62
86
  if path2.index(Rails.root.to_s) != 0
@@ -0,0 +1,36 @@
1
+ <textarea name='source'><%= @diff %></textarea>
2
+
3
+ <table>
4
+ <tr>
5
+ <td>File:</td>
6
+ <td>
7
+ <%= link_to @path, fredit_path(:file => @path) %>
8
+ </td>
9
+ </tr>
10
+ <tr>
11
+ <td>Commit:</td>
12
+ <td>
13
+ <%= @sha %>
14
+ </td>
15
+ </tr>
16
+ <tr>
17
+ <td>Edited By:</td>
18
+ <td>
19
+ <%= @git_object.author.name %>
20
+ </td>
21
+ </tr>
22
+ <tr>
23
+ <td>Date:</td>
24
+ <td>
25
+ <%= @git_object.date %>
26
+ </td>
27
+ </tr>
28
+ <tr>
29
+ <td>Log Message:</td>
30
+ <td>
31
+ <%= @git_object.message %>
32
+ </td>
33
+ </tr>
34
+ </table>
35
+
36
+
@@ -0,0 +1,55 @@
1
+
2
+ <form action="<%= fredit_path %>" method="post">
3
+ <input name="_method" type="hidden" value="put" />
4
+ <input name="utf8" type="hidden" value="&#x2713;" />
5
+ <input type="hidden" name="file" value="<%=@path%>"/>
6
+ <textarea name='source'><%= @source %></textarea>
7
+
8
+ <table>
9
+ <tr>
10
+ <td>File:</td>
11
+ <td>
12
+ <%= @path %>
13
+ </td>
14
+ </tr>
15
+ <tr>
16
+ <td>Edit Message (optional):</td>
17
+ <td>
18
+ <input type="text" name="edit_message" value="" placeholder="Describe the edit " size="50"/>
19
+ </td>
20
+ </tr>
21
+ <tr>
22
+ <td>Edited By (required): </td>
23
+ <td>
24
+ <input type="text" name="commit_author" value="<%=session[:commit_author]%>" placeholder="Your Name <yourname@example.com>" size="50"/>
25
+ </td>
26
+ </tr>
27
+ <tr>
28
+ <td>Action:</td>
29
+ <td>
30
+ <input hidden="text" name="file_path" value="<%=@path%>" />
31
+ <input type="submit" name="commit" value="update this file"/>
32
+ <input id="deleteBtn" type="submit" name="commit" value="delete this file"/>
33
+ </td>
34
+ </tr>
35
+ </table>
36
+ </form>
37
+
38
+ <form id="createFileForm" action="<%= fredit_path %>" method="post">
39
+ <table>
40
+ <tr>
41
+ <td>Create file at path:</td>
42
+ <td>
43
+ <input type="text" name="new_file" value="" placeholder="<%=Fredit.editables[:views].first%>" size="50"/>
44
+ </td>
45
+ </tr>
46
+ <tr>
47
+ <td>Action:</td>
48
+ <td>
49
+ <input type="submit" name="commit" value="create file"/>
50
+ </td>
51
+ </tr>
52
+ </table>
53
+ </form>
54
+
55
+
@@ -0,0 +1,130 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%=@path%></title>
5
+ <%= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js' %>
6
+ <style type="text/css">
7
+
8
+ body {
9
+ padding-top:0;
10
+ padding-bottom: 30px;
11
+ font-family: Verdana, Helvetica, sans;
12
+ font-size: 12px;
13
+ margin-left: 40px;
14
+ width: 92%;
15
+ background-color: #EDEDED;
16
+ }
17
+ h1#appName {
18
+ margin:0;
19
+ padding:0;
20
+ display: inline;
21
+ }
22
+ h1#appName em {
23
+ font-size: smaller;
24
+ }
25
+ section#editor {
26
+ float: left;
27
+ width: 74%;
28
+ }
29
+ section#git {
30
+ float: left;
31
+ width: 23%;
32
+ padding-left: 2%;
33
+ }
34
+ section#git h3 {
35
+ margin-top: 0;
36
+ margin-bottom: 0.7em;
37
+ }
38
+ section#git ul {
39
+ padding-left: 0;
40
+ list-style-type: none;
41
+ }
42
+
43
+ textarea {
44
+ width: 100%;
45
+ height: 500px;
46
+ font-family: monospace;
47
+ }
48
+ #notice {
49
+ background-color: yellow;
50
+ }
51
+ input#deleteBtn {
52
+ float:right;
53
+ }
54
+ input[type=text] {
55
+ width: 100%;
56
+ }
57
+ table {
58
+ width: 100%
59
+ }
60
+ form#fileSelector {
61
+ float:right;
62
+ }
63
+ form#createFileForm {
64
+ border-top: 1px solid #CCC;
65
+ margin-top: 10px;
66
+ padding-top: 10px;
67
+ }
68
+
69
+ </style>
70
+ </head>
71
+ <body>
72
+
73
+ <% if flash[:notice] %>
74
+ <div id="notice"><%= flash[:notice] %></div>
75
+ <% end %>
76
+
77
+ <section id="editor">
78
+ <h1 id="appName">fredit <em>front-end edit</em></h1>
79
+ <form id="fileSelector" action="<%=fredit_path%>">
80
+ <select id="fileSelectorDropDown" name="file">
81
+ <% Fredit.editables.each_pair do |k, v| %>
82
+ <optgroup label="<%= k %>">
83
+ <% v.each do |path| %>
84
+ <option value="<%= path %>" <%= @path == path ? 'selected=\"selected\"' : nil %>><%= Fredit.link(path)%></li>
85
+ <% end %>
86
+ </optgroup>
87
+ <% end %>
88
+ </select>
89
+ <input type="submit" id="changeFileBtn" value="change file"/>
90
+ </form>
91
+ <script>
92
+ $(document).ready(function() {
93
+ $('#fileSelectorDropDown').bind('change', function() {
94
+ $('#fileSelector').submit();
95
+ });
96
+ $('#changeFileBtn').hide();
97
+ });
98
+ </script>
99
+
100
+ <%= yield %>
101
+ </section>
102
+
103
+ <section id="git">
104
+ <nav>
105
+ <h3>git</h3>
106
+ <div id="currentBranch">
107
+ Current branch:
108
+ <strong><%= @git.current_branch %></strong>
109
+ </div>
110
+
111
+ <h4>Recent edits</h4>
112
+
113
+ <ul>
114
+ <% @git_log.each do |commit| %>
115
+ <li>
116
+ <%= link_to "#{commit.date.strftime('%m-%d-%y')}",
117
+ fredit_revision_path(:sha => commit.sha, :file => @path),
118
+ :title => commit.message %>
119
+ <%= commit.author && commit.author.name %>:
120
+ <%= truncate(commit.message, :length => 15) %>
121
+ </li>
122
+ <% end %>
123
+ </ul>
124
+
125
+ </nav>
126
+ </section>
127
+
128
+ </body>
129
+ </html>
130
+
data/config/routes.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  Rails.application.routes.draw do
2
- get "/fredit" => "fredit#index"
3
- post "/fredit/update" => "fredit#update"
2
+ get 'fredit/revision' => "fredit#revision"
3
+ get 'fredit' => "fredit#show"
4
+ put 'fredit' => "fredit#update"
5
+ post 'fredit' => "fredit#create"
4
6
  end
5
7
 
data/lib/fredit.rb CHANGED
@@ -1,4 +1,8 @@
1
- require 'fredit/erb'
1
+ if Rails.version < '3.1.0'
2
+ require 'fredit/erb'
3
+ else
4
+ require 'fredit/erb31'
5
+ end
2
6
  require 'uri'
3
7
 
4
8
  module Fredit
data/lib/fredit/erb.rb CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  module ActionView
3
2
  class Template
4
3
  module Handlers
@@ -0,0 +1,50 @@
1
+ module ActionView
2
+ class Template
3
+ module Handlers
4
+ class ERB
5
+ def call(template)
6
+ if template.source.encoding_aware?
7
+ # First, convert to BINARY, so in case the encoding is
8
+ # wrong, we can still find an encoding tag
9
+ # (<%# encoding %>) inside the String using a regular
10
+ # expression
11
+ template_source = template.source.dup.force_encoding("BINARY")
12
+
13
+ erb = template_source.gsub(ENCODING_TAG, '')
14
+ encoding = $2
15
+
16
+ erb.force_encoding valid_encoding(template.source.dup, encoding)
17
+
18
+ # Always make sure we return a String in the default_internal
19
+ erb.encode!
20
+ else
21
+ erb = template.source.dup
22
+ end
23
+
24
+ # begin Fredit patch
25
+
26
+ if Fredit.template_editable?(template)
27
+ source_file = Fredit.rel_path template.identifier
28
+ edit_link = "<div style='color:red'>#{Fredit.link(source_file)}</div> "
29
+ if erb =~ /^\s*<!DOCTYPE/ && erb =~ /<body[^>]*>/
30
+ erb = erb.sub(/<body[^>]*>/, '\&' + edit_link)
31
+ else
32
+ erb = edit_link + erb
33
+ end
34
+ end
35
+
36
+ # end Fredit patch
37
+
38
+
39
+ self.class.erb_implementation.new(
40
+ erb,
41
+ :trim => (self.class.erb_trim_mode == "-")
42
+ ).src
43
+
44
+ end
45
+
46
+ end
47
+ end
48
+ end
49
+ end
50
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fredit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,18 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
  date: 2011-10-25 00:00:00.000000000Z
13
- dependencies: []
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: git
16
+ requirement: &82978850 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *82978850
14
25
  description: Edit the front end of Rails apps through the browser.
15
26
  email:
16
27
  - dhchoi@gmail.com
@@ -18,10 +29,12 @@ executables: []
18
29
  extensions: []
19
30
  extra_rdoc_files: []
20
31
  files:
21
- - app/views/fredit/index.html.erb
22
- - app/views/fredit/layout.html.erb
32
+ - app/views/layouts/fredit.html.erb
33
+ - app/views/fredit/show.html.erb
34
+ - app/views/fredit/revision.html.erb
23
35
  - app/controllers/fredit_controller.rb
24
36
  - lib/fredit.rb
37
+ - lib/fredit/erb31.rb
25
38
  - lib/fredit/erb.rb
26
39
  - lib/fredit/engine.rb
27
40
  - config/routes.rb
@@ -43,7 +56,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
43
56
  version: '0'
44
57
  segments:
45
58
  - 0
46
- hash: -150563923
59
+ hash: 122408225
47
60
  required_rubygems_version: !ruby/object:Gem::Requirement
48
61
  none: false
49
62
  requirements:
@@ -52,11 +65,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
52
65
  version: '0'
53
66
  segments:
54
67
  - 0
55
- hash: -150563923
68
+ hash: 122408225
56
69
  requirements: []
57
70
  rubyforge_project:
58
71
  rubygems_version: 1.8.11
59
72
  signing_key:
60
73
  specification_version: 3
61
- summary: fredit 0.1.0
74
+ summary: fredit 0.1.2
62
75
  test_files: []
@@ -1,121 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title><%=@path%></title>
5
- <style>
6
-
7
- body {
8
- padding-top:0;
9
- padding-bottom: 30px;
10
- font-family: Verdana, Helvetica, sans;
11
- font-size: 12px;
12
- margin-left: 40px;
13
- width: 80%;
14
- background-color: #EDEDED;
15
- }
16
- h1 {
17
- margin:0;
18
- padding:0;
19
- float:left;
20
- }
21
- h1 em {
22
- font-size: smaller;
23
- }
24
- textarea {
25
- width: 100%;
26
- height: 500px;
27
- font-family: monospace;
28
- }
29
- #notice {
30
- background-color: yellow;
31
- }
32
- input#deleteBtn {
33
- float:right;
34
- }
35
- input[type=text] {
36
- width: 100%;
37
- }
38
- table {
39
- width: 100%
40
- }
41
- form#fileSelector {
42
- float:right;
43
- }
44
- form#createFileForm {
45
- border-top: 1px solid #CCC;
46
- margin-top: 10px;
47
- padding-top: 10px;
48
- }
49
-
50
- </style>
51
- </head>
52
- <body>
53
-
54
- <% if flash[:notice] %>
55
- <div id="notice"><%= flash[:notice] %></div>
56
- <% end %>
57
-
58
- <h1>fredit <em>front-end edit</em></h1>
59
-
60
- <form id="fileSelector" action="<%=url_for%>">
61
- <select name="file">
62
- <% Fredit.editables.each_pair do |k, v| %>
63
- <optgroup label="<%= k %>">
64
- <% v.each do |path| %>
65
- <option value="<%= path %>" <%= @path == path ? 'selected=\"selected\"' : nil %>><%= Fredit.link(path)%></li>
66
- <% end %>
67
- </optgroup>
68
- <% end %>
69
- </select>
70
- <input type="submit" value="change file"/>
71
- </form>
72
-
73
- <form action="<%=url_for(:action => :update)%>" method="post">
74
- <input type="hidden" name="file" value="<%=@path%>"/>
75
- <textarea name='source'><%= @source %></textarea>
76
-
77
- <table>
78
- <tr>
79
- <td>Edit Message (optional):</td>
80
- <td>
81
- <input type="text" name="edit_message" value="" placeholder="Describe the edit " size="50"/>
82
- </td>
83
- </tr>
84
- <tr>
85
- <td>Edited By (required): </td>
86
- <td>
87
- <input type="text" name="commit_author" value="<%=session[:commit_author]%>" placeholder="Your Name <yourname@example.com>" size="50"/>
88
- </td>
89
- </tr>
90
- <tr>
91
- <td>Action:</td>
92
- <td>
93
- <input hidden="text" name="file_path" value="<%=@path%>" />
94
- <input type="submit" name="commit" value="update this file"/>
95
- <input id="deleteBtn" type="submit" name="commit" value="delete this file"/>
96
- </td>
97
- </tr>
98
- </table>
99
- </form>
100
-
101
- <form id="createFileForm" action="<%=url_for%>" method="get">
102
- <table>
103
- <tr>
104
- <td>Create file at path:</td>
105
- <td>
106
- <input type="text" name="new_path" value="" placeholder="<%=Fredit.editables[:views].first%>" size="50"/>
107
- </td>
108
- </tr>
109
- <tr>
110
- <td>Action:</td>
111
- <td>
112
- <input type="submit" name="commit" value="create file"/>
113
- </td>
114
- </tr>
115
- </table>
116
- </form>
117
-
118
-
119
-
120
- </body>
121
- </html>
@@ -1,16 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>test</title>
5
- <style>
6
-
7
- textarea {
8
- width: 100%;
9
- height: 400px;
10
- }
11
- </style>
12
- </head>
13
- <body>
14
- <%= yield %>
15
- </body>
16
- </html>