trahald 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/.gitignore +2 -1
  2. data/.travis.yml +16 -0
  3. data/Gemfile.lock +58 -0
  4. data/README.md +29 -8
  5. data/lib/public/lib/markdown/markdown.js +1616 -0
  6. data/lib/public/lib/masonry/jquery.masonry.min.js +10 -0
  7. data/lib/public/lib/reveal/markdown.js +151 -0
  8. data/lib/public/lib/reveal/showdown.js +62 -0
  9. data/lib/public/lib/reveal/theme/beige.css +142 -0
  10. data/lib/public/lib/reveal/theme/default.css +150 -0
  11. data/lib/public/lib/reveal/theme/moon.css +142 -0
  12. data/lib/public/lib/reveal/theme/night.css +130 -0
  13. data/lib/public/lib/reveal/theme/serif.css +130 -0
  14. data/lib/public/lib/reveal/theme/simple.css +132 -0
  15. data/lib/public/lib/reveal/theme/sky.css +136 -0
  16. data/lib/public/lib/reveal/theme/solarized.css +142 -0
  17. data/lib/trahald.rb +90 -11
  18. data/lib/trahald/.redis-client.rb.swn +0 -0
  19. data/lib/trahald/article.rb +34 -0
  20. data/lib/trahald/backend-base.rb +13 -0
  21. data/lib/trahald/git.rb +46 -1
  22. data/lib/trahald/markdown-body.rb +44 -0
  23. data/lib/trahald/redis-client.rb +33 -9
  24. data/lib/trahald/version.rb +1 -1
  25. data/lib/views/edit.slim +47 -10
  26. data/lib/views/fd.scss +22 -0
  27. data/lib/views/header.slim +13 -0
  28. data/lib/views/layout.slim +7 -4
  29. data/lib/views/list.slim +3 -1
  30. data/lib/views/page.slim +5 -8
  31. data/lib/views/slide.slim +37 -0
  32. data/lib/views/style.scss +3 -1
  33. data/lib/views/summary.slim +36 -0
  34. data/lib/views/tab.slim +10 -0
  35. data/lib/views/tab_edit.slim +10 -0
  36. data/spec/git_spec.rb +3 -23
  37. data/spec/redis-client_spec.rb +3 -25
  38. data/spec/spec_helper.rb +2 -1
  39. data/spec/support/shared_examples_for_backends.rb +38 -0
  40. data/trahald.gemspec +1 -0
  41. metadata +44 -4
