saber 1.2.3 → 1.2.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,17 @@
1
- ## 1.2.0 (xx)
1
+ ## 1.2.4 (Nov 4, 2012)
2
+
3
+ **Improvements**
4
+
5
+ - better book description for bB.
6
+ - auto generate tags from goodreads.
7
+ - add per-tracker mktorrent options.
8
+ - configration add '<tracker>.mktorrent_options', 'api_url'.
9
+
10
+ **Changes**
11
+
12
+ - configuration changes from 'upload.move_yml, upload.move_torrent' to 'upload.archive'
13
+
14
+ ## 1.2.0 (Nov 1, 2012)
2
15
 
3
16
  **Improvements**
4
17
 
data/Gemfile CHANGED
@@ -1,9 +1,9 @@
1
1
  source "https://rubygems.org"
2
2
 
3
3
  gem "pd"
4
- gem "tagen", "~>2.0.1"
4
+ gem "tagen", "~>2.0.2"
5
5
  gem "optimism", "~>3.3.1"
6
- gem "pa", "~>1.3.3"
6
+ gem "pa", "~>1.4.0"
7
7
  gem "retort", "~>0.0.6"
8
8
  gem "thor", "~>0.16.0"
9
9
  gem "net-ssh", "~>2.5.2"
@@ -24,7 +24,6 @@ group :development do
24
24
  gem "guard"
25
25
  gem "guard-rspec"
26
26
  gem "rb-inotify"
27
- #gem "rag", path: "/home/guten/dev/one/rag"
28
27
  end
29
28
 
30
29
  # gemspec
@@ -66,7 +66,7 @@ GEM
66
66
  optimism (3.3.1)
67
67
  json
68
68
  pd
69
- pa (1.3.3)
69
+ pa (1.4.0)
70
70
  pd
71
71
  pd (1.1.0)
72
72
  pry (0.9.10)
@@ -95,7 +95,7 @@ GEM
95
95
  slop (3.3.3)
96
96
  sys-filesystem (1.0.0)
97
97
  ffi (>= 1.0.0)
98
- tagen (2.0.1)
98
+ tagen (2.0.2)
99
99
  activesupport
100
100
  pd
101
101
  thor (0.16.0)
@@ -127,14 +127,14 @@ DEPENDENCIES
127
127
  mechanize (~> 2.5.1)
128
128
  net-ssh (~> 2.5.2)
129
129
  optimism (~> 3.3.1)
130
- pa (~> 1.3.3)
130
+ pa (~> 1.4.0)
131
131
  pd
132
132
  rb-inotify
133
133
  retort (~> 0.0.6)
134
134
  reverse_markdown (~> 0.3.0)
135
135
  rspec
136
136
  sys-filesystem (~> 1.0.0)
137
- tagen (~> 2.0.1)
137
+ tagen (~> 2.0.2)
138
138
  thor (~> 0.16.0)
139
139
  vcr
140
140
  watir (~> 4.0.1)
data/extconf.rb CHANGED
@@ -13,8 +13,6 @@ gem_home = if Gem.dir.match(%~/(\.rvm|\.rbenv)/~)
13
13
  end
14
14
  dist_bindir = ENV["GEM_BINDIR"] || Gem.bindir(gem_home)
15
15
 
16
- p Gem.dir, Gem.user_dir
17
-
18
16
  FileUtils.install File.join(bindir, "saber-drb_add"), dist_bindir
19
17
  FileUtils.install File.join(bindir, "saber.bib"), dist_bindir
20
18
  FileUtils.install File.join(bindir, "saber.bb"), dist_bindir
@@ -42,7 +42,7 @@ module Saber
42
42
  private
43
43
 
44
44
  def convert_bibtags(tags)
