Add my existing implementation

This commit is contained in:
2021-05-20 14:27:51 -04:00
commit db8802dd37
18 changed files with 1367 additions and 0 deletions

67
tests/tagtimerc Normal file
View File

@@ -0,0 +1,67 @@
# Settings for TagTime.
# This file must be in your home directory, called .tagtimerc
# NB: restart the daemon (tagtimed.pl) if you change this file.
$usr = "auser"; # CHANGEME to your username
$path = "/home/auser/dev/TagTime/"; # CHANGEME to your path to tagtime
$logf = "$path$usr.log"; # log file for pings
# If you're using windows, you'll need cygwin and to set this flag to 1:
$cygwin = 0; # CHANGEME to 1 if you're using windows/cygwin.
$ED = "/usr/bin/vim +"; # CHANGEME if you don't like vi (eg: /usr/bin/pico)
$XT = "/usr/bin/st"; # CHANGEME to your path to xterm
# Get your personal Beeminder auth token (after signing in) from
# https://www.beeminder.com/api/v1/auth_token.json
$beemauth = "abc123"; # CHANGEME to your personal beeminder auth token
# WARNING WARNING WARNING:
# if you point this at a beeminder goal with data that was not generated from
# this tagtime log, it will DELETE ALL OF YOUR DATA
# CHANGEME by adding entries for each beeminder graph you want to auto-update:
%beeminder = (
#"alice/work" => "job", # all "job" pings get added to bmndr.com/alice/work
#"bob/play" => ["fun","whee"], # pings w/ "fun" and/or "whee" sent to bob/play
# ADVANCED USAGE: regular expressions
# pings tagged like "eat1", "eat2", "eat3" get added to carol/food:
#"carol/food" => qr/\beat\d+\b/,
# ADVANCED USAGE: plug-in functions
# pings tagged anything except "afk" get added to "dan/nafk":
#"dan/nafk" => sub { return shift() !~ /\bafk\b/; }
# pings tagged "workout" get added to dave/tueworkouts, but only on tuesdays:
#"dave/tueworkouts" => sub { my @now = localtime();
# return shift() =~/\bworkout\b/ && $now[6] == 2;
#}
);
# Pings from more than this many seconds ago get autologged with tags "afk" and
# "RETRO". (Pings can be overdue either because the computer was off or tagtime
# was waiting for you to answer a previous ping. If the computer was off, the
# tag "off" is also added.)
$retrothresh = 60;
# If you want the universal ping schedule, don't touch these 3 settings...
$gap = 45*60; # Average number of seconds between pings (eg, 60*60 = 1 hour).
$URPING = 1184097393; # Ur-ping, ie, the birth of timepie/tagtime! (unixtime)
$seed = 11193462;
$linelen = 79; # Try to keep log lines at most this long.
$catchup = 1; # Whether it beeps for old pings, ie, should it beep a bunch
# of times in a row when the computer wakes from sleep.
$enforcenums = 0; # Whether it forces you to include a number in your
# ping response (include tag non or nonXX where XX is day
# of month to override). This is for task editor integration.
# System command that will play a sound for pings.
# Often "play" or "playsound" on Linux, or "afplay" on Mac osx.
# $playsound = "afplay ${path}sound/blip-twang.wav";
# $playsound = "echo -e '\a'"; # this is the default if $playsound not defined.
# $playsound = ""; # makes tagtime stay quiet.
1; # When requiring a library in perl it has to return 1.

121
tests/test_ping.py Normal file
View File

@@ -0,0 +1,121 @@
import unittest
from ping import Ping
class TestLineToPing(unittest.TestCase):
def test_line_to_ping(self):
l = "1600790846 afk off RETRO [2020.09.22 12:07:26 TUE]"
p1 = Ping.line_to_ping(l)
p2 = Ping(1600790846,
["afk", "off", "RETRO"],
["2020.09.22 12:07:26 TUE"],
l)
self.assertEqual(p1, p2)
l = " 1600790846 [2020.09.22 12:07:26 TUE] foo bar (lol)"
p1 = Ping.line_to_ping(l)
p2 = Ping(1600790846,
["foo", "bar"],
["lol", "2020.09.22 12:07:26 TUE"],
l)
self.assertEqual(p1, p2)
l = "1600790846 12weird #tags :should work"
p1 = Ping.line_to_ping(l)
p2 = Ping(1600790846,
["12weird", "#tags", ":should", "work"],
[],
l)
self.assertEqual(p1, p2)
def test_line_to_ping_no_timestamp(self):
l = " 846 [2020.09.22 12:07:26 TUE] foo bar (lol)"
with self.assertRaises(AttributeError):
Ping.line_to_ping(l)
l = "foo bar (lol)"
with self.assertRaises(AttributeError):
Ping.line_to_ping(l)
def test_line_to_ping_no_tags(self):
l = "1600790846 [2020.09.22 12:07:26 TUE] (foo) [baar]"
p = Ping.line_to_ping(l)
self.assertEqual([], p.tags)
class TestGetTags(unittest.TestCase):
def test_get_tags(self):
tags = Ping.get_tags("123456789 foo #bar quz [sd ab)")
expected = ["foo", "#bar", "quz", "[sd", "ab)"]
self.assertEqual(tags, expected)
class TestPingToLine(unittest.TestCase):
def test_ping_to_line(self):
p = Ping(1600790846,
["afk", "off", "RETRO"],
["qul", "2020.09.22 12:07:26 TUE"])
line = Ping.ping_to_line(p)
expected = "1600790846 afk off RETRO [qul] [2020.09.22 12:07:26 TUE]"
self.assertEqual(line, expected)
def test_ping_to_line_with_annotation(self):
p = Ping(1600790846,
["afk", "off", "RETRO"],
["qul"])
line = Ping.ping_to_line(p, True, 57)
expected = "1600790846 afk off RETRO [qul] [2020.09.22 12:07:26 Tue]"
self.assertEqual(line, expected)
class TestAddTimeAnnotation(unittest.TestCase):
def test_add_time_annotation_24(self):
time = 1600790846
line = str(time)
new_line = Ping.add_time_annotation(time, line, 40)
exp_line = line + " [2020.09.22 12:07:26 Tue]"
self.assertEqual(new_line, exp_line)
def test_add_time_annotation_18(self):
time = 1600790846
line = str(time)
new_line = Ping.add_time_annotation(time, line, 29)
exp_line = line + " [09.22 12:07:26 Tue]"
self.assertEqual(new_line, exp_line)
def test_add_time_annotation_15(self):
time = 1600790846
line = str(time)
new_line = Ping.add_time_annotation(time, line, 26)
exp_line = line + " [22 12:07:26 Tue]"
self.assertEqual(new_line, exp_line)
def test_add_time_annotation_12(self):
time = 1600790846
line = str(time)
new_line = Ping.add_time_annotation(time, line, 23)
exp_line = line + " [12:07:26 Tue]"
self.assertEqual(new_line, exp_line)
def test_add_time_annotation_9(self):
time = 1600790846
line = str(time)
new_line = Ping.add_time_annotation(time, line, 20)
exp_line = line + " [12:07 Tue]"
self.assertEqual(new_line, exp_line)
def test_add_time_annotation_5(self):
time = 1600790846
line = str(time)
new_line = Ping.add_time_annotation(time, line, 16)
exp_line = line + " [12:07]"
self.assertEqual(new_line, exp_line)
def test_add_time_annotation_else(self):
time = 1600790846
line = str(time)
new_line = Ping.add_time_annotation(time, line, 10)
exp_line = line + " [07]"
self.assertEqual(new_line, exp_line)

67
tests/test_taglog.py Normal file
View File

@@ -0,0 +1,67 @@
import os
import unittest
import taglog
class TestTagLog(unittest.TestCase):
TEST_LOG_1 = "tests/user1.log"
TEST_LOG_2 = "tests/user2.log"
TEST_LOG_3 = "tests/user3.log"
TEST_LOG_1_LOCK = TEST_LOG_1 + ".lock"
TEST_LOG_2_LOCK = TEST_LOG_2 + ".lock"
def test_tag_log_locking(self):
tl1 = taglog.TagLog(self.TEST_LOG_1)
tl2 = taglog.TagLog(self.TEST_LOG_2)
# Make sure that lock files are created.
self.assertTrue(os.path.isfile(self.TEST_LOG_1_LOCK))
self.assertTrue(os.path.isfile(self.TEST_LOG_2_LOCK))
# Make sure that lock files are deleted on object destruction.
del tl2
self.assertFalse(os.path.isfile(self.TEST_LOG_2_LOCK))
del tl1
self.assertFalse(os.path.isfile(self.TEST_LOG_1_LOCK))
def test_tag_log_locking_conflict(self):
tl1 = taglog.TagLog(self.TEST_LOG_1)
self.assertTrue(os.path.isfile(self.TEST_LOG_1_LOCK))
# Creating another TagLog object for the same log caues a system exit.
with self.assertRaises(SystemExit):
tl2 = taglog.TagLog(self.TEST_LOG_1)
# Create another TagLog after destroying the first one.
del tl1
tl2 = taglog.TagLog(self.TEST_LOG_1)
self.assertTrue(os.path.isfile(self.TEST_LOG_1_LOCK))
del tl2
def test_exists(self):
tl = taglog.TagLog(self.TEST_LOG_1)
self.assertTrue(tl.exists())
tl = taglog.TagLog(self.TEST_LOG_3)
self.assertFalse(tl.exists())
def test_last_ping(self):
Ping = taglog.Ping
p1 = taglog.TagLog(self.TEST_LOG_1).last_ping()
line = "1600808609 (lol) afk bar [lulz]\n"
p2 = Ping(1600808609, ["afk", "bar"], ["lol", "lulz"], line)
self.assertEqual(p1, p2)
def test_last_ping_time(self):
time = taglog.TagLog(self.TEST_LOG_1).last_ping_time()
self.assertEqual(time, 1600808609)
time = taglog.TagLog(self.TEST_LOG_2).last_ping_time()
self.assertEqual(time, 1601543391)
def test_get_tags(self):
tags = taglog.TagLog(self.TEST_LOG_1).get_tags()
expected_tags = [
(6, "afk"),
(5, "off"),
(3, "bar"),
(1, "quz"),
(1, "foo")]
self.assertEqual(tags, expected_tags)

26
tests/test_tagtimerc.py Normal file
View File

@@ -0,0 +1,26 @@
import unittest
import tagtimerc
class TestTagTimeRc(unittest.TestCase):
def test_parse_tagtimerc(self):
test_rc = "./tests/tagtimerc"
ttrc = tagtimerc.parse_tagtimerc(test_rc)
self.assertEqual(ttrc.log_file, "/home/auser/dev/TagTime/auser.log")
self.assertEqual(ttrc.ed, "/usr/bin/vim +")
self.assertEqual(ttrc.xt, "/usr/bin/st")
self.assertEqual(ttrc.retrothresh, 60)
self.assertEqual(ttrc.gap, 45 * 60)
self.assertEqual(ttrc.urping, 1184097393)
self.assertEqual(ttrc.seed, 11193462)
self.assertEqual(ttrc.linelen, 79)
self.assertEqual(ttrc.catchup, 1)
def test_value_to_int(self):
value_to_int = tagtimerc.value_to_int
self.assertEqual(value_to_int("312"), 312)
with self.assertRaises(ValueError):
value_to_int("")
self.assertEqual(value_to_int("12 * 3*2"), 72)

77
tests/test_timer.py Normal file
View File

