Update isort & rerun formatting

This commit is contained in:
Sonny 2019-07-01 12:11:44 +02:00
parent ed658c4dfd
commit 982c5bb132
51 changed files with 1993 additions and 1926 deletions

View file

@ -2,6 +2,11 @@
include_trailing_comma = true include_trailing_comma = true
line_length = 80 line_length = 80
multi_line_output = 3 multi_line_output = 3
skip = env/ skip = env/, venv/
forced_separate=django, newsreader default_section = THIRDPARTY
known_first_party = newsreader
known_django = django
sections = FUTURE,STDLIB,DJANGO,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
lines_between_types=1
lines_after_imports=2
lines_between_types=1 lines_between_types=1

View file

@ -12,6 +12,7 @@ https://docs.djangoproject.com/en/2.2/ref/settings/
import os import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...) # 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 = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@ -62,9 +63,9 @@ TEMPLATES = [
"django.template.context_processors.request", "django.template.context_processors.request",
"django.contrib.auth.context_processors.auth", "django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages", "django.contrib.messages.context_processors.messages",
], ]
}, },
}, }
] ]
WSGI_APPLICATION = "newsreader.wsgi.application" WSGI_APPLICATION = "newsreader.wsgi.application"
@ -82,19 +83,10 @@ DATABASES = {
# Password validation # Password validation
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators # https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [ AUTH_PASSWORD_VALIDATORS = [
{ {"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"},
"NAME": {"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"},
"django.contrib.auth.password_validation.UserAttributeSimilarityValidator", {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"},
}, {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
{
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
},
{
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
},
{
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
},
] ]
# Internationalization # Internationalization

View file

@ -1,5 +1,6 @@
from .base import * from .base import *
# Development settings # Development settings
DEBUG = True DEBUG = True

View file

@ -1,3 +1,4 @@
from django.contrib import admin from django.contrib import admin
# Register your models here. # Register your models here.

View file

@ -2,4 +2,4 @@ from django.apps import AppConfig
class CoreConfig(AppConfig): class CoreConfig(AppConfig):
name = 'core' name = "core"

View file

@ -6,6 +6,7 @@ class TimeStampedModel(models.Model):
An abstract base class model that provides self- An abstract base class model that provides self-
updating ``created`` and ``modified`` fields. updating ``created`` and ``modified`` fields.
""" """
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True) modified = models.DateTimeField(auto_now=True)

View file

@ -1,3 +1,4 @@
from django.test import TestCase from django.test import TestCase
# Create your tests here. # Create your tests here.

View file

@ -1,3 +1,4 @@
from django.shortcuts import render from django.shortcuts import render
# Create your views here. # Create your views here.

View file

@ -2,4 +2,4 @@ from django.apps import AppConfig
class CollectionConfig(AppConfig): class CollectionConfig(AppConfig):
name = 'collection' name = "collection"

View file

@ -1,11 +1,11 @@
from typing import ContextManager, Dict, List, Optional, Tuple from typing import ContextManager, Dict, List, Optional, Tuple
from django.utils import timezone
import requests import requests
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from django.utils import timezone
from newsreader.news.collection.exceptions import StreamParseException from newsreader.news.collection.exceptions import StreamParseException
from newsreader.news.collection.models import CollectionRule from newsreader.news.collection.models import CollectionRule
from newsreader.news.collection.utils import fetch from newsreader.news.collection.utils import fetch

View file

@ -13,6 +13,7 @@ from newsreader.news.collection.base import (
from newsreader.news.collection.exceptions import StreamException from newsreader.news.collection.exceptions import StreamException
from newsreader.news.collection.feed import FeedClient from newsreader.news.collection.feed import FeedClient
LINK_RELS = ["icon", "shortcut icon", "apple-touch-icon", "apple-touch-icon-precomposed"] LINK_RELS = ["icon", "shortcut icon", "apple-touch-icon", "apple-touch-icon-precomposed"]

View file

@ -1,13 +1,13 @@
from concurrent.futures import ThreadPoolExecutor, as_completed from concurrent.futures import ThreadPoolExecutor, as_completed
from typing import ContextManager, Dict, Generator, List, Optional, Tuple from typing import ContextManager, Dict, Generator, List, Optional, Tuple
from django.utils import timezone
import bleach import bleach
import pytz import pytz
from feedparser import parse from feedparser import parse
from django.utils import timezone
from newsreader.news.collection.base import Builder, Client, Collector, Stream from newsreader.news.collection.base import Builder, Client, Collector, Stream
from newsreader.news.collection.exceptions import ( from newsreader.news.collection.exceptions import (
StreamDeniedException, StreamDeniedException,

View file

@ -5,7 +5,7 @@ from newsreader.news.collection.models import CollectionRule
class Command(BaseCommand): class Command(BaseCommand):
help = 'Collects Atom/RSS feeds' help = "Collects Atom/RSS feeds"
def handle(self, *args, **options): def handle(self, *args, **options):
CollectionRule.objects.all() CollectionRule.objects.all()

View file

@ -11,21 +11,18 @@ class Migration(migrations.Migration):
operations = [ operations = [
migrations.CreateModel( migrations.CreateModel(
name='CollectionRule', name="CollectionRule",
fields=[ fields=[
( (
'id', "id",
models.AutoField( models.AutoField(
auto_created=True, auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
primary_key=True, ),
serialize=False,
verbose_name='ID'
)
), ),
('name', models.CharField(max_length=100)), ("name", models.CharField(max_length=100)),
('url', models.URLField()), ("url", models.URLField()),
('last_suceeded', models.DateTimeField()), ("last_suceeded", models.DateTimeField()),
('succeeded', models.BooleanField(default=False)), ("succeeded", models.BooleanField(default=False)),
], ],
), )
] ]

View file

@ -5,14 +5,12 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [("collection", "0001_initial")]
('collection', '0001_initial'),
]
operations = [ operations = [
migrations.AlterField( migrations.AlterField(
model_name='collectionrule', model_name="collectionrule",
name='last_suceeded', name="last_suceeded",
field=models.DateTimeField(blank=True, null=True), field=models.DateTimeField(blank=True, null=True),
), )
] ]

View file

@ -7,22 +7,19 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [("posts", "0002_auto_20190520_2206"), ("collection", "0002_auto_20190410_2028")]
('posts', '0002_auto_20190520_2206'),
('collection', '0002_auto_20190410_2028'),
]
operations = [ operations = [
migrations.AddField( migrations.AddField(
model_name='collectionrule', model_name="collectionrule",
name='category', name="category",
field=models.ForeignKey( field=models.ForeignKey(
blank=True, blank=True,
help_text='Posts from this rule will be tagged with this category', help_text="Posts from this rule will be tagged with this category",
null=True, null=True,
on_delete=django.db.models.deletion.SET_NULL, on_delete=django.db.models.deletion.SET_NULL,
to='posts.Category', to="posts.Category",
verbose_name='Category' verbose_name="Category",
), ),
), )
] ]

View file

@ -5,20 +5,18 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [("collection", "0004_collectionrule_timezone")]
('collection', '0004_collectionrule_timezone'),
]
operations = [ operations = [
migrations.AddField( migrations.AddField(
model_name='collectionrule', model_name="collectionrule",
name='favicon', name="favicon",
field=models.ImageField(blank=True, null=True, upload_to=''), field=models.ImageField(blank=True, null=True, upload_to=""),
), ),
migrations.AddField( migrations.AddField(
model_name='collectionrule', model_name="collectionrule",
name='source', name="source",
field=models.CharField(default='source', max_length=100), field=models.CharField(default="source", max_length=100),
preserve_default=False, preserve_default=False,
), ),
] ]

