githubwatcher 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.md +84 -0
- data/Rakefile +2 -0
- data/bin/githubwatcher +33 -0
- data/githubwatcher.gemspec +24 -0
- data/images/icon.png +0 -0
- data/lib/githubwatcher.rb +100 -0
- data/lib/githubwatcher/version.rb +3 -0
- metadata +126 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
## Github Watcher
|
2
|
+
|
3
|
+
Github watcher is a simple and useful gem that help you to constantly monitor your repositories to get updates when:
|
4
|
+
|
5
|
+
* Number of watchers change
|
6
|
+
* Number of forks change
|
7
|
+
* Number of issues change
|
8
|
+
* Repo was updated
|
9
|
+
|
10
|
+
It uses [foreverb](https://github.com/DAddYE/foreverb) to demonize the process.
|
11
|
+
|
12
|
+
A [demonstration video is here](http://www.daddye.it/post/7275490125/github-growl)
|
13
|
+
|
14
|
+
## Prerequisites
|
15
|
+
|
16
|
+
You need to have **growlnotify** installed. To do that you can install it through official [site](http://growl.info) or
|
17
|
+
if you have the awesome [brew](https://github.com/mxcl/homebrew) simply with:
|
18
|
+
|
19
|
+
``` sh
|
20
|
+
$ brew install growlnotify
|
21
|
+
```
|
22
|
+
|
23
|
+
## Installation
|
24
|
+
|
25
|
+
``` sh
|
26
|
+
$ sudo gem install githubwatcher
|
27
|
+
$ githubwatcher start
|
28
|
+
$ githubwatcher stop
|
29
|
+
```
|
30
|
+
|
31
|
+
## Configuration
|
32
|
+
|
33
|
+
You need to tell to our program which repositories you want to watch, to do that simply edit ```~/.githubwatcher/repos.yaml```
|
34
|
+
with your favorite editor.
|
35
|
+
|
36
|
+
Should look like this (if you have ran ```githubwatcher start```)
|
37
|
+
|
38
|
+
``` yaml
|
39
|
+
---
|
40
|
+
- daddye/all
|
41
|
+
- padrino/all
|
42
|
+
```
|
43
|
+
|
44
|
+
So if for example you want to watch [sinatra](https://github.com/sinatra/sinatra) add it, the result should look like:
|
45
|
+
|
46
|
+
``` yaml
|
47
|
+
---
|
48
|
+
- daddye/all
|
49
|
+
- padrino/all
|
50
|
+
- sinatra/sinatra
|
51
|
+
```
|
52
|
+
|
53
|
+
If you want to watch **all** repositories of a given user you simply provide **/all** so will look like:
|
54
|
+
|
55
|
+
``` yaml
|
56
|
+
---
|
57
|
+
- daddye/all
|
58
|
+
- padrino/all
|
59
|
+
- sinatra/all
|
60
|
+
```
|
61
|
+
|
62
|
+
Restart the deamon
|
63
|
+
|
64
|
+
``` sh
|
65
|
+
$ githubwatcher start
|
66
|
+
```
|
67
|
+
|
68
|
+
## Working with Ruby Forever
|
69
|
+
|
70
|
+
``` sh
|
71
|
+
$ foreverb list
|
72
|
+
PID RSS CPU CMD
|
73
|
+
12494 27132 0.2 Forever: /usr/bin/githubwatcher
|
74
|
+
|
75
|
+
$ foreverb stop github
|
76
|
+
Do you want really stop Forever: /usr/bin/githubwatcher with pid 12494? y
|
77
|
+
Killing process Forever: /usr/bin/githubwatcher with pid 12494...
|
78
|
+
```
|
79
|
+
|
80
|
+
Your are done!
|
81
|
+
|
82
|
+
## Author
|
83
|
+
|
84
|
+
DAddYE, you can follow me on twitter [@daddye](http://twitter.com/daddye)
|
data/Rakefile
ADDED
data/bin/githubwatcher
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
require 'rubygems' unless defined?(Gem)
|
3
|
+
require 'forever'
|
4
|
+
require 'mail'
|
5
|
+
|
6
|
+
Forever.run do
|
7
|
+
##
|
8
|
+
# You can set these values
|
9
|
+
#
|
10
|
+
# dir "foo" # Default: File.expand_path('../../', __FILE__)
|
11
|
+
# file "bar" # Default: __FILE__
|
12
|
+
# log "bar.log" # Default: File.expand_path(dir, '/log/[file_name].log')
|
13
|
+
# pid "bar.pid" # Default: File.expand_path(dir, '/tmp/[file_name].pid')
|
14
|
+
#
|
15
|
+
|
16
|
+
dir File.expand_path('~/.githubwatcher')
|
17
|
+
|
18
|
+
on_error do |e|
|
19
|
+
Mail.deliver do
|
20
|
+
delivery_method :sendmail, :location => `which sendmail`.chomp
|
21
|
+
to "d.dagostino@lipsiasoft.com"
|
22
|
+
from "exceptions@lipsiasoft.com"
|
23
|
+
subject "[GitHub Watcher] #{e.message}"
|
24
|
+
body "%s\n %s" % [e.message, e.backtrace.join("\n ")]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
on_ready do
|
29
|
+
require 'bundler/setup'
|
30
|
+
require 'githubwatcher'
|
31
|
+
Githubwatcher.start!
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "githubwatcher/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "githubwatcher"
|
7
|
+
s.version = Githubwatcher::VERSION
|
8
|
+
s.authors = ["Davide D'Agostino"]
|
9
|
+
s.email = ["d.dagostino@lipsiasoft.com"]
|
10
|
+
s.homepage = "https://github.com/DAddYE/githubwatcher"
|
11
|
+
s.summary = "Github Growl Watcher, watch any project and receive growl notification"
|
12
|
+
s.description = "Github Growl Watcher, watch any project and receive growl notification for updates, new watchers, forks and issues"
|
13
|
+
|
14
|
+
s.rubyforge_project = "githubwatcher"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
s.add_dependency 'httparty', '~>0.7.8'
|
21
|
+
s.add_dependency 'growl', '~>1.0.3'
|
22
|
+
s.add_dependency 'foreverb', '~>0.1.6'
|
23
|
+
s.add_dependency 'mail', '~>2.3.0'
|
24
|
+
end
|
data/images/icon.png
ADDED
Binary file
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require "githubwatcher/version"
|
2
|
+
require "httparty"
|
3
|
+
require "growl"
|
4
|
+
|
5
|
+
module Githubwatcher
|
6
|
+
extend self
|
7
|
+
include HTTParty
|
8
|
+
|
9
|
+
WATCH = File.expand_path("~/.githubwatcher/repos.yaml")
|
10
|
+
DB = File.expand_path("~/.githubwatcher/db.yaml", __FILE__)
|
11
|
+
|
12
|
+
base_uri 'https://api.github.com'
|
13
|
+
format :json
|
14
|
+
|
15
|
+
def start!
|
16
|
+
raise "You need to install growlnotify, use brew install growlnotify or install it from growl.info site" unless Growl.installed?
|
17
|
+
log "Starting GitHub Watcher..."
|
18
|
+
|
19
|
+
unless File.exist?(WATCH)
|
20
|
+
warn "Add the repositories you're willing to monitor editing: ~/.githubwatcher/repos.yaml"
|
21
|
+
Dir.mkdir(File.dirname(WATCH)) unless File.exist?(File.dirname(WATCH))
|
22
|
+
File.open(WATCH, "w") { |f| f.write ["daddye/all", "padrino/all"].to_yaml }
|
23
|
+
end
|
24
|
+
|
25
|
+
@_watch = YAML.load_file(WATCH)
|
26
|
+
|
27
|
+
notify("GitHub Watcher", "is now listening...")
|
28
|
+
@_repos = YAML.load_file(DB) if File.exist?(DB)
|
29
|
+
while !@_stop do
|
30
|
+
repos_was = repos.dup
|
31
|
+
watch.each do |value|
|
32
|
+
key, value = *value.split("/")
|
33
|
+
r = get "/users/%s/repos" % key
|
34
|
+
r.each do |repo|
|
35
|
+
next unless value.include?(repo["name"]) || value.include?("all")
|
36
|
+
log "Quering #{repo["git_url"]}..."
|
37
|
+
|
38
|
+
found = repos_was.find { |r| r["name"] == repo["name"] }
|
39
|
+
|
40
|
+
if !found
|
41
|
+
notify(repo["name"], "Was created")
|
42
|
+
repos_was << repo
|
43
|
+
repos << repo
|
44
|
+
end
|
45
|
+
|
46
|
+
repo_was = repos_was.find { |r| r["name"] == repo["name"] }
|
47
|
+
|
48
|
+
if repo_was["watchers"] != repo["watchers"]
|
49
|
+
notify(repo["name"], "Has new #{repo["watchers"]-repo_was["watchers"]} watchers")
|
50
|
+
repo_was["watchers"] = repo["watchers"]
|
51
|
+
end
|
52
|
+
|
53
|
+
if repo_was["open_issues"] != repo["open_issues"]
|
54
|
+
notify(repo["name"], "Has new #{repo["open_issues"]-repo_was["open_issues"]} open issues")
|
55
|
+
repo_was["open_issues"] = repo["open_issues"]
|
56
|
+
end
|
57
|
+
|
58
|
+
if repo_was["pushed_at"] != repo["pushed_at"]
|
59
|
+
notify(repo["name"], "Was updated!")
|
60
|
+
repo_was["pushed_at"] = repo["pushed_at"]
|
61
|
+
end
|
62
|
+
|
63
|
+
if repo_was["forks"] != repo["forks"]
|
64
|
+
notify(repo["name"], "Has new #{repo["forks"]-repo_was["forks"]} forks")
|
65
|
+
repo_was["forks"] = repo["forks"]
|
66
|
+
end
|
67
|
+
|
68
|
+
found = repo if found
|
69
|
+
end
|
70
|
+
end
|
71
|
+
Dir.mkdir(File.dirname(DB)) unless File.exist?(File.dirname(DB))
|
72
|
+
File.open(DB, "w"){ |f| f.write @_repos.to_yaml }
|
73
|
+
sleep 5
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def repos
|
78
|
+
@_repos ||= []
|
79
|
+
end
|
80
|
+
|
81
|
+
def watch
|
82
|
+
@_watch ||= []
|
83
|
+
end
|
84
|
+
|
85
|
+
def stop!
|
86
|
+
puts "\n<= Exiting ..."
|
87
|
+
@_stop = true
|
88
|
+
end
|
89
|
+
|
90
|
+
def log(text="")
|
91
|
+
text = "[%s] %s" % [Time.now.strftime("%d/%m %H:%M"), text.to_s]
|
92
|
+
text += "\n" unless text[-1] == ?\n
|
93
|
+
print text; $stdout.flush
|
94
|
+
end
|
95
|
+
|
96
|
+
def notify(title, text)
|
97
|
+
Growl.notify text, :title => title, :icon => File.expand_path("../../images/icon.png", __FILE__); sleep 0.2
|
98
|
+
log "=> #{title}: #{text}"
|
99
|
+
end
|
100
|
+
end
|
metadata
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: githubwatcher
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Davide D'Agostino
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-07-08 00:00:00 +02:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: httparty
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
- 7
|
30
|
+
- 8
|
31
|
+
version: 0.7.8
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: growl
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 1
|
43
|
+
- 0
|
44
|
+
- 3
|
45
|
+
version: 1.0.3
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: foreverb
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
segments:
|
56
|
+
- 0
|
57
|
+
- 1
|
58
|
+
- 6
|
59
|
+
version: 0.1.6
|
60
|
+
type: :runtime
|
61
|
+
version_requirements: *id003
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: mail
|
64
|
+
prerelease: false
|
65
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
segments:
|
70
|
+
- 2
|
71
|
+
- 3
|
72
|
+
- 0
|
73
|
+
version: 2.3.0
|
74
|
+
type: :runtime
|
75
|
+
version_requirements: *id004
|
76
|
+
description: Github Growl Watcher, watch any project and receive growl notification for updates, new watchers, forks and issues
|
77
|
+
email:
|
78
|
+
- d.dagostino@lipsiasoft.com
|
79
|
+
executables:
|
80
|
+
- githubwatcher
|
81
|
+
extensions: []
|
82
|
+
|
83
|
+
extra_rdoc_files: []
|
84
|
+
|
85
|
+
files:
|
86
|
+
- .gitignore
|
87
|
+
- Gemfile
|
88
|
+
- README.md
|
89
|
+
- Rakefile
|
90
|
+
- bin/githubwatcher
|
91
|
+
- githubwatcher.gemspec
|
92
|
+
- images/icon.png
|
93
|
+
- lib/githubwatcher.rb
|
94
|
+
- lib/githubwatcher/version.rb
|
95
|
+
has_rdoc: true
|
96
|
+
homepage: https://github.com/DAddYE/githubwatcher
|
97
|
+
licenses: []
|
98
|
+
|
99
|
+
post_install_message:
|
100
|
+
rdoc_options: []
|
101
|
+
|
102
|
+
require_paths:
|
103
|
+
- lib
|
104
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
segments:
|
109
|
+
- 0
|
110
|
+
version: "0"
|
111
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
segments:
|
116
|
+
- 0
|
117
|
+
version: "0"
|
118
|
+
requirements: []
|
119
|
+
|
120
|
+
rubyforge_project: githubwatcher
|
121
|
+
rubygems_version: 1.3.6
|
122
|
+
signing_key:
|
123
|
+
specification_version: 3
|
124
|
+
summary: Github Growl Watcher, watch any project and receive growl notification
|
125
|
+
test_files: []
|
126
|
+
|