:- module(track_episodes, [update_tracked_episodes/0, toggle_episode/1, forget_episode/1, most_recently_watched/1, watched/1, next_unwatched/2, previous_unwatched/2]). :- use_module(library(dcg/basics)). :- use_module(library(registry)). :- use_module(library(persistency)). :- use_module(local_episodes). attach :- absolute_file_name('track_episodes.db', F, [access(write)]), db_attach(F, []). detach :- db_detach. :- persistent episode_watched(episode:integer, watched:atom). % Helpers. swapbc(P, A, B, C, D) :- call(P, A, C, B, D). compound(F, A, B, T) :- T =.. [F, A, B]. % Get data from registry. file(N) --> "File Name ", integer(N). pos(N) --> "File Position ", integer(N). mpc_reg(Phrase, Value) :- phrase(Phrase, Name), atom_codes(Name1, Name), registry_get_key(current_user/software/'mpc-hc'/'mpc-hc'/settings, Name1, Value). % Create episode-position list. epipos(L) :- epipos_x(0, L). epipos_x(N, L) :- ( catch((mpc_reg(file(N), File), mpc_reg(pos(N), Pos)), _, fail) -> M is N + 1, ( atom_codes(File, File1), findall(Ep, phrase(local_episode(Ep), File1), Eps) -> atom_codes(Pos, Pos1), phrase(integer(Pos2), Pos1), maplist(swapbc(compound, '-', Pos2), Eps, Eps1), append(Eps1, T, L), epipos_x(M, T) ; epipos_x(M, L)) ; L = [] ). considered_watched(_-Pos) :- Pos > 11000000000. % Update database. update_tracked_episodes :- epipos(All), include(considered_watched, All, Watched), maplist(add, Watched). add(Ep-_) :- episode_watched(Ep, _), !. add(Ep-_) :- assert_episode_watched(Ep, true). forget_episode(Ep) :- retractall_episode_watched(Ep, true), retractall_episode_watched(Ep, false). toggle_episode(Ep) :- episode_watched(Ep, true), !, retractall_episode_watched(Ep, true), assert_episode_watched(Ep, false). toggle_episode(Ep) :- episode_watched(Ep, false), !, retractall_episode_watched(Ep, false), assert_episode_watched(Ep, true). toggle_episode(Ep) :- assert_episode_watched(Ep, true). % Utility. most_recently_watched(Ep) :- findall(N, episode_watched(N, true), All), last(All, Ep). watched(Ep) :- episode_watched(Ep, true). next_unwatched(Ep0, Ep) :- Ep1 is Ep0 + 1, ( \+ watched(Ep1) -> Ep = Ep1 ; next_unwatched(Ep1, Ep) ). previous_unwatched(Ep0, Ep) :- Ep1 is Ep0 - 1, ( \+ watched(Ep1) -> Ep = Ep1 ; previous_unwatched(Ep1, Ep) ).