From e8c553e5d898b6ceb69dc0d1c7f4793f96cb685b Mon Sep 17 00:00:00 2001 From: xenofem Date: Sun, 3 Mar 2024 02:14:56 -0500 Subject: [PATCH 1/3] add suggested works (next step: make useful suggestions) --- dlibrary/dlibrary.py | 8 +++++--- dlibrary/static/dlibrary.css | 7 ++++++- dlibrary/static/index.js | 2 +- dlibrary/templates/categorization.html | 2 +- dlibrary/templates/index.html | 2 +- dlibrary/templates/list.html | 16 +++------------- dlibrary/templates/utils.html | 14 ++++++++++++++ dlibrary/templates/viewer.html | 4 ++-- dlibrary/templates/work.html | 8 +++++++- 9 files changed, 40 insertions(+), 23 deletions(-) diff --git a/dlibrary/dlibrary.py b/dlibrary/dlibrary.py index 82cf74f..3498072 100755 --- a/dlibrary/dlibrary.py +++ b/dlibrary/dlibrary.py @@ -865,16 +865,18 @@ def generate(args): 'authors': authors, 'tags': tags, 'thumbnail_path': thumbnail_path, + 'images': images, } works.append(work) - work_dir = site_dir / 'works' / work_id + for work in works: + work_dir = site_dir / 'works' / work['id'] viewer_dir = work_dir / 'view' viewer_dir.mkdir(parents=True, exist_ok=True) with open(work_dir / 'index.html', 'w') as f: - f.write(work_template.render(depth=2, work=work, title=title, images=images)) + f.write(work_template.render(depth=2, work=work, title=work['title'], suggested=works[:5])) with open(viewer_dir / 'index.html', 'w') as f: - f.write(viewer_template.render(depth=3, work=work, title=title, images=images)) + f.write(viewer_template.render(depth=3, work=work, title=work['title'])) def make_categorization(categorization, query, work_filter, work_style_cards=False): categorization_dir = site_dir / categorization diff --git a/dlibrary/static/dlibrary.css b/dlibrary/static/dlibrary.css index fc6aa0b..00c1846 100644 --- a/dlibrary/static/dlibrary.css +++ b/dlibrary/static/dlibrary.css @@ -78,7 +78,7 @@ body { margin-bottom: 25px; } -#card-listing { +.card-listing { display: flex; flex-wrap: wrap; justify-content: center; @@ -115,6 +115,7 @@ body { flex-wrap: wrap; justify-content: center; gap: 30px; + margin-bottom: 40px; } .work-preview { @@ -157,3 +158,7 @@ body { display: inline-block; margin-bottom: 5px; } + +#suggested-subheader { + text-align: center; +} diff --git a/dlibrary/static/index.js b/dlibrary/static/index.js index 2ea74f5..f818247 100644 --- a/dlibrary/static/index.js +++ b/dlibrary/static/index.js @@ -32,7 +32,7 @@ document.addEventListener('DOMContentLoaded', () => { const shuffleButton = document.getElementById('shuffle'); const sortButton = document.getElementById('sort'); const searchBox = document.getElementById('search'); - const listContainer = document.getElementById('card-listing'); + const listContainer = document.getElementById('main-listing'); let ordering = localStorage.getItem('indexOrdering') || 'dateDesc'; let shuffleSeed = parseInt(localStorage.getItem('shuffleSeed')) || newSeed(); diff --git a/dlibrary/templates/categorization.html b/dlibrary/templates/categorization.html index 40e6817..75a4c8b 100644 --- a/dlibrary/templates/categorization.html +++ b/dlibrary/templates/categorization.html @@ -4,7 +4,7 @@ {% from 'utils.html' import urlcat, index, root with context %}

DLibrary > {{ categorization.capitalize() }}

{% include 'nav.html' %} -
+
{% for cat in categories %}
diff --git a/dlibrary/templates/index.html b/dlibrary/templates/index.html index 836539f..fa432a9 100644 --- a/dlibrary/templates/index.html +++ b/dlibrary/templates/index.html @@ -23,6 +23,6 @@
-
+
{% endblock %} diff --git a/dlibrary/templates/list.html b/dlibrary/templates/list.html index 940ca91..fb68cf0 100644 --- a/dlibrary/templates/list.html +++ b/dlibrary/templates/list.html @@ -1,21 +1,11 @@ {% extends 'base.html' %} {% block body %} -{% from 'utils.html' import index, root with context %} +{% from 'utils.html' import index, root, card with context %}

DLibrary{% if categorization %} > {{ categorization.capitalize() }}{% endif %}{% if title %} > {{ title }}{% endif %}