45
- tags.map{|v|
45
+ tags.map {|v|
46
46
  v.gsub(/ \(programming\)/i, '')
47
47
  }.sort_by {|v|
48
48
  %w[fiction nonfiction].include?(v) ? -1 : tags.index(v)
@@ -22,7 +22,7 @@ module Saber
22
22
  if options["force"]
23
23
  Pa.rm torrent_file
24
24
  else
25
- Saber.ui.say "Skip make: #{file} (torrent alreay exists. use -f to overwrite it.)"
25
+ Saber.ui.say "SKIP make: #{torrent_file} (torrent alreay exists. use --force to overwrite it.)"
26
26
  next
27
27
  end
28
28
  end
@@ -32,7 +32,9 @@ module Saber
32
32
  next
33
33
  end
34
34
 
35
- system "mktorrent -p -a #{Rc[tracker_name].announce_url} #{file.shellescape} #{options['option']}", show_cmd: true
35
+ extra_options = Rc._fetch(["#{tracker_name}.mktorrent_options", "mktorrent_options"], "")
36
+ cmd = "mktorrent -p #{extra_options} -a #{Rc[tracker_name].announce_url} #{file.shellescape} #{options['option']}"
37
+ system cmd, show_cmd: "$"
36
38
 
37
39
  # cp tororent file
38
40
  if Rc._has_key?("make.watch")
@@ -26,7 +26,6 @@ module Saber
26
26
  # make torrent if torrent_file not exists.
27
27
  filemap.each { |file, torrent_file|
28
28
  if not Pa.exists?(torrent_file)
29
-
30
29
  if not Pa.exists?(file)
31
30
  Saber.ui.error "SKIP: Can't find torrent_file nor file -- #{file}"
32
31
  filemap.delete(file)
@@ -18,8 +18,6 @@ module Saber
18
18
 
19
19
  class << self
20
20
  def [](name)
21
- require "saber/tracker/#{name}"
22
-
23
21
  trackers[name]
24
22
  end
25
23
  end
@@ -27,7 +25,10 @@ module Saber
27
25
  end
28
26
 
29
27
  require "saber/tracker/base"
28
+ require "saber/tracker/gazelle"
30
29
  require "saber/tracker/what"
30
+ require "saber/tracker/bb"
31
31
  require "saber/tracker/bib"
32
32
  require "saber/tracker/stp"
33
33
 
34
+
@@ -6,6 +6,8 @@ module Saber
6
6
  DELEGATE_METHODS = [:get]
7
7
 
8
8
  def self.inherited(child)
9
+ return if [Gazelle].include?(child)
10
+
9
11
  Tracker.trackers[child.name.demodulize.underscore] = child
10
12
  end
11
13
 
@@ -28,10 +30,10 @@ module Saber
28
30
  BASE_URL = ""
29
31
  LOGIN_CHECK_PATH = ""
30
32
 
31
- attr_reader :agent
32
- attr_reader :name
33
+ attr_reader :agent, :name, :options
33
34
 
34
- def initialize
35
+ def initialize(options={})
36
+ @options = options
35
37
  @agent = Mechanize.new
36
38
  end
37
39
 
@@ -1,7 +1,6 @@
1
1
  module Saber
2
2
  module Tracker
3
- # DOESN'T WORK for mechanize does not support javascript.
4
- class BB < Base
3
+ class BB < Gazelle
5
4
  BASE_URL = "https://baconbits.org"
6
5
  LOGIN_CHECK_PATH = "/inbox.php"
7
6
 
@@ -179,32 +178,6 @@ module Saber
179
178
  },
180
179
  }
181
180
 
182
- # Upload one torrent file to the site.
183
- #
184
- # @param [String] file a filename
185
- # @param [Optimism] info comes from <file>.yml data file.
186
- #
187
- # @return [Boolean] result-code
188
- def do_upload(file, info)
189
- info["file_input"] = "#{file}.torrent"
190
-
191
- agent.get("/upload.php") {|p|
192
- ret = p.form_with(action: "") {|f|
193
- FIELDS[info.type].each {|k,t|
194
- f.set(t, k, info[k])
195
- }
196
- }.submit
197
-
198
- if ret.uri.path == "/upload.php"
199
- msg = ReverseMarkdown.parse(ret.at("//*[@id='content']/div[2]/p[2]"))
200
- Saber.ui.error "ERROR: #{msg.to_s.strip}\n"
201
- return false
202
- else
203
- return true
204
- end
205
- }
206
- end
207
-
208
181
  protected
209
182
 
210
183
  # Attpened to login the site with username and password. this happens
@@ -182,6 +182,10 @@ module Saber
182
182
  ret
183
183
  end
184
184
 
185
+ def convert_tags(*tags)
186
+ tags
187
+ end
188
+
185
189
  protected
186
190
 
187
191
  # Attpened to login the site with username and password. this happens
@@ -1,7 +1,16 @@
1
1
  module Saber
2
2
  module Tracker
3
- class Gazelle
3
+ class Gazelle < Base
4
+ TAG_MAP = {
5
+ "nonfiction" => "non.fiction"
6
+ }
4
7
 
8
+ def convert_tags(*tags)
9
+ tags.map {|tag|
10
+ tag = tag.downcase.gsub(/&/, "and").gsub(/ +/, ".").gsub(/'/, "")
11
+ self.class::TAG_MAP[tag] || tag
12
+ }
13
+ end
5
14
  end
6
15
  end
7
16
  end
@@ -1,13 +1,9 @@
1
1
  module Saber
2
2
  module Tracker
3
- class STP < Base
3
+ class STP < Gazelle
4
4
  BASE_URL = "https://stopthepress.es"
5
5
  LOGIN_CHECK_PATH = "/inbox.php"
6
6
 
7
- TAG_MAP = {
8
- "nonfiction" => "non.fiction"
9
- }
10
-
11
7
  def exists?(o={})
12
8
  url = "/torrents.php?cataloguenumber=#{o[:isbn]}"
13
9
  page = agent.get(url)
@@ -15,14 +11,6 @@ module Saber
15
11
  not page.at("//*[@id='content']/div[2]/h2[contains(text(), 'Your search did not match anything.')]")
16
12
  end
17
13
 
18
- def convert_tags(*tags)
19
- tags.map{|tag|
20
- tag = tag.downcase.gsub(/&/, "and").gsub(/\s+/, ".").gsub(/'/, "")
21
-
22
- TAG_MAP.fetch(tag, tag)
23
- }
24
- end
25
-
26
14
  protected
27
15
 
28
16
  def do_login_with_username(username)
@@ -1,7 +1,6 @@
1
1
  module Saber
2
2
  module Tracker
3
- # DON'T WORK for mechanize does not support javascript.
4
- class What < Base
3
+ class What < Gazelle
5
4
  BASE_URL = "https://what.cd"
6
5
  LOGIN_CHECK_PATH = "/inbox.php"
7
6
 
@@ -16,28 +15,6 @@ module Saber
16
15
  }
17
16
  }
18
17
 
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"
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
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
40
-
41
18
  protected
42
19
 
43
20
  def do_login_with_username(username)
@@ -1,5 +1,5 @@
1
1
  require "watir"
2
- require "saber/watir_ext"
2
+ require "tagen/watir"
3
3
  require "reverse_markdown"
4
4
  require "active_support/core_ext/module/attribute_accessors"
5
5
 
@@ -15,8 +15,6 @@ module Saber
15
15
 
16
16
  class << self
17
17
  def [](name)
18
- require "saber/tracker2/#{name}"
19
-
20
18
  trackers[name]
21
19
  end
22
20
  end
@@ -27,5 +25,5 @@ require "saber/tracker2/base"
27
25
  require "saber/tracker2/gazelle"
28
26
  require "saber/tracker2/what"
29
27
  require "saber/tracker2/bib"
28
+ require "saber/tracker2/bb"
30
29
  require "saber/tracker2/stp"
31
-
@@ -4,6 +4,8 @@ module Saber
4
4
  module Tracker2
5
5
  class Base
6
6
  def self.inherited(child)
7
+ return if [Gazelle].include?(child)
8
+
7
9
  Tracker2.trackers[child.name.demodulize.underscore] = child
8
10
  end
9
11
 
@@ -15,23 +17,18 @@ module Saber
15
17
 
16
18
  def initialize(options={})
17
19
  @name = self.class.name.demodulize.underscore
18
- @agent = Watir::Browser.new *Rc.browser
19
20
  @options = options
20
- #@agent.load_cookies("#{Rc.p.home}/#{name}.cookies")
21
-
22
- # share cookies
23
- launcher = agent.driver.instance_variable_get("@bridge").instance_variable_get("@launcher")
24
- origin_profile_dir = launcher.instance_variable_get("@profile").instance_variable_get("@model")
25
- profile_dir = launcher.instance_variable_get("@profile_dir")
26
-
27
- Pa.symln_f "#{origin_profile_dir}/cookies.sqlite", "#{profile_dir}/cookies.sqlite"
21
+ @agent = Watir::Browser.new(*Rc.browser)
22
+ @agent.keep_cookies!
28
23
  end
29
24
 
30
25
  def upload(format, filemap, o={})
31
26
  failed_counts = 0
32
27
 
33
28
  filemap.each {|file, torrent_file|
34
- info0 = YAML.load_file("#{file}.yml")
29
+ yaml_file = "#{file}.yml"
30
+ info0 = YAML.load_file(yaml_file)
31
+ is_archived = torrent_file.to_s.start_with?("#{name}/")
35
32
 
36
33
  # current release only support ebook type.
37
34
  Saber.ui.error "Current doesn't support this upload_type -- #{info0['upload_type']}." unless
@@ -60,7 +57,7 @@ module Saber
60
57
 
61
58
  # skip empty description.
62
59
  if info[:description].empty?
63
- Saber.ui.error "SKIP: Empty description -- #{file}.yml"
60
+ Saber.ui.error "SKIP: Empty description -- yaml_file"
64
61
  next
65
62
  end
66
63
 
@@ -74,12 +71,24 @@ module Saber
74
71
  end
75
72
  end
76
73
 
74
+ process_info!(info)
77
75
  upload_method = o[:add] ? :add_format : :new_upload
78
76
  if send(upload_method, info)
79
77
  Saber.ui.say "Upload Complete: #{file}"
80
78
 
81
- Pa.mv "#{file}.yml", Rc.upload.move_yml if Rc._has_key?("upload.move_yml")
82
- Pa.mv torrent_file, Rc.upload.move_torrent if Rc._has_key?("upload.move_torrent")
79
+ # archive
80
+ if !is_archived and Rc._has_key?("upload.archive")
81
+ archive = case (archive=Rc.upload.archive)
82
+ when Proc
83
+ archive.call(info[:upload_type])
84
+ else
85
+ archive
86
+ end
87
+
88
+ Pa.mv yaml_file, archive, mkdir: true
89
+ Pa.mv torrent_file, "#{archive}/#{name}", mkdir: true
90
+ end
91
+
83
92
  else
84
93
  failed_counts += 1
85
94
  Saber.ui.error "SKIP: Upload failed -- #{file}"
@@ -119,6 +128,10 @@ module Saber
119
128
  def add_format(info)
120
129
  raise NotImplementedError
121
130
  end
131
+
132
+ def process_info!(info)
133
+ info
134
+ end
122
135
  end
123
136
  end
124
137
  end
@@ -194,7 +194,7 @@ module Saber
194
194
  sleep 0.1
195
195
 
196
196
  FIELDS[info[:upload_type]].each {|key, selector|
197
- form.quick_set(selector, info[key])
197
+ form.set2(selector, info[key])
198
198
  }
199
199
 
200
200
  # comic
@@ -204,6 +204,19 @@ module Saber
204
204
  }
205
205
  end
206
206
  end
207
+
208
+ def process_info!(info)
209
+ info[:description] = <<-EOF
210
+
211
+ [size=3][b][color=#FF3300]Book Details:[/color][/b][/size]
212
+ [size=2][quote]
213
+ #{info[:release_description].strip}
214
+ [/quote][/size]
215
+ [size=3][b][color=#FF3300]Book Description:[/color][/b][/size]
216
+ [quote][size=2]#{info[:description].strip}
217
+ [/size][/quote]
218
+ EOF
219
+ end
207
220
  end
208
221
  end
209
222
  end
@@ -133,15 +133,13 @@ module Saber
133
133
  }
134
134
 
135
135
  def new_upload(info)
136
- info[:complete] = (info[:type] == "Pack")
137
-
138
136
  agent.goto "#{BASE_URL}/upload/#{info[:upload_type2]}"
139
137
  check_login %r~/upload/#{info[:upload_type2]}~
140
138
 
141
139
  form = agent.form(action: "")
142
140
 
143
141
  FIELDS[info[:upload_type]].each {|key, selector|
144
- form.quick_set(selector, info[key])
142
+ form.set2(selector, info[key])
145
143
  }
146
144
 
147
145
  form.submit()
@@ -155,6 +153,11 @@ module Saber
155
153
  return true
156
154
  end
157
155
  end
156
+
157
+ def process_info!(info)
158
+ info[:complete] = (info[:type] == "Pack")
159
+ info[:description] = "#{info[:release_description].strip}\n\n#{info[:description]}"
160
+ end
158
161
  end
159
162
  end
160
163
  end
@@ -95,7 +95,7 @@ module Saber
95
95
  end
96
96
 
97
97
  ADD_FIELDS[info[:upload_type]].each {|key, selector|
98
- form.quick_set(selector, check_value!(info[key]))
98
+ form.set2(selector, check_value!(info[key]))
99
99
  }
100
100
  end
101
101
 
@@ -119,7 +119,7 @@ module Saber
119
119
  end
120
120
 
121
121
  FIELDS[info[:upload_type]].each {|key, selector|
122
- form.quick_set(selector, info[key])
122
+ form.set2(selector, info[key])
123
123
  }
124
124
 
125
125
  # authors
@@ -35,7 +35,7 @@ module Saber
35
35
  sleep 0.1
36
36
 
37
37
  FIELDS[info[:type]].each {|key, selector|
38
- form.quick_set(selector, info[key])
38
+ form.set2(selector, info[key])
39
39
  }
40
40
 
41
41
  form.submit()
@@ -1,3 +1,3 @@
1
1
  module Saber
2
- VERSION = "1.2.3"
2
+ VERSION = "1.2.4"
3
3
  end
@@ -1,4 +1,5 @@
1
1
  browser = [:firefox, {profile: "default"}]
2
+ #api_url = "http://saberapi.heroku.com"
2
3
 
3
4
  make:
4
5
  #dir = Pa(".") # move to directory.
@@ -9,8 +10,8 @@ find_uploads:
9
10
  #dir = Pa("~/bt/watch")
10
11
 
11
12
  upload:
12
- #move_yml = Pa("done")
13
- #move_torrent = Pa("done")
13
+ archive = proc {|upload_type| upload_type}
14
+ #archive = "archive"
14
15
 
15
16
  fetch:
16
17
  dir = Pa("~/downloads") # aria2 download directory.
@@ -23,11 +24,13 @@ server:
23
24
  user = "x" # seedbox login name
24
25
  host = "seedbox" # set seedbox ip address in /etc/hosts
25
26
 
26
- # [saber-upload]
27
- username = "foo" # default username for login into site.
27
+ # [saber-upload] [saber-make]
28
+ username = "foo" # global username for login into site.
29
+ #mktorrent_options = "" # global mktorrent options.
28
30
 
29
31
  bib:
30
- #username = "bar" # per-site username. use default username if not set.
32
+ #username = "bar" # per-tracker username. use default username if not set.
33
+ #mktorrent_options = "-l 17" # per-tracker mktorrent options.
31
34
  announce_url = "x"
32
35
 
33
36
  chd:
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: saber
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ version: 1.2.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-02 00:00:00.000000000 Z
12
+ date: 2012-11-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: pd
@@ -335,7 +335,6 @@ files:
335
335
  - lib/saber/tracker2/what.rb
336
336
  - lib/saber/ui.rb
337
337
  - lib/saber/version.rb
338
- - lib/saber/watir_ext.rb
339
338
  - rutorrent/init.js
340
339
  - rutorrent/init.php
341
340
  - rutorrent/plugin.info
@@ -1,95 +0,0 @@
1
- # Cookies
2
- module Watir
3
- class Browser
4
- # Read cookies from Mozilla cookies.txt-style IO stream
5
- #
6
- # @param file [IO,String]
7
- #
8
- def load_cookies(file)
9
- now = ::Time.now
10
-
11
- io = case file
12
- when String
13
- open(file)
14
- else
15
- file
16
- end
17
-
18
- io.each_line do |line|
19
- line.chomp!
20
- line.gsub!(/#.+/, '')
21
- fields = line.split("\t")
22
-
23
- next if fields.length != 7
24
-
25
- name, value, domain, for_domain, path, secure, version = fields[5], fields[6],
26
- fields[0], (fields[1] == "TRUE"), fields[2], (fields[3] == "TRUE"), 0
27
-
28
- expires_seconds = fields[4].to_i
29
- expires = (expires_seconds == 0) ? nil : ::Time.at(expires_seconds)
30
- next if expires and (expires < now)
31
-
32
- cookies.add(name, value, domain: domain, path: path, expires: expires, secure: secure)
33
- end
34
-
35
- io.close if String === file
36
-
37
- self
38
- end
39
-
40
- # Write cookies to Mozilla cookies.txt-style IO stream
41
- #
42
- # @param file [IO,String]
43
- def dump_cookies(file)
44
- io = case file
45
- when String
46
- open(file, "w")
47
- else
48
- file
49
- end
50
-
51
- cookies.to_a.each do |cookie|
52
- io.puts([
53
- cookie[:domain],
54
- "FALSE", # for_domain
55
- cookie[:path],
56
- cookie[:secure] ? "TRUE" : "FALSE",
57
- cookie[:expires].to_i.to_s,
58
- cookie[:name],
59
- cookie[:value]
60
- ].join("\t"))
61
- end
62
-
63
- io.close if String === file
64
-
65
- self
66
- end
67
- end
68
- end
69
-
70
- # Element
71
- module Watir
72
- class Element
73
- # quick set value.
74
- #
75
- # @example
76
- #
77
- # form = browser.form
78
- # form.quick_set("//input[@name='value']", "hello")
79
- # form.quick_set("//input[@name='check']", true)
80
- # form.quick_set("//select[@name='foo']", "Bar")
81
- # form.quick_set("//textarea[@name='foo']", "bar")
82
- #
83
- def quick_set(selector, value)
84
- elem = element(xpath: selector).to_subtype
85
- case elem.tag_name
86
- when "input"
87
- elem.set value
88
- when "select"
89
- elem.select value
90
- when "textarea"
91
- elem.set value
92
- end
93
- end
94
- end
95
- end