-
Notifications
You must be signed in to change notification settings - Fork 25
/
Copy pathapp.iced
193 lines (169 loc) · 5.66 KB
/
app.iced
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
express = require 'express'
http = require 'http'
path = require 'path'
fs = require 'fs'
moment = require 'moment'
icedcoffeescript = require('iced-coffee-script')
client = require './client'
{
exec
execFile
spawn
} = require 'child_process'
moment.locale 'zh-cn'
app = express favicon: false
app.locals.info = client = require './client'
app.locals.pretty = true
app.locals.moment = moment
app.locals.filesize = require 'filesize'
app.locals.active_tab = 'unknown'
app.locals.version = require('./package').version
app.set 'view engine', 'jade'
app.set 'views', path.join __dirname, 'views'
app.set 'strict routing', true
app.use '/files', express.static client.cwd
app.use '/assets', express.static path.join __dirname, 'assets'
app.use express.bodyParser()
app.use express.methodOverride()
app.use express.cookieParser()
app.use express.cookieSession
key: 'lixian-portal.session'
secret: "lixian-portal.#{Math.random()}"
app.use express.csrf()
vcodeReqs = []
await client.init defer e
throw e if e
client.startCron()
queue = client.queue
queue.lixian.vcodeHandler = (vcodeData, cb)->
vcodeReqs.push
data: "data:image/jpeg;base64,#{vcodeData.toString 'base64'}"
cb: cb
app.use (req, res, n)->
res.locals.csrfToken = req.csrfToken()
n null
app.get '/stats.json', (req, res, n)->
for task in client.stats.tasks
task.total = 0
task.fetched = 0
for file in task.files
file.retrieving = client.stats.retrieving?.task.id == task.id && client.stats.retrieving?.file.name == file.name
task.total += file.size
if file.finished
task.fetched += file.size
else if file.retrieving && client.stats.retrieving?.progress
task.fetched += client.stats.retrieving.progress.currentSize
task.progress = task.fetched * 100 / task.total
data =
vcode: vcodeReqs[0]?.data
executings: client.stats.executings
tasks: client.stats.tasks
if client.stats.retrieving?.progress
data.progress =
speed: client.stats.retrieving.progress.speed
progress: client.stats.retrieving.progress.percentage
fetched: client.stats.retrieving.progress.currentSize
eta: client.stats.retrieving.progress.remainingTime
res.json data
await fs.readFile path.join(__dirname, 'script.iced'), 'utf8', defer e, script
throw e if e
app.locals.script = icedcoffeescript.compile script, runtime: 'window'
app.get '/script.js', (req, res, n)->
if process.env.DEBUG
await fs.readFile path.join(__dirname, 'script.iced'), 'utf8', defer e, script
return n e if e
try
console.log 'recompiling script...'
app.locals.script = icedcoffeescript.compile script, runtime: 'window'
catch e
return n e
res.end app.locals.script
app.get '/', (req, res, n)->
return res.redirect '/login' if client.stats.requireLogin
while client.log.length > 100
client.log.pop()
res.render 'tasks', active_tab: 'tasks'
app.get '/new_task', (req, res, n)->
return res.redirect '/login' if client.stats.requireLogin
res.render 'new_task', active_tab: 'new_task'
app.get '/browse', (req, res, n)->
req.query.path ?= ''
dirpath = path.resolve client.cwd, req.query.path
return n 403 unless 0 == dirpath.indexOf client.cwd
await fs.readdir dirpath, defer e, files
return n e if e
res.locals.files = []
res.locals.path = req.query.path
for file in files
continue if file.match /^\./
await fs.stat path.join(dirpath, file), defer e, stats
return n e if e
res.locals.files.push
name: file
path: path.join(req.query.path, file)
isFile: stats.isFile()
isDirectory: stats.isDirectory()
size: stats.size
mtime: stats.mtime
atime: stats.atime
segs = req.query.path.split '/'
segs = segs.filter (s)-> s != ''
res.locals.parents = []
for seg, i in segs
res.locals.parents.push
name: seg
path: segs[0..i].join path.sep
res.render 'browse',
active_tab: 'browse'
app.post '/vcode', (req, res, n)->
vcodeReqs.shift()?.cb null, req.body.vcode
res.end ''
app.post '/', (req, res, n)->
if req.files && req.files.bt && req.files.bt.path && req.files.bt.size
bt = req.files.bt
await fs.rename bt.path, "#{bt.path}.torrent", defer e
return n e if e
await queue.execute 'addBtTask', bt.name, "#{bt.path}.torrent", defer e
return n e if e
if req.body.url && req.body.url.length
await queue.execute 'addTask', req.body.url, defer e
return n e if e
res.redirect '/'
app.get '/login', (req, res)->
res.locals.vcode = null
res.render 'login'
app.post '/login', (req, res, n)->
await queue.execute 'login', req.body.username, req.body.password, defer e
return n e if e
res.redirect '/'
app.post '/logout', (req, res, n)->
await queue.execute 'logout', defer e
return n e if e
res.redirect '/'
app.delete '/tasks/:id', (req, res, n)->
await queue.execute 'deleteTask', req.params.id, defer e
return n e if e
res.redirect '/'
app.use (e, req, res, next)->
res.render 'error',
error: e
autorefresh = ->
await queue.execute 'updateTasklist', defer(e)
setTimeout autorefresh, 60000 * (1 + Math.random() * 3)
autorefresh()
port = process.env.PORT || 3000
if isNaN Number port
await exec "fuser #{port}", defer e
throw new Error "#{port} already owned by another process" unless e
await fs.unlink port, defer e
await (server = http.createServer app).listen port, defer e
throw e if e
console.log "portal ready on unix://#{port}"
await fs.chmod port, '0777', defer e
throw e if e
else
await (server = http.createServer app).listen (Number port), defer e
throw e if e
address = server.address().address
address = '*' if address == '0.0.0.0'
console.log "portal ready on http://#{address}:#{port}/"