diff --git a/server/forge.py b/server/forge.py new file mode 100644 index 0000000..7aba484 --- /dev/null +++ b/server/forge.py @@ -0,0 +1,53 @@ +from datetime import datetime, timedelta + + +def get_timefile_exact(time): + ''' + time is of type `datetime`; it is not "rounded" to match the real file; + that work is done in get_timefile(time) + ''' + return time.strftime('%Y-%m/%d/rec-%Y-%m-%d-%H-%M-%S-ror.mp3') + + +def round_timefile(exact): + ''' + This will round the datetime, so to match the file organization structure + ''' + return datetime(exact.year, exact.month, exact.day, exact.hour) + + +def get_timefile(exact): + return get_timefile_exact(round_timefile(exact)) + + +def get_files_and_intervals(start, end, rounder=round_timefile): + ''' + both arguments are datetime objects + returns an iterator whose elements are (filename, start_cut, end_cut) + Cuts are expressed in seconds + ''' + print '%s < %s' % (start, end) + if end <= start: + raise ValueError("end < start!") + + while start <= end: + begin = rounder(start) + start_cut = (start - begin).total_seconds() + if end < begin + timedelta(seconds=3599): + end_cut = (begin + timedelta(seconds=3599) - end).total_seconds() + else: + end_cut = 0 + yield (begin, start_cut, end_cut) + start = begin + timedelta(hours=1) + + +def mp3_join(named_intervals): + ''' + Note that these are NOT the intervals returned by get_files_and_intervals, + as they do not supply a filename, but only a datetime. + What we want in input is basically the same thing, but with get_timefile() + applied on the first element + ''' + for (filename, start_cut, end_cut) in named_intervals: + pass + raise NotImplementedError() diff --git a/server/test_forge.py b/server/test_forge.py new file mode 100644 index 0000000..e843ae4 --- /dev/null +++ b/server/test_forge.py @@ -0,0 +1,154 @@ +from datetime import datetime, timedelta + +from nose.tools import raises, assert_items_equal, eq_ + +from forge import get_files_and_intervals, get_timefile_exact, round_timefile,\ + get_timefile + +eight = datetime(2014, 5, 30, 20) +nine = datetime(2014, 5, 30, 21) +ten = datetime(2014, 5, 30, 22) + + +def minutes(n): + return timedelta(minutes=n) + + +def seconds(n): + return timedelta(seconds=n) + +## timefile + + +def test_timefile_exact(): + eq_(get_timefile_exact(eight), + '2014-05/30/rec-2014-05-30-20-00-00-ror.mp3') + +## Rounding + + +def test_rounding_similarity(): + eq_(round_timefile(eight), round_timefile(eight+minutes(20))) + assert round_timefile(eight) != round_timefile(nine) + + +def test_rounding_value(): + eq_(round_timefile(eight), eight) + eq_(round_timefile(eight + minutes(20)), eight) + + +## Rounding + timefile + + +def test_timefile_alreadyround(): + eq_(get_timefile(eight), + '2014-05/30/rec-2014-05-30-20-00-00-ror.mp3') + + +def test_timefile_toround(): + eq_(get_timefile(eight + minutes(20)), + '2014-05/30/rec-2014-05-30-20-00-00-ror.mp3') + +## Intervals + + +@raises(ValueError) +def test_intervals_same(): + tuple(get_files_and_intervals(eight, eight)) + + +@raises(ValueError) +def test_intervals_before(): + tuple(get_files_and_intervals(nine, eight)) + + +def test_intervals_full_1(): + res = list(get_files_and_intervals(eight, nine-seconds(1))) + eq_(len(res), 1) + eq_(res[0][1], 0) + eq_(res[0][2], 0) + + +def test_intervals_partial_1(): + res = list(get_files_and_intervals(eight, nine-minutes(10))) + eq_(len(res), 1) + eq_(res[0][1], 0) + eq_(res[0][2], 10*60 - 1) + + +def test_intervals_exact_2(): + res = list(get_files_and_intervals(eight, nine)) + eq_(len(res), 2) + eq_(res[0][1], 0) + eq_(res[0][2], 0) + eq_(res[1][1], 0) + eq_(res[1][2], 3599) + + +def test_intervals_partial_2(): + res = list(get_files_and_intervals(eight, nine + minutes(50))) + eq_(len(res), 2) + eq_(res[0][1], 0) + eq_(res[0][2], 0) + eq_(res[1][1], 0) + eq_(res[1][2], 599) + + +def test_intervals_full_2(): + res = list(get_files_and_intervals(eight, + nine + minutes(59) + seconds(59))) + eq_(len(res), 2) + eq_(res[0][1], 0) + eq_(res[0][2], 0) + eq_(res[1][1], 0) + eq_(res[1][2], 0) + + +def test_intervals_exact_3(): + res = list(get_files_and_intervals(eight, ten)) + eq_(len(res), 3) + eq_(res[0][1], 0) + eq_(res[0][2], 0) + eq_(res[1][1], 0) + eq_(res[1][2], 0) + eq_(res[2][1], 0) + eq_(res[2][2], 3599) + + +def test_intervals_partial_3(): + res = list(get_files_and_intervals(eight, ten+minutes(50))) + eq_(len(res), 3) + eq_(res[0][1], 0) + eq_(res[0][2], 0) + eq_(res[1][1], 0) + eq_(res[1][2], 0) + eq_(res[2][1], 0) + eq_(res[2][2], 599) + + +def test_intervals_full_3(): + res = list(get_files_and_intervals(eight, ten+minutes(59) + seconds(59))) + eq_(len(res), 3) + eq_(res[0][1], 0) + eq_(res[0][2], 0) + eq_(res[1][1], 0) + eq_(res[1][2], 0) + eq_(res[2][1], 0) + eq_(res[2][2], 0) + + +def test_intervals_middle_1(): + res = list(get_files_and_intervals(eight + minutes(20), + nine - minutes(20))) + eq_(len(res), 1) + eq_(res[0][1], 20*60) + eq_(res[0][2], 20*60-1) + + +def test_intervals_left_2(): + res = list(get_files_and_intervals(eight+minutes(30), nine)) + eq_(len(res), 2) + eq_(res[0][1], 30*60) + eq_(res[0][2], 0) + eq_(res[1][1], 0) + eq_(res[1][2], 3599)