@@ -0,0 +1,136 @@
1
+ @import url(http://fonts.googleapis.com/css?family=Quicksand:400,700,400italic,700italic);
2
+ @import url(http://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700);
3
+ /**
4
+ * Sky theme for reveal.js.
5
+ *
6
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
7
+ */
8
+ /*********************************************
9
+ * GLOBAL STYLES
10
+ *********************************************/
11
+ body {
12
+ background: #add9e4;
13
+ background: -moz-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
14
+ background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, #f7fbfc), color-stop(100%, #add9e4));
15
+ background: -webkit-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
16
+ background: -o-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
17
+ background: -ms-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
18
+ background: radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
19
+ background-color: #f7fbfc; }
20
+
21
+ .reveal {
22
+ font-family: "Open Sans", sans-serif;
23
+ font-size: 36px;
24
+ font-weight: 200;
25
+ letter-spacing: -0.02em;
26
+ color: #333333; }
27
+
28
+ ::selection {
29
+ color: white;
30
+ background: #134674;
31
+ text-shadow: none; }
32
+
33
+ /*********************************************
34
+ * HEADERS
35
+ *********************************************/
36
+ .reveal h1,
37
+ .reveal h2,
38
+ .reveal h3,
39
+ .reveal h4,
40
+ .reveal h5,
41
+ .reveal h6 {
42
+ margin: 0 0 20px 0;
43
+ color: #333333;
44
+ font-family: "Quicksand", sans-serif;
45
+ line-height: 0.9em;
46
+ letter-spacing: -0.08em;
47
+ text-transform: uppercase;
48
+ text-shadow: none; }
49
+
50
+ .reveal h1 {
51
+ text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
52
+
53
+ /*********************************************
54
+ * LINKS
55
+ *********************************************/
56
+ .reveal a:not(.image) {
57
+ color: #3b759e;
58
+ text-decoration: none;
59
+ -webkit-transition: color 0.15s ease;
60
+ -moz-transition: color 0.15s ease;
61
+ -ms-transition: color 0.15s ease;
62
+ -o-transition: color 0.15s ease;
63
+ transition: color 0.15s ease; }
64
+
65
+ .reveal a:not(.image):hover {
66
+ color: #74a7cb;
67
+ text-shadow: none;
68
+ border: none; }
69
+
70
+ .reveal .roll span:after {
71
+ color: #fff;
72
+ background: #264c66; }
73
+
74
+ /*********************************************
75
+ * IMAGES
76
+ *********************************************/
77
+ .reveal section img {
78
+ margin: 15px 0px;
79
+ background: rgba(255, 255, 255, 0.12);
80
+ border: 4px solid #333333;
81
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
82
+ -webkit-transition: all 0.2s linear;
83
+ -moz-transition: all 0.2s linear;
84
+ -ms-transition: all 0.2s linear;
85
+ -o-transition: all 0.2s linear;
86
+ transition: all 0.2s linear; }
87
+
88
+ .reveal a:hover img {
89
+ background: rgba(255, 255, 255, 0.2);
90
+ border-color: #3b759e;
91
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
92
+
93
+ /*********************************************
94
+ * NAVIGATION CONTROLS
95
+ *********************************************/
96
+ .reveal .controls div.navigate-left,
97
+ .reveal .controls div.navigate-left.enabled {
98
+ border-right-color: #3b759e; }
99
+
100
+ .reveal .controls div.navigate-right,
101
+ .reveal .controls div.navigate-right.enabled {
102
+ border-left-color: #3b759e; }
103
+
104
+ .reveal .controls div.navigate-up,
105
+ .reveal .controls div.navigate-up.enabled {
106
+ border-bottom-color: #3b759e; }
107
+
108
+ .reveal .controls div.navigate-down,
109
+ .reveal .controls div.navigate-down.enabled {
110
+ border-top-color: #3b759e; }
111
+
112
+ .reveal .controls div.navigate-left.enabled:hover {
113
+ border-right-color: #74a7cb; }
114
+
115
+ .reveal .controls div.navigate-right.enabled:hover {
116
+ border-left-color: #74a7cb; }
117
+
118
+ .reveal .controls div.navigate-up.enabled:hover {
119
+ border-bottom-color: #74a7cb; }
120
+
121
+ .reveal .controls div.navigate-down.enabled:hover {
122
+ border-top-color: #74a7cb; }
123
+
124
+ /*********************************************
125
+ * PROGRESS BAR
126
+ *********************************************/
127
+ .reveal .progress {
128
+ background: rgba(0, 0, 0, 0.2); }
129
+
130
+ .reveal .progress span {
131
+ background: #3b759e;
132
+ -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
133
+ -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
134
+ -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
135
+ -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
136
+ transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
@@ -0,0 +1,142 @@
1
+ @import url(http://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
2
+ /**
3
+ * Solarized Light theme for reveal.js.
4
+ * Author: Achim Staebler
5
+ */
6
+ @font-face {
7
+ font-family: 'League Gothic';
8
+ src: url("../../lib/font/league_gothic-webfont.eot");
9
+ src: url("../../lib/font/league_gothic-webfont.eot?#iefix") format("embedded-opentype"), url("../../lib/font/league_gothic-webfont.woff") format("woff"), url("../../lib/font/league_gothic-webfont.ttf") format("truetype"), url("../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular") format("svg");
10
+ font-weight: normal;
11
+ font-style: normal; }
12
+
13
+ /**
14
+ * Solarized colors by Ethan Schoonover
15
+ */
16
+ html * {
17
+ color-profile: sRGB;
18
+ rendering-intent: auto; }
19
+
20
+ /*********************************************
21
+ * GLOBAL STYLES
22
+ *********************************************/
23
+ body {
24
+ background: #fdf6e3;
25
+ background-color: #fdf6e3; }
26
+
27
+ .reveal {
28
+ font-family: "Lato", sans-serif;
29
+ font-size: 36px;
30
+ font-weight: 200;
31
+ letter-spacing: -0.02em;
32
+ color: #657b83; }
33
+
34
+ ::selection {
35
+ color: white;
36
+ background: #d33682;
37
+ text-shadow: none; }
38
+
39
+ /*********************************************
40
+ * HEADERS
41
+ *********************************************/
42
+ .reveal h1,
43
+ .reveal h2,
44
+ .reveal h3,
45
+ .reveal h4,
46
+ .reveal h5,
47
+ .reveal h6 {
48
+ margin: 0 0 20px 0;
49
+ color: #586e75;
50
+ font-family: "League Gothic", Impact, sans-serif;
51
+ line-height: 0.9em;
52
+ letter-spacing: 0.02em;
53
+ text-transform: uppercase;
54
+ text-shadow: none; }
55
+
56
+ .reveal h1 {
57
+ text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
58
+
59
+ /*********************************************
60
+ * LINKS
61
+ *********************************************/
62
+ .reveal a:not(.image) {
63
+ color: #268bd2;
64
+ text-decoration: none;
65
+ -webkit-transition: color 0.15s ease;
66
+ -moz-transition: color 0.15s ease;
67
+ -ms-transition: color 0.15s ease;
68
+ -o-transition: color 0.15s ease;
69
+ transition: color 0.15s ease; }
70
+
71
+ .reveal a:not(.image):hover {
72
+ color: #78b9e6;
73
+ text-shadow: none;
74
+ border: none; }
75
+
76
+ .reveal .roll span:after {
77
+ color: #fff;
78
+ background: #1a6091; }
79
+
80
+ /*********************************************
81
+ * IMAGES
82
+ *********************************************/
83
+ .reveal section img {
84
+ margin: 15px 0px;
85
+ background: rgba(255, 255, 255, 0.12);
86
+ border: 4px solid #657b83;
87
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
88
+ -webkit-transition: all 0.2s linear;
89
+ -moz-transition: all 0.2s linear;
90
+ -ms-transition: all 0.2s linear;
91
+ -o-transition: all 0.2s linear;
92
+ transition: all 0.2s linear; }
93
+
94
+ .reveal a:hover img {
95
+ background: rgba(255, 255, 255, 0.2);
96
+ border-color: #268bd2;
97
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
98
+
99
+ /*********************************************
100
+ * NAVIGATION CONTROLS
101
+ *********************************************/
102
+ .reveal .controls div.navigate-left,
103
+ .reveal .controls div.navigate-left.enabled {
104
+ border-right-color: #268bd2; }
105
+
106
+ .reveal .controls div.navigate-right,
107
+ .reveal .controls div.navigate-right.enabled {
108
+ border-left-color: #268bd2; }
109
+
110
+ .reveal .controls div.navigate-up,
111
+ .reveal .controls div.navigate-up.enabled {
112
+ border-bottom-color: #268bd2; }
113
+
114
+ .reveal .controls div.navigate-down,
115
+ .reveal .controls div.navigate-down.enabled {
116
+ border-top-color: #268bd2; }
117
+
118
+ .reveal .controls div.navigate-left.enabled:hover {
119
+ border-right-color: #78b9e6; }
120
+
121
+ .reveal .controls div.navigate-right.enabled:hover {
122
+ border-left-color: #78b9e6; }
123
+
124
+ .reveal .controls div.navigate-up.enabled:hover {
125
+ border-bottom-color: #78b9e6; }
126
+
127
+ .reveal .controls div.navigate-down.enabled:hover {
128
+ border-top-color: #78b9e6; }
129
+
130
+ /*********************************************
131
+ * PROGRESS BAR
132
+ *********************************************/
133
+ .reveal .progress {
134
+ background: rgba(0, 0, 0, 0.2); }
135
+
136
+ .reveal .progress span {
137
+ background: #268bd2;
138
+ -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
139
+ -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
140
+ -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
141
+ -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
142
+ transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
+ require_relative "trahald/article"
2
3
  require_relative "trahald/backend-base"
3
- require_relative "trahald/git"
4
- require_relative "trahald/redis-client"
4
+ require_relative "trahald/markdown-body"
5
5
  require_relative "trahald/version"
6
6
 
7
7
  module Trahald
@@ -14,26 +14,86 @@ module Trahald
14
14
 
15
15
  class App < Sinatra::Base
16
16
 
17
+ configure :test do
18
+ require_relative "trahald/git"
19
+ require_relative "trahald/redis-client"
20
+ end
21
+
17
22
  configure :production, :development, :git do
23
+ require_relative "trahald/git"
18
24
  dir = Dir::pwd + "/data"
19
25
  Git::init_repo_if_needed dir
20
26
  DB = Git.new dir
21
27
  end
22
28
 
23
29
  configure :redis do
24
- url = "redis://localhost:6379"
25
- DB = RedisClient.new url
30
+ require_relative "trahald/redis-client"
31
+ DB = RedisClient.new ENV["TRAHALD_REDIS_URL"]
32
+ end
33
+
34
+ configure do
35
+ UPLOAD = "upload"
36
+ UPLOAD_DIR = "#{Dir::pwd}/lib/public/#{UPLOAD}"
37
+ UPLOAD_LIMIT_SIZE = 2000000 # 2MB
38
+ Dir::mkdir UPLOAD_DIR unless FileTest.exist? UPLOAD_DIR
39
+ end
40
+
41
+ helpers do
42
+ def request_headers
43
+ env.inject({}){|acc, (k,v) | acc[$1.downcase] = v if k =~ /^http_(.*)/i; acc}
44
+ end
45
+ end
46
+
47
+ before do
48
+ expires 500, :public, :must_revalidate
26
49
  end
27
50
 
28
51
  get '/' do
29
- redirect 'home'
52
+ #redirect 'home'
53
+ redirect 'summary'
30
54
  end
31
55
 
32
56
  get '/list' do
57
+ last_modified DB.last_modified
58
+ @name = "list"
59
+ @title = "ページ一覧"
33
60
  @keys = DB.list
34
61
  slim :list
35
62
  end
36
63
 
64
+ get '/summary' do
65
+ last_modified DB.last_modified
66
+ @name = "summary" # not used
67
+ @title = "summary" # not used
68
+ @data = DB.data.sort_by{|d| d.date}.reverse
69
+ slim :summary
70
+ end
71
+
72
+ get '/uploads' do
73
+ @name = "uploads"
74
+ @title = "添付画像一覧"
75
+ @keys = Dir::glob("#{UPLOAD_DIR}/**/*.{gif,jpg,jpeg,png}").map{|f| "#{UPLOAD}/#{File.basename(f)}"}
76
+ slim :list
77
+ end
78
+
79
+ get '/css/fd.css' do
80
+ scss :fd
81
+ end
82
+
83
+ get %r{^/(.+?)/slide$} do
84
+ puts "slide"
85
+ puts params[:captures]
86
+ @name = params[:captures][0]
87
+ @body = DB.body(@name)
88
+ puts @body
89
+ if @body
90
+ slim :slide, :layout => :raw_layout
91
+ else
92
+ @body = ""
93
+ slim :edit
94
+ end
95
+ end
96
+
37
97
  get %r{^/(.+?)/edit$} do
38
98
  puts "edit"
39
99
  puts params[:captures]
@@ -60,12 +120,11 @@ module Trahald
60
120
  get %r{^/(.+?)$} do
61
121
  puts params[:captures]
62
122
  @name = params[:captures][0]
63
- @body = DB.body(@name)
64
- puts "body:#{@body}"
65
- @style = scss :style
66
- puts "style:#{@style}"
67
- if @body
68
- @body = Kramdown::Document.new(@body).to_html
123
+ article = DB.article(@name)
124
+ if article
125
+ @body = Kramdown::Document.new(article.body).to_html
126
+ @date = article.date
127
+ @tab = slim :tab
69
128
  slim :page
70
129
  else
71
130
  @body = ""
@@ -91,6 +150,26 @@ module Trahald
91
150
  redirect "/#{URI.escape(@name)}"
92
151
  end
93
152
 
153
+ post "/upload" do
154
+ header = request_headers
155
+ data = request.body.read
156
+ name = header["x_file_name"]
157
+ size = header["x_file_size"].to_i
158
+ halt(400, "Invalid request. (Maybe filetype is forbidden.)") unless name
159
+ halt(400, "Only gif, jpg, png file is enable.") unless ['png', 'jpg', 'jpeg', 'gif'].include? name.split('.').last.downcase
160
+ filepath = UPLOAD_DIR + "/" + name.downcase
161
+ halt(423, "File has already existed.") if File.exist? filepath
162
+ halt(413, "File size is too big.") if size > UPLOAD_LIMIT_SIZE
163
+ begin
164
+ File.open(filepath, "w") do |f|
165
+ f.write(data)
166
+ end
167
+ rescue Exception
168
+ halt(403, "File can not be written. ")
169
+ end
170
+ halt 200
171
+ end
172
+
94
173
  run! if $0 == __FILE__
95
174
  end
96
175
  end
@@ -0,0 +1,34 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Trahald
3
+ require 'json'
4
+
5
+ class Article
6
+ attr_reader :name, :body, :date
7
+ def initialize(name, body, date)
8
+ @name = name
9
+ @body = body
10
+ @date = date
11
+ end
12
+
13
+ def to_h
14
+ {
15
+ :name => @name,
16
+ :body => @body,
17
+ :date => @date
18
+ }
19
+ end
20
+
21
+ def to_json
22
+ JSON.generate to_h
23
+ end
24
+
25
+ def Article.from_json(json)
26
+ begin
27
+ h = JSON.parse json
28
+ Article.new(h["name"], h["body"], h["date"])
29
+ rescue exception
30
+ "Json parse error."
31
+ end
32
+ end
33
+ end
34
+ end