trahald 0.0.4 → 0.0.5
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.
- data/.gitignore +2 -1
- data/.travis.yml +16 -0
- data/Gemfile.lock +58 -0
- data/README.md +29 -8
- data/lib/public/lib/markdown/markdown.js +1616 -0
- data/lib/public/lib/masonry/jquery.masonry.min.js +10 -0
- data/lib/public/lib/reveal/markdown.js +151 -0
- data/lib/public/lib/reveal/showdown.js +62 -0
- data/lib/public/lib/reveal/theme/beige.css +142 -0
- data/lib/public/lib/reveal/theme/default.css +150 -0
- data/lib/public/lib/reveal/theme/moon.css +142 -0
- data/lib/public/lib/reveal/theme/night.css +130 -0
- data/lib/public/lib/reveal/theme/serif.css +130 -0
- data/lib/public/lib/reveal/theme/simple.css +132 -0
- data/lib/public/lib/reveal/theme/sky.css +136 -0
- data/lib/public/lib/reveal/theme/solarized.css +142 -0
- data/lib/trahald.rb +90 -11
- data/lib/trahald/.redis-client.rb.swn +0 -0
- data/lib/trahald/article.rb +34 -0
- data/lib/trahald/backend-base.rb +13 -0
- data/lib/trahald/git.rb +46 -1
- data/lib/trahald/markdown-body.rb +44 -0
- data/lib/trahald/redis-client.rb +33 -9
- data/lib/trahald/version.rb +1 -1
- data/lib/views/edit.slim +47 -10
- data/lib/views/fd.scss +22 -0
- data/lib/views/header.slim +13 -0
- data/lib/views/layout.slim +7 -4
- data/lib/views/list.slim +3 -1
- data/lib/views/page.slim +5 -8
- data/lib/views/slide.slim +37 -0
- data/lib/views/style.scss +3 -1
- data/lib/views/summary.slim +36 -0
- data/lib/views/tab.slim +10 -0
- data/lib/views/tab_edit.slim +10 -0
- data/spec/git_spec.rb +3 -23
- data/spec/redis-client_spec.rb +3 -25
- data/spec/spec_helper.rb +2 -1
- data/spec/support/shared_examples_for_backends.rb +38 -0
- data/trahald.gemspec +1 -0
- metadata +44 -4
data/lib/trahald/backend-base.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
module Trahald
|
4
4
|
class BackendBase
|
5
|
+
|
5
6
|
def initialize
|
6
7
|
end
|
7
8
|
|
@@ -9,6 +10,10 @@ module Trahald
|
|
9
10
|
raise "Called abstract method: add!"
|
10
11
|
end
|
11
12
|
|
13
|
+
def article(name)
|
14
|
+
raise "Called abstract method: article"
|
15
|
+
end
|
16
|
+
|
12
17
|
def body(name)
|
13
18
|
raise "Called abstract method: body"
|
14
19
|
end
|
@@ -17,10 +22,18 @@ module Trahald
|
|
17
22
|
raise "Called abstract method: commit!"
|
18
23
|
end
|
19
24
|
|
25
|
+
def last_modified
|
26
|
+
raise "Called abstract method: last_modified"
|
27
|
+
end
|
28
|
+
|
20
29
|
def list
|
21
30
|
raise "Called abstract method: list"
|
22
31
|
end
|
23
32
|
|
33
|
+
def data
|
34
|
+
raise "Called abstract method: data"
|
35
|
+
end
|
36
|
+
|
24
37
|
def self.init_repo_if_needed(dir)
|
25
38
|
raise "Called abstract method: self.init_repo_if_needed"
|
26
39
|
end
|
data/lib/trahald/git.rb
CHANGED
@@ -9,13 +9,25 @@ module Trahald
|
|
9
9
|
@ext = ext
|
10
10
|
end
|
11
11
|
|
12
|
+
def article(name)
|
13
|
+
commit = repo.commits('master', false).find{|c|
|
14
|
+
c.diffs.first.b_path.force_encoding("ASCII-8BIT") == "#{name}.#{@ext}".force_encoding("ASCII-8BIT")
|
15
|
+
}
|
16
|
+
return nil unless commit
|
17
|
+
Article.new(
|
18
|
+
name,
|
19
|
+
commit.diffs.first.b_blob.data.force_encoding("UTF-8"),
|
20
|
+
commit.date
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
12
24
|
def add!(name, body)
|
13
25
|
path = "#{@repo_dir}/#{name}.#{@ext}"
|
14
26
|
FileUtils.mkdir_p File.dirname(path)
|
15
27
|
begin
|
16
28
|
File.open(path, 'w'){|f| f.write(body)}
|
17
29
|
Dir.chdir(@repo_dir){
|
18
|
-
repo.add "#{name}.#{@ext}"
|
30
|
+
repo.add "#{name}.#{@ext}".force_encoding("ASCII-8BIT")
|
19
31
|
}
|
20
32
|
true
|
21
33
|
rescue => exception
|
@@ -24,7 +36,13 @@ module Trahald
|
|
24
36
|
end
|
25
37
|
end
|
26
38
|
|
39
|
+
#experimental
|
27
40
|
def body(name)
|
41
|
+
a = article(name)
|
42
|
+
if a; a.body else nil end
|
43
|
+
end
|
44
|
+
|
45
|
+
def body_old(name)
|
28
46
|
first = first_commit
|
29
47
|
return nil unless first
|
30
48
|
|
@@ -39,6 +57,17 @@ module Trahald
|
|
39
57
|
repo.commit_index(message)
|
40
58
|
end
|
41
59
|
|
60
|
+
# experimental
|
61
|
+
def data
|
62
|
+
first = first_commit
|
63
|
+
return [] unless first
|
64
|
+
summary 50
|
65
|
+
end
|
66
|
+
|
67
|
+
def last_modified
|
68
|
+
first_commit.date
|
69
|
+
end
|
70
|
+
|
42
71
|
def list
|
43
72
|
first = first_commit
|
44
73
|
return [] unless first
|
@@ -59,18 +88,34 @@ module Trahald
|
|
59
88
|
end
|
60
89
|
|
61
90
|
def first_commit
|
91
|
+
return Time.now unless repo.commits.any?
|
62
92
|
repo.commits.first
|
63
93
|
end
|
64
94
|
|
65
95
|
def files(pos, tree, list)
|
66
96
|
tree.blobs.each{|blob|
|
97
|
+
puts blob.name
|
67
98
|
list.push pos + File.basename(blob.name.force_encoding("UTF-8"), ".#{@ext}")
|
68
99
|
}
|
69
100
|
tree.trees.each{|t|
|
101
|
+
puts t.name
|
70
102
|
files "#{pos}#{t.name.force_encoding("UTF-8")}/", t, list
|
71
103
|
}
|
72
104
|
end
|
73
105
|
|
106
|
+
# args:
|
107
|
+
# max: number of commits gotten. if max is false, all commits are gotten.
|
108
|
+
def summary(max=false)
|
109
|
+
repo.commits('master', max).map{|commit|
|
110
|
+
path = commit.diffs.first.b_path.force_encoding("UTF-8")
|
111
|
+
MarkdownBody.new(
|
112
|
+
path.slice(0, path.size - (@ext.size+1)),
|
113
|
+
commit.diffs.first.b_blob.data.force_encoding("UTF-8"),
|
114
|
+
commit.date
|
115
|
+
).summary
|
116
|
+
}.uniq{|i| i.name}
|
117
|
+
end
|
118
|
+
|
74
119
|
def repo
|
75
120
|
@repo ||= Grit::Repo.new @repo_dir
|
76
121
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Trahald
|
4
|
+
require 'kramdown'
|
5
|
+
require 'sanitize'
|
6
|
+
|
7
|
+
class MarkdownBody
|
8
|
+
MAX_TEXT_SIZE = 160
|
9
|
+
Summary = Struct.new("Summary", :name, :imgs, :body, :date)
|
10
|
+
|
11
|
+
def initialize(name, body, date)
|
12
|
+
@name = name
|
13
|
+
@body = body
|
14
|
+
@date = date
|
15
|
+
end
|
16
|
+
|
17
|
+
def pre
|
18
|
+
raw = Sanitize.clean Kramdown::Document.new(@body).to_html
|
19
|
+
if raw.size > MAX_TEXT_SIZE
|
20
|
+
raw[0, MAX_TEXT_SIZE] + "..."
|
21
|
+
else
|
22
|
+
raw
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def img_src
|
27
|
+
pattern = Regexp.new '!\[.+\]\((.+)\)'
|
28
|
+
raw = @body.split('\n')
|
29
|
+
raw.map{|r|
|
30
|
+
$1 if pattern =~ r
|
31
|
+
}.select{|i| i}
|
32
|
+
end
|
33
|
+
|
34
|
+
def summary
|
35
|
+
Summary.new(
|
36
|
+
@name,
|
37
|
+
img_src,
|
38
|
+
pre,
|
39
|
+
@date
|
40
|
+
)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
data/lib/trahald/redis-client.rb
CHANGED
@@ -5,14 +5,20 @@ module Trahald
|
|
5
5
|
require 'uri'
|
6
6
|
|
7
7
|
class RedisClient < BackendBase
|
8
|
+
# track all page names.
|
9
|
+
KEY_SET = ".keys" # TODO: this must not be collided with any page names.
|
10
|
+
|
11
|
+
# for using cache.
|
12
|
+
MODIFIED_DATE = ".modified" # TODO: same
|
13
|
+
|
8
14
|
def initialize(url)
|
9
|
-
|
10
|
-
@
|
11
|
-
|
12
|
-
:port => uri.port
|
13
|
-
)
|
15
|
+
@redis = Redis.new(:url => url)
|
16
|
+
@params = Hash.new
|
17
|
+
end
|
14
18
|
|
15
|
-
|
19
|
+
def article(name)
|
20
|
+
json = @redis.zrange(name, -1, -1).first # nil unless zrange(..).any?
|
21
|
+
if json; Article.from_json(json) else nil end
|
16
22
|
end
|
17
23
|
|
18
24
|
# This method does not set data to Redis DB. To confirm, use commit! after add!.
|
@@ -21,14 +27,20 @@ module Trahald
|
|
21
27
|
end
|
22
28
|
|
23
29
|
def body(name)
|
24
|
-
|
30
|
+
a = article name
|
31
|
+
if a; a.body else nil end
|
25
32
|
end
|
26
33
|
|
27
34
|
# message is not used.
|
28
35
|
def commit!(message)
|
36
|
+
date = Time.now
|
29
37
|
@params.each{|name, body|
|
30
|
-
|
38
|
+
json = Article.new(name, body, date).to_json
|
39
|
+
zcard = @redis.zcard name
|
40
|
+
@redis.zadd name, zcard+1, json
|
41
|
+
@redis.sadd KEY_SET, name
|
31
42
|
}
|
43
|
+
@redis.set MODIFIED_DATE, date.to_s
|
32
44
|
end
|
33
45
|
|
34
46
|
# CAUTION! This method flush data on current db.
|
@@ -36,8 +48,20 @@ module Trahald
|
|
36
48
|
@redis.flushdb
|
37
49
|
end
|
38
50
|
|
51
|
+
def data
|
52
|
+
@redis.smembers(KEY_SET).map do |name|
|
53
|
+
a = article name
|
54
|
+
MarkdownBody.new(name, a.body, a.date).summary
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def last_modified
|
59
|
+
date = @redis.get(MODIFIED_DATE)
|
60
|
+
if date; Time.parse date else Time.now end
|
61
|
+
end
|
62
|
+
|
39
63
|
def list
|
40
|
-
@redis.
|
64
|
+
@redis.smembers(KEY_SET).sort
|
41
65
|
end
|
42
66
|
|
43
67
|
def self.init_repo_if_needed(dir)
|
data/lib/trahald/version.rb
CHANGED
data/lib/views/edit.slim
CHANGED
@@ -1,10 +1,47 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
1
|
+
script src="/lib/markdown/markdown.js"
|
2
|
+
script src="http://proger.i-forge.net/filedrop-min.js"
|
3
|
+
|
4
|
+
javascript:
|
5
|
+
$(function(){
|
6
|
+
var updatePreview = function(){
|
7
|
+
$("#preview").html(markdown.toHTML($("#text-input").val()));
|
8
|
+
};
|
9
|
+
$(document).ready(updatePreview());
|
10
|
+
$("#text-input").on("keyup", function(event){
|
11
|
+
updatePreview();
|
12
|
+
});
|
13
|
+
|
14
|
+
var options = {iframe: {url: '/upload'}};
|
15
|
+
var zone = new FileDrop('zone', options);
|
16
|
+
zone.on.send.push(function(files){
|
17
|
+
var unix_t = parseInt(new Date / 1000);
|
18
|
+
for(var i=0; i<files.length;++i){
|
19
|
+
name = unix_t + "." + files[i].name.split('.').pop().toLowerCase();
|
20
|
+
files[i].name = name
|
21
|
+
files[i].on.done.push(function(xhr,e){
|
22
|
+
var input = $("#text-input").val() + "\n\n";
|
23
|
+
$("#text-input").val(input);
|
24
|
+
updatePreview();
|
25
|
+
});
|
26
|
+
files[i].on.error.push(function(e, xhr){
|
27
|
+
alert(xhr.response);
|
28
|
+
});
|
29
|
+
files[i].SendTo('/upload');
|
30
|
+
}
|
31
|
+
});
|
32
|
+
});
|
33
|
+
|
34
|
+
== slim :header
|
35
|
+
|
36
|
+
div.row-fluid
|
37
|
+
div.span6
|
38
|
+
form action="/edit" method="post" style="margin-top:20px;"
|
39
|
+
div.row-fluid
|
40
|
+
input type="text" name="name" value="#{@name}" class="span12 input" style="font-size: 24px;"
|
41
|
+
fieldset#zone.row-fluid
|
42
|
+
textarea name="body" id="text-input" style="border:0; box-shadow: none; height: 500px;" class="span12" #{@body}
|
43
|
+
div.row-fluid
|
44
|
+
input type="submit" value="作成/更新" class="btn btn-primary"
|
45
|
+
div.span6#preview.well style="background: #fdfdfd; margin-top: 20px;"
|
46
|
+
|
47
|
+
== slim :tab_edit
|
data/lib/views/fd.scss
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
.fd-zone {
|
2
|
+
position: relative;
|
3
|
+
overflow: hidden;
|
4
|
+
//width: 15em;
|
5
|
+
text-align:center;
|
6
|
+
}
|
7
|
+
|
8
|
+
.fd-file {
|
9
|
+
opacity: 0;
|
10
|
+
font-size:118px;
|
11
|
+
position: absolute;
|
12
|
+
right: 0;
|
13
|
+
top: 0;
|
14
|
+
z-index: 1;
|
15
|
+
padding: 0;
|
16
|
+
margin: 0;
|
17
|
+
cursor: pointer;
|
18
|
+
filter: alpha(opacity=0);
|
19
|
+
font-family: sans-serif;
|
20
|
+
}
|
21
|
+
|
22
|
+
.fd-zone.over {border-color: maroon;}
|
data/lib/views/layout.slim
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
html
|
2
2
|
head
|
3
3
|
meta charset='UTF-8'
|
4
|
+
meta name="viewport" content="width=device-width, initial-scale=1.0"
|
4
5
|
title Trahald
|
5
|
-
link href=
|
6
|
+
link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet"
|
7
|
+
link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-responsive.min.css" rel="stylesheet"
|
8
|
+
link href="/css/fd.css" rel="stylesheet"
|
9
|
+
script src="//code.jquery.com/jquery-1.9.1.min.js"
|
10
|
+
script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/js/bootstrap.min.js"
|
6
11
|
body
|
7
12
|
div.container
|
8
|
-
|
9
|
-
a href='/' Trahald
|
10
|
-
== yield
|
13
|
+
== yield
|
data/lib/views/list.slim
CHANGED
data/lib/views/page.slim
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
html
|
2
|
+
head
|
3
|
+
meta charset='UTF-8'
|
4
|
+
meta content="yes" name="apple-mobile-web-app-capable"
|
5
|
+
meta content="black-translucent" name="apple-mobile-web-app-status-bar-style"
|
6
|
+
meta name="viewport" content="width=device-width, initial-scale=1.0"
|
7
|
+
title Trahald
|
8
|
+
link rel="stylesheet" href="//cdn.jsdelivr.net/reveal.js/2.2/reveal.min.css"
|
9
|
+
link rel="stylesheet" href="/lib/reveal/theme/serif.css" id="theme"
|
10
|
+
style
|
11
|
+
body{}
|
12
|
+
body
|
13
|
+
.reveal
|
14
|
+
.slides
|
15
|
+
section data-markdown="" data-separator="---"
|
16
|
+
script type="text/template"
|
17
|
+
== @body
|
18
|
+
script src="//cdn.jsdelivr.net/headjs/0.99/head.min.js"
|
19
|
+
script src="//cdn.jsdelivr.net/reveal.js/2.2/reveal.min.js"
|
20
|
+
javascript:
|
21
|
+
Reveal.initialize({
|
22
|
+
controls: true,
|
23
|
+
progress: true,
|
24
|
+
history: true,
|
25
|
+
center: true,
|
26
|
+
|
27
|
+
theme: Reveal.getQueryHash().theme,
|
28
|
+
transition: Reveal.getQueryHash().transition || 'default',
|
29
|
+
|
30
|
+
// Optional libraries used to extend on reveal.js
|
31
|
+
dependencies: [
|
32
|
+
{ src: '/lib/reveal/showdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
|
33
|
+
{ src: '/lib/reveal/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } }
|
34
|
+
]
|
35
|
+
});
|
36
|
+
|
37
|
+
|
data/lib/views/style.scss
CHANGED
@@ -0,0 +1,36 @@
|
|
1
|
+
== slim :header
|
2
|
+
script src="/lib/masonry/jquery.masonry.min.js"
|
3
|
+
|
4
|
+
css:
|
5
|
+
.item{
|
6
|
+
width: 300px;
|
7
|
+
margin: 10px;
|
8
|
+
float: center;
|
9
|
+
}
|
10
|
+
|
11
|
+
javascript:
|
12
|
+
$(function(){
|
13
|
+
$('#ultarget').masonry({
|
14
|
+
itemSelector: '.item',
|
15
|
+
columnWidth: 350
|
16
|
+
});
|
17
|
+
});
|
18
|
+
|
19
|
+
/h1 =@title
|
20
|
+
- if @data.any?
|
21
|
+
ul#ultarget.thumbnails
|
22
|
+
- for summary in @data do
|
23
|
+
li.thumbnail.item.span4
|
24
|
+
a href="#{summary.name}"
|
25
|
+
h3 =summary.name
|
26
|
+
- if summary.imgs.any?
|
27
|
+
a href="#{summary.name}"
|
28
|
+
img src="#{summary.imgs.first}" alt=""/
|
29
|
+
p=summary.body
|
30
|
+
p
|
31
|
+
small
|
32
|
+
em="更新日時: #{summary.date.to_s}"
|
33
|
+
- else
|
34
|
+
ul
|
35
|
+
li まだページが作成されていません。
|
36
|
+
|