Skip to content

Commit

Permalink
modify html, check library changes, TUI editor
Browse files Browse the repository at this point in the history
  • Loading branch information
Parzival1918 committed Sep 30, 2024
1 parent 17c4e3a commit b9e9066
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 29 deletions.
12 changes: 8 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# Changelog

## v0.3.1
## v0.3.2

Released on 2024-09-18.
Released on

- Update the minimum python version to 3.11.
- `check library` command now ignores the `.git` folder.
- Modify html output of `html` command.
- Margins are smaller in mobile devices.
- Can now show notes by folder.
- In the TUI, the editor for the entry and note is taken from the `EDITOR` environment variable. If not set, it raises a warning.

Pypi: https://pypi.org/project/bibmancli/0.3.1/
Pypi: https://pypi.org/project/bibmancli/0.3.2/
12 changes: 4 additions & 8 deletions requirements-dev.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
# all-features: false
# with-sources: false
# generate-hashes: false
# universal: false

-e file:.
babel==2.16.0
Expand All @@ -24,7 +25,7 @@ cachecontrol==0.14.0
certifi==2024.7.4
# via requests
cffi==1.17.1
# via cryptography
# via xattr
charset-normalizer==3.3.2
# via requests
cleo==2.1.0
Expand All @@ -37,8 +38,6 @@ colorama==0.4.6
crashtest==0.4.1
# via cleo
# via poetry
cryptography==43.0.1
# via secretstorage
distlib==0.3.8
# via virtualenv
dulwich==0.21.7
Expand All @@ -60,9 +59,6 @@ installer==0.7.0
# via poetry
jaraco-classes==3.4.0
# via keyring
jeepney==0.8.0
# via keyring
# via secretstorage
jinja2==3.1.4
# via mkdocs
# via mkdocs-material
Expand Down Expand Up @@ -169,8 +165,6 @@ requests-toolbelt==1.0.0
rich==13.7.1
# via textual
# via typer
secretstorage==3.3.3
# via keyring
shellingham==1.5.4
# via poetry
# via typer
Expand Down Expand Up @@ -201,3 +195,5 @@ virtualenv==20.26.5
# via poetry
watchdog==4.0.2
# via mkdocs
xattr==1.1.0
# via poetry
1 change: 1 addition & 0 deletions requirements.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
# all-features: false
# with-sources: false
# generate-hashes: false
# universal: false

