-
Notifications
You must be signed in to change notification settings - Fork 25
/
client.iced
233 lines (204 loc) · 7.23 KB
/
client.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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
path = require 'path'
fs = require 'fs'
mkdirp = require 'mkdirp'
request = require 'request'
filesize = require 'filesize'
StatusBar = require 'status-bar'
Lixian = require 'node-lixian'
lixian = new Lixian()
exports.stats = stats =
task: null
retrieving: null
error: {}
speed: 'NaN'
tasks: []
requireLogin: true
requireVerificationCode: false
password: ''
username: ''
stats.retrieves = []
exports.log = log = []
exports.queue = queue = {}
exports.cwd = cwd = process.env.LIXIAN_PORTAL_HOME || process.cwd()
exports.startCron = ->
while true
if retrieve = stats.retrieves.shift()
await queue.execute 'retrieve', retrieve.task, retrieve.file, defer e
await setTimeout defer(), 100
exports.init = (cb)->
await fs.readFile (path.join cwd, '.lixian-portal.cookies'), 'utf8', defer e, cookie
try
cookie = JSON.parse cookie
await lixian.init cookie: cookie, defer e
return cb e if e
await fs.readFile (path.join cwd, '.lixian-portal.username'), 'utf8', defer e, username
await fs.readFile (path.join cwd, '.lixian-portal.password'), 'utf8', defer e, password
if (stats.requireLogin = !lixian.logon) && username && password
console.log '正在尝试自动登录...'
await queue.execute 'login', username, password, defer e
if e
console.error e.message
else
console.log '自动登录成功.'
cb null
stats.executings = []
queue.lixian = lixian
execute_log = []
lixian.on 'debug', (prefix, data)->
execute_log.push
prefix: prefix
data: data
queue.execute = (command, args..., cb)=>
commands =
retrieve: (task, file)-> "取回文件 #{task.name}/#{file.name}"
deleteTask: (id)-> "删除任务 #{id}"
updateTasklist: -> "刷新任务列表"
addTask: (url)-> "添加任务 #{url}"
addBtTask: (filename, torrent)-> "添加 BT 任务 #{filename}"
login: (username, password)-> "以 #{username} 登录"
logout: -> "登出"
command_name = commands[command] args...
log.unshift "#{command_name} 启动"
console.log log[0]
stats.executings.push command_name
execute_log = []
await queue.tasks[command] args..., defer e, results...
stats.executings.splice (stats.executings.indexOf command_name), 1
stats.requireLogin = !lixian.logon
if e
e.extra = execute_log.map ({prefix, data})->
try
message = JSON.stringify data, null, ' ' unless data?.constructor is String
return (message||'undefined').split('\n').map (line)->
"#{prefix}> #{line}\n"
.join('')
catch e
console.error e.message
return String data
.join('-------------\n')
if e.message.match /重新登录/i
stats.requireLogin = true
log.unshift e.message
console.log log[0]
log.unshift "#{command_name} 失败"
console.log log[0]
else
log.unshift "#{command_name} 完成"
console.log log[0]
cb e, results...
queue.tasks =
retrieve: (task, file, cb)->
await fs.stat file.dest_path, defer e, dest_stats
if dest_stats?.size == file.size
console.log "已存在 #{file.dest_path} 取回取消"
else
console.log "正在取回 #{file.dest_path}..."
req = request
url: file.url
headers:
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
'Cookie': stats.cookie
'Referer': 'http://dynamic.cloud.vip.xunlei.com/user_task'
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36'
'Accept-Language': 'zh-CN,zh;q=0.8,it-IT;q=0.6,it;q=0.4,en-US;q=0.2,en;q=0.2'
proxy: process.env['http_proxy']
req.on 'error', cb
await mkdirp (path.dirname file.dest_path), defer e
return cb e if e
await req.on 'response', defer res
stats.retrieving =
req: req
task: task
file: file
writer = fs.createWriteStream file.dest_path
statusBar = StatusBar.create total: file.size
statusBar.on 'render', (progress)->
stats.retrieving.progress = progress
req.pipe statusBar
req.pipe writer
await writer.on 'finish', defer()
statusBar.cancel()
if req._aborted
stats.retrieving = null
return cb new Error '任务已删除'
stats.retrieving = null
await queue.execute 'updateTasklist', defer e
return cb e if e
cb()
updateTasklist: (cb)->
return cb new Error '未登录' if stats.requireLogin
await lixian.list {}, defer e, data
return cb e if e
stats.cookie = data.cookie
stats.tasks = data.tasks
for task in stats.tasks
task.finished = true
for file in task.files
task.total += file.size
if task.name == file.name
file.dest_path = path.join cwd, file.name
else
file.dest_path = path.join cwd, task.name, file.name.replace /[\/\\]/g, path.sep
file.finished = false
if file.url
dest_stats = null
try
dest_stats = fs.statSync file.dest_path
file.finished = dest_stats?.size == file.size
if file.finished
stats.retrieves = stats.retrieves.filter((r)-> r.task.id != task.id || r.file.name != file.name)
if stats.retrieving?.task.id == task.id && stats.retrieving?.file.name == file.name
task.finished = false
else if stats.retrieves.filter((r)-> r.task.id == task.id && r.file.name == file.name).length
task.finished = false
else
if !file.finished
task.finished = false
stats.retrieves.push
task: task
file: file
else
task.finished = false
if task.finished
await queue.execute 'deleteTask', task.id, defer e
return cb e if e
cb()
deleteTask: (id, cb)->
if stats.retrieving?.task.id == id
stats.retrieving.req.abort()
stats.retrieves = stats.retrieves.filter (retrieve)-> retrieve.task.id != id
await lixian.delete_task delete: id, defer e
return cb e if e
await queue.execute 'updateTasklist', defer e
return cb e if e
cb null
login: (username, password, cb)->
await lixian.login username: username, password: password, defer e
return cb e if e
stats.requireLogin = !lixian.logon
await queue.execute 'updateTasklist', defer e
return cb e if e
await fs.writeFile (path.join cwd, '.lixian-portal.username'), username, 'utf8', defer e
await fs.writeFile (path.join cwd, '.lixian-portal.password'), password, 'utf8', defer e
cb null
logout: (cb)->
stats.retrieves = []
stats.retrieving?.req.abort()
await fs.unlink (path.join cwd, '.lixian-portal.username'), defer e
await fs.unlink (path.join cwd, '.lixian-portal.password'), defer e
await lixian.init {}, defer e
return cb if e
stats.requireLogin = !lixian.logon
cb null
addBtTask: (filename, torrent, cb)->
await lixian.add_torrent torrent: torrent, defer e
return cb e if e
await queue.execute 'updateTasklist', defer e
return cb e if e
cb null
addTask: (url, cb)->
await lixian.add_url url: url, defer e
return cb e if e
await queue.execute 'updateTasklist', defer e
return cb e if e
cb null