google_text 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in google_text.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,32 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ google_text (0.0.2)
5
+ curb (~> 0.7.6)
6
+ json
7
+ nokogiri
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ curb (0.7.15)
13
+ diff-lcs (1.1.3)
14
+ fakeweb (1.3.0)
15
+ json (1.6.1)
16
+ nokogiri (1.5.0)
17
+ rspec (2.6.0)
18
+ rspec-core (~> 2.6.0)
19
+ rspec-expectations (~> 2.6.0)
20
+ rspec-mocks (~> 2.6.0)
21
+ rspec-core (2.6.4)
22
+ rspec-expectations (2.6.0)
23
+ diff-lcs (~> 1.1.2)
24
+ rspec-mocks (2.6.0)
25
+
26
+ PLATFORMS
27
+ ruby
28
+
29
+ DEPENDENCIES
30
+ fakeweb
31
+ google_text!
32
+ rspec
data/HISTORY.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 0.0.3 (2011-09-23)
2
+
3
+ * Adjusted parsers to Google Voice changes
4
+
1
5
  ## 0.0.2 (2010-10-04)
2
6
 
3
7
  * Ruby 1.9.2 compatibility
data/README.md CHANGED
@@ -24,6 +24,7 @@ Prerequisites
24
24
 
25
25
  GoogleText currently relies on the following gems:
26
26
 
27
+ * bundler
27
28
  * nokogiri
28
29
  * curb
29
30
  * json
@@ -33,10 +34,14 @@ Installation
33
34
 
34
35
  1. Get a Google Voice account, if don't already have one.
35
36
 
36
- 2. Install the gem, which should also install all the prerequisites.
37
+ 2. Install the gem:
37
38
 
38
39
  `gem install google_text`
39
40
 
41
+ 3. Install all dependencies using bundler:
42
+
43
+ `bundle install`
44
+
40
45
  3. Configure GoogleText someplace sensible, using the email address and password you use to log on to your Google Voice account. If you are using GoogleText in a Rails application, `config/initializers/google_text.rb` is a good place to put the configuration block:
41
46
 
42
47
 
data/Rakefile CHANGED
@@ -1,21 +1,4 @@
1
- require 'rake/testtask'
2
- require 'rake/rdoctask'
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
3
 
4
- desc "Push a new version to Rubygems."
5
- task :publish do
6
- require File.dirname(__FILE__) + '/lib/google_text/version'
7
-
8
- system "git tag v#{GoogleText::Version}"
9
- sh "gem build google_text.gemspec"
10
- sh "gem push google_text-#{GoogleText::Version}.gem"
11
- sh "git push origin master --tags"
12
- sh "git clean -fd"
13
- end
14
-
15
-
16
- desc "Install gem locally"
17
- task :install do
18
- require File.dirname(__FILE__) + '/lib/google_text/version'
19
- sh "gem build google_text.gemspec"
20
- sh "sudo gem install ./google_text-#{GoogleText::Version}.gem"
21
- end
4
+ RSpec::Core::RakeTask.new('spec')
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require 'google_text/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "google_text"
7
+ s.version = GoogleText::VERSION
8
+ s.summary = "GoogleText is a SMS client library for sending and receiving free SMS through Google Voice."
9
+ s.description = "GoogleText is a SMS client library for sending and receiving free SMS through Google Voice. Alas, Google Voice does not yet have an API, so GoogleText uses Curl and Nokogiri to scrape and post using Google Voice web URLs."
10
+
11
+ s.homepage = "http://github.com/feldpost/google_text"
12
+ s.email = "sebastian@feldpost.com"
13
+ s.authors = [ "Sebastian Friedrich" ]
14
+
15
+ s.rubyforge_project = "google_text"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_runtime_dependency "json"
23
+ s.add_runtime_dependency "nokogiri"
24
+ s.add_runtime_dependency "curb", '~>0.7.6'
25
+
26
+ s.add_development_dependency('rspec')
27
+ s.add_development_dependency('fakeweb')
28
+
29
+ end
30
+
31
+
32
+
@@ -27,12 +27,12 @@ module GoogleText
27
27
  end
28
28
 
29
29
  def get_xsrf_token
30
- @xsrf_token = parser.xsrf_token_from login_page
30
+ @xsrf_token = Parsers::Login.new(login_page).xsrf_token
31
31
  end
32
32
 
33
33
  def get_session_id
34
34
  begin
35
- @session_id = parser.session_id_from dashboard_page
35
+ @session_id = Parsers::Dashboard.new(dashboard_page).session_id
36
36
  rescue
37
37
  raise "Could not retrieve Google Voice Session ID"
38
38
  end
@@ -44,7 +44,7 @@ module GoogleText
44
44
  end
45
45
 
46
46
  def get_messages
47
- @messages = parser.messages_from inbox_page
47
+ @messages = Parsers::Inbox.new(inbox_page).messages
48
48
  end
49
49
 
50
50
  def mark_as_read(id)
@@ -3,7 +3,7 @@ module GoogleText
3
3
  attr_accessor :email, :password, :login_url, :user_agent, :dashboard_url, :inbox_url, :service, :send_url, :mark_as_read_url
4
4
 
