rails-wiki 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +55 -0
- data/Rakefile +37 -0
- data/app/assets/javascripts/inject.js +34 -0
- data/app/assets/javascripts/wiki/application.js +13 -0
- data/app/assets/stylesheets/wiki/application.css +15 -0
- data/app/controllers/wiki/application_controller.rb +33 -0
- data/app/controllers/wiki/pages_controller.rb +80 -0
- data/app/helpers/wiki/application_helper.rb +4 -0
- data/app/helpers/wiki/wiki_helper.rb +8 -0
- data/app/models/wiki/attachment.rb +116 -0
- data/app/models/wiki/page.rb +213 -0
- data/app/models/wiki/wiki.rb +194 -0
- data/app/views/layouts/application.html.erb +14 -0
- data/app/views/layouts/wiki.html.erb +19 -0
- data/app/views/wiki/_change.erb +21 -0
- data/app/views/wiki/_search.erb +4 -0
- data/app/views/wiki/pages/edit.html.erb +69 -0
- data/app/views/wiki/pages/index.html.erb +16 -0
- data/app/views/wiki/pages/log.html.erb +29 -0
- data/app/views/wiki/pages/show.html.erb +50 -0
- data/config/initializers/wiki.rb +35 -0
- data/config/routes.rb +16 -0
- data/lib/frontmatter.rb +23 -0
- data/lib/markdown.rb +24 -0
- data/lib/rails-wiki.rb +18 -0
- data/lib/tasks/wiki_tasks.rake +4 -0
- data/lib/wiki/engine.rb +10 -0
- data/lib/wiki/version.rb +3 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +16 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/models/user.rb +11 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +29 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +23 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +39 -0
- data/test/dummy/config/environments/production.rb +77 -0
- data/test/dummy/config/environments/test.rb +42 -0
- data/test/dummy/config/initializers/assets.rb +11 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +4 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/db/wiki/test.md +1 -0
- data/test/dummy/db/wiki/test/brown-forward.jpg +0 -0
- data/test/dummy/log/development.log +1558 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/20sgF5rnRshHxz-s4EBzqr6J28hCEioHDZq4UwSklVg.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/2c3DnJIoxPn2b4vs5wqFWgOX0nJESf5SGAUi9N58_9o.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/3CXqY8DyRTsJJYP9iYJaaQRmpXDbd-MFR1m4pug2GnQ.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/3RqPYAE8n3lRHkprA7M3_eFnzLV5PF6FMwwk-fs_ieM.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/5Lly_CA8DZvPhQV2jDQx-Y6P_y3Ygra9t5jfSlGhHDA.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/BPtu96YPU5tNXsZRFA9WtMIergTFfHMuhAG3ON7DdJY.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/D0X36t9hc6V_oaygIyRL41fwhkF3u9Lw12FETkPMVoc.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/GtnQFUKxR1hZ540gdO9116uyLq4JfA-QB7ZsLJwvlj0.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/HiLFBQupKg3TaAuqwWTIVzukgysleTkF1bjaEaIODS0.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/JZuS80RuzB2Cuqgdj4m_cnDrAKe36_z_v5Ty_dPoIJ4.cache +3 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/OI6uxGcnsKavdWTtwDAasU3wPx8QXhzBgV0X2n1KjMQ.cache +3 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/X6P11z9IhRL9BK1a0t3QcW0nzXwZKzz50d35fpmMDbQ.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/YzlRBEEf9MMtDMXOU1Dy6zoeRsaAZSXIUSZmXxVflT0.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/h0IIenP5nZ0YCtFDIHLHyp9pvsOLSDEu6ATiy3gr5D0.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/hOPmvE7Kf6eW1WQC0bUXD7G5V_zrmprQYp0Ovw03Cng.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/hPk5G_BGOYjelHgOl4_2QEgvC6YnAVRQzTyN1dBvBAE.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/hZi1k6tpxxCGYxRe7zY74ItcOI8gZrREOpGuA8JSpGg.cache +3 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/hz0b1Jdsh_JFLZIiQe7zAkicSerKslNSllnkeXXp_04.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/nAoWwNAloHngS8ny7fZE5G4uUShw8tjgvVMkDMvMkpg.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/pEhaat2KBd5SrT7szC_8R1_6hK17FTpvoRFkmCRSD3M.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/qZPgqsYHITlAKR9bPIGwt2SSzDuKpMUUkQrEZb2MkMg.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/rG7CS4nu-OV8bgDR74JP3ukGDdcMYoC_w7V0TMphk04.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/z-qEGw9bb3jqMEbMPC02VNSESIylpz0Pri2mSnoVNv8.cache +1 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/test_helper.rb +20 -0
- data/test/wiki_test.rb +7 -0
- metadata +256 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: aaa5b76e359711bd8dc4aa0e183906b335bce16d
|
4
|
+
data.tar.gz: f3c24e3ec96ae567912750f402331420e12ecb7a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 82b49289f36a9d89d5df6ca1f4e740b9761c9c2fe32a0a745124e657a3738b68f9075f6f9c53ec966e34784773700486c527c9a5528dc59133ba6e00b31ff590
|
7
|
+
data.tar.gz: 7d859845c6c6f10347cdef24afca2658208e6a46e1b85a3b41effbd6b698f95f2e48ec807a695bb7ec06cbc903a01cad2d4704841ad5c351299d6080d803fa7f
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2015 Hans Gerwitz
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# Rails Wiki
|
2
|
+
|
3
|
+
A small Rails engine that provides a git-based Markdown wiki.
|
4
|
+
|
5
|
+
WARNING: this has been abstracted from a proprietary tool, and so is poorly documented and lacks a standalone test suite. It would be premature to include it as a blind dependency.
|
6
|
+
|
7
|
+
## How it Works
|
8
|
+
|
9
|
+
Rails Wiki is based on [gollum-lib](https://github.com/gollum/gollum-lib). None of [Gollum](https://github.com/gollum/gollum/wiki)'s layout (e.g. sidebars, headers, footers) are implemented, and a many of the text filters (e.g. macros, code, diagrams) have been disabled. Also unlike Gollum, the hierarchy of pages is considered meaningful.
|
10
|
+
|
11
|
+
The storage structure will be familiar to users of Middleman or Jekyll. Each page is an `.md` file with YAML frontmatter for metadata. Other files are treated as attachments to the page associated with their containing directory.
|
12
|
+
|
13
|
+
All storage is via a local Git repository. Optionally, a remote can be specified and changes will be pushed to it.
|
14
|
+
|
15
|
+
_TODO: review and document remote behavior_
|
16
|
+
|
17
|
+
## Installation
|
18
|
+
|
19
|
+
Add Rails Wiki to your Gemfile
|
20
|
+
|
21
|
+
gem 'rails-wiki'
|
22
|
+
|
23
|
+
Your application controller needs to provide two methods:
|
24
|
+
|
25
|
+
- `auth_required` is called on every request
|
26
|
+
- `current_user` returns a _user object_
|
27
|
+
|
28
|
+
The user object must response to `.name` and `.email` with string values.
|
29
|
+
|
30
|
+
## Configuration
|
31
|
+
|
32
|
+
In your `routes.rb`, specify a mount point:
|
33
|
+
|
34
|
+
mount Wiki::Engine, at: '/wiki'
|
35
|
+
|
36
|
+
In your `config/environment/*` files, configure the wiki:
|
37
|
+
|
38
|
+
require 'rails-wiki'
|
39
|
+
Wiki.local_directory = 'db/wiki'
|
40
|
+
|
41
|
+
_TODO: move this configuration to an initializer?_
|
42
|
+
|
43
|
+
## Usage
|
44
|
+
|
45
|
+
Pathnames that begin with underscore (`_`) are reserved.
|
46
|
+
|
47
|
+
## Feature Roadmap
|
48
|
+
|
49
|
+
1. Markdown link rooting
|
50
|
+
1. Recursive page deletion
|
51
|
+
1. Individual attachment deletion
|
52
|
+
1. Path redirection rules
|
53
|
+
1. Configurable help paths
|
54
|
+
1. Nicer attachment upload
|
55
|
+
1. Nicer page editing
|
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'Rails Wiki'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
|
21
|
+
load 'rails/tasks/statistics.rake'
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
Bundler::GemHelper.install_tasks
|
26
|
+
|
27
|
+
require 'rake/testtask'
|
28
|
+
|
29
|
+
Rake::TestTask.new(:test) do |t|
|
30
|
+
t.libs << 'lib'
|
31
|
+
t.libs << 'test'
|
32
|
+
t.pattern = 'test/**/*_test.rb'
|
33
|
+
t.verbose = false
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
task default: :test
|
@@ -0,0 +1,34 @@
|
|
1
|
+
// inserts text at cursor, or before and after selection
|
2
|
+
// based on http://stackoverflow.com/a/12815163/5610
|
3
|
+
jQuery.fn.extend({
|
4
|
+
inject: function(insertTextPre, insertTextPost){
|
5
|
+
return this.each(function(i) {
|
6
|
+
if (document.selection) {
|
7
|
+
// IE
|
8
|
+
this.focus();
|
9
|
+
sel = document.selection.createRange();
|
10
|
+
sel.text = insertTextPre + insertTextPost;
|
11
|
+
this.focus();
|
12
|
+
}
|
13
|
+
else if (this.selectionStart || this.selectionStart == '0') {
|
14
|
+
// modern browser
|
15
|
+
var startPos = this.selectionStart;
|
16
|
+
var endPos = this.selectionEnd;
|
17
|
+
var scrollTop = this.scrollTop;
|
18
|
+
this.value = this.value.substring(0, startPos)+insertTextPre+this.value.substring(startPos,endPos)+insertTextPost+this.value.substring(endPos,this.value.length);
|
19
|
+
this.focus();
|
20
|
+
this.selectionStart = startPos + insertTextPre.length;
|
21
|
+
this.selectionEnd = ((startPos + insertTextPre.length) + this.value.substring(startPos,endPos).length);
|
22
|
+
this.scrollTop = scrollTop;
|
23
|
+
} else {
|
24
|
+
// no selection, only use prefix
|
25
|
+
if (document.queryCommandSupported('insertText')) {
|
26
|
+
document.execCommand('insertText', false, text);
|
27
|
+
} else {
|
28
|
+
this.value += insertTextPre;
|
29
|
+
this.focus();
|
30
|
+
}
|
31
|
+
}
|
32
|
+
})
|
33
|
+
}
|
34
|
+
});
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any styles
|
10
|
+
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
|
11
|
+
* file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Wiki
|
2
|
+
# inherit from host app for current_user and auth_required
|
3
|
+
class ApplicationController < ::ApplicationController
|
4
|
+
|
5
|
+
before_filter :auth_required
|
6
|
+
|
7
|
+
layout 'layouts/wiki'
|
8
|
+
|
9
|
+
def display
|
10
|
+
@home = Rails.configuration.wiki.home_page
|
11
|
+
|
12
|
+
ext = File.extname(request.path_info).downcase
|
13
|
+
if ext.blank? || ext == ".html"
|
14
|
+
@page = Rails.configuration.wiki.find_page(params[:path])
|
15
|
+
if @page.nil?
|
16
|
+
raise Exception.new("Attempt to create orphan page")
|
17
|
+
elsif @page.new_page?
|
18
|
+
redirect_to controller: :pages, action: :new
|
19
|
+
else
|
20
|
+
render 'wiki/pages/show'
|
21
|
+
end
|
22
|
+
else
|
23
|
+
@attachment = Rails.configuration.wiki.find_attachment(params[:path], ext)
|
24
|
+
if @attachment.blank?
|
25
|
+
raise ActionController::RoutingError.new('File Not Found')
|
26
|
+
else
|
27
|
+
send_file @attachment.filesystem_path, type: @attachment.mime_type, disposition: 'inline'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
class Wiki::PagesController < Wiki::ApplicationController
|
2
|
+
|
3
|
+
layout 'layouts/wiki'
|
4
|
+
|
5
|
+
def index
|
6
|
+
select = params[:select]
|
7
|
+
query = params[:query]
|
8
|
+
if query
|
9
|
+
@query = query
|
10
|
+
@pages = Rails.configuration.wiki.search(query)
|
11
|
+
else
|
12
|
+
@pages = Rails.configuration.wiki.all_pages
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def log
|
17
|
+
@changes_by_path = Rails.configuration.wiki.changelog.group_by{|c| c[:path]}
|
18
|
+
end
|
19
|
+
|
20
|
+
def new
|
21
|
+
@page = Rails.configuration.wiki.find_page(params[:path])
|
22
|
+
render :edit
|
23
|
+
end
|
24
|
+
|
25
|
+
def create
|
26
|
+
@page = Rails.configuration.wiki.create_page(params[:path])
|
27
|
+
@page.update(page_params)
|
28
|
+
if @page.save(current_user)
|
29
|
+
redirect_to @page
|
30
|
+
else
|
31
|
+
render :edit
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def edit
|
36
|
+
Rails.configuration.wiki.pull_repo
|
37
|
+
@page = Rails.configuration.wiki.find_page(params[:path])
|
38
|
+
end
|
39
|
+
|
40
|
+
def update
|
41
|
+
@page = Rails.configuration.wiki.find_page(params[:path])
|
42
|
+
@page.update(page_params)
|
43
|
+
if @page.save(current_user)
|
44
|
+
redirect_to @page
|
45
|
+
else
|
46
|
+
render :edit
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def destroy
|
51
|
+
return_path = root_path
|
52
|
+
# ext = File.extname(request.path_info).downcase
|
53
|
+
# if ext.blank? || ext == "html"
|
54
|
+
page = Rails.configuration.wiki.find_page(params[:path])
|
55
|
+
parent_path = page.parent_path
|
56
|
+
if parent_path.empty?
|
57
|
+
return_path = root_path
|
58
|
+
else
|
59
|
+
return_path = page_path(parent_path)
|
60
|
+
end
|
61
|
+
page.destroy!(current_user)
|
62
|
+
# TODO: recurse pages and attachments
|
63
|
+
|
64
|
+
# else
|
65
|
+
# file = Rails.configuration.wiki.find_file(params[:path] + '.' + params[:format])
|
66
|
+
# return_path = page_path(file.parent_path)
|
67
|
+
# file.destroy!(current_user)
|
68
|
+
# end
|
69
|
+
|
70
|
+
# TODO: look for first *valid* parent
|
71
|
+
redirect_to return_path
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def page_params
|
77
|
+
params.require(:page).permit(:name, :content, uploaded_files: [])
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
|
3
|
+
module Wiki
|
4
|
+
class Attachment
|
5
|
+
|
6
|
+
include ActiveModel::AttributeMethods
|
7
|
+
include ActiveModel::Conversion
|
8
|
+
include ActiveModel::Dirty
|
9
|
+
extend ActiveModel::Naming
|
10
|
+
|
11
|
+
define_attribute_methods :name, :content
|
12
|
+
|
13
|
+
attr_accessor :wiki, :name, :content, :path, :format
|
14
|
+
alias :id :path
|
15
|
+
|
16
|
+
def name=(value)
|
17
|
+
name_will_change!
|
18
|
+
@name=value unless value.nil?
|
19
|
+
end
|
20
|
+
|
21
|
+
def content=(value)
|
22
|
+
content_will_change!
|
23
|
+
@content=value unless value.nil?
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_s
|
27
|
+
self.path
|
28
|
+
end
|
29
|
+
|
30
|
+
def path
|
31
|
+
@path
|
32
|
+
end
|
33
|
+
|
34
|
+
def update(hash)
|
35
|
+
self.name = hash[:name]
|
36
|
+
self.content = hash[:content]
|
37
|
+
|
38
|
+
return true
|
39
|
+
end
|
40
|
+
|
41
|
+
def initialize(params={})
|
42
|
+
wiki = params[:wiki]
|
43
|
+
gollum_file = params[:gollum_file]
|
44
|
+
path = params[:path]
|
45
|
+
|
46
|
+
if wiki
|
47
|
+
@wiki = wiki
|
48
|
+
end
|
49
|
+
if gollum_file
|
50
|
+
self.gollum_file = gollum_file
|
51
|
+
elsif path
|
52
|
+
safepath = path.downcase
|
53
|
+
@path = safepath
|
54
|
+
new_file = @wiki.find_gollum_file(safepath)
|
55
|
+
if new_file
|
56
|
+
self.gollum_file = new_file
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def gollum_file=(file)
|
62
|
+
@gollum_file = file
|
63
|
+
@name = file.name
|
64
|
+
@format = File.extname(file.name).split('.').last.to_sym
|
65
|
+
# filename = ::Attachment.basename(fullname, ext)
|
66
|
+
@path = file.url_path + file.name
|
67
|
+
end
|
68
|
+
|
69
|
+
def gollum_file
|
70
|
+
@gollum_file
|
71
|
+
end
|
72
|
+
|
73
|
+
def filesystem_path
|
74
|
+
return File.join(@wiki.base_path, @path)
|
75
|
+
end
|
76
|
+
|
77
|
+
def mime_type
|
78
|
+
@gollum_file.mime_type
|
79
|
+
end
|
80
|
+
|
81
|
+
def to_param
|
82
|
+
@path
|
83
|
+
end
|
84
|
+
|
85
|
+
def parent_path
|
86
|
+
parent_path = File.dirname(@path)
|
87
|
+
(parent_path == '.') ? '' : parent_path + '/'
|
88
|
+
end
|
89
|
+
|
90
|
+
def destroy!(user)
|
91
|
+
commit_options = {name: user.name, email: user.email, message: "removed #{@path}"}
|
92
|
+
Rails.logger.debug("removing #{@path}")
|
93
|
+
|
94
|
+
committer = Gollum::Committer.new(@wiki.gollum_wiki, commit_options)
|
95
|
+
committer.delete(@path)
|
96
|
+
|
97
|
+
committer.after_commit do |index, _sha|
|
98
|
+
dir = File.dirname(@path)
|
99
|
+
dir = '' if dir == '.'
|
100
|
+
|
101
|
+
@wiki.gollum_wiki.clear_cache
|
102
|
+
committer.update_working_dir(dir, parent_path, @format)
|
103
|
+
end
|
104
|
+
|
105
|
+
@wiki.pull_repo
|
106
|
+
committer.commit
|
107
|
+
@wiki.push_repo
|
108
|
+
end
|
109
|
+
|
110
|
+
def persisted?
|
111
|
+
# TODO: make this a real dirty flag
|
112
|
+
true
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,213 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
|
3
|
+
module Wiki
|
4
|
+
class Page
|
5
|
+
# a gollum page facade
|
6
|
+
|
7
|
+
@@format = :markdown
|
8
|
+
|
9
|
+
# include ActiveModel::Model
|
10
|
+
include ActiveModel::AttributeMethods
|
11
|
+
include ActiveModel::Conversion
|
12
|
+
include ActiveModel::Dirty
|
13
|
+
extend ActiveModel::Naming
|
14
|
+
|
15
|
+
define_attribute_methods :name, :content
|
16
|
+
|
17
|
+
attr_accessor :wiki, :name, :content, :path, :uploaded_files
|
18
|
+
alias :id :path
|
19
|
+
|
20
|
+
def name=(value)
|
21
|
+
name_will_change!
|
22
|
+
@name=value unless value.nil?
|
23
|
+
end
|
24
|
+
|
25
|
+
def content=(value)
|
26
|
+
content_will_change!
|
27
|
+
@content=value unless value.nil?
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_param
|
31
|
+
@path
|
32
|
+
end
|
33
|
+
|
34
|
+
def path
|
35
|
+
@path
|
36
|
+
end
|
37
|
+
|
38
|
+
def update(hash)
|
39
|
+
self.name = hash[:name]
|
40
|
+
self.content = hash[:content]
|
41
|
+
@uploaded_files = hash[:uploaded_files]
|
42
|
+
|
43
|
+
return true
|
44
|
+
end
|
45
|
+
|
46
|
+
def initialize(params={})
|
47
|
+
wiki = params[:wiki]
|
48
|
+
gollum_page = params[:gollum_page]
|
49
|
+
path = params[:path]
|
50
|
+
|
51
|
+
if wiki
|
52
|
+
@wiki = wiki
|
53
|
+
end
|
54
|
+
if gollum_page
|
55
|
+
self.gollum_page = gollum_page
|
56
|
+
elsif path
|
57
|
+
safepath = path.downcase
|
58
|
+
@path = safepath
|
59
|
+
new_page = @wiki.find_gollum_page(safepath)
|
60
|
+
if new_page
|
61
|
+
self.gollum_page = new_page
|
62
|
+
else
|
63
|
+
@name = safepath.split('/').last
|
64
|
+
@blank = true
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def gollum_page=(new_gp)
|
70
|
+
@gollum_page = new_gp
|
71
|
+
@name = new_gp.name
|
72
|
+
@path = new_gp.url_path
|
73
|
+
@content = new_gp.raw_data
|
74
|
+
end
|
75
|
+
|
76
|
+
def gollum_page
|
77
|
+
@gollum_page
|
78
|
+
end
|
79
|
+
|
80
|
+
def new_page?
|
81
|
+
@blank && true
|
82
|
+
end
|
83
|
+
|
84
|
+
# may be out of sync with @content!
|
85
|
+
def html
|
86
|
+
@gollum_page.formatted_data unless @blank
|
87
|
+
end
|
88
|
+
|
89
|
+
def metadata
|
90
|
+
@gollum_page.metadata
|
91
|
+
end
|
92
|
+
|
93
|
+
# def to_param
|
94
|
+
# @gollum_page.url_path unless @blank
|
95
|
+
# end
|
96
|
+
|
97
|
+
def author
|
98
|
+
@gollum_page.versions.first.author.name unless @blank
|
99
|
+
end
|
100
|
+
def authored_date
|
101
|
+
@gollum_page.versions.first.authored_date unless @blank
|
102
|
+
end
|
103
|
+
|
104
|
+
def history_url
|
105
|
+
# @@format is :markdown, so let's presume
|
106
|
+
@wiki.history_url + @path + '.md'
|
107
|
+
end
|
108
|
+
|
109
|
+
def parents
|
110
|
+
parents = []
|
111
|
+
ancestors = @path.split('/')
|
112
|
+
for i in 1..(ancestors.length - 1) do
|
113
|
+
parent_name = ancestors.take(i).join('/')
|
114
|
+
parents << @wiki.find_page(parent_name)
|
115
|
+
end
|
116
|
+
return parents
|
117
|
+
end
|
118
|
+
|
119
|
+
def parent_path
|
120
|
+
parent_path = File.dirname(@path)
|
121
|
+
(parent_path == '.') ? '' : parent_path # + '/'
|
122
|
+
end
|
123
|
+
|
124
|
+
def children
|
125
|
+
@wiki.pages_under_path(@path)
|
126
|
+
end
|
127
|
+
|
128
|
+
def attachments
|
129
|
+
return @wiki.files_under_path(@path)
|
130
|
+
end
|
131
|
+
|
132
|
+
def save(user)
|
133
|
+
if @blank
|
134
|
+
commit = {name: user.name, email: user.email, message: "created #{@path}"}
|
135
|
+
Rails.logger.debug("creating #{@path}")
|
136
|
+
|
137
|
+
@wiki.pull_repo
|
138
|
+
@wiki.gollum_wiki.write_page(@name, @@format, @content, commit, self.parent_path)
|
139
|
+
|
140
|
+
@gollum_page = @wiki.find_gollum_page(@path)
|
141
|
+
@blank = false
|
142
|
+
else
|
143
|
+
commit = {name: user.name, email: user.email, message: "updated #{@path}"}
|
144
|
+
Rails.logger.debug("saving #{@path}")
|
145
|
+
|
146
|
+
@wiki.pull_repo
|
147
|
+
@wiki.gollum_wiki.update_page(@gollum_page, @name, @@format, @content, commit)
|
148
|
+
end
|
149
|
+
|
150
|
+
if @uploaded_files.present?
|
151
|
+
Rails.logger.debug("found #{@uploaded_files.length} new files for #{@path}")
|
152
|
+
head = @wiki.gollum_wiki.repo.head
|
153
|
+
|
154
|
+
# NOTE: may raise Gollum::DuplicatePageError
|
155
|
+
commit_options = {
|
156
|
+
message: "added #{@uploaded_files.length} attachments to #{@path}",
|
157
|
+
name: user.name,
|
158
|
+
email: user.email
|
159
|
+
}
|
160
|
+
committer = Gollum::Committer.new(@wiki.gollum_wiki, commit_options)
|
161
|
+
|
162
|
+
self.uploaded_files.each do |uploaded|
|
163
|
+
# TODO: maybe this should be creating then saving new files
|
164
|
+
fullname = uploaded.original_filename
|
165
|
+
ext = File.extname(fullname)
|
166
|
+
format = ext.split('.').last
|
167
|
+
filename = File.basename(fullname, ext)
|
168
|
+
contents = uploaded.read
|
169
|
+
fsdir = File.join(@wiki.gollum_wiki.path, @path)
|
170
|
+
pathname = File.join(@path, fullname)
|
171
|
+
|
172
|
+
if !FileTest::directory?(fsdir)
|
173
|
+
Dir::mkdir(fsdir)
|
174
|
+
end
|
175
|
+
fspath = File.join(fsdir, fullname)
|
176
|
+
File.open(fspath, 'wb') do |file|
|
177
|
+
file.write(contents)
|
178
|
+
Rails.logger.debug("uploaded #{format} to #{fspath}")
|
179
|
+
end
|
180
|
+
|
181
|
+
committer.index.add(pathname, contents)
|
182
|
+
# committer.add_to_index(@path, filename, format, contents)
|
183
|
+
# # committer.add_to_index(@path, filename, format, "file")
|
184
|
+
committer.after_commit do |committer, sha|
|
185
|
+
@wiki.gollum_wiki.clear_cache
|
186
|
+
committer.update_working_dir(@path, filename, format)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
committer.commit
|
190
|
+
end
|
191
|
+
|
192
|
+
@wiki.push_repo
|
193
|
+
changes_applied
|
194
|
+
end
|
195
|
+
|
196
|
+
def destroy!(user)
|
197
|
+
commit = {name: user.name, email: user.email, message: "removed #{@path}"}
|
198
|
+
Rails.logger.debug("removing #{@path}")
|
199
|
+
@wiki.gollum_wiki.delete_page(@gollum_page, commit)
|
200
|
+
@wiki.push_repo
|
201
|
+
end
|
202
|
+
|
203
|
+
def inspect
|
204
|
+
"Wiki::Page '#{@path}' (#{@gollum_page})"
|
205
|
+
end
|
206
|
+
|
207
|
+
def persisted?
|
208
|
+
# TODO: make this a real dirty flag
|
209
|
+
! self.new_page?
|
210
|
+
end
|
211
|
+
|
212
|
+
end
|
213
|
+
end
|