{% include 'nav.html' %} -
+ {% endblock %} diff --git a/dlibrary/templates/utils.html b/dlibrary/templates/utils.html index 161dc38..d0caf65 100644 --- a/dlibrary/templates/utils.html +++ b/dlibrary/templates/utils.html @@ -1,3 +1,17 @@ {% macro root() %}{% if depth == 0 %}.{% else %}..{% endif %}{{ '/..' * (depth-1) }}{% endmacro %} {% macro index() %}{% if not noindex %}index.html{% endif %}{% endmacro %} {% macro urlcat(s) %}{{ s | replace('/', ' ') | urlencode }}{% endmacro %} + +{% macro card(work) %} + +{% endmacro %} diff --git a/dlibrary/templates/viewer.html b/dlibrary/templates/viewer.html index aee53e8..9125ab2 100644 --- a/dlibrary/templates/viewer.html +++ b/dlibrary/templates/viewer.html @@ -6,7 +6,7 @@ const WORK_ID = "{{ work['id'] }}"; const INDEX = "{{ index() }}"; const IMAGES = [ - {% for filename in images %} + {% for filename in work['images'] %} "{{ root() }}/images/{{ work['id'] }}/{{ filename }}", {% endfor %} ]; @@ -18,7 +18,7 @@
- +
{{ images | length }}
{{ work['images'] | length }}
diff --git a/dlibrary/templates/work.html b/dlibrary/templates/work.html index c2860fa..e622c0b 100644 --- a/dlibrary/templates/work.html +++ b/dlibrary/templates/work.html @@ -1,6 +1,6 @@ {% extends 'base.html' %} {% block body %} -{% from 'utils.html' import urlcat, root, index with context %} +{% from 'utils.html' import urlcat, root, index, card with context %}

DL > {{ title }}

@@ -41,4 +41,10 @@ {% endif %}
+

Suggested works

+
+ {% for sugg in suggested %} + {{ card(sugg) }} + {% endfor %} +
{% endblock %} From f994060149f68a1205e59dae9e99868ac12acd10 Mon Sep 17 00:00:00 2001 From: xenofem Date: Sun, 3 Mar 2024 02:56:46 -0500 Subject: [PATCH 2/3] suggest works with similar titles that aren't already in the same series --- dlibrary/dlibrary.py | 55 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/dlibrary/dlibrary.py b/dlibrary/dlibrary.py index 3498072..03f7f4e 100755 --- a/dlibrary/dlibrary.py +++ b/dlibrary/dlibrary.py @@ -821,6 +821,47 @@ def copy_recursive(src, dest): else: shutil.copyfile(item, dest / item.name) + +memoized_similarities = {} + +def similarity(a, b): + if len(a) < len(b): + shorter = a + longer = b + else: + shorter = b + longer = a + if len(shorter) == 0: + return 0 + + if (shorter, longer) in memoized_similarities: + return memoized_similarities[(shorter, longer)] + + skip_similarity = similarity(shorter[1:], longer) + match_idx = longer.find(shorter[0]) + if match_idx == -1: + result = skip_similarity + else: + take_similarity = 1 + similarity(shorter[1:], longer[match_idx+1:]) + result = max(skip_similarity, take_similarity) + + memoized_similarities[(shorter, longer)] = result + return result + +def top(items, n, key): + if len(items) == 0: + return [] + winners = items[:1] + for item in items[1:]: + if len(winners) < n or key(item) > key(winners[-1]): + for i in range(len(winners)): + if key(item) > key(winners[i]): + winners.insert(i, item) + break + if len(winners) > n: + winners.pop() + return winners + def generate(args): jenv = Environment( loader=PackageLoader("dlibrary"), @@ -869,15 +910,25 @@ def generate(args): } works.append(work) - for work in works: + for (idx, work) in enumerate(works): + def suggestion_priority(other_work): + if other_work is work: + return -2 + if work['series'] and work['series'] == other_work['series']: + return -1 + return similarity(work['title'], other_work['title']) + suggested = top(works, 6, suggestion_priority) + work_dir = site_dir / 'works' / work['id'] viewer_dir = work_dir / 'view' viewer_dir.mkdir(parents=True, exist_ok=True) with open(work_dir / 'index.html', 'w') as f: - f.write(work_template.render(depth=2, work=work, title=work['title'], suggested=works[:5])) + f.write(work_template.render(depth=2, work=work, title=work['title'], suggested=suggested)) with open(viewer_dir / 'index.html', 'w') as f: f.write(viewer_template.render(depth=3, work=work, title=work['title'])) + print(f'\x1b[2K\r{idx+1}/{len(works)} works processed...', end='') + def make_categorization(categorization, query, work_filter, work_style_cards=False): categorization_dir = site_dir / categorization From 42b49c7ecc0b22b0f35d61250900bc0aef1c0c46 Mon Sep 17 00:00:00 2001 From: xenofem Date: Sun, 3 Mar 2024 03:21:53 -0500 Subject: [PATCH 3/3] prioritize matches with more consecutive characters --- dlibrary/dlibrary.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dlibrary/dlibrary.py b/dlibrary/dlibrary.py index 03f7f4e..97d657c 100755 --- a/dlibrary/dlibrary.py +++ b/dlibrary/dlibrary.py @@ -837,13 +837,13 @@ def similarity(a, b): if (shorter, longer) in memoized_similarities: return memoized_similarities[(shorter, longer)] - skip_similarity = similarity(shorter[1:], longer) - match_idx = longer.find(shorter[0]) - if match_idx == -1: - result = skip_similarity - else: - take_similarity = 1 + similarity(shorter[1:], longer[match_idx+1:]) - result = max(skip_similarity, take_similarity) + options = [similarity(shorter[1:], longer)] + for i in range(1, len(shorter)+1): + match_idx = longer.find(shorter[:i]) + if match_idx == -1: + break + options.append(i*i + similarity(shorter[i:], longer[match_idx+i:])) + result = max(options) memoized_similarities[(shorter, longer)] = result return result