delayed add url and search

This commit is contained in:
Silver Ghost 2022-11-14 20:03:13 +03:00
parent 9904586ea0
commit dddbb034e5
No known key found for this signature in database
14 changed files with 198 additions and 61 deletions

View File

@ -34,6 +34,7 @@ services:
max-file: "5"
later42:
build: .
container_name: later42
image: dntskdev/later42:master
restart: always
@ -59,6 +60,28 @@ services:
- "traefik.http.routers.later42-opt.tls.certresolver=myresolver"
- "extdns.cf.later42.hostname=later42.com"
# later42_tasks:
# build: .
# container_name: later42_tasks
# image: dntskdev/later42:master
# restart: always
# command: celery -A later42 worker --loglevel=info
# environment:
# SECRET: "ahth3chaquodahh6que8thie1EThe5Iephich8eikei2Uojaemae6gee0kaet4aush2aoqu0ruL9oGhaiR9luu7cohreH6lebo0v"
# DB_TYPE: postgres
# DB_HOST: later42db
# DB_NAME: later42
# DB_USER: later42
# DB_PASS: later42
# DOMAIN: later42.com
# READABILITY_HOST: http://ureadability:8080/
# REDIS_URL: redis://redis:6379
# logging:
# driver: json-file
# options:
# max-size: "10m"
# max-file: "5"
later42db:
container_name: later42db
image: postgres

View File

@ -0,0 +1,31 @@
# Generated by Django 4.1.2 on 2022-11-14 12:28
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('later42', '0005_rename_articles_article'),
]
operations = [
migrations.RemoveField(
model_name='url',
name='content',
),
migrations.RemoveField(
model_name='url',
name='title',
),
migrations.AddField(
model_name='article',
name='short',
field=models.TextField(blank=True, null=True),
),
migrations.AddField(
model_name='article',
name='title',
field=models.CharField(blank=True, max_length=2000, null=True),
),
]

View File

@ -1,4 +1,3 @@
from django.contrib.auth.models import User
from django.db import models
from later42.models.urls import URL
@ -7,3 +6,5 @@ class Article(models.Model):
id = models.AutoField(auto_created=True, primary_key=True)
url = models.ForeignKey(URL, on_delete=models.CASCADE)
content = models.TextField(blank=True, null=True)
title = models.CharField(max_length=2000, blank=True, null=True)
short = models.TextField(blank=True, null=True)

View File

