sanguinews 0.60 → 0.61

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8fa336b8808a65611854b554245a288b4b05f303
4
- data.tar.gz: 0c4309243350764bae4669b537f65d4ed9b79e12
3
+ metadata.gz: 40aa32aca9a225e90465338f0e81ab91e3a6d252
4
+ data.tar.gz: d54b92ab842f357493d401bbe2f125896e019c8d
5
5
  SHA512:
6
- metadata.gz: b231b17b59ab469a3d64294c6f3befc97abf0083ebfac5fce887e74511844591708f879de799b09dc75348f202d6bfd5aa1bb05bde52b8970960214922f6abba
7
- data.tar.gz: e551da80f3d6f1641c4e47b46636b34ffcfd196fbd9f111c6fab804823df3112418669f38ecd5e3c2c34e4f8a25407f7616d0383d4146cfa4f281f4ab07a8c7f
6
+ metadata.gz: a6502eba0c482db080ab3a0a3eedd47ae3523a5772e908d68fe6d21041844cae67fcd02cb631cb6501b6b6ee18448c1837ec5a45c01cfca4eb4e04f02828829f
7
+ data.tar.gz: d501c3176bf7f6e2ca3197e1234c74652e770574e6d668f4881daea9b5e0009b44dc832eca6ca9a91ece5f0af069bf01edb807d8a6f78578908b8f9f069df722
@@ -0,0 +1,152 @@
1
+ #######################################################################
2
+ # Config - class designed specifically for sanguinews
3
+ # Copyright (c) 2013-2014, Tadeus Dobrovolskij
4
+ # This library is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License along
15
+ # with this library; if not, write to the Free Software Foundation, Inc.,
16
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
+ #########################################################################
18
+ module Sanguinews
19
+ class Config
20
+ attr_reader :config, :data
21
+
22
+ %w(username password server port from connections
23
+ article_size reconnect_delay groups prefix ssl
24
+ xna nzb header_check verbose debug filemode files directory).each do |meth|
25
+ define_method(meth) { @data[meth.to_sym] }
26
+ end
27
+
28
+ def parse_config(config)
29
+ config = ParseConfig.new(config)
30
+ config.get_params().each do |key|
31
+ value = config[key]
32
+ value = true if value == 'yes'
33
+ value = false if value == 'no'
34
+ value = value.to_i if %w(connections article_size reconnect_delay).include? key
35
+ @data[key.to_sym] ||= value
36
+ end
37
+ end
38
+
39
+ def mode
40
+ self.ssl ? :tls : :original
41
+ end
42
+
43
+ def parse_options!(args)
44
+ # version and legal info presented to user
45
+ banner = []
46
+ banner << ""
47
+ banner << "sanguinews v#{Sanguinews::VERSION}. Copyright (c) 2013-2014 Tadeus Dobrovolskij."
48
+ banner << "Comes with ABSOLUTELY NO WARRANTY. Distributed under GPL v2 license(http://www.gnu.org/licenses/gpl-2.0.txt)."
49
+ banner << "sanguinews is a simple nntp(usenet) binary poster. It supports multithreading and SSL. More info in README."
50
+ banner << ""
51
+ # option parser
52
+
53
+ opt_parser = OptionParser.new do |opt|
54
+ opt.banner = "Usage: sanguinews [OPTIONS] [DIRECTORY] | -f FILE1..[FILEX]"
55
+ opt.separator ""
56
+ opt.separator "Options"
57
+
58
+ opt.on("-c", "--config CONFIG", "use different config file") do |cfg|
59
+ @config = cfg
60
+ end
61
+ opt.on("-C", "--check", "check headers while uploading; slow but reliable") do
62
+ @data[:header_check] = true
63
+ end
64
+ opt.on("-f", "--file FILE", "upload FILE, treat all additional parameters as files") do |file|
65
+ @data[:filemode] = true
66
+ @data[:files] << file
67
+ end
68
+ opt.on("-g", "--groups GROUP_LIST", "use these groups(comma separated) for upload") do |group_list|
69
+ @data[:groups] = group_list
70
+ end
71
+ opt.on("-h", "--help", "help") do
72
+ banner.each do |msg|
73
+ puts msg
74
+ end
75
+ puts opt_parser
76
+ puts
77
+ exit
78
+ end
79
+ opt.on("-p", "--password PASSWORD", "use PASSWORD as your password(overwrites config file)") do |password|
80
+ @data[:password] = password
81
+ end
82
+ opt.on("-u", "--user USERNAME", "use USERNAME as your username(overwrites config file)") do |username|
83
+ @data[:username] = username
84
+ end
85
+ opt.on("-v", "--verbose", "be verbose?") do
86
+ @data[:verbose] = true
87
+ end
88
+ opt.on("-V", "--version", "print version information and then exit") do
89
+ puts Sanguinews::VERSION
90
+ exit
91
+ end
92
+ end
93
+
94
+ begin
95
+ opt_parser.parse!(args)
96
+ rescue OptionParser::InvalidOption, OptionParser::MissingArgument
97
+ puts opt_parser
98
+ exit 1
99
+ end
100
+
101
+ # in file mode treat every additional parameter as a file
102
+ if !args.empty? && @data[:filemode]
103
+ args.each do |file|
104
+ @data[:files] << file.to_s
105
+ end
106
+ end
107
+
108
+ # exit when no file list is provided
109
+ if @data[:files].empty?
110
+ if @data[:filemode] || args.empty?
111
+ puts "You need to specify something to upload!"
112
+ puts opt_parser
113
+ exit 1
114
+ else
115
+ args[0].end_with?('/') ? @data[:directory] = args[0] : @data[:directory] = args[0] + '/'
116
+ end
117
+ end
118
+
119
+ end
120
+
121
+ def config_gen
122
+ puts "It looks like you are launching sanguinews for the first time."
123
+ `cp #{File.expand_path(File.dirname(__FILE__)) + '/../../sample.conf'} ~/.sanguinews.conf`
124
+ puts "Sample config was copied to your home directory."
125
+ puts "Please edit #{File.expand_path('~/.sanguinews.conf')} in your favourite text editor."
126
+ puts "Relaunch the application when ready."
127
+ exit
128
+ end
129
+
130
+ def initialize(args)
131
+ @data = {}
132
+ @data[:filemode] = false
133
+ @data[:files] = []
134
+
135
+ parse_options!(args)
136
+
137
+ # Parse options in config file
138
+ if @data[:config] && File.exist?(File.expand_path(@data[:config]))
139
+ config = @data[:config]
140
+ else
141
+ config = File.expand_path("~/.sanguinews.conf")
142
+ end
143
+
144
+ if File.exist?(config)
145
+ parse_config(config)
146
+ else
147
+ config_gen
148
+ end
149
+ end
150
+
151
+ end
152
+ end
@@ -65,11 +65,8 @@ module Sanguinews
65
65
  until self.eof?
