quora_notify 0.0.7 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a2e83b718291fe349330076b9e419979994700fc
4
- data.tar.gz: ce758c4e070950ce22d476fe8528832b547eb685
3
+ metadata.gz: 18a733e9ecd69603d65c8446b7b2ed93d8f37c69
4
+ data.tar.gz: ffc967ed622f81bc98351421ee28b03bc9d39952
5
5
  SHA512:
6
- metadata.gz: b07cbb3b8a2a6a80c15cd1c0d3489b3ecf574b95cdc66a2aac699f4ecf046c912015fbe8dfe1649bba73392eb895312beb6613f7bfd2e3a161254de640e04491
7
- data.tar.gz: 9bff482d70fd30f821cfb0f0e3396bce26d09cfe8027eb630048469b93d913db9ad1afa281785b4d83bce31475d813f92c0a1d69fcc7be9b1e42fce326d38b2e
6
+ metadata.gz: 630b7abc59ea8d58b0430aadc07250c8a9344e878602be73c00fc927edfa14bcd4b8fbc157ab6503f987d57e62b3c34a9c4288b06005cf6f0d7e038172a2f058
7
+ data.tar.gz: 76a5838745afafec15c41849a1e8b4e7db59c0d121b9805060ce43c2b747f56f8c3f0b2a043734629bc4ff80bff73406a2bcec403aefe27afebe629940be7ea8
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- quora_notify (0.0.6)
4
+ quora_notify (0.0.7)
5
5
  htmlentities
6
6
  sqlite3
7
7
  terminal-notifier
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Receive quora.com notifications in Notification Center on OSX Mountain Lion.
4
4
 
5
+ Due to the hackish way this currently works (using local cookies), only certain versions of Safari, Chrome, and Firefox are supported for now.
6
+
5
7
  ## Installation
6
8
 
7
9
  Install a launchAgent to poll Quora for notifications
data/Rakefile CHANGED
@@ -2,7 +2,10 @@ require 'rake/testtask'
2
2
  require "bundler/gem_tasks"
3
3
 
4
4
  Rake::TestTask.new do |t|
5
- t.libs << 'test'
5
+ t.libs << "test"
6
+ t.pattern = "test/**/test_*.rb"
7
+ t.warning = true
8
+ t.verbose = true
6
9
  end
7
10
 
8
11
  desc "Run all tests"
data/lib/quora_notify.rb CHANGED
@@ -1,5 +1,8 @@
1
+ require 'quora_notify/version'
2
+ require 'quora_notify/exceptions'
1
3
  require 'quora_notify/base'
2
4
  require 'quora_notify/install'
5
+ require 'quora_notify/cookie'
3
6
  require 'quora_notify/cookie_readers'
4
7
  require 'quora_notify/notification'
5
8
 
@@ -3,17 +3,14 @@ require 'json'
3
3
  require 'terminal-notifier'
4
4
 
5
5
  module QuoraNotify
6
-
7
6
  API_NOTIFICATION_PATH = 'http://api.quora.com/api/logged_in_user?fields=notifs'
8
7
  TMP_COOKIE_PATH = '/tmp/quora_notifier'
9
8
 
10
9
  class << self
11
10
  def quora_notifications
12
- cookies = quora_cookies_for_browser(:default)
13
- write_cookies_to_file(cookies, TMP_COOKIE_PATH)
14
-
15
- notification_response = `curl #{API_NOTIFICATION_PATH} -b #{TMP_COOKIE_PATH}`.sub('while(1);', '')
16
- JSON.parse(notification_response)
11
+ fetch_notifications_with_cookies quora_cookies do |notifications|
12
+ JSON.parse(notifications)
13
+ end
17
14
  end
18
15
 
19
16
  def run!
@@ -27,6 +24,13 @@ module QuoraNotify
27
24
 
28
25
  private
29
26
 