@ -8,6 +8,4 @@ class URL(models.Model):
id = models.AutoField(auto_created=True, primary_key=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
url = models.CharField(max_length=2000)
title = models.CharField(max_length=2000)
archived = models.BooleanField(default=False)
content = models.TextField(blank=True, null=True)

View File

@ -1,6 +1,7 @@
import os
import pybrake
from celery import shared_task
from django.contrib.auth.models import User
from pybrake.middleware.celery import patch_celery
from later42.models.urls import URL
from later42.models.article import Article
@ -19,9 +20,17 @@ if AIRBRAKE_PROJECT_ID is not None and AIRBRAKE_PROJECT_KEY is not None:
@shared_task()
def get_url_content_task(id):
url = URL.objects.get(id=id)
article = Article.objects.create(url=url)
content = get_content(url.url)['rich_content']
article.content = content
def get_url_content_task(url, user_id):
print(url)
print(user_id)
user = User.objects.get(pk=int(user_id))
url_object = URL(url=url, user=user)
url_object.save()
data = get_content(url)
article = Article.objects.create(url=url_object)
article.content = data['rich_content']
article.title = data['title']
article.short = data['excerpt']
article.save()

View File

@ -2,54 +2,57 @@
{% block content %}
<div class="post-preview">
{% if urls|length > 0 %}
{% for url in urls %}
{% if data|length > 0 %}
{% for d in data %}
<!-- Post preview-->
<div class="post-preview">
<div class="d-flex justify-content-between">
<div class="p-2">
<a href="{% url 'reader' url.id %}">
<h2 class="post-title">{{ url.title }}</h2>
<a href="{% url 'reader' d.url.id %}">
<h2 class="post-title">{% if d.title %}{{ d.title }}{% else %}Без заголовка{% endif %}</h2>
</a>
</div>
<div class="p-2">
<a href="/delete/{{ url.id }}"><span class="fa-regular fa-trash-can"></span></a>
<a href="/delete/{{ d.url.id }}"><span class="fa-regular fa-trash-can"></span></a>
</div>
</div>
{% if url.content %}
{% if d.short %}
<p class="post-meta">
{{ url.content }}
{{ d.short }}
</p>
{% endif %}
<p class="post-meta">
<a href="{{ url.url }}">
{{ url.url }}
<a href="{{ d.url.url }}">
{{ d.url.url }}
</a>
</p>
</div>
<!-- Divider-->
<hr class="my-4" />
{% endfor %}
{% if data.number %}
<div class="pagination container row justify-content-end">
<div></div>
<div class="step-links col-auto">
{% if urls.has_previous %}
{% if data.has_previous %}
<a href="?page=1">&laquo;</a>
<a href="?page={{ urls.previous_page_number }}">&lsaquo;</a>
<a href="?page={{ data.previous_page_number }}">&lsaquo;</a>
{% endif %}
<span class="current">
страница {{ urls.number }} из {{ urls.paginator.num_pages }}
страница {{ data.number }} из {{ data.paginator.num_pages }}
</span>
{% if urls.has_next %}
<a href="?page={{ urls.next_page_number }}">&rsaquo;</a>
<a href="?page={{ urls.paginator.num_pages }}">&raquo;</a>
{% if data.has_next %}
<a href="?page={{ data.next_page_number }}">&rsaquo;</a>
<a href="?page={{ data.paginator.num_pages }}">&raquo;</a>
{% endif %}
</div>
</div>
{% endif %}
{% else %}
<h2 class="post-title">У вас нет ссылок в архиве</h2>
{% endif %}
</div>
{% endblock %}
{% endblock %}

View File

@ -57,6 +57,7 @@
<li class="nav-item"><a class="nav-link px-lg-3 py-3 py-lg-4" href="{% url 'about' %}">О нас</a></li>
<li class="nav-item"><a class="nav-link px-lg-3 py-3 py-lg-4" href="{% url 'profile' %}">Профиль</a></li>
<li class="nav-item"><a class="nav-link px-lg-3 py-3 py-lg-4" href="{% url 'archive' %}">Архив</a></li>
<li class="nav-item"><a class="nav-link px-lg-3 py-3 py-lg-4" href="{% url 'search' %}">Поиск</a></li>
<li class="nav-item"><a class="nav-link px-lg-3 py-3 py-lg-4" href="{% url 'logout' %}">Выйти</a></li>
{% else %}
<li class="nav-item"><a class="nav-link px-lg-3 py-3 py-lg-4" href="{% url 'signup' %}">Регистрация</a></li>

View File

@ -1,27 +1,27 @@
{% extends 'base.html' %}
{% block content %}
{% if user.is_authenticated and urls|length > 0 %}
{% for url in urls %}
{% if user.is_authenticated and data|length > 0 %}
{% for d in data %}
<!-- Post preview-->
<div class="post-preview">
<div class="d-flex justify-content-between">
<div class="p-2">
<a href="{% url 'reader' url.id %}">
<h2 class="post-title">{{ url.title }}</h2>
<a href="{% url 'reader' d.url_id %}">
<h2 class="post-title">{% if d.title %}{{ d.title }}{% else %}Без заголовка{% endif %}</h2>
</a>
</div>
<div class="p-2">
<a href="{% url 'archive_url' url.id %}"><span class="fa-regular fa-square-check"></span></a>
<a href="{% url 'archive_url' d.url_id %}"><span class="fa-regular fa-square-check"></span></a>
</div>
</div>
{% if url.content %}
{% if d.short %}
<p class="post-meta">
{{ url.content }}
{{ d.short }}
</p>
{% endif %}
<p class="post-meta">
{{ url.url|urlizetrunc:70 }}
{{ d.url.url|urlizetrunc:70 }}
</p>
</div>
<!-- Divider-->

View File

@ -0,0 +1,58 @@
{% extends 'base.html' %}
{% block title %}Поиск{% endblock %}
{% block content %}
<form action="{% url 'search' %}" method="post">
{% csrf_token %}
<input type="text" name="search" placeholder="Что ищем?">
<input type="submit" value="Искать" />
</form>
<br />
{% for d in data %}
<!-- Post preview-->
<div class="post-preview">
<div class="d-flex justify-content-between">
<div class="p-2">
<a href="{% url 'reader' d.url.id %}">
<h2 class="post-title">{{ d.title }}</h2>
</a>
</div>
<div class="p-2">
<a href="{% url 'archive_url' d.url.id %}"><span class="fa-regular fa-square-check"></span></a>
</div>
</div>
{% if d.short %}
<p class="post-meta">
{{ d.short }}
</p>
{% endif %}
<p class="post-meta">
{{ d.url.url|urlizetrunc:70 }}
</p>
</div>
<!-- Divider-->
<hr class="my-4" />
{% endfor %}
{% if data.number %}
<div class="pagination container row justify-content-end">
<div></div>
<div class="step-links col-auto">
{% if data.has_previous %}
<a href="?page=1">&laquo;</a>
<a href="?page={{ data.previous_page_number }}">&lsaquo;</a>
{% endif %}
<span class="current">
страница {{ data.number }} из {{ data.paginator.num_pages }}
</span>
{% if data.has_next %}
<a href="?page={{ data.next_page_number }}">&rsaquo;</a>
<a href="?page={{ data.paginator.num_pages }}">&raquo;</a>
{% endif %}
</div>
</div>
{% endif %}
{% endblock %}

View File

@ -22,7 +22,7 @@ from django.contrib.auth.models import User
from rest_framework import routers, serializers, viewsets
# from later42.forms import CustomLoginForm
from later42.views import account_activation, index, profile, api, api_token, reader, signup, about
from later42.views import account_activation, index, profile, api, api_token, reader, search, signup, about
class UserSerializer(serializers.HyperlinkedModelSerializer):
@ -54,4 +54,5 @@ urlpatterns = [
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'),
path('search/', search.search, name='search'),
]

View File

@ -8,26 +8,8 @@ from django.conf import settings
class URL(APIView):
def post(self, request, format=None):
url = request.GET.get('url')
if url:
page = get_content(url)
try:
title = page['title']
except KeyError:
title = ''
content = None
if settings.READABILITY_HOST:
try:
content = page['excerpt']
except KeyError:
content = ''
url = URLModel(url=url, user=request.user,
title=title, content=content)
url.save()
get_url_content_task.delay(url.id)
if request.GET.get('url'):
get_url_content_task.delay(request.GET.get('url'), request.user.id)
return Response({'status': 'success'})
else:
return Response({'status': 'error'})

View File

@ -3,16 +3,20 @@ 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.models.article import Article
from later42.models.urls import URL
def get(request):
data = {}
try:
urls = URL.objects.filter(
user=request.user, archived=False).order_by('-id')
data = Article.objects.filter(url__in=urls).select_related('url')
except:
urls = []
context = {'urls': urls}
context = {'data': data}
return render(request, 'index.html', context)
@ -24,12 +28,13 @@ def archive(request, url_id=None):
try:
urls = URL.objects.filter(
user=request.user, archived=True).order_by('-id')
paginator = Paginator(urls, settings.URLS_PER_PAGE)
data = Article.objects.filter(url__in=urls).select_related('url')
paginator = Paginator(data, settings.URLS_PER_PAGE)
page_number = request.GET.get('page')
urls = paginator.get_page(page_number)
data = paginator.get_page(page_number)
except:
urls = []
context = {'urls': urls}
context = {'data': data}
return render(request, 'archive.html', context)

View File

@ -6,16 +6,13 @@ from django.conf import settings
from later42.libs.content import get_content, sanitize_img_size
from later42.models.article import Article
from later42.models.urls import URL
from later42.tasks import get_url_content_task
@login_required
def get(request, url_id=None):
url = URL.objects.get(
user=request.user, id=url_id)
content = {}
try:
article = Article.objects.get(url=url)
content['rich_content'] = article.content
@ -24,6 +21,5 @@ def get(request, url_id=None):
content['rich_content'] = sanitize_img_size(content['rich_content'])
except:
content = get_content(url.url)
get_url_content_task.delay(url.id)
context = {'url': url, 'content': content}
return render(request, 'reader.html', context)

29
later42/views/search.py Normal file
View File

@ -0,0 +1,29 @@
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator
from django.db.models import Q
from django.shortcuts import render
from later42.models.article import Article
from later42.models.urls import URL as URL
@login_required
def search(request):
pattern = request.POST.get('search')
context = {}
if request.method == 'GET':
return render(request, 'search.html', context)
elif request.method == 'POST':
urls = URL.objects.filter(
user=request.user).order_by('-id')
data = Article.objects.filter(
Q(title__contains=pattern) |
Q(content__contains=pattern) |
Q(short__contains=pattern) |
Q(url__url__contains=pattern), url__user_id=request.user.id).select_related('url')
paginator = Paginator(data, settings.URLS_PER_PAGE)
page_number = request.GET.get('page')
data = paginator.get_page(page_number)
context = {'data': data}
return render(request, 'search.html', context)