aboutsummaryrefslogtreecommitdiff
path: root/pl
diff options
context:
space:
mode:
authorJohn Ankarström <john@ankarstrom.se>2022-08-24 15:17:08 +0200
committerJohn Ankarström <john@ankarstrom.se>2022-08-24 15:17:33 +0200
commit6fd66a9264731bd7ee6d7602675965021d929a4a (patch)
treee94fc63efb823ad2f5c9ef6de6188da389a08d38 /pl
parentff48d644a45dd71098ecb9007a41807fb37d0081 (diff)
downloadEpisodeBrowser-6fd66a9264731bd7ee6d7602675965021d929a4a.tar.gz
Remove Prolog dependency.
The only thing left to reimplement is the tracking of watched episodes in MPC-HC.
Diffstat (limited to 'pl')
-rw-r--r--pl/atom_dcg.pl82
-rw-r--r--pl/cfg.pl76
-rw-r--r--pl/episode_data.pl196
-rw-r--r--pl/local_episodes.pl50
-rw-r--r--pl/track_episodes.pl112
5 files changed, 0 insertions, 516 deletions
diff --git a/pl/atom_dcg.pl b/pl/atom_dcg.pl
deleted file mode 100644
index c5b9bfc..0000000
--- a/pl/atom_dcg.pl
+++ /dev/null
@@ -1,82 +0,0 @@
-:- module(atom_dcg, [compound_atom_codes/2]).
-
-% with_atoms/1-9 automatically convert atoms for the caller to codes
-% for the callee, primarily to make atoms easier to use with
-% definite-clause grammars. atom_phrase/2 is defined as a shortcut.
-
-% with_codes/1-9, conversely, convert codes for the caller to atoms
-% for the callee.
-
-:- meta_predicate user:with_atoms(0).
-:- meta_predicate user:with_atoms(0,0).
-:- meta_predicate user:with_atoms(0,0,0).
-:- meta_predicate user:with_atoms(0,0,0,0).
-:- meta_predicate user:with_atoms(0,0,0,0,0).
-:- meta_predicate user:with_atoms(0,0,0,0,0,0).
-:- meta_predicate user:with_atoms(0,0,0,0,0,0,0).
-:- meta_predicate user:with_atoms(0,0,0,0,0,0,0,0).
-:- meta_predicate user:with_atoms(0,0,0,0,0,0,0,0,0).
-user:with_atoms(A) :- atom_dcg:compound_atom_codes(A, A1), call(A1).
-user:with_atoms(A, B) :- maplist(user:with_atoms, [A,B]).
-user:with_atoms(A, B, C) :- maplist(user:with_atoms, [A,B,C]).
-user:with_atoms(A, B, C, D) :- maplist(user:with_atoms, [A,B,C,D]).
-user:with_atoms(A, B, C, D, E) :- maplist(user:with_atoms, [A,B,C,D,E]).
-user:with_atoms(A, B, C, D, E, F) :- maplist(user:with_atoms, [A,B,C,D,E,F]).
-user:with_atoms(A, B, C, D, E, F, G) :- maplist(user:with_atoms, [A,B,C,D,E,F,G]).
-user:with_atoms(A, B, C, D, E, F, G, H) :- maplist(user:with_atoms, [A,B,C,D,E,F,G,H]).
-user:with_atoms(A, B, C, D, E, F, G, H, I) :- maplist(user:with_atoms, [A,B,C,D,E,F,G,H,I]).
-
-:- meta_predicate user:with_codes(0).
-:- meta_predicate user:with_codes(0,0).
-:- meta_predicate user:with_codes(0,0,0).
-:- meta_predicate user:with_codes(0,0,0,0).
-:- meta_predicate user:with_codes(0,0,0,0,0).
-:- meta_predicate user:with_codes(0,0,0,0,0,0).
-:- meta_predicate user:with_codes(0,0,0,0,0,0,0).
-:- meta_predicate user:with_codes(0,0,0,0,0,0,0,0).
-:- meta_predicate user:with_codes(0,0,0,0,0,0,0,0,0).
-user:with_codes(A) :- atom_dcg:compound_atom_codes(A1, A), call(A1).
-user:with_codes(A, B) :- maplist(user:with_codes, [A,B]).
-user:with_codes(A, B, C) :- maplist(user:with_codes, [A,B,C]).
-user:with_codes(A, B, C, D) :- maplist(user:with_codes, [A,B,C,D]).
-user:with_codes(A, B, C, D, E) :- maplist(user:with_codes, [A,B,C,D,E]).
-user:with_codes(A, B, C, D, E, F) :- maplist(user:with_codes, [A,B,C,D,E,F]).
-user:with_codes(A, B, C, D, E, F, G) :- maplist(user:with_codes, [A,B,C,D,E,F,G]).
-user:with_codes(A, B, C, D, E, F, G, H) :- maplist(user:with_codes, [A,B,C,D,E,F,G,H]).
-user:with_codes(A, B, C, D, E, F, G, H, I) :- maplist(user:with_codes, [A,B,C,D,E,F,G,H,I]).
-
-:- meta_predicate user:atom_phrase(2, ?).
-user:atom_phrase(G, A) :-
- atom_dcg:compound_atom_codes(G, G1),
- ( var(A)
- -> phrase(G1, C),
- atom_codes(A, C)
- ; atom_codes(A, C),
- phrase(G1, C)
- ).
-
-compound_atom_codes(Module:G, Module:G1) :- !, compound_atom_codes(G, G1).
-compound_atom_codes(G, G1) :-
- ( nonvar(G)
- -> G =.. [F|Args0],
- maplist(maybe_atom_codes, Args0, Args),
- G1 =.. [F|Args]
- ; G1 =.. [F|Args],
- maplist(maybe_atom_codes, Args0, Args),
- G =.. [F|Args0]
- ).
-
-maybe_atom_codes(A, C) :-
- (compound(A) ; compound(C)), !,
- compound_atom_codes(A, C).
-
-maybe_atom_codes(A, C) :-
- nonvar(A), !,
- ( atom(A)
- -> atom_codes(A, C)
- ; C = A
- ).
-
-maybe_atom_codes(A, C) :-
- var(A), !,
- when((ground(A) ; ground(C)), catch(atom_codes(A, C), _, A = C)).
diff --git a/pl/cfg.pl b/pl/cfg.pl
deleted file mode 100644
index 297d426..0000000
--- a/pl/cfg.pl
+++ /dev/null
@@ -1,76 +0,0 @@
-:- module(cfg, [set_glob/1,
- get_glob/1,
- set_root/1,
- get_root/1,
- set_url/1,
- get_url/1]).
-
-:- use_module(library(registry)).
-
-set_key(Key, Value) :-
- registry_set_key(current_user/software/'JohnAJ'/'EpisodeBrowser'/'Settings', Key, Value).
-get_key(Key, Value) :-
- catch(registry_get_key(current_user/software/'JohnAJ'/'EpisodeBrowser'/'Settings', Key, Value),
- _,
- fail).
-
-set_root(V) :- set_key('EpisodeRoot', V).
-get_root(V) :-
- get_key('EpisodeRoot', V0),
- re_replace('\\\\', '/', V0, V1),
- atom_string(V, V1).
-
-set_glob(V) :- set_key('EpisodeGlob', V).
-get_glob(V) :-
- ( get_key('EpisodeGlob', V), !
- ; V = '*/*.*'
- ).
-
-set_url(V) :- set_key('UrlPrefix', V).
-get_url(V) :-
- ( get_key('UrlPrefix', V), !
- ; V = 'https://animixplay.to/v1/detective-conan/ep'
- ).
-
-set_view_watched(V) :- set_key('ViewWatched', V).
-get_view_watched(V) :-
- ( get_key('ViewWatched', V),
- integer(V), !
- ; V = 1
- ).
-
-set_view_tv_original(V) :- set_key('ViewTVOriginal', V).
-get_view_tv_original(V) :-
- ( get_key('ViewTVOriginal', V),
- integer(V), !
- ; V = 1
- ).
-
-set_limit_screenwriter(V) :- set_key('LimitScreenwriter', V).
-get_limit_screenwriter(V) :-
- ( get_key('LimitScreenwriter', V),
- atom(V), !
- ; V = ""
- ).
-
-set_sort(V) :- W is V + 2147483647, set_key('Sort', W).
-get_sort(V) :-
- ( get_key('Sort', W),
- integer(W), !,
- V is W - 2147483647
- ; V = 1
- ).
-
-set_focus(V) :- set_key('Focus', V).
-get_focus(V) :-
- ( get_key('Focus', V),
- integer(V), !
- ; V = 1
- ).
-
-set_dlv_height(V) :- set_key('DlvHeight', V).
-get_dlv_height(V) :-
- ( get_key('DlvHeight', V),
- integer(V), !
- ; V = 0
- ).
diff --git a/pl/episode_data.pl b/pl/episode_data.pl
deleted file mode 100644
index 5b83546..0000000
--- a/pl/episode_data.pl
+++ /dev/null
@@ -1,196 +0,0 @@
-:- module(episode_data, [ensure_episode_data/0,
- update_episode_data/0,
- update_screenwriters/0,
- retract_episode/1,
- episode_count/1,
- rate_episode/2,
- episode_rating/2,
- tv_original/1,
- thread_running/1,
- thread_exception/2]).
-
-:- use_module(library(clpfd)).
-:- use_module(library(dcg/basics)).
-:- use_module(library(http/http_open)).
-:- use_module(library(sgml)).
-:- use_module(library(xpath)).
-:- use_module(library(persistency)).
-:- use_module(atom_dcg).
-
-:- persistent episode_title(episode:integer, title:atom).
-:- persistent episode_wiki(episode:integer, wiki:atom).
-:- persistent episode_datum(episode:integer, key:atom, value:atom).
-:- persistent episode_rating(episode:integer, rating:integer).
-
-attach :-
- absolute_file_name('episode_data.db', F, [access(write)]),
- db_attach(F, []).
-
-detach :-
- db_detach.
-
-ensure_episode_data :- episode_title(_, _), !.
-ensure_episode_data :- update_episode_data.
-
-retract_episode(Ep) :-
- ( episode_title(Ep, _)
- -> retractall_episode_title(Ep, _)
- ; true
- ),
- ( episode_datum(Ep, 'Hint', _)
- -> retractall_episode_datum(Ep, 'Hint', _)
- ; true
- ).
-
-episode_count(N) :-
- setof(E, T^episode_title(E,T), Es),
- last(Es, N).
-
-rate_episode(Ep, 0) :-
- ( episode_rating(Ep, _)
- -> retractall_episode_rating(Ep, _)
- ; true
- ),
- !.
-
-rate_episode(Ep, R) :-
- dif(R, 0),
- ( episode_rating(Ep, R)
- -> true
- ; ( episode_rating(Ep, _)
- -> retractall_episode_rating(Ep, _)
- ; true
- ),
- assert_episode_rating(Ep, R)
- ).
-
-open_episode_wiki(Ep) :-
- episode_wiki(Ep, W),
- win_shell(open, W).
-
-tv_original(Ep) :- episode_datum(Ep, 'Source', 'TV Original').
-
-% Remote data retrieval.
-
-absolute_url(R) --> "https://www.detectiveconanworld.com", R.
-
-thread_running(T) :- thread_property(T, status(running)).
-thread_exception(T, E) :- thread_property(T, status(exception(E))).
-
-update_episode_data :-
- findall(Ep-Info,
- (fetch_episode_info(Ep, Info)),
- Set),
- maplist(set_episode_info, Set).
-
-set_episode_info(Ep-Info) :-
- maplist(set_episode_datum(Ep), Info).
-
-set_episode_datum(Ep, 'Title'-Title) :- !,
- maybe_assert_episode_title(Ep, Title).
-set_episode_datum(Ep, 'Wiki'-W) :- !,
- maybe_assert_episode_wiki(Ep, W).
-set_episode_datum(Ep, Key-Value) :-
- maybe_assert_episode_datum(Ep, Key, Value).
-
-maybe_assert_episode_title(Ep, Title) :-
- ( episode_title(Ep, Title), !
- ; assert_episode_title(Ep, Title)
- ).
-
-maybe_assert_episode_wiki(Ep, W) :-
- ( episode_wiki(Ep, W), !
- ; assert_episode_wiki(Ep, W)
- ).
-
-maybe_assert_episode_datum(Ep, Key, Value) :-
- ( episode_datum(Ep, Key, Value), !
- ; ( episode_datum(Ep, Key, _)
- -> retract_episode_datum(Ep, Key, _)
- ; true
- ),
- assert_episode_datum(Ep, Key, Value)
- ).
-
-episode_number(Ep) --> integer(Ep).
-episode_number(Ep) --> integer(Ep), "WPS", integer(_).
-
-% Temporary helper.
-fetch_episode_data(Ep, Title, W, Date, Source, Hint) :-
- fetch_episode_info(Ep, ['Title'-Title, 'Wiki'-W, 'Date'-Date, 'Source'-Source, 'Hint'-Hint]).
-
-fetch_episode_info(Ep, ['Title'-Title, 'Wiki'-W, 'Date'-Date, 'Source'-Source, 'Hint'-Hint]) :-
- cached_html('https://www.detectiveconanworld.com/wiki/Anime', H),
- xpath(H, //tr(td(index(3),@style='background:#f2fde9;')), R),
- xpath(R, td(index(1),normalize_space), Ep0),
- atom_phrase(episode_number(Ep), Ep0),
- xpath(R, td(index(3),normalize_space), Title),
- xpath(R, td(index(3))/a(@href), W0),
- atom_phrase(absolute_url(W0), W),
- xpath(R, td(index(4),normalize_space), Date),
- xpath(R, td(index(7),normalize_space), Source0),
- re_replace('\\(([0-9])', ' (\\1', Source0, Source1),
- atom_string(Source, Source1),
- xpath(R, td(index(8),normalize_space), Hint).
-
-update_screenwriters :-
- findall(Ep-Name,
- (maybe_fetch_screenwriter_episode(Name, Ep)),
- Set),
- maplist(set_episode_screenwriter, Set).
-
-set_episode_screenwriter(Ep-Name) :-
- maybe_assert_episode_datum(Ep, 'Screenwriter', Name).
-
-maybe_fetch_screenwriter_episode(Name, Ep) :-
- \+ episode_datum(Ep, 'Screenwriter', Ep),
- fetch_screenwriter_episode(Name, Ep).
-
-fetch_screenwriter(Name) :-
- cached_html('https://www.detectiveconanworld.com/wiki/Category:Screenplay_writers', H),
- xpath(H, //'div'(@id='mw-pages')//a, A),
- xpath(A, /self(normalize_space), Name).
-
-fetch_screenwriter_url(Name, U) :-
- cached_html('https://www.detectiveconanworld.com/wiki/Category:Screenplay_writers', H),
- xpath(H, //'div'(@id='mw-pages')//a, A),
- xpath(A, /self(normalize_space), Name),
- xpath(A, /self(@href), U).
-
-screenwriter_episode(Ep) --> string(_), "(Episode ", integer(Ep), ")".
-screenwriter_episode(Ep) --> string(_), "(Episodes ", integer(Ep1), "-", integer(Ep2), ")",
- { between(Ep1, Ep2, Ep) }.
-screenwriter_episode(Ep) --> string(_), "(Episodes ", integer(Ep1), "-", integer(Ep2), " only)",
- { between(Ep1, Ep2, Ep) }.
-
-fetch_screenwriter_episode(Name, Ep) :-
- fetch_screenwriter_url(Name, U0),
- atom_phrase(absolute_url(U0), U),
- cached_html(U, H),
- xpath(H, //div(@id='mw-content-text')//li, L),
- xpath(L, /self(normalize_space), T),
- atom_phrase(screenwriter_episode(Ep), T).
-
-fetch_html(U, H) :-
- catch(http_load_html(U, H), _, fail),
- !,
- nb_setval(U, H).
-
-cached_html(U, H) :- nb_current(U, H), !.
-cached_html(U, H) :- fetch_html(U, H).
-
-http_load_html(URL, DOM) :-
- setup_call_cleanup(http_open(URL, In,
- [ timeout(60)
- ]),
- ( dtd(html, DTD),
- load_structure(stream(In),
- DOM,
- [ dtd(DTD),
- dialect(sgml),
- shorttag(false),
- max_errors(-1),
- syntax_errors(quiet)
- ])
- ),
- close(In)).
diff --git a/pl/local_episodes.pl b/pl/local_episodes.pl
deleted file mode 100644
index 68809a7..0000000
--- a/pl/local_episodes.pl
+++ /dev/null
@@ -1,50 +0,0 @@
-:- module(local_episodes, [local_episode//1,
- episode_file/2,
- open_episode_locally/1,
- open_episode_online/1]).
-
-:- use_module(library(dcg/basics)).
-:- use_module(atom_dcg).
-:- use_module(cfg).
-
-local_episode_prefix --> string(_), "Detective_Conan_-_".
-local_episode_prefix --> string(_), "Detective Conan - ".
-local_episode_prefix --> string(_), "Detective-Conan-".
-local_episode_prefix --> string(_), "detective_conan_".
-
-nondigit --> [C], !, { \+ code_type(C, digit) }.
-nondigit --> [].
-
-zeroes --> "0".
-zeroes --> "0", zeroes.
-
-paddedint(N) --> integer(N).
-paddedint(N) --> zeroes, integer(N).
-
-local_episode -->
- local_episode(_).
-local_episode(N) -->
- local_episode_prefix, paddedint(N), nondigit, string(_).
-local_episode(N) -->
- local_episode_prefix, paddedint(First), "-", paddedint(Last), nondigit, string(_),
- { Second is First + 1, between(Second, Last, N) }.
-
-% Find episode on disk.
-
-episode_file(N, F) :-
- get_root(R),
- get_glob(G),
- atomic_list_concat([R, '/', G], G1),
- expand_file_name(G1, F1),
- ( nonvar(N)
- -> include(atom_phrase(local_episode(N)), F1, [F|_])
- ; include(atom_phrase(local_episode), F1, F2),
- member(F, F2),
- atom_phrase(local_episode(N), F)
- ).
-
-% Open episode.
-
-episode_url(N) --> { with_codes(get_url(U)) }, string(U), integer(N).
-open_episode_locally(N) :- episode_file(N, F), !, win_shell(open, F).
-open_episode_online(N) :- atom_phrase(episode_url(N), U), win_shell(open, U).
diff --git a/pl/track_episodes.pl b/pl/track_episodes.pl
deleted file mode 100644
index 1973a75..0000000
--- a/pl/track_episodes.pl
+++ /dev/null
@@ -1,112 +0,0 @@
-:- 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)
- ).