Implement bookmark export
This commit is contained in:
parent
1f7ccb214a
commit
991025d13e
44
bookmarks/services/exporter.py
Normal file
44
bookmarks/services/exporter.py
Normal 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>')
|
@ -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>
|
||||||
|
@ -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'),
|
||||||
]
|
]
|
||||||
|
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user