5
5
  DEFAULTS = {
6
- :login_url => 'https://www.google.com/accounts/ServiceLoginAuth',
6
+ :login_url => 'https://accounts.google.com/ServiceLoginAuth',
7
7
  :dashboard_url => 'https://www.google.com/voice',
8
8
  :mark_as_read_url => 'https://www.google.com/voice/inbox/mark',
9
9
  :inbox_url => 'https://www.google.com/voice/inbox/recent',
@@ -0,0 +1,55 @@
1
+ module GoogleText
2
+ module Parsers
3
+ class Base
4
+ attr_accessor :string
5
+
6
+ def self.selectors_for(symbol_or_hash)
7
+ if symbol_or_hash.respond_to?(:keys)
8
+ @selectors = symbol_or_hash
9
+ else
10
+ @selectors[symbol_or_hash]
11
+ end
12
+ end
13
+
14
+ def initialize(string)
15
+ @string = string
16
+ process
17
+ end
18
+
19
+ protected
20
+
21
+ def selectors_for(*args)
22
+ self.class.selectors_for(*args)
23
+ end
24
+
25
+ def process
26
+ raise "Not implemented"
27
+ end
28
+
29
+ def html_for(string,selector)
30
+ selected = string.css(selector)
31
+ if block_given?
32
+ selected.each do |item|
33
+ yield(item)
34
+ end
35
+ else
36
+ selected.inner_html
37
+ end
38
+ end
39
+
40
+ def parse_document(string)
41
+ Nokogiri::HTML::Document.parse(string)
42
+ end
43
+
44
+ def parse_fragment(string)
45
+ Nokogiri::HTML::DocumentFragment.parse(string)
46
+ end
47
+
48
+ def parse_string(string)
49
+ Nokogiri::XML.parse(string)
50
+ end
51
+
52
+
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,16 @@
1
+ module GoogleText
2
+ module Parsers
3
+ class Dashboard < Base
4
+ attr_accessor :session_id
5
+ selectors_for :session_id => 'form#gc-search-form'
6
+
7
+ protected
8
+
9
+ def process
10
+ section = html_for parse_document(@string), selectors_for(:session_id)
11
+ @session_id = section.match(/value="(.+)"/)[1]
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,75 @@
1
+ module GoogleText
2
+ module Parsers
3
+ class Inbox < Base
4
+
5
+ attr_accessor :messages
6
+
7
+ selectors_for :message_row => 'div.gc-message-sms-row',
8
+ :message_from => 'span.gc-message-sms-from',
9
+ :message_time => 'span.gc-message-sms-time',
10
+ :message_text => 'span.gc-message-sms-text'
11
+
12
+ protected
13
+
14
+ def process
15
+ @messages = []
16
+ document = parse_string string
17
+ html_fragment = parse_fragment document.to_html
18
+ inbox = json_inbox(document)
19
+ @messages = parse_messages(inbox['messages'], html_fragment)
20
+ end
21
+
22
+ def json_inbox(document)
23
+ string = document.css('json').first.to_s.scan(/CDATA\[(.+)\]\]/).flatten
24
+ JSON.parse(string.first)
25
+ end
26
+
27
+ def parse_messages(json_messages, page_fragment)
28
+ build_messages(json_messages)
29
+ read_message_details(page_fragment)
30
+ return @messages
31
+ end
32
+
33
+ def build_messages(json_messages)
34
+ json_messages.each do |json_message|
35
+ if json_message[1]['type'].to_i == 2
36
+ next
37
+ else
38
+ @messages << parse_message(json_message)
39
+ end
40
+ @messages.sort_by {|message| message.start_time}
41
+ end
42
+ end
43
+
44
+ def read_message_details(page_fragment)
45
+ @messages.each do |message|
46
+ html_for page_fragment, selectors_for(:message_row) do |row|
47
+ if html_for(row,selectors_for(:message_from)).strip! =~ /Me:/
48
+ next
49
+ elsif html_for(row, selectors_for(:message_time)) =~ Regexp.new(message.display_start_time)
50
+ message.to = 'Me'
51
+ message.from = html_for(row, selectors_for(:message_from)).strip!.gsub!(':', '')
52
+ message.text = html_for row, selectors_for(:message_text)
53
+ else
54
+ next
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ def parse_message(json_array)
61
+ message = Message.new
62
+ message.id = json_array[0]
63
+ message.start_time = json_array[1]['startTime'].to_i
64
+ message.read_status = json_array[1]['isRead']
65
+ message.display_start_time = json_array[1]['displayStartTime']
66
+ message.relative_start_time = json_array[1]['relativeStartTime']
67
+ message.display_number = json_array[1]['displayNumber']
68
+ message.display_start_date_time = json_array[1]['displayStartDateTime']
69
+ message.labels = json_array[1]['labels']
70
+ return message
71
+ end
72
+
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,20 @@
1
+ module GoogleText
2
+ module Parsers
3
+ class Login < Base
4
+ attr_accessor :xsrf_token
5
+ selectors_for :xsrf_token => 'form#gaia_loginform input'
6
+
7
+ protected
8
+
9
+ def process
10
+ @xsrf_token = nil
11
+ html_for parse_fragment(@string), selectors_for(:xsrf_token) do |input|
12
+ if input.to_s =~ /GALX/
13
+ @xsrf_token = input.to_s.scan(/value\="(.+?)"/).flatten.pop
14
+ end
15
+ end
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -1,3 +1,3 @@
1
1
  module GoogleText # :nodoc:
2
- VERSION = Version = File.readlines(File.expand_path('../../../VERSION', __FILE__)).first
2
+ VERSION = "0.0.3"
3
3
  end
data/lib/google_text.rb CHANGED
@@ -1,9 +1,16 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+
1
4
  require 'curb'
2
5
  require 'nokogiri'
3
6
  require 'json'
7
+ require "google_text/version"
4
8
  require 'google_text/configuration'
5
- require 'google_text/parser'
6
9
  require 'google_text/session'
7
10
  require 'google_text/message'
8
11
  require 'google_text/account'
9
- require 'google_text/client'
12
+ require 'google_text/client'
13
+ require 'google_text/parsers/base'
14
+ require 'google_text/parsers/inbox'
15
+ require 'google_text/parsers/dashboard'
16
+ require 'google_text/parsers/login'