geostats 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +13 -0
- data/README.md +58 -0
- data/bin/geostats +33 -0
- data/lib/geostats.rb +36 -0
- data/lib/geostats/commands/base.rb +73 -0
- data/lib/geostats/commands/console.rb +17 -0
- data/lib/geostats/commands/generate.rb +21 -0
- data/lib/geostats/commands/help.rb +20 -0
- data/lib/geostats/commands/init.rb +31 -0
- data/lib/geostats/commands/migrate.rb +21 -0
- data/lib/geostats/commands/push.rb +41 -0
- data/lib/geostats/commands/set.rb +35 -0
- data/lib/geostats/commands/update.rb +175 -0
- data/lib/geostats/console.rb +2 -0
- data/lib/geostats/core_ext.rb +5 -0
- data/lib/geostats/database.rb +15 -0
- data/lib/geostats/generator.rb +43 -0
- data/lib/geostats/grabber/cache.rb +95 -0
- data/lib/geostats/grabber/log.rb +27 -0
- data/lib/geostats/grabber/logs.rb +37 -0
- data/lib/geostats/grabber/user.rb +15 -0
- data/lib/geostats/http.rb +97 -0
- data/lib/geostats/migrations/001_create_caches.rb +27 -0
- data/lib/geostats/migrations/002_create_cache_types.rb +16 -0
- data/lib/geostats/migrations/003_create_logs.rb +13 -0
- data/lib/geostats/migrations/004_create_log_types.rb +15 -0
- data/lib/geostats/migrations/005_create_settings.rb +9 -0
- data/lib/geostats/migrations/006_add_cito_cache_type.rb +5 -0
- data/lib/geostats/models/cache.rb +47 -0
- data/lib/geostats/models/cache_type.rb +9 -0
- data/lib/geostats/models/log.rb +33 -0
- data/lib/geostats/models/log_type.rb +9 -0
- data/lib/geostats/models/setting.rb +16 -0
- data/lib/geostats/stats.rb +220 -0
- data/lib/geostats/templates/default.mustache +10 -0
- data/lib/geostats/templates/difficulty_terrain_matrix.mustache +40 -0
- data/lib/geostats/templates/founds_by_cache_type.mustache +17 -0
- data/lib/geostats/templates/milestones.mustache +19 -0
- data/lib/geostats/templates/monthly_founds.mustache +18 -0
- data/lib/geostats/templates/stylesheet.css +160 -0
- data/lib/geostats/utils.rb +42 -0
- data/lib/geostats/version.rb +3 -0
- data/lib/geostats/views/base.rb +19 -0
- data/lib/geostats/views/default.rb +13 -0
- data/lib/geostats/views/difficulty_terrain_matrix.rb +34 -0
- data/lib/geostats/views/founds_by_cache_type.rb +24 -0
- data/lib/geostats/views/milestones.rb +23 -0
- data/lib/geostats/views/monthly_founds.rb +24 -0
- metadata +165 -0
data/LICENSE
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright (c) 2010 Thomas Cyron <thomas@thcyron.de>
|
2
|
+
|
3
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
4
|
+
purpose with or without fee is hereby granted, provided that the above
|
5
|
+
copyright notice and this permission notice appear in all copies.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
8
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
9
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
10
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
11
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
12
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
13
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
Geostats — Geocaching.com Statistics Generator
|
2
|
+
===============================================
|
3
|
+
|
4
|
+
Geostats is a tool for generating statistics about your geocaching.com
|
5
|
+
account. It generates HTML files and allows you to push them to your
|
6
|
+
public profile at geocaching.com. It doesn’t rely on Pocket Queries.
|
7
|
+
|
8
|
+
|
9
|
+
Getting Started
|
10
|
+
---------------
|
11
|
+
|
12
|
+
bin/geostats init <username> <password>
|
13
|
+
bin/geostats update
|
14
|
+
bin/geostats generate > stats.html
|
15
|
+
open stats.html
|
16
|
+
|
17
|
+
bin/geostats console
|
18
|
+
|
19
|
+
Inside the console you have access to the following
|
20
|
+
ActiveRecord models:
|
21
|
+
|
22
|
+
* Cache
|
23
|
+
* CacheType
|
24
|
+
* Log
|
25
|
+
* LogType
|
26
|
+
|
27
|
+
|
28
|
+
Todo
|
29
|
+
----
|
30
|
+
|
31
|
+
* Better error handling
|
32
|
+
* Logging / More output
|
33
|
+
* HTML generation
|
34
|
+
* Pushing
|
35
|
+
|
36
|
+
|
37
|
+
Usage
|
38
|
+
-----
|
39
|
+
|
40
|
+
Environment Variables:
|
41
|
+
GEOSTATS_DIR="~/geostats"
|
42
|
+
|
43
|
+
Commands:
|
44
|
+
Initialize new database: $ geostats init username password
|
45
|
+
$ geostats init username password directory
|
46
|
+
|
47
|
+
Update database: $ geostats update
|
48
|
+
$ geostats update all
|
49
|
+
$ geostats update all caches
|
50
|
+
$ geostats update all logs
|
51
|
+
$ geostats update GC12345 GC67890
|
52
|
+
|
53
|
+
-d <secs> (delay)
|
54
|
+
|
55
|
+
Generate statistics: $ geostats generate
|
56
|
+
$ geostats generate default
|
57
|
+
|
58
|
+
Push statistics to geocaching.com: $ geostats push
|
data/bin/geostats
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
begin
|
4
|
+
require "geostats"
|
5
|
+
rescue LoadError
|
6
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", "lib")))
|
7
|
+
require "geostats"
|
8
|
+
end
|
9
|
+
|
10
|
+
command_name = ARGV.shift || "help"
|
11
|
+
command_instance = nil
|
12
|
+
|
13
|
+
possibilities = Geostats::COMMANDS.select do |cmd|
|
14
|
+
cmd =~ /^#{Regexp.escape(command_name)}/
|
15
|
+
end
|
16
|
+
|
17
|
+
if possibilities.length == 1
|
18
|
+
command_name = possibilities.first
|
19
|
+
else
|
20
|
+
command_name = "help"
|
21
|
+
end
|
22
|
+
|
23
|
+
require "geostats/commands/#{command_name}"
|
24
|
+
|
25
|
+
command_const = "Geostats::Commands::#{command_name.camelcase}".constantize
|
26
|
+
command_instance = command_const.new(ARGV)
|
27
|
+
|
28
|
+
begin
|
29
|
+
command_instance.invoke
|
30
|
+
rescue Geostats::Commands::UsageError
|
31
|
+
command_instance.usage
|
32
|
+
exit 1
|
33
|
+
end
|
data/lib/geostats.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require "cgi"
|
2
|
+
require "time"
|
3
|
+
require "active_record"
|
4
|
+
|
5
|
+
require "geostats/core_ext"
|
6
|
+
require "geostats/version"
|
7
|
+
|
8
|
+
require "geostats/models/cache"
|
9
|
+
require "geostats/models/cache_type"
|
10
|
+
require "geostats/models/log"
|
11
|
+
require "geostats/models/log_type"
|
12
|
+
require "geostats/models/setting"
|
13
|
+
|
14
|
+
module Geostats
|
15
|
+
COMMANDS = %w(console generate help init migrate push set update)
|
16
|
+
ROOT = File.join(File.expand_path(File.dirname(__FILE__)), "geostats")
|
17
|
+
|
18
|
+
module Commands
|
19
|
+
autoload :Base, "geostats/commands/base"
|
20
|
+
autoload :Help, "geostats/commands/help"
|
21
|
+
end
|
22
|
+
|
23
|
+
autoload :Database, "geostats/database"
|
24
|
+
|
25
|
+
module Grabber
|
26
|
+
autoload :Cache, "geostats/grabber/cache"
|
27
|
+
autoload :Log, "geostats/grabber/log"
|
28
|
+
autoload :Logs, "geostats/grabber/logs"
|
29
|
+
autoload :User, "geostats/grabber/user"
|
30
|
+
end
|
31
|
+
|
32
|
+
autoload :Generator, "geostats/generator"
|
33
|
+
autoload :HTTP, "geostats/http"
|
34
|
+
autoload :Stats, "geostats/stats"
|
35
|
+
autoload :Utils, "geostats/utils"
|
36
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require "term/ansicolor"
|
2
|
+
|
3
|
+
module Term::ANSIColor
|
4
|
+
def erase(n=nil)
|
5
|
+
"\e[#{n}K"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
module Geostats
|
10
|
+
module Commands
|
11
|
+
class UsageError < Exception
|
12
|
+
end
|
13
|
+
|
14
|
+
class Base
|
15
|
+
include Term::ANSIColor
|
16
|
+
|
17
|
+
def initialize(args=[])
|
18
|
+
@args = args
|
19
|
+
end
|
20
|
+
|
21
|
+
def invoke
|
22
|
+
parse_args
|
23
|
+
before; run; after
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
def parse_args; end
|
29
|
+
def before; end
|
30
|
+
def after; end
|
31
|
+
|
32
|
+
def log(*args)
|
33
|
+
print *args.join
|
34
|
+
end
|
35
|
+
|
36
|
+
def warn(message)
|
37
|
+
log "Warning: #{message}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def error(message)
|
41
|
+
STDERR.puts "Error: #{message}"
|
42
|
+
exit 1
|
43
|
+
end
|
44
|
+
|
45
|
+
def verbose(message)
|
46
|
+
log message
|
47
|
+
end
|
48
|
+
|
49
|
+
def connect_database(directory = ENV["GEOSTATS_DIR"])
|
50
|
+
Database.connect!(directory)
|
51
|
+
rescue => e
|
52
|
+
error "could not connect to database: #{e.message}"
|
53
|
+
end
|
54
|
+
|
55
|
+
def login
|
56
|
+
HTTP.login(Setting.get(:username), Setting.get(:password))
|
57
|
+
rescue ArgumentError, Net::HTTPExceptions => e
|
58
|
+
error "Failed to log in: #{e.message}"
|
59
|
+
end
|
60
|
+
|
61
|
+
def logout
|
62
|
+
HTTP.logout
|
63
|
+
rescue Net::HTTPExceptions => e
|
64
|
+
error "Failed to log out: #{e.message}"
|
65
|
+
end
|
66
|
+
|
67
|
+
def usage
|
68
|
+
STDERR.puts "Usage: geostats command [arguments ...]"
|
69
|
+
exit 1
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Geostats
|
2
|
+
module Commands
|
3
|
+
class Console < Base
|
4
|
+
def usage
|
5
|
+
STDERR.puts "Usage: geostats console"
|
6
|
+
end
|
7
|
+
|
8
|
+
def parse_args
|
9
|
+
raise UsageError unless @args.length.zero?
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
exec "irb -I lib -r geostats -r geostats/console"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Geostats
|
2
|
+
module Commands
|
3
|
+
class Generate < Base
|
4
|
+
def usage
|
5
|
+
STDERR.puts "Usage: geostats generate"
|
6
|
+
end
|
7
|
+
|
8
|
+
def parse_args
|
9
|
+
raise UsageError unless @args.length.zero?
|
10
|
+
end
|
11
|
+
|
12
|
+
def before
|
13
|
+
connect_database
|
14
|
+
end
|
15
|
+
|
16
|
+
def run
|
17
|
+
puts Generator.generate
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Geostats
|
2
|
+
module Commands
|
3
|
+
class Help < Base
|
4
|
+
def usage
|
5
|
+
run
|
6
|
+
end
|
7
|
+
|
8
|
+
def run
|
9
|
+
STDERR.puts "Usage: geostats <command> [...]"
|
10
|
+
STDERR.puts
|
11
|
+
STDERR.puts "Commands: init <username> <password> [<directory>]"
|
12
|
+
STDERR.puts " update [all | <code>]"
|
13
|
+
STDERR.puts " generate [<template>]"
|
14
|
+
STDERR.puts " push"
|
15
|
+
STDERR.puts " console"
|
16
|
+
STDERR.puts " set [<key>] [<value>]"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require "geostats/commands/migrate"
|
3
|
+
|
4
|
+
module Geostats
|
5
|
+
module Commands
|
6
|
+
class Init < Base
|
7
|
+
def usage
|
8
|
+
STDERR.puts "Usage: geostats init <username> <password> [<directory>]"
|
9
|
+
end
|
10
|
+
|
11
|
+
def parse_args
|
12
|
+
raise UsageError unless @args.length == 2 or @args.length == 3
|
13
|
+
|
14
|
+
@username, @password, @directory = @args
|
15
|
+
@directory ||= File.expand_path("~/.geostats")
|
16
|
+
|
17
|
+
FileUtils.mkdir_p(@directory) unless File.exists?(@directory)
|
18
|
+
end
|
19
|
+
|
20
|
+
def before
|
21
|
+
connect_database(@directory)
|
22
|
+
end
|
23
|
+
|
24
|
+
def run
|
25
|
+
Migrate.new.invoke
|
26
|
+
Setting.set(:username, @username)
|
27
|
+
Setting.set(:password, @password)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Geostats
|
2
|
+
module Commands
|
3
|
+
class Migrate < Base
|
4
|
+
def usage
|
5
|
+
STDERR.puts "Usage: geostats migrate"
|
6
|
+
end
|
7
|
+
|
8
|
+
def parse_args
|
9
|
+
raise UsageError unless @args.length.zero?
|
10
|
+
end
|
11
|
+
|
12
|
+
def before
|
13
|
+
connect_database
|
14
|
+
end
|
15
|
+
|
16
|
+
def run
|
17
|
+
ActiveRecord::Migrator.migrate(File.join(Geostats::ROOT, "migrations"))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Geostats
|
2
|
+
module Commands
|
3
|
+
class Push < Base
|
4
|
+
def usage
|
5
|
+
STDERR.puts "Usage: geostats push"
|
6
|
+
end
|
7
|
+
|
8
|
+
def parse_args
|
9
|
+
raise UsageError unless @args.length.zero?
|
10
|
+
end
|
11
|
+
|
12
|
+
def before
|
13
|
+
connect_database
|
14
|
+
login
|
15
|
+
end
|
16
|
+
|
17
|
+
def after
|
18
|
+
logout
|
19
|
+
end
|
20
|
+
|
21
|
+
def run
|
22
|
+
log yellow("Generating statistics")
|
23
|
+
@html = Generator.generate
|
24
|
+
log "\r", green("Successfully generated statistics"), erase, "\n"
|
25
|
+
|
26
|
+
log yellow("Pushing statistics to geocaching.com")
|
27
|
+
|
28
|
+
resp, data = HTTP.post("/account/editprofiledetails.aspx", {
|
29
|
+
"ctl00$ContentBody$uxProfileDetails" => @html,
|
30
|
+
"ctl00$ContentBody$uxSave" => "Save Changes"
|
31
|
+
})
|
32
|
+
|
33
|
+
log "\r",
|
34
|
+
green("Successfully pushed statistics to geocaching.com"),
|
35
|
+
erase, "\n"
|
36
|
+
rescue Net::HTTPExceptions => e
|
37
|
+
error e.message
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Geostats
|
2
|
+
module Commands
|
3
|
+
class Set < Base
|
4
|
+
def usage
|
5
|
+
STDERR.puts "Usage: geostats set"
|
6
|
+
STDERR.puts " set <key>"
|
7
|
+
STDERR.puts " set <key> <value>"
|
8
|
+
end
|
9
|
+
|
10
|
+
def parse_args
|
11
|
+
raise UsageError if @args.length > 2
|
12
|
+
@key, @value = @args
|
13
|
+
end
|
14
|
+
|
15
|
+
def before
|
16
|
+
connect_database
|
17
|
+
end
|
18
|
+
|
19
|
+
def run
|
20
|
+
if @key
|
21
|
+
if @value
|
22
|
+
Setting.set(@key, @value)
|
23
|
+
puts "#{@key} = #{@value}"
|
24
|
+
else
|
25
|
+
puts "#{@key} = #{Setting.get(@key) || "<null>"}"
|
26
|
+
end
|
27
|
+
else
|
28
|
+
Setting.all.each do |setting|
|
29
|
+
puts "#{setting.key} = #{setting.value || "<null>"}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
module Geostats
|
2
|
+
module Commands
|
3
|
+
class Update < Base
|
4
|
+
def usage
|
5
|
+
STDERR.puts "Usage: geostats update"
|
6
|
+
STDERR.puts " update all"
|
7
|
+
end
|
8
|
+
|
9
|
+
def parse_args
|
10
|
+
@update_all = (@args.first == "all")
|
11
|
+
end
|
12
|
+
|
13
|
+
def before
|
14
|
+
connect_database
|
15
|
+
login
|
16
|
+
|
17
|
+
@delay = Setting.get(:delay) || 5
|
18
|
+
@sleep = false
|
19
|
+
end
|
20
|
+
|
21
|
+
def after
|
22
|
+
logout
|
23
|
+
end
|
24
|
+
|
25
|
+
def run
|
26
|
+
begin
|
27
|
+
@logs = Grabber::Logs.new.logs
|
28
|
+
rescue Net::HTTPExceptions => e
|
29
|
+
error "Failed to fetch your logs: #{e.message}"
|
30
|
+
end
|
31
|
+
|
32
|
+
@logs.reverse.each do |loginfo|
|
33
|
+
handle_log(loginfo)
|
34
|
+
|
35
|
+
if @sleep
|
36
|
+
sleep(@delay + rand(@delay))
|
37
|
+
@sleep = false
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def handle_log(loginfo)
|
45
|
+
missing = []
|
46
|
+
|
47
|
+
[:log_uuid, :logged_at, :icon, :cache_uuid, :cache_name].each do |attribute|
|
48
|
+
missing << attribute unless loginfo.send(attribute)
|
49
|
+
end
|
50
|
+
|
51
|
+
if missing.any?
|
52
|
+
log red("Skipping log because there are missing attributes: #{attributes.join(", ")}")
|
53
|
+
return
|
54
|
+
end
|
55
|
+
|
56
|
+
cache = create_or_update_cache(loginfo)
|
57
|
+
return unless cache
|
58
|
+
|
59
|
+
log = create_or_update_log(loginfo)
|
60
|
+
return unless log
|
61
|
+
|
62
|
+
cache.logs << log
|
63
|
+
end
|
64
|
+
|
65
|
+
def create_or_update_cache(loginfo)
|
66
|
+
cache = Cache.where(:uuid => loginfo.cache_uuid).first
|
67
|
+
|
68
|
+
if cache.nil?
|
69
|
+
log \
|
70
|
+
yellow("Adding new cache "),
|
71
|
+
yellow(bold(loginfo.cache_name))
|
72
|
+
|
73
|
+
@sleep = true
|
74
|
+
|
75
|
+
begin
|
76
|
+
cache = Cache.create_from_website(loginfo.cache_uuid)
|
77
|
+
rescue Net::HTTPError => e
|
78
|
+
log "\r",
|
79
|
+
red("Failed to add new cache "),
|
80
|
+
red(bold(loginfo.cache_name)),
|
81
|
+
red(": "),
|
82
|
+
red("Could not fetch cache information from website: #{e.message}"),
|
83
|
+
erase, "\n"
|
84
|
+
return
|
85
|
+
end
|
86
|
+
|
87
|
+
if cache.save
|
88
|
+
log "\r",
|
89
|
+
green("Successfully added new cache "),
|
90
|
+
green(bold(cache.name)),
|
91
|
+
erase, "\n"
|
92
|
+
else
|
93
|
+
log "\r",
|
94
|
+
red("Failed to add new cache "),
|
95
|
+
red(bold(loginfo.cache_name)),
|
96
|
+
red(": "),
|
97
|
+
red("Could not fetch all needed information from website"),
|
98
|
+
erase, "\n"
|
99
|
+
|
100
|
+
cache.errors.full_messages.each do |msg|
|
101
|
+
verbose " o #{msg}"
|
102
|
+
end
|
103
|
+
|
104
|
+
cache = nil
|
105
|
+
end
|
106
|
+
else
|
107
|
+
cache.update_attribute(:name, loginfo.cache_name)
|
108
|
+
end
|
109
|
+
|
110
|
+
cache
|
111
|
+
end
|
112
|
+
|
113
|
+
def create_or_update_log(loginfo)
|
114
|
+
# Don't handle reviewer notes
|
115
|
+
return nil if loginfo.icon == "big_smile"
|
116
|
+
|
117
|
+
log = Log.where(:uuid => loginfo.log_uuid).first
|
118
|
+
|
119
|
+
if log.nil?
|
120
|
+
log \
|
121
|
+
yellow("Adding new log for "),
|
122
|
+
yellow(bold(loginfo.cache_name)),
|
123
|
+
yellow(" from "),
|
124
|
+
yellow(bold(loginfo.logged_at.strftime("%F")))
|
125
|
+
|
126
|
+
@sleep = true
|
127
|
+
|
128
|
+
begin
|
129
|
+
log = Log.create_from_website(loginfo.log_uuid)
|
130
|
+
rescue Net::HTTPEeror => e
|
131
|
+
log "\r",
|
132
|
+
red("Failed to add new log for "),
|
133
|
+
red(bold(loginfo.cache_name)),
|
134
|
+
red(" from "),
|
135
|
+
red(bold(loginfo.logged_at.strftime("%F"))),
|
136
|
+
red(": "),
|
137
|
+
red("Could not fetch log information from website: #{e.message}"),
|
138
|
+
erase, "\n"
|
139
|
+
return
|
140
|
+
end
|
141
|
+
|
142
|
+
if log.save
|
143
|
+
log "\r",
|
144
|
+
green("Successfully added log for "),
|
145
|
+
green(bold(loginfo.cache_name)),
|
146
|
+
green(" from "),
|
147
|
+
green(bold(log.logged_at.strftime("%F"))),
|
148
|
+
erase, "\n"
|
149
|
+
else
|
150
|
+
log "\r",
|
151
|
+
red("Failed to add new log for "),
|
152
|
+
red(bold(loginfo.cache_name)),
|
153
|
+
red(" from "),
|
154
|
+
red(bold(loginfo.logged_at.strftime("%F"))),
|
155
|
+
red(": "),
|
156
|
+
red("Could not fetch all needed information from website"),
|
157
|
+
erase, "\n"
|
158
|
+
|
159
|
+
log.errors.full_messages.each do |msg|
|
160
|
+
verbose " o #{msg}"
|
161
|
+
end
|
162
|
+
|
163
|
+
log = nil
|
164
|
+
end
|
165
|
+
else
|
166
|
+
log.logged_at = loginfo.logged_at
|
167
|
+
log.set_type_from_icon(loginfo.icon)
|
168
|
+
log.save
|
169
|
+
end
|
170
|
+
|
171
|
+
log
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|