mirror of
https://github.com/aquatix/digimarks.git
synced 2025-12-06 22:05:09 +01:00
Only fetch new bookmarks and tags when cache is not up-to-date
This commit is contained in:
@@ -19,7 +19,7 @@ from fastapi.staticfiles import StaticFiles
|
||||
from fastapi.templating import Jinja2Templates
|
||||
from pydantic import AnyUrl, DirectoryPath, FilePath
|
||||
from pydantic_settings import BaseSettings
|
||||
from sqlmodel import AutoString, Field, Session, SQLModel, create_engine, select
|
||||
from sqlmodel import AutoString, Field, Session, SQLModel, create_engine, desc, select
|
||||
|
||||
DIGIMARKS_USER_AGENT = 'digimarks/2.0.0-dev'
|
||||
DIGIMARKS_VERSION = '2.0.0a1'
|
||||
@@ -381,7 +381,11 @@ def get_bookmark(
|
||||
url_hash: str,
|
||||
) -> Bookmark:
|
||||
"""Show bookmark details."""
|
||||
bookmark = session.exec(select(Bookmark).where(Bookmark.userkey == user_key, Bookmark.url_hash == url_hash)).first()
|
||||
bookmark = session.exec(
|
||||
select(Bookmark).where(
|
||||
Bookmark.userkey == user_key, Bookmark.url_hash == url_hash, Bookmark.status != Visibility.DELETED
|
||||
)
|
||||
).first()
|
||||
# bookmark = session.get(Bookmark, {'url_hash': url_hash, 'userkey': user_key})
|
||||
return bookmark
|
||||
|
||||
@@ -450,13 +454,42 @@ def delete_bookmark(
|
||||
return {'ok': True}
|
||||
|
||||
|
||||
@app.get('/api/v1/{user_key}/latest_changes/')
|
||||
def bookmarks_changed_since(
|
||||
session: SessionDep,
|
||||
user_key: str,
|
||||
):
|
||||
"""Last update on server, so the (browser) client knows whether to fetch an update."""
|
||||
latest_modified_bookmark = session.exec(
|
||||
select(Bookmark)
|
||||
.where(Bookmark.userkey == user_key, Bookmark.status != Visibility.DELETED)
|
||||
.order_by(desc(Bookmark.modified_date))
|
||||
).first()
|
||||
latest_created_bookmark = session.exec(
|
||||
select(Bookmark)
|
||||
.where(Bookmark.userkey == user_key, Bookmark.status != Visibility.DELETED)
|
||||
.order_by(desc(Bookmark.created_date))
|
||||
).first()
|
||||
|
||||
latest_modification = max(latest_modified_bookmark.modified_date, latest_created_bookmark.created_date)
|
||||
|
||||
return {
|
||||
'current_time': datetime.now(UTC),
|
||||
'latest_change': latest_modified_bookmark.modified_date,
|
||||
'latest_created': latest_created_bookmark.created_date,
|
||||
'latest_modification': latest_modification,
|
||||
}
|
||||
|
||||
|
||||
@app.get('/api/v1/{user_key}/tags/')
|
||||
def list_tags_for_user(
|
||||
session: SessionDep,
|
||||
user_key: str,
|
||||
) -> list[str]:
|
||||
"""List all tags in use by the user."""
|
||||
bookmarks = session.exec(select(Bookmark).where(Bookmark.userkey == user_key)).all()
|
||||
bookmarks = session.exec(
|
||||
select(Bookmark).where(Bookmark.userkey == user_key, Bookmark.status != Visibility.DELETED)
|
||||
).all()
|
||||
tags = []
|
||||
for bookmark in bookmarks:
|
||||
tags += bookmark.tags_list
|
||||
|
||||
@@ -9,12 +9,18 @@ document.addEventListener('alpine:init', () => {
|
||||
bookmarks: [],
|
||||
tags: [],
|
||||
|
||||
tryout: 'hey',
|
||||
|
||||
/* Loading indicator */
|
||||
loading: false,
|
||||
|
||||
/* Search filter */
|
||||
search: '',
|
||||
|
||||
/* Sort on ~ */
|
||||
sort_title_asc: Alpine.$persist(false).as('sort_title_asc'),
|
||||
sort_title_desc: Alpine.$persist(false).as('sort_title_desc'),
|
||||
sort_created_asc: Alpine.$persist(false).as('sort_created_asc'),
|
||||
sort_created_desc: Alpine.$persist(false).as('sort_created_desc'),
|
||||
|
||||
async init() {
|
||||
/** Initialise the application after loading */
|
||||
// if (this.userKey in this.cache) {
|
||||
@@ -28,28 +34,47 @@ document.addEventListener('alpine:init', () => {
|
||||
}, 1000);
|
||||
},
|
||||
async loadCache() {
|
||||
if (this.userKey in this.cache) {
|
||||
console.log('Loading bookmarks from cache for user "' + this.userKey + '"');
|
||||
this.bookmarks = this.cache[this.userKey]['bookmarks'] || [];
|
||||
|
||||
}
|
||||
},
|
||||
async getBookmarks() {
|
||||
/** Get the bookmarks from the backend */
|
||||
this.loading = true;
|
||||
if (!(this.userKey in this.cache)) {
|
||||
/* There is no cache for this userKey yet, create on */
|
||||
console.log('Creating cache for user "' + this.userKey + '"');
|
||||
this.cache[this.userKey] = {'bookmarks': [], 'latest_changes': {}};
|
||||
}
|
||||
|
||||
let latest_status_response = await fetch('/api/v1/' + this.userKey + '/latest_changes/');
|
||||
let latest_status_result = await latest_status_response.json();
|
||||
let should_fetch = false;
|
||||
let latest_modification_in_cache = this.cache[this.userKey].latest_changes.latest_modification || "0000-00-00";
|
||||
should_fetch = latest_status_result.latest_modification > latest_modification_in_cache;
|
||||
this.cache[this.userKey].latest_changes = latest_status_result;
|
||||
|
||||
if (!should_fetch) {
|
||||
console.log('Cache is up-to-date');
|
||||
this.loading = false;
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Fetching latest bookmarks from backend for user "' + this.userKey + '"...');
|
||||
let response = await fetch('/api/v1/' + this.userKey + '/bookmarks/?limit=10000');
|
||||
let result = await response.json();
|
||||
console.log(result);
|
||||
this.bookmarks = result;
|
||||
if (!(this.userKey in this.cache)) {
|
||||
/* There is no cache for this userKey yet, create on */
|
||||
console.log('caching');
|
||||
this.cache[this.userKey] = {'bookmarks': []};
|
||||
}
|
||||
/* Cache the bookmarks to Local Storage */
|
||||
this.cache[this.userKey]['bookmarks'] = result;
|
||||
|
||||
let tags_response = await fetch('/api/v1/' + this.userKey + '/tags/');
|
||||
let tags_result = await tags_response.json();
|
||||
this.cache[this.userKey]['tags'] = tags_result;
|
||||
|
||||
this.loading = false;
|
||||
},
|
||||
get filteredItems() {
|
||||
get filteredBookmarks() {
|
||||
// return this.cache[this.userKey]['bookmarks'].filter(
|
||||
// i => i.title.includes(this.search)
|
||||
// )
|
||||
@@ -58,6 +83,11 @@ document.addEventListener('alpine:init', () => {
|
||||
i => i.title.match(new RegExp(this.search, "i"))
|
||||
)
|
||||
},
|
||||
get filteredTags() {
|
||||
return this.cache[this.userKey].tags.filter(
|
||||
i => i.match(new RegExp(this.search, "i"))
|
||||
)
|
||||
},
|
||||
async sortAlphabetically(order = 'asc') {
|
||||
if (order === 'desc') {
|
||||
this.bookmarks.sort((a, b) => b.title.localeCompare(a.title));
|
||||
|
||||
@@ -31,10 +31,17 @@
|
||||
</p>
|
||||
|
||||
<ul x-cloak>
|
||||
<template x-for="bookmark in $store.digimarks.filteredItems" :key="bookmark.id">
|
||||
<template x-for="bookmark in $store.digimarks.filteredBookmarks" :key="bookmark.id">
|
||||
<li><a x-text="bookmark.title" x-bind:href="bookmark.url" target="_blank"></a></li>
|
||||
</template>
|
||||
</ul>
|
||||
|
||||
<h2>tags</h2>
|
||||
<ul x-cloak>
|
||||
<template x-for="tag in $store.digimarks.filteredTags" :key="tag">
|
||||
<li x-text="tag"></li>
|
||||
</template>
|
||||
</ul>
|
||||
</main>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user