saber 1.2.3 → 1.2.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.
@@ -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