27
+ def fetch_notifications_with_cookies(cookies)
28
+ write_cookies_to_file(cookies, TMP_COOKIE_PATH)
29
+ response = `curl #{API_NOTIFICATION_PATH} -b #{TMP_COOKIE_PATH}`.sub('while(1);', '')
30
+ File.delete TMP_COOKIE_PATH
31
+ yield response
32
+ end
33
+
30
34
  def process(notifications)
31
35
  return [] if notifications.empty? || notifications['notifs']['unseen_count'] == 0
32
36
 
@@ -36,17 +40,18 @@ module QuoraNotify
36
40
  end
37
41
 
38
42
  def write_cookies_to_file(cookies, file)
39
- File.open(file, 'w') do |file|
43
+ File.open(file, 'w') do |f|
40
44
  cookies.each do |cookie|
41
45
  # TODO: could be in to_s for cookie object
42
- file.puts "#{cookie.domain}\tTRUE\t#{cookie.path}\tFALSE\t#{cookie.expires}\t#{cookie.name}\t#{cookie.value}"
46
+ f.puts "#{cookie.domain}\tTRUE\t#{cookie.path}\tFALSE\t#{cookie.expires}\t#{cookie.name}\t#{cookie.value}"
43
47
  end
44
48
  end
45
49
  end
46
50
 
47
- def quora_cookies_for_browser(browser)
51
+ def quora_cookies
48
52
  readers = [
49
53
  CookieReaders::ChromeCookieReader.new,
54
+ CookieReaders::FirefoxCookieReader.new,
50
55
  CookieReaders::SafariCookieReader.new
51
56
  ]
52
57
 
@@ -54,6 +59,8 @@ module QuoraNotify
54
59
  begin
55
60
  reader.read_cookies
56
61
  rescue => e
62
+ puts e.message
63
+ puts e.backtrace
57
64
  []
58
65
  end
59
66
  end.flatten.uniq.select { |cookie| cookie.domain == '.quora.com' }
@@ -0,0 +1,15 @@
1
+ module QuoraNotify
2
+ class Cookie
3
+ attr_reader :name, :value, :domain, :path, :flag, :expires, :created
4
+
5
+ def initialize(opts = {})
6
+ @name = opts[:name]
7
+ @value = opts[:value]
8
+ @domain = opts[:domain]
9
+ @path = opts[:path]
10
+ @flag = opts[:flag]
11
+ @expires = opts[:expires]
12
+ @created = opts[:created]
13
+ end
14
+ end
15
+ end
@@ -1,5 +1,33 @@
1
+ require 'stringio'
2
+
1
3
  module QuoraNotify::CookieReaders
4
+ class CookieIO < StringIO
5
+ def next
6
+ self.read(4)
7
+ end
8
+
9
+ def next_as_int
10
+ self.next.unpack('l<')[0]
11
+ end
12
+
13
+ def read_as_flag
14
+ case self.next_as_int
15
+ when 0; ''
16
+ when 1; 'Secure'
17
+ when 4; 'HttpOnly'
18
+ when 5; 'Secure: HttpOnly'
19
+ else; 'Unknown'
20
+ end
21
+ end
22
+
23
+ def read_as_date
24
+ epoch = self.read(8).unpack('E')[0] + 978307200
25
+ Time.at(epoch).strftime('%a, %d %b %Y')
26
+ end
27
+ end
2
28
  end
3
29
 
30
+ require 'quora_notify/cookie_readers/cookie_reader'
31
+ require 'quora_notify/cookie_readers/firefox_cookie_reader'
4
32
  require 'quora_notify/cookie_readers/safari_cookie_reader'
5
33
  require 'quora_notify/cookie_readers/chrome_cookie_reader'
@@ -1,56 +1,35 @@
1
1
  require 'sqlite3'
2
- require 'quora_notify/cookie_readers/cookie'
3
2
 
