saber 0.0.7 → 1.0.0
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.
- data/.gitignore +1 -0
- data/.travis.yml +4 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +18 -8
- data/Gemfile.lock +72 -33
- data/Guardfile +4 -0
- data/README.md +192 -52
- data/Rakefile +46 -0
- data/bin/1saber +5 -3
- data/bin/saber +4 -0
- data/bin/saber.bib +3 -0
- data/bin/saber.what +3 -0
- data/extconf.rb +4 -1
- data/lib/saber.rb +7 -13
- data/lib/saber/autofetcher.rb +8 -0
- data/lib/saber/autofetcher/client.rb +66 -0
- data/lib/saber/autofetcher/server.rb +78 -0
- data/lib/saber/cli.rb +65 -26
- data/lib/saber/{downloader.rb → fetcher.rb} +9 -11
- data/lib/saber/mechanize_ext.rb +136 -0
- data/lib/saber/rc.rb +3 -21
- data/lib/saber/task.rb +26 -11
- data/lib/saber/task/base.rb +18 -0
- data/lib/saber/task/clean.rb +18 -0
- data/lib/saber/task/generate.rb +38 -0
- data/lib/saber/task/make.rb +44 -0
- data/lib/saber/task/send.rb +21 -0
- data/lib/saber/task/upload.rb +37 -0
- data/lib/saber/tracker.rb +28 -0
- data/lib/saber/tracker/base.rb +115 -2
- data/lib/saber/tracker/bb.rb +244 -0
- data/lib/saber/tracker/bib.rb +225 -0
- data/lib/saber/tracker/ptp.rb +100 -0
- data/lib/saber/tracker/what.rb +55 -7
- data/lib/saber/ui.rb +65 -22
- data/lib/saber/version.rb +1 -1
- data/rutorrent/init.js +8 -9
- data/rutorrent/plugin.info +1 -1
- data/saber.gemspec +14 -10
- data/spec/data/_saber/.gitkeep +0 -0
- data/spec/saber/downloader_spec.rb +5 -2
- data/spec/saber/task_spec.rb +16 -0
- data/spec/saber/tracker/bib_spec.rb +24 -0
- data/spec/spec_helper.rb +25 -0
- data/templates/_saberrc +36 -0
- data/templates/bb/anime.yml +6 -0
- data/templates/bb/application.yml +7 -0
- data/templates/bb/audiobook.yml +12 -0
- data/templates/bb/comic.yml +7 -0
- data/templates/bb/documentary.yml +26 -0
- data/templates/bb/ebook.yml +8 -0
- data/templates/bb/elearning_video.yml +7 -0
- data/templates/bb/game_console.yml +6 -0
- data/templates/bb/game_pc.yml +6 -0
- data/templates/bb/magazine.yml +6 -0
- data/templates/bb/misc.yml +6 -0
- data/templates/bb/movie.yml +26 -0
- data/templates/bb/music.yml +21 -0
- data/templates/bb/tv.yml +6 -0
- data/templates/bib/application.yml +9 -0
- data/templates/bib/article.yml +18 -0
- data/templates/bib/audiobook.yml +17 -0
- data/templates/bib/comic.yml +22 -0
- data/templates/bib/ebook.yml +20 -0
- data/templates/bib/journal.yml +18 -0
- data/templates/bib/magazine.yml +18 -0
- data/templates/ptp/movie.yml +63 -0
- data/templates/ptp/movie_add.yml +35 -0
- data/templates/what/ebook.yml +6 -0
- data/templates/what/music.yml +2 -0
- data/templates/what/music_add.yml +2 -0
- metadata +182 -26
- data/doc/Development.md +0 -3
- data/lib/saber/client.rb +0 -58
- data/lib/saber/server.rb +0 -70
- data/saber.watchr +0 -23
@@ -0,0 +1,100 @@
|
|
1
|
+
require "active_support/core_ext/object/try"
|
2
|
+
|
3
|
+
module Saber
|
4
|
+
module Tracker
|
5
|
+
class PTP < Base
|
6
|
+
@@BASE_URL = "https://tls.passthepopcorn.me"
|
7
|
+
@@LOGIN_CHECK_PATH = "/inbox.php"
|
8
|
+
|
9
|
+
FIELDS = {
|
10
|
+
"new" => {
|
11
|
+
"file_input" => :file_upload,
|
12
|
+
"type" => :select_list,
|
13
|
+
"title" => :text,
|
14
|
+
"year" => :text,
|
15
|
+
"image" => :text,
|
16
|
+
"trailer" => :text,
|
17
|
+
"special" => :checkbox,
|
18
|
+
"remaster" => :checkbox,
|
19
|
+
"scene" => :checkbox,
|
20
|
+
"source" => :select_list,
|
21
|
+
"codec" => :select_list,
|
22
|
+
"container" => :select_list,
|
23
|
+
"resolution" => :select_list,
|
24
|
+
"tags" => :text,
|
25
|
+
"album_desc" => :text,
|
26
|
+
"release_desc" => :text,
|
27
|
+
},
|
28
|
+
|
29
|
+
"add" => {
|
30
|
+
"file_input" => :file_upload,
|
31
|
+
"special" => :checkbox,
|
32
|
+
"remaster" => :checkbox,
|
33
|
+
"scene" => :checkbox,
|
34
|
+
"source" => :select_list,
|
35
|
+
"codec" => :select_list,
|
36
|
+
"container" => :select_list,
|
37
|
+
"resolution" => :select_list,
|
38
|
+
"release_desc" => :text,
|
39
|
+
},
|
40
|
+
}
|
41
|
+
|
42
|
+
def do_upload(file, info)
|
43
|
+
info["file_input"] = "#{file}.torrent"
|
44
|
+
path = info["group_id"] ? "/upload.php?group_id=#{info['group_id']}" : "/upload.php"
|
45
|
+
agent.get(path) {|p|
|
46
|
+
ret = p.form_with(action: "") {|f|
|
47
|
+
FIELDS[info.type].each {|k,t|
|
48
|
+
f.set(t, k, info[k])
|
49
|
+
}
|
50
|
+
|
51
|
+
# subtitles[]
|
52
|
+
info["subtitles"].each {|subtitle|
|
53
|
+
f.checkboxes("subtitles[]").find {|checkbox|
|
54
|
+
checkbox.node.at("following-sibling::label").inner_text == subtitle
|
55
|
+
}.check
|
56
|
+
}
|
57
|
+
}.submit
|
58
|
+
|
59
|
+
# error
|
60
|
+
if ret.uri.path =~ %~^/upload.php~
|
61
|
+
errors = ret.search("//*[class='bvalidator_errmsg']")
|
62
|
+
msg = errors.map{|e| "- #{ReverseMarkdown.parse(e)}" }.join("\n\n")
|
63
|
+
Saber.ui.error "ERROR:\n #{msg}"
|
64
|
+
return false
|
65
|
+
else
|
66
|
+
return true
|
67
|
+
end
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
protected
|
72
|
+
|
73
|
+
def do_login_with_username
|
74
|
+
agent.get("/login.php") { |p|
|
75
|
+
ret = p.form_with(action: "login.php" ) {|f|
|
76
|
+
# error
|
77
|
+
unless f
|
78
|
+
Saber.ui.error! p.at("//body").inner_html
|
79
|
+
end
|
80
|
+
|
81
|
+
f.username = username || ask("Username: ")
|
82
|
+
f.password = ask("Password: "){|q| q.echo = false}
|
83
|
+
f.checkbox(name: "keeplogged").check
|
84
|
+
}.submit
|
85
|
+
|
86
|
+
# error
|
87
|
+
if ret.uri.path == "/login.php"
|
88
|
+
msg = ret.at("//*[@id='loginfail']/p[1]").inner_text
|
89
|
+
Saber.ui.error "Faild. #{msg}"
|
90
|
+
return false
|
91
|
+
else
|
92
|
+
return true
|
93
|
+
end
|
94
|
+
}
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# vim: fdn=4
|
data/lib/saber/tracker/what.rb
CHANGED
@@ -1,20 +1,68 @@
|
|
1
1
|
module Saber
|
2
|
-
|
2
|
+
module Tracker
|
3
|
+
# DON'T WORK for mechanize does not support javascript.
|
3
4
|
class What < Base
|
4
|
-
|
5
|
-
|
5
|
+
@@BASE_URL = "https://what.cd"
|
6
|
+
@@LOGIN_CHECK_PATH = "/inbox.php"
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
FIELDS = {
|
9
|
+
"E-Books" => {
|
10
|
+
"file_input" => :file_upload,
|
11
|
+
"type" => :select_list,
|
12
|
+
"title" => :text,
|
13
|
+
"tags" => :text,
|
14
|
+
"image" => :text,
|
15
|
+
"desc" => :text
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
def do_upload(file, info)
|
20
|
+
info["file_input"] = "#{file}.torrent"
|
21
|
+
path = info["group_id"] ? "/upload.php?group_id=#{info['group_id']}" : "/upload.php"
|
10
22
|
|
23
|
+
agent.get(path) {|p|
|
24
|
+
ret = p.form_with(action: "") {|f|
|
25
|
+
FIELDS[info.type].each {|k,t|
|
26
|
+
f.set(t, k, info[k])
|
27
|
+
}
|
28
|
+
}.submit
|
11
29
|
|
30
|
+
# error
|
31
|
+
if ret.uri.path =~ %r~^/upload.php~
|
32
|
+
msg = ReverseMarkdown.parse(ret.at("//*[@id='content']/div[2]/p[2]"))
|
33
|
+
Saber.ui.error "ERROR:\n#{msg}"
|
34
|
+
return false
|
35
|
+
else
|
36
|
+
return true
|
37
|
+
end
|
38
|
+
}
|
39
|
+
end
|
12
40
|
|
41
|
+
protected
|
13
42
|
|
43
|
+
def do_login_with_username(username)
|
44
|
+
agent.get("/login.php") {|p|
|
45
|
+
ret = p.form_with(action: "login.php" ) {|f|
|
46
|
+
# error
|
47
|
+
unless f
|
48
|
+
Saber.ui.error! p.at("//body").inner_text
|
49
|
+
end
|
14
50
|
|
51
|
+
f.username = username || ask("Username: ")
|
52
|
+
f.password = ask("Password: "){|q| q.echo = false}
|
53
|
+
f.checkbox(name: "keeplogged").check
|
54
|
+
}.submit
|
15
55
|
|
56
|
+
# error
|
57
|
+
if ret.uri.path == "/login.php"
|
58
|
+
msg = ret.at("//*[@id='loginform']/span[2]").inner_text
|
59
|
+
Saber.ui.error "Failed. You have #{msg} attempts remaining."
|
60
|
+
return false
|
61
|
+
else
|
62
|
+
return true
|
63
|
+
end
|
64
|
+
}
|
16
65
|
end
|
17
|
-
|
18
66
|
end
|
19
67
|
end
|
20
68
|
end
|
data/lib/saber/ui.rb
CHANGED
@@ -1,60 +1,103 @@
|
|
1
1
|
module Saber
|
2
2
|
class UI
|
3
|
-
def
|
3
|
+
def initialize
|
4
|
+
@quiet = false
|
5
|
+
@debug = ENV["DEBUG"]
|
4
6
|
end
|
5
7
|
|
6
|
-
def
|
8
|
+
def info(msg)
|
9
|
+
do_info(msg) if !@quiet
|
7
10
|
end
|
8
11
|
|
9
|
-
def
|
12
|
+
def debug(msg)
|
13
|
+
do_debug(msg) if @debug && !@quiet
|
10
14
|
end
|
11
15
|
|
12
|
-
def
|
16
|
+
def warn(msg)
|
17
|
+
do_warn(msg)
|
13
18
|
end
|
14
19
|
|
15
|
-
def
|
20
|
+
def error(msg)
|
21
|
+
do_error(msg)
|
16
22
|
end
|
17
23
|
|
18
|
-
#
|
19
|
-
def
|
20
|
-
|
24
|
+
# error with exit
|
25
|
+
def error!(msg)
|
26
|
+
error(msg)
|
27
|
+
exit 1
|
28
|
+
end
|
29
|
+
|
30
|
+
def confirm(msg)
|
31
|
+
do_confirm(msg) if !@quiet
|
32
|
+
end
|
33
|
+
|
34
|
+
def say(msg)
|
35
|
+
info(msg)
|
36
|
+
end
|
37
|
+
|
38
|
+
def be_quiet!
|
39
|
+
@quiet = true
|
40
|
+
end
|
41
|
+
|
42
|
+
def debug!
|
43
|
+
@debug = true
|
21
44
|
end
|
22
45
|
|
23
46
|
class Shell < UI
|
24
47
|
attr_writer :shell
|
25
48
|
|
26
49
|
def initialize(shell)
|
50
|
+
super()
|
27
51
|
@shell = shell
|
28
|
-
@quiet = false
|
29
|
-
@debug = ENV['DEBUG']
|
30
52
|
end
|
31
53
|
|
32
|
-
def
|
54
|
+
def do_info(msg)
|
55
|
+
@shell.say(msg) if !@quiet
|
56
|
+
end
|
57
|
+
|
58
|
+
def do_debug(msg)
|
33
59
|
@shell.say(msg) if @debug && !@quiet
|
34
60
|
end
|
35
61
|
|
36
|
-
def
|
37
|
-
@shell.say(msg)
|
62
|
+
def do_warn(msg)
|
63
|
+
@shell.say(msg, :yellow)
|
64
|
+
end
|
65
|
+
|
66
|
+
def do_error(msg)
|
67
|
+
@shell.say(msg, :red)
|
38
68
|
end
|
39
69
|
|
40
|
-
def
|
70
|
+
def do_confirm(msg)
|
41
71
|
@shell.say(msg, :green) if !@quiet
|
42
72
|
end
|
73
|
+
end
|
43
74
|
|
44
|
-
|
45
|
-
|
75
|
+
class Logger < UI
|
76
|
+
attr_accessor :logger
|
77
|
+
|
78
|
+
def initialize(logger)
|
79
|
+
super()
|
80
|
+
@logger = logger
|
46
81
|
end
|
47
82
|
|
48
|
-
def
|
49
|
-
@
|
83
|
+
def do_debug(msg)
|
84
|
+
@logger.debug(msg)
|
85
|
+
end
|
86
|
+
|
87
|
+
def do_info(msg)
|
88
|
+
@logger.info(msg)
|
89
|
+
end
|
90
|
+
|
91
|
+
def do_confirm(msg)
|
92
|
+
@logger.confirm(msg)
|
50
93
|
end
|
51
94
|
|
52
|
-
def
|
53
|
-
@
|
95
|
+
def do_warn(msg)
|
96
|
+
@logger.warn(msg)
|
54
97
|
end
|
55
98
|
|
56
|
-
def
|
57
|
-
@
|
99
|
+
def do_error(msg)
|
100
|
+
@logger.error(msg)
|
58
101
|
end
|
59
102
|
end
|
60
103
|
end
|
data/lib/saber/version.rb
CHANGED
data/rutorrent/init.js
CHANGED
@@ -1,28 +1,27 @@
|
|
1
|
-
pd = console.log
|
1
|
+
pd = function(){ console.log.apply(console, arguments) }
|
2
2
|
|
3
3
|
if(plugin.canChangeMenu())
|
4
4
|
{
|
5
|
-
theWebUI.
|
6
|
-
theWebUI.perform("
|
5
|
+
theWebUI.saberFetch = function(id){
|
6
|
+
theWebUI.perform("saberFetch");
|
7
7
|
}
|
8
8
|
|
9
9
|
plugin.createMenu = theWebUI.createMenu;
|
10
10
|
theWebUI.createMenu = function( e, id )
|
11
11
|
{
|
12
12
|
plugin.createMenu.call(this, e, id);
|
13
|
-
if(plugin.enabled)
|
13
|
+
if (plugin.enabled)
|
14
14
|
{
|
15
|
-
|
16
|
-
if( el )
|
17
|
-
theContextMenu.add( el, ["Saber Download", "theWebUI.saberDownload('"+id+"')"]);
|
15
|
+
theContextMenu.add(["Saber Fetch", "theWebUI.saberFetch('"+id+"')"]);
|
18
16
|
}
|
19
17
|
}
|
20
18
|
}
|
21
19
|
|
22
|
-
rTorrentStub.prototype.
|
20
|
+
rTorrentStub.prototype.saberFetch = function()
|
23
21
|
{
|
24
22
|
var cmd = new rXMLRPCCommand("execute");
|
25
|
-
cmd.addParameter("string", "
|
23
|
+
cmd.addParameter("string", "saber-drb_add");
|
26
24
|
cmd.addParameter("string", this.hashes.join(","));
|
25
|
+
cmd.addParameter("string", "saber");
|
27
26
|
this.commands.push(cmd);
|
28
27
|
}
|
data/rutorrent/plugin.info
CHANGED
data/saber.gemspec
CHANGED
@@ -1,12 +1,11 @@
|
|
1
|
-
|
2
|
-
require "saber/version"
|
1
|
+
Kernel.load File.expand_path("../lib/saber/version.rb", __FILE__)
|
3
2
|
|
4
3
|
spec = Gem::Specification.new do |s|
|
5
4
|
s.name = "saber"
|
6
5
|
s.version = Saber::VERSION
|
7
|
-
s.summary = "
|
6
|
+
s.summary = "A complete solution for PT users."
|
8
7
|
s.description = <<-EOF
|
9
|
-
|
8
|
+
A complete solution for PT users.
|
10
9
|
EOF
|
11
10
|
|
12
11
|
s.author = "GutenYe"
|
@@ -18,10 +17,15 @@ the saber
|
|
18
17
|
s.executables = ["saber"]
|
19
18
|
s.extensions << "extconf.rb"
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
20
|
+
s.add_dependency "pd", ">= 0"
|
21
|
+
s.add_dependency "tagen", "~> 2.0.1"
|
22
|
+
s.add_dependency "optimism", "~> 3.3.1"
|
23
|
+
s.add_dependency "pa", "~> 1.3.2"
|
24
|
+
s.add_dependency "retort", "~> 0.0.6"
|
25
|
+
s.add_dependency "thor", "~> 0.16.0"
|
26
|
+
s.add_dependency "net-ssh", "~> 2.5.2"
|
27
|
+
s.add_dependency "xmpp4r", "~> 0.5"
|
28
|
+
s.add_dependency "mechanize", "~> 2.5.1"
|
29
|
+
s.add_dependency "highline", "~> 1.6.14"
|
30
|
+
s.add_dependency "reverse_markdown", "~> 0.3.0"
|
27
31
|
end
|
File without changes
|
@@ -2,7 +2,11 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
Downloader = Saber::Downloader
|
4
4
|
|
5
|
-
|
5
|
+
|
6
|
+
uri="Microsoft Office 2010 Professional Plus (Activator Included)/KMS Activator for Microsoft Office 2010 Applications x86 x64 Multilingual-FIXISO~DiBYA/mini-KMS_Activator_v1.053.exe"
|
7
|
+
|
8
|
+
|
9
|
+
xdescribe Downloader do
|
6
10
|
describe "test everyting" do
|
7
11
|
it "works" do
|
8
12
|
XMLRPC::Client.stub(:new2)
|
@@ -14,4 +18,3 @@ describe Downloader do
|
|
14
18
|
end
|
15
19
|
end
|
16
20
|
end
|
17
|
-
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
Task = Saber::Task
|
4
|
+
|
5
|
+
class Task::HelloTest < Task::Base
|
6
|
+
def invoke(*args)
|
7
|
+
args
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe Task do
|
12
|
+
it "(complete example)" do
|
13
|
+
expect(Task["hello_test"]).to be(Task::HelloTest)
|
14
|
+
expect(Task["hello_test"].invoke(1, 2)).to eq([1, 2])
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
=begin
|
2
|
+
require "spec_helper"
|
3
|
+
require "saber/tracker/bib"
|
4
|
+
|
5
|
+
BIB = Saber::Tracker::BIB
|
6
|
+
|
7
|
+
describe BIB do
|
8
|
+
it do
|
9
|
+
VCR.use_cassette("bib", record: :new_episodes) do
|
10
|
+
#VCR.use_cassette("bib", record: :all) do
|
11
|
+
a = Mechanize.new
|
12
|
+
#a.get "http://www.google.com"
|
13
|
+
#ret = a.get "http://www.g.cn"
|
14
|
+
#a.get "http://bibliotik.org/"
|
15
|
+
#ret = a.get "http://bibliotik.org/login"
|
16
|
+
#ret = a.get "http://what.cd/"
|
17
|
+
#pd ret.uri
|
18
|
+
|
19
|
+
bib = BIB.new
|
20
|
+
bib.login
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
=end
|