@@ -0,0 +1,77 @@
import unittest
import timer
class TestTimer(unittest.TestCase):
def create_timer(self):
seed, urping, gap = 11193462, 1184097393, 45 * 60
return timer.Timer(seed, urping, gap)
def test_create_timer(self):
p = self.create_timer()
self.assertEqual(p.seed, 11193462)
self.assertEqual(p.ping, 1184097393)
self.assertEqual(p.gap, 45 * 60)
self.assertEqual(p.ia, 16807)
self.assertEqual(p.im, 2147483647)
def test_ran0(self):
p = self.create_timer()
self.assertEqual(p.ran0(), 1297438545)
self.assertEqual(p.ran0(), 500674177)
self.assertEqual(p.ran0(), 989963893)
def test_ran01(self):
p = self.create_timer()
self.assertEqual(p.ran01(), 0.6041669033487174)
self.assertEqual(p.ran01(), 0.2331445818921293)
self.assertEqual(p.ran01(), 0.4609878610172252)
def test_exprand(self):
p = self.create_timer()
self.assertEqual(p.exprand(), 1360.5429307641098)
self.assertEqual(p.exprand(), 3931.4605357416476)
self.assertEqual(p.exprand(), 2090.8356340914393)
def test_next_at_urping(self):
p = self.create_timer()
self.assertEqual(p.next(), 1184098754)
self.assertEqual(p.next(), 1184102685)
self.assertEqual(p.next(), 1184104776)
self.assertEqual(p.next(), 1184105302)
def test_next_in_2020(self):
""" I took the following ping times from the Perl implementation for
this test.
1600803512 afk off RETRO [2020.09.22 15:38:32 TUE]
1600805511 afk off RETRO [2020.09.22 16:11:51 TUE]
1600806947 afk off RETRO [2020.09.22 16:35:47 TUE]
"""
p = self.create_timer()
self.assertEqual(p.prev(1600803600), 1600803512)
self.assertEqual(p.next(), 1600805511)
self.assertEqual(p.next(), 1600806947)
def test_prev(self):
p = self.create_timer()
time = 1601502077 # 2020/09/30 17:40:26 ET
self.assertEqual(p.prev(time), 1601502026)
self.assertEqual(p.seed, 1953937112)
def test_prev_repeat(self):
""" Calling prev multiple times should work even if the timer has
already moved past time. """
p = self.create_timer()
self.assertEqual(p.prev(1600803600), 1600803512)
self.assertEqual(p.next(), 1600805511)
self.assertEqual(p.next(), 1600806947)
self.assertEqual(p.prev(1600803600), 1600803512)
self.assertEqual(p.next(), 1600805511)
self.assertEqual(p.next(), 1600806947)
def test_time_now(self):
p = self.create_timer()
self.assertEqual(type(p.time_now()), int)

8
tests/user1.log Normal file
View File

@@ -0,0 +1,8 @@
1600790846 foo bar [2020.09.22 12:07:26 TUE]
1600791982 afk off [2020.09.22 12:26:22 TUE]
1600793495 afk off [2020.09.22 12:51:35 TUE]
1600797909 afk off [2020.09.22 14:05:09 TUE]
1600803512 afk off [2020.09.22 15:38:32 TUE]
1600805511 quz bar [2020.09.22 16:11:51 TUE]
1600806947 afk off [2020.09.22 16:35:47 TUE]
1600808609 (lol) afk bar [lulz]

9
tests/user2.log Normal file
View File

@@ -0,0 +1,9 @@
1601534943 afk off RETRO [2020.10.01 02:49:03 THU]
1601535769 afk off RETRO [2020.10.01 03:02:49 THU]
1601535868 afk off RETRO [2020.10.01 03:04:28 THU]
1601537458 afk off RETRO [2020.10.01 03:30:58 THU]
1601538061 afk off RETRO [2020.10.01 03:41:01 THU]
1601538726 afk off RETRO [2020.10.01 03:52:06 THU]
1601538750 afk off RETRO [2020.10.01 03:52:30 THU]
1601542553 afk off RETRO [2020.10.01 04:55:53 THU]
1601543391 afk off RETRO [2020.10.01 05:09:51 THU]