Add fetch favicon task & split account urls

This commit is contained in:
Sonny Bakker 2020-09-30 23:32:28 +02:00
parent b183612a36
commit ab81b06e6d
10 changed files with 118 additions and 51 deletions

View file

@ -7,7 +7,12 @@
<a class="link button button--primary" href="{% url 'accounts:password-change' %}"> <a class="link button button--primary" href="{% url 'accounts:password-change' %}">
{% trans "Change password" %} {% trans "Change password" %}
</a> </a>
<a class="link button button--primary" href="{% url 'accounts:integrations' %}">
<a class="link button button--primary" href="{% url 'accounts:settings:favicon' %}">
{% trans "Fetch favicons" %}
</a>
<a class="link button button--primary" href="{% url 'accounts:settings:integrations' %}">
{% trans "Third party integrations" %} {% trans "Third party integrations" %}
</a> </a>

View file

@ -2,7 +2,7 @@
{% block content %} {% block content %}
<main id="password-change--page" class="main"> <main id="password-change--page" class="main">
{% url 'accounts:settings' as cancel_url %} {% url 'accounts:settings:settings' as cancel_url %}
{% include "components/form/form.html" with form=form title="Change password" confirm_text="Change password" cancel_url=cancel_url %} {% include "components/form/form.html" with form=form title="Change password" confirm_text="Change password" cancel_url=cancel_url %}
</main> </main>
{% endblock %} {% endblock %}

View file

@ -13,7 +13,7 @@
{% endif %} {% endif %}
<p> <p>
<a class="link" href="{% url 'accounts:integrations' %}">{% trans "Return to integrations page" %}</a> <a class="link" href="{% url 'accounts:settings:integrations' %}">{% trans "Return to integrations page" %}</a>
</p> </p>
</section> </section>
</main> </main>

View file

@ -13,7 +13,7 @@
{% endif %} {% endif %}
<p> <p>
<a class="link" href="{% url 'accounts:integrations' %}">{% trans "Return to integrations page" %}</a> <a class="link" href="{% url 'accounts:settings:integrations' %}">{% trans "Return to integrations page" %}</a>
</p> </p>
</section> </section>
</main> </main>

View file

@ -1,10 +1,11 @@
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.urls import path from django.urls import include, path
from newsreader.accounts.views import ( from newsreader.accounts.views import (
ActivationCompleteView, ActivationCompleteView,
ActivationResendView, ActivationResendView,
ActivationView, ActivationView,
FaviconRedirectView,
IntegrationsView, IntegrationsView,
LoginView, LoginView,
LogoutView, LogoutView,
@ -26,6 +27,46 @@ from newsreader.accounts.views import (
) )
settings_patterns = [
# Integrations
path(
"integrations/reddit/callback/",
login_required(RedditTemplateView.as_view()),
name="reddit-template",
),
path(
"integrations/reddit/refresh/",
login_required(RedditTokenRedirectView.as_view()),
name="reddit-refresh",
),
path(
"integrations/reddit/revoke/",
login_required(RedditRevokeRedirectView.as_view()),
name="reddit-revoke",
),
path(
"integrations/twitter/auth/",
login_required(TwitterAuthRedirectView.as_view()),
name="twitter-auth",
),
path(
"integrations/twitter/callback/",
login_required(TwitterTemplateView.as_view()),
name="twitter-template",
),
path(
"integrations/twitter/revoke/",
login_required(TwitterRevokeRedirectView.as_view()),
name="twitter-revoke",
),
path(
"integrations/", login_required(IntegrationsView.as_view()), name="integrations"
),
# Misc
path("favicon/", login_required(FaviconRedirectView.as_view()), name="favicon"),
path("", login_required(SettingsView.as_view()), name="settings"),
]
urlpatterns = [ urlpatterns = [
# Auth # Auth
path("login/", LoginView.as_view(), name="login"), path("login/", LoginView.as_view(), name="login"),
@ -70,42 +111,6 @@ urlpatterns = [
login_required(PasswordChangeView.as_view()), login_required(PasswordChangeView.as_view()),
name="password-change", name="password-change",
), ),
# Integrations
path(
"settings/integrations/reddit/callback/",
login_required(RedditTemplateView.as_view()),
name="reddit-template",
),
path(
"settings/integrations/reddit/refresh/",
login_required(RedditTokenRedirectView.as_view()),
name="reddit-refresh",
),
path(
"settings/integrations/reddit/revoke/",
login_required(RedditRevokeRedirectView.as_view()),
name="reddit-revoke",
),
path(
"settings/integrations/twitter/auth/",
login_required(TwitterAuthRedirectView.as_view()),
name="twitter-auth",
),
path(
"settings/integrations/twitter/callback/",
login_required(TwitterTemplateView.as_view()),
name="twitter-template",
),
path(
"settings/integrations/twitter/revoke/",
login_required(TwitterRevokeRedirectView.as_view()),
name="twitter-revoke",
),
path(
"settings/integrations",
login_required(IntegrationsView.as_view()),
name="integrations",
),
# Settings # Settings
path("settings/", login_required(SettingsView.as_view()), name="settings"), path("settings/", include((settings_patterns, "settings"))),
] ]

View file

@ -1,4 +1,5 @@
from newsreader.accounts.views.auth import LoginView, LogoutView from newsreader.accounts.views.auth import LoginView, LogoutView
from newsreader.accounts.views.favicon import FaviconRedirectView
from newsreader.accounts.views.integrations import ( from newsreader.accounts.views.integrations import (
IntegrationsView, IntegrationsView,
RedditRevokeRedirectView, RedditRevokeRedirectView,

View file

@ -0,0 +1,26 @@
from django.contrib import messages
from django.core.cache import cache
from django.urls import reverse_lazy
from django.utils.translation import gettext as _
from django.views.generic import RedirectView
from newsreader.news.collection.tasks import FaviconTask
class FaviconRedirectView(RedirectView):
url = reverse_lazy("accounts:settings:integrations")
def get(self, request, *args, **kwargs):
response = super().get(request, *args, **kwargs)
user = request.user
task_active = cache.get(f"{user.email}-favicon-task")
if not task_active:
FaviconTask.delay(user.pk)
messages.success(request, _("Favicons are being fetched"))
cache.set(f"{user.email}-favicon-task", 1, 18000) # 5 hours
return response
messages.error(request, _("Limit reached, try again later"))
return response

View file

@ -53,7 +53,7 @@ class IntegrationsView(TemplateView):
and not user.reddit_access_token and not user.reddit_access_token
and not reddit_task_active and not reddit_task_active
): ):
reddit_refresh_url = reverse_lazy("accounts:reddit-refresh") reddit_refresh_url = reverse_lazy("accounts:settings:reddit-refresh")
if not user.reddit_refresh_token: if not user.reddit_refresh_token:
reddit_authorization_url = get_reddit_authorization_url(user) reddit_authorization_url = get_reddit_authorization_url(user)
@ -62,7 +62,7 @@ class IntegrationsView(TemplateView):
"reddit_authorization_url": reddit_authorization_url, "reddit_authorization_url": reddit_authorization_url,
"reddit_refresh_url": reddit_refresh_url, "reddit_refresh_url": reddit_refresh_url,
"reddit_revoke_url": ( "reddit_revoke_url": (
reverse_lazy("accounts:reddit-revoke") reverse_lazy("accounts:settings:reddit-revoke")
if not reddit_authorization_url if not reddit_authorization_url
else None else None
), ),
@ -72,10 +72,10 @@ class IntegrationsView(TemplateView):
twitter_revoke_url = None twitter_revoke_url = None
if self.request.user.has_twitter_auth: if self.request.user.has_twitter_auth:
twitter_revoke_url = reverse_lazy("accounts:twitter-revoke") twitter_revoke_url = reverse_lazy("accounts:settings:twitter-revoke")
return { return {
"twitter_auth_url": reverse_lazy("accounts:twitter-auth"), "twitter_auth_url": reverse_lazy("accounts:settings:twitter-auth"),
"twitter_revoke_url": twitter_revoke_url, "twitter_revoke_url": twitter_revoke_url,
} }
@ -130,7 +130,7 @@ class RedditTemplateView(TemplateView):
class RedditTokenRedirectView(RedirectView): class RedditTokenRedirectView(RedirectView):
url = reverse_lazy("accounts:integrations") url = reverse_lazy("accounts:settings:integrations")
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
response = super().get(request, *args, **kwargs) response = super().get(request, *args, **kwargs)
@ -149,7 +149,7 @@ class RedditTokenRedirectView(RedirectView):
class RedditRevokeRedirectView(RedirectView): class RedditRevokeRedirectView(RedirectView):
url = reverse_lazy("accounts:integrations") url = reverse_lazy("accounts:settings:integrations")
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
response = super().get(request, *args, **kwargs) response = super().get(request, *args, **kwargs)
@ -181,7 +181,7 @@ class RedditRevokeRedirectView(RedirectView):
class TwitterRevokeRedirectView(RedirectView): class TwitterRevokeRedirectView(RedirectView):
url = reverse_lazy("accounts:integrations") url = reverse_lazy("accounts:settings:integrations")
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
if not request.user.has_twitter_auth: if not request.user.has_twitter_auth:
@ -212,7 +212,7 @@ class TwitterRevokeRedirectView(RedirectView):
class TwitterAuthRedirectView(RedirectView): class TwitterAuthRedirectView(RedirectView):
url = reverse_lazy("accounts:integrations") url = reverse_lazy("accounts:settings:integrations")
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
oauth = OAuth( oauth = OAuth(

View file

@ -147,7 +147,37 @@ class TwitterTimelineTask(app.Task):
raise Reject(reason="Task already running", requeue=False) raise Reject(reason="Task already running", requeue=False)
class FaviconTask(app.Task):
name = "FaviconTask"
ignore_result = True
def run(self, user_pk):
from newsreader.news.collection.favicon import FaviconCollector
try:
user = User.objects.get(pk=user_pk)
except ObjectDoesNotExist:
message = f"User {user_pk} does not exist"
logger.exception(message)
raise Reject(reason=message, requeue=False)
with MemCacheLock("f{user.email}-favicon-task", self.app.oid) as acquired:
if acquired:
logger.info(f"Running favicon task for user {user_pk}")
rules = user.rules.enabled()
collector = FaviconCollector()
collector.collect(rules=rules)
else:
logger.warning(f"Cancelling task due to existing lock")
raise Reject(reason="Task already running", requeue=False)
FeedTask = app.register_task(FeedTask()) FeedTask = app.register_task(FeedTask())
FaviconTask = app.register_task(FaviconTask())
RedditTask = app.register_task(RedditTask()) RedditTask = app.register_task(RedditTask())
RedditTokenTask = app.register_task(RedditTokenTask()) RedditTokenTask = app.register_task(RedditTokenTask())
TwitterTimelineTask = app.register_task(TwitterTimelineTask()) TwitterTimelineTask = app.register_task(TwitterTimelineTask())

View file

@ -17,7 +17,7 @@
<li class="nav__item"><a href="{% url 'index' %}">Home</a></li> <li class="nav__item"><a href="{% url 'index' %}">Home</a></li>
<li class="nav__item"><a href="{% url 'news:core:categories' %}">Categories</a></li> <li class="nav__item"><a href="{% url 'news:core:categories' %}">Categories</a></li>
<li class="nav__item"><a href="{% url 'news:collection:rules' %}">Feeds</a></li> <li class="nav__item"><a href="{% url 'news:collection:rules' %}">Feeds</a></li>
<li class="nav__item"><a href="{% url 'accounts:settings' %}">Settings</a></li> <li class="nav__item"><a href="{% url 'accounts:settings:settings' %}">Settings</a></li>
{% if request.user.is_superuser %} {% if request.user.is_superuser %}
<li class="nav__item"><a href="{% url 'admin:index' %}">Admin</a></li> <li class="nav__item"><a href="{% url 'admin:index' %}">Admin</a></li>
{% endif %} {% endif %}