code_review_notifier 0.1.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Brewfile +2 -2
- data/Gemfile +1 -1
- data/bin/code_review_notifier +1 -1
- data/lib/base_api.rb +5 -1
- data/lib/cipher.rb +3 -5
- data/lib/code_review_notifier.rb +17 -5
- data/lib/gerrit_api.rb +12 -3
- data/lib/models/code_change.rb +1 -1
- data/lib/notifier.rb +20 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c3615d3a36962ada56ab1f0e0cc212e73915ec1a656d563a7754490c8697c0f7
|
4
|
+
data.tar.gz: 5e9b86d5c6ebaa58b3b315b43b212eae412d5ac71d8cad9c27d212b66347af31
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b9430f29ab8cda0f0096d6b8d67b5c8b7620cec2cae1574b7eccbdf9094d2bee134712f0b718b7b53cbb5167aa2d4adfee57fae06ae1da94c230963a6440f063
|
7
|
+
data.tar.gz: ceeb73098c2c8a322f30949f7f5af234dc2b153ef1dc48126693d5c1614420f54ec900aa7804e1b3c25ea13cc4d3fb9970be2e38d6c57e5fd095aaa12fcb5625
|
data/Brewfile
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
brew
|
2
|
-
brew
|
1
|
+
brew "sqlite"
|
2
|
+
brew "terminal-notifier"
|
data/Gemfile
CHANGED
data/bin/code_review_notifier
CHANGED
data/lib/base_api.rb
CHANGED
@@ -10,6 +10,10 @@ end
|
|
10
10
|
class BaseApi
|
11
11
|
include HTTParty
|
12
12
|
|
13
|
+
def self.token
|
14
|
+
@token ||= DB.get_setting("api_token") || self.authenticate
|
15
|
+
end
|
16
|
+
|
13
17
|
def self.authenticate
|
14
18
|
raise NotImplementedError
|
15
19
|
end
|
@@ -44,7 +48,7 @@ class BaseApi
|
|
44
48
|
@base_api_url ||= begin
|
45
49
|
url = DB.get_setting("base_api_url")
|
46
50
|
base_uri(url)
|
47
|
-
url
|
51
|
+
url&.chomp("/")
|
48
52
|
end
|
49
53
|
end
|
50
54
|
|
data/lib/cipher.rb
CHANGED
@@ -2,8 +2,6 @@ require "base64"
|
|
2
2
|
require "openssl"
|
3
3
|
require "digest/sha1"
|
4
4
|
|
5
|
-
KEY = ""
|
6
|
-
|
7
5
|
class Cipher
|
8
6
|
def self.encrypt(text)
|
9
7
|
cipher = OpenSSL::Cipher.new("aes-256-cbc")
|
@@ -14,17 +12,17 @@ class Cipher
|
|
14
12
|
cipher.iv = iv
|
15
13
|
encrypted = cipher.update(text)
|
16
14
|
encrypted << cipher.final
|
17
|
-
["#{key}:#{Base64.encode64(iv).encode(
|
15
|
+
["#{key}:#{Base64.encode64(iv).encode("utf-8")}", Base64.encode64(encrypted).encode("utf-8")]
|
18
16
|
end
|
19
17
|
|
20
18
|
def self.decrypt(encrypted, salt)
|
21
19
|
key, iv = salt.split(":")
|
22
|
-
iv = Base64.decode64(iv.encode(
|
20
|
+
iv = Base64.decode64(iv.encode("ascii-8bit"))
|
23
21
|
cipher = OpenSSL::Cipher.new("aes-256-cbc")
|
24
22
|
cipher.decrypt
|
25
23
|
cipher.key = key
|
26
24
|
cipher.iv = iv
|
27
|
-
decrypted = cipher.update(Base64.decode64(encrypted.encode(
|
25
|
+
decrypted = cipher.update(Base64.decode64(encrypted.encode("ascii-8bit")))
|
28
26
|
decrypted << cipher.final
|
29
27
|
decrypted
|
30
28
|
end
|
data/lib/code_review_notifier.rb
CHANGED
@@ -2,7 +2,7 @@ require "io/console"
|
|
2
2
|
require_relative "./api.rb"
|
3
3
|
require_relative "./notifier.rb"
|
4
4
|
|
5
|
-
SECONDS_BETWEEN_RUNS =
|
5
|
+
SECONDS_BETWEEN_RUNS = 90
|
6
6
|
SECONDS_BETWEEN_NOTIFICATIONS = 5
|
7
7
|
|
8
8
|
class CodeReviewNotifier
|
@@ -10,7 +10,7 @@ class CodeReviewNotifier
|
|
10
10
|
system("mkdir -p ~/.code_review_notifier")
|
11
11
|
system("brew bundle --file #{File.expand_path(File.dirname(__FILE__) + "/..")}/Brewfile")
|
12
12
|
|
13
|
-
if args[0] == "--setup"
|
13
|
+
if args[0] == "--setup"
|
14
14
|
print("What's the base URL? (i.e. https://gerrit.google.com) ")
|
15
15
|
DB.save_setting("base_api_url", STDIN.gets.chomp, is_secret: false)
|
16
16
|
|
@@ -25,6 +25,18 @@ class CodeReviewNotifier
|
|
25
25
|
DB.save_setting("account_id", STDIN.gets.chomp, is_secret: false)
|
26
26
|
|
27
27
|
puts("All setup!")
|
28
|
+
puts
|
29
|
+
puts("It's recommended that you set this up as a system service with serviceman. Check it out here: https://git.rootprojects.org/root/serviceman")
|
30
|
+
puts("Set code_review_notifier to run on startup with `serviceman add --name code_review_notifier code_review_notifier`")
|
31
|
+
exit
|
32
|
+
end
|
33
|
+
|
34
|
+
if !Api.current_api.is_setup?
|
35
|
+
Notifier.notify("Missing Setup Info", "Run `code_review_notifier --setup` to setup.")
|
36
|
+
puts
|
37
|
+
puts("You must finish setup first by running with the `--setup` option.")
|
38
|
+
puts("`code_review_notifier --setup`")
|
39
|
+
exit
|
28
40
|
end
|
29
41
|
end
|
30
42
|
|
@@ -48,11 +60,11 @@ class CodeReviewNotifier
|
|
48
60
|
code_change_activity.notified
|
49
61
|
unless is_first_run
|
50
62
|
puts("Notifying of change!")
|
51
|
-
Notifier.
|
52
|
-
sleep
|
63
|
+
Notifier.notify_about_code_change(code_change_activity)
|
64
|
+
sleep(SECONDS_BETWEEN_NOTIFICATIONS)
|
53
65
|
end
|
54
66
|
end
|
55
|
-
sleep
|
67
|
+
sleep(SECONDS_BETWEEN_RUNS)
|
56
68
|
end
|
57
69
|
end
|
58
70
|
|
data/lib/gerrit_api.rb
CHANGED
@@ -4,6 +4,7 @@ require_relative "./models/code_change_activity.rb"
|
|
4
4
|
|
5
5
|
class GerritApi < BaseApi
|
6
6
|
def self.authenticate
|
7
|
+
@token = nil
|
7
8
|
res = post("/login/", {
|
8
9
|
body: "username=#{username}&password=#{URI.escape(password)}&rememberme=1",
|
9
10
|
headers: {
|
@@ -11,15 +12,23 @@ class GerritApi < BaseApi
|
|
11
12
|
},
|
12
13
|
follow_redirects: false
|
13
14
|
})
|
14
|
-
|
15
|
-
|
15
|
+
set_cookie_header = res.headers["set-cookie"] || ""
|
16
|
+
token = set_cookie_header.match("GerritAccount=(.*?);")&.to_a&.fetch(1)
|
17
|
+
if token.nil?
|
18
|
+
Notifier.notify("Incorrect Credentials", "Trying running `code_review_notifier --setup` again.")
|
19
|
+
sleep(120)
|
20
|
+
exit
|
21
|
+
else
|
22
|
+
DB.save_setting("api_token", token, is_secret: true)
|
23
|
+
token
|
24
|
+
end
|
16
25
|
end
|
17
26
|
|
18
27
|
def self.all_code_changes
|
19
28
|
wrap_with_authentication do
|
20
29
|
get("/changes/?S=0&q=is%3Aopen%20owner%3Aself%20-is%3Awip%20-is%3Aignored%20limit%3A25&q=is%3Aopen%20owner%3Aself%20is%3Awip%20limit%3A25&q=is%3Aopen%20-owner%3Aself%20-is%3Awip%20-is%3Aignored%20reviewer%3Aself%20limit%3A25&q=is%3Aclosed%20-is%3Aignored%20%28-is%3Awip%20OR%20owner%3Aself%29%20%28owner%3Aself%20OR%20reviewer%3Aself%29%20-age%3A4w%20limit%3A10&o=DETAILED_ACCOUNTS&o=MESSAGES", {
|
21
30
|
headers: {
|
22
|
-
"Cookie" => "GerritAccount=#{
|
31
|
+
"Cookie" => "GerritAccount=#{token};"
|
23
32
|
}
|
24
33
|
})
|
25
34
|
end.parsed_response.flat_map { |js| js.map { |j| code_change_from_json(j) } }
|
data/lib/models/code_change.rb
CHANGED
data/lib/notifier.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "./api.rb"
|
2
2
|
|
3
3
|
class Notifier
|
4
|
-
def self.
|
4
|
+
def self.notify_about_code_change(code_change_activity)
|
5
5
|
code_change = code_change_activity.code_change
|
6
6
|
id = code_change.id
|
7
7
|
owner = code_change.owner
|
@@ -9,6 +9,23 @@ class Notifier
|
|
9
9
|
|
10
10
|
message = code_change_activity.message
|
11
11
|
author = code_change_activity.author
|
12
|
-
|
12
|
+
notify(author, message, "#{owner}: #{subject}", Api.current_api.favicon, Api.current_api.code_change_url(code_change))
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.notify(title, message, subtitle = nil, icon = nil, url = nil)
|
16
|
+
args = {
|
17
|
+
"title" => title,
|
18
|
+
"message" => message,
|
19
|
+
"subtitle" => subtitle,
|
20
|
+
"appIcon" => icon,
|
21
|
+
"open" => url
|
22
|
+
}
|
23
|
+
all_args = args.keys.reduce("") do |arg_string, key|
|
24
|
+
if args[key]
|
25
|
+
arg_string += " -#{key} '#{args[key]}'"
|
26
|
+
end
|
27
|
+
arg_string
|
28
|
+
end
|
29
|
+
system("/usr/local/bin/terminal-notifier #{all_args}")
|
13
30
|
end
|
14
31
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: code_review_notifier
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kyle Grinstead
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-07-
|
11
|
+
date: 2020-07-08 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email: kyleag@hey.com
|