66
66
  f = self.read(@@max_mem)
67
67
  crc32 = Zlib.crc32(f, 0)
68
- if fcrc32.nil?
69
- fcrc32 = crc32
70
- else
71
- fcrc32 = Zlib.crc32_combine(fcrc32, crc32, f.size)
72
- end
68
+ fcrc32 &&= Zlib.crc32_combine(fcrc32, crc32, f.size)
69
+ fcrc32 ||= crc32
73
70
  end
74
71
  self.rewind
75
72
  fcrc32.to_s(16)
@@ -99,7 +96,7 @@ module Sanguinews
99
96
  end
100
97
 
101
98
  def max_mem
102
- if @@max_mem.nil?
99
+ @@max_mem ||= begin
103
100
  memory = Vmstat.memory
104
101
  @@max_mem = (memory[:free] * memory[:pagesize] * 0.1).floor
105
102
  end
@@ -22,17 +22,14 @@ module Sanguinews
22
22
  class NntpMsg
23
23
  attr_accessor :message, :from, :groups, :subject, :poster, :date, :xna
24
24
 
25
- def initialize(from, groups, subject, message='', date=nil, poster=nil)
25
+ def initialize(from, groups, subject, message='', **opts)
26
26
  @from = from
27
27
  @groups = groups
28
28
  @subject = subject
29
29
  @message = message
30
- if date.nil?
31
- @date = DateTime.now().strftime('%a, %d %b %Y %T %z')
32
- else
33
- @date = date
34
- end
35
- @poster = poster if !poster.nil?
30
+ @date = opts[:date] if opts[:date]
31
+ @date ||= DateTime.now().strftime('%a, %d %b %Y %T %z')
32
+ @poster = opts[:poster] if opts[:poster]
36
33
  end
37
34
 
38
35
  def create_header
@@ -40,7 +37,7 @@ module Sanguinews
40
37
  sio.puts "From: #{@from}"
41
38
  sio.puts "Newsgroups: #{@groups}"
42
39
  sio.puts "Subject: #{@subject}"
43
- sio.puts "X-Newsposter: #{@poster}" unless poster.nil?
40
+ sio.puts "X-Newsposter: #{@poster}" if @poster
44
41
  sio.puts "X-No-Archive: yes" if @xna
45
42
  sio.puts "Date: #{@date}"
46
43
  sio.puts
@@ -72,7 +69,6 @@ module Sanguinews
72
69
  def return_self
73
70
  header = self.create_header
74
71
  header << @message
75
- return header
76
72
  end
77
73
 
78
74
  def size
@@ -1,3 +1,3 @@
1
1
  module Sanguinews
2
- VERSION = "0.60"
2
+ VERSION = "0.61"
3
3
  end
data/lib/sanguinews.rb CHANGED
@@ -31,19 +31,20 @@ require_relative 'sanguinews/nntp'
31
31
  require_relative 'sanguinews/nntp_msg'
32
32
  require_relative 'sanguinews/file_to_upload'
33
33
  require_relative 'sanguinews/yencoded'
34
+ require_relative 'sanguinews/config'
34
35
  require_relative 'sanguinews/version'
35
36
 
36
37
  module Sanguinews
37
38
  module_function
38
39
  # Method returns yenc encoded string and crc32 value
39
40
  def yencode(file, length, queue)
40
- i = 1
41
+ chunk = 1
41
42
  until file.eof?
42
43
  bindata = file.read(length)
43
44
  # We can't take all memory, so we wait
44
45
  queue.synchronize do
45
46
  @cond.wait_while do
46
- queue.length > @threads * 3
47
+ queue.length > @config.connections * 3
47
48
  end
48
49
  end
49
50
  data = {}
@@ -52,12 +53,12 @@ module Sanguinews
52
53
  data[:yenc] = Yencoded::Data.yenc(bindata, len)
53
54
  data[:crc32] = Zlib.crc32(bindata, 0).to_s(16)
54
55
  data[:length] = len
55
- data[:chunk] = i
56
+ data[:chunk] = chunk
56
57
  data[:file] = file
57
58
  final_data[0] = form_message(data)
58
59
  final_data[1] = file
59
60
  queue.push(final_data)
60
- i += 1
61
+ chunk += 1
61
62
  end
62
63
  end
63
64
 
@@ -72,168 +73,68 @@ module Sanguinews
72
73
  chunks = file.chunks
73
74
  basename = file.name
74
75
  # usenet works with ASCII
75
- subject="#{@prefix}#{file.dir_prefix}\"#{basename}\" yEnc (#{chunk}/#{chunks})"
76
- msg = NntpMsg.new(@from, @groups, subject)
76
+ subject="#{@config.prefix}#{file.dir_prefix}\"#{basename}\" yEnc (#{chunk}/#{chunks})"
77
+ msg = NntpMsg.new(@config.from, @config.groups, subject)
77
78
  msg.poster = "sanguinews v#{Sanguinews::VERSION} (ruby #{RUBY_VERSION}) - https://github.com/tdobrovolskij/sanguinews"
78
- msg.xna = @xna
79
+ msg.xna = @config.xna
79
80
  msg.message = message.force_encoding('ASCII-8BIT')
80
81
  msg.yenc_body(chunk, chunks, crc32, pcrc32, length, fsize, basename)
81
82
  msg = msg.return_self
82
83
  { message: msg, filename: basename, chunk: chunk, length: length }
83
84
  end
84
85
 
85
- def connect(x)
86
+ def connect(conn_nr)
86
87
  begin
87
- nntp = Net::NNTP.start(@server, @port, @username, @password, @mode)
88
+ nntp = Net::NNTP.start(
89
+ @config.server, @config.port, @config.username, @config.password, @config.mode)
88
90
  rescue
89
- @s.log([$!, $@], stderr: true) if @debug
90
- if @verbose
91
+ @s.log([$!, $@], stderr: true) if @config.debug
92
+ if @config.verbose
91
93
  parse_error($!.to_s)
92
- @s.log("Connection nr. #{x} has failed. Reconnecting...\n", stderr: true)
94
+ @s.log("Connection nr. #{conn_nr} has failed. Reconnecting...\n", stderr: true)
93
95
  end
94
- sleep @delay
96
+ sleep @config.reconnect_delay
95
97
  retry
96
98
  end
97
99
  return nntp
98
100
  end
99
101
 
100
- def parse_config(config)
101
- config = ParseConfig.new(config)
102
- config.get_params()
103
- @username = config['username']
104
- @password = config['password']
105
- @from = config['from']
106
- @server = config['server']
107
- @port = config['port']
108
- @threads = config['connections'].to_i
109
- @length = config['article_size'].to_i
110
- @delay = config['reconnect_delay'].to_i
111
- @groups = config['groups']
112
- @prefix = config['prefix']
113
- ssl = config['ssl']
114
- if ssl == 'yes'
115
- @mode = :tls
116
- else
117
- @mode = :original
118
- end
119
- config['xna'] == 'yes' ? @xna = true : @xna = false
120
- config['nzb'] == 'yes' ? @nzb = true : @nzb = false
121
- config['header_check'] == 'yes' ? @header_check = true : @header_check = false
122
- config['debug'] == 'yes' ? @debug = true : @debug = false
123
- end
124
-
125
- def get_msgid(response)
102
+ def get_msgid(responses)
126
103
  msgid = ''
127
- response.each do |r|
128
- msgid = r.sub(/>.*/, '').tr("<", '') if r.end_with?('Article posted')
104
+ responses.each do |response|
105
+ msgid = response.sub(/>.*/, '').tr("<", '') if response.end_with?('Article posted')
129
106
  end
130
107
  return msgid
131
108
  end
132
109
 
