rgroups 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/README.rdoc +25 -0
  2. data/VERSION +1 -1
  3. data/lib/rgroups.rb +114 -2
  4. data/rgroups.gemspec +65 -0
  5. metadata +5 -4
@@ -2,6 +2,31 @@
2
2
 
3
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
4
 
5
+ == Usage
6
+ Setup is easy!
7
+ require 'rgroups'
8
+ rg = RGroup.new
9
+ rg.login('username', 'password')
10
+
11
+ Or, if you're using Google Apps for your Domain (GAFYD):
12
+ rg = RGroup.new('mydomain.com')
13
+ rg.login('username', 'password')
14
+
15
+ Adding a user to a group:
16
+ rg.add_user('address@domain.com', 'group', :message => 'message to send to invitees')
17
+
18
+ Adding a user directly (only for GAFYD accounts):
19
+ rg.add_user('address@mydomain.com', 'group', :mode => 'direct', :notify => true, :message => 'message to send to people', :delivery => 'digest')
20
+
21
+ Modifying a user's delivery options:
22
+ rg.update_user('address@domain.com', 'group', 'set_delivery', :value => 'summary')
23
+
24
+ Modifying a user's membership type:
25
+ rg.update_user('address@domain.com', 'group', 'set_member', :value => 'manager')
26
+
27
+ == Notes
28
+ This relies on the 'old style' Google Groups. Please ensure that your group is using the old style before reporting a bug. Support for the new style should come soon...
29
+
5
30
  == Contributing to rgroups
6
31
 
7
32
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
@@ -6,6 +6,10 @@ class RGroup
6
6
  @@DIRECT_ADD = '/manage_members_add'
7
7
  @@INVITE_ADD = '/members_invite'
8
8
  @@GROUP_SETTINGS = '/manage_general'
9
+ @@ACCESS_SETTINGS = '/manage_access'
10
+ @@POST_SETTINGS = '/manage_post'
11
+ @@ADV_SETTINGS = '/manage_advanced'
12
+ @@SPAM_SETTINGS = '/manage_spam'
9
13
 
10
14
  def initialize(*gafyd)
11
15
  @scraper = Mechanize.new
@@ -19,7 +23,8 @@ class RGroup
19
23
  @GAFYD = true
20
24
  end
21
25
  end
22
-
26
+
27
+ # login to google apps
23
28
  def login(username, password)
24
29
  page = @scraper.get(@LOGIN_URL)
25
30
  f = page.forms[0]
@@ -28,6 +33,14 @@ class RGroup
28
33
  @scraper.submit(f, f.buttons.first)
29
34
  end
30
35
 
36
+ # add a user
37
+ # email = email address to add
38
+ # group = group name
39
+ # :mode => direct (only for gafyd accounts)
40
+ # :notify => true/false to notify users they've been added (only for gafyd)
41
+ # :delivery => only for gafyd
42
+ # - none, email, summary, one
43
+ # :message => message to send to person when being added
31
44
  def add_user(email, group, opts={})
32
45
  if (opts[:mode] && opts[:mode].downcase == "direct")
33
46
  raise "direct add mode is only available for gafyd accounts" unless @GAFYD
@@ -73,6 +86,13 @@ class RGroup
73
86
  @scraper.submit(member_form, member_form.button_with(:name => 'Action.InitialAddMembers'))
74
87
  end
75
88
 
89
+ # update a user
90
+ # email = email address to update
91
+ # group = group name
92
+ # action = set_member, set_email
93
+ # :value => depends on what you're doing.
94
+ # - set_member: regular, manager, owner, unsubscribe, ban
95
+ # - set_email: none, email, summary, one
76
96
  def update_user(email, group, action, opts={})
77
97
  page = @scraper.get(@BASE_URL + group + @@MANAGE)
78
98
  member_set = page.search('//table[@class="memlist"]//td')
@@ -120,9 +140,99 @@ class RGroup
120
140
 
121
141
  end
122
142
 
143
+ # return a hash of group settings
144
+ def settings(group)
145
+ settings = {}
146
+
147
+ page = @scraper.get(@BASE_URL + group + @@GROUP_SETTINGS)
148
+ settings['group_name'] = page.search('//div[@id="name_view"]').text.strip
149
+ settings['group_description'] = page.search('//div[@id="desc_view"]').text.strip
150
+ settings['group_website'] = page.search('//div[@id="info_url_view"]').text.strip
151
+
152
+
153
+ page = @scraper.get(@BASE_URL + group + @@ACCESS_SETTINGS)
154
+ form = page.form_with(:id => "GM_form")
155
+ if (@GAFYD)
156
+ settings['allow_external'] = form.checkbox_with(:name => 'param.allow_external_members').checked?
157
+ end
158
+ form.radiobuttons_with(:name => 'param.archive_view').each do |r|
159
+ settings['archive_view'] = r.value if r.checked?
160
+ end
161
+ form.radiobuttons_with(:name => 'param.members_view').each do |r|
162
+ settings['member_view'] = r.value if r.checked?
163
+ end
164
+ form.radiobuttons_with(:name => 'param.who_can_join').each do |r|
165
+ settings['can_join'] = r.value if r.checked?
166
+ end
167
+ settings['join_question'] = form.field_with(:name => 'param.join_question').value.strip
168
+ form.radiobuttons_with(:name => 'param.who_can_post').each do |r|
169
+ settings['who_can_post'] = "managers" if r.checked? && r.value == 'm'
170
+ settings['who_can_post'] = "members" if r.checked? && r.value == 's'
171
+ settings['who_can_post'] = "domain" if r.checked? && r.value == 'd'
172
+ settings['who_can_post'] = "anyone" if r.checked? && r.value == 'p'
173
+ end
174
+ settings['mod_non_members'] = form.checkbox_with(:name => 'param.mod_non_members').checked?
175
+ settings['web_posting'] = form.checkbox_with(:name => 'param.allow_web_posting').checked?
176
+ form.radiobuttons_with(:name => 'param.who_can_invite').each do |r|
177
+ settings['who_can_invite'] = r.value if r.checked?
178
+ end
179
+ form.radiobuttons_with(:name => 'param.msg_moderation').each do |r|
180
+ settings['msg_moderation'] = r.value if r.checked?
181
+ end
182
+ settings['mod_new_members'] = form.checkbox_with(:name => 'param.mod_new_members').checked?
183
+
184
+
185
+ page = @scraper.get(@BASE_URL + group + @@POST_SETTINGS)
186
+ form = page.form_with(:id => "GM_form")
187
+ if (@GAFYD)
188
+ settings['custom_reply_to'] = form.field_with(:name => 'param.custom_reply_to').value.strip
189
+ form.field_with(:name => 'param.max_size').options.each do |s|
190
+ settings['max_size'] = s.value if s.selected?
191
+ end
192
+ settings['reply_with_bounce_list'] = form.checkbox_with(:name => 'param.reply_with_bounce_list').checked?
193
+ end
194
+ settings['subject_tag'] = form.field_with(:name => 'param.subject_tag').value.strip
195
+ form.radiobuttons_with(:name => 'param.footer').each do |r|
196
+ settings['message_footer'] = "none" if r.checked? && r.value == 'n'
197
+ settings['message_footer'] = "default" if r.checked? && r.value == 'd'
198
+ settings['message_footer'] = "custom" if r.checked? && r.value == 'c'
199
+ end
200
+ settings['reply_to'] = form.field_with(:name => 'param.footer_text').value.strip
201
+ form.radiobuttons_with(:name => 'param.reply_to').each do |r|
202
+ settings['reply_to'] = "whole_group" if r.checked? && r.value == 'l'
203
+ settings['reply_to'] = "author" if r.checked? && r.value == 'a'
204
+ settings['reply_to'] = "owner" if r.checked? && r.value == 'o'
205
+ settings['reply_to'] = "user_decide" if r.checked? && r.value == 'n'
206
+ settings['reply_to'] = "custom" if r.checked? && r.value == 'c'
207
+ end
208
+ settings['posting_as_group'] = form.checkbox_with(:name => 'param.posting_as_group').checked?
209
+ settings['moderation_notify'] = form.checkbox_with(:name => 'param.moderation_notify').checked?
210
+ settings['moderation_message_text'] = form.field_with(:name => 'param.footer_text').value.strip
211
+
212
+ page = @scraper.get(@BASE_URL + group + @@ADV_SETTINGS)
213
+ form = page.form_with(:id => "GM_form")
214
+ form.field_with(:name => 'param.lang').options.each do |s|
215
+ settings['primary_language'] = s.value if s.selected?
216
+ end
217
+ settings['fixed_font'] = form.checkbox_with(:name => 'param.font_type').checked?
218
+ settings['no_archive_msgs'] = form.checkbox_with(:name => 'param.no_archive').checked?
219
+ settings['group_is_archived'] = form.checkbox_with(:name => 'param.status_archive').checked?
220
+ settings['google_contact'] = form.checkbox_with(:name => 'param.can_contact').checked?
221
+
222
+ page = @scraper.get(@BASE_URL + group + @@SPAM_SETTINGS)
223
+ form = page.form_with(:id => "GM_form")
224
+ form.radiobuttons_with(:name => 'param.spam_mode').each do |r|
225
+ settings['spam_mode'] = "post" if r.checked? && r.value == '0'
226
+ settings['spam_mode'] = "mod" if r.checked? && r.value == '1'
227
+ settings['spam_mode'] = "mod_quiet" if r.checked? && r.value == '3'
228
+ settings['spam_mode'] = "reject" if r.checked? && r.value == '2'
229
+ end
230
+ return settings
231
+ end
232
+
123
233
  end
124
234
 
125
- # monkey-patch Mechanize so we can't reuse ssl sessions
235
+ # monkey-patch Mechanize::HTTP::Agent so we can't reuse ssl sessions
126
236
  # as that seems to break things
127
237
  class Mechanize::HTTP::Agent
128
238
  def reuse_ssl_sessions
@@ -134,6 +244,8 @@ class Mechanize::HTTP::Agent
134
244
  end
135
245
  end
136
246
 
247
+ # monkey-patch Mechanize so we can't reuse ssl sessions
248
+ # as that seems to break things
137
249
  class Mechanize
138
250
  def reuse_ssl_sessions
139
251
  @agent.reuse_ssl_sessions
@@ -0,0 +1,65 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "rgroups"
8
+ s.version = "0.2.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Andrew Hayworth"]
12
+ s.date = "2012-06-18"
13
+ s.description = "This is a Ruby API for accessing and updating Google Groups. It's based on Mechanize, which means it's essentially screen-scraping."
14
+ s.email = "ahayworth@gmail.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ "Gemfile",
22
+ "Gemfile.lock",
23
+ "LICENSE.txt",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "lib/rgroups.rb",
28
+ "rgroups.gemspec",
29
+ "test/helper.rb",
30
+ "test/test_rgroups.rb"
31
+ ]
32
+ s.homepage = "http://github.com/ahayworth/rgroups"
33
+ s.licenses = ["MIT"]
34
+ s.require_paths = ["lib"]
35
+ s.rubygems_version = "1.8.24"
36
+ s.summary = "Ruby API for accessing/updating Google Groups - based on Mechanize"
37
+
38
+ if s.respond_to? :specification_version then
39
+ s.specification_version = 3
40
+
41
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
42
+ s.add_runtime_dependency(%q<mechanize>, [">= 0"])
43
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
44
+ s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
45
+ s.add_development_dependency(%q<bundler>, [">= 0"])
46
+ s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
47
+ s.add_development_dependency(%q<rcov>, [">= 0"])
48
+ else
49
+ s.add_dependency(%q<mechanize>, [">= 0"])
50
+ s.add_dependency(%q<shoulda>, [">= 0"])
51
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
52
+ s.add_dependency(%q<bundler>, [">= 0"])
53
+ s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
54
+ s.add_dependency(%q<rcov>, [">= 0"])
55
+ end
56
+ else
57
+ s.add_dependency(%q<mechanize>, [">= 0"])
58
+ s.add_dependency(%q<shoulda>, [">= 0"])
59
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
60
+ s.add_dependency(%q<bundler>, [">= 0"])
61
+ s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
62
+ s.add_dependency(%q<rcov>, [">= 0"])
63
+ end
64
+ end
65
+
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rgroups
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 1
8
+ - 2
9
9
  - 0
10
- version: 0.1.0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Andrew Hayworth
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-06-17 00:00:00 Z
18
+ date: 2012-06-18 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  requirement: &id001 !ruby/object:Gem::Requirement
@@ -122,6 +122,7 @@ files:
122
122
  - Rakefile
123
123
  - VERSION
124
124
  - lib/rgroups.rb
125
+ - rgroups.gemspec
125
126
  - test/helper.rb
126
127
  - test/test_rgroups.rb
127
128
  homepage: http://github.com/ahayworth/rgroups