mirror of
https://github.com/sissbruecker/linkding.git
synced 2025-08-15 06:29:21 +02:00
Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a867614461 | ||
![]() |
194f5884df | ||
![]() |
8e1cda1104 | ||
![]() |
f9659f4342 | ||
![]() |
6fab248c95 | ||
![]() |
b7676227c0 | ||
![]() |
0db7610d68 | ||
![]() |
be7b92d608 | ||
![]() |
256084f6cb |
18
API.md
18
API.md
@@ -59,7 +59,7 @@ Example response:
|
||||
}
|
||||
```
|
||||
|
||||
**List Archived**
|
||||
**Archived**
|
||||
|
||||
```
|
||||
GET /api/bookmarks/archived/
|
||||
@@ -121,22 +121,6 @@ Example payload:
|
||||
}
|
||||
```
|
||||
|
||||
**Archive**
|
||||
|
||||
```
|
||||
POST /api/bookmarks/<id>/archive/
|
||||
```
|
||||
|
||||
Archives a bookmark.
|
||||
|
||||
**Unarchive**
|
||||
|
||||
```
|
||||
POST /api/bookmarks/<id>/unarchive/
|
||||
```
|
||||
|
||||
Unarchives a bookmark.
|
||||
|
||||
**Delete**
|
||||
|
||||
```
|
||||
|
22
CHANGELOG.md
22
CHANGELOG.md
@@ -1,27 +1,5 @@
|
||||
# Changelog
|
||||
|
||||
## v1.3.2 (18/02/2021)
|
||||
- [**closed**] /archive and /unarchive API routes return 404 [#77](https://github.com/sissbruecker/linkding/issues/77)
|
||||
- [**closed**] API - /api/check_url?url= with token authetification [#55](https://github.com/sissbruecker/linkding/issues/55)
|
||||
|
||||
---
|
||||
|
||||
## v1.3.1 (15/02/2021)
|
||||
[enhancement] Enhance delete links with inline confirmation
|
||||
|
||||
---
|
||||
|
||||
## v1.3.0 (14/02/2021)
|
||||
- [**closed**] Novice help. [#71](https://github.com/sissbruecker/linkding/issues/71)
|
||||
- [**closed**] Option to create bookmarks public [#70](https://github.com/sissbruecker/linkding/issues/70)
|
||||
- [**enhancement**] Show URL if title is not available [#64](https://github.com/sissbruecker/linkding/issues/64)
|
||||
- [**bug**] minor ui nitpicks [#62](https://github.com/sissbruecker/linkding/issues/62)
|
||||
- [**enhancement**] add an archive function [#46](https://github.com/sissbruecker/linkding/issues/46)
|
||||
- [**closed**] remove non fqdn check and alert [#36](https://github.com/sissbruecker/linkding/issues/36)
|
||||
- [**closed**] Add Lotus Notes links [#22](https://github.com/sissbruecker/linkding/issues/22)
|
||||
|
||||
---
|
||||
|
||||
## v1.2.1 (12/01/2021)
|
||||
- [**bug**] Bug: Two equal tags with different capitalisation lead to 500 server errors [#65](https://github.com/sissbruecker/linkding/issues/65)
|
||||
- [**closed**] Enhancement: category and pagination [#11](https://github.com/sissbruecker/linkding/issues/11)
|
||||
|
@@ -1,4 +1,3 @@
|
||||
from django.urls import reverse
|
||||
from rest_framework import viewsets, mixins, status
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.response import Response
|
||||
@@ -7,8 +6,6 @@ from rest_framework.routers import DefaultRouter
|
||||
from bookmarks import queries
|
||||
from bookmarks.api.serializers import BookmarkSerializer, TagSerializer
|
||||
from bookmarks.models import Bookmark, Tag
|
||||
from bookmarks.services.bookmarks import archive_bookmark, unarchive_bookmark
|
||||
from bookmarks.services.website_loader import load_website_metadata
|
||||
|
||||
|
||||
class BookmarkViewSet(viewsets.GenericViewSet,
|
||||
@@ -42,37 +39,6 @@ class BookmarkViewSet(viewsets.GenericViewSet,
|
||||
data = serializer(page, many=True).data
|
||||
return self.get_paginated_response(data)
|
||||
|
||||
@action(methods=['post'], detail=True)
|
||||
def archive(self, request, pk):
|
||||
bookmark = self.get_object()
|
||||
archive_bookmark(bookmark)
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
@action(methods=['post'], detail=True)
|
||||
def unarchive(self, request, pk):
|
||||
bookmark = self.get_object()
|
||||
unarchive_bookmark(bookmark)
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
@action(methods=['get'], detail=False)
|
||||
def check(self, request):
|
||||
url = request.GET.get('url')
|
||||
bookmark = Bookmark.objects.filter(owner=request.user, url=url).first()
|
||||
existing_bookmark_data = None
|
||||
|
||||
if bookmark is not None:
|
||||
existing_bookmark_data = {
|
||||
'id': bookmark.id,
|
||||
'edit_url': reverse('bookmarks:edit', args=[bookmark.id])
|
||||
}
|
||||
|
||||
metadata = load_website_metadata(url)
|
||||
|
||||
return Response({
|
||||
'bookmark': existing_bookmark_data,
|
||||
'metadata': metadata.to_dict()
|
||||
}, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
class TagViewSet(viewsets.GenericViewSet,
|
||||
mixins.ListModelMixin,
|
||||
|
@@ -30,11 +30,8 @@ class BookmarkSerializer(serializers.ModelSerializer):
|
||||
'date_modified'
|
||||
]
|
||||
|
||||
# Override optional char fields to provide default value
|
||||
title = serializers.CharField(required=False, allow_blank=True, default='')
|
||||
description = serializers.CharField(required=False, allow_blank=True, default='')
|
||||
# Override readonly tag_names property to allow passing a list of tag names to create/update
|
||||
tag_names = TagListField(required=False, default=[])
|
||||
tag_names = TagListField()
|
||||
|
||||
def create(self, validated_data):
|
||||
bookmark = Bookmark()
|
||||
|
@@ -56,13 +56,6 @@ ul.bookmark-list {
|
||||
color: darken($gray-color, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
.actions .btn-link.bm-remove-confirm {
|
||||
color: $error-color;
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bookmark-pagination {
|
||||
|
@@ -32,7 +32,8 @@
|
||||
class="btn btn-link btn-sm">Archive</a>
|
||||
{% endif %}
|
||||
<a href="{% url 'bookmarks:remove' bookmark.id %}?return_url={{ return_url }}"
|
||||
class="btn btn-link btn-sm bm-remove">Remove</a>
|
||||
class="btn btn-link btn-sm"
|
||||
onclick="return confirm('Do you really want to delete this bookmark?')">Remove</a>
|
||||
</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
@@ -41,38 +42,3 @@
|
||||
<div class="bookmark-pagination">
|
||||
{% pagination bookmarks %}
|
||||
</div>
|
||||
|
||||
{# Enhance delete links to show inline confirmation #}
|
||||
<script type="application/javascript">
|
||||
window.addEventListener("load", function () {
|
||||
const linkEls = document.querySelectorAll('.bookmark-list a.bm-remove');
|
||||
|
||||
function showConfirmation(linkEl) {
|
||||
const cancelEl = document.createElement('span');
|
||||
cancelEl.innerText = 'Cancel';
|
||||
cancelEl.className = 'btn btn-link btn-sm bm-remove-confirm mr-1';
|
||||
cancelEl.addEventListener('click', function() {
|
||||
container.remove();
|
||||
linkEl.style = '';
|
||||
});
|
||||
|
||||
const confirmEl = document.createElement('a');
|
||||
confirmEl.innerText = 'Confirm';
|
||||
confirmEl.className = 'btn btn-link btn-delete btn-sm bm-remove-confirm';
|
||||
confirmEl.href = linkEl.href;
|
||||
|
||||
const container = document.createElement('span');
|
||||
container.appendChild(cancelEl);
|
||||
container.appendChild(confirmEl);
|
||||
linkEl.parentElement.appendChild(container);
|
||||
linkEl.style = 'display: none';
|
||||
}
|
||||
|
||||
linkEls.forEach(function (linkEl) {
|
||||
linkEl.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
showConfirmation(linkEl);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
@@ -97,7 +97,7 @@
|
||||
toggleIcon(descriptionInput, true);
|
||||
|
||||
const websiteUrl = encodeURIComponent(urlInput.value);
|
||||
const requestUrl = `{% url 'bookmarks:api-root' %}bookmarks/check?url=${websiteUrl}`;
|
||||
const requestUrl = `{% url 'bookmarks:api.check_url' %}?url=${websiteUrl}`;
|
||||
fetch(requestUrl)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
|
@@ -23,5 +23,6 @@ urlpatterns = [
|
||||
path('settings/import', views.settings.bookmark_import, name='settings.import'),
|
||||
path('settings/export', views.settings.bookmark_export, name='settings.export'),
|
||||
# API
|
||||
path('api/check_url', views.api.check_url, name='api.check_url'),
|
||||
path('api/', include(router.urls), name='api')
|
||||
]
|
||||
|
@@ -1,2 +1,3 @@
|
||||
from .api import *
|
||||
from .bookmarks import *
|
||||
from .settings import *
|
||||
|
27
bookmarks/views/api.py
Normal file
27
bookmarks/views/api.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.forms import model_to_dict
|
||||
from django.http import JsonResponse
|
||||
from django.urls import reverse
|
||||
|
||||
from bookmarks.services.website_loader import load_website_metadata
|
||||
from bookmarks.models import Bookmark
|
||||
|
||||
|
||||
@login_required
|
||||
def check_url(request):
|
||||
url = request.GET.get('url')
|
||||
bookmark = Bookmark.objects.filter(owner=request.user, url=url).first()
|
||||
existing_bookmark_data = None
|
||||
|
||||
if bookmark is not None:
|
||||
existing_bookmark_data = {
|
||||
'id': bookmark.id,
|
||||
'edit_url': reverse('bookmarks:edit', args=[bookmark.id])
|
||||
}
|
||||
|
||||
metadata = load_website_metadata(url)
|
||||
|
||||
return JsonResponse({
|
||||
'bookmark': existing_bookmark_data,
|
||||
'metadata': metadata.to_dict()
|
||||
})
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "linkding",
|
||||
"version": "1.3.3",
|
||||
"version": "1.3.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
@@ -1 +1 @@
|
||||
1.3.3
|
||||
1.3.0
|
Reference in New Issue
Block a user