rgroups 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ gem "mechanize"
7
+
8
+ # Add dependencies to develop your gem here.
9
+ # Include everything needed to run rake, tests, features, etc.
10
+ group :development do
11
+ gem "shoulda", ">= 0"
12
+ gem "rdoc", "~> 3.12"
13
+ gem "bundler"
14
+ gem "jeweler", "~> 1.8.3"
15
+ gem "rcov", ">= 0"
16
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,49 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ domain_name (0.5.3)
5
+ unf (~> 0.0.3)
6
+ git (1.2.5)
7
+ jeweler (1.8.3)
8
+ bundler (~> 1.0)
9
+ git (>= 1.2.5)
10
+ rake
11
+ rdoc
12
+ json (1.7.3)
13
+ mechanize (2.5.1)
14
+ domain_name (~> 0.5, >= 0.5.1)
15
+ mime-types (~> 1.17, >= 1.17.2)
16
+ net-http-digest_auth (~> 1.1, >= 1.1.1)
17
+ net-http-persistent (~> 2.5, >= 2.5.2)
18
+ nokogiri (~> 1.4)
19
+ ntlm-http (~> 0.1, >= 0.1.1)
20
+ webrobots (~> 0.0, >= 0.0.9)
21
+ mime-types (1.18)
22
+ net-http-digest_auth (1.2.1)
23
+ net-http-persistent (2.7)
24
+ nokogiri (1.5.4)
25
+ ntlm-http (0.1.1)
26
+ rake (0.9.2.2)
27
+ rcov (1.0.0)
28
+ rdoc (3.12)
29
+ json (~> 1.4)
30
+ shoulda (3.0.1)
31
+ shoulda-context (~> 1.0.0)
32
+ shoulda-matchers (~> 1.0.0)
33
+ shoulda-context (1.0.0)
34
+ shoulda-matchers (1.0.0)
35
+ unf (0.0.5)
36
+ unf_ext
37
+ unf_ext (0.0.5)
38
+ webrobots (0.0.13)
39
+
40
+ PLATFORMS
41
+ ruby
42
+
43
+ DEPENDENCIES
44
+ bundler
45
+ jeweler (~> 1.8.3)
46
+ mechanize
47
+ rcov
48
+ rdoc (~> 3.12)
49
+ shoulda
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Andrew Hayworth
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,19 @@
1
+ = rgroups
2
+
3
+ Ruby API for accessing/updating Google Groups - based on Mechanize. This essentially just screen-scrapes Google Groups and automates clicking on things. It's not entirely efficient, but it sure beats having to script it yourself.
4
+
5
+ == Contributing to rgroups
6
+
7
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
8
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
9
+ * Fork the project.
10
+ * Start a feature/bugfix branch.
11
+ * Commit and push until you are happy with your contribution.
12
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2012 Andrew Hayworth. See LICENSE.txt for
18
+ further details.
19
+
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "rgroups"
18
+ gem.homepage = "http://github.com/ahayworth/rgroups"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Ruby API for accessing/updating Google Groups - based on Mechanize}
21
+ gem.description = %Q{This is a Ruby API for accessing and updating Google Groups. It's based on Mechanize, which means it's essentially screen-scraping.}
22
+ gem.email = "ahayworth@gmail.com"
23
+ gem.authors = ["Andrew Hayworth"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rake/testtask'
29
+ Rake::TestTask.new(:test) do |test|
30
+ test.libs << 'lib' << 'test'
31
+ test.pattern = 'test/**/test_*.rb'
32
+ test.verbose = true
33
+ end
34
+
35
+ require 'rcov/rcovtask'
36
+ Rcov::RcovTask.new do |test|
37
+ test.libs << 'test'
38
+ test.pattern = 'test/**/test_*.rb'
39
+ test.verbose = true
40
+ test.rcov_opts << '--exclude "gems/*"'
41
+ end
42
+
43
+ task :default => :test
44
+
45
+ require 'rdoc/task'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "rgroups #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/lib/rgroups.rb ADDED
@@ -0,0 +1,145 @@
1
+ require 'mechanize'
2
+
3
+
4
+ class RGroup
5
+ @@MANAGE = '/manage_members'
6
+ @@DIRECT_ADD = '/manage_members_add'
7
+ @@INVITE_ADD = '/members_invite'
8
+ @@GROUP_SETTINGS = '/manage_general'
9
+
10
+ def initialize(*gafyd)
11
+ @scraper = Mechanize.new
12
+ @scraper.reuse_ssl_sessions = false
13
+ if (gafyd.length == 0)
14
+ @BASE_URL = 'https://groups.google.com/group/'
15
+ @LOGIN_URL = 'https://accounts.google.com/ServiceLogin?service=groups2&passive=1209600&continue=https://groups.google.com/&followup=https://groups.google.com/'
16
+ else
17
+ @BASE_URL = 'https://groups.google.com/a/' + gafyd[0] + "/group/"
18
+ @LOGIN_URL = 'https://groups.google.com/a/' + gafyd[0]
19
+ @GAFYD = true
20
+ end
21
+ end
22
+
23
+ def login(username, password)
24
+ page = @scraper.get(@LOGIN_URL)
25
+ f = page.forms[0]
26
+ f.Email = username
27
+ f.Passwd = password
28
+ @scraper.submit(f, f.buttons.first)
29
+ end
30
+
31
+ def add_user(email, group, opts={})
32
+ if (opts[:mode] && opts[:mode].downcase == "direct")
33
+ raise "direct add mode is only available for gafyd accounts" unless @GAFYD
34
+ page = @scraper.get(@BASE_URL + group + @@DIRECT_ADD)
35
+ member_form = page.form('cr')
36
+ if (email.is_a? Array)
37
+ member_form.members_new = email.join(", ")
38
+ else
39
+ member_form.members_new = email
40
+ end
41
+
42
+ if (opts[:notify])
43
+ member_form.body = opts[:message]
44
+ member_form.checkbox_with(:name => 'notification').check
45
+ elsif (!opts[:notify] || opts[:notify].nil?)
46
+ member_form.checkbox_with(:name => 'notification').uncheck
47
+ end
48
+
49
+ if (opts[:delivery])
50
+ case opts[:delivery]
51
+ when "none"
52
+ member_form.radiobuttons_with(:name => 'delivery')[0].check
53
+ when "email"
54
+ member_form.radiobuttons_with(:name => 'delivery')[1].check
55
+ when "summary"
56
+ member_form.radiobuttons_with(:name => 'delivery')[2].check
57
+ when "one"
58
+ member_form.radiobuttons_with(:name => 'delivery')[3].check
59
+ else
60
+ member_form.radiobuttons_with(:name => 'delivery')[0].check
61
+ end
62
+ end
63
+ else # we're going to invite, not add
64
+ page = @scraper.get(@BASE_URL + group + @@INVITE_ADD)
65
+ member_form = page.form('cr')
66
+ if (email.is_a? Array)
67
+ member_form.members_new = email.join(", ")
68
+ else
69
+ member_form.members_new = email
70
+ end
71
+ member_form.body = opts[:message]
72
+ end
73
+ @scraper.submit(member_form, member_form.button_with(:name => 'Action.InitialAddMembers'))
74
+ end
75
+
76
+ def update_user(email, group, action, opts={})
77
+ page = @scraper.get(@BASE_URL + group + @@MANAGE)
78
+ member_set = page.search('//table[@class="memlist"]//td')
79
+ members = []
80
+ member_set.each do |m|
81
+ members.push(member_set[member_set.index(m) + 1]) if m.to_s.include?('class="cb"')
82
+ end
83
+
84
+ member_form = page.form('memberlist')
85
+ email.downcase!
86
+ index = nil
87
+ members.each_index do |m|
88
+ index = m if members[m].to_s.downcase.include?(email)
89
+ end
90
+
91
+ member_form.checkboxes_with(:name => 'subcheckbox')[index].check unless index.nil?
92
+
93
+ if (action.downcase == "set_member")
94
+ case opts[:value]
95
+ when "regular"
96
+ member_form.field_with(:name => 'membership_type').options[1].select
97
+ when "manager"
98
+ member_form.field_with(:name => 'membership_type').options[2].select
99
+ when "owner"
100
+ member_form.field_with(:name => 'membership_type').options[3].select
101
+ when "unsubscribe"
102
+ member_form.field_with(:name => 'membership_type').options[5].select
103
+ when "ban"
104
+ member_form.field_with(:name => 'membership_type').options[6].select
105
+ end
106
+ @scraper.submit(member_form, member_form.button_with(:name => 'Action.SetMembershipType'))
107
+ elsif (action.downcase == "set_email")
108
+ case opts[:value]
109
+ when "none"
110
+ member_form.field_with(:name => 'delivery').options[1].select
111
+ when "email"
112
+ member_form.field_with(:name => 'delivery').options[2].select
113
+ when "summary"
114
+ member_form.field_with(:name => 'delivery').options[3].select
115
+ when "one"
116
+ member_form.field_with(:name => 'delivery').options[4].select
117
+ end
118
+ @scraper.submit(member_form, member_form.button_with(:name => 'Action.SetDeliveryType'))
119
+ end
120
+
121
+ end
122
+
123
+ end
124
+
125
+ # monkey-patch Mechanize so we can't reuse ssl sessions
126
+ # as that seems to break things
127
+ class Mechanize::HTTP::Agent
128
+ def reuse_ssl_sessions
129
+ @http.reuse_ssl_sessions
130
+ end
131
+
132
+ def reuse_ssl_sessions= reuse_ssl_sessions
133
+ @http.reuse_ssl_sessions = reuse_ssl_sessions
134
+ end
135
+ end
136
+
137
+ class Mechanize
138
+ def reuse_ssl_sessions
139
+ @agent.reuse_ssl_sessions
140
+ end
141
+
142
+ def reuse_ssl_sessions= reuse_ssl_sessions
143
+ @agent.reuse_ssl_sessions = reuse_ssl_sessions
144
+ end
145
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'shoulda'
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ require 'rgroups'
16
+
17
+ class Test::Unit::TestCase
18
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestRgroups < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,161 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rgroups
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Andrew Hayworth
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-06-17 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ requirement: &id001 !ruby/object:Gem::Requirement
22
+ none: false
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ hash: 3
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ version_requirements: *id001
31
+ name: mechanize
32
+ prerelease: false
33
+ type: :runtime
34
+ - !ruby/object:Gem::Dependency
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ hash: 3
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ version_requirements: *id002
45
+ name: shoulda
46
+ prerelease: false
47
+ type: :development
48
+ - !ruby/object:Gem::Dependency
49
+ requirement: &id003 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ hash: 31
55
+ segments:
56
+ - 3
57
+ - 12
58
+ version: "3.12"
59
+ version_requirements: *id003
60
+ name: rdoc
61
+ prerelease: false
62
+ type: :development
63
+ - !ruby/object:Gem::Dependency
64
+ requirement: &id004 !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ hash: 3
70
+ segments:
71
+ - 0
72
+ version: "0"
73
+ version_requirements: *id004
74
+ name: bundler
75
+ prerelease: false
76
+ type: :development
77
+ - !ruby/object:Gem::Dependency
78
+ requirement: &id005 !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ~>
82
+ - !ruby/object:Gem::Version
83
+ hash: 49
84
+ segments:
85
+ - 1
86
+ - 8
87
+ - 3
88
+ version: 1.8.3
89
+ version_requirements: *id005
90
+ name: jeweler
91
+ prerelease: false
92
+ type: :development
93
+ - !ruby/object:Gem::Dependency
94
+ requirement: &id006 !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ hash: 3
100
+ segments:
101
+ - 0
102
+ version: "0"
103
+ version_requirements: *id006
104
+ name: rcov
105
+ prerelease: false
106
+ type: :development
107
+ description: This is a Ruby API for accessing and updating Google Groups. It's based on Mechanize, which means it's essentially screen-scraping.
108
+ email: ahayworth@gmail.com
109
+ executables: []
110
+
111
+ extensions: []
112
+
113
+ extra_rdoc_files:
114
+ - LICENSE.txt
115
+ - README.rdoc
116
+ files:
117
+ - .document
118
+ - Gemfile
119
+ - Gemfile.lock
120
+ - LICENSE.txt
121
+ - README.rdoc
122
+ - Rakefile
123
+ - VERSION
124
+ - lib/rgroups.rb
125
+ - test/helper.rb
126
+ - test/test_rgroups.rb
127
+ homepage: http://github.com/ahayworth/rgroups
128
+ licenses:
129
+ - MIT
130
+ post_install_message:
131
+ rdoc_options: []
132
+
133
+ require_paths:
134
+ - lib
135
+ required_ruby_version: !ruby/object:Gem::Requirement
136
+ none: false
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ hash: 3
141
+ segments:
142
+ - 0
143
+ version: "0"
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ hash: 3
150
+ segments:
151
+ - 0
152
+ version: "0"
153
+ requirements: []
154
+
155
+ rubyforge_project:
156
+ rubygems_version: 1.8.24
157
+ signing_key:
158
+ specification_version: 3
159
+ summary: Ruby API for accessing/updating Google Groups - based on Mechanize
160
+ test_files: []
161
+