argosnap 0.0.3 → 0.0.4
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.
- 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
|