-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.rb
128 lines (96 loc) · 3.15 KB
/
app.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
require 'rubygems'
require 'rack'
require 'sinatra'
require 'sinatra/json'
require 'dropbox_sdk'
require 'redcarpet'
require 'rouge'
require 'rouge/plugins/redcarpet'
require 'sinatra/reloader' if development?
# ------------------- 設定読み込み
# 基本的にdokku前提なので全てENVから設定は読む(設定ファイルを使わない)
APP_BASE_URL = ENV['APP_BASE_URL'] || 'http://localhost:4567'
APP_TITLE = ENV['APP_TITLE'] || 'GauWriter'
DROPBOX_ACCESS_TYPE = :app_folder
DROPBOX_APP_KEY = ENV['DROPBOX_APP_KEY']
DROPBOX_APP_SECRET = ENV['DROPBOX_APP_SECRET']
DROPBOX_REQUEST_TOKEN_KEY = ENV['DROPBOX_REQUEST_TOKEN_KEY']
DROPBOX_REQUEST_TOKEN_SECRET = ENV['DROPBOX_REQUEST_TOKEN_SECRET']
DROPBOX_ACCESS_TOKEN_KEY = ENV['DROPBOX_ACCESS_TOKEN_KEY']
DROPBOX_ACCESS_TOKEN_SECRET = ENV['DROPBOX_ACCESS_TOKEN_SECRET']
# ------------------- クラス拡張
class DropboxClient
def get_metadata_if_exists(path)
result = self.metadata(path)
return result
rescue DropboxError
return nil
end
end
class HTMLWithCodeHighlight < Redcarpet::Render::HTML
include Rouge::Plugins::Redcarpet
end
# ------------------- ヘルパー
helpers do
def create_dropbox_client
session = DropboxSession.new(DROPBOX_APP_KEY, DROPBOX_APP_SECRET)
session.set_request_token(DROPBOX_REQUEST_TOKEN_KEY, DROPBOX_REQUEST_TOKEN_SECRET)
session.set_access_token(DROPBOX_ACCESS_TOKEN_KEY, DROPBOX_ACCESS_TOKEN_SECRET)
DropboxClient.new(session, DROPBOX_ACCESS_TYPE)
end
def send_dropbox_file(path, opts = {})
client = create_dropbox_client
raw, metadata = client.get_file_and_metadata(path)
last_modified Time.parse(metadata['modified'])
if opts[:type] or not response['Content-Type']
content_type opts[:type] || File.extname(path), :default => 'application/octet-stream'
end
headers['Content-Length'] ||= raw.length
opts[:status] = Integer(opts.fetch(:status, 200))
halt opts[:status], raw
rescue DropboxError
not_found
end
def render_dropbox_markdown(path, opts = {})
dirname = File.dirname(path)
basename = File.basename(path, '.md')
client = create_dropbox_client
metadata = client.get_metadata_if_exists(path)
if metadata && metadata['is_dir']
entry = client.metadata("#{dirname}/#{basename}/index.md")
elsif /\/$/ !~ path
entry = client.metadata("#{dirname}/#{basename}.md")
end
not_found unless entry
not_found if entry['is_dir']
raw = client.get_file(entry['path'])
raw.force_encoding 'utf-8'
processor = Redcarpet::Markdown.new(HTMLWithCodeHighlight, fenced_code_blocks: true, autolink: true, tables: true)
rendered = processor.render(raw)
@title = APP_TITLE
@title = "#{APP_TITLE} :: #{path}" if path == '/'
@body = rendered
erb :md
rescue DropboxError
not_found
end
end
# ------------------- API実装
not_found do
'Not found'
end
get /(\/.*)\// do |path|
redirect path
end
get '/*' do |path|
extname = File.extname(path)
unless extname == '' || extname == '.md'
send_dropbox_file path
else
render_dropbox_markdown path
end
end
# ------------------- 生存チェック用
get '/ping' do
'running!'
end