4
- class ChromeCookieReaderException < StandardError; end
3
+ module QuoraNotify::CookieReaders
4
+ class ChromeCookieReader < CookieReader
5
+ DEFAULT_COOKIE_PATH = "#{ENV['HOME']}/Library/Application Support/Google/Chrome/Default/Cookies"
5
6
 
6
- class QuoraNotify::CookieReaders::ChromeCookieReader
7
+ # Returns an array of Cookie objects
8
+ # Raises: binarycookieReaderException
9
+ def read_cookies
10
+ raise QuoraNotify::Exceptions::CookieReaderException, 'No cookie file found' unless File.exists?(cookie_file_path)
7
11
 
8
- DEFAULT_CHROME_COOKIE_PATH = "#{ENV['HOME']}/Library/Application Support/Google/Chrome/Default/Cookies"
12
+ cookies = []
13
+ db = SQLite3::Database.new(cookie_file_path)
14
+ db.execute('SELECT name, value, host_key, path, secure, httponly, expires_utc, creation_utc FROM cookies') do |row|
15
+ cookies << cookie_for_row(row)
16
+ end
9
17
 
10
- # Accepts:
11
- # cookie_file_path: Use default cookie file if nil (default)
12
- def initialize(file_path = nil)
13
- @cookie_file_path = file_path
14
- end
15
-
16
- # Returns an array of Cookie objects
17
- # Raises: binarycookieReaderException
18
- def read_cookies
19
- raise ChromeCookieReaderException 'No cookie file found' unless File.exists?(cookie_file_path)
20
-
21
- cookies = []
22
- db = SQLite3::Database.new(cookie_file_path)
23
- db.execute('SELECT name, value, host_key, path, secure, httponly, expires_utc, creation_utc FROM cookies') do |row|
24
- cookies << cookie_for_row(row)
18
+ cookies
25
19
  end
26
20
 
27
- cookies
28
- end
29
-
30
- private
21
+ private
31
22
 
32
- def cookie_for_row(row)
33
- # CREATE TABLE cookies (creation_utc INTEGER NOT NULL UNIQUE PRIMARY KEY,host_key TEXT NOT NULL,name TEXT NOT NULL,value TEXT NOT NULL,path TEXT NOT NULL,expires_utc INTEGER N OT NULL,secure INTEGER NOT NULL,httponly INTEGER NOT NULL,last_access_utc INTEGER NOT NULL, has_expires INTEGER NOT NULL DEFAULT 1, persistent INTEGER NOT NULL DEFAULT 1);
34
- name = row[0]
35
- value = row[1]
36
- domain = row[2]
37
- path = row[3]
38
- flag = flag(row[4], row[5])
39
- expires = row[6]
40
- created = row[7]
23
+ def cookie_for_row(row)
24
+ name = row[0]
25
+ value = row[1]
26
+ domain = row[2]
27
+ path = row[3]
28
+ flag = flag(row[4], row[5])
29
+ expires = row[6]
30
+ created = row[7]
41
31
 
42
- QuoraNotify::CookieReaders::Cookie.new(name: name, value: value, domain: domain, path: path, flag: flag, expires: expires, created: created)
43
- end
44
-
45
- def flag(secure, httponly)
46
- return 'Secure: HttpOnly' if secure == 1 && httponly == 1
47
- return 'Secure' if secure == 1
48
- return 'HttpOnly' if httponly == 1
49
- 'Unknown'
50
- end
51
-
52
- # Defaults to the standard safari cookie system path
53
- def cookie_file_path
54
- @cookie_file_path || DEFAULT_CHROME_COOKIE_PATH
55
- end
32
+ QuoraNotify::Cookie.new(name: name, value: value, domain: domain, path: path, flag: flag, expires: expires, created: created)
33
+ end
34
+ end
56
35
  end
@@ -0,0 +1,32 @@
1
+ module QuoraNotify::CookieReaders
2
+ # Subclasses should define a DEFAULT_COOKIE_PATH constant
3
+ # that will be used if no file path is provided to the constructor
4
+ class CookieReader
5
+ DEFAULT_COOKIE_PATH = nil
6
+ # Accepts:
7
+ # cookie_file_path: Use DEFAULT_COOKIE_PATH if nil (default)
8
+ def initialize(file_path = nil)
9
+ @cookie_file_path = file_path
10
+ end
11
+
12
+ # Returns an array of Cookie objects
13
+ # Raises: binarycookieReaderException
14
+ def read_cookies
15
+ raise QuoraNotify::Exceptions::CookieReaderException, 'Not implemented'
16
+ end
17
+
18
+ # Defaults to the standard safari cookie system path
19
+ def cookie_file_path
20
+ @cookie_file_path || self.class::DEFAULT_COOKIE_PATH
21
+ end
22
+
23
+ protected
24
+
25
+ def flag(secure, httponly)
26
+ return 'Secure: HttpOnly' if secure == 1 && httponly == 1
27
+ return 'Secure' if secure == 1
28
+ return 'HttpOnly' if httponly == 1
29
+ 'Unknown'
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,36 @@
1
+ require 'sqlite3'
2
+
3
+ module QuoraNotify::CookieReaders
4
+ class FirefoxCookieReader < CookieReader
5
+ DEFAULT_COOKIE_PATH = "#{ENV['HOME']}/Library/Application Support/Firefox/Profiles/*/cookies.sqlite"
6
+
7
+ # Returns an array of Cookie objects
8
+ # Raises: binarycookieReaderException
9
+ def read_cookies
10
+ cookie_file = Dir[cookie_file_path][0]
11
+ raise QuoraNotify::Exceptions::CookieReaderException, 'No cookie file found' unless cookie_file && File.exists?(cookie_file)
12
+
13
+ cookies = []
14
+ db = SQLite3::Database.new(cookie_file)
15
+ db.execute('SELECT name, value, baseDomain, path, isSecure, isHttpOnly, expiry, creationTime FROM moz_cookies') do |row|
16
+ cookies << cookie_for_row(row)
17
+ end
18
+
19
+ cookies
20
+ end
21
+
22
+ private
23
+
24
+ def cookie_for_row(row)
25
+ name = row[0]
26
+ value = row[1]
27
+ domain = row[2]
28
+ path = row[3]
29
+ flag = flag(row[4], row[5])
30
+ expires = row[6]
31
+ created = row[7]
32
+
33
+ QuoraNotify::Cookie.new(name: name, value: value, domain: domain, path: path, flag: flag, expires: expires, created: created)
34
+ end
35
+ end
36
+ end
@@ -1,107 +1,67 @@
1
+ module QuoraNotify::CookieReaders
2
+ class SafariCookieReader < CookieReader
3
+ DEFAULT_COOKIE_PATH = "#{ENV['HOME']}/Library/Cookies/Cookies.binarycookies"
1
4
 
2
- require 'stringio'
3
- require 'quora_notify/cookie_readers/cookie'
5
+ # Returns an array of Cookie objects
6
+ # Raises: CookieReaderException
7
+ def read_cookies
8
+ raise QuoraNotify::Exceptions::CookieReaderException, 'No cookie file found' unless File.exists?(cookie_file_path)
4
9
 
5
- class SfariCookieReaderException < StandardError; end
6
-
7
- class QuoraNotify::CookieReaders::SafariCookieReader
8
-
9
- class CookieIO < StringIO
10
- def next
11
- self.read(4)
12
- end
13
-
14
- def next_as_int
15
- self.next.unpack('l<')[0]
16
- end
17
-
18
- def read_as_flag
19
- case self.next_as_int
20
- when 0; ''
21
- when 1; 'Secure'
22
- when 4; 'HttpOnly'
23
- when 5; 'Secure: HttpOnly'
24
- else; 'Unknown'
10
+ File.open(cookie_file_path, 'rb') do |cookie_file|
11
+ process_file cookie_file
25
12
  end
26
13
  end
27
14
 
28
- def read_as_date
29
- epoch = self.read(8).unpack('E')[0] + 978307200
30
- Time.at(epoch).strftime('%a, %d %b %Y')
31
- end
32
- end
33
-
34
- DEFAULT_SAFARI_COOKIE_PATH = "#{ENV['HOME']}/Library/Cookies/Cookies.binarycookies"
15
+ private
35
16
 
36
- # Accepts:
37
- # cookie_file_path: Use default cookie file if nil (default)
38
- def initialize(file_path = nil)
39
- @cookie_file_path = file_path
40
- end
17
+ def process_file(cookie_file)
18
+ header = cookie_file.read(4)
19
+ raise QuoraNotify::Exceptions::CookieReaderException, 'Not recognized as a binarycookie file' unless header == 'cook'
41
20
 
42
- # Returns an array of Cookie objects
43
- # Raises: binarycookieReaderException
44
- def read_cookies
45
- raise SafariCookieReaderException 'No cookie file found' unless File.exists?(cookie_file_path)
21
+ n_pages = cookie_file.read(4).unpack('l>')[0]
22
+ sizes = (0..n_pages - 1).collect { |page| cookie_file.read(4).unpack('l>')[0] }
23
+ pages = sizes.collect { |size| cookie_file.read(size) }
46
24
 
47
- File.open(cookie_file_path, 'rb') do |cookie_file|
48
- process_file cookie_file
49
- end
50
- end
25
+ cookie_groups = pages.collect do |page|
26
+ page = CookieIO.new(page); page.next
51
27
 
52
- def process_file(cookie_file)
53
- header = cookie_file.read(4)
54
- raise SafariCookieReaderException 'Not recognized as a binarycookie file' unless header == 'cook'
28
+ n_items = page.next_as_int
29
+ cookie_offsets = (0..n_items - 1).collect { |item| page.next_as_int }
55
30
 
56
- n_pages = cookie_file.read(4).unpack('l>')[0]
57
- sizes = (0..n_pages - 1).collect { |page| cookie_file.read(4).unpack('l>')[0] }
58
- pages = sizes.collect { |size| cookie_file.read(size) }
31
+ page.next
59
32
 
60
- cookie_groups = pages.collect do |page|
61
- page = CookieIO.new(page); page.next
33
+ cookie_offsets.collect do |offset|
34
+ page.seek(offset) # Move to the start of the next page of cookies
35
+ cookie_for_data CookieIO.new(page.read(page.next_as_int)) # Pulls each cookie out of the page
36
+ end
37
+ end
62
38
 
63
- n_items = page.next_as_int
64
- cookie_offsets = (0..n_items - 1).collect { |item| page.next_as_int }
65
-
66
- page.next
67
-
68
- cookie_offsets.collect do |offset|
69
- page.seek(offset) # Move to the start of the next page of cookies
70
- cookie_for_data CookieIO.new(page.read(page.next_as_int)) # Pulls each cookie out of the page
39
+ cookie_groups.flatten
71
40
  end
72
- end
73
41
 
74
- cookie_groups.flatten
75
- end
42
+ def cookie_for_data(cookie)
43
+ cookie.next; flag = cookie.read_as_flag; cookie.next
76
44
 
77
- def cookie_for_data(cookie)
78
- cookie.next; flag = cookie.read_as_flag; cookie.next
45
+ domain_off, name_off, path_off, value_off = 4.times.map { cookie.next_as_int }
79
46
 
80
- domain_off, name_off, path_off, value_off = 4.times.map { cookie.next_as_int }
47
+ cookie.next; cookie.next
81
48
 
82
- cookie.next; cookie.next
49
+ expires, created = 2.times.map { cookie.read_as_date }
83
50
 
84
- expires, created = 2.times.map { cookie.read_as_date }
51
+ domain, name, path, value = [domain_off, name_off, path_off, value_off].collect do |offset|
52
+ cookie.seek(offset - 4)
85
53
 
