From 61e45ed0cc9d4b72a286eaacb95e99b3992942d0 Mon Sep 17 00:00:00 2001 From: sonny Date: Sat, 18 Jan 2020 19:39:26 +0100 Subject: [PATCH] [#14] opml import export --- gulp/sass.js | 1 + src/newsreader/conf/base.py | 5 +- src/newsreader/js/pages/rules/App.js | 12 +- src/newsreader/news/collection/forms.py | 5 + .../templates/collection/import.html | 41 ++++++ .../news/collection/tests/test_views.py | 132 ++++++++++++++++++ src/newsreader/news/collection/urls.py | 2 + src/newsreader/news/collection/views.py | 35 ++++- .../components/import-form/_import-form.scss | 17 +++ .../import/components/import-form/index.scss | 1 + .../scss/pages/import/components/index.scss | 1 + .../scss/pages/import/elements/index.scss | 0 src/newsreader/scss/pages/import/index.scss | 8 ++ .../pages/rules/components/card/_card.scss | 4 + src/newsreader/utils/formatter.sh | 10 -- src/newsreader/utils/opml.py | 41 ++++++ src/newsreader/utils/pre-commit | 13 -- src/newsreader/utils/tests/__init__.py | 0 .../utils/tests/files/empty-feeds.opml | 9 ++ src/newsreader/utils/tests/files/feeds.opml | 15 ++ .../utils/tests/files/invalid-url-feeds.opml | 16 +++ .../utils/tests/files/missing-feeds.opml | 17 +++ src/newsreader/utils/tests/files/test.png | Bin 0 -> 81814 bytes src/newsreader/utils/tests/test_opml.py | 46 ++++++ 24 files changed, 401 insertions(+), 30 deletions(-) create mode 100644 src/newsreader/news/collection/templates/collection/import.html create mode 100644 src/newsreader/scss/pages/import/components/import-form/_import-form.scss create mode 100644 src/newsreader/scss/pages/import/components/import-form/index.scss create mode 100644 src/newsreader/scss/pages/import/components/index.scss create mode 100644 src/newsreader/scss/pages/import/elements/index.scss create mode 100644 src/newsreader/scss/pages/import/index.scss delete mode 100644 src/newsreader/utils/formatter.sh create mode 100644 src/newsreader/utils/opml.py delete mode 100644 src/newsreader/utils/pre-commit create mode 100644 src/newsreader/utils/tests/__init__.py create mode 100644 src/newsreader/utils/tests/files/empty-feeds.opml create mode 100644 src/newsreader/utils/tests/files/feeds.opml create mode 100644 src/newsreader/utils/tests/files/invalid-url-feeds.opml create mode 100644 src/newsreader/utils/tests/files/missing-feeds.opml create mode 100644 src/newsreader/utils/tests/files/test.png create mode 100644 src/newsreader/utils/tests/test_opml.py diff --git a/gulp/sass.js b/gulp/sass.js index 46cd291..3847e37 100644 --- a/gulp/sass.js +++ b/gulp/sass.js @@ -28,6 +28,7 @@ const taskMappings = [ { name: 'category', destDir: `${CORE_DIR}/${STATIC_SUFFIX}` }, { name: 'rules', destDir: `${COLLECTION_DIR}/${STATIC_SUFFIX}` }, { name: 'rule', destDir: `${COLLECTION_DIR}/${STATIC_SUFFIX}` }, + { name: 'import', destDir: `${COLLECTION_DIR}/${STATIC_SUFFIX}` }, ]; export const sassTask = done => { diff --git a/src/newsreader/conf/base.py b/src/newsreader/conf/base.py index 6f19f91..c0a84c1 100644 --- a/src/newsreader/conf/base.py +++ b/src/newsreader/conf/base.py @@ -12,9 +12,10 @@ https://docs.djangoproject.com/en/2.2/ref/settings/ import os +from pathlib import Path -# Build paths inside the project like this: os.path.join(BASE_DIR, ...) -BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + +BASE_DIR = Path(__file__).resolve().parent.parent # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ diff --git a/src/newsreader/js/pages/rules/App.js b/src/newsreader/js/pages/rules/App.js index fd01229..7ceae4a 100644 --- a/src/newsreader/js/pages/rules/App.js +++ b/src/newsreader/js/pages/rules/App.js @@ -74,9 +74,15 @@ class App extends React.Component { const pageHeader = ( <>

Rules

- - Create rule - + +
+ + Import rules + + + Create rule + +
); diff --git a/src/newsreader/news/collection/forms.py b/src/newsreader/news/collection/forms.py index 89c72e9..2213840 100644 --- a/src/newsreader/news/collection/forms.py +++ b/src/newsreader/news/collection/forms.py @@ -28,3 +28,8 @@ class CollectionRuleForm(forms.ModelForm): class Meta: model = CollectionRule fields = ("name", "url", "timezone", "favicon", "category") + + +class OPMLImportForm(forms.Form): + file = forms.FileField(allow_empty_file=False) + skip_existing = forms.BooleanField(initial=False, required=False) diff --git a/src/newsreader/news/collection/templates/collection/import.html b/src/newsreader/news/collection/templates/collection/import.html new file mode 100644 index 0000000..28785b8 --- /dev/null +++ b/src/newsreader/news/collection/templates/collection/import.html @@ -0,0 +1,41 @@ +{% extends "base.html" %} + +{% load static i18n %} + +{% block head %} + +{% endblock %} + +{% block content %} +
+
+ {% csrf_token %} + {{ form.non_field_errors }} + +
+

{% trans "Import an OPML file" %}

+
+
+
+ + {{ form.file.errors }} + {{ form.file }} +
+ +
+ + {{ form.skip_existing }} +
+ +
+ Cancel + +
+
+
+
+{% endblock %} diff --git a/src/newsreader/news/collection/tests/test_views.py b/src/newsreader/news/collection/tests/test_views.py index d6a478e..5a1a59e 100644 --- a/src/newsreader/news/collection/tests/test_views.py +++ b/src/newsreader/news/collection/tests/test_views.py @@ -1,5 +1,9 @@ +import os + +from django.conf import settings from django.test import Client, TestCase from django.urls import reverse +from django.utils.translation import gettext_lazy as _ import pytz @@ -146,3 +150,131 @@ class CollectionRuleUpdateViewTestCase(CollectionRuleViewTestCase, TestCase): self.rule.refresh_from_db() self.assertEquals(self.rule.category, None) + + +class OPMLImportTestCase(TestCase): + def setUp(self): + self.user = UserFactory(password="test") + self.client.login(email=self.user.email, password="test") + + self.form_data = {"file": "", "skip_existing": False} + self.url = reverse("import") + + def _get_file_path(self, name): + file_dir = os.path.join(settings.BASE_DIR, "utils", "tests", "files") + return os.path.join(file_dir, name) + + def test_simple(self): + file_path = self._get_file_path("feeds.opml") + + with open(file_path) as file: + self.form_data.update(file=file) + + response = self.client.post(self.url, self.form_data) + + self.assertRedirects(response, reverse("rules")) + + rules = CollectionRule.objects.all() + self.assertEquals(len(rules), 4) + + def test_existing_rules(self): + CollectionRuleFactory(url="http://www.engadget.com/rss-full.xml", user=self.user) + CollectionRuleFactory(url="https://news.ycombinator.com/rss", user=self.user) + CollectionRuleFactory( + url="http://feeds.feedburner.com/Techcrunch", user=self.user + ) + CollectionRuleFactory( + url="http://feeds.feedburner.com/tweakers/nieuws", user=self.user + ) + + file_path = self._get_file_path("feeds.opml") + + with open(file_path) as file: + self.form_data.update(file=file) + + response = self.client.post(self.url, self.form_data) + + self.assertRedirects(response, reverse("rules")) + + rules = CollectionRule.objects.all() + self.assertEquals(len(rules), 8) + + def test_skip_existing_rules(self): + CollectionRuleFactory(url="http://www.engadget.com/rss-full.xml", user=self.user) + CollectionRuleFactory(url="https://news.ycombinator.com/rss", user=self.user) + CollectionRuleFactory( + url="http://feeds.feedburner.com/Techcrunch", user=self.user + ) + CollectionRuleFactory( + url="http://feeds.feedburner.com/tweakers/nieuws", user=self.user + ) + + file_path = self._get_file_path("feeds.opml") + + with open(file_path) as file: + self.form_data.update(file=file, skip_existing=True) + + response = self.client.post(self.url, self.form_data) + + self.assertEquals(response.status_code, 200) + + rules = CollectionRule.objects.all() + self.assertEquals(len(rules), 4) + + def test_empty_feed_file(self): + file_path = self._get_file_path("empty-feeds.opml") + + with open(file_path) as file: + self.form_data.update(file=file) + + response = self.client.post(self.url, self.form_data) + + self.assertEquals(response.status_code, 200) + + rules = CollectionRule.objects.all() + self.assertEquals(len(rules), 0) + + self.assertFormError(response, "form", "file", _("No (new) rules found")) + + def test_invalid_feeds(self): + file_path = self._get_file_path("invalid-url-feeds.opml") + + with open(file_path) as file: + self.form_data.update(file=file) + + response = self.client.post(self.url, self.form_data) + + self.assertEquals(response.status_code, 200) + + rules = CollectionRule.objects.all() + + self.assertEquals(len(rules), 0) + self.assertFormError(response, "form", "file", _("No (new) rules found")) + + def test_invalid_file(self): + file_path = self._get_file_path("test.png") + + with open(file_path, "rb") as file: + self.form_data.update(file=file) + + response = self.client.post(self.url, self.form_data) + + self.assertEquals(response.status_code, 200) + + rules = CollectionRule.objects.all() + self.assertEquals(len(rules), 0) + + self.assertFormError(response, "form", "file", _("Invalid OPML file")) + + def test_feeds_with_missing_attr(self): + file_path = self._get_file_path("missing-feeds.opml") + + with open(file_path) as file: + self.form_data.update(file=file) + + response = self.client.post(self.url, self.form_data) + + self.assertRedirects(response, reverse("rules")) + + rules = CollectionRule.objects.all() + self.assertEquals(len(rules), 2) diff --git a/src/newsreader/news/collection/urls.py b/src/newsreader/news/collection/urls.py index 16c80b7..28b6f38 100644 --- a/src/newsreader/news/collection/urls.py +++ b/src/newsreader/news/collection/urls.py @@ -11,6 +11,7 @@ from newsreader.news.collection.views import ( CollectionRuleCreateView, CollectionRuleListView, CollectionRuleUpdateView, + OPMLImportView, ) @@ -33,4 +34,5 @@ urlpatterns = [ login_required(CollectionRuleCreateView.as_view()), name="rule-create", ), + path("rules/import/", login_required(OPMLImportView.as_view()), name="import"), ] diff --git a/src/newsreader/news/collection/views.py b/src/newsreader/news/collection/views.py index 8919ddf..b62542c 100644 --- a/src/newsreader/news/collection/views.py +++ b/src/newsreader/news/collection/views.py @@ -1,14 +1,17 @@ from typing import Dict, Iterable +from django.contrib import messages from django.urls import reverse_lazy -from django.views.generic.edit import CreateView, UpdateView +from django.utils.translation import gettext_lazy as _ +from django.views.generic.edit import CreateView, FormView, UpdateView from django.views.generic.list import ListView import pytz -from newsreader.news.collection.forms import CollectionRuleForm +from newsreader.news.collection.forms import CollectionRuleForm, OPMLImportForm from newsreader.news.collection.models import CollectionRule from newsreader.news.core.models import Category +from newsreader.utils.opml import parse_opml class CollectionRuleViewMixin: @@ -56,3 +59,31 @@ class CollectionRuleCreateView( CollectionRuleViewMixin, CollectionRuleDetailMixin, CreateView ): template_name = "collection/rule-create.html" + + +class OPMLImportView(FormView): + form_class = OPMLImportForm + success_url = reverse_lazy("rules") + template_name = "collection/import.html" + + def form_valid(self, form): + user = self.request.user + file = form.cleaned_data["file"] + skip_existing = form.cleaned_data["skip_existing"] + + instances = parse_opml(file, user, skip_existing=skip_existing) + + try: + rules = CollectionRule.objects.bulk_create(instances) + except IOError: + form.add_error("file", _("Invalid OPML file")) + return self.form_invalid(form) + + if not rules: + form.add_error("file", _("No (new) rules found")) + return self.form_invalid(form) + + message = _(f"{len(rules)} new rules created") + messages.success(self.request, message) + + return super().form_valid(form) diff --git a/src/newsreader/scss/pages/import/components/import-form/_import-form.scss b/src/newsreader/scss/pages/import/components/import-form/_import-form.scss new file mode 100644 index 0000000..19acc5c --- /dev/null +++ b/src/newsreader/scss/pages/import/components/import-form/_import-form.scss @@ -0,0 +1,17 @@ +.import-form { + margin: 20px 0; + + &__fieldset:last-child { + display: flex; + flex-direction: row; + justify-content: space-between; + } + + & input[type=file] { + width: 50%; + } + + & input[type=checkbox] { + margin: 0 auto 0 10px; + } +} diff --git a/src/newsreader/scss/pages/import/components/import-form/index.scss b/src/newsreader/scss/pages/import/components/import-form/index.scss new file mode 100644 index 0000000..b6407f2 --- /dev/null +++ b/src/newsreader/scss/pages/import/components/import-form/index.scss @@ -0,0 +1 @@ +@import "import-form"; diff --git a/src/newsreader/scss/pages/import/components/index.scss b/src/newsreader/scss/pages/import/components/index.scss new file mode 100644 index 0000000..0bccecf --- /dev/null +++ b/src/newsreader/scss/pages/import/components/index.scss @@ -0,0 +1 @@ +@import "import-form/index"; diff --git a/src/newsreader/scss/pages/import/elements/index.scss b/src/newsreader/scss/pages/import/elements/index.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/newsreader/scss/pages/import/index.scss b/src/newsreader/scss/pages/import/index.scss new file mode 100644 index 0000000..16b6493 --- /dev/null +++ b/src/newsreader/scss/pages/import/index.scss @@ -0,0 +1,8 @@ +// General imports +@import "../../partials/variables"; +@import "../../components/index"; +@import "../../elements/index"; + +// Page specific +@import "./components/index"; +@import "./elements/index"; diff --git a/src/newsreader/scss/pages/rules/components/card/_card.scss b/src/newsreader/scss/pages/rules/components/card/_card.scss index ec09189..efc2418 100644 --- a/src/newsreader/scss/pages/rules/components/card/_card.scss +++ b/src/newsreader/scss/pages/rules/components/card/_card.scss @@ -8,6 +8,10 @@ padding: 0 10px; } } + + &--action > .button { + margin: 0 10px; + } } &__content { diff --git a/src/newsreader/utils/formatter.sh b/src/newsreader/utils/formatter.sh deleted file mode 100644 index de70b4a..0000000 --- a/src/newsreader/utils/formatter.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -FILES=$(git diff --cached --name-only --diff-filter=ACM "*.py" | sed 's| |\\ |g') - -if [ ! -z "$FILES" ]; then - # Format all selected files - echo "$FILES" | xargs ./env/bin/isort - - # Add back the modified/prettified files to staging - echo "$FILES" | xargs git add -fi diff --git a/src/newsreader/utils/opml.py b/src/newsreader/utils/opml.py new file mode 100644 index 0000000..55a9387 --- /dev/null +++ b/src/newsreader/utils/opml.py @@ -0,0 +1,41 @@ +import logging + +from django.core.exceptions import ValidationError +from django.core.validators import URLValidator + +from lxml.etree import XMLSyntaxError, parse + +from newsreader.news.collection.models import CollectionRule + + +def parse_opml(file, user, skip_existing=False): + known_urls = CollectionRule.objects.filter(user=user).values_list("url", flat=True) + + try: + tree = parse(file) + except XMLSyntaxError as e: + raise IOError("Invalid file") from e + + root = tree.getroot() + + validate = URLValidator(schemes=["http", "https"]) + + for element in root.iter(tag="outline"): + if not "xmlUrl" in element.keys(): + continue + + feed_url = element.get("xmlUrl") + name = element.get("text") + + if not all([feed_url, name]): + continue + elif skip_existing and feed_url in known_urls: + continue + + try: + validate(feed_url) + except ValidationError as e: + logging.info(f"Skipped due to invalid URL: {e}") + continue + + yield CollectionRule(url=feed_url, name=name, user=user) diff --git a/src/newsreader/utils/pre-commit b/src/newsreader/utils/pre-commit deleted file mode 100644 index d1e29b9..0000000 --- a/src/newsreader/utils/pre-commit +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -# Check if the directory is the root directory -if [ ! -d ".git/" ]; then - echo "Please commit from within the root directory" - exit 1 -fi - -# Run every file inside the pre-commit.d directory -for file in .git/hooks/pre-commit.d/* -do - . $file -done diff --git a/src/newsreader/utils/tests/__init__.py b/src/newsreader/utils/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/newsreader/utils/tests/files/empty-feeds.opml b/src/newsreader/utils/tests/files/empty-feeds.opml new file mode 100644 index 0000000..34ad8f2 --- /dev/null +++ b/src/newsreader/utils/tests/files/empty-feeds.opml @@ -0,0 +1,9 @@ + + + + Sat, 18 Jan 2020 17:32:03 +0000 + Tiny Tiny RSS Feed Export + + + + diff --git a/src/newsreader/utils/tests/files/feeds.opml b/src/newsreader/utils/tests/files/feeds.opml new file mode 100644 index 0000000..2cc14cf --- /dev/null +++ b/src/newsreader/utils/tests/files/feeds.opml @@ -0,0 +1,15 @@ + + + + Sat, 18 Jan 2020 17:32:03 +0000 + Tiny Tiny RSS Feed Export + + + + + + + + + + diff --git a/src/newsreader/utils/tests/files/invalid-url-feeds.opml b/src/newsreader/utils/tests/files/invalid-url-feeds.opml new file mode 100644 index 0000000..aad9a7f --- /dev/null +++ b/src/newsreader/utils/tests/files/invalid-url-feeds.opml @@ -0,0 +1,16 @@ + + + + Sat, 18 Jan 2020 17:32:03 +0000 + Tiny Tiny RSS Feed Export + + + + + + + + + + + diff --git a/src/newsreader/utils/tests/files/missing-feeds.opml b/src/newsreader/utils/tests/files/missing-feeds.opml new file mode 100644 index 0000000..22ac9a3 --- /dev/null +++ b/src/newsreader/utils/tests/files/missing-feeds.opml @@ -0,0 +1,17 @@ + + + + Sat, 18 Jan 2020 17:32:03 +0000 + Tiny Tiny RSS Feed Export + + + + + + + + + + + + diff --git a/src/newsreader/utils/tests/files/test.png b/src/newsreader/utils/tests/files/test.png new file mode 100644 index 0000000000000000000000000000000000000000..848a7ef196174c8d710428447b6825f0ef03ad5e GIT binary patch literal 81814 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 Ue#kfMMn8)`t9B;il=1EV17%&%cK`qY literal 0 HcmV?d00001 diff --git a/src/newsreader/utils/tests/test_opml.py b/src/newsreader/utils/tests/test_opml.py new file mode 100644 index 0000000..d2baf8f --- /dev/null +++ b/src/newsreader/utils/tests/test_opml.py @@ -0,0 +1,46 @@ +import os + +from pathlib import Path + +from django.test import TestCase + +from newsreader.accounts.tests.factories import UserFactory +from newsreader.utils.opml import parse_opml + + +class OPMImportTestCase(TestCase): + def setUp(self): + self.directory = Path(__file__).parent.absolute() + self.user = UserFactory() + + def test_simple(self): + path = os.path.join(self.directory, "files", "feeds.opml") + + with open(path, "r") as file: + rules = list(parse_opml(file, self.user)) + + self.assertEquals(len(rules), 4) + + def test_file_without_feeds(self): + path = os.path.join(self.directory, "files", "empty-feeds.opml") + + with open(path, "r") as file: + rules = list(parse_opml(file, self.user)) + + self.assertEquals(len(rules), 0) + + def test_file_with_missing_rule_properties(self): + path = os.path.join(self.directory, "files", "missing-feeds.opml") + + with open(path, "r") as file: + rules = list(parse_opml(file, self.user)) + + self.assertEquals(len(rules), 2) + + def test_url_validation(self): + path = os.path.join(self.directory, "files", "invalid-url-feeds.opml") + + with open(path, "r") as file: + rules = list(parse_opml(file, self.user)) + + self.assertEquals(len(rules), 0)