-e file:.
beautifulsoup4==4.13.0b2
Expand Down
4 changes: 4 additions & 0 deletions src/bibmancli/subcommands/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ def library(
# skip _site folder
continue

if root.name == ".git":
# skip .git folder
continue

for name in files:
filepath = root / name

Expand Down
30 changes: 17 additions & 13 deletions src/bibmancli/tui.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from textual.containers import Horizontal, Vertical
from pathlib import Path
from typing import Iterable
from os import system
from os import system, environ


class FilenameTree(DirectoryTree):
Expand Down Expand Up @@ -98,14 +98,16 @@ def action_edit_file(self) -> None:
return

# get environment variable EDITOR
# editor = environ.get("EDITOR", None)
# if editor:
# self.notify("EDITOR environment variable not set", severity="warning")
# return
editor = environ.get("EDITOR", None)
if not editor:
self.notify(
"EDITOR environment variable not set", severity="warning"
)
return

with self.suspend():
# system(f"{editor} {main_pane.save_path}")
system(f"vim {main_pane.save_path}")
system(f"{editor} {main_pane.save_path}")
# system(f"vim {main_pane.save_path}")

main_pane.update_text(main_pane.save_path)

Expand All @@ -116,18 +118,20 @@ def action_edit_note(self) -> None:
return

# get environment variable EDITOR
# editor = environ.get("EDITOR", None)
# if editor:
# self.notify("EDITOR environment variable not set", severity="warning")
# return
editor = environ.get("EDITOR", None)
if not editor:
self.notify(
"EDITOR environment variable not set", severity="warning"
)
return

filename = main_pane.save_path.name
notename = "." + filename.replace(".bib", ".txt")
notepath = main_pane.save_path.parent / notename

with self.suspend():
# system(f"{editor} {main_pane.save_path}")
system(f"vim {notepath}")
system(f"{editor} {notepath}")
# system(f"vim {notepath}")

main_pane.update_text(main_pane.save_path)

Expand Down
92 changes: 88 additions & 4 deletions src/bibmancli/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,35 @@ def entries_as_json_string(
return json.dumps(json_entries, indent=4, ensure_ascii=False)


def folder_list_html(entries: Iterable[Entry], library_location: Path) -> str:
"""
Create an HTML list of folders containing the entries
:param entries: Entries to list
:type entries: Iterable[Entry]
:param library_location: Location of the library
:type library_location: Path
:return: HTML string
:rtype: str
"""
folders = {}
total_count = 0
for entry in entries:
folder = entry.path.parent
total_count += 1
if folder not in folders:
folders[folder] = 1
else:
folders[folder] += 1

html = ""
html += f'<option selected value="all">All entries ({total_count} entries)</option>'
for folder, count in folders.items():
html += f'<option value="{folder.relative_to(library_location).as_posix()}">{folder.relative_to(library_location).as_posix()} ({count} entries)</option>'

return html


def create_html(location: Path) -> str:
"""
Create an HTML page to display the library entries
Expand All @@ -253,6 +282,7 @@ def create_html(location: Path) -> str:
:rtype: str
"""
json_string = entries_as_json_string(iterate_files(location), location)
folder_list = folder_list_html(iterate_files(location), location)

html = (
"""
Expand All @@ -265,7 +295,7 @@ def create_html(location: Path) -> str:
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body>
<div class="container-md align-items-center justify-content-center px-5" id="main-container">
<div class="container-md align-items-center justify-content-center px-1 px-lg-5" id="main-container">
<div class="input-group my-3">
<input type="text" class="form-control" placeholder="Search" aria-label="Search" aria-describedby="button-clear" id="input-search">
<!--
Expand All @@ -274,6 +304,11 @@ def create_html(location: Path) -> str:
<button class="btn btn-outline-secondary" type="button" id="button-settings" data-bs-toggle="modal" data-bs-target="#settingsModal">Config</button>
<button class="btn btn-outline-secondary" type="button" id="button-clear" onclick="ClearClick()">Clear</button>
</div>
<select class="form-select my-3" id="selector" aria-label="Folder selection">
"""
+ folder_list
+ """
</select>
<div class="modal fade" id="entryModal" tabindex="-1" data-bs-backdrop="static" data-bs-keyboard="false" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
Expand Down Expand Up @@ -358,7 +393,7 @@ def create_html(location: Path) -> str:
// function to create HTML elements for each entry
function createEntryHTML(entry, i) {
let card = document.createElement("div");
card.className = "card my-4 bib-entry";
card.className = "card my-4 bib-entry ACTIVE";
card.id = entry.html_id;
let cardHeader = document.createElement("div");
cardHeader.className = "card-header text-body-secondary fs-6";
Expand Down Expand Up @@ -409,8 +444,17 @@ def create_html(location: Path) -> str:
// If the search bar is empty, show all entries
let search_string = searchInput.value;
// Use only entries that are currently displayed ACTIVE
let shownEntries = [];
for (let i = 0; i < bibEntries.length; i++) {
entry = bibEntries[i];
if (entry.classList.contains("ACTIVE")) {
shownEntries.push(entries[i]);
}
}
// Fuzzy search on multiple keys
let results = fuzzysort.go(search_string, entries, {keys: ["contents.title", "contents.author", "contents.note"], limit: 15, all: true});
let results = fuzzysort.go(search_string, shownEntries, {keys: ["contents.title", "contents.author", "contents.note"], limit: 15, all: true});
for (let i = 0; i < bibEntries.length; i++) {
bibEntries[i].style.display = "none";
}
Expand All @@ -422,13 +466,53 @@ def create_html(location: Path) -> str:
}
};
// Show entries from a specific folder when selected
let folderSelect = document.getElementById("selector");
folderSelect.addEventListener("change", function() {
// clear search bar
document.getElementById("input-search").value = "";
let selectedFolder = folderSelect.value;
for (let i = 0; i < bibEntries.length; i++) {
let entry = bibEntries[i];
if (selectedFolder === "all") {
entry.style.display = "block";
entry.classList.add("ACTIVE");
} else if (selectedFolder === ".") {
// show entries in the root folder, so entries with no "/" in their card-header
if (entry.getElementsByClassName("card-header")[0].innerText.indexOf("/") === -1) {
entry.style.display = "block";
entry.classList.add("ACTIVE");
} else {
entry.style.display = "none";
entry.classList.remove("ACTIVE");
}
} else {
if (entry.getElementsByClassName("card-header")[0].innerText.startsWith("Location: " + selectedFolder)) {
entry.style.display = "block";
entry.classList.add("ACTIVE");
} else {
entry.style.display = "none";
entry.classList.remove("ACTIVE");
}
}
}
});
searchInput.addEventListener("input", function () {
fuzzy();
});
function ClearClick() {
document.getElementById("input-search").value = "";
fuzzy();
// show entries with ACTIVE class
for (let i = 0; i < bibEntries.length; i++) {
let entry = bibEntries[i];
if (entry.classList.contains("ACTIVE")) {
entry.style.display = "block";
} else {
entry.style.display = "none";
}
}
};
</script>
</body>
Expand Down

0 comments on commit b9e9066

Please sign in to comment.