hotmailer 1.0.0
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/README +98 -0
- data/lib/hotmailer.rb +263 -0
- metadata +63 -0
data/README
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
Hotmailer Library v0.1
|
2
|
+
|
3
|
+
The hotmailer library is used to programatically access your hotmail account. It depends on the 'mechanize' (and by extension 'hpricot') libraries.
|
4
|
+
|
5
|
+
The Hotmailer library contains two objects:
|
6
|
+
|
7
|
+
1. WWW::Hotmailer - this is descended from WWW::Mechanize, but has been specialised for hotmail.
|
8
|
+
2. Hotmailer::Message - This is the class for hotmail messages.
|
9
|
+
|
10
|
+
|
11
|
+
=== WWW::Hotmailer
|
12
|
+
|
13
|
+
This contains the following methods.
|
14
|
+
|
15
|
+
- new(username,password) - Used for creating a new hotmailer object. Note that this will not login for you, but only initialize the object.
|
16
|
+
|
17
|
+
eg. zaphod = Hotmailer.new('zaphod@hotmail.com','chunkybacon')
|
18
|
+
|
19
|
+
- login - This logs in a hotmailer object to hotmail.
|
20
|
+
|
21
|
+
eg. zaphod.login
|
22
|
+
|
23
|
+
- contacts(reload=false) : this gets a list of your hotmail contacts, in the form of a list of hashes, each hash containing a :name, and an :email for that contact. The first time it gets the contacts it caches them to save time - passing reload=true to the function forces it to reload the contacts from hotmail.
|
24
|
+
|
25
|
+
eg. contacts = zaphod.contacts
|
26
|
+
|
27
|
+
contacts is now [{:name => "Ford Prefect",:email => "fprefect@bt.net"},{:name => "Trishia Macmillan",:email => "trillian@gmail.com"}]
|
28
|
+
|
29
|
+
|
30
|
+
- compose(to,subject,body) : This sends an email to the 'to' address, using subject and body.
|
31
|
+
|
32
|
+
- messages(reload=false) : This gets all the messages in your hotmail inbox. It returns an array of Hotmailer::Message objects. The first time it gets them it caches them and returns this cache on subsequent calls, unless you specify reload=true.
|
33
|
+
|
34
|
+
eg. messages = zaphod.messages(true)
|
35
|
+
|
36
|
+
- add_contact(quickname,email,fname='',lname='') : This adds a contact to your hotmail address book. Only quickname and email are obligatory - fname (First Name) and lname (Last Name) can be left blank.
|
37
|
+
|
38
|
+
eg. zaphod.add_contact('barty','slartibartfast@fjord.net','Slarti','Bartfast')
|
39
|
+
|
40
|
+
|
41
|
+
Any of these methods will raise an error if there is a problem - you therefore should capture these errors in your program if you want to recover from them somehow.
|
42
|
+
|
43
|
+
|
44
|
+
=== Hotmailer::Message
|
45
|
+
|
46
|
+
This is the hotmail message class, and it contains the following (read only) attributes:
|
47
|
+
|
48
|
+
- from_email : The sender's email address.
|
49
|
+
- from_name : The sender's name.
|
50
|
+
- status : One of "Read", "Unread", and "Forwarded", describing the status of the message
|
51
|
+
- subject : The subject of the message
|
52
|
+
- date : The date it was sent
|
53
|
+
- size - The message's size (eg. '4 KB')
|
54
|
+
- body - The text of the message (in plain text)
|
55
|
+
|
56
|
+
|
57
|
+
In addition the following methods are also available:
|
58
|
+
|
59
|
+
- read : This returns the body of the message (in plain text). This is the same as the body attribute.
|
60
|
+
- delete : This deletes the message from the user's inbox, and places it in trash (where it will automatically disappear into the great void after a few days).
|
61
|
+
- forward(to) - This forwards a message to the to email address specified.
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
=== Example Run
|
67
|
+
|
68
|
+
require 'hotmailer'
|
69
|
+
|
70
|
+
#Create object and login
|
71
|
+
zaphod = Hotmailer.new('zaphod@hotmail.com','chunkybacon')
|
72
|
+
zaphod.login
|
73
|
+
|
74
|
+
|
75
|
+
#Get messages
|
76
|
+
messages = zaphod.messages
|
77
|
+
|
78
|
+
#Get details of first message
|
79
|
+
puts messages[0].from_email
|
80
|
+
puts messages[0].from_name
|
81
|
+
puts messages[0].subject
|
82
|
+
puts messages[0].body
|
83
|
+
|
84
|
+
|
85
|
+
#Forward first message to Arhur
|
86
|
+
messages[0].forward('dentarthurdent@gmail.com')
|
87
|
+
|
88
|
+
#Delete first message
|
89
|
+
messages[0].delete
|
90
|
+
|
91
|
+
#Add Arthur's contact details
|
92
|
+
zaphod.add_contact('arthur','dentarthurdent@hotmail.com','Arthur','Dent')
|
93
|
+
|
94
|
+
#Get contacts list
|
95
|
+
contacts = zaphod.contacts
|
96
|
+
|
97
|
+
|
98
|
+
|
data/lib/hotmailer.rb
ADDED
@@ -0,0 +1,263 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'mechanize'
|
3
|
+
|
4
|
+
|
5
|
+
class Hotmailer < WWW::Mechanize
|
6
|
+
|
7
|
+
attr_accessor :username, :passwd
|
8
|
+
attr_reader :inbox, :logged_in
|
9
|
+
|
10
|
+
def initialize(username,passwd)
|
11
|
+
super()
|
12
|
+
self.user_agent_alias = "Windows IE 6"
|
13
|
+
@username = username
|
14
|
+
@passwd = passwd
|
15
|
+
@inbox = ''
|
16
|
+
@contacts = []
|
17
|
+
@messages = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def login
|
21
|
+
#Logs in the user
|
22
|
+
first_page = self.get('http://hotmail.com')
|
23
|
+
login_form = first_page.form('f1')
|
24
|
+
login_form.login = self.username
|
25
|
+
login_form.passwd = self.passwd
|
26
|
+
|
27
|
+
login_page = self.submit(login_form)
|
28
|
+
|
29
|
+
if login_page.body =~ /window\.location\.replace\(\"([^"]+)\"/
|
30
|
+
new_loc = $1
|
31
|
+
else
|
32
|
+
raise "Error logging in - check username and password and try again"
|
33
|
+
end
|
34
|
+
|
35
|
+
main_page = self.get(new_loc)
|
36
|
+
|
37
|
+
if main_page.body =~ /_UM\s*=\s*"([^"]+)";?/
|
38
|
+
@inbox = $1
|
39
|
+
else
|
40
|
+
raise "Error getting mailbox - hotmail format may have changed! (Please try logging in manually using your web browser, then retry this)."
|
41
|
+
end
|
42
|
+
|
43
|
+
@logged_in = true
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
def contacts(reload=false)
|
48
|
+
#Get user's contact list (returns an array of hashes, each has a record for one
|
49
|
+
# user, and contains :name and :email keys)
|
50
|
+
|
51
|
+
unless reload
|
52
|
+
return @contacts unless @contacts.empty?
|
53
|
+
end
|
54
|
+
|
55
|
+
self.login unless self.logged_in
|
56
|
+
|
57
|
+
#The URL to use to get contacts in printable view
|
58
|
+
contacts_url = "/cgi-bin/addresses?fti=yes&PrintView=1&"+self.inbox
|
59
|
+
|
60
|
+
all_contacts = self.get(contacts_url)
|
61
|
+
|
62
|
+
#Get separate contacts [those within trs within trs]
|
63
|
+
scontacts = all_contacts/"tr/tr"
|
64
|
+
|
65
|
+
scontacts.each do |c|
|
66
|
+
#Get each contact's name and email, and append it to @contacts
|
67
|
+
details = (c/"td")
|
68
|
+
name = details[0].inner_html
|
69
|
+
email = (details[1]/"span")[0].inner_html
|
70
|
+
@contacts << {:name => name,:email => email}
|
71
|
+
end
|
72
|
+
|
73
|
+
return @contacts
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
def compose(to,subject,body)
|
78
|
+
#Sends an email
|
79
|
+
|
80
|
+
self.login unless self.logged_in
|
81
|
+
|
82
|
+
compose_url ="/cgi-bin/compose?"+self.inbox
|
83
|
+
comp_page = self.get(compose_url)
|
84
|
+
|
85
|
+
comp_form = comp_page.form("composeform")
|
86
|
+
comp_form.to = to
|
87
|
+
comp_form.subject = subject
|
88
|
+
comp_form.body = body
|
89
|
+
|
90
|
+
res_page = self.submit(comp_form)
|
91
|
+
|
92
|
+
unless res_page.body =~ /Your message has been sent/
|
93
|
+
raise "There was an error sending the message"
|
94
|
+
end
|
95
|
+
|
96
|
+
return true
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
def messages(reload=false)
|
101
|
+
|
102
|
+
unless reload
|
103
|
+
return @messages unless @messages.empty?
|
104
|
+
end
|
105
|
+
|
106
|
+
self.login unless self.logged_in
|
107
|
+
|
108
|
+
page = 1
|
109
|
+
last_page = 1
|
110
|
+
raw_messages = []
|
111
|
+
messages = []
|
112
|
+
|
113
|
+
while page <= last_page.to_i
|
114
|
+
msg_url = "/cgi-bin/HoTMaiL?&Sort=rDate&page=#{page}&"+self.inbox
|
115
|
+
msg_page = self.get(msg_url)
|
116
|
+
|
117
|
+
#Get last page
|
118
|
+
lastp = (msg_page/"a[@title='Last Page']")[0]
|
119
|
+
if lastp
|
120
|
+
lastp.attributes['href'] =~ /HM\('page=(\d+)/
|
121
|
+
last_page = $1
|
122
|
+
end
|
123
|
+
|
124
|
+
msgs = msg_page/"tr[@name]"
|
125
|
+
raw_messages += msgs
|
126
|
+
|
127
|
+
page+=1
|
128
|
+
end
|
129
|
+
|
130
|
+
for msg in raw_messages
|
131
|
+
fname = (msg/"a")[0].inner_html
|
132
|
+
femail = msg.attributes['name']
|
133
|
+
status = (msg/"img")[0].attributes['alt']
|
134
|
+
|
135
|
+
mlink = (msg/"a")[0].attributes['href']
|
136
|
+
mlink =~ /G\('([^']+)'/
|
137
|
+
mlink = $1
|
138
|
+
|
139
|
+
subject = (msg/"td")[6].inner_html
|
140
|
+
date = (msg/"td")[7].inner_html
|
141
|
+
size = (msg/"td")[8].inner_html
|
142
|
+
|
143
|
+
m = Hotmailer::Message.new(self,:from_name=> fname, :from_email => femail, :status => status, :link => mlink, :subject => subject, :date => date, :size => size)
|
144
|
+
|
145
|
+
messages << m
|
146
|
+
end
|
147
|
+
|
148
|
+
@messages = messages
|
149
|
+
return @messages
|
150
|
+
end
|
151
|
+
|
152
|
+
def add_contact(quickname,email,fname='',lname='')
|
153
|
+
#To add a contact
|
154
|
+
|
155
|
+
self.login unless self.logged_in
|
156
|
+
|
157
|
+
main_url = '/cgi-bin/hmhome?'+self.inbox
|
158
|
+
main_page = self.get(main_url)
|
159
|
+
|
160
|
+
c_link = (main_page/"a[@href=#]").find {|c| c.inner_html == "New Contact"}
|
161
|
+
unless c_link['onclick'] =~ /G\('([^']+)'/
|
162
|
+
raise "Error adding contact - hotmail format may have changed"
|
163
|
+
end
|
164
|
+
|
165
|
+
c_href = $1
|
166
|
+
contact_page = self.get(c_href+"&"+self.inbox)
|
167
|
+
contact_form = contact_page.form('addr')
|
168
|
+
|
169
|
+
contact_form.alias = quickname
|
170
|
+
contact_form.addrlist = email
|
171
|
+
|
172
|
+
contact_form.aliasfname = fname
|
173
|
+
contact_form.aliaslname = lname
|
174
|
+
|
175
|
+
res_page = self.submit(contact_form)
|
176
|
+
|
177
|
+
unless res_page.body =~ /Contact/
|
178
|
+
raise "Error adding contact"
|
179
|
+
end
|
180
|
+
|
181
|
+
return true
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
class Hotmailer::Message
|
188
|
+
attr_reader :from_email, :from_name, :status, :link, :subject, :date, :size, :parent, :id
|
189
|
+
|
190
|
+
|
191
|
+
def initialize(parent,opts = {})
|
192
|
+
@from_email = opts[:from_email]
|
193
|
+
@from_name = opts[:from_name]
|
194
|
+
@status = opts[:status]
|
195
|
+
@link = opts[:link]
|
196
|
+
@subject = opts[:subject]
|
197
|
+
@date = opts[:date]
|
198
|
+
@size = opts[:size]
|
199
|
+
@body = ''
|
200
|
+
@parent = parent
|
201
|
+
#Get message id
|
202
|
+
@link =~ /msg=(.+)/
|
203
|
+
@id = $1
|
204
|
+
end
|
205
|
+
|
206
|
+
def read
|
207
|
+
#Used to read the message's contents (in plain text)
|
208
|
+
return @body unless @body.empty?
|
209
|
+
|
210
|
+
msg_link = self.link+"&raw=0&"+@parent.inbox
|
211
|
+
msg_page = @parent.get(msg_link)
|
212
|
+
raw_text = (msg_page/"pre")[0].inner_html
|
213
|
+
|
214
|
+
if raw_text =~ /\n\n(.+)/m
|
215
|
+
msg_text = $1
|
216
|
+
else
|
217
|
+
msg_text = ''
|
218
|
+
end
|
219
|
+
|
220
|
+
@body = msg_text
|
221
|
+
return @body
|
222
|
+
end
|
223
|
+
|
224
|
+
alias :body :read
|
225
|
+
|
226
|
+
def delete
|
227
|
+
#Used to delete the message
|
228
|
+
#Get message page, and all links on page
|
229
|
+
msg_page = parent.get(self.link)
|
230
|
+
links = (msg_page/"a")
|
231
|
+
|
232
|
+
#Get delete link
|
233
|
+
del_a = links.find {|a| a.inner_html == 'Delete' }
|
234
|
+
if del_a.attributes['onclick'] =~ /G\('([^']+)'/
|
235
|
+
del_link = $1
|
236
|
+
else
|
237
|
+
raise "Could not find delete link - hotmail layout changed?"
|
238
|
+
end
|
239
|
+
|
240
|
+
res_page = parent.get(del_link)
|
241
|
+
#Remove self from parent's messages array
|
242
|
+
parent.messages.delete(self)
|
243
|
+
return true if res_page.body =~ /Mail/
|
244
|
+
|
245
|
+
end
|
246
|
+
|
247
|
+
def forward(to)
|
248
|
+
#Forward this message
|
249
|
+
f_url = "/cgi-bin/compose?type=f&msg=#{self.id}&"+parent.inbox
|
250
|
+
f_page = parent.get(f_url)
|
251
|
+
|
252
|
+
fwd_form = f_page.form('composeform')
|
253
|
+
fwd_form.to = to
|
254
|
+
res_page = parent.submit(fwd_form)
|
255
|
+
|
256
|
+
if res_page.body =~ /Your message has been sent/
|
257
|
+
return true
|
258
|
+
else
|
259
|
+
raise "Error forwarding message"
|
260
|
+
end
|
261
|
+
|
262
|
+
end
|
263
|
+
end
|
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.11
|
3
|
+
specification_version: 1
|
4
|
+
name: hotmailer
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 1.0.0
|
7
|
+
date: 2006-11-15 00:00:00 +00:00
|
8
|
+
summary: Package for programatically accessing hotmail accounts
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: amrangaye@gmail.com
|
12
|
+
homepage:
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire: hotmailer
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
authors:
|
29
|
+
- Amran Gaye
|
30
|
+
files:
|
31
|
+
- lib/hotmailer.rb
|
32
|
+
- README
|
33
|
+
test_files: []
|
34
|
+
|
35
|
+
rdoc_options: []
|
36
|
+
|
37
|
+
extra_rdoc_files:
|
38
|
+
- README
|
39
|
+
executables: []
|
40
|
+
|
41
|
+
extensions: []
|
42
|
+
|
43
|
+
requirements: []
|
44
|
+
|
45
|
+
dependencies:
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: mechanize
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.0.0
|
54
|
+
version:
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: hpricot
|
57
|
+
version_requirement:
|
58
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 0.0.0
|
63
|
+
version:
|