133
- def parse_options(args)
134
- # version and legal info presented to user
135
- banner = []
136
- banner << ""
137
- banner << "sanguinews v#{Sanguinews::VERSION}. Copyright (c) 2013-2014 Tadeus Dobrovolskij."
138
- banner << "Comes with ABSOLUTELY NO WARRANTY. Distributed under GPL v2 license(http://www.gnu.org/licenses/gpl-2.0.txt)."
139
- banner << "sanguinews is a simple nntp(usenet) binary poster. It supports multithreading and SSL. More info in README."
140
- banner << ""
141
- # option parser
142
- options = {}
143
- options[:filemode] = false
144
- options[:files] = []
145
-
146
- opt_parser = OptionParser.new do |opt|
147
- opt.banner = "Usage: #{$0} [OPTIONS] [DIRECTORY] | -f FILE1..[FILEX]"
148
- opt.separator ""
149
- opt.separator "Options"
150
-
151
- opt.on("-c", "--config CONFIG", "use different config file") do |cfg|
152
- options[:config] = cfg
153
- end
154
- opt.on("-C", "--check", "check headers while uploading; slow but reliable") do
155
- options[:header_check] = true
156
- end
157
- opt.on("-f", "--file FILE", "upload FILE, treat all additional parameters as files") do |file|
158
- options[:filemode] = true
159
- options[:files] << file
160
- end
161
- opt.on("-g", "--groups GROUP_LIST", "use these groups(comma separated) for upload") do |group_list|
162
- options[:groups] = group_list
163
- end
164
- opt.on("-h", "--help", "help") do
165
- banner.each do |msg|
166
- puts msg
167
- end
168
- puts opt_parser
169
- puts
170
- exit
171
- end
172
- opt.on("-p", "--password PASSWORD", "use PASSWORD as your password(overwrites config file)") do |password|
173
- options[:password] = password
174
- end
175
- opt.on("-u", "--user USERNAME", "use USERNAME as your username(overwrites config file)") do |username|
176
- options[:username] = username
177
- end
178
- opt.on("-v", "--verbose", "be verbose?") do
179
- options[:verbose] = true
180
- end
181
- end
182
-
183
- begin
184
- opt_parser.parse!(args)
185
- rescue OptionParser::InvalidOption, OptionParser::MissingArgument
186
- puts opt_parser
187
- exit 1
188
- end
189
-
190
- options[:directory] = args[0] unless options[:filemode]
191
-
192
- # in file mode treat every additional parameter as a file
193
- if !args.empty? && options[:filemode]
194
- args.each do |file|
195
- options[:files] << file.to_s
196
- end
197
- end
198
-
199
- # exit when no file list is provided
200
- if options[:directory].nil? && options[:files].empty?
201
- puts "You need to specify something to upload!"
202
- puts opt_parser
203
- exit 1
204
- end
205
-
206
- return options
207
- end
208
-
209
110
  def parse_error(msg, **info)
210
- if info[:file].nil? || info[:chunk].nil?
211
- fileinfo = ''
212
- else
111
+ if info[:file] && info[:chunk]
213
112
  fileinfo = '(' + info[:file] + ' / Chunk: ' + info[:chunk].to_s + ')'
113
+ else
114
+ fileinfo = ''
214
115
  end
215
116
 
216
117
  case
217
118
  when /\A411/ === msg
218
- @s.log("Invalid newsgroup specified.", stderr: true)
119
+ @s.log("Invalid newsgroup specified.\n", stderr: true)
219
120
  when /\A430/ === msg
220
- @s.log("No such article. Maybe server is lagging...#{fileinfo}", stderr: true)
121
+ @s.log("No such article. Maybe server is lagging...#{fileinfo}\n", stderr: true)
221
122
  when /\A(4\d{2}\s)?437/ === msg
222
- @s.log("Article rejected by server. Maybe it's too big.#{fileinfo}", stderr: true)
123
+ @s.log("Article rejected by server. Maybe it's too big.#{fileinfo}\n", stderr: true)
223
124
  when /\A440/ === msg
224
- @s.log("Posting not allowed.", stderr: true)
125
+ @s.log("Posting not allowed.\n", stderr: true)
225
126
  when /\A441/ === msg
226
- @s.log("Posting failed for some reason.#{fileinfo}", stderr: true)
127
+ @s.log("Posting failed for some reason.#{fileinfo}\n", stderr: true)
227
128
  when /\A450/ === msg
228
- @s.log("Not authorized.", stderr: true)
129
+ @s.log("Not authorized.\n", stderr: true)
229
130
  when /\A452/ === msg
230
- @s.log("Wrong username and/or password.", stderr: true)
131
+ @s.log("Wrong username and/or password.\n", stderr: true)
231
132
  when /\A500/ === msg
232
- @s.log("Command not recognized.", stderr: true)
133
+ @s.log("Command not recognized.\n", stderr: true)
233
134
  when /\A501/ === msg
234
- @s.log("Command syntax error.", stderr: true)
135
+ @s.log("Command syntax error.\n", stderr: true)
235
136
  when /\A502/ === msg
