diff --git a/bookmarks/services/exporter.py b/bookmarks/services/exporter.py
new file mode 100644
index 0000000..459b6fe
--- /dev/null
+++ b/bookmarks/services/exporter.py
@@ -0,0 +1,44 @@
+from typing import List
+
+from bookmarks.models import Bookmark
+
+BookmarkDocument = List[str]
+
+
+def export_netscape_html(bookmarks: List[Bookmark]):
+ doc = []
+ append_header(doc)
+ append_list_start(doc)
+ [append_bookmark(doc, bookmark) for bookmark in bookmarks]
+ append_list_end(doc)
+
+ return '\n\r'.join(doc)
+
+
+def append_header(doc: BookmarkDocument):
+ doc.append('')
+ doc.append('')
+ doc.append('
Bookmarks')
+ doc.append('Bookmarks
')
+
+
+def append_list_start(doc: BookmarkDocument):
+ doc.append('')
+
+
+def append_bookmark(doc: BookmarkDocument, bookmark: Bookmark):
+ url = bookmark.url
+ title = bookmark.resolved_title
+ desc = bookmark.resolved_description
+ tags = ','.join(bookmark.tag_names)
+ toread = '1' if bookmark.unread else '0'
+ added = int(bookmark.date_added.timestamp())
+
+ doc.append(f'
- {title}')
+
+ if desc:
+ doc.append(f'
- {desc}')
+
+
+def append_list_end(doc: BookmarkDocument):
+ doc.append('
')
diff --git a/bookmarks/templates/settings/index.html b/bookmarks/templates/settings/index.html
index 150dbd1..30950b5 100644
--- a/bookmarks/templates/settings/index.html
+++ b/bookmarks/templates/settings/index.html
@@ -39,7 +39,14 @@
Export
Export all bookmarks in Netscape HTML format.
- Download (.html)
+ Download (.html)
+ {% if export_error %}
+
+
+ {{ export_error }}
+
+
+ {% endif %}
diff --git a/bookmarks/urls.py b/bookmarks/urls.py
index 7244a18..90b8487 100644
--- a/bookmarks/urls.py
+++ b/bookmarks/urls.py
@@ -18,6 +18,7 @@ urlpatterns = [
# Settings
path('settings', views.settings.index, name='settings.index'),
path('settings/import', views.settings.bookmark_import, name='settings.import'),
+ path('settings/export', views.settings.bookmark_export, name='settings.export'),
# API
path('api/website_metadata', views.api.website_metadata, name='api.website_metadata'),
]
diff --git a/bookmarks/views/settings.py b/bookmarks/views/settings.py
index e7bbf3d..d9552cc 100644
--- a/bookmarks/views/settings.py
+++ b/bookmarks/views/settings.py
@@ -1,9 +1,11 @@
from django.contrib import messages
from django.contrib.auth.decorators import login_required
-from django.http import HttpResponseRedirect
+from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import render
from django.urls import reverse
+from bookmarks.models import Bookmark
+from bookmarks.services.exporter import export_netscape_html
from bookmarks.services.importer import import_netscape_html
@@ -22,13 +24,30 @@ def bookmark_import(request):
content = import_file.read()
import_netscape_html(content, request.user)
messages.success(request, 'Bookmarks were successfully imported.', 'bookmark_import')
- except():
+ except Exception:
messages.error(request, 'An error occurred during bookmark import.', 'bookmark_import')
pass
return HttpResponseRedirect(reverse('bookmarks:settings.index'))
+@login_required
+def bookmark_export(request):
+ try:
+ bookmarks = Bookmark.objects.all()
+ file_content = export_netscape_html(bookmarks)
+
+ response = HttpResponse(content_type='text/plain; charset=UTF-8')
+ response['Content-Disposition'] = 'attachment; filename="bookmarks.html"'
+ response.write(file_content)
+
+ return response
+ except Exception:
+ return render(request, 'settings/index.html', {
+ 'export_error': 'An error occurred during bookmark export.'
+ })
+
+
def _find_message_with_tag(messages, tag):
for message in messages:
if message.extra_tags == tag: