155 lines
3.7 KiB
Plaintext
155 lines
3.7 KiB
Plaintext
mapping db = ([]);
|
|
|
|
mapping make_episode(string series, string title, string episode, array date)
|
|
{
|
|
return ([ "series":series, "episode":episode, "title":title, "date":date ]);
|
|
}
|
|
|
|
void print_episode(mapping episode)
|
|
{
|
|
write(" %-30s %10s %-30s (%{%d.%})\n",
|
|
episode->series, episode->episode, episode->title, episode->date);
|
|
}
|
|
|
|
void print_series(mapping series)
|
|
{
|
|
write("%-30s %-10s\n", series->series, series->status);
|
|
map(series->episodes, print_episode);
|
|
}
|
|
|
|
void dump_db(mapping database)
|
|
{
|
|
foreach(database; string name; mapping series)
|
|
{
|
|
print_series(series);
|
|
}
|
|
}
|
|
|
|
array get_latest(mapping database)
|
|
{
|
|
array latest = ({});
|
|
foreach(database; string name; mapping series)
|
|
{
|
|
latest += ({ series->episodes[0] });
|
|
}
|
|
return latest;
|
|
}
|
|
|
|
int(0..1) compare_date(array a, array b)
|
|
{
|
|
if (!arrayp(a) && !arrayp(b)) return false;
|
|
if (!arrayp(a) || !sizeof(a)) return arrayp(b) && sizeof(b);
|
|
if (!arrayp(b) || !sizeof(b)) return arrayp(a) && sizeof(a);
|
|
if (a[0] == b[0]) return compare_date(a[1..], b[1..]);
|
|
return a[0] < b[0];
|
|
}
|
|
|
|
int(0..1) compare_by_date(mapping a, mapping b)
|
|
{
|
|
return compare_date(reverse(a->date), reverse(b->date));
|
|
}
|
|
|
|
void watch_list(mapping database)
|
|
{
|
|
map(Array.sort_array(get_latest(database), compare_by_date),
|
|
print_episode);
|
|
}
|
|
|
|
string prompt_read(string prompt)
|
|
{
|
|
write("%s: ", prompt);
|
|
return Stdio.stdin.gets();
|
|
}
|
|
|
|
array parse_date(string date)
|
|
{
|
|
return (array(int))(date/".");
|
|
}
|
|
|
|
mapping prompt_for_episode()
|
|
{
|
|
return make_episode(prompt_read("Series"),
|
|
prompt_read("Title"),
|
|
prompt_read("Episode"),
|
|
parse_date(prompt_read("Date watched")));
|
|
}
|
|
|
|
// pike offers encode_value() and decode_value() as standard ways
|
|
// to save and read data, but that is not a human readable format.
|
|
// therefore we are instead printing the structure as debug-output
|
|
// which is a readable form as long as it only contains integers,
|
|
// strings, mappings, arrays and multisets this format can be read by pike.
|
|
// to read it we are creating a class that contains the data as a value,
|
|
// which is then compiled and instantiated to allow us to pull the data out.
|
|
void save_db(string filename, mapping database)
|
|
{
|
|
Stdio.write_file(filename, sprintf("%O", database));
|
|
}
|
|
|
|
void watch_save()
|
|
{
|
|
save_db("pwatch", db);
|
|
}
|
|
|
|
mapping load_db(string filename)
|
|
{
|
|
if (file_stat(filename))
|
|
return compile_string("mixed data = " +
|
|
Stdio.read_file(filename) + ";")()->data;
|
|
else return ([]);
|
|
}
|
|
|
|
mapping get_series(string name, mapping database)
|
|
{
|
|
return database[name];
|
|
}
|
|
|
|
array get_episode_list(string series, mapping database)
|
|
{
|
|
return database[series]->episodes;
|
|
}
|
|
|
|
void watch_new_series(string name, string status, mapping database)
|
|
{
|
|
database[name] = (["series":name, "status":status, "episodes":({}) ]);
|
|
}
|
|
|
|
mapping get_or_add_series(string name, mapping database)
|
|
{
|
|
if (!database[name])
|
|
{
|
|
string answer = prompt_read("Add new series? [y/n]: ");
|
|
if (answer == "y")
|
|
watch_new_series(name, "active", database);
|
|
}
|
|
return database[name];
|
|
}
|
|
|
|
void watch_add(mapping database)
|
|
{
|
|
mapping episode = prompt_for_episode();
|
|
string series_name = episode->series;
|
|
mapping series = get_or_add_series(series_name, database);
|
|
if (!series)
|
|
watch_add(database);
|
|
else
|
|
series->episodes = Array.unshift(series->episodes, episode);
|
|
}
|
|
|
|
void watch_load()
|
|
{
|
|
db = load_db("pwatch");
|
|
}
|
|
|
|
int main(int argc, array argv)
|
|
{
|
|
watch_load();
|
|
if (argc>1 && argv[1] == "add")
|
|
{
|
|
watch_add(db);
|
|
watch_save();
|
|
}
|
|
else
|
|
watch_list(db);
|
|
}
|