feat: reader

This commit is contained in:
Silver Ghost 2022-10-25 14:35:00 +03:00
parent dc09b4b353
commit 168d40789b
No known key found for this signature in database
7 changed files with 82 additions and 29 deletions

0
later42/libs/__init__.py Normal file
View File

21
later42/libs/content.py Normal file
View 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

View File

@ -7,12 +7,12 @@
<div class="post-preview"> <div class="post-preview">
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
<div class="p-2"> <div class="p-2">
<a href="{{ url.url }}"> <a href="{% url 'reader' url.id %}">
<h2 class="post-title">{{ url.title }}</h2> <h2 class="post-title">{{ url.title }}</h2>
</a> </a>
</div> </div>
<div class="p-2"> <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>
</div> </div>
{% if url.content %} {% if url.content %}

View 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>&nbsp;Отметить прочитанным</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>&nbsp;Отметить прочитанным</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 %}

View File

@ -22,7 +22,7 @@ from django.contrib.auth.views import LoginView
from rest_framework import routers, serializers, viewsets from rest_framework import routers, serializers, viewsets
from later42.forms import CustomLoginForm 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): class UserSerializer(serializers.HyperlinkedModelSerializer):
@ -53,5 +53,5 @@ urlpatterns = [
path('about/', about.get, name='about'), path('about/', about.get, name='about'),
path('archive/', index.archive, name='archive'), path('archive/', index.archive, name='archive'),
path('archive/<int:url_id>', index.archive, name='archive_url'), path('archive/<int:url_id>', index.archive, name='archive_url'),
path('reader/<int:url_id>', reader.get, name='reader'),
] ]

View File

@ -1,41 +1,21 @@
import requests
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.views import APIView 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 later42.models.urls import URL as URLModel
from django.conf import settings from django.conf import settings
class URL(APIView): 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): def post(self, request, format=None):
url = request.GET.get('url') url = request.GET.get('url')
if url: if url:
title = self.get_title(url) page = get_content(url)
if title is None:
title = url title = page['title']
content = None content = None
if settings.READABILITY_HOST: if settings.READABILITY_HOST:
content = self.get_content(url) content = page['excerpt']
url = URLModel(url=url, user=request.user, url = URLModel(url=url, user=request.user,
title=title, content=content) title=title, content=content)

17
later42/views/reader.py Normal file
View 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)