sanguinews 0.60

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.
@@ -0,0 +1,82 @@
1
+ ########################################################################
2
+ # NntpMsg - class creates NNTP message specifically for sanguinews
3
+ # Copyright (c) 2013, 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
+ #
19
+ require 'date'
20
+
21
+ module Sanguinews
22
+ class NntpMsg
23
+ attr_accessor :message, :from, :groups, :subject, :poster, :date, :xna
24
+
25
+ def initialize(from, groups, subject, message='', date=nil, poster=nil)
26
+ @from = from
27
+ @groups = groups
28
+ @subject = subject
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?
36
+ end
37
+
38
+ def create_header
39
+ sio = StringIO.new("", "w:ASCII-8BIT")
40
+ sio.puts "From: #{@from}"
41
+ sio.puts "Newsgroups: #{@groups}"
42
+ sio.puts "Subject: #{@subject}"
43
+ sio.puts "X-Newsposter: #{@poster}" unless poster.nil?
44
+ sio.puts "X-No-Archive: yes" if @xna
45
+ sio.puts "Date: #{@date}"
46
+ sio.puts
47
+ header = sio.string
48
+ sio.close
49
+ return header
50
+ end
51
+
52
+ def yenc_body(current_part, parts, crc32, pcrc32, part_size, file_size, filename)
53
+ chunk_start = ((current_part - 1) * part_size) + 1
54
+ chunk_end = current_part * part_size
55
+ if (parts==1)
56
+ headerline = "=ybegin line=128 size=#{file_size} name=#{filename}"
57
+ trailer = "=yend size=#{file_size} crc32=#{crc32}"
58
+ else
59
+ headerline = "=ybegin part=#{current_part} total=#{parts} line=128 size=#{file_size} name=#{filename}\n=ypart begin=#{chunk_start} end=#{chunk_end}"
60
+ # last part
61
+ if (current_part == parts)
62
+ trailer = "=yend size=#{part_size} part=#{current_part} pcrc32=#{pcrc32} crc32=#{crc32}"
63
+ else
64
+ trailer = "=yend size=#{part_size} part=#{current_part} pcrc32=#{pcrc32}"
65
+ end
66
+ end
67
+ headerline << "\n#{@message}\n"
68
+ headerline << trailer
69
+ @message = headerline
70
+ end
71
+
72
+ def return_self
73
+ header = self.create_header
74
+ header << @message
75
+ return header
76
+ end
77
+
78
+ def size
79
+ return @message.length
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,150 @@
1
+ # Ruby Thread Pool
2
+ # ================
3
+ # A thread pool is useful when you wish to do some work in a thread, but do
4
+ # not know how much work you will be doing in advance. Spawning one thread
5
+ # for each task is potentially expensive, as threads are not free.
6
+ #
7
+ # In this case, it might be more beneficial to start a predefined set of
8
+ # threads and then hand off work to them as it becomes available. This is
9
+ # the pure essence of what a thread pool is: an array of threads, all just
10
+ # waiting to do some work for you!
11
+ #
12
+ # Prerequisites
13
+ # -------------
14
+
15
+ # We need the [Queue](http://rdoc.info/stdlib/thread/1.9.2/Queue), as our
16
+ # thread pool is largely dependent on it. Thanks to this, the implementation
17
+ # becomes very simple!
18
+ require 'thread'
19
+
20
+ # Public Interface
21
+ # ----------------
22
+
23
+ # `Pool` is our thread pool class. It will allow us to do three operations:
24
+ #
25
+ # - `.new(size)` creates a thread pool of a given size
26
+ # - `#schedule(*args, &job)` schedules a new job to be executed
27
+ # - `#shutdown` shuts down all threads (after letting them finish working, of course)
28
+ class Pool
29
+
30
+ # ### initialization, or `Pool.new(size)`
31
+ # Creating a new `Pool` involves a certain amount of work. First, however,
32
+ # we need to define its’ `size`. It defines how many threads we will have
33
+ # working internally.
34
+ #
35
+ # Which size is best for you is hard to answer. You do not want it to be
36
+ # too low, as then you won’t be able to do as many things concurrently.
37
+ # However, if you make it too high Ruby will spend too much time switching
38
+ # between threads, and that will also degrade performance!
39
+ def initialize(size)
40
+ # Before we do anything else, we need to store some information about
41
+ # our pool. `@size` is useful later, when we want to shut our pool down,
42
+ # and `@jobs` is the heart of our pool that allows us to schedule work.
43
+ @size = size
44
+ @jobs = Queue.new
45
+
46
+ # #### Creating our pool of threads
47
+ # Once preparation is done, it’s time to create our pool of threads.
48
+ # Each thread store its’ index in a thread-local variable, in case we
49
+ # need to know which thread a job is executing in later on.
50
+ @pool = Array.new(@size) do |i|
51
+ Thread.new do
52
+ Thread.current[:id] = i
53
+
54
+ # We start off by defining a `catch` around our worker loop. This
55
+ # way we’ve provided a method for graceful shutdown of our threads.
56
+ # Shutting down is merely a `#schedule { throw :exit }` away!
57
+ catch(:exit) do
58
+ # The worker thread life-cycle is very simple. We continuously wait
59
+ # for tasks to be put into our job `Queue`. If the `Queue` is empty,
60
+ # we will wait until it’s not.
61
+ loop do
62
+ # Once we have a piece of work to be done, we will pull out the
63
+ # information we need and get to work.
64
+ job, args = @jobs.pop
65
+ job.call(*args)
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ # ### Work scheduling
73
+
74
+ # To schedule a piece of work to be done is to say to the `Pool` that you
75
+ # want something done.
76
+ def schedule(*args, &block)
77
+ # Your given task will not be run immediately; rather, it will be put
78
+ # into the work `Queue` and executed once a thread is ready to work.
79
+ @jobs << [block, args]
80
+ end
81
+
82
+ # ### Graceful shutdown
83
+
84
+ # If you ever wish to close down your application, I took the liberty of
85
+ # making it easy for you to wait for any currently executing jobs to finish
86
+ # before you exit.
87
+ def shutdown
88
+ # A graceful shutdown involves threads exiting cleanly themselves, and
89
+ # since we’ve defined a `catch`-handler around the threads’ worker loop
90
+ # it is simply a matter of throwing `:exit`. Thus, if we throw one `:exit`
91
+ # for each thread in our pool, they will all exit eventually!
92
+ @size.times do
93
+ schedule { throw :exit }
94
+ end
95
+
96
+ # And now one final thing: wait for our `throw :exit` jobs to be run on
97
+ # all our worker threads. This call will not return until all worker threads
98
+ # have exited.
99
+ @pool.map(&:join)
100
+ end
101
+ end
102
+
103
+ # Demonstration
104
+ # -------------
105
+ # Running this file will display how the thread pool works.
106
+ if $0 == __FILE__
107
+ # - First, we create a new thread pool with a size of 10. This number is
108
+ # lower than our planned amount of work, to show that threads do not
109
+ # exit once they have finished a task.
110
+ p = Pool.new(10)
111
+
112
+ # - Next we simulate some workload by scheduling a large amount of work
113
+ # to be done. The actual time taken for each job is randomized. This
114
+ # is to demonstrate that even if two tasks are scheduled approximately
115
+ # at the same time, the one that takes less time to execute is likely
116
+ # to finish before the other one.
117
+ 20.times do |i|
118
+ p.schedule do
119
+ sleep rand(4) + 2
120
+ puts "Job #{i} finished by thread #{Thread.current[:id]}"
121
+ end
122
+ end
123
+
124
+ # - Finally, register an `at_exit`-hook that will wait for our thread pool
125
+ # to properly shut down before allowing our script to completely exit.
126
+ at_exit { p.shutdown }
127
+ end
128
+
129
+ # License (X11 License)
130
+ # =====================
131
+ #
132
+ # Copyright (c) 2012, Kim Burgestrand <kim@burgestrand.se>
133
+ #
134
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
135
+ # of this software and associated documentation files (the "Software"), to deal
136
+ # in the Software without restriction, including without limitation the rights
137
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
138
+ # copies of the Software, and to permit persons to whom the Software is
139
+ # furnished to do so, subject to the following conditions:
140
+ #
141
+ # The above copyright notice and this permission notice shall be included in
142
+ # all copies or substantial portions of the Software.
143
+ #
144
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
145
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
146
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
147
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
148
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
149
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
150
+ # SOFTWARE.
@@ -0,0 +1,3 @@
1
+ module Sanguinews
2
+ VERSION = "0.60"
3
+ end
metadata ADDED
@@ -0,0 +1,153 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sanguinews
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.60'
5
+ platform: ruby
6
+ authors:
7
+ - Tadeus Dobrovolskij
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: speedometer
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.1'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.1.2
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '0.1'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 0.1.2
33
+ - !ruby/object:Gem::Dependency
34
+ name: nzb
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '0.2'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 0.2.2
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '0.2'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 0.2.2
53
+ - !ruby/object:Gem::Dependency
54
+ name: vmstat
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '2.1'
60
+ type: :runtime
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '2.1'
67
+ - !ruby/object:Gem::Dependency
68
+ name: parseconfig
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - "~>"
72
+ - !ruby/object:Gem::Version
73
+ version: '1.0'
74
+ type: :runtime
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - "~>"
79
+ - !ruby/object:Gem::Version
80
+ version: '1.0'
81
+ - !ruby/object:Gem::Dependency
82
+ name: rake
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: '10.3'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - "~>"
93
+ - !ruby/object:Gem::Version
94
+ version: '10.3'
95
+ - !ruby/object:Gem::Dependency
96
+ name: rake-compiler
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - "~>"
100
+ - !ruby/object:Gem::Version
101
+ version: '0.9'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - "~>"
107
+ - !ruby/object:Gem::Version
108
+ version: '0.9'
109
+ description: Sanguinews is a simple, commandline client for Usenet(nntp) uploads.
110
+ Inspired by newsmangler. Supports multithreading and SSL.
111
+ email:
112
+ - root@tad-do.net
113
+ executables:
114
+ - sanguinews
115
+ extensions:
116
+ - ext/yencoded/extconf.rb
117
+ extra_rdoc_files: []
118
+ files:
119
+ - bin/sanguinews
120
+ - ext/yencoded/extconf.rb
121
+ - ext/yencoded/yencoded.c
122
+ - ext/yencoded/yencoded.h
123
+ - lib/sanguinews.rb
124
+ - lib/sanguinews/file_to_upload.rb
125
+ - lib/sanguinews/nntp.rb
126
+ - lib/sanguinews/nntp_msg.rb
127
+ - lib/sanguinews/thread-pool.rb
128
+ - lib/sanguinews/version.rb
129
+ homepage: http://www.tad-do.net
130
+ licenses:
131
+ - GPLv2
132
+ metadata: {}
133
+ post_install_message:
134
+ rdoc_options: []
135
+ require_paths:
136
+ - lib
137
+ required_ruby_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '2.0'
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ requirements: []
148
+ rubyforge_project:
149
+ rubygems_version: 2.2.2
150
+ signing_key:
151
+ specification_version: 4
152
+ summary: Simple, commandline client for Usenet uploads
153
+ test_files: []