236
- @s.log("Access denied.", stderr: true)
137
+ @s.log("Access denied.\n", stderr: true)
237
138
  end
238
139
  end
239
140
 
@@ -261,80 +162,52 @@ module Sanguinews
261
162
  end
262
163
 
263
164
  @s.start
264
- x = 1
165
+ check_delay = 1
265
166
  begin
266
167
  response = nntp.post msg
267
168
  msgid = get_msgid(response)
268
- if @header_check
269
- sleep x
169
+ if @config.header_check
170
+ sleep check_delay
270
171
  nntp.stat("<#{msgid}>")
271
172
  end
272
173
  rescue
273
- @s.log([$!, $@], stderr: true) if @debug
274
- if @verbose
174
+ @s.log([$!, $@], stderr: true) if @config.debug
175
+ if @config.verbose
275
176
  parse_error($!.to_s, file: basename, chunk: chunk)
276
177
  @s.log("Upload of chunk #{chunk} from file #{basename} unsuccessful. Retrying...\n", stderr: true)
277
178
  end
278
- sleep @delay
279
- x += 4
179
+ sleep @config.reconnect_delay
180
+ check_delay += 4
280
181
  retry
281
182
  end
282
183
 
283
- if @verbose
184
+ if @config.verbose
284
185
  @s.log("Uploaded chunk Nr:#{chunk}\n", stderr: true)
285
186
  end
286
187
 
287
188
  @s.done(length)
288
189
  @s.uploaded += full_size
289
- if @nzb
190
+ if @config.nzb
290
191
  file.write_segment_info(length, chunk, msgid)
291
192
  end
292
193
  nntp_pool.push(nntp)
293
194
  end
294
195
 
295
196
  def run!
296
- # Parse options in config file
297
- config = "~/.sanguinews.conf"
298
- config = File.expand_path(config)
299
- # variable to store if config was parsed
300
- saw_config = false
301
- if File.exist?(config)
302
- saw_config = true
303
- parse_config(config)
304
- end
305
-
306
- options = parse_options(ARGV)
307
-
308
- optconfig = options[:config]
309
- optconfig = '' if optconfig.nil?
310
- if !File.exist?(optconfig) && !saw_config
311
- puts "No config information specified. Aborting..."
312
- exit
313
- end
314
- parse_config(optconfig) if File.exist?(optconfig)
315
-
316
- options[:verbose] ? @verbose = true : @verbose = false
317
- @header_check = true unless options[:header_check].nil?
318
- filemode = options[:filemode]
319
-
320
- @username = options[:username] unless options[:username].nil?
321
- @password = options[:password] unless options[:password].nil?
322
- @groups = options[:groups] unless options[:groups].nil?
323
- directory = options[:directory] unless filemode
324
- files = options[:files]
197
+ @config = Config.new(ARGV)
198
+ files = @config.files
325
199
 
326
200
  # skip hidden files
327
- if !filemode
328
- directory = directory + "/" unless directory.end_with?('/')
329
- Dir.foreach(directory) do |item|
201
+ if !@config.filemode
202
+ Dir.foreach(@config.directory) do |item|
330
203
  next if item.start_with?('.')
331
- files << directory+item
204
+ files << @config.directory+item
332
205
  end
333
206
  end
334
207
 
335
208
  # "max" is needed only in dirmode
336
209
  max = files.length
337
- c = 1
210
+ current_chunk = 1
338
211
 
339
212
  unprocessed = 0
340
213
  info_lock=Mutex.new
@@ -347,13 +220,13 @@ module Sanguinews
347
220
 
348
221
  pool = Queue.new
349
222
  Thread.new {
350
- @threads.times do |x|
351
- nntp = connect(x)
223
+ @config.connections.times do |conn_nr|
224
+ nntp = connect(conn_nr)
352
225
  pool.push(nntp)
353
226
  end
354
227
  }
355
228
 
356
- p = Pool.new(@threads)
229
+ thread_pool = Pool.new(@config.connections)
357
230
  informed = {}
358
231
 
359
232
  files.each do |file|
@@ -361,9 +234,9 @@ module Sanguinews
361
234
 
362
235
  informed[file.to_sym] = false
363
236
  file = FileToUpload.new(
364
- name: file, chunk_length: @length,
365
- prefix: @prefix, current: c, last: max, filemode: filemode,
366
- from: @from, groups: @groups, nzb: @nzb
237
+ name: file, chunk_length: @config.article_size, prefix: @config.prefix,
238
+ current: current_chunk, last: max, filemode: @config.filemode,
239
+ from: @config.from, groups: @config.groups, nzb: @config.nzb
367
240
  )
368
241
  @s.to_upload += file.size
369
242
 
@@ -372,28 +245,28 @@ module Sanguinews
372
245
  end
373
246
 
374
247
  files_to_process << file
375
- c += 1
248
+ current_chunk += 1
376
249
  end
377
250
 
378
251
  # let's give a little bit higher priority for file processing thread
379
- @t = Thread.new {
252
+ @file_proc_thread = Thread.new {
380
253
  files_to_process.each do |file|
381
254
  @s.log("Calculating CRC32 value for #{file.name}\n", stderr: true) if @verbose
382
255
  file.file_crc32
383
256
  @s.log("Encoding #{file.name}\n")
384
- yencode(file, @length, messages)
257
+ yencode(file, @config.article_size, messages)
385
258
  end
386
259
  }
387
- @t.priority += 2
260
+ @file_proc_thread.priority += 2
388
261
 
389
262
  until unprocessed == 0
390
- p.schedule do
263
+ thread_pool.schedule do
391
264
  process_and_upload(messages, pool, info_lock, informed)
392
265
  end
393
266
  unprocessed -= 1
394
267
  end
395
268
 
396
- p.shutdown
269
+ thread_pool.shutdown
397
270
 
398
271
  until pool.empty?
399
272
  nntp = pool.pop
data/sample.conf ADDED
@@ -0,0 +1,37 @@
1
+ # Sample config file
2
+ # Groups to post to
3
+ # Separate multiple groups with comma
4
+ groups = alt.binaries.test
5
+ # Your identity
6
+ from = witty_nickname <whatever@example.com>
7
+
8
+ # Username to use for authentication
9
+ username = your_username
10
+ # Password
11
+ password = your_password
12
+ # server to use
13
+ server = your_server
14
+ # Use SSL connection?
15
+ ssl = yes
16
+ # port
17
+ port = 563
18
+ # number of connections
19
+ connections = 10
20
+ # article size in bytes
21
+ article_size = 768000
22
+ # Wait this many seconds before trying to reconnect after unsuccessful upload
23
+ reconnect_delay = 5
24
+ # Subject prefix to use
25
+ prefix = "[sanguinews] - "
26
+ # Enable nzb creation
27
+ nzb = yes
28
+ # Use header checking? Upload will be slow but reliable.
29
+ header_check = no
30
+
31
+ # Debug information
32
+ debug = no
33
+ #######################
34
+ # headers
35
+ #######################
36
+ # X-No-Archive
37
+ xna = no
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sanguinews
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.60'
4
+ version: '0.61'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tadeus Dobrovolskij
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-01 00:00:00.000000000 Z
11
+ date: 2014-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: speedometer
@@ -121,11 +121,13 @@ files:
121
121
  - ext/yencoded/yencoded.c
122
122
  - ext/yencoded/yencoded.h
123
123
  - lib/sanguinews.rb
124
+ - lib/sanguinews/config.rb
124
125
  - lib/sanguinews/file_to_upload.rb
125
126
  - lib/sanguinews/nntp.rb
126
127
  - lib/sanguinews/nntp_msg.rb
127
128
  - lib/sanguinews/thread-pool.rb
128
129
  - lib/sanguinews/version.rb
130
+ - sample.conf
129
131
  homepage: http://www.tad-do.net
130
132
  licenses:
131
133
  - GPLv2