galerts 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []