kuport 0.1.3 → 0.1.4
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.
- checksums.yaml +4 -4
- data/README.md +61 -61
- data/bin/kuport +18 -4
- data/lib/kuport.rb +17 -9
- data/lib/kuport/helper.rb +19 -1
- data/lib/kuport/materials.rb +42 -0
- data/lib/kuport/message.rb +2 -1
- data/lib/kuport/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6841261656c40a5000fc5833d9e523af4175fd0a
|
4
|
+
data.tar.gz: 6acf47faf6733559a31ef6e5739f770eb9155456
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d38df664332a587adcb785f1f2979bded64284cb6e86ef22cf7fb4647945749d201180490c3cd5be7e6a1d6391d945c9930125b0d78d8f3a8b9ef40088c3356d
|
7
|
+
data.tar.gz: dafed4261b2058fc94ef504d7ff03d84f1faa6d5d17741bb8788113bac5e869b9c7681c5de5466a7009ff7de9b92079a1f3522690ac0ff061912ef1335a5bca4
|
data/README.md
CHANGED
@@ -10,7 +10,7 @@ $ gem install kuport
|
|
10
10
|
|
11
11
|
## Usage
|
12
12
|
|
13
|
-
###Command
|
13
|
+
### Command
|
14
14
|
|
15
15
|
端末でjsonを読むには`jid`がおすすめ。
|
16
16
|
|
@@ -23,45 +23,52 @@ $ cat sample.json | jid
|
|
23
23
|
|
24
24
|
一度ログインすればキャッシュが効くので、暫くは`--id`とパスワード入力は不要。
|
25
25
|
|
26
|
+
`--download`で複数のファイルを一括で落とすにはjqなどで上手くフィルタして`name`と`path`を含むディクショナリのリストを取り出す必要がある。
|
27
|
+
`[{name: 'Name', path: 'https://~~'}, ...]`
|
26
28
|
|
27
29
|
```bash
|
28
30
|
# 個人宛メッセージ取得
|
29
|
-
|
31
|
+
kuport --id jx91234 -m
|
30
32
|
|
31
33
|
|
32
34
|
# 個人宛メッセージ(既読)取得
|
33
|
-
|
35
|
+
kuport --id jx91234 -m read
|
34
36
|
|
35
37
|
|
36
38
|
# ログインのみ(一度ログインするとCookieがキャッシュされる)
|
37
|
-
|
39
|
+
kuport --id jx91234
|
38
40
|
|
39
41
|
|
40
|
-
#
|
41
|
-
|
42
|
+
# キューポートからファイルを1つダウンロード
|
43
|
+
kuport --download URL --output-file FILE
|
42
44
|
|
43
45
|
|
44
46
|
# メッセージの添付ファイルをまとめてダウンロード(jqでjsonパース)
|
45
|
-
|
46
|
-
$ kuport --download "$json"
|
47
|
+
kuport --id jx91234 -m | jq '.[0].links' | kuport --download
|
47
48
|
|
48
49
|
|
49
50
|
# 動的にダウンロードするファイルを選択
|
50
|
-
|
51
|
+
kuport --id jx91234 -m | jid | kuport --download
|
51
52
|
|
52
53
|
|
53
54
|
# 時間割取得
|
54
|
-
|
55
|
+
kuport -t
|
56
|
+
|
57
|
+
|
58
|
+
# 電子教材の特定の科目をダウンロード
|
59
|
+
kuport --materials | jq 'map(select( .["subject"] | test("^線形代数") ).links | .[])' | kuport --download
|
60
|
+
|
55
61
|
```
|
56
62
|
|
57
|
-
###Library
|
63
|
+
### Library
|
58
64
|
```ruby
|
59
|
-
require 'kuport'
|
60
|
-
kp = Kuport.new
|
65
|
+
require 'kuport'
|
66
|
+
kp = Kuport.new
|
61
67
|
kp.login('jx91234')
|
62
68
|
|
63
69
|
messages = kp.messages
|
64
70
|
timetable = kp.timetable
|
71
|
+
materials = kp.materials
|
65
72
|
|
66
73
|
m = messages[0]
|
67
74
|
puts m.title, m.body, m.links
|
@@ -71,17 +78,19 @@ puts messages.to_json
|
|
71
78
|
timetable.compact
|
72
79
|
puts timetable.to_json
|
73
80
|
|
81
|
+
puts materials.to_json
|
82
|
+
|
74
83
|
kp.download(url, name)
|
75
84
|
kp.download([{name: 'File.pdf', path: 'https://example.com/file.pdf'}, ])
|
76
85
|
|
77
86
|
kp.cookies_clear
|
78
87
|
```
|
79
88
|
|
80
|
-
##Formats
|
89
|
+
## Formats
|
81
90
|
|
82
|
-
###message
|
91
|
+
### message
|
83
92
|
|
84
|
-
```
|
93
|
+
```
|
85
94
|
[
|
86
95
|
{
|
87
96
|
"title": "おしらせ その1",
|
@@ -107,7 +116,7 @@ kp.cookies_clear
|
|
107
116
|
```
|
108
117
|
|
109
118
|
|
110
|
-
###timetable
|
119
|
+
### timetable
|
111
120
|
|
112
121
|
| 要素 | 中身 |
|
113
122
|
|---------|--------------------------|
|
@@ -117,7 +126,7 @@ kp.cookies_clear
|
|
117
126
|
| special | 集中講義など |
|
118
127
|
|
119
128
|
|
120
|
-
```
|
129
|
+
```
|
121
130
|
{
|
122
131
|
"year": "2022年",
|
123
132
|
"dates": [
|
@@ -125,22 +134,9 @@ kp.cookies_clear
|
|
125
134
|
"date": "12月19日 月",
|
126
135
|
"special": null
|
127
136
|
},
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
},
|
132
|
-
{
|
133
|
-
"date": "12月21日 水",
|
134
|
-
"special": null
|
135
|
-
},
|
136
|
-
{
|
137
|
-
"date": "12月22日 木",
|
138
|
-
"special": null
|
139
|
-
},
|
140
|
-
{
|
141
|
-
"date": "12月23日 金",
|
142
|
-
"special": "天皇誕生日"
|
143
|
-
},
|
137
|
+
.
|
138
|
+
.
|
139
|
+
.
|
144
140
|
{
|
145
141
|
"date": "12月24日 土",
|
146
142
|
"special": null
|
@@ -160,30 +156,9 @@ kp.cookies_clear
|
|
160
156
|
"period": null,
|
161
157
|
"status": []
|
162
158
|
},
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
"period": "Q2",
|
167
|
-
"status": []
|
168
|
-
},
|
169
|
-
{
|
170
|
-
"name": null,
|
171
|
-
"room": null,
|
172
|
-
"period": null,
|
173
|
-
"status": []
|
174
|
-
},
|
175
|
-
{
|
176
|
-
"name": "IT",
|
177
|
-
"room": "QA",
|
178
|
-
"period": null,
|
179
|
-
"status": []
|
180
|
-
},
|
181
|
-
{
|
182
|
-
"name": null,
|
183
|
-
"room": null,
|
184
|
-
"period": null,
|
185
|
-
"status": []
|
186
|
-
},
|
159
|
+
.
|
160
|
+
.
|
161
|
+
.
|
187
162
|
{
|
188
163
|
"name": null,
|
189
164
|
"room": null,
|
@@ -202,7 +177,33 @@ kp.cookies_clear
|
|
202
177
|
|
203
178
|
```
|
204
179
|
|
205
|
-
###
|
180
|
+
### materials
|
181
|
+
|
182
|
+
```
|
183
|
+
[
|
184
|
+
{
|
185
|
+
"subject": "世界一スゴイ講義",
|
186
|
+
"teacher": "スゴイ先生",
|
187
|
+
"title": "第100回目資料",
|
188
|
+
"period": "2117/04/04 〜 2117/08/20",
|
189
|
+
"state": "未ダウンロード",
|
190
|
+
"links": [
|
191
|
+
{
|
192
|
+
"name": "講義資料.pdf",
|
193
|
+
"path": "http://example.com/abc.pdf"
|
194
|
+
}
|
195
|
+
.
|
196
|
+
.
|
197
|
+
.
|
198
|
+
]
|
199
|
+
},
|
200
|
+
.
|
201
|
+
.
|
202
|
+
.
|
203
|
+
]
|
204
|
+
```
|
205
|
+
|
206
|
+
### download
|
206
207
|
|
207
208
|
| 形式 | 説明 | 例 |
|
208
209
|
|------------|---------------|------------------------------------------------------------------|
|
@@ -211,11 +212,10 @@ kp.cookies_clear
|
|
211
212
|
| JSON(配列) | 複数の要素 | [{"name": "img.png", "path": "http://example.com/efg.png"}, ...] |
|
212
213
|
|
213
214
|
|
214
|
-
|
215
215
|
## Contributing
|
216
216
|
|
217
217
|
バグがあったらお気軽にどうぞ。
|
218
|
-
コントリビューター募集中。
|
218
|
+
コントリビューター募集中。
|
219
219
|
|
220
220
|
|
221
221
|
## License
|
data/bin/kuport
CHANGED
@@ -32,6 +32,9 @@ $ kuport --download "$json"
|
|
32
32
|
# Interactively download message attachment
|
33
33
|
$ go get github.com/simeji/jid/cmd/jid
|
34
34
|
$ kuport --download "$(kuport --id jx91234 -m | jid)"
|
35
|
+
|
36
|
+
# Download specific subjects materials
|
37
|
+
kuport --materials | jq 'map(select( .["subject"] | test("^Computer") ).links | .[])' | kuport --download
|
35
38
|
USAGE
|
36
39
|
|
37
40
|
def debug?
|
@@ -51,7 +54,7 @@ parser = OptionParser.new do |o|
|
|
51
54
|
|
52
55
|
# 候補からデフォルト値をセットする
|
53
56
|
def o.on_select(symbol, short, long, cands, *desc)
|
54
|
-
on_setopt(symbol, short, long, cands, cands.join(' | '), *desc){|arg| arg
|
57
|
+
on_setopt(symbol, short, long, cands, cands.join(' | '), *desc){|arg| arg || cands[0]}
|
55
58
|
end
|
56
59
|
|
57
60
|
o.program_name= 'kuport'
|
@@ -62,15 +65,21 @@ parser = OptionParser.new do |o|
|
|
62
65
|
|
63
66
|
|
64
67
|
o.on_setopt(:id, '-I', '--id ID', 'Student number')
|
65
|
-
o.on_setopt(:download, '-D', '--download
|
66
|
-
|
68
|
+
o.on_setopt(:download, '-D', '--download=[-|URL|JSON]',
|
69
|
+
'Download file.',
|
70
|
+
'URL need --output-file',
|
71
|
+
'JSON contain [{name: "FILE", path: "URL"}, ...]',
|
72
|
+
"'-' read URL|JSON from stdin"){|v| v || '-'}
|
73
|
+
o.on_setopt(:output_file, '-O', '--output-file FILE', 'Specify destination filename')
|
67
74
|
o.on_setopt(:clear_cookies, '-C', '--clear-cookies')
|
75
|
+
o.on_setopt(:proxy, '-P', '--proxy SERVER:PORT')
|
68
76
|
o.separator('')
|
69
77
|
|
70
78
|
o.on_select(:messages, '-m', '--messages [TYPE]', %i[default read backno],
|
71
79
|
"read\tAlready read messages",
|
72
80
|
"backno\tBack number messages(Unimplemented)")
|
73
81
|
o.on_select(:timetable, '-t', '--timetable [TYPE]', %i[default compact])
|
82
|
+
o.on_select(:materials, '-d', '--materials [TYPE]', %i[default])
|
74
83
|
o.separator('')
|
75
84
|
|
76
85
|
o.separator('')
|
@@ -87,7 +96,7 @@ if debug?
|
|
87
96
|
end
|
88
97
|
|
89
98
|
# kp = KuportView.new
|
90
|
-
kp = Kuport.new
|
99
|
+
kp = Kuport.new(proxy: opts[:proxy])
|
91
100
|
|
92
101
|
if opts[:clear_cookies]
|
93
102
|
kp.cookies_clear
|
@@ -129,6 +138,11 @@ if opts[:timetable]
|
|
129
138
|
puts table.to_json
|
130
139
|
end
|
131
140
|
|
141
|
+
# materials
|
142
|
+
if opts[:materials]
|
143
|
+
mat = kp.materials
|
144
|
+
puts mat.to_json
|
145
|
+
end
|
132
146
|
|
133
147
|
if debug?
|
134
148
|
require 'pry'
|
data/lib/kuport.rb
CHANGED
@@ -3,8 +3,6 @@ require 'nokogiri'
|
|
3
3
|
require 'open-uri'
|
4
4
|
require 'fileutils'
|
5
5
|
require 'json'
|
6
|
-
require 'io/console'
|
7
|
-
require 'nkf'
|
8
6
|
|
9
7
|
require 'kuport/helper'
|
10
8
|
|
@@ -35,12 +33,18 @@ class Kuport
|
|
35
33
|
@@cookies_file = File.join(@@cache_dir, 'cookies.jar')
|
36
34
|
FileUtils.mkdir_p(@@cache_dir)
|
37
35
|
|
38
|
-
|
39
|
-
|
40
|
-
def initialize
|
41
|
-
@agent = Mechanize.new
|
42
|
-
@agent.html_parser = self.class
|
36
|
+
def initialize(proxy: nil)
|
37
|
+
agent.html_parser = self.class
|
43
38
|
cookies_load
|
39
|
+
|
40
|
+
proxy ||= Kuport.get_proxy_env_var
|
41
|
+
if proxy
|
42
|
+
agent.set_proxy(*Kuport.parse_proxy_str(proxy))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def agent
|
47
|
+
@agent ||= Mechanize.new
|
44
48
|
end
|
45
49
|
|
46
50
|
def self.module_url(*parts)
|
@@ -120,7 +124,7 @@ class Kuport
|
|
120
124
|
end
|
121
125
|
|
122
126
|
def materials
|
123
|
-
|
127
|
+
@materials ||= Materials.new(get_module(:materials))
|
124
128
|
end
|
125
129
|
|
126
130
|
def download_file(file_path, url)
|
@@ -139,7 +143,10 @@ class Kuport
|
|
139
143
|
|
140
144
|
json = JSON.parse(url_or_json, {symbolize_names: true})
|
141
145
|
if Array === json
|
142
|
-
json.each
|
146
|
+
json.each do |link|
|
147
|
+
download_file(link[:name], link[:path])
|
148
|
+
puts link[:name]
|
149
|
+
end
|
143
150
|
else
|
144
151
|
download_file(json[:name], json[:path])
|
145
152
|
end
|
@@ -156,5 +163,6 @@ end
|
|
156
163
|
|
157
164
|
require 'kuport/message'
|
158
165
|
require 'kuport/timetable'
|
166
|
+
require 'kuport/materials'
|
159
167
|
require 'kuport/view'
|
160
168
|
require 'kuport/version'
|
data/lib/kuport/helper.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
require 'uri'
|
2
|
+
require 'nkf'
|
3
|
+
require 'io/console'
|
2
4
|
|
3
5
|
class Kuport
|
4
6
|
module Helper
|
@@ -8,6 +10,10 @@ class Kuport
|
|
8
10
|
uri.to_s
|
9
11
|
end
|
10
12
|
|
13
|
+
def escape_filename(filename)
|
14
|
+
File.basename(filename.strip)
|
15
|
+
end
|
16
|
+
|
11
17
|
def color_str(color_num, str)
|
12
18
|
"\e[38;5;#{color_num}m#{str}\e[00m"
|
13
19
|
end
|
@@ -36,6 +42,18 @@ class Kuport
|
|
36
42
|
warn mes
|
37
43
|
exit ret
|
38
44
|
end
|
45
|
+
|
46
|
+
def get_proxy_env_var
|
47
|
+
keys = %w[ http_proxy https_proxy all_proxy ].map{|s| [s, s.upcase]}.flatten
|
48
|
+
keys.each do |key|
|
49
|
+
return ENV[key] if ENV.key?(key)
|
50
|
+
end
|
51
|
+
return nil
|
52
|
+
end
|
53
|
+
|
54
|
+
def parse_proxy_str(str)
|
55
|
+
str.split(':')[0..1]
|
56
|
+
end
|
39
57
|
end
|
40
58
|
|
41
59
|
module ClassExtensions
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'pry'
|
2
|
+
class Kuport::Materials
|
3
|
+
using Kuport::ClassExtensions
|
4
|
+
attr_reader :trs, :base_url
|
5
|
+
|
6
|
+
def initialize(page)
|
7
|
+
@trs = page.at_css('.portlet_module > table').css('tr')
|
8
|
+
trs.shift
|
9
|
+
@base_url = page.uri
|
10
|
+
end
|
11
|
+
|
12
|
+
def materials
|
13
|
+
@materials ||= trs.map{|tr| parse_table_line(tr)}.freeze
|
14
|
+
end
|
15
|
+
|
16
|
+
def parse_table_line(tr)
|
17
|
+
tds = tr.css('td')
|
18
|
+
{subject: tds[1].text,
|
19
|
+
teacher: tds[2].text,
|
20
|
+
title: tds[3].text,
|
21
|
+
period: tds[4].text,
|
22
|
+
state: tds[5].text,
|
23
|
+
links: tds[6].css('li').map{|li| parse_link(li)},}.freeze
|
24
|
+
end
|
25
|
+
|
26
|
+
def parse_link(link)
|
27
|
+
{name: Kuport.escape_filename(link.text),
|
28
|
+
path: Kuport.to_abs_url(base_url, link.at_css('a')[:href]),}.freeze
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_h
|
32
|
+
materials
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_s
|
36
|
+
@materials_s ||= materials.to_s
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_json(*a)
|
40
|
+
@materials_json ||= to_h.to_json(*a)
|
41
|
+
end
|
42
|
+
end
|
data/lib/kuport/message.rb
CHANGED
data/lib/kuport/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kuport
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- u+
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-07-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -83,6 +83,7 @@ files:
|
|
83
83
|
- kuport.gemspec
|
84
84
|
- lib/kuport.rb
|
85
85
|
- lib/kuport/helper.rb
|
86
|
+
- lib/kuport/materials.rb
|
86
87
|
- lib/kuport/message.rb
|
87
88
|
- lib/kuport/timetable.rb
|
88
89
|
- lib/kuport/version.rb
|
@@ -107,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
107
108
|
version: '0'
|
108
109
|
requirements: []
|
109
110
|
rubyforge_project:
|
110
|
-
rubygems_version: 2.6.
|
111
|
+
rubygems_version: 2.6.11
|
111
112
|
signing_key:
|
112
113
|
specification_version: 4
|
113
114
|
summary: Kuport scraping library and command
|