View file

@ -5,14 +5,12 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [("collection", "0005_auto_20190521_1941")]
('collection', '0005_auto_20190521_1941'),
]
operations = [ operations = [
migrations.AddField( migrations.AddField(
model_name='collectionrule', model_name="collectionrule",
name='error', name="error",
field=models.CharField(blank=True, max_length=255, null=True), field=models.CharField(blank=True, max_length=255, null=True),
), )
] ]

View file

@ -1,9 +1,9 @@
import pytz
from django.conf import settings from django.conf import settings
from django.db import models from django.db import models
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
import pytz
class CollectionRule(models.Model): class CollectionRule(models.Model):
name = models.CharField(max_length=100) name = models.CharField(max_length=100)

View file

@ -1,5 +1,6 @@
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
simple_mock = BeautifulSoup( simple_mock = BeautifulSoup(
""" """
<html> <html>

View file

@ -1,7 +1,7 @@
from freezegun import freeze_time
from django.test import TestCase from django.test import TestCase
from freezegun import freeze_time
from newsreader.news.collection.favicon import FaviconBuilder from newsreader.news.collection.favicon import FaviconBuilder
from newsreader.news.collection.tests.factories import CollectionRuleFactory from newsreader.news.collection.tests.factories import CollectionRuleFactory
from newsreader.news.collection.tests.favicon.builder.mocks import * from newsreader.news.collection.tests.favicon.builder.mocks import *

View file

@ -1,5 +1,6 @@
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
simple_mock = BeautifulSoup( simple_mock = BeautifulSoup(
""" """
<html> <html>

View file

@ -2,6 +2,7 @@ from time import struct_time
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
feed_mock = { feed_mock = {
"bozo": 0, "bozo": 0,
"encoding": "utf-8", "encoding": "utf-8",

View file

@ -1,14 +1,12 @@
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
from django.test import TestCase
from django.utils import timezone
import pytz import pytz
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from .mocks import feed_mock, website_mock
from django.test import TestCase
from django.utils import timezone
from newsreader.news.collection.exceptions import ( from newsreader.news.collection.exceptions import (
StreamDeniedException, StreamDeniedException,
StreamException, StreamException,
@ -20,6 +18,8 @@ from newsreader.news.collection.exceptions import (
from newsreader.news.collection.favicon import FaviconCollector from newsreader.news.collection.favicon import FaviconCollector
from newsreader.news.collection.tests.factories import CollectionRuleFactory from newsreader.news.collection.tests.factories import CollectionRuleFactory
from .mocks import feed_mock, website_mock
class FaviconCollectorTestCase(TestCase): class FaviconCollectorTestCase(TestCase):
def setUp(self): def setUp(self):

View file

@ -1,4 +1,4 @@
html_summary = ''' html_summary = """
<html> <html>
<body> <body>
<article> <article>
@ -7,4 +7,4 @@ html_summary = '''
</article> </article>
</body> </body>
</html> </html>
''' """

File diff suppressed because it is too large Load diff

View file

@ -1,20 +1,20 @@
from datetime import date, datetime, time from datetime import date, datetime, time
from unittest.mock import MagicMock from unittest.mock import MagicMock
from django.test import TestCase
from django.utils import timezone
import pytz import pytz
from freezegun import freeze_time from freezegun import freeze_time
from .mocks import *
from django.test import TestCase
from django.utils import timezone
from newsreader.news.collection.feed import FeedBuilder from newsreader.news.collection.feed import FeedBuilder
from newsreader.news.collection.tests.factories import CollectionRuleFactory from newsreader.news.collection.tests.factories import CollectionRuleFactory
from newsreader.news.posts.models import Post from newsreader.news.posts.models import Post
from newsreader.news.posts.tests.factories import PostFactory from newsreader.news.posts.tests.factories import PostFactory
from .mocks import *
class FeedBuilderTestCase(TestCase): class FeedBuilderTestCase(TestCase):
def setUp(self): def setUp(self):

View file

@ -1,61 +1,63 @@
from time import struct_time from time import struct_time
simple_mock = { simple_mock = {
'bozo': 0, "bozo": 0,
'encoding': 'utf-8', "encoding": "utf-8",
'entries': [{ "entries": [
'guidislink': False, {
'href': '', "guidislink": False,
'id': 'https://www.bbc.co.uk/news/world-us-canada-48338168', "href": "",
'link': 'https://www.bbc.co.uk/news/world-us-canada-48338168', "id": "https://www.bbc.co.uk/news/world-us-canada-48338168",
'links': [{ "link": "https://www.bbc.co.uk/news/world-us-canada-48338168",
'href': 'https://www.bbc.co.uk/news/world-us-canada-48338168', "links": [
'rel': 'alternate', {
'type': 'text/html' "href": "https://www.bbc.co.uk/news/world-us-canada-48338168",
}], "rel": "alternate",
'media_thumbnail': [{ "type": "text/html",
'height': '1152', }
'url': 'http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg', ],
'width': '2048' "media_thumbnail": [
}], {
'published': 'Mon, 20 May 2019 16:07:37 GMT', "height": "1152",
'published_parsed': struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), "url": "http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg",
'summary': 'Foreign Minister Mohammad Javad Zarif says the US ' "width": "2048",
'president should try showing Iranians some respect.', }
'summary_detail': { ],
'base': 'http://feeds.bbci.co.uk/news/rss.xml', "published": "Mon, 20 May 2019 16:07:37 GMT",
'language': None, "published_parsed": struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)),
'type': 'text/html', "summary": "Foreign Minister Mohammad Javad Zarif says the US "
'value': 'Foreign Minister Mohammad Javad ' "president should try showing Iranians some respect.",
'Zarif says the US president should ' "summary_detail": {
'try showing Iranians some ' "base": "http://feeds.bbci.co.uk/news/rss.xml",
'respect.' "language": None,
}, "type": "text/html",
'title': "Trump's 'genocidal taunts' will not end Iran - Zarif", "value": "Foreign Minister Mohammad Javad "
'title_detail': { "Zarif says the US president should "
'base': 'http://feeds.bbci.co.uk/news/rss.xml', "try showing Iranians some "
'language': None, "respect.",
'type': 'text/plain',
'value': "Trump's 'genocidal taunts' will not "
'end Iran - Zarif'
}
}],
'feed': {
'image': {
'href': 'https://news.bbcimg.co.uk/nol/shared/img/bbc_news_120x60.gif',
'link': 'https://www.bbc.co.uk/news/',
'title': 'BBC News - Home',
'language': 'en-gb',
'link': 'https://www.bbc.co.uk/news/'
}, },
'links': [{ "title": "Trump's 'genocidal taunts' will not end Iran - Zarif",
'href': 'https://www.bbc.co.uk/news/', "title_detail": {
'rel': 'alternate', "base": "http://feeds.bbci.co.uk/news/rss.xml",
'type': 'text/html' "language": None,
}], "type": "text/plain",
'title': 'BBC News - Home', "value": "Trump's 'genocidal taunts' will not " "end Iran - Zarif",
},
}
],
"feed": {
"image": {
"href": "https://news.bbcimg.co.uk/nol/shared/img/bbc_news_120x60.gif",
"link": "https://www.bbc.co.uk/news/",
"title": "BBC News - Home",
"language": "en-gb",
"link": "https://www.bbc.co.uk/news/",
},
"links": [{"href": "https://www.bbc.co.uk/news/", "rel": "alternate", "type": "text/html"}],
"title": "BBC News - Home",
}, },
'href': 'http://feeds.bbci.co.uk/news/rss.xml', "href": "http://feeds.bbci.co.uk/news/rss.xml",
'status': 200, "status": 200,
'version': 'rss20' "version": "rss20",
} }

View file

@ -1,7 +1,5 @@
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
from .mocks import simple_mock
from django.test import TestCase from django.test import TestCase
from django.utils import timezone from django.utils import timezone
@ -15,6 +13,8 @@ from newsreader.news.collection.exceptions import (
from newsreader.news.collection.feed import FeedClient from newsreader.news.collection.feed import FeedClient
from newsreader.news.collection.tests.factories import CollectionRuleFactory from newsreader.news.collection.tests.factories import CollectionRuleFactory
from .mocks import simple_mock
class FeedClientTestCase(TestCase): class FeedClientTestCase(TestCase):
def setUp(self): def setUp(self):

View file

@ -1,430 +1,442 @@
from time import struct_time from time import struct_time
multiple_mock = { multiple_mock = {
'bozo': 0, "bozo": 0,
'encoding': 'utf-8', "encoding": "utf-8",
'entries': [ "entries": [
{ {
'guidislink': False, "guidislink": False,
'href': '', "href": "",
'id': 'https://www.bbc.co.uk/news/world-us-canada-48338168', "id": "https://www.bbc.co.uk/news/world-us-canada-48338168",
'link': 'https://www.bbc.co.uk/news/world-us-canada-48338168', "link": "https://www.bbc.co.uk/news/world-us-canada-48338168",
'links': [{ "links": [
'href': 'https://www.bbc.co.uk/news/world-us-canada-48338168', {
'rel': 'alternate', "href": "https://www.bbc.co.uk/news/world-us-canada-48338168",
'type': 'text/html' "rel": "alternate",
}], "type": "text/html",
'media_thumbnail': [{ }
'height': '1152', ],
'url': 'http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg', "media_thumbnail": [
'width': '2048' {
}], "height": "1152",
'published': 'Mon, 20 May 2019 16:07:37 GMT', "url": "http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg",
'published_parsed': struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), "width": "2048",
'summary': 'Foreign Minister Mohammad Javad Zarif says the US ' }
'president should try showing Iranians some respect.', ],
'summary_detail': { "published": "Mon, 20 May 2019 16:07:37 GMT",
'base': 'http://feeds.bbci.co.uk/news/rss.xml', "published_parsed": struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)),
'language': None, "summary": "Foreign Minister Mohammad Javad Zarif says the US "
'type': 'text/html', "president should try showing Iranians some respect.",
'value': 'Foreign Minister Mohammad Javad ' "summary_detail": {
'Zarif says the US president should ' "base": "http://feeds.bbci.co.uk/news/rss.xml",
'try showing Iranians some ' "language": None,
'respect.' "type": "text/html",
"value": "Foreign Minister Mohammad Javad "
"Zarif says the US president should "
"try showing Iranians some "
"respect.",
},
"title": "Trump's 'genocidal taunts' will not end Iran - Zarif",
"title_detail": {
"base": "http://feeds.bbci.co.uk/news/rss.xml",
"language": None,
"type": "text/plain",
"value": "Trump's 'genocidal taunts' will not " "end Iran - Zarif",
}, },
'title': "Trump's 'genocidal taunts' will not end Iran - Zarif",
'title_detail': {
'base': 'http://feeds.bbci.co.uk/news/rss.xml',
'language': None,
'type': 'text/plain',
'value': "Trump's 'genocidal taunts' will not "
'end Iran - Zarif'
}
}, },
{ {
'guidislink': False, "guidislink": False,
'href': '', "href": "",
'id': 'https://www.bbc.co.uk/news/technology-48334739', "id": "https://www.bbc.co.uk/news/technology-48334739",
'link': 'https://www.bbc.co.uk/news/technology-48334739', "link": "https://www.bbc.co.uk/news/technology-48334739",
'links': [{ "links": [
'href': 'https://www.bbc.co.uk/news/technology-48334739', {
'rel': 'alternate', "href": "https://www.bbc.co.uk/news/technology-48334739",
'type': 'text/html' "rel": "alternate",
}], "type": "text/html",
'media_thumbnail': [{ }
'height': '432', ],
'url': 'http://c.files.bbci.co.uk/4789/production/_107031381_mediaitem107028670.jpg', "media_thumbnail": [
'width': '768' {
}], "height": "432",
'published': 'Mon, 20 May 2019 12:19:19 GMT', "url": "http://c.files.bbci.co.uk/4789/production/_107031381_mediaitem107028670.jpg",
'published_parsed': struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0,)), "width": "768",
'summary': "Google's move to end business ties with Huawei will " }
'affect current devices and future purchases.', ],
'summary_detail': { "published": "Mon, 20 May 2019 12:19:19 GMT",
'base': 'http://feeds.bbci.co.uk/news/rss.xml', "published_parsed": struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0)),
'language': None, "summary": "Google's move to end business ties with Huawei will "
'type': 'text/html', "affect current devices and future purchases.",
'value': "Google's move to end business ties " "summary_detail": {
'with Huawei will affect current ' "base": "http://feeds.bbci.co.uk/news/rss.xml",
'devices and future purchases.' "language": None,
"type": "text/html",
"value": "Google's move to end business ties "
"with Huawei will affect current "
"devices and future purchases.",
},
"title": "Huawei's Android loss: How it affects you",
"title_detail": {
"base": "http://feeds.bbci.co.uk/news/rss.xml",
"language": None,
"type": "text/plain",
"value": "Huawei's Android loss: How it " "affects you",
}, },
'title': "Huawei's Android loss: How it affects you",
'title_detail': {
'base': 'http://feeds.bbci.co.uk/news/rss.xml',
'language': None,
'type': 'text/plain',
'value': "Huawei's Android loss: How it "
'affects you'
}
}, },
{ {
'guidislink': False, "guidislink": False,
'href': '', "href": "",
'id': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', "id": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
'link': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', "link": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
'links': [{ "links": [
'href': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', {
'rel': 'alternate', "href": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
'type': 'text/html' "rel": "alternate",
}], "type": "text/html",
'media_thumbnail': [{ }
'height': '549', ],
'url': 'http://c.files.bbci.co.uk/11D67/production/_107036037_lgbtheadjpg.jpg', "media_thumbnail": [
'width': '976' {
}], "height": "549",
'published': 'Mon, 20 May 2019 16:32:38 GMT', "url": "http://c.files.bbci.co.uk/11D67/production/_107036037_lgbtheadjpg.jpg",
'published_parsed': struct_time((2019, 5, 20, 16, 32, 38, 0, 140, 0)), "width": "976",
'summary': 'Police are investigating the messages while an MP ' }
],
"published": "Mon, 20 May 2019 16:32:38 GMT",
"published_parsed": struct_time((2019, 5, 20, 16, 32, 38, 0, 140, 0)),
"summary": "Police are investigating the messages while an MP "
'calls for a protest exclusion zone "to protect ' 'calls for a protest exclusion zone "to protect '
'children".', 'children".',
'summary_detail': { "summary_detail": {
'base': 'http://feeds.bbci.co.uk/news/rss.xml', "base": "http://feeds.bbci.co.uk/news/rss.xml",
'language': None, "language": None,
'type': 'text/html', "type": "text/html",
'value': 'Police are investigating the ' "value": "Police are investigating the "
'messages while an MP calls for a ' "messages while an MP calls for a "
'protest exclusion zone "to protect ' 'protest exclusion zone "to protect '
'children".' 'children".',
},
"title": "Birmingham head teacher threatened over LGBT lessons",
"title_detail": {
"base": "http://feeds.bbci.co.uk/news/rss.xml",
"language": None,
"type": "text/plain",
"value": "Birmingham head teacher threatened " "over LGBT lessons",
}, },
'title': 'Birmingham head teacher threatened over LGBT lessons',
'title_detail': {
'base': 'http://feeds.bbci.co.uk/news/rss.xml',
'language': None,
'type': 'text/plain',
'value': 'Birmingham head teacher threatened '
'over LGBT lessons'
}
}, },
], ],
'feed': { "feed": {
'image': { "image": {
'href': 'https://news.bbcimg.co.uk/nol/shared/img/bbc_news_120x60.gif', "href": "https://news.bbcimg.co.uk/nol/shared/img/bbc_news_120x60.gif",
'link': 'https://www.bbc.co.uk/news/', "link": "https://www.bbc.co.uk/news/",
'title': 'BBC News - Home', "title": "BBC News - Home",
'language': 'en-gb', "language": "en-gb",
'link': 'https://www.bbc.co.uk/news/' "link": "https://www.bbc.co.uk/news/",
}, },
'links': [{ "links": [{"href": "https://www.bbc.co.uk/news/", "rel": "alternate", "type": "text/html"}],
'href': 'https://www.bbc.co.uk/news/', "title": "BBC News - Home",
'rel': 'alternate',
'type': 'text/html'
}],
'title': 'BBC News - Home',
}, },
'href': 'http://feeds.bbci.co.uk/news/rss.xml', "href": "http://feeds.bbci.co.uk/news/rss.xml",
'status': 200, "status": 200,
'version': 'rss20' "version": "rss20",
} }
empty_mock = { empty_mock = {
'bozo': 0, "bozo": 0,
'encoding': 'utf-8', "encoding": "utf-8",
'entries': [], "entries": [],
'feed': { "feed": {
'image': { "image": {
'href': 'https://news.bbcimg.co.uk/nol/shared/img/bbc_news_120x60.gif', "href": "https://news.bbcimg.co.uk/nol/shared/img/bbc_news_120x60.gif",
'link': 'https://www.bbc.co.uk/news/', "link": "https://www.bbc.co.uk/news/",
'title': 'BBC News - Home', "title": "BBC News - Home",
'language': 'en-gb', "language": "en-gb",
'link': 'https://www.bbc.co.uk/news/' "link": "https://www.bbc.co.uk/news/",
}, },
'links': [{ "links": [{"href": "https://www.bbc.co.uk/news/", "rel": "alternate", "type": "text/html"}],
'href': 'https://www.bbc.co.uk/news/', "title": "BBC News - Home",
'rel': 'alternate',
'type': 'text/html'
}],
'title': 'BBC News - Home',
}, },
'href': 'http://feeds.bbci.co.uk/news/rss.xml', "href": "http://feeds.bbci.co.uk/news/rss.xml",
'status': 200, "status": 200,
'version': 'rss20' "version": "rss20",
} }
duplicate_mock = { duplicate_mock = {
'bozo': 0, "bozo": 0,
'encoding': 'utf-8', "encoding": "utf-8",
'entries': [ "entries": [
{ {
'guidislink': False, "guidislink": False,
'href': '', "href": "",
'link': 'https://www.bbc.co.uk/news/world-us-canada-48338168', "link": "https://www.bbc.co.uk/news/world-us-canada-48338168",
'links': [{ "links": [
'href': 'https://www.bbc.co.uk/news/world-us-canada-48338168', {
'rel': 'alternate', "href": "https://www.bbc.co.uk/news/world-us-canada-48338168",
'type': 'text/html' "rel": "alternate",
}], "type": "text/html",
'media_thumbnail': [{ }
'height': '1152', ],
'url': 'http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg', "media_thumbnail": [
'width': '2048' {
}], "height": "1152",
'published': 'Mon, 20 May 2019 16:07:37 GMT', "url": "http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg",
'published_parsed': struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), "width": "2048",
'summary': 'Foreign Minister Mohammad Javad Zarif says the US ' }
'president should try showing Iranians some respect.', ],
'summary_detail': { "published": "Mon, 20 May 2019 16:07:37 GMT",
'base': 'http://feeds.bbci.co.uk/news/rss.xml', "published_parsed": struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)),
'language': None, "summary": "Foreign Minister Mohammad Javad Zarif says the US "
'type': 'text/html', "president should try showing Iranians some respect.",
'value': 'Foreign Minister Mohammad Javad ' "summary_detail": {
'Zarif says the US president should ' "base": "http://feeds.bbci.co.uk/news/rss.xml",
'try showing Iranians some ' "language": None,
'respect.' "type": "text/html",
"value": "Foreign Minister Mohammad Javad "
"Zarif says the US president should "
"try showing Iranians some "
"respect.",
},
"title": "Trump's 'genocidal taunts' will not end Iran - Zarif",
"title_detail": {
"base": "http://feeds.bbci.co.uk/news/rss.xml",
"language": None,
"type": "text/plain",
"value": "Trump's 'genocidal taunts' will not " "end Iran - Zarif",
}, },
'title': "Trump's 'genocidal taunts' will not end Iran - Zarif",
'title_detail': {
'base': 'http://feeds.bbci.co.uk/news/rss.xml',
'language': None,
'type': 'text/plain',
'value': "Trump's 'genocidal taunts' will not "
'end Iran - Zarif'
}
}, },
{ {
'guidislink': False, "guidislink": False,
'href': '', "href": "",
'link': 'https://www.bbc.co.uk/news/technology-48334739', "link": "https://www.bbc.co.uk/news/technology-48334739",
'links': [{ "links": [
'href': 'https://www.bbc.co.uk/news/technology-48334739', {
'rel': 'alternate', "href": "https://www.bbc.co.uk/news/technology-48334739",
'type': 'text/html' "rel": "alternate",
}], "type": "text/html",
'media_thumbnail': [{ }
'height': '432', ],
'url': 'http://c.files.bbci.co.uk/4789/production/_107031381_mediaitem107028670.jpg', "media_thumbnail": [
'width': '768' {
}], "height": "432",
'published': 'Mon, 20 May 2019 12:19:19 GMT', "url": "http://c.files.bbci.co.uk/4789/production/_107031381_mediaitem107028670.jpg",
'published_parsed': struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0,)), "width": "768",
'summary': "Google's move to end business ties with Huawei will " }
'affect current devices and future purchases.', ],
'summary_detail': { "published": "Mon, 20 May 2019 12:19:19 GMT",
'base': 'http://feeds.bbci.co.uk/news/rss.xml', "published_parsed": struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0)),
'language': None, "summary": "Google's move to end business ties with Huawei will "
'type': 'text/html', "affect current devices and future purchases.",
'value': "Google's move to end business ties " "summary_detail": {
'with Huawei will affect current ' "base": "http://feeds.bbci.co.uk/news/rss.xml",
'devices and future purchases.' "language": None,
"type": "text/html",
"value": "Google's move to end business ties "
"with Huawei will affect current "
"devices and future purchases.",
},
"title": "Huawei's Android loss: How it affects you",
"title_detail": {
"base": "http://feeds.bbci.co.uk/news/rss.xml",
"language": None,
"type": "text/plain",
"value": "Huawei's Android loss: How it " "affects you",
}, },
'title': "Huawei's Android loss: How it affects you",
'title_detail': {
'base': 'http://feeds.bbci.co.uk/news/rss.xml',
'language': None,
'type': 'text/plain',
'value': "Huawei's Android loss: How it "
'affects you'
}
}, },
{ {
'guidislink': False, "guidislink": False,
'href': '', "href": "",
'link': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', "link": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
'links': [{ "links": [
'href': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', {
'rel': 'alternate', "href": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
'type': 'text/html' "rel": "alternate",
}], "type": "text/html",
'media_thumbnail': [{ }
'height': '549', ],
'url': 'http://c.files.bbci.co.uk/11D67/production/_107036037_lgbtheadjpg.jpg', "media_thumbnail": [
'width': '976' {
}], "height": "549",
'published': 'Mon, 20 May 2019 16:32:38 GMT', "url": "http://c.files.bbci.co.uk/11D67/production/_107036037_lgbtheadjpg.jpg",
'published_parsed': struct_time((2019, 5, 20, 16, 32, 38, 0, 140, 0)), "width": "976",
'summary': 'Police are investigating the messages while an MP ' }
],
"published": "Mon, 20 May 2019 16:32:38 GMT",
"published_parsed": struct_time((2019, 5, 20, 16, 32, 38, 0, 140, 0)),
"summary": "Police are investigating the messages while an MP "
'calls for a protest exclusion zone "to protect ' 'calls for a protest exclusion zone "to protect '
'children".', 'children".',
'summary_detail': { "summary_detail": {
'base': 'http://feeds.bbci.co.uk/news/rss.xml', "base": "http://feeds.bbci.co.uk/news/rss.xml",
'language': None, "language": None,
'type': 'text/html', "type": "text/html",
'value': 'Police are investigating the ' "value": "Police are investigating the "
'messages while an MP calls for a ' "messages while an MP calls for a "
'protest exclusion zone "to protect ' 'protest exclusion zone "to protect '
'children".' 'children".',
},
"title": "Birmingham head teacher threatened over LGBT lessons",
"title_detail": {
"base": "http://feeds.bbci.co.uk/news/rss.xml",
"language": None,
"type": "text/plain",
"value": "Birmingham head teacher threatened " "over LGBT lessons",
}, },
'title': 'Birmingham head teacher threatened over LGBT lessons',
'title_detail': {
'base': 'http://feeds.bbci.co.uk/news/rss.xml',
'language': None,
'type': 'text/plain',
'value': 'Birmingham head teacher threatened '
'over LGBT lessons'
}
}, },
], ],
'feed': { "feed": {
'image': { "image": {
'href': 'https://news.bbcimg.co.uk/nol/shared/img/bbc_news_120x60.gif', "href": "https://news.bbcimg.co.uk/nol/shared/img/bbc_news_120x60.gif",
'link': 'https://www.bbc.co.uk/news/', "link": "https://www.bbc.co.uk/news/",
'title': 'BBC News - Home', "title": "BBC News - Home",
'language': 'en-gb', "language": "en-gb",
'link': 'https://www.bbc.co.uk/news/' "link": "https://www.bbc.co.uk/news/",
}, },
'links': [{ "links": [{"href": "https://www.bbc.co.uk/news/", "rel": "alternate", "type": "text/html"}],
'href': 'https://www.bbc.co.uk/news/', "title": "BBC News - Home",
'rel': 'alternate',
'type': 'text/html'
}],
'title': 'BBC News - Home',
}, },
'href': 'http://feeds.bbci.co.uk/news/rss.xml', "href": "http://feeds.bbci.co.uk/news/rss.xml",
'status': 200, "status": 200,
'version': 'rss20' "version": "rss20",
} }
multiple_update_mock = { multiple_update_mock = {
'bozo': 0, "bozo": 0,
'encoding': 'utf-8', "encoding": "utf-8",
'entries': [ "entries": [
{ {
'guidislink': False, "guidislink": False,
'href': '', "href": "",
'id': 'https://www.bbc.co.uk/news/world-us-canada-48338168', "id": "https://www.bbc.co.uk/news/world-us-canada-48338168",
'link': 'https://www.bbc.co.uk/news/world-us-canada-48338168', "link": "https://www.bbc.co.uk/news/world-us-canada-48338168",
'links': [{ "links": [
'href': 'https://www.bbc.co.uk/news/world-us-canada-48338168', {
'rel': 'alternate', "href": "https://www.bbc.co.uk/news/world-us-canada-48338168",
'type': 'text/html' "rel": "alternate",
}], "type": "text/html",
'media_thumbnail': [{ }
'height': '1152', ],
'url': 'http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg', "media_thumbnail": [
'width': '2048' {
}], "height": "1152",
'published': 'Mon, 20 May 2019 16:07:37 GMT', "url": "http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg",
'published_parsed': struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), "width": "2048",
'summary': 'Foreign Minister Mohammad Javad Zarif says the US ' }
'president should try showing Iranians some respect.', ],
'summary_detail': { "published": "Mon, 20 May 2019 16:07:37 GMT",
'base': 'http://feeds.bbci.co.uk/news/rss.xml', "published_parsed": struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)),
'language': None, "summary": "Foreign Minister Mohammad Javad Zarif says the US "
'type': 'text/html', "president should try showing Iranians some respect.",
'value': 'Foreign Minister Mohammad Javad ' "summary_detail": {
'Zarif says the US president should ' "base": "http://feeds.bbci.co.uk/news/rss.xml",
'try showing Iranians some ' "language": None,
'respect.' "type": "text/html",
"value": "Foreign Minister Mohammad Javad "
"Zarif says the US president should "
"try showing Iranians some "
"respect.",
},
"title": "Trump's 'genocidal taunts' will not end Iran - Zarif",
"title_detail": {
"base": "http://feeds.bbci.co.uk/news/rss.xml",
"language": None,
"type": "text/plain",
"value": "Trump's 'genocidal taunts' will not " "end Iran - Zarif",
}, },
'title': "Trump's 'genocidal taunts' will not end Iran - Zarif",
'title_detail': {
'base': 'http://feeds.bbci.co.uk/news/rss.xml',
'language': None,
'type': 'text/plain',
'value': "Trump's 'genocidal taunts' will not "
'end Iran - Zarif'
}
}, },
{ {
'guidislink': False, "guidislink": False,
'href': '', "href": "",
'id': 'https://www.bbc.co.uk/news/technology-48334739', "id": "https://www.bbc.co.uk/news/technology-48334739",
'link': 'https://www.bbc.co.uk/news/technology-48334739', "link": "https://www.bbc.co.uk/news/technology-48334739",
'links': [{ "links": [
'href': 'https://www.bbc.co.uk/news/technology-48334739', {
'rel': 'alternate', "href": "https://www.bbc.co.uk/news/technology-48334739",
'type': 'text/html' "rel": "alternate",
}], "type": "text/html",
'media_thumbnail': [{ }
'height': '432', ],
'url': 'http://c.files.bbci.co.uk/4789/production/_107031381_mediaitem107028670.jpg', "media_thumbnail": [
'width': '768' {
}], "height": "432",
'published': 'Mon, 20 May 2019 12:19:19 GMT', "url": "http://c.files.bbci.co.uk/4789/production/_107031381_mediaitem107028670.jpg",
'published_parsed': struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0,)), "width": "768",
'summary': "Google's move to end business ties with Huawei will " }
'affect current devices and future purchases.', ],
'summary_detail': { "published": "Mon, 20 May 2019 12:19:19 GMT",
'base': 'http://feeds.bbci.co.uk/news/rss.xml', "published_parsed": struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0)),
'language': None, "summary": "Google's move to end business ties with Huawei will "
'type': 'text/html', "affect current devices and future purchases.",
'value': "Google's move to end business ties " "summary_detail": {
'with Huawei will affect current ' "base": "http://feeds.bbci.co.uk/news/rss.xml",
'devices and future purchases.' "language": None,
"type": "text/html",
"value": "Google's move to end business ties "
"with Huawei will affect current "
"devices and future purchases.",
},
"title": "Huawei's Android loss: How it affects you",
"title_detail": {
"base": "http://feeds.bbci.co.uk/news/rss.xml",
"language": None,
"type": "text/plain",
"value": "Huawei's Android loss: How it " "affects you",
}, },
'title': "Huawei's Android loss: How it affects you",
'title_detail': {
'base': 'http://feeds.bbci.co.uk/news/rss.xml',
'language': None,
'type': 'text/plain',
'value': "Huawei's Android loss: How it "
'affects you'
}
}, },
{ {
'guidislink': False, "guidislink": False,
'href': '', "href": "",
'id': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', "id": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
'link': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', "link": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
'links': [{ "links": [
'href': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', {
'rel': 'alternate', "href": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
'type': 'text/html' "rel": "alternate",
}], "type": "text/html",
'media_thumbnail': [{ }
'height': '549', ],
'url': 'http://c.files.bbci.co.uk/11D67/production/_107036037_lgbtheadjpg.jpg', "media_thumbnail": [
'width': '976' {
}], "height": "549",
'published': 'Mon, 20 May 2019 16:32:38 GMT', "url": "http://c.files.bbci.co.uk/11D67/production/_107036037_lgbtheadjpg.jpg",
'published_parsed': struct_time((2019, 5, 20, 16, 32, 38, 0, 140, 0)), "width": "976",
'summary': 'Police are investigating the messages while an MP ' }
],
"published": "Mon, 20 May 2019 16:32:38 GMT",
"published_parsed": struct_time((2019, 5, 20, 16, 32, 38, 0, 140, 0)),
"summary": "Police are investigating the messages while an MP "
'calls for a protest exclusion zone "to protect ' 'calls for a protest exclusion zone "to protect '
'children".', 'children".',
'summary_detail': { "summary_detail": {
'base': 'http://feeds.bbci.co.uk/news/rss.xml', "base": "http://feeds.bbci.co.uk/news/rss.xml",
'language': None, "language": None,
'type': 'text/html', "type": "text/html",
'value': 'Police are investigating the ' "value": "Police are investigating the "
'messages while an MP calls for a ' "messages while an MP calls for a "
'protest exclusion zone "to protect ' 'protest exclusion zone "to protect '
'children".' 'children".',
},
"title": "Birmingham head teacher threatened over LGBT lessons",
"title_detail": {
"base": "http://feeds.bbci.co.uk/news/rss.xml",
"language": None,
"type": "text/plain",
"value": "Birmingham head teacher threatened " "over LGBT lessons",
}, },
'title': 'Birmingham head teacher threatened over LGBT lessons',
'title_detail': {
'base': 'http://feeds.bbci.co.uk/news/rss.xml',
'language': None,
'type': 'text/plain',
'value': 'Birmingham head teacher threatened '
'over LGBT lessons'
}
}, },
], ],
'feed': { "feed": {
'image': { "image": {
'href': 'https://news.bbcimg.co.uk/nol/shared/img/bbc_news_120x60.gif', "href": "https://news.bbcimg.co.uk/nol/shared/img/bbc_news_120x60.gif",
'link': 'https://www.bbc.co.uk/news/', "link": "https://www.bbc.co.uk/news/",
'title': 'BBC News - Home', "title": "BBC News - Home",
'language': 'en-gb', "language": "en-gb",
'link': 'https://www.bbc.co.uk/news/' "link": "https://www.bbc.co.uk/news/",
}, },
'links': [{ "links": [{"href": "https://www.bbc.co.uk/news/", "rel": "alternate", "type": "text/html"}],
'href': 'https://www.bbc.co.uk/news/', "title": "BBC News - Home",
'rel': 'alternate',
'type': 'text/html'
}],
'title': 'BBC News - Home',
}, },
'href': 'http://feeds.bbci.co.uk/news/rss.xml', "href": "http://feeds.bbci.co.uk/news/rss.xml",
'status': 200, "status": 200,
'version': 'rss20' "version": "rss20",
} }

View file

@ -2,20 +2,13 @@ from datetime import date, datetime, time
from time import struct_time from time import struct_time
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
from django.test import TestCase
from django.utils import timezone
import pytz import pytz
from freezegun import freeze_time from freezegun import freeze_time
from .mocks import (
duplicate_mock,
empty_mock,
multiple_mock,
multiple_update_mock,
)
from django.test import TestCase
from django.utils import timezone
from newsreader.news.collection.exceptions import ( from newsreader.news.collection.exceptions import (
StreamDeniedException, StreamDeniedException,
StreamException, StreamException,
@ -30,6 +23,13 @@ from newsreader.news.collection.utils import build_publication_date
from newsreader.news.posts.models import Post from newsreader.news.posts.models import Post
from newsreader.news.posts.tests.factories import PostFactory from newsreader.news.posts.tests.factories import PostFactory
from .mocks import (
duplicate_mock,
empty_mock,
multiple_mock,
multiple_update_mock,
)
class FeedCollectorTestCase(TestCase): class FeedCollectorTestCase(TestCase):
def setUp(self): def setUp(self):

View file

@ -1,5 +1,6 @@
from time import struct_time from time import struct_time
simple_mock = { simple_mock = {
"bozo": 1, "bozo": 1,
"encoding": "utf-8", "encoding": "utf-8",

View file

@ -1,7 +1,5 @@
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
from .mocks import simple_mock
from django.test import TestCase from django.test import TestCase
from django.utils import timezone from django.utils import timezone
@ -16,6 +14,8 @@ from newsreader.news.collection.exceptions import (
from newsreader.news.collection.feed import FeedStream from newsreader.news.collection.feed import FeedStream
from newsreader.news.collection.tests.factories import CollectionRuleFactory from newsreader.news.collection.tests.factories import CollectionRuleFactory
from .mocks import simple_mock
class FeedStreamTestCase(TestCase): class FeedStreamTestCase(TestCase):
def setUp(self): def setUp(self):

View file

@ -1,11 +1,9 @@
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
from bs4 import BeautifulSoup
from .mocks import feed_mock_without_link, simple_feed_mock, simple_mock
from django.test import TestCase from django.test import TestCase
from bs4 import BeautifulSoup
from newsreader.news.collection.base import URLBuilder, WebsiteStream from newsreader.news.collection.base import URLBuilder, WebsiteStream
from newsreader.news.collection.exceptions import ( from newsreader.news.collection.exceptions import (
StreamDeniedException, StreamDeniedException,
@ -17,6 +15,8 @@ from newsreader.news.collection.exceptions import (
) )
from newsreader.news.collection.tests.factories import CollectionRuleFactory from newsreader.news.collection.tests.factories import CollectionRuleFactory
from .mocks import feed_mock_without_link, simple_feed_mock, simple_mock
class WebsiteStreamTestCase(TestCase): class WebsiteStreamTestCase(TestCase):
def setUp(self): def setUp(self):

View file

@ -1,5 +1,7 @@
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
from django.test import TestCase
from requests.exceptions import ConnectionError as RequestConnectionError from requests.exceptions import ConnectionError as RequestConnectionError
from requests.exceptions import ( from requests.exceptions import (
HTTPError, HTTPError,
@ -8,8 +10,6 @@ from requests.exceptions import (
TooManyRedirects, TooManyRedirects,
) )
from django.test import TestCase
from newsreader.news.collection.exceptions import ( from newsreader.news.collection.exceptions import (
StreamConnectionError, StreamConnectionError,
StreamDeniedException, StreamDeniedException,

View file

@ -2,13 +2,13 @@ from datetime import datetime, tzinfo
from time import mktime, struct_time from time import mktime, struct_time
from typing import Tuple from typing import Tuple
from django.utils import timezone
import requests import requests
from requests.exceptions import RequestException from requests.exceptions import RequestException
from requests.models import Response from requests.models import Response
from django.utils import timezone
from newsreader.news.collection.response_handler import ResponseHandler from newsreader.news.collection.response_handler import ResponseHandler

View file

@ -1,3 +1,4 @@
from django.shortcuts import render from django.shortcuts import render
# Create your views here. # Create your views here.

View file

@ -4,26 +4,13 @@ from newsreader.news.posts.models import Category, Post
class PostAdmin(admin.ModelAdmin): class PostAdmin(admin.ModelAdmin):
list_display = ( list_display = ("publication_date", "author", "rule", "title")
"publication_date", list_display_links = ("title",)
"author", list_filter = ("rule",)
"rule",
"title",
)
list_display_links = ("title", )
list_filter = ("rule", )
ordering = ("-publication_date", "title") ordering = ("-publication_date", "title")
fields = ( fields = ("title", "body", "author", "publication_date", "url", "remote_identifier", "category")
"title",
"body",
"author",
"publication_date",
"url",
"remote_identifier",
"category",
)
search_fields = ["title"] search_fields = ["title"]

View file

@ -2,4 +2,4 @@ from django.apps import AppConfig
class PostsConfig(AppConfig): class PostsConfig(AppConfig):
name = 'posts' name = "posts"

View file

@ -9,70 +9,57 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [("collection", "0001_initial")]
('collection', '0001_initial'),
]
operations = [ operations = [
migrations.CreateModel( migrations.CreateModel(
name='Category', name="Category",
fields=[ fields=[
( (
'id', "id",
models.AutoField( models.AutoField(
auto_created=True, auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
primary_key=True, ),
serialize=False,
verbose_name='ID'
)
), ),
('created', models.DateTimeField(auto_now_add=True)), ("created", models.DateTimeField(auto_now_add=True)),
('modified', models.DateTimeField(auto_now=True)), ("modified", models.DateTimeField(auto_now=True)),
('name', models.CharField(max_length=50)), ("name", models.CharField(max_length=50)),
], ],
options={ options={"abstract": False},
'abstract': False,
},
), ),
migrations.CreateModel( migrations.CreateModel(
name='Post', name="Post",
fields=[ fields=[
( (
'id', "id",
models.AutoField( models.AutoField(
auto_created=True, auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
primary_key=True, ),
serialize=False,
verbose_name='ID'
)
), ),
('created', models.DateTimeField(auto_now_add=True)), ("created", models.DateTimeField(auto_now_add=True)),
('modified', models.DateTimeField(auto_now=True)), ("modified", models.DateTimeField(auto_now=True)),
('title', models.CharField(max_length=200)), ("title", models.CharField(max_length=200)),
('body', models.TextField()), ("body", models.TextField()),
('source', models.CharField(max_length=200)), ("source", models.CharField(max_length=200)),
('publication_date', models.DateTimeField()), ("publication_date", models.DateTimeField()),
('url', models.URLField()), ("url", models.URLField()),
('remote_identifier', models.CharField(max_length=500)), ("remote_identifier", models.CharField(max_length=500)),
( (
'category', "category",
models.ForeignKey( models.ForeignKey(
blank=True, blank=True,
null=True, null=True,
on_delete=django.db.models.deletion.PROTECT, on_delete=django.db.models.deletion.PROTECT,
to='posts.Category' to="posts.Category",
) ),
), ),
( (
'rule', "rule",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, on_delete=django.db.models.deletion.CASCADE, to="collection.CollectionRule"
to='collection.CollectionRule' ),
)
), ),
], ],
options={ options={"abstract": False},
'abstract': False,
},
), ),
] ]

View file

@ -5,16 +5,11 @@ from django.db import migrations
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [("posts", "0001_initial")]
('posts', '0001_initial'),
]
operations = [ operations = [
migrations.AlterModelOptions( migrations.AlterModelOptions(
name='category', name="category",
options={ options={"verbose_name": "Category", "verbose_name_plural": "Categories"},
'verbose_name': 'Category', )
'verbose_name_plural': 'Categories'
},
),
] ]

View file

@ -5,14 +5,10 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [("posts", "0002_auto_20190520_2206")]
('posts', '0002_auto_20190520_2206'),
]
operations = [ operations = [
migrations.AlterField( migrations.AlterField(
model_name='category', model_name="category", name="name", field=models.CharField(max_length=50, unique=True)
name='name', )
field=models.CharField(max_length=50, unique=True),
),
] ]

View file

@ -5,18 +5,13 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [("posts", "0003_auto_20190520_2031")]
('posts', '0003_auto_20190520_2031'),
]
operations = [ operations = [
migrations.RemoveField( migrations.RemoveField(model_name="post", name="source"),
model_name='post',
name='source',
),
migrations.AddField( migrations.AddField(
model_name='post', model_name="post",
name='author', name="author",
field=models.CharField(blank=True, max_length=100, null=True), field=models.CharField(blank=True, max_length=100, null=True),
), ),
] ]

View file

@ -5,19 +5,13 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [("posts", "0004_auto_20190521_1941")]
('posts', '0004_auto_20190521_1941'),
]
operations = [ operations = [
migrations.AlterField(model_name="post", name="body", field=models.TextField(blank=True)),
migrations.AlterField( migrations.AlterField(
model_name='post', model_name="post",
name='body', name="remote_identifier",
field=models.TextField(blank=True),
),
migrations.AlterField(
model_name='post',
name='remote_identifier',
field=models.CharField(blank=True, max_length=500, null=True), field=models.CharField(blank=True, max_length=500, null=True),
), ),
] ]

View file

@ -5,29 +5,23 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [("posts", "0005_auto_20190608_1054")]
('posts', '0005_auto_20190608_1054'),
]
operations = [ operations = [
migrations.AlterField( migrations.AlterField(
model_name='post', model_name="post", name="body", field=models.TextField(blank=True, null=True)
name='body',
field=models.TextField(blank=True, null=True),
), ),
migrations.AlterField( migrations.AlterField(
model_name='post', model_name="post",
name='publication_date', name="publication_date",
field=models.DateTimeField(blank=True, null=True), field=models.DateTimeField(blank=True, null=True),
), ),
migrations.AlterField( migrations.AlterField(
model_name='post', model_name="post",
name='title', name="title",
field=models.CharField(blank=True, max_length=200, null=True), field=models.CharField(blank=True, max_length=200, null=True),
), ),
migrations.AlterField( migrations.AlterField(
model_name='post', model_name="post", name="url", field=models.URLField(blank=True, null=True)
name='url',
field=models.URLField(blank=True, null=True),
), ),
] ]

View file

@ -15,9 +15,7 @@ class Post(TimeStampedModel):
rule = models.ForeignKey(CollectionRule, on_delete=models.CASCADE) rule = models.ForeignKey(CollectionRule, on_delete=models.CASCADE)
remote_identifier = models.CharField(max_length=500, blank=True, null=True) remote_identifier = models.CharField(max_length=500, blank=True, null=True)
category = models.ForeignKey( category = models.ForeignKey("Category", blank=True, null=True, on_delete=models.PROTECT)
'Category', blank=True, null=True, on_delete=models.PROTECT
)
def __str__(self): def __str__(self):
return "Post-{}".format(self.pk) return "Post-{}".format(self.pk)

View file

@ -19,8 +19,8 @@ class PostFactory(factory.django.DjangoModelFactory):
title = factory.Faker("sentence") title = factory.Faker("sentence")
body = factory.Faker("paragraph") body = factory.Faker("paragraph")
author = factory.Faker("name") author = factory.Faker("name")
publication_date = factory.Faker('date_time_this_year', tzinfo=pytz.utc) publication_date = factory.Faker("date_time_this_year", tzinfo=pytz.utc)
url = factory.Faker('url') url = factory.Faker("url")
remote_identifier = factory.Faker("url") remote_identifier = factory.Faker("url")
rule = factory.SubFactory(CollectionRuleFactory) rule = factory.SubFactory(CollectionRuleFactory)

View file

@ -1,3 +1,4 @@
from django.shortcuts import render from django.shortcuts import render
# Create your views here. # Create your views here.

View file

@ -1,6 +1,5 @@
from django.contrib import admin from django.contrib import admin
from django.urls import include, path from django.urls import include, path
urlpatterns = [
path("admin/", admin.site.urls), urlpatterns = [path("admin/", admin.site.urls)]
]

View file

@ -11,6 +11,7 @@ import os
from django.core.wsgi import get_wsgi_application from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'newsreader.settings')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "newsreader.settings")
application = get_wsgi_application() application = get_wsgi_application()