Implement bookmark export

This commit is contained in:
Sascha Ißbrücker 2019-12-26 13:45:12 +01:00
parent 1f7ccb214a
commit 991025d13e
4 changed files with 74 additions and 3 deletions

View File

@ -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('<!DOCTYPE NETSCAPE-Bookmark-file-1>')
doc.append('<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">')
doc.append('<TITLE>Bookmarks</TITLE>')
doc.append('<H1>Bookmarks</H1>')
def append_list_start(doc: BookmarkDocument):
doc.append('<DL><p>')
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'<DT><A HREF="{url}" ADD_DATE="{added}" PRIVATE="0" TOREAD="{toread}" TAGS="{tags}">{title}</A>')
if desc:
doc.append(f'<DD>{desc}')
def append_list_end(doc: BookmarkDocument):
doc.append('</DL><p>')

View File

@ -39,7 +39,14 @@
<h2>Export</h2> <h2>Export</h2>
</div> </div>
<p>Export all bookmarks in Netscape HTML format.</p> <p>Export all bookmarks in Netscape HTML format.</p>
<a class="btn btn-primary">Download (.html)</a> <a class="btn btn-primary" href="{% url 'bookmarks:settings.export' %}">Download (.html)</a>
{% if export_error %}
<div class="has-error">
<p class="form-input-hint">
{{ export_error }}
</p>
</div>
{% endif %}
</section> </section>
</div> </div>

View File

@ -18,6 +18,7 @@ urlpatterns = [
# Settings # Settings
path('settings', views.settings.index, name='settings.index'), path('settings', views.settings.index, name='settings.index'),
path('settings/import', views.settings.bookmark_import, name='settings.import'), path('settings/import', views.settings.bookmark_import, name='settings.import'),
path('settings/export', views.settings.bookmark_export, name='settings.export'),
# API # API
path('api/website_metadata', views.api.website_metadata, name='api.website_metadata'), path('api/website_metadata', views.api.website_metadata, name='api.website_metadata'),
] ]

View File

@ -1,9 +1,11 @@
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.decorators import login_required 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.shortcuts import render
from django.urls import reverse 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 from bookmarks.services.importer import import_netscape_html
@ -22,13 +24,30 @@ def bookmark_import(request):
content = import_file.read() content = import_file.read()
import_netscape_html(content, request.user) import_netscape_html(content, request.user)
messages.success(request, 'Bookmarks were successfully imported.', 'bookmark_import') messages.success(request, 'Bookmarks were successfully imported.', 'bookmark_import')
except(): except Exception:
messages.error(request, 'An error occurred during bookmark import.', 'bookmark_import') messages.error(request, 'An error occurred during bookmark import.', 'bookmark_import')
pass pass
return HttpResponseRedirect(reverse('bookmarks:settings.index')) 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): def _find_message_with_tag(messages, tag):
for message in messages: for message in messages:
if message.extra_tags == tag: if message.extra_tags == tag: