argosnap 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/Gemfile +14 -2
- data/Guardfile +25 -0
- data/README.md +5 -5
- data/argosnap.gemspec +2 -2
- data/bin/argosnap +43 -18
- data/files/local.sh +10 -2
- data/files/mail.body.haml +24 -0
- data/lib/argosnap.rb +4 -2
- data/lib/argosnap/balance.rb +36 -27
- data/lib/argosnap/config.rb +40 -0
- data/lib/argosnap/helpers.rb +41 -0
- data/lib/argosnap/install.rb +83 -13
- data/lib/argosnap/notifications.rb +78 -0
- data/lib/argosnap/notifications/mailer.rb +101 -0
- data/lib/argosnap/notifications/osxnotifications.rb +5 -0
- data/lib/argosnap/notifications/pushover.rb +32 -0
- data/lib/argosnap/version.rb +1 -1
- metadata +16 -7
- data/lib/argosnap/osxnotify.rb +0 -58
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a7a15c8ff5820ce085fbe1a69147fe44e2516f31
|
4
|
+
data.tar.gz: b24ede47dff5a3e52e9db0bf3be9799f25728920
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9e3c652266467c06d5234fc673e16aa433ae80b175d80b1ce19e7522a9ffaef84820ac22a48ecbd67ad1e1a6e6ac34999a6918be850c3bb8a589d9fe3832ee02
|
7
|
+
data.tar.gz: 2946547f4570be8b426b71ddb2dd4c6233bf47aa08bdedccc4f8acc0f2561c2bb44539806d5ae46b4d959869e24a5b7fbb457630c5eb2af40a39a3769a78465f
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
@@ -1,7 +1,19 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
gem 'mechanize', '2.7.3'
|
3
|
-
gem '
|
4
|
-
gem '
|
3
|
+
gem 'haml', '4.0.7'
|
4
|
+
gem 'mail', '2.6.3'
|
5
|
+
|
6
|
+
# osx related
|
7
|
+
gem 'terminal-notifier'
|
8
|
+
gem 'plist'
|
9
|
+
|
10
|
+
group :development do
|
11
|
+
gem 'minitest'
|
12
|
+
gem 'minitest-reporters'
|
13
|
+
gem 'guard' # NOTE: this is necessary in newer versions
|
14
|
+
gem 'guard-minitest'
|
15
|
+
gem 'ruby_gntp'
|
16
|
+
end
|
5
17
|
|
6
18
|
# Specify your gem's dependencies in argosnap.gemspec
|
7
19
|
gemspec
|
data/Guardfile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
## Uncomment and set this to only include directories you want to watch
|
5
|
+
directories %w(bin lib files test) \
|
6
|
+
.select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
|
7
|
+
|
8
|
+
## Note: if you are using the `directories` clause above and you are not
|
9
|
+
## watching the project directory ('.'), then you will want to move
|
10
|
+
## the Guardfile to a watched dir and symlink it back, e.g.
|
11
|
+
#
|
12
|
+
# $ mkdir config
|
13
|
+
# $ mv Guardfile config/
|
14
|
+
# $ ln -s config/Guardfile .
|
15
|
+
#
|
16
|
+
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"
|
17
|
+
|
18
|
+
notification :gntp, host: '127.0.0.1', password: ENV['GNTP_PASSWORD']
|
19
|
+
|
20
|
+
guard :minitest do
|
21
|
+
# with Minitest::Unit
|
22
|
+
watch(%r{^test/(.*)\/?test_(.*)\.rb$})
|
23
|
+
watch(%r{^lib/(.*/)?([^/]+)\.rb$}) { |m| "test/#{m[1]}test_#{m[2]}.rb" }
|
24
|
+
watch(%r{^test/test_helper\.rb$}) { 'test' }
|
25
|
+
end
|
data/README.md
CHANGED
@@ -2,13 +2,13 @@
|
|
2
2
|
|
3
3
|
This gem allows you to displays your current amount of picodollars along with [OSX notifications](http://support.apple.com/kb/ht5362) when your [tarsnap account](http://www.tarsnap.com/) falls bellow a predefined threshold of [picodollars](http://www.tarsnap.com/picoUSD-why.html).
|
4
4
|
|
5
|
-
|
5
|
+
# Installation
|
6
6
|
|
7
7
|
Install the gem via rubygems:
|
8
8
|
|
9
9
|
$ gem install argosnap plist mechanize terminal-notifier
|
10
10
|
|
11
|
-
|
11
|
+
# Configure
|
12
12
|
|
13
13
|
Run the following command for the script to create a configuration file like:
|
14
14
|
|
@@ -27,7 +27,7 @@ Just put your tarsnap login credentials. You can omit the other two variables if
|
|
27
27
|
$ argosnap -p
|
28
28
|
|
29
29
|
|
30
|
-
|
30
|
+
# Configure Launchd under MacOSX
|
31
31
|
|
32
32
|
In the `config.yml` adjust the `threshold` and `seconds` options as you see fit. Threshold is the amount of *picodollars* bellow which you'd like to start seeing notifications and the `seconds` consists of the time window. Then type:
|
33
33
|
|
@@ -35,7 +35,7 @@ In the `config.yml` adjust the `threshold` and `seconds` options as you see fit.
|
|
35
35
|
|
36
36
|
Now just start the installed `.plist` file following instruction you'll see on the screen and you're done.
|
37
37
|
|
38
|
-
|
38
|
+
# Options
|
39
39
|
|
40
40
|
To run an osx notification use the command:
|
41
41
|
|
@@ -49,7 +49,7 @@ To get the amount of picodollars as an integer type:
|
|
49
49
|
|
50
50
|
That's all :-)
|
51
51
|
|
52
|
-
|
52
|
+
# Contributing
|
53
53
|
|
54
54
|
1. Fork it ( http://github.com/atmosx/argosnap/fork )
|
55
55
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
data/argosnap.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = Argosnap::VERSION
|
9
9
|
spec.authors = ["Panagiotis Atmatzidis"]
|
10
10
|
spec.email = ["atma@convalesco.org"]
|
11
|
-
spec.summary = %q{
|
12
|
-
spec.description = %q{A ruby script displays
|
11
|
+
spec.summary = %q{Read your tarsnap picoUSD amount in cli and display notifications when it runs out!.}
|
12
|
+
spec.description = %q{A ruby script that displays tarsnap current ballance in picoUSD. The script can send notifications when the acount balance falls below the predefined threshold. Argosnap supports email, pushover and OSX notifications.}
|
13
13
|
spec.homepage = "https://github.com/atmosx/argosnap"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
data/bin/argosnap
CHANGED
@@ -7,25 +7,37 @@ options = {}
|
|
7
7
|
opt_parser = OptionParser.new do |opt|
|
8
8
|
opt.banner = "argosnap #{Argosnap::VERSION} ( https://github.com/atmosx/argosnap/ )\nUsage: argosnap [OPTIONS]"
|
9
9
|
opt.separator ""
|
10
|
-
opt.separator " -v:
|
11
|
-
opt.separator " -i config:
|
12
|
-
opt.separator " -i cron:
|
13
|
-
opt.separator " -
|
14
|
-
opt.separator " -p
|
15
|
-
opt.separator " -p clean:
|
10
|
+
opt.separator " -v: dislay version"
|
11
|
+
opt.separator " -i config: install configuration files"
|
12
|
+
opt.separator " -i cron: display sample cron entry"
|
13
|
+
opt.separator " -i plist: install plist file for OSX"
|
14
|
+
opt.separator " -p: prints the current amount in picoUSD"
|
15
|
+
opt.separator " -p clean: prints only the picollars (float rounded in 4 decimals), to use in cli"
|
16
|
+
opt.separator " -n mail: send notification via email"
|
17
|
+
opt.separator " -n pushover: send notification via pushover"
|
18
|
+
opt.separator " -n osx: display osx notification"
|
19
|
+
opt.separator " -n all: send notifications everywhere"
|
16
20
|
opt.separator ""
|
17
21
|
|
18
22
|
opt.on("-v","--version","display version") do |version|
|
19
23
|
options[:version] = version
|
20
24
|
end
|
21
25
|
|
26
|
+
opt.on("-c","--cron","run notifications - to use with cron") do |version|
|
27
|
+
options[:cron] = cron
|
28
|
+
end
|
29
|
+
|
22
30
|
opt.on("-i","--install [OPTION]", "install configuration files") do |install|
|
23
31
|
options[:install] = install || 'config'
|
24
32
|
end
|
25
33
|
|
26
|
-
opt.on("-p","--print [OPTION]","fetch current amount in
|
34
|
+
opt.on("-p","--print [OPTION]","fetch current amount in picoUSD") do |print|
|
27
35
|
options[:print] = print || 'default'
|
28
36
|
end
|
37
|
+
|
38
|
+
opt.on("-n","--notification [OPTION]","send notification via email") do |notification|
|
39
|
+
options[:notification] = notification || 'notification'
|
40
|
+
end
|
29
41
|
|
30
42
|
opt.on("-h","--help","help") do |h|
|
31
43
|
options[:help] = h
|
@@ -40,30 +52,43 @@ begin
|
|
40
52
|
puts Argosnap::VERSION
|
41
53
|
elsif options[:install]
|
42
54
|
if options[:install] == 'config'
|
43
|
-
Argosnap::Install.new.
|
55
|
+
Argosnap::Install.new.install
|
44
56
|
elsif options[:install] == 'cron'
|
45
|
-
Argosnap::
|
57
|
+
Argosnap::Install.new.cron_entry
|
58
|
+
elsif options[:install] == 'plist'
|
59
|
+
Argosnap::Helpers.new.install_plist
|
46
60
|
end
|
61
|
+
elsif options[:notification]
|
62
|
+
if options[:notification] == 'mail'
|
63
|
+
Argosnap::Notifications.new.send_mail
|
64
|
+
elsif options[:notification] == 'pushover'
|
65
|
+
Argosnap::Notifications.new.send_pushover
|
66
|
+
elsif options[:notification] == 'osx'
|
67
|
+
Argosnap::Notifications.new.send_osx_notification
|
68
|
+
elsif options[:notification] == 'osx_check'
|
69
|
+
Argosnap::Notifications.new.osx_check
|
70
|
+
elsif options[:notification] == 'all'
|
71
|
+
Argosnap::Notifications.new.notify
|
72
|
+
else
|
73
|
+
puts "You need to need to speficy notification option: 'mail' or 'pushover'"
|
74
|
+
end
|
75
|
+
elsif options[:cron]
|
76
|
+
Argosnap::Notifications.notify
|
47
77
|
elsif options[:help]
|
48
78
|
# avoids double printing of 'opt_parser'
|
49
79
|
elsif options[:print]
|
50
|
-
if options[:print] == '
|
51
|
-
Argosnap::OSXNotifications.new.display
|
52
|
-
elsif options[:print] == 'osx_check'
|
53
|
-
Argosnap::OSXNotifications.new.display_check
|
54
|
-
elsif options[:print] == 'default'
|
80
|
+
if options[:print] == 'default'
|
55
81
|
b = Argosnap::Fetch.new.balance
|
56
|
-
puts "Current balance
|
82
|
+
puts "Current picoUSD balance: #{b}"
|
57
83
|
elsif options[:print] == 'clean'
|
58
|
-
|
59
|
-
puts b
|
84
|
+
puts Argosnap::Fetch.new.balance
|
60
85
|
else
|
61
86
|
puts "Option not recognized"
|
62
87
|
end
|
63
88
|
else
|
64
89
|
puts opt_parser
|
65
90
|
end
|
66
|
-
rescue OptionParser::InvalidOption
|
91
|
+
rescue OptionParser::InvalidOption
|
67
92
|
puts "No such option! Type 'argosnap -h' for help!"
|
68
93
|
exit
|
69
94
|
end
|
data/files/local.sh
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
#!/bin/bash
|
2
2
|
|
3
|
+
SH=/bin/sh
|
4
|
+
|
3
5
|
# Load RVM into a shell session *as a function*
|
4
6
|
if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
|
5
7
|
# First try to load from a user install
|
@@ -7,9 +9,15 @@ if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
|
|
7
9
|
elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
|
8
10
|
# Then try to load from a root install
|
9
11
|
source "/usr/local/rvm/scripts/rvm"
|
12
|
+
elif [[ -s "$HOME/.rbenv/bin" ]] ; then
|
13
|
+
# try to load rbenv
|
14
|
+
$SH -c 'export PATH="$HOME/.rbenv/bin:$PATH" ; eval "$(rbenv init -)"'
|
15
|
+
elif [[ -s `which ruby` ]] ; then
|
16
|
+
# Nothing to do here(?)
|
17
|
+
echo "Using system's ruby" >> ~/.argosnap/argosnap.log
|
10
18
|
else
|
11
|
-
printf "ERROR:
|
19
|
+
printf "ERROR: No ruby installation was found!\n"
|
12
20
|
fi
|
13
21
|
|
14
22
|
# Executable now should be in path
|
15
|
-
argosnap -
|
23
|
+
argosnap -n osx_check
|
@@ -0,0 +1,24 @@
|
|
1
|
+
%p Hello
|
2
|
+
%p
|
3
|
+
Your
|
4
|
+
%a{:href => "https://www.tarsnap.com/"} tarsnap account
|
5
|
+
is running out of funds.
|
6
|
+
|
7
|
+
Your current amount of picoUSD is
|
8
|
+
= succeed "." do
|
9
|
+
%strong #{self.to_s}
|
10
|
+
|
11
|
+
%p
|
12
|
+
Have a nice day!
|
13
|
+
|
14
|
+
%p
|
15
|
+
argosnap
|
16
|
+
|
17
|
+
\--
|
18
|
+
|
19
|
+
%p
|
20
|
+
%strong Argosnap:
|
21
|
+
Receive notifications when your tarsnap account is running out of picoUSD!
|
22
|
+
%p
|
23
|
+
%strong URL:
|
24
|
+
%a{:href => "https://github.com/atmosx/argosnap"} https://github.com/atmosx/argosnap
|
data/lib/argosnap.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
# argosnap
|
1
|
+
# load argosnap classes and modules
|
2
2
|
|
3
3
|
require_relative File.expand_path("../argosnap/version", __FILE__)
|
4
4
|
require_relative File.expand_path("../argosnap/install", __FILE__)
|
5
|
+
require_relative File.expand_path("../argosnap/config", __FILE__)
|
6
|
+
require_relative File.expand_path("../argosnap/helpers", __FILE__)
|
5
7
|
require_relative File.expand_path("../argosnap/balance", __FILE__)
|
6
|
-
require_relative File.expand_path("../argosnap/
|
8
|
+
require_relative File.expand_path("../argosnap/notifications", __FILE__)
|
data/lib/argosnap/balance.rb
CHANGED
@@ -1,39 +1,48 @@
|
|
1
|
-
require 'yaml'
|
2
1
|
require 'mechanize'
|
3
|
-
require 'logger'
|
4
2
|
|
5
3
|
module Argosnap
|
6
|
-
# Given a username and a password, fetch balance from
|
4
|
+
# Given a username and a password, fetch balance from https://www.tarsnap.com
|
7
5
|
class Fetch
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
exit
|
6
|
+
|
7
|
+
# Elementary configuration file check
|
8
|
+
def check_configuration
|
9
|
+
Install.new.ensure_compatibility
|
10
|
+
Install.new.ensure_installation
|
11
|
+
if config.data[:email].empty?
|
12
|
+
config.log_and_abort("Please add your tarsnap email to #{config}")
|
13
|
+
end
|
14
|
+
if config.data[:password].empty?
|
15
|
+
config.log_and_abort("Please add your tarsnap password to #{config}")
|
19
16
|
end
|
20
17
|
end
|
21
18
|
|
22
|
-
# Fetch balance from tarsnap using
|
19
|
+
# Fetch balance from tarsnap using
|
23
20
|
def balance
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
21
|
+
check_configuration
|
22
|
+
agent = Mechanize.new
|
23
|
+
page = agent.get('https://www.tarsnap.com/account.html')
|
24
|
+
form = page.form_with(:action => 'https://www.tarsnap.com/manage.cgi')
|
25
|
+
form.address = config.data[:email]
|
26
|
+
form.password = config.data[:password]
|
27
|
+
panel = agent.submit(form)
|
28
|
+
wrong_email_message = 'No user exists with the provided email address; please try again.'
|
29
|
+
wrong_password_message = 'Password is incorrect; please try again.'
|
30
|
+
if panel.body.include?(wrong_email_message)
|
31
|
+
config.log_and_abort('Password is incorrect; please try again.')
|
32
|
+
elsif panel.body.include?(wrong_password_message)
|
33
|
+
config.log_and_abort('Bad password. Please check your configuration file tarsnap password!')
|
36
34
|
end
|
35
|
+
picodollars = panel.parser.to_s.scan(/\$\d+\.\d+/)[0].scan(/\d+\.\d+/)[0].to_f.round(4)
|
36
|
+
config.logger.info("Current amount of picoUSD: #{picodollars}")
|
37
|
+
picodollars
|
38
|
+
end
|
39
|
+
|
40
|
+
# private methods
|
41
|
+
private
|
42
|
+
|
43
|
+
# load configuration files
|
44
|
+
def config
|
45
|
+
Configuration.new
|
37
46
|
end
|
38
47
|
end
|
39
48
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
module Argosnap
|
5
|
+
class Configuration
|
6
|
+
# configuration files
|
7
|
+
def files
|
8
|
+
{
|
9
|
+
config: "#{Dir.home}/.argosnap/config.yml",
|
10
|
+
home: "#{Dir.home}/.argosnap/",
|
11
|
+
logfile: "#{Dir.home}/.argosnap/argosnap.log"
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
# logger object
|
16
|
+
def logger
|
17
|
+
Logger.new(files[:logfile], 10, 1024000)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Config data in hash
|
21
|
+
def data
|
22
|
+
YAML::load_file(files[:config])
|
23
|
+
end
|
24
|
+
|
25
|
+
# Check if gem is available
|
26
|
+
def gem_available?(name)
|
27
|
+
Gem::Specification.find_by_name(name)
|
28
|
+
rescue Gem::LoadError
|
29
|
+
false
|
30
|
+
rescue
|
31
|
+
Gem.available?(name)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Log and Abort!
|
35
|
+
def log_and_abort(msg)
|
36
|
+
logger.error(msg)
|
37
|
+
Kernel.abort(msg)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Argosnap
|
2
|
+
|
3
|
+
# Helper Class
|
4
|
+
class Helpers
|
5
|
+
|
6
|
+
# Creates launchd script with user's variables
|
7
|
+
def install_plist
|
8
|
+
if configuration.gem_available?('plist')
|
9
|
+
require 'plist'
|
10
|
+
time_interval = configuration.data[:seconds]
|
11
|
+
# Gem::Platform.local.os # => osx
|
12
|
+
user = ENV['USER']
|
13
|
+
launch_agents = "/Users/#{user}/Library/LaunchAgents/"
|
14
|
+
# start_script loads ruby - optimized for 'rvm'
|
15
|
+
start_script = File.expand_path('../../../files/local.sh', __FILE__)
|
16
|
+
if Dir.exists?(launch_agents)
|
17
|
+
filename = "org.#{user}.argosnap.plist"
|
18
|
+
if File.exist?("#{launch_agents}#{filename}")
|
19
|
+
puts "Please delete file: #{launch_agents}#{filename} before proceeding!"
|
20
|
+
else
|
21
|
+
hash = {"Label"=>"#{filename.scan(/(.+)(?:\.[^.]+)/).flatten[0]}", "ProgramArguments"=>["#{start_script}"], "StartInterval"=> time_interval, "RunAtLoad"=>true}
|
22
|
+
File.open("#{launch_agents}#{filename}", 'w') {|f| f.write(hash.to_plist)}
|
23
|
+
puts "Launchd script is installed. Type 'launchctl load -w #{launch_agents}#{filename}' to load the plist."
|
24
|
+
end
|
25
|
+
else
|
26
|
+
puts "No '#{launch_agents}' directory found! Aborting installation."
|
27
|
+
end
|
28
|
+
else
|
29
|
+
configuration.log_and_abort("Please install plist!")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# private
|
34
|
+
private
|
35
|
+
def configuration
|
36
|
+
Configuration.new
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
data/lib/argosnap/install.rb
CHANGED
@@ -1,22 +1,92 @@
|
|
1
|
-
require '
|
2
|
-
require 'yaml'
|
3
|
-
require 'plist'
|
1
|
+
require 'fileutils'
|
4
2
|
|
5
3
|
module Argosnap
|
4
|
+
|
6
5
|
class Install
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
|
7
|
+
# Install configuration files in the system
|
8
|
+
def install
|
9
|
+
ensure_compatibility
|
11
10
|
begin
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
11
|
+
# permissions are a-rwx, u+rwx
|
12
|
+
if File.exists? configuration.files[:config]
|
13
|
+
puts "Config file exists!"
|
14
|
+
puts "Please remove config: #{configuration.files[:config]} manually and re-install the configuration file."
|
15
|
+
else
|
16
|
+
Dir.mkdir(File.join(Dir.home, ".argosnap"), 0700) unless File.exist? configuration.files[:home]
|
17
|
+
FileUtils.touch(configuration.files[:logfile]) unless File.exist? configuration.files[:logfile]
|
18
|
+
config = {
|
19
|
+
email: 'tarsnap_email',
|
20
|
+
password: 'tarsnap_password',
|
21
|
+
threshold: 10,
|
22
|
+
seconds: 86400,
|
23
|
+
notifications_osx: false,
|
24
|
+
notifications_email: false,
|
25
|
+
smtp: {
|
26
|
+
email_delivery_method: 'smtp',
|
27
|
+
smtpd_user: 'username',
|
28
|
+
smtpd_password: 'password',
|
29
|
+
smtpd_address: "gmail.google.com",
|
30
|
+
smtpd_port: 587,
|
31
|
+
smtpd_from: 'user@host.domain.com',
|
32
|
+
smtpd_to: 'your@email.com',
|
33
|
+
format: 'txt'},
|
34
|
+
notifications_pushover: false,
|
35
|
+
pushover: {
|
36
|
+
key: 'user_key',
|
37
|
+
token: 'app_token'}
|
38
|
+
}
|
39
|
+
File.open(configuration.files[:config], "w") {|f| f.write(config.to_yaml)}
|
40
|
+
|
41
|
+
puts ""
|
42
|
+
puts "Configuration file created! To setup argosnap: "
|
43
|
+
puts "1. Edit the configuration file: #{configuration.files[:config]}"
|
44
|
+
puts "2. Run argosnap by typing in the terminal 'argosnap -p' to fetch current balance"
|
45
|
+
puts "3. To configure notifications see: <link>"
|
46
|
+
puts ""
|
47
|
+
|
48
|
+
end
|
49
|
+
rescue Errno::ENOENT => e
|
50
|
+
puts "Can't configuration locate file!"
|
18
51
|
puts e.message
|
52
|
+
puts e.backtrace
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def cron_entry
|
57
|
+
puts "\nA standard cron entry looks like this:\n"
|
58
|
+
puts "\n5 8 * * 6 <user> <command>\n"
|
59
|
+
puts "\nFor detailed instructions see here: <wiki-link>"
|
60
|
+
puts ""
|
61
|
+
end
|
62
|
+
|
63
|
+
# Check OS support and configuration file
|
64
|
+
def ensure_compatibility
|
65
|
+
# Check the operating system. Windows is not supported at this time.
|
66
|
+
unless %w{ darwin linux freebsd openbsd netbsd }.include? Gem::Platform.local.os
|
67
|
+
Kernel.abort("\nThis gem is made for UNIX! Please check the website for details #{url} !\n\n")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def ensure_installation
|
72
|
+
if File.exist?(configuration.files[:home])
|
73
|
+
if (File.exist?(configuration.files[:logfile]) && File.exist?(configuration.files[:config]))
|
74
|
+
true
|
75
|
+
else
|
76
|
+
Kernel.abort("\nNo configuration files found! Please run 'argosnap -i config'\n\n")
|
77
|
+
end
|
78
|
+
else
|
79
|
+
Kernel.abort("\nNo configuration directory found! Please run 'argosnap -i config'\n\n")
|
19
80
|
end
|
20
81
|
end
|
82
|
+
|
83
|
+
# private methods
|
84
|
+
private
|
85
|
+
|
86
|
+
# Load onfiguration files
|
87
|
+
def configuration
|
88
|
+
Configuration.new
|
89
|
+
end
|
90
|
+
|
21
91
|
end
|
22
92
|
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Argosnap
|
2
|
+
class Notifications
|
3
|
+
|
4
|
+
# When tarsnap balance is bellow threshold notify me
|
5
|
+
# Method is chosen based on threshold
|
6
|
+
def notify
|
7
|
+
if config.data[:threshold] >= Fetch.new.balance
|
8
|
+
send_mail
|
9
|
+
send_pushover
|
10
|
+
send_osx_notification
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Use with plist file
|
15
|
+
def osx_check
|
16
|
+
if config.data[:threshold] >= Fetch.new.balance
|
17
|
+
send_osx_notification
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# send notification via email
|
22
|
+
def send_mail
|
23
|
+
if config.data[:notifications_email]
|
24
|
+
if config.gem_available?('mail')
|
25
|
+
require 'mail'
|
26
|
+
require 'socket'
|
27
|
+
require_relative File.expand_path("../notifications/mailer", __FILE__)
|
28
|
+
Mailer.new(config.data, config.logger).send_mail
|
29
|
+
else
|
30
|
+
config.log_and_abort("Please install 'mail' gem by executing: '$ gem install mail'.")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# send notification via pushover.net
|
36
|
+
def send_pushover
|
37
|
+
if config.data[:notifications_pushover]
|
38
|
+
require "net/https"
|
39
|
+
require_relative File.expand_path("../notifications/pushover", __FILE__)
|
40
|
+
key = config.data[:pushover][:key]
|
41
|
+
token = config.data[:pushover][:token]
|
42
|
+
amount = Fetch.new.balance
|
43
|
+
message = "Your current tarsnap amount is #{amount} picoUSD!"
|
44
|
+
Pushover.send(token, key, message, config.logger, amount)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# send notification to osx notifications (desktop)
|
49
|
+
def send_osx_notification
|
50
|
+
if config.data[:notifications_osx]
|
51
|
+
if Gem::Platform.local.os == 'darwin'
|
52
|
+
# load 'terminal-notifier'
|
53
|
+
if config.gem_available?('terminal-notifier')
|
54
|
+
require 'terminal-notifier'
|
55
|
+
require_relative File.expand_path("../notifications/osxnotifications", __FILE__)
|
56
|
+
message = "Your picoUSD amount is: #{Fetch.new.balance}"
|
57
|
+
title = 'argosnap'
|
58
|
+
subtitle = 'running out of picoUSD!'
|
59
|
+
OSXnotify.send(message, title, subtitle)
|
60
|
+
else
|
61
|
+
config.log_and_abort("You need to install 'terminal-notifier' gem!")
|
62
|
+
end
|
63
|
+
else
|
64
|
+
config.log_and_abort("OSX notifications are available only under OSX > 10.8.x")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# private methods
|
70
|
+
private
|
71
|
+
|
72
|
+
# load configuration files
|
73
|
+
def config
|
74
|
+
Configuration.new
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module Argosnap
|
2
|
+
class Mailer
|
3
|
+
|
4
|
+
# load configuration files
|
5
|
+
def config
|
6
|
+
Configuration.new
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :logger, :smtpd_user, :smtpd_password, :smtpd_address, :smtpd_port, :smtpd_from, :smtpd_to, :method, :format, :balance
|
10
|
+
def initialize(config, logger)
|
11
|
+
@logger = logger
|
12
|
+
@smtpd_user = config[:smtp][:smtpd_user]
|
13
|
+
@smtpd_password = config[:smtp][:smtpd_password]
|
14
|
+
@smtpd_address = config[:smtp][:smtpd_address]
|
15
|
+
@smtpd_port = config[:smtp][:smtpd_port]
|
16
|
+
@smtpd_from = config[:smtp][:smtpd_from]
|
17
|
+
@smtpd_to = config[:smtp][:smtpd_to]
|
18
|
+
@method = config[:smtp][:email_delivery_method]
|
19
|
+
@format = config[:smtp][:format]
|
20
|
+
@balance = Fetch.new.balance.to_s
|
21
|
+
end
|
22
|
+
|
23
|
+
def ensure_mail_configuration
|
24
|
+
if smtpd_address.empty?
|
25
|
+
config.log_and_abort("There is no 'smtpd_address' in #{config}. Please check your configuration file.")
|
26
|
+
elsif smtpd_to.empty?
|
27
|
+
config.log_and_abort("There is no 'smtpd_to' in #{config}. Please check your configuration file.")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def text_message(amount)
|
32
|
+
message = <<EOF
|
33
|
+
|
34
|
+
Hello
|
35
|
+
|
36
|
+
Your tarsnap account is running out of funds. Your current amount of picoUSD is #{amount}.
|
37
|
+
|
38
|
+
This automated email message was sent by argosnap. Please do not reply to this email.
|
39
|
+
|
40
|
+
Have a nice day!
|
41
|
+
|
42
|
+
argosnap
|
43
|
+
--
|
44
|
+
|
45
|
+
Argosnap: Receive notifications when your tarsnap account is running out of picoUSD!
|
46
|
+
URL: https://github.com/atmosx/argosnap
|
47
|
+
|
48
|
+
EOF
|
49
|
+
|
50
|
+
message
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
# send email. HTML format is the default.
|
55
|
+
def send_mail
|
56
|
+
# ensure compatibility first
|
57
|
+
Install.new.ensure_compatibility
|
58
|
+
ensure_mail_configuration
|
59
|
+
|
60
|
+
# create the 'mail' object
|
61
|
+
mail = Mail.new
|
62
|
+
|
63
|
+
# configure mail options
|
64
|
+
mail[:from] = smtpd_from
|
65
|
+
mail[:to] = smtpd_to
|
66
|
+
mail[:subject] = "ARGOSNAP: your tarsnap balance."
|
67
|
+
|
68
|
+
# configure mail format: Use HTML if the user wants it, otherwise default to 'txt'
|
69
|
+
if format == 'html'
|
70
|
+
if config.gem_available?('haml')
|
71
|
+
require 'haml'
|
72
|
+
mail['content-type'] = 'text/html; charset=UTF-8'
|
73
|
+
# convert HAML to HTML
|
74
|
+
Haml::Engine.new(File.read(File.expand_path('../../../../files/mail.body.haml', __FILE__))).def_method(balance, :render)
|
75
|
+
mail[:body] = balance.render
|
76
|
+
else
|
77
|
+
log.error("Please install haml gem to receive HTML emails: '$ gem install haml'")
|
78
|
+
mail[:body] = text_message(balance)
|
79
|
+
end
|
80
|
+
else
|
81
|
+
mail[:body] = text_message(balance)
|
82
|
+
end
|
83
|
+
|
84
|
+
# SMTPd configuration. Defaults to local 'sendmail'
|
85
|
+
if method == 'smtp'
|
86
|
+
if smtpd_port == 465
|
87
|
+
# use smtps with some defaults
|
88
|
+
mail.delivery_method :smtp, address: smtpd_address, port: smtpd_port, user_name: smtpd_user, password: smtpd_password, ssl: true, openssl_verify_mode: 0
|
89
|
+
else
|
90
|
+
mail.delivery_method :smtp, address: smtpd_address, port: smtpd_port
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# dispatch email
|
95
|
+
mail.deliver
|
96
|
+
logger.info("Argosnap sent an email to #{smtpd_to}!")
|
97
|
+
logger.info("Current amount in picoUSD: #{balance}")
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# pushover.net module
|
2
|
+
module Pushover
|
3
|
+
def self.send(token, user, message, log, amount)
|
4
|
+
begin
|
5
|
+
# be nice to Pushover API
|
6
|
+
sleep(5)
|
7
|
+
url = URI.parse("https://api.pushover.net/1/messages.json")
|
8
|
+
req = Net::HTTP::Post.new(url.path)
|
9
|
+
req.set_form_data({
|
10
|
+
token: token,
|
11
|
+
user: user,
|
12
|
+
message: message
|
13
|
+
})
|
14
|
+
res = Net::HTTP.new(url.host, url.port)
|
15
|
+
res.use_ssl = true
|
16
|
+
res.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
17
|
+
res.start do |http|
|
18
|
+
status = http.request(req).code
|
19
|
+
if status == '200'
|
20
|
+
log.info('Notification sent via Pushover!')
|
21
|
+
log.info("Current amount of picoUSD: #{amount}")
|
22
|
+
elsif (400...500).to_a.include?(status)
|
23
|
+
log.error("Please revise your Pushover credentials. API request failed.")
|
24
|
+
else
|
25
|
+
log.error("Request returned status code: #{status}, Pushover notification probably failed.")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
rescue SocketError
|
30
|
+
log.error("No internet connection available, Pushover notification failed.")
|
31
|
+
end
|
32
|
+
end
|
data/lib/argosnap/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: argosnap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Panagiotis Atmatzidis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-10-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -38,8 +38,9 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
-
description: A ruby script displays
|
42
|
-
|
41
|
+
description: A ruby script that displays tarsnap current ballance in picoUSD. The
|
42
|
+
script can send notifications when the acount balance falls below the predefined
|
43
|
+
threshold. Argosnap supports email, pushover and OSX notifications.
|
43
44
|
email:
|
44
45
|
- atma@convalesco.org
|
45
46
|
executables:
|
@@ -49,16 +50,23 @@ extra_rdoc_files: []
|
|
49
50
|
files:
|
50
51
|
- ".gitignore"
|
51
52
|
- Gemfile
|
53
|
+
- Guardfile
|
52
54
|
- LICENSE.txt
|
53
55
|
- README.md
|
54
56
|
- Rakefile
|
55
57
|
- argosnap.gemspec
|
56
58
|
- bin/argosnap
|
57
59
|
- files/local.sh
|
60
|
+
- files/mail.body.haml
|
58
61
|
- lib/argosnap.rb
|
59
62
|
- lib/argosnap/balance.rb
|
63
|
+
- lib/argosnap/config.rb
|
64
|
+
- lib/argosnap/helpers.rb
|
60
65
|
- lib/argosnap/install.rb
|
61
|
-
- lib/argosnap/
|
66
|
+
- lib/argosnap/notifications.rb
|
67
|
+
- lib/argosnap/notifications/mailer.rb
|
68
|
+
- lib/argosnap/notifications/osxnotifications.rb
|
69
|
+
- lib/argosnap/notifications/pushover.rb
|
62
70
|
- lib/argosnap/version.rb
|
63
71
|
- test/lib/argosnap/options_test.rb
|
64
72
|
- test/lib/argosnap/version_test.rb
|
@@ -83,10 +91,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
83
91
|
version: '0'
|
84
92
|
requirements: []
|
85
93
|
rubyforge_project:
|
86
|
-
rubygems_version: 2.4.
|
94
|
+
rubygems_version: 2.4.8
|
87
95
|
signing_key:
|
88
96
|
specification_version: 4
|
89
|
-
summary:
|
97
|
+
summary: Read your tarsnap picoUSD amount in cli and display notifications when it
|
98
|
+
runs out!.
|
90
99
|
test_files:
|
91
100
|
- test/lib/argosnap/options_test.rb
|
92
101
|
- test/lib/argosnap/version_test.rb
|
data/lib/argosnap/osxnotify.rb
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
require 'terminal-notifier'
|
2
|
-
require_relative File.expand_path('../balance', __FILE__)
|
3
|
-
require 'yaml'
|
4
|
-
|
5
|
-
module Argosnap
|
6
|
-
class OSXNotifications
|
7
|
-
def initialize
|
8
|
-
begin
|
9
|
-
user = ENV['USER']
|
10
|
-
raise ArgumentError.new("This command is made for Darwin! Please check the website for details #{url} !") unless Gem::Platform.local.os == 'darwin'
|
11
|
-
r = YAML::load_file("#{Dir.home}/.argosnap/config.yml")
|
12
|
-
logfile = "#{Dir.home}/.argosnap/argosnap.log"
|
13
|
-
@threshold, @logger, @picodollars, @time_interval = r[:threshold], Logger.new(logfile), Argosnap::Fetch.new.balance, r[:seconds]
|
14
|
-
rescue ArgumentError => e
|
15
|
-
puts e.message
|
16
|
-
# puts e.backtrace
|
17
|
-
exit
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
# Creates launchd script with user's variables
|
22
|
-
def install_launchd_script
|
23
|
-
raise ArgumentError.new("Please make sure you run 'argosnap install' in order to install configuration files, before running asnap!") unless File.exists?("#{Dir.home}/.argosnap/config.yml")
|
24
|
-
user = ENV['USER']
|
25
|
-
c = "#{Dir.home}/.argosnap/config.yml"
|
26
|
-
begin
|
27
|
-
launch_agents = "/Users/#{user}/Library/LaunchAgents/"
|
28
|
-
# start_script loads the RVM environment.
|
29
|
-
start_script = File.expand_path('../../../files/local.sh', __FILE__)
|
30
|
-
if Dir.exists?(launch_agents)
|
31
|
-
filename = "org.#{user}.argosnap.plist"
|
32
|
-
if File.exist?("#{launch_agents}#{filename}")
|
33
|
-
puts "Please delete file: #{launch_agents}#{filename} before proceeding!"
|
34
|
-
else
|
35
|
-
hash = {"Label"=>"#{filename.scan(/(.+)(?:\.[^.]+)/).flatten[0]}", "ProgramArguments"=>["#{start_script}"], "StartInterval"=> @time_interval, "RunAtLoad"=>true}
|
36
|
-
File.open("#{launch_agents}#{filename}", 'w') {|f| f.write(hash.to_plist)}
|
37
|
-
puts "Launchd script is installed. Type 'launchctl load -w #{launch_agents}#{filename}' to load the plist."
|
38
|
-
end
|
39
|
-
else
|
40
|
-
puts "No '#{launch_agents}' directory found! Aborting installation."
|
41
|
-
end
|
42
|
-
rescue Exception => e
|
43
|
-
puts e.message
|
44
|
-
# puts e.backtrace
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
# Display notification if threshold is surpassed
|
49
|
-
def display_check
|
50
|
-
TerminalNotifier.notify("Current balance: #{@picodollars}", :title => 'TarSnap', :subtitle => 'balance running out') if @picodollars < @threshold.to_i
|
51
|
-
end
|
52
|
-
|
53
|
-
# Display current ballance in OSX style notifications
|
54
|
-
def display
|
55
|
-
TerminalNotifier.notify("Current balance: #{@picodollars}", :title => 'TarSnap', :subtitle => 'balance running out')
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|