galerts 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2ade27844d1c41508bbacd7b030c2ed4654a45e4
4
+ data.tar.gz: 6e1f27c679e63c21e1d238158397e2442dea11c6
5
+ SHA512:
6
+ metadata.gz: f8b27acbde41ba7bd76d0d34b7404260989d3aced4d22a697057b5ba483646bd17368c46b9f17e7ad55e3545a79f514da39ca4b4f1719258119d7750e24455eb
7
+ data.tar.gz: 219056aebeb3d6e3834012f4fd98d7a521df6d7931579c7798fb1782077d81d6dc4631850ffc3c9db7afead1d65dca15cd58922e710e6532551338678d86867a
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,41 @@
1
+ # Galerts
2
+
3
+ Simple Ruby library that uses Mechanize to scrape Google Alerts from the google
4
+ alerts webpage.
5
+
6
+ ## Features
7
+
8
+ - List all alerts associated with account.
9
+ - Create new alerts for any google domain.
10
+
11
+ ## Example
12
+
13
+ ```ruby
14
+ require 'google_alerts'
15
+
16
+ manager = Galerts::Manager.new('example@gmail.com', 'password')
17
+
18
+ # List alerts
19
+ alerts = manager.alerts
20
+
21
+ # Create a new alert for on Google News Turkey in real time delivering alerts
22
+ # via RSS
23
+ manager.create("my keywords", {
24
+ :frequency => Galerts::RT,
25
+ :domain => 'com.tr',
26
+ :language => "tr",
27
+ :sources => [Galerts::NEWS],
28
+ :how_many => Galerts::ALL_RESULTS,
29
+ :region => "TR",
30
+ :delivery => Galerts::RSS
31
+ }
32
+ )
33
+ ```
34
+
35
+ ## Contribute
36
+
37
+ I need your contributions to make that work better!
38
+
39
+ ## License
40
+
41
+ This project licensed under MIT.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,18 @@
1
+ require File.expand_path('../lib/galerts/version', __FILE__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'galerts'
5
+ s.version = Galerts::VERSION.dup
6
+ s.date = '2014-09-16'
7
+ s.summary = 'Ruby library to manage google alerts'
8
+ s.description = %q{Manage to Google Alerts}
9
+ s.authors = ["Emre Can Yılmaz"]
10
+ s.email = ['emrecan@ecylmz.com']
11
+ s.files = `git ls-files`.split("\n")
12
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
13
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
14
+ s.require_paths = ['lib']
15
+ s.homepage = 'https://github.com/pivotus/galerts'
16
+ s.license = 'MIT'
17
+ s.add_runtime_dependency('mechanize', '~> 2.7')
18
+ end
@@ -0,0 +1,51 @@
1
+ require File.expand_path('../galerts/alert', __FILE__)
2
+ require File.expand_path('../galerts/manager', __FILE__)
3
+
4
+ module Galerts
5
+ # URLs
6
+ CREATE_ALERT_URL = 'https://www.google.com/alerts/create?'
7
+ GOOGLE_LOGIN_URL = 'https://accounts.google.com/ServiceLogin?'
8
+ ALERTS_URL = 'https://www.google.com/alerts'
9
+ LOGIN_URL = "#{GOOGLE_LOGIN_URL}service=alerts&continue=#{ALERTS_URL}"
10
+
11
+ # Google Return HTML Definitions
12
+ ALERT_EXIST = "[null,11,null,\"\"]"
13
+ ALERT_SOMETHING_WENT_WRONG = "[null,7,null,\"\"]"
14
+
15
+ # Google Value
16
+ BEST_RESULTS = 'Only the best results'
17
+ ALL_RESULTS = 'All results'
18
+
19
+ HOW_MANY_TYPES = {
20
+ ALL_RESULTS => 2,
21
+ BEST_RESULTS => 3
22
+ }
23
+
24
+ RSS = 'rss'
25
+ EMAIL = 'email'
26
+
27
+ DELIVERY_TYPES = [RSS, EMAIL]
28
+
29
+ RT = 'As it happens'
30
+ DAILY = 'Once a day'
31
+ WEEKLY = 'Once a week'
32
+
33
+ FREQ_TYPES = [RT, DAILY, WEEKLY]
34
+
35
+
36
+ BLOGS = 'Blogs'
37
+ NEWS = 'News'
38
+ WEB = 'Web'
39
+ VIDEOS = 'Videos'
40
+ BOOKS = 'Books'
41
+ DISCUSSIONS = 'Discussions'
42
+
43
+ SOURCES_TYPES = {
44
+ BLOGS => 1,
45
+ NEWS => 2,
46
+ WEB => 3,
47
+ VIDEOS => 5,
48
+ BOOKS => 6,
49
+ DISCUSSIONS => 7
50
+ }
51
+ end
@@ -0,0 +1,36 @@
1
+ module Galerts
2
+ class Alert
3
+ attr_accessor :search_query, :id, :data_id, :domain, :frequency, :sources, :language, :how_many, :region, :delivery, :feed_url
4
+ def initialize(search_query, options = {})
5
+
6
+ default_options = {
7
+ id: 0,
8
+ data_id: 0,
9
+ domain: 'com',
10
+ frequency: 'rt',
11
+ sources: '',
12
+ language: 'tr',
13
+ how_many: 'all_results',
14
+ region: 'TR',
15
+ delivery: 'rss',
16
+ feed_url: nil
17
+ }
18
+
19
+ default_options.each do |key, value|
20
+ options[key] ||= value
21
+ end
22
+
23
+ @search_query = search_query
24
+ @id = options[:id]
25
+ @data_id = options[:data_id]
26
+ @domain = options[:domain]
27
+ @frequency = options[:frequency]
28
+ @sources = options[:sources]
29
+ @language = options[:language]
30
+ @how_many = options[:how_many]
31
+ @region = options[:region]
32
+ @delivery = options[:delivery]
33
+ @feed_url = options[:feed_url]
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,141 @@
1
+ require 'mechanize'
2
+
3
+ module Galerts
4
+ class Manager
5
+ def initialize(email, password)
6
+ @email = email
7
+ @password = password
8
+ init_agent
9
+ login
10
+ end
11
+
12
+ def init_agent
13
+ @agent = Mechanize.new
14
+ @agent.user_agent_alias = 'Linux Mozilla'
15
+ @agent.keep_alive = true
16
+ @agent.redirect_ok = true
17
+ @agent.follow_meta_refresh = true
18
+ end
19
+
20
+ def login
21
+ response = @agent.get(LOGIN_URL) # get login page
22
+ login_form = Nokogiri::HTML(response.body, nil, 'utf-8').css('form#gaia_loginform input') # get login form
23
+ params = get_login_form_params(login_form) # fetch form parameters and edit
24
+ response = @agent.post(LOGIN_URL, params) # do login
25
+ error = response.parser.css('span[id^=errormsg]')
26
+ unless error.empty?
27
+ raise error.text.delete("\n").strip
28
+ end
29
+ end
30
+
31
+ def get_login_form_params(login_form)
32
+ params = {}
33
+ login_form.each do |input|
34
+ if input['name'] == 'Email'
35
+ params[input['name']] = @email
36
+ elsif input['name'] == 'Passwd'
37
+ params[input['name']] = @password
38
+ else
39
+ params[input['name']] = input['value']
40
+ end
41
+ end
42
+ return params
43
+ end
44
+
45
+ def alerts_page
46
+ Nokogiri::HTML(@agent.get(ALERTS_URL).body, nil, 'utf-8')
47
+ end
48
+
49
+ def alerts
50
+ result = []
51
+ contents = alerts_page.css('div#gb-main div.main-page script').text
52
+
53
+ contents = contents.gsub('null', 'nil')
54
+
55
+ contents = eval(contents.gsub("window.STATE = ", ""))
56
+
57
+ # only 'id, search_query, feed_url, data_id' variables have true value,
58
+ # other variables have default Alert class values.
59
+ contents[1][1].each do |alert|
60
+ result << Alert.new(alert[2][3][1], {
61
+ id: alert[2].last.last.last,
62
+ search_query: alert[2][3][1],
63
+ feed_url: "/alerts/feeds/#{alert.last}/#{alert[2].last.last.last}",
64
+ data_id: alert[1],
65
+ domain: 'Unknown',
66
+ frequency: 'Unknown',
67
+ sources: 'Unknown',
68
+ language: 'Unknown',
69
+ how_many: 'Unknown',
70
+ region: 'Unknown',
71
+ delivery: 'Unknown'
72
+ }
73
+ )
74
+ end
75
+ result
76
+ end
77
+
78
+ def build_create_params(search_query, options)
79
+ # check parameters
80
+ raise "Unknown alert how_many" unless HOW_MANY_TYPES.has_key?(options[:how_many])
81
+ raise "Unknown alert delivery type" unless DELIVERY_TYPES.include?(options[:delivery])
82
+ raise "Unknown alert frequency type" unless FREQ_TYPES.include?(options[:frequency])
83
+
84
+ # set delivery and frequency parameters
85
+ if options[:delivery] == EMAIL
86
+ if options[:frequency] == DAILY
87
+ delivery_and_frequency = @email + ',[null,null,11],2'
88
+ elsif options[:frequency] == WEEKLY
89
+ delivery_and_frequency = @email + ',[null,null,11,1],3'
90
+ elsif options[:frequency] == RT
91
+ delivery_and_frequency = "1,\"#{@email}\",[],1"
92
+ end
93
+ elsif options[:delivery] == RSS
94
+ delivery_and_frequency = "2,\"\",[],1"
95
+ end
96
+
97
+ # options[:sources] ? sources = options[:sources] : sources = ""
98
+
99
+ if options[:sources].nil?
100
+ sources_text = 'null'
101
+ else
102
+ sources_text = "["
103
+ options[:sources].collect do |source|
104
+ raise "Unknown alert source" unless SOURCES_TYPES.has_key?(source)
105
+ sources_text += SOURCES_TYPES[source].to_s + ','
106
+ end
107
+ sources_text = sources_text.chop + ']'
108
+ end
109
+
110
+ # TODO: need more readable
111
+ params = {
112
+ 'params' => "[null,[null,null,null,[null,\"#{search_query}\",\"#{options[:domain]}\",[null,\"#{options[:language]}\",\"#{options[:region]}\"],null,null,null,#{options[:region] == "" ? 1 : 0},1],#{sources_text},#{HOW_MANY_TYPES[options[:how_many]]},[[null,#{delivery_and_frequency},\"#{options[:language] + '-' + options[:region].upcase}\",null,null,null,null,null,'0']]]]"
113
+ }
114
+
115
+ params = URI.encode_www_form(params)
116
+ end
117
+
118
+ def create(search_query, options = {})
119
+ x = alerts_page.css('div#gb-main div.main-page script').text.split(',').last[1..-4]
120
+ response = @agent.post("#{CREATE_ALERT_URL}x=#{x}", build_create_params(search_query, options), {'Content-Type' => 'application/x-www-form-urlencoded'})
121
+
122
+ if response.body == ALERT_EXIST
123
+ raise "Alert exist!"
124
+ elsif response.body == ALERT_SOMETHING_WENT_WRONG
125
+ raise "Something went wrong!" # internal error, html changed maybe
126
+ else
127
+ response_body = response.body.gsub('null', 'nil')
128
+ created_alert = Nokogiri::HTML(eval(response_body)[4][0][2], nil, 'utf-8')
129
+
130
+ alert = Alert.new(search_query, options)
131
+
132
+ if options[:delivery] == RSS
133
+ alert.id = created_alert.css('a')[0]['href'].split('/').last if options[:delivery] == RSS
134
+ alert.feed_url = created_alert.css('a')[0]['href']
135
+ end
136
+ alert.data_id = created_alert.css('li')[0]['data-id']
137
+ alert
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,3 @@
1
+ module Galerts
2
+ VERSION = '0.0.1'.freeze unless defined?(::Galerts::VERSION)
3
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: galerts
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Emre Can Yılmaz
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-09-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mechanize
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.7'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.7'
27
+ description: Manage to Google Alerts
28
+ email:
29
+ - emrecan@ecylmz.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - Gemfile
35
+ - README.md
36
+ - Rakefile
37
+ - galerts.gemspec
38
+ - lib/galerts.rb
39
+ - lib/galerts/alert.rb
40
+ - lib/galerts/manager.rb
41
+ - lib/galerts/version.rb
42
+ homepage: https://github.com/pivotus/galerts
43
+ licenses:
44
+ - MIT
45
+ metadata: {}
46
+ post_install_message:
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubyforge_project:
62
+ rubygems_version: 2.2.2
63
+ signing_key:
64
+ specification_version: 4
65
+ summary: Ruby library to manage google alerts
66
+ test_files: []