feat: reader
This commit is contained in:
parent
dc09b4b353
commit
168d40789b
0
later42/libs/__init__.py
Normal file
0
later42/libs/__init__.py
Normal file
21
later42/libs/content.py
Normal file
21
later42/libs/content.py
Normal file
@ -0,0 +1,21 @@
|
||||
import requests
|
||||
|
||||
from bs4 import BeautifulSoup
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
def sanitize_img_size(html: str):
|
||||
soup = BeautifulSoup(html, 'html.parser')
|
||||
for img in soup.find_all('img'):
|
||||
img['width'] = '100%'
|
||||
img['height'] = 'auto'
|
||||
return str(soup)
|
||||
|
||||
|
||||
def get_content(url: str):
|
||||
url = settings.READABILITY_HOST.rstrip(
|
||||
'/') + '/api/content/v1/parser?url=' + url
|
||||
try:
|
||||
return requests.get(url).json()
|
||||
except KeyError:
|
||||
return None
|
@ -7,12 +7,12 @@
|
||||
<div class="post-preview">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="p-2">
|
||||
<a href="{{ url.url }}">
|
||||
<a href="{% url 'reader' url.id %}">
|
||||
<h2 class="post-title">{{ url.title }}</h2>
|
||||
</a>
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<a href="/archive/{{ url.id }}"><span class="fa-regular fa-square-check"></span></a>
|
||||
<a href="{% url 'archive_url' url.id %}"><span class="fa-regular fa-square-check"></span></a>
|
||||
</div>
|
||||
</div>
|
||||
{% if url.content %}
|
||||
|
35
later42/templates/reader.html
Normal file
35
later42/templates/reader.html
Normal file
@ -0,0 +1,35 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="post-preview">
|
||||
<!-- Post preview-->
|
||||
{% if content %}
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="p-2">
|
||||
<h2 class="post-title">{{ content.title }}</h2>
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="p-2">
|
||||
<a href="{% url 'archive_url' url.id %}"><span class="fa-regular fa-square-check"></span> Отметить прочитанным</a>
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<a href="{{ url.url }}">Открыть оригинал статьи</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="my-4" />
|
||||
{{ content.rich_content|safe }}
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="p-2">
|
||||
<a href="{% url 'archive_url' url.id %}"><span class="fa-regular fa-square-check"></span> Отметить прочитанным</a>
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<a href="{{ url.url }}">Открыть оригинал статьи</a>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<h2 class="post-title">Что-то пошло не так.</h2>
|
||||
Открыть <a href="{{ url.url }}">оригинал ссылки</a>.
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
@ -22,7 +22,7 @@ from django.contrib.auth.views import LoginView
|
||||
from rest_framework import routers, serializers, viewsets
|
||||
|
||||
from later42.forms import CustomLoginForm
|
||||
from later42.views import index, profile, api, api_token, signup, about
|
||||
from later42.views import index, profile, api, api_token, reader, signup, about
|
||||
|
||||
|
||||
class UserSerializer(serializers.HyperlinkedModelSerializer):
|
||||
@ -53,5 +53,5 @@ urlpatterns = [
|
||||
path('about/', about.get, name='about'),
|
||||
path('archive/', index.archive, name='archive'),
|
||||
path('archive/<int:url_id>', index.archive, name='archive_url'),
|
||||
|
||||
path('reader/<int:url_id>', reader.get, name='reader'),
|
||||
]
|
||||
|
@ -1,41 +1,21 @@
|
||||
import requests
|
||||
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from bs4 import BeautifulSoup
|
||||
from later42.libs.content import get_content
|
||||
from later42.models.urls import URL as URLModel
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
class URL(APIView):
|
||||
def get_title(self, url: str):
|
||||
try:
|
||||
response = requests.get(url)
|
||||
soup = BeautifulSoup(response.text, 'html.parser')
|
||||
title = soup.find('title').text
|
||||
return title
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
def get_content(self, url: str):
|
||||
url = settings.READABILITY_HOST.rstrip(
|
||||
'/') + '/api/content/v1/parser?url=' + url
|
||||
try:
|
||||
response = requests.get(url).json()
|
||||
return response['excerpt']
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
def post(self, request, format=None):
|
||||
url = request.GET.get('url')
|
||||
if url:
|
||||
title = self.get_title(url)
|
||||
if title is None:
|
||||
title = url
|
||||
page = get_content(url)
|
||||
|
||||
title = page['title']
|
||||
|
||||
content = None
|
||||
if settings.READABILITY_HOST:
|
||||
content = self.get_content(url)
|
||||
content = page['excerpt']
|
||||
|
||||
url = URLModel(url=url, user=request.user,
|
||||
title=title, content=content)
|
||||
|
17
later42/views/reader.py
Normal file
17
later42/views/reader.py
Normal file
@ -0,0 +1,17 @@
|
||||
from multiprocessing import context
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.shortcuts import render, redirect
|
||||
from django.core.paginator import Paginator
|
||||
from django.conf import settings
|
||||
from later42.libs.content import get_content, sanitize_img_size
|
||||
from later42.models.urls import URL
|
||||
|
||||
|
||||
@login_required
|
||||
def get(request, url_id=None):
|
||||
url = URL.objects.get(
|
||||
user=request.user, archived=False, id=url_id)
|
||||
content = get_content(url.url)
|
||||
content['rich_content'] = sanitize_img_size(content['rich_content'])
|
||||
context = {'url': url, 'content': content}
|
||||
return render(request, 'reader.html', context)
|
Loading…
Reference in New Issue
Block a user