manhunt 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -5,13 +5,14 @@ begin
5
5
  require 'jeweler'
6
6
  Jeweler::Tasks.new do |gem|
7
7
  gem.name = "manhunt"
8
- gem.summary = %Q{one-line summary of your gem}
9
- gem.description = %Q{ longer description of your gem}
10
- gem.email = "self@richardpenwell.me"
8
+ gem.summary = %Q{Client library for manhunt.net }
9
+ gem.description = %Q{Provides object model to access manhunt.net data}
10
+ gem.email = "almightylinuxgod@me.com"
11
11
  gem.homepage = "http://github.com/penwellr/manhunt"
12
12
  gem.authors = ["Richard Penwell"]
13
13
  gem.add_development_dependency "rspec", ">= 1.2.9"
14
- gem.add_dependency "smartfox"
14
+ gem.add_dependency 'smartfox', '>= 3.1'
15
+ gem.files.exclude 'nbproject/**'
15
16
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
17
  end
17
18
  Jeweler::GemcutterTasks.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.1.3
@@ -0,0 +1,13 @@
1
+ require 'smartfox'
2
+ require 'logger'
3
+ require 'net/http'
4
+
5
+ module Manhunt
6
+ autoload :Folder, 'manhunt/folder'
7
+ autoload :Sessuion, 'manhunt/session'
8
+ autoload :User, 'manhunt/user'
9
+ autoload :Photo, 'manhunt/photo'
10
+ autoload :Message, 'manhunt/message'
11
+
12
+ Logger = Logger.new(STDOUT)
13
+ end
@@ -0,0 +1,60 @@
1
+ class Manhunt::Folder
2
+ attr_reader :name, :count
3
+
4
+ def initialize(session, folder)
5
+ @session = session
6
+ @name = folder
7
+ @messages = {}
8
+ end
9
+
10
+ def messages(page = 1)
11
+ reload(page)
12
+ @messages.values.sort{ |a,b| a.date <=> b.date }.reverse
13
+ end
14
+
15
+ def reload(page)
16
+ url = "/mail/folder/#{@name}/#{page}"
17
+ document = @session.get_document(url)
18
+ @count = ManhuntFolder.parse_message_count(document)
19
+
20
+ @messages = ManhuntFolder.parse_messages(document)
21
+ end
22
+
23
+ def message(id)
24
+ url = "/mail/viewMessage/id/#{id}/folder/#{@name}"
25
+ document = @session.get_document(url)
26
+
27
+ ManhuntMessage.parse_message(document, id)
28
+ end
29
+
30
+ def self.parse_messages(document)
31
+ messages = {}
32
+ message_table = (document/"#msgsListTable")
33
+ format = parse_message_header(message_table/"tr.header")
34
+
35
+ (message_table/"tr").each do |row|
36
+ unless row[:class] == 'header'
37
+ message = ManhuntMessage.parse_header(format, row)
38
+ messages[message.id] = message
39
+ end
40
+ end
41
+
42
+ messages
43
+ end
44
+
45
+ def self.parse_message_header(header_row)
46
+ (header_row/'td').map do |column|
47
+ header = column.inner_text.strip
48
+ if header.empty?
49
+ nil
50
+ else
51
+ header.delete(':').downcase.gsub(' ', '_').to_sym
52
+ end
53
+ end
54
+ end
55
+
56
+ def self.parse_message_count(document)
57
+ count_field = (document / "#msgsShownTxt").inner_text
58
+ (/(\d+)\s+$/.match(count_field))[1].to_i
59
+ end
60
+ end
@@ -0,0 +1,74 @@
1
+ class Manhunt::Message
2
+ include ActiveModel::Serializers::Xml
3
+ include ActiveModel::Serializers::JSON
4
+
5
+ GUID_REGEX = /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/
6
+ PROFILE_NAME_REGEX = /setWindow\('profile\/(\w+)','profile'\);/
7
+ USER_ID_REGEX = /modalOpen\('list\/modalAddBuddy',\{buddy:(\d+)\}\);/
8
+
9
+ attr_reader :row, :subject, :from, :format, :state, :id, :body, :from_id, :date, :online
10
+
11
+ def attributes
12
+ { 'subject' => subject, 'from' => from, 'state' => state, 'id' => id, 'body' => body, 'date' => date, 'online' => online }
13
+ end
14
+
15
+ def self.parse_header(format, row)
16
+ ManhuntMessage.new(:header, row, format)
17
+ end
18
+
19
+ def self.parse_message(document, id)
20
+ message = ManhuntMessage.new(:message, document)
21
+ message.instance_eval do
22
+ @id = id
23
+ end
24
+ message
25
+ end
26
+
27
+ def self.compose(session, user_name, user_id, reply_message_id = nil)
28
+ if reply_message_id
29
+ url = "/mail/compose/recipientId/#{user_id}/messageId/#{reply_message_id}/username/#{user_name}"
30
+ end
31
+ compose = session.get_document(url)
32
+
33
+ { :subject => (compose/"#subject").first.attributes['value'], :body => (compose/"#body").first.inner_html, :raw => compose }
34
+ end
35
+
36
+ def initialize(type, document, format = nil)
37
+ @format = format
38
+ @row = document
39
+
40
+ case type
41
+ when :header
42
+ columns = (document/"td")
43
+
44
+ @subject = (document/".subject").inner_text.strip
45
+ @online = (document/".buddyOnline").any?
46
+ @from = columns[@format.index(:from)].inner_text
47
+ @state = :unread
48
+ @state = :read if (document/".messageRead").any?
49
+ @state = :replied if (document/".messageReplied").any?
50
+ @id = GUID_REGEX.match((document/".subject a").first.attributes['href'])[0]
51
+ @date = Time.at((columns[@format.index(:date)]/".LocalTime").first.attributes['gmt_time'].to_i)
52
+ when :message
53
+ @body = (document/"#msgTextDiv").inner_html
54
+ @subject = (document/".headerColored").inner_text.strip
55
+ @from = PROFILE_NAME_REGEX.match((document/"#readRecipProfLink a").first.attributes['onclick'])[1]
56
+ @from_id = USER_ID_REGEX.match((document/"#buddyButton").first.attributes['onclick'])[1]
57
+ end
58
+ end
59
+
60
+ def self.send_message(session, params)
61
+ url = "/mail/send"
62
+
63
+ options = { 'body' => params[:body], 'subject' => params[:subject], 'recipientId' => params[:send_to_id], 'username' => params[:send_to] }
64
+ options['replyMessageId'] = params[:reply_message_id] if params[:reply_message_id]
65
+
66
+
67
+ session.post_nil(url, options)
68
+ end
69
+
70
+ def to_param
71
+ id
72
+ end
73
+
74
+ end
@@ -0,0 +1,18 @@
1
+ class Manhunt::Photo
2
+ attr_reader :photo_id
3
+
4
+ def initialize(user, photo_id)
5
+ @user = user
6
+ @photo_id = photo_id
7
+ end
8
+
9
+ def user_id
10
+ @user.user_id
11
+ end
12
+
13
+ def self.content(session, profile_id, photo_id, size = "med")
14
+ photo_ref = session.post_object('/photo/ajaxGetPhoto', {'profileId' => profile_id, 'photoId' => photo_id, 'photoSize' => size })
15
+
16
+ session.get_binary(photo_ref['url'])
17
+ end
18
+ end
@@ -0,0 +1,184 @@
1
+ require 'net/http'
2
+
3
+ class Manhunt::Session
4
+ LOGIN_PAGE_REGEX = /<form id="login" name="login" method="post" action="\/">/
5
+
6
+ attr_reader :username
7
+ attr_reader :language
8
+
9
+ def initialize(username, password, language = 'en')
10
+ @username = username
11
+ @password = password
12
+ @language = language
13
+ @cookies = { 'MHLogin' => '1', '__utma' => '179992888.1977247352.1264973581.1267729320.1267734788.33',
14
+ '__utmb' => '179992888.15.10.1267734788', '__utmc' => '179992888',
15
+ '__utmz' => '179992888.1264973581.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)' }
16
+ end
17
+
18
+ def self.create(options)
19
+ options[:language] ||= 'en'
20
+ session = Manhunt::Session.new(options[:username], options[:password], options[:language])
21
+ session.create
22
+
23
+ return session
24
+ end
25
+
26
+ def create
27
+ @login_options = { 'loginLang' => @language, 'rememberLogin' => false, 'name' => @username, 'pass' => @password, 'skinId' => 'mh', 'canChat' => false }
28
+ login
29
+ end
30
+
31
+ def login
32
+ @login_options ||= { 'loginLang' => @language, 'rememberLogin' => false, 'name' => @username, 'pass' => @password, 'skinId' => 'mh', 'canChat' => false }
33
+ result = post_object('/user/janusLookup', @login_options)
34
+
35
+ @valid = result["handleError"] == 'success'
36
+ end
37
+
38
+ def valid?
39
+ @valid || false
40
+ end
41
+
42
+ def post_object(url, object)
43
+ request_object(url, :post, object)
44
+ end
45
+
46
+ def get_object(url)
47
+ RAILS_DEFAULT_LOGGER.info " \e[1;#{color}mObject Load (0.0s) \e[1;30m#{url}\e[0m"
48
+ request_object(url, :get)
49
+ end
50
+
51
+ def request_object(url, method, object = nil)
52
+ case method
53
+ when :get
54
+ request = Net::HTTP::Get.new(url)
55
+ when :post
56
+ request = Net::HTTP::Post.new(url)
57
+ end
58
+ request['Accept'] = 'application/json, text/javascript, */*'
59
+ request['X-Requested-With'] = 'XMLHttpRequest'
60
+ request.form_data = object if object
61
+ result = prepare_request(request)
62
+ ActiveSupport::JSON.decode(ManhuntSession.pureify_json(result.body))
63
+ end
64
+
65
+ def post_nil(url, object = nil)
66
+ request_nil(url, :post, object)
67
+ end
68
+
69
+ def request_nil(url, method, object = nil)
70
+ RAILS_DEFAULT_LOGGER.info " \e[1;#{color}m#{method.to_s.capitalize} Save (0.0s) \e[1;30m#{url} - #{object.inspect if object}\e[0m"
71
+ case method
72
+ when :get
73
+ request = Net::HTTP::Get.new(url)
74
+ when :post
75
+ request = Net::HTTP::Post.new(url)
76
+ end
77
+ request['Accept'] = 'application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5'
78
+ request['Content-Type'] = 'application/x-www-form-urlencoded' if method == :post
79
+ request.form_data = object if object
80
+ result = prepare_request(request)
81
+ RAILS_DEFAULT_LOGGER.debug "Result => #{result}"
82
+ nil
83
+ end
84
+
85
+
86
+
87
+ def get_document(url)
88
+ RAILS_DEFAULT_LOGGER.info " \e[1;#{color}mDocument Load (0.0s) \e[1;30m#{url}\e[0m"
89
+ request = Net::HTTP::Get.new(url)
90
+ request['Accept'] = 'application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5'
91
+
92
+ result = prepare_request(request)
93
+
94
+ if block_given?
95
+ Hpricot(yield(result.body))
96
+ else
97
+ Hpricot(result.body)
98
+ end
99
+ end
100
+
101
+ def get_binary(url)
102
+ puts " \e[1;#{color}mBinary Load (0.0s) \e[1;30m#{url}\e[0m"
103
+ request = Net::HTTP::Get.new(url)
104
+ request['Accept'] = 'application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5'
105
+
106
+ prepare_request(request)
107
+ end
108
+
109
+ def prepare_request(request)
110
+ request["Cookie"] = @cookies.map{|key, value| "#{key}=#{value}"}.join('; ')
111
+ request["Referer"] = 'http://www.manhunt.net/welcome'
112
+ request["User-Agent"] = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-us) AppleWebKit/533.1+ (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10'
113
+ request['Accept-Language'] = 'Accept-Language: en-us'
114
+
115
+ result = Net::HTTP.new('www.manhunt.net', 80).start { |http|
116
+ http.request(request)
117
+ }
118
+ if result['Set-Cookie']
119
+ result.get_fields('Set-Cookie').each do |cookie|
120
+ data = cookie.split(';')[0]
121
+ key = data.split('=')[0]
122
+ value = data.split('=')[1]
123
+ @cookies[key] = value
124
+ end
125
+ end
126
+
127
+ if LOGIN_PAGE_REGEX.match(result.body)
128
+ login
129
+ result = Net::HTTP.new('www.manhunt.net', 80).start { |http|
130
+ http.request(request)
131
+ }
132
+ end
133
+
134
+ result
135
+ end
136
+
137
+ def unlock_photos(user)
138
+ parameters = { 'uid' => user.platform_id, 'name' => user.username }
139
+ Rails.logger.info post_object('/list/ajaxAddUnlock', parameters)
140
+ end
141
+
142
+ def folders
143
+ @folders = ['inbox', 'sent', 'saved', 'trash'].map do |name|
144
+ ManhuntFolder.new(self, name)
145
+ end
146
+ end
147
+
148
+ def folder(name)
149
+ ManhuntFolder.new(self, name)
150
+ end
151
+
152
+ def photo_content(profile_id, photo_id, size = "med")
153
+ ManhuntPhoto.content(self, profile_id, photo_id, size)
154
+ end
155
+
156
+ def unread_count
157
+ get_object('/mail/ajaxGetUnreadMessageCount')
158
+ end
159
+
160
+ def user(name)
161
+ Manhunt::User.find(self, name)
162
+ end
163
+
164
+
165
+
166
+ def compose(user, user_id, reply_message_id = nil)
167
+ Manhunt::Message.compose(self, user, user_id, reply_message_id)
168
+ end
169
+
170
+ def send_message(params)
171
+ Manhunt::Message.send_message(self, params)
172
+ end
173
+
174
+ private
175
+ def color
176
+ @@color ||= 36
177
+ @@color = (@@color == 35) ? 36 : 35
178
+ end
179
+
180
+ def self.pureify_json(input)
181
+ replace_input = /^\((.*)\)$/.match(input)
182
+ replace_input ? replace_input[1] : input
183
+ end
184
+ end
@@ -0,0 +1,80 @@
1
+ class Manhunt::User
2
+ attr_reader :user_id, :username, :online, :headline, :photos, :body
3
+ attr_reader :location, :position, :age, :build, :height, :eyes, :ethnicity
4
+ attr_reader :hair, :availability, :hiv, :place, :html, :stats
5
+
6
+ def self.find(session, username)
7
+ uri = "/profile/#{username}"
8
+ document = session.get_document(uri) do |text|
9
+ # This little ugly hack fixes some majorly broken HTML on the site
10
+ text.gsub(", \"med\", \"#largePic\")'; return false;>", ", \"med\", \"#largePic\"); return false;'>")
11
+ end
12
+
13
+ ManhuntUser.parse(session, document)
14
+ end
15
+
16
+ def self.parse(session, document)
17
+ user = ManhuntUser.new(session, document)
18
+ end
19
+
20
+ def id
21
+ user_id
22
+ end
23
+
24
+ def model_name
25
+ "user"
26
+ end
27
+
28
+ def initialize(session, document)
29
+ @session = session
30
+ @username = (document/"#name").inner_text.strip
31
+ @user_id = ManhuntUser.parse_user_id(document)
32
+ @online = (document/".buddyOnline").any?
33
+ @location = (document/"#profileLocation").inner_text.strip
34
+ @body = (document/'#body').inner_text
35
+ @headline = (document/'#headline').inner_text
36
+ @html = document
37
+ @photos = ManhuntUser.parse_photos(self, document/"#pics")
38
+
39
+ parse_stats(document/"#stats")
40
+
41
+
42
+ end
43
+
44
+ def parse_stats(stats_div)
45
+ @stats = {}
46
+ (stats_div/"div").each do |stat|
47
+ title = (stat/"strong").inner_text.strip
48
+ value = (stat/"p").inner_text.strip
49
+
50
+ @stats[title] = value unless title.blank?
51
+ end
52
+
53
+ (stats_div/"label").each do |label|
54
+ title = label.inner_text.strip
55
+ value = label.next_sibling.inner_text.strip
56
+
57
+ @stats[title] = value unless title.blank?
58
+ end
59
+ end
60
+
61
+ def self.parse_photos(user, photo_element)
62
+ (photo_element/'div').map do |photo|
63
+ photo_id = photo[:photoid].to_i
64
+ ManhuntPhoto.new(user, photo_id)
65
+ end
66
+ end
67
+
68
+ def self.parse_user_id(document)
69
+ large_pic = (document/"#largePic").first
70
+ if large_pic
71
+ onclick = large_pic.attributes['onclick']
72
+ match = (/viewProfilePic\(this, (\d+)\); return false;/.match(onclick))
73
+ if match
74
+ return match[1]
75
+ end
76
+ end
77
+
78
+ nil
79
+ end
80
+ end
@@ -0,0 +1,63 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{manhunt}
8
+ s.version = "0.1.3"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Richard Penwell"]
12
+ s.date = %q{2010-06-16}
13
+ s.description = %q{Provides object model to access manhunt.net data}
14
+ s.email = %q{almightylinuxgod@me.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "lib/manhunt.rb",
27
+ "lib/manhunt/folder.rb",
28
+ "lib/manhunt/message.rb",
29
+ "lib/manhunt/photo.rb",
30
+ "lib/manhunt/session.rb",
31
+ "lib/manhunt/user.rb",
32
+ "manhunt.gemspec",
33
+ "spec/manhunt_spec.rb",
34
+ "spec/spec.opts",
35
+ "spec/spec_helper.rb"
36
+ ]
37
+ s.homepage = %q{http://github.com/penwellr/manhunt}
38
+ s.rdoc_options = ["--charset=UTF-8"]
39
+ s.require_paths = ["lib"]
40
+ s.rubygems_version = %q{1.3.7}
41
+ s.summary = %q{Client library for manhunt.net}
42
+ s.test_files = [
43
+ "spec/manhunt_spec.rb",
44
+ "spec/spec_helper.rb"
45
+ ]
46
+
47
+ if s.respond_to? :specification_version then
48
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
49
+ s.specification_version = 3
50
+
51
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
52
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
53
+ s.add_runtime_dependency(%q<smartfox>, [">= 3.1"])
54
+ else
55
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
56
+ s.add_dependency(%q<smartfox>, [">= 3.1"])
57
+ end
58
+ else
59
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
60
+ s.add_dependency(%q<smartfox>, [">= 3.1"])
61
+ end
62
+ end
63
+
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: manhunt
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 29
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
8
  - 1
8
- - 1
9
- version: 0.1.1
9
+ - 3
10
+ version: 0.1.3
10
11
  platform: ruby
11
12
  authors:
12
13
  - Richard Penwell
@@ -21,9 +22,11 @@ dependencies:
21
22
  name: rspec
22
23
  prerelease: false
23
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
24
26
  requirements:
25
27
  - - ">="
26
28
  - !ruby/object:Gem::Version
29
+ hash: 13
27
30
  segments:
28
31
  - 1
29
32
  - 2
@@ -35,16 +38,19 @@ dependencies:
35
38
  name: smartfox
36
39
  prerelease: false
37
40
  requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
38
42
  requirements:
39
43
  - - ">="
40
44
  - !ruby/object:Gem::Version
45
+ hash: 5
41
46
  segments:
42
- - 0
43
- version: "0"
47
+ - 3
48
+ - 1
49
+ version: "3.1"
44
50
  type: :runtime
45
51
  version_requirements: *id002
46
- description: " longer description of your gem"
47
- email: self@richardpenwell.me
52
+ description: Provides object model to access manhunt.net data
53
+ email: almightylinuxgod@me.com
48
54
  executables: []
49
55
 
50
56
  extensions: []
@@ -60,6 +66,12 @@ files:
60
66
  - Rakefile
61
67
  - VERSION
62
68
  - lib/manhunt.rb
69
+ - lib/manhunt/folder.rb
70
+ - lib/manhunt/message.rb
71
+ - lib/manhunt/photo.rb
72
+ - lib/manhunt/session.rb
73
+ - lib/manhunt/user.rb
74
+ - manhunt.gemspec
63
75
  - spec/manhunt_spec.rb
64
76
  - spec/spec.opts
65
77
  - spec/spec_helper.rb
@@ -73,26 +85,30 @@ rdoc_options:
73
85
  require_paths:
74
86
  - lib
75
87
  required_ruby_version: !ruby/object:Gem::Requirement
88
+ none: false
76
89
  requirements:
77
90
  - - ">="
78
91
  - !ruby/object:Gem::Version
92
+ hash: 3
79
93
  segments:
80
94
  - 0
81
95
  version: "0"
82
96
  required_rubygems_version: !ruby/object:Gem::Requirement
97
+ none: false
83
98
  requirements:
84
99
  - - ">="
85
100
  - !ruby/object:Gem::Version
101
+ hash: 3
86
102
  segments:
87
103
  - 0
88
104
  version: "0"
89
105
  requirements: []
90
106
 
91
107
  rubyforge_project:
92
- rubygems_version: 1.3.6
108
+ rubygems_version: 1.3.7
93
109
  signing_key:
94
110
  specification_version: 3
95
- summary: one-line summary of your gem
111
+ summary: Client library for manhunt.net
96
112
  test_files:
97
113
  - spec/manhunt_spec.rb
98
114
  - spec/spec_helper.rb