ruml 0.0.1

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 ADDED
@@ -0,0 +1 @@
1
+ pkg
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm @ruml --create
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gem 'mail'
data/Gemfile.lock ADDED
@@ -0,0 +1,19 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ i18n (0.6.0)
5
+ mail (2.3.0)
6
+ i18n (>= 0.4.0)
7
+ mime-types (~> 1.16)
8
+ treetop (~> 1.4.8)
9
+ mime-types (1.17.2)
10
+ polyglot (0.3.2)
11
+ treetop (1.4.10)
12
+ polyglot
13
+ polyglot (>= 0.3.1)
14
+
15
+ PLATFORMS
16
+ ruby
17
+
18
+ DEPENDENCIES
19
+ mail
data/README.md ADDED
@@ -0,0 +1,22 @@
1
+ # ruml
2
+
3
+ Ruby mailing list software
4
+
5
+ ## File structure
6
+
7
+ <pre>
8
+ testml/
9
+ ├── bounce_to
10
+ ├── members
11
+ ├── name
12
+ └── to
13
+ </pre>
14
+
15
+ * to - E-mail of the mailing list
16
+ * name - Name of the mailing list displayed in subject. E.g. \[Fancy ML\] (optional)
17
+ * member - List of member's addresses
18
+ * bounce_to - Bounce mails go to this email (optional)
19
+
20
+ ## TODO
21
+
22
+ * Write tests!
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/ruml ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $debug = ENV['DEBUG']
4
+
5
+ require 'ruml'
6
+
7
+ ml = Ruml.new(ARGV[0])
8
+ ml.broadcast!(STDIN.read)
@@ -0,0 +1 @@
1
+ testml-bounce@example.com
@@ -0,0 +1,5 @@
1
+ # Empty entries or entries with pound sign will be ignored
2
+ foo@bar.com
3
+ # stupid@guy.com
4
+
5
+ info@example.com
@@ -0,0 +1 @@
1
+ [ExampleML]
data/example/testml/to ADDED
@@ -0,0 +1 @@
1
+ testml@example.com
data/lib/ruml.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'mail'
2
+
3
+ module Ruml
4
+ autoload :List, 'ruml/list'
5
+ autoload :Broadcaster, 'ruml/broadcaster'
6
+ autoload :VERSION, 'ruml/version'
7
+
8
+ def self.new(*args)
9
+ List.new(*args)
10
+ end
11
+ end
@@ -0,0 +1,85 @@
1
+ module Ruml
2
+ class Broadcaster
3
+ def initialize(ml, message)
4
+ @ml = ml
5
+ @message = Mail.new(message)
6
+ end
7
+
8
+ def sendable?
9
+ !been_there? && valid_member?
10
+ end
11
+
12
+ def valid_member?
13
+ expected = @message.from.size
14
+ actual = (@message.from(&:downvase) & @ml.members.map(&:downcase)).size
15
+ expected == actual
16
+ end
17
+
18
+ def been_there?
19
+ @message['X-BeenThere'].to_s == @ml.to
20
+ end
21
+
22
+ def add_headers!(mail)
23
+ mail['X-BeenThere'] = @ml.to
24
+ mail['List-Id'] = "<#{@ml.id}>"
25
+ mail['List-Post'] = "<mailto:#{@ml.to}>"
26
+ mail['Precedence'] = 'list'
27
+ mail['Sender'] = @ml.bounce_to
28
+ mail['Errors-To'] = @ml.bounce_to
29
+ mail['User-Agent'] = @message['User-Agent'].value if @message['User-Agent']
30
+ end
31
+
32
+ def add_body!(mail)
33
+ if @message.multipart?
34
+ @message.parts.each do |part|
35
+ mail.add_part part
36
+ end
37
+ else
38
+ mail.body @message.body.raw_source
39
+ end
40
+ end
41
+
42
+ def from
43
+ @message.from.first
44
+ end
45
+
46
+ def to
47
+ @ml.to
48
+ end
49
+
50
+ def subject
51
+ if @ml.name && !@message.subject.include?(@ml.name)
52
+ "#{@ml.name} #{@message.subject}"
53
+ else
54
+ @message.subject
55
+ end
56
+ end
57
+
58
+ def send!
59
+ @ml.members.each do |recipient|
60
+ send_to(recipient)
61
+ end
62
+ end
63
+
64
+ def send_to(recipient)
65
+ mail = Mail.new
66
+ mail.subject subject
67
+ mail.from from
68
+ mail.to to
69
+ mail.bcc recipient
70
+
71
+ add_headers! mail
72
+ add_body! mail
73
+ deliver! mail
74
+ end
75
+
76
+ def deliver! mail
77
+ if $debug
78
+ puts mail.to_s
79
+ else
80
+ mail.delivery_method :sendmail
81
+ mail.deliver
82
+ end
83
+ end
84
+ end
85
+ end
data/lib/ruml/list.rb ADDED
@@ -0,0 +1,50 @@
1
+ module Ruml
2
+ class List
3
+ attr_reader :name
4
+
5
+ def initialize(dir)
6
+ @dir = dir
7
+ raise "Unknown ml #{name} (#{@dir})" unless File.directory?(@dir)
8
+ end
9
+
10
+ def id
11
+ @id ||= to.gsub('@', '.')
12
+ end
13
+
14
+ def name
15
+ @name ||= readlines("name").first
16
+ end
17
+
18
+ def members
19
+ @members ||= readlines("members").reject { |member| member =~ /^#|^$/ }
20
+ end
21
+
22
+ def to
23
+ @to ||= readlines("to").first
24
+ end
25
+
26
+ def bounce_to
27
+ @bounce_to ||= readlines("bounce_to").first || to
28
+ end
29
+
30
+ def broadcaster(body)
31
+ Broadcaster.new(self, body)
32
+ end
33
+
34
+ def broadcast!(body)
35
+ message = broadcaster(body)
36
+ if message.sendable?
37
+ message.send!
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ def readlines(name)
44
+ path = File.join(@dir, name)
45
+ File.readlines(path).map(&:strip)
46
+ rescue Errno::ENOENT
47
+ []
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,3 @@
1
+ module Ruml
2
+ VERSION = "0.0.1"
3
+ end
data/ruml.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "ruml"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "ruml"
7
+ s.version = Ruml::VERSION
8
+ s.authors = ["Peter Suschlik"]
9
+ s.email = ["peter@suschlik.de"]
10
+ s.homepage = "https://github.com/splattael/ruml"
11
+ s.summary = %q{Ruby mailing list software}
12
+ s.description = %q{}
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ["lib"]
18
+
19
+ # specify any dependencies here; for example:
20
+ s.add_runtime_dependency "mail", "~> 2.3.0"
21
+ end
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruml
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Peter Suschlik
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-10-27 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: mail
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 2
31
+ - 3
32
+ - 0
33
+ version: 2.3.0
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ description: ""
37
+ email:
38
+ - peter@suschlik.de
39
+ executables:
40
+ - ruml
41
+ extensions: []
42
+
43
+ extra_rdoc_files: []
44
+
45
+ files:
46
+ - .gitignore
47
+ - .rvmrc
48
+ - Gemfile
49
+ - Gemfile.lock
50
+ - README.md
51
+ - Rakefile
52
+ - bin/ruml
53
+ - example/testml/bounce_to
54
+ - example/testml/members
55
+ - example/testml/name
56
+ - example/testml/to
57
+ - lib/ruml.rb
58
+ - lib/ruml/broadcaster.rb
59
+ - lib/ruml/list.rb
60
+ - lib/ruml/version.rb
61
+ - ruml.gemspec
62
+ homepage: https://github.com/splattael/ruml
63
+ licenses: []
64
+
65
+ post_install_message:
66
+ rdoc_options: []
67
+
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ hash: 3
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ hash: 3
85
+ segments:
86
+ - 0
87
+ version: "0"
88
+ requirements: []
89
+
90
+ rubyforge_project:
91
+ rubygems_version: 1.8.10
92
+ signing_key:
93
+ specification_version: 3
94
+ summary: Ruby mailing list software
95
+ test_files: []
96
+