86
- domain, name, path, value = [domain_off, name_off, path_off, value_off].collect do |offset|
87
- cookie.seek(offset - 4)
54
+ data = ''
55
+ while char = cookie.read(1)
56
+ new_data = char.unpack('c')[0]
57
+ break if new_data == 0
58
+ data << new_data
59
+ end
88
60
 
89
- data = ''
90
- while char = cookie.read(1)
91
- new_data = char.unpack('c')[0]
92
- break if new_data == 0
93
- data << new_data
94
- end
61
+ data
62
+ end
95
63
 
96
- data
97
- end
98
-
99
- QuoraNotify::CookieReaders::Cookie.new(name: name, value: value, domain: domain, path: path, flag: flag, expires: expires, created: created)
100
- end
101
-
102
- # Defaults to the standard safari cookie system path
103
- def cookie_file_path
104
- @cookie_file_path || DEFAULT_SAFARI_COOKIE_PATH
64
+ QuoraNotify::Cookie.new(name: name, value: value, domain: domain, path: path, flag: flag, expires: expires, created: created)
65
+ end
105
66
  end
106
-
107
67
  end
@@ -0,0 +1,4 @@
1
+ module QuoraNotify::Exceptions
2
+ class QNError < StandardError; end
3
+ class CookieReaderException < QNError; end
4
+ end
@@ -2,7 +2,6 @@ require "fileutils"
2
2
  require 'erb'
3
3
 
4
4
  class QuoraNotify::Install
5
-
6
5
  INSTALL_PATH = File.join(ENV["HOME"], "Library", "LaunchAgents")
7
6
  LAUNCHD_PROCESS_NAME = "com.joeycarmello.quora_notify"
8
7
  LAUNCHD_FILE_NAME = "#{LAUNCHD_PROCESS_NAME}.plist"
@@ -11,9 +10,12 @@ class QuoraNotify::Install
11
10
  class << self
12
11
  def run!
13
12
  uninstall!
13
+
14
+ # Used with the ERB binding
14
15
  gem_path = ENV['GEM_HOME']
15
16
  ruby_path = File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name']).sub(/.*\s.*/m, '"\&"')
16
17
  bin_path = `which quora_notify`.chomp
18
+
17
19
  template = ERB.new File.read(erb_path)
18
20
  File.write(install_file_path, template.result(binding))
19
21
  start
@@ -1,3 +1,3 @@
1
1
  module QuoraNotify
2
- VERSION = '0.0.7'
2
+ VERSION = '0.0.9'
3
3
  end
@@ -0,0 +1,49 @@
1
+ require 'test/unit'
2
+ require 'quora_notify'
3
+ require 'mocha/setup'
4
+ require 'fileutils'
5
+
6
+ def fill_with_mocks
7
+ # create some notifications
8
+ QuoraNotify.expects(:quora_notifications).returns(mock_notifications)
9
+ # go fetch for the fake ones, creating real local notifs
10
+ QuoraNotify.run!
11
+ end
12
+
13
+ def mock_notifications
14
+ {
15
+ 'notifs' => {
16
+ 'unseen_count' => 2,
17
+ 'unseen' => [
18
+ '<a href="http://quora.com">Some text</a>',
19
+ '<a href="http://quora.com">Some text 2</a>'
20
+ ]
21
+ }
22
+ }
23
+ end
24
+
25
+ def mock_empty_notifications
26
+ {
27
+ 'notifs' => {
28
+ 'unseen_count' => 0,
29
+ 'unseen' => []
30
+ }
31
+ }
32
+ end
33
+
34
+ def make_tmp_file_for_reference
35
+ tmp_path = '/tmp/some_file_that_will_be_deleted'
36
+ FileUtils.touch(tmp_path)
37
+ yield tmp_path if block_given?
38
+ File.delete tmp_path
39
+ end
40
+
41
+ class MockSqlite3DBResults
42
+ NUMBER_OF_COOKIES = 3
43
+
44
+ def execute(query)
45
+ result = NUMBER_OF_COOKIES.times.collect { ['name', 'value', 'host', 'path', 1, 0, Time.now.to_i, Time.now.to_i] }
46
+ result.each { |row| yield row } if block_given?
47
+ result
48
+ end
49
+ end
@@ -1,6 +1,4 @@
1
- require 'test/unit'
2
- require 'mocha/setup'
3
- require 'quora_notify'
1
+ require 'test_helper'
4
2
 
5
3
  class QuoraNotifyTest < Test::Unit::TestCase
6
4
  def test_can_parse_quora_api_response
@@ -37,33 +35,4 @@ class QuoraNotifyTest < Test::Unit::TestCase
37
35
  fill_with_mocks
38
36
  end
39
37
 
40
- private
41
-
42
- def fill_with_mocks
43
- # create some notifications
44
- QuoraNotify.expects(:quora_notifications).returns(mock_notifications)
45
- # go fetch for the fake ones, creating real local notifs
46
- QuoraNotify.run!
47
- end
48
-
49
- def mock_notifications
50
- {
51
- 'notifs' => {
52
- 'unseen_count' => 2,
53
- 'unseen' => [
54
- '<a href="http://quora.com">Some text</a>',
55
- '<a href="http://quora.com">Some text 2</a>'
56
- ]
57
- }
58
- }
59
- end
60
-
61
- def mock_empty_notifications
62
- {
63
- 'notifs' => {
64
- 'unseen_count' => 0,
65
- 'unseen' => []
66
- }
67
- }
68
- end
69
38
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quora_notify
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joey Carmello
@@ -14,58 +14,58 @@ dependencies:
14
14
  name: terminal-notifier
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ~>
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '1.4'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ~>
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '1.4'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: sqlite3
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ~>
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '1.3'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ~>
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '1.3'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: htmlentities
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ~>
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '4.3'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ~>
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '4.3'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: mocha
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - ~>
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: '0.13'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - ~>
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: '0.13'
69
69
  description: |2
70
70
  QuoraNotify provides basic access to one of the few API's Quora.com has opened to the public.
71
71
  It uses local quora cookies to access this API as a logged-in user.
@@ -78,15 +78,19 @@ extensions: []
78
78
  extra_rdoc_files: []
79
79
  files:
80
80
  - lib/quora_notify/base.rb
81
+ - lib/quora_notify/cookie.rb
81
82
  - lib/quora_notify/cookie_readers/chrome_cookie_reader.rb
82
- - lib/quora_notify/cookie_readers/cookie.rb
83
+ - lib/quora_notify/cookie_readers/cookie_reader.rb
84
+ - lib/quora_notify/cookie_readers/firefox_cookie_reader.rb
83
85
  - lib/quora_notify/cookie_readers/safari_cookie_reader.rb
84
86
  - lib/quora_notify/cookie_readers.rb
87
+ - lib/quora_notify/exceptions.rb
85
88
  - lib/quora_notify/install.rb
86
89
  - lib/quora_notify/notification.rb
87
90
  - lib/quora_notify/version.rb
88
91
  - lib/quora_notify.rb
89
92
  - bin/quora_notify
93
+ - test/test_helper.rb
90
94
  - test/test_quora_notify.rb
91
95
  - Gemfile
92
96
  - Gemfile.lock
@@ -1,14 +0,0 @@
1
-
2
- class QuoraNotify::CookieReaders::Cookie
3
- attr_reader :name, :value, :domain, :path, :flag, :expires, :created
4
-
5
- def initialize(opts = {})
6
- @name = opts[:name]
7
- @value = opts[:value]
8
- @domain = opts[:domain]
9
- @path = opts[:path]
10
- @flag = opts[:flag]
11
- @expires = opts[:expires]
12
- @created = opts[:created]
13
- end
14
- end