hubdate 0.0.01
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.
- data/bin/hubdate +48 -0
- data/hubdate.gemspec +17 -0
- data/lib/.rudoo/config.yml +4 -0
- data/lib/.rudoo/list.yml +14 -0
- data/lib/hubdate.rb +36 -0
- data/lib/hubdate/base.rb +20 -0
- data/lib/hubdate/checker.rb +78 -0
- data/lib/hubdate/connection.rb +96 -0
- data/lib/hubdate/notification.rb +33 -0
- data/lib/hubdate/repository.rb +35 -0
- data/lib/hubdate/storage.rb +61 -0
- data/lib/hubdate/user.rb +70 -0
- data/lib/version.rb +3 -0
- metadata +77 -0
data/bin/hubdate
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'hubdate.rb'))
|
6
|
+
|
7
|
+
options = {}
|
8
|
+
|
9
|
+
opt_parser = OptionParser.new do |opt|
|
10
|
+
opt.banner = "Usage: rd COMMAND [OPTIONS]"
|
11
|
+
opt.separator ""
|
12
|
+
opt.separator "Commands"
|
13
|
+
opt.separator " init: initialize a new rudoo file architecture"
|
14
|
+
opt.separator ""
|
15
|
+
opt.separator "Options"
|
16
|
+
|
17
|
+
opt.on("-u", "--username USERNAME", "username of the github account you would like to monitor") do |username|
|
18
|
+
options[:username] = username
|
19
|
+
end
|
20
|
+
|
21
|
+
opt.on("-p", "--password PASSWORD", "password for the github account you would like to monitor") do |password|
|
22
|
+
options[:password] = password
|
23
|
+
end
|
24
|
+
|
25
|
+
opt.on("-t", "--time TIME", "time you would like to wait between polls (Minimum of 70s)") do |time|
|
26
|
+
options[:time] = time
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
opt_parser.parse!
|
31
|
+
|
32
|
+
username = options[:username] || nil
|
33
|
+
password = options[:password] || nil
|
34
|
+
time = options[:time] || 70
|
35
|
+
|
36
|
+
if username.nil?
|
37
|
+
puts "A username must be specified!"
|
38
|
+
elsif password.nil?
|
39
|
+
puts "A password must be specified!"
|
40
|
+
else
|
41
|
+
begin
|
42
|
+
run(username, password, time.to_i)
|
43
|
+
rescue
|
44
|
+
puts "Invalid credentials!"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
data/hubdate.gemspec
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Tommy Schaefer"]
|
6
|
+
gem.email = ["me@tommyschaefer.net"]
|
7
|
+
gem.description = %q{A ruby program that polls github for updates and sends them to notification center.}
|
8
|
+
gem.summary = %q{Hubdate is a console executed program that polls github for updates (notifications, stars, and watchers). Any new updates will be sent to notification center.}
|
9
|
+
gem.homepage = "https://github.com/tommyschaefer/hubdate"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "hubdate"
|
15
|
+
gem.version = Hubdate::VERSION
|
16
|
+
gem.add_dependency "terminal-notifier"
|
17
|
+
end
|
data/lib/.rudoo/list.yml
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
---
|
2
|
+
!binary "MDQxMDIz": !ruby/object:Rudoo::Task
|
3
|
+
todo: Upload initial commit
|
4
|
+
priority: 0
|
5
|
+
!binary "ODgxNDMw": !ruby/object:Rudoo::Task
|
6
|
+
todo: Add executable
|
7
|
+
priority: 0
|
8
|
+
!binary "MWRhMzM0": !ruby/object:Rudoo::Task
|
9
|
+
todo: Fix bug that occurs when creating files for the first time and move execution
|
10
|
+
into executable :done
|
11
|
+
priority: 0
|
12
|
+
!binary "NmJmODEx": !ruby/object:Rudoo::Task
|
13
|
+
todo: Gemify program :wkng
|
14
|
+
priority: 0
|
data/lib/hubdate.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "terminal-notifier"
|
3
|
+
|
4
|
+
require 'json'
|
5
|
+
require 'yaml'
|
6
|
+
require 'net/http'
|
7
|
+
require 'net/https'
|
8
|
+
require 'fileutils'
|
9
|
+
|
10
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "hubdate", "base"))
|
11
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "hubdate", "user"))
|
12
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "hubdate", "repository"))
|
13
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "hubdate", "notification"))
|
14
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "hubdate", "connection"))
|
15
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "hubdate", "storage"))
|
16
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "hubdate", "checker"))
|
17
|
+
|
18
|
+
def run(user, password, time)
|
19
|
+
if !Storage.dir_initialized?(File.join(Dir.home, ".hubdate"))
|
20
|
+
Storage.generate_files
|
21
|
+
else
|
22
|
+
Storage.generate_follow if !Storage.file_initialized?(File.join(Dir.home, ".hubdate", "followers.yaml"))
|
23
|
+
Storage.generate_star if !Storage.file_initialized?(File.join(Dir.home, ".hubdate", "stargazers.yaml"))
|
24
|
+
Storage.generate_watch if !Storage.file_initialized?(File.join(Dir.home, ".hubdate", "watchers.yaml"))
|
25
|
+
end
|
26
|
+
|
27
|
+
connection = Github::Connection.new({:user => user, :pass => password})
|
28
|
+
|
29
|
+
loop do
|
30
|
+
Checker.check_notifications(connection)
|
31
|
+
Checker.check_followers(connection)
|
32
|
+
Checker.check_watchers(:stargazer, connection)
|
33
|
+
Checker.check_watchers(:watcher, connection)
|
34
|
+
sleep time
|
35
|
+
end
|
36
|
+
end
|
data/lib/hubdate/base.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
class Github
|
2
|
+
module Base
|
3
|
+
attr_reader :response, :connection
|
4
|
+
|
5
|
+
# Initialize module by gathering JSON hash and connection
|
6
|
+
def initialize(responseHash, conn = Github::Connection.new)
|
7
|
+
@connection = conn
|
8
|
+
@response = responseHash
|
9
|
+
end
|
10
|
+
|
11
|
+
# If method doesnt exist, check if the id is a response key and if so return the value
|
12
|
+
def method_missing(id, *args)
|
13
|
+
unless @response && @response.keys.include?(id.id2name)
|
14
|
+
raise NoMethodError.new("Undefined method #{id.id2name} for #{self}: #{self.class}.")
|
15
|
+
end
|
16
|
+
|
17
|
+
@response[id.id2name]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
class Checker
|
2
|
+
def self.check_notifications(connection)
|
3
|
+
notifications = Github::User.fetch(connection).notifications.reverse
|
4
|
+
|
5
|
+
notifications.each do |notif|
|
6
|
+
TerminalNotifier.notify("#{notif.message}", :title => "#{notif.reason[0] = notif.reason[0].capitalize; notif.reason}: #{notif.type}")
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.check_watchers(type, connection)
|
11
|
+
watchers_file = File.join(Dir.home, ".hubdate", "stargazers.yaml") if type == :stargazer
|
12
|
+
watchers_file = File.join(Dir.home, ".hubdate", "watchers.yaml") if type == :watcher
|
13
|
+
|
14
|
+
watchers = Github::User.fetch(connection).watchers(type)
|
15
|
+
|
16
|
+
begin
|
17
|
+
file_watchers = YAML.load_file(watchers_file)
|
18
|
+
rescue
|
19
|
+
Storage.write_file(watchers, watchers_file)
|
20
|
+
end
|
21
|
+
|
22
|
+
if file_watchers != watchers
|
23
|
+
new_gazers = {}
|
24
|
+
|
25
|
+
watchers.each do |repo, gazers|
|
26
|
+
begin
|
27
|
+
added = (gazers - file_watchers[repo])
|
28
|
+
rescue
|
29
|
+
added = []
|
30
|
+
end
|
31
|
+
|
32
|
+
new_gazers[repo] = added
|
33
|
+
end
|
34
|
+
|
35
|
+
new_gazers.each do |repo, logins|
|
36
|
+
if logins != []
|
37
|
+
case type
|
38
|
+
when :stargazer
|
39
|
+
action = "Starred"
|
40
|
+
message_action = "starred"
|
41
|
+
when :watcher
|
42
|
+
action = "Now Being Watched"
|
43
|
+
message_action = "now watching"
|
44
|
+
end
|
45
|
+
TerminalNotifier.notify("", :title => "Repository #{action}!", :subtitle => "#{logins.join(", ")} #{message_action} your repository \"#{repo}\"!")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
Storage.write_file(watchers, watchers_file)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.check_followers(connection)
|
54
|
+
followers_file = File.join(Dir.home, ".hubdate", "followers.yaml")
|
55
|
+
|
56
|
+
followers = Github::User.fetch(connection).followers.map {|follower| follower.login}
|
57
|
+
|
58
|
+
begin
|
59
|
+
file_followers = YAML.load_file(followers_file)
|
60
|
+
rescue
|
61
|
+
Storage.write_file(followers, followers_file)
|
62
|
+
end
|
63
|
+
|
64
|
+
if file_followers != followers
|
65
|
+
begin
|
66
|
+
added = (followers - file_followers)
|
67
|
+
rescue
|
68
|
+
added = []
|
69
|
+
end
|
70
|
+
|
71
|
+
added.each do |login|
|
72
|
+
TerminalNotifier.notify("", :title => 'New Follower!', :subtitle => "#{login} is now following you!")
|
73
|
+
end
|
74
|
+
|
75
|
+
Storage.write_file(followers, followers_file)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
class Github
|
2
|
+
class Connection
|
3
|
+
attr_accessor :user # Allows us to call for the connections user later
|
4
|
+
attr_reader :pass, :token
|
5
|
+
|
6
|
+
# Check for argument errors and format credentials
|
7
|
+
def initialize(args={})
|
8
|
+
raise ArgumentError.new("Github::Connection does not take any arguments of type #{args.class}.") unless args.is_a?(Hash)
|
9
|
+
|
10
|
+
args.keys.each do |key|
|
11
|
+
raise ArgumentError.new("Unknown option '#{key}'.") unless [:user, :pass, :token].include? key
|
12
|
+
end
|
13
|
+
|
14
|
+
if args.keys.include?(:user) || args.keys.include?(:pass)
|
15
|
+
unless args.keys.include?(:user) && args.keys.include?(:pass)
|
16
|
+
raise ArgumentError.new("When using basic authentication, both :user and :pass are required.")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
if args.keys.include?(:token)
|
21
|
+
if args.keys.include?(:user) || args.keys.include?(:pass)
|
22
|
+
raise ArgumentError.new("Both OAuth parameters and basic authenctication parameters have been previded.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
@user = args[:user]
|
27
|
+
@pass = args[:pass]
|
28
|
+
@token = args[:token]
|
29
|
+
|
30
|
+
@server = "api.github.com"
|
31
|
+
|
32
|
+
if !@token.nil?
|
33
|
+
@creds = {:token => @token}
|
34
|
+
elsif !@user.nil?
|
35
|
+
@creds = {:user => @user, :pass => @pass}
|
36
|
+
elsif @token.nil? && @user.nil?
|
37
|
+
@creds = {}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Check is user is authenticated
|
42
|
+
def authenticated?
|
43
|
+
if (user && pass) || token
|
44
|
+
true
|
45
|
+
else
|
46
|
+
false
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Send HTTP Get request
|
51
|
+
def get(path, params = {}, creds = @creds, server = @server)
|
52
|
+
path = linkPath(path, params) if params != {}
|
53
|
+
path = linkPath(path, params, creds[:token]) if params != {} && creds.keys.include?(:token)
|
54
|
+
|
55
|
+
http = Net::HTTP.new(server, 443)
|
56
|
+
req = Net::HTTP::Get.new(path)
|
57
|
+
http.use_ssl = true
|
58
|
+
req.basic_auth creds[:user], creds[:pass] if creds.keys.include?(:user)
|
59
|
+
response = http.request(req)
|
60
|
+
return JSON.parse(response.body)
|
61
|
+
end
|
62
|
+
|
63
|
+
def post(path, params={}, creds = @creds, server = @server)
|
64
|
+
path = linkPath(path, params, creds[:token]) if params != {} && creds.keys.include?(:token)
|
65
|
+
|
66
|
+
http = Net::HTTP.new(server, 443)
|
67
|
+
req = Net::HTTP::Post.new(path)
|
68
|
+
http.use_ssl = true
|
69
|
+
req.body = params.to_json
|
70
|
+
req.basic_auth creds[:user], creds[:pass] if creds.keys.include?(:user)
|
71
|
+
response = http.request(req)
|
72
|
+
return JSON.parse(response.body)
|
73
|
+
end
|
74
|
+
|
75
|
+
def edit
|
76
|
+
end
|
77
|
+
|
78
|
+
def delete
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
# Method used to link multiple parameters with a base path
|
84
|
+
def linkPath(path, params, token = nil)
|
85
|
+
param1 = params.shift
|
86
|
+
paramString = "?#{param1[0].to_s}=#{param1[1]}"
|
87
|
+
|
88
|
+
params.each do |name, value|
|
89
|
+
paramString += "&&#{name.to_s}=#{value}"
|
90
|
+
end
|
91
|
+
|
92
|
+
paramString += "&&#{token}" unless token.nil?
|
93
|
+
paramString = path + paramString
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class Github
|
2
|
+
class Notification
|
3
|
+
include Github::Base
|
4
|
+
|
5
|
+
# Generate JSON hash and create new Github::Repository object through Github::Base
|
6
|
+
def self.fetch(conn = Github::Connection.new)
|
7
|
+
raise ArgumentError.new("You must be authenticated to retrieve this information!") if !connection.authenticated?
|
8
|
+
|
9
|
+
responseHash = conn.get("/notifications")
|
10
|
+
new(responseHash, conn)
|
11
|
+
end
|
12
|
+
|
13
|
+
def message
|
14
|
+
subject["title"]
|
15
|
+
end
|
16
|
+
|
17
|
+
def type
|
18
|
+
subject["type"]
|
19
|
+
end
|
20
|
+
|
21
|
+
# Do some argument checking and then return an array of repository objects
|
22
|
+
def self.list(params = {}, conn = Github::Connection.new)
|
23
|
+
conn = params if params.class == Github::Connection
|
24
|
+
params = {} if params.class == Github::Connection
|
25
|
+
|
26
|
+
notifications = conn.get("/notifications", params)
|
27
|
+
|
28
|
+
notifications.map do |notification|
|
29
|
+
new(notification, conn)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class Github
|
2
|
+
class Repository
|
3
|
+
include Github::Base
|
4
|
+
|
5
|
+
# Generate JSON hash and create new Github::Repository object through Github::Base
|
6
|
+
def self.fetch(user, name, conn = Github::Connection.new)
|
7
|
+
raise ArgumentError.new("Username must be provided. Call user.repo(*) for an authenticated user's repository.") if user.nil?
|
8
|
+
raise ArgumentError.new("Repository name must be provided.") if name.nil?
|
9
|
+
|
10
|
+
responseHash = conn.get("/repos/#{user}/#{name}")
|
11
|
+
new(responseHash, conn)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Do some argument checking and then return an array of repository objects
|
15
|
+
def self.list(login, account_type, params = {}, conn = Github::Connection.new)
|
16
|
+
conn = params if params.class == Github::Connection
|
17
|
+
params = {} if params.class == Github::Connection
|
18
|
+
|
19
|
+
case account_type
|
20
|
+
when "User"
|
21
|
+
baseUrl = "users"
|
22
|
+
when "Organization"
|
23
|
+
baseUrl = "orgs"
|
24
|
+
else
|
25
|
+
raise ArgumentError.new("Unknown account type: #{account_type}.")
|
26
|
+
end
|
27
|
+
|
28
|
+
repositories = conn.get("/#{baseUrl}/#{login}/repos", params)
|
29
|
+
|
30
|
+
repositories.map do |repo|
|
31
|
+
new(repo, conn)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
class Storage
|
2
|
+
def self.write_file(contents, destination)
|
3
|
+
File.open(destination, "w") do |file|
|
4
|
+
file << contents.to_yaml
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.clear_files(dir)
|
9
|
+
raise StandardError.new("Unable to delete folder.") unless FileUtils.rm_rf(dir)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.make_file(dir, file)
|
13
|
+
f = File.new(File.join(dir, file), "w+")
|
14
|
+
|
15
|
+
raise StandardError.new("Unable to make file.") unless f
|
16
|
+
|
17
|
+
f.close
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.make_folder(dir)
|
21
|
+
folder = FileUtils.mkdir(dir)
|
22
|
+
|
23
|
+
raise StandardError.new("Unable to create directory.") unless folder
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.dir_initialized?(dir)
|
27
|
+
if File.directory?(dir)
|
28
|
+
return true
|
29
|
+
else
|
30
|
+
return false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.file_initialized?(file)
|
35
|
+
if File.exists?(file)
|
36
|
+
return true
|
37
|
+
else
|
38
|
+
return false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.generate_follow
|
43
|
+
Storage.make_file(File.join(Dir.home, ".hubdate") , "followers.yaml")
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.generate_star
|
47
|
+
Storage.make_file(File.join(Dir.home, ".hubdate"), "stargazers.yaml")
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.generate_watch
|
51
|
+
Storage.make_file(File.join(Dir.home, ".hubdate"), "watchers.yaml")
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.generate_files
|
55
|
+
Storage.make_folder(File.join(Dir.home, ".hubdate"))
|
56
|
+
|
57
|
+
self.generate_follow
|
58
|
+
self.generate_star
|
59
|
+
self.generate_watch
|
60
|
+
end
|
61
|
+
end
|
data/lib/hubdate/user.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
class Github
|
2
|
+
class User
|
3
|
+
include Github::Base
|
4
|
+
|
5
|
+
# Generate JSON hash and create new Github::User object through Github::Base
|
6
|
+
def self.fetch(user = nil, conn = Github::Connection.new)
|
7
|
+
conn = user if user.class == Github::Connection
|
8
|
+
user = nil if user.class == Github::Connection
|
9
|
+
if user.nil?
|
10
|
+
raise ArgumentError.new("Authenticated request required when making calls on logged in user.") unless conn.authenticated?
|
11
|
+
responseHash = conn.get("/user")
|
12
|
+
else
|
13
|
+
responseHash = conn.get("/users/#{user}")
|
14
|
+
end
|
15
|
+
|
16
|
+
new(responseHash, conn)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Define ID because its reserved by ruby
|
20
|
+
def id
|
21
|
+
@response['id']
|
22
|
+
end
|
23
|
+
|
24
|
+
# Define type because its reserved by ruby
|
25
|
+
def type
|
26
|
+
@response['type']
|
27
|
+
end
|
28
|
+
|
29
|
+
# Return a Github::User object for each follower
|
30
|
+
def followers
|
31
|
+
result = connection.get("/users/#{login}/followers")
|
32
|
+
|
33
|
+
result.map do |follower|
|
34
|
+
self.class.new(follower, connection)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def notifications(params = {})
|
39
|
+
Github::Notification.list(params, connection)
|
40
|
+
end
|
41
|
+
|
42
|
+
def repos(params = {})
|
43
|
+
Github::Repository.list(login, type, params, connection)
|
44
|
+
end
|
45
|
+
|
46
|
+
def watchers(type)
|
47
|
+
|
48
|
+
case type
|
49
|
+
when :stargazer
|
50
|
+
type = "stargazers"
|
51
|
+
when :watcher
|
52
|
+
type = "subscribers"
|
53
|
+
else
|
54
|
+
raise StandardError.new("Watcher type must be either :stargazer or :watcher!")
|
55
|
+
end
|
56
|
+
|
57
|
+
stargazers_hash = {}
|
58
|
+
repos = self.repos.map {|repo| repo.name}
|
59
|
+
|
60
|
+
repos.each do |repo|
|
61
|
+
stargazers = connection.get("/repos/#{login}/#{repo}/#{type}")
|
62
|
+
stargazers_array = stargazers.map {|gazer| gazer["login"]}
|
63
|
+
|
64
|
+
stargazers_hash[repo.to_s] = stargazers_array
|
65
|
+
end
|
66
|
+
|
67
|
+
return stargazers_hash
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/version.rb
ADDED
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hubdate
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.01
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Tommy Schaefer
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-12-08 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: terminal-notifier
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
description: A ruby program that polls github for updates and sends them to notification
|
31
|
+
center.
|
32
|
+
email:
|
33
|
+
- me@tommyschaefer.net
|
34
|
+
executables:
|
35
|
+
- hubdate
|
36
|
+
extensions: []
|
37
|
+
extra_rdoc_files: []
|
38
|
+
files:
|
39
|
+
- bin/hubdate
|
40
|
+
- hubdate.gemspec
|
41
|
+
- lib/.rudoo/config.yml
|
42
|
+
- lib/.rudoo/list.yml
|
43
|
+
- lib/hubdate.rb
|
44
|
+
- lib/hubdate/base.rb
|
45
|
+
- lib/hubdate/checker.rb
|
46
|
+
- lib/hubdate/connection.rb
|
47
|
+
- lib/hubdate/notification.rb
|
48
|
+
- lib/hubdate/repository.rb
|
49
|
+
- lib/hubdate/storage.rb
|
50
|
+
- lib/hubdate/user.rb
|
51
|
+
- lib/version.rb
|
52
|
+
homepage: https://github.com/tommyschaefer/hubdate
|
53
|
+
licenses: []
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options: []
|
56
|
+
require_paths:
|
57
|
+
- lib
|
58
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
60
|
+
requirements:
|
61
|
+
- - ! '>='
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
requirements: []
|
71
|
+
rubyforge_project:
|
72
|
+
rubygems_version: 1.8.24
|
73
|
+
signing_key:
|
74
|
+
specification_version: 3
|
75
|
+
summary: Hubdate is a console executed program that polls github for updates (notifications,
|
76
|
+
stars, and watchers). Any new updates will be sent to notification center.
|
77
|
+
test_files: []
|