From 982c5bb132190eeb235ea0a73bfa03a6b254154e Mon Sep 17 00:00:00 2001 From: Sonny Date: Mon, 1 Jul 2019 12:11:44 +0200 Subject: [PATCH] Update isort & rerun formatting --- .isort.cfg | 9 +- src/newsreader/conf/base.py | 22 +- src/newsreader/conf/dev.py | 1 + src/newsreader/core/admin.py | 1 + src/newsreader/core/apps.py | 2 +- src/newsreader/core/models.py | 1 + src/newsreader/core/tests.py | 1 + src/newsreader/core/views.py | 1 + src/newsreader/news/collection/apps.py | 2 +- src/newsreader/news/collection/base.py | 4 +- src/newsreader/news/collection/favicon.py | 1 + src/newsreader/news/collection/feed.py | 4 +- .../collection/management/commands/collect.py | 2 +- .../collection/migrations/0001_initial.py | 21 +- .../migrations/0002_auto_20190410_2028.py | 10 +- .../0003_collectionrule_category.py | 17 +- .../0004_collectionrule_timezone.py | 1100 ++++++------ .../migrations/0005_auto_20190521_1941.py | 16 +- .../migrations/0006_collectionrule_error.py | 10 +- src/newsreader/news/collection/models.py | 4 +- .../collection/tests/favicon/builder/mocks.py | 1 + .../collection/tests/favicon/builder/tests.py | 4 +- .../collection/tests/favicon/client/mocks.py | 1 + .../tests/favicon/collector/mocks.py | 1 + .../tests/favicon/collector/tests.py | 10 +- .../tests/feed/builder/mock_html.py | 4 +- .../collection/tests/feed/builder/mocks.py | 1562 +++++++++-------- .../collection/tests/feed/builder/tests.py | 10 +- .../collection/tests/feed/client/mocks.py | 112 +- .../collection/tests/feed/client/tests.py | 4 +- .../collection/tests/feed/collector/mocks.py | 760 ++++---- .../collection/tests/feed/collector/tests.py | 20 +- .../collection/tests/feed/stream/mocks.py | 1 + .../collection/tests/feed/stream/tests.py | 4 +- src/newsreader/news/collection/tests/tests.py | 8 +- .../news/collection/tests/utils/tests.py | 4 +- src/newsreader/news/collection/utils.py | 4 +- src/newsreader/news/collection/views.py | 1 + src/newsreader/news/posts/admin.py | 21 +- src/newsreader/news/posts/apps.py | 2 +- .../news/posts/migrations/0001_initial.py | 69 +- .../migrations/0002_auto_20190520_2206.py | 13 +- .../migrations/0003_auto_20190520_2031.py | 10 +- .../migrations/0004_auto_20190521_1941.py | 13 +- .../migrations/0005_auto_20190608_1054.py | 14 +- .../migrations/0006_auto_20190608_1520.py | 20 +- src/newsreader/news/posts/models.py | 4 +- src/newsreader/news/posts/tests/factories.py | 4 +- src/newsreader/news/posts/views.py | 1 + src/newsreader/urls.py | 5 +- src/newsreader/wsgi.py | 3 +- 51 files changed, 1993 insertions(+), 1926 deletions(-) diff --git a/.isort.cfg b/.isort.cfg index e453b8d..2b81405 100644 --- a/.isort.cfg +++ b/.isort.cfg @@ -2,6 +2,11 @@ include_trailing_comma = true line_length = 80 multi_line_output = 3 -skip = env/ -forced_separate=django, newsreader +skip = env/, venv/ +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 diff --git a/src/newsreader/conf/base.py b/src/newsreader/conf/base.py index 4b9f9df..16927e4 100644 --- a/src/newsreader/conf/base.py +++ b/src/newsreader/conf/base.py @@ -12,6 +12,7 @@ https://docs.djangoproject.com/en/2.2/ref/settings/ import os + # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -62,9 +63,9 @@ TEMPLATES = [ "django.template.context_processors.request", "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", - ], + ] }, - }, + } ] WSGI_APPLICATION = "newsreader.wsgi.application" @@ -82,19 +83,10 @@ DATABASES = { # Password validation # https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ - { - "NAME": - "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", - }, - { - "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", - }, - { - "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", - }, - { - "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", - }, + {"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"}, + {"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"}, + {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"}, + {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"}, ] # Internationalization diff --git a/src/newsreader/conf/dev.py b/src/newsreader/conf/dev.py index 8b5de69..245a78c 100644 --- a/src/newsreader/conf/dev.py +++ b/src/newsreader/conf/dev.py @@ -1,5 +1,6 @@ from .base import * + # Development settings DEBUG = True diff --git a/src/newsreader/core/admin.py b/src/newsreader/core/admin.py index 8c38f3f..a011d19 100644 --- a/src/newsreader/core/admin.py +++ b/src/newsreader/core/admin.py @@ -1,3 +1,4 @@ from django.contrib import admin + # Register your models here. diff --git a/src/newsreader/core/apps.py b/src/newsreader/core/apps.py index 26f78a8..5ef1d60 100644 --- a/src/newsreader/core/apps.py +++ b/src/newsreader/core/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class CoreConfig(AppConfig): - name = 'core' + name = "core" diff --git a/src/newsreader/core/models.py b/src/newsreader/core/models.py index 4bd2e28..2e696fb 100644 --- a/src/newsreader/core/models.py +++ b/src/newsreader/core/models.py @@ -6,6 +6,7 @@ class TimeStampedModel(models.Model): An abstract base class model that provides self- updating ``created`` and ``modified`` fields. """ + created = models.DateTimeField(auto_now_add=True) modified = models.DateTimeField(auto_now=True) diff --git a/src/newsreader/core/tests.py b/src/newsreader/core/tests.py index 7ce503c..7c72b39 100644 --- a/src/newsreader/core/tests.py +++ b/src/newsreader/core/tests.py @@ -1,3 +1,4 @@ from django.test import TestCase + # Create your tests here. diff --git a/src/newsreader/core/views.py b/src/newsreader/core/views.py index 91ea44a..dc1ba72 100644 --- a/src/newsreader/core/views.py +++ b/src/newsreader/core/views.py @@ -1,3 +1,4 @@ from django.shortcuts import render + # Create your views here. diff --git a/src/newsreader/news/collection/apps.py b/src/newsreader/news/collection/apps.py index 1454371..1f4c1c0 100644 --- a/src/newsreader/news/collection/apps.py +++ b/src/newsreader/news/collection/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class CollectionConfig(AppConfig): - name = 'collection' + name = "collection" diff --git a/src/newsreader/news/collection/base.py b/src/newsreader/news/collection/base.py index 2f392b7..c202df8 100644 --- a/src/newsreader/news/collection/base.py +++ b/src/newsreader/news/collection/base.py @@ -1,11 +1,11 @@ from typing import ContextManager, Dict, List, Optional, Tuple +from django.utils import timezone + import requests from bs4 import BeautifulSoup -from django.utils import timezone - from newsreader.news.collection.exceptions import StreamParseException from newsreader.news.collection.models import CollectionRule from newsreader.news.collection.utils import fetch diff --git a/src/newsreader/news/collection/favicon.py b/src/newsreader/news/collection/favicon.py index 8270692..05bd6c9 100644 --- a/src/newsreader/news/collection/favicon.py +++ b/src/newsreader/news/collection/favicon.py @@ -13,6 +13,7 @@ from newsreader.news.collection.base import ( from newsreader.news.collection.exceptions import StreamException from newsreader.news.collection.feed import FeedClient + LINK_RELS = ["icon", "shortcut icon", "apple-touch-icon", "apple-touch-icon-precomposed"] diff --git a/src/newsreader/news/collection/feed.py b/src/newsreader/news/collection/feed.py index ef66b69..2cf248c 100644 --- a/src/newsreader/news/collection/feed.py +++ b/src/newsreader/news/collection/feed.py @@ -1,13 +1,13 @@ from concurrent.futures import ThreadPoolExecutor, as_completed from typing import ContextManager, Dict, Generator, List, Optional, Tuple +from django.utils import timezone + import bleach import pytz from feedparser import parse -from django.utils import timezone - from newsreader.news.collection.base import Builder, Client, Collector, Stream from newsreader.news.collection.exceptions import ( StreamDeniedException, diff --git a/src/newsreader/news/collection/management/commands/collect.py b/src/newsreader/news/collection/management/commands/collect.py index c72301f..855089f 100644 --- a/src/newsreader/news/collection/management/commands/collect.py +++ b/src/newsreader/news/collection/management/commands/collect.py @@ -5,7 +5,7 @@ from newsreader.news.collection.models import CollectionRule class Command(BaseCommand): - help = 'Collects Atom/RSS feeds' + help = "Collects Atom/RSS feeds" def handle(self, *args, **options): CollectionRule.objects.all() diff --git a/src/newsreader/news/collection/migrations/0001_initial.py b/src/newsreader/news/collection/migrations/0001_initial.py index 354a97f..1091b7a 100644 --- a/src/newsreader/news/collection/migrations/0001_initial.py +++ b/src/newsreader/news/collection/migrations/0001_initial.py @@ -11,21 +11,18 @@ class Migration(migrations.Migration): operations = [ migrations.CreateModel( - name='CollectionRule', + name="CollectionRule", fields=[ ( - 'id', + "id", models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name='ID' - ) + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), ), - ('name', models.CharField(max_length=100)), - ('url', models.URLField()), - ('last_suceeded', models.DateTimeField()), - ('succeeded', models.BooleanField(default=False)), + ("name", models.CharField(max_length=100)), + ("url", models.URLField()), + ("last_suceeded", models.DateTimeField()), + ("succeeded", models.BooleanField(default=False)), ], - ), + ) ] diff --git a/src/newsreader/news/collection/migrations/0002_auto_20190410_2028.py b/src/newsreader/news/collection/migrations/0002_auto_20190410_2028.py index 9c0807e..ce45e0e 100644 --- a/src/newsreader/news/collection/migrations/0002_auto_20190410_2028.py +++ b/src/newsreader/news/collection/migrations/0002_auto_20190410_2028.py @@ -5,14 +5,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('collection', '0001_initial'), - ] + dependencies = [("collection", "0001_initial")] operations = [ migrations.AlterField( - model_name='collectionrule', - name='last_suceeded', + model_name="collectionrule", + name="last_suceeded", field=models.DateTimeField(blank=True, null=True), - ), + ) ] diff --git a/src/newsreader/news/collection/migrations/0003_collectionrule_category.py b/src/newsreader/news/collection/migrations/0003_collectionrule_category.py index 4c3f267..b15f7f7 100644 --- a/src/newsreader/news/collection/migrations/0003_collectionrule_category.py +++ b/src/newsreader/news/collection/migrations/0003_collectionrule_category.py @@ -7,22 +7,19 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('posts', '0002_auto_20190520_2206'), - ('collection', '0002_auto_20190410_2028'), - ] + dependencies = [("posts", "0002_auto_20190520_2206"), ("collection", "0002_auto_20190410_2028")] operations = [ migrations.AddField( - model_name='collectionrule', - name='category', + model_name="collectionrule", + name="category", field=models.ForeignKey( 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, on_delete=django.db.models.deletion.SET_NULL, - to='posts.Category', - verbose_name='Category' + to="posts.Category", + verbose_name="Category", ), - ), + ) ] diff --git a/src/newsreader/news/collection/migrations/0004_collectionrule_timezone.py b/src/newsreader/news/collection/migrations/0004_collectionrule_timezone.py index e5943dc..837e625 100644 --- a/src/newsreader/news/collection/migrations/0004_collectionrule_timezone.py +++ b/src/newsreader/news/collection/migrations/0004_collectionrule_timezone.py @@ -5,513 +5,609 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('collection', '0003_collectionrule_category'), - ] + dependencies = [("collection", "0003_collectionrule_category")] operations = [ migrations.AddField( - model_name='collectionrule', - name='timezone', + model_name="collectionrule", + name="timezone", field=models.CharField( choices=[ - ('Africa/Abidjan', 'Africa/Abidjan'), - ('Africa/Accra', 'Africa/Accra'), - ('Africa/Addis_Ababa', 'Africa/Addis_Ababa'), - ('Africa/Algiers', 'Africa/Algiers'), - ('Africa/Asmara', - 'Africa/Asmara'), ('Africa/Asmera', 'Africa/Asmera'), - ('Africa/Bamako', - 'Africa/Bamako'), ('Africa/Bangui', 'Africa/Bangui'), - ('Africa/Banjul', 'Africa/Banjul'), - ('Africa/Bissau', 'Africa/Bissau'), - ('Africa/Blantyre', 'Africa/Blantyre'), - ('Africa/Brazzaville', 'Africa/Brazzaville'), - ('Africa/Bujumbura', 'Africa/Bujumbura'), - ('Africa/Cairo', 'Africa/Cairo'), - ('Africa/Casablanca', 'Africa/Casablanca'), - ('Africa/Ceuta', - 'Africa/Ceuta'), ('Africa/Conakry', 'Africa/Conakry'), - ('Africa/Dakar', 'Africa/Dakar'), - ('Africa/Dar_es_Salaam', 'Africa/Dar_es_Salaam'), - ('Africa/Djibouti', 'Africa/Djibouti'), - ('Africa/Douala', 'Africa/Douala'), - ('Africa/El_Aaiun', 'Africa/El_Aaiun'), - ('Africa/Freetown', 'Africa/Freetown'), - ('Africa/Gaborone', 'Africa/Gaborone'), - ('Africa/Harare', 'Africa/Harare'), - ('Africa/Johannesburg', 'Africa/Johannesburg'), - ('Africa/Juba', 'Africa/Juba'), ('Africa/Kampala', 'Africa/Kampala'), - ('Africa/Khartoum', 'Africa/Khartoum'), - ('Africa/Kigali', 'Africa/Kigali'), - ('Africa/Kinshasa', 'Africa/Kinshasa'), - ('Africa/Lagos', 'Africa/Lagos'), - ('Africa/Libreville', 'Africa/Libreville'), - ('Africa/Lome', 'Africa/Lome'), ('Africa/Luanda', 'Africa/Luanda'), - ('Africa/Lubumbashi', 'Africa/Lubumbashi'), - ('Africa/Lusaka', - 'Africa/Lusaka'), ('Africa/Malabo', 'Africa/Malabo'), - ('Africa/Maputo', 'Africa/Maputo'), - ('Africa/Maseru', 'Africa/Maseru'), - ('Africa/Mbabane', 'Africa/Mbabane'), - ('Africa/Mogadishu', 'Africa/Mogadishu'), - ('Africa/Monrovia', 'Africa/Monrovia'), - ('Africa/Nairobi', 'Africa/Nairobi'), - ('Africa/Ndjamena', 'Africa/Ndjamena'), - ('Africa/Niamey', 'Africa/Niamey'), - ('Africa/Nouakchott', 'Africa/Nouakchott'), - ('Africa/Ouagadougou', 'Africa/Ouagadougou'), - ('Africa/Porto-Novo', 'Africa/Porto-Novo'), - ('Africa/Sao_Tome', 'Africa/Sao_Tome'), - ('Africa/Timbuktu', 'Africa/Timbuktu'), - ('Africa/Tripoli', 'Africa/Tripoli'), - ('Africa/Tunis', 'Africa/Tunis'), - ('Africa/Windhoek', 'Africa/Windhoek'), - ('America/Adak', 'America/Adak'), - ('America/Anchorage', 'America/Anchorage'), - ('America/Anguilla', 'America/Anguilla'), - ('America/Antigua', 'America/Antigua'), - ('America/Araguaina', 'America/Araguaina'), - ('America/Argentina/Buenos_Aires', 'America/Argentina/Buenos_Aires'), - ('America/Argentina/Catamarca', 'America/Argentina/Catamarca'), - ( - 'America/Argentina/ComodRivadavia', - 'America/Argentina/ComodRivadavia' - ), ('America/Argentina/Cordoba', 'America/Argentina/Cordoba'), - ('America/Argentina/Jujuy', 'America/Argentina/Jujuy'), - ('America/Argentina/La_Rioja', 'America/Argentina/La_Rioja'), - ('America/Argentina/Mendoza', 'America/Argentina/Mendoza'), - ('America/Argentina/Rio_Gallegos', 'America/Argentina/Rio_Gallegos'), - ('America/Argentina/Salta', 'America/Argentina/Salta'), - ('America/Argentina/San_Juan', 'America/Argentina/San_Juan'), - ('America/Argentina/San_Luis', 'America/Argentina/San_Luis'), - ('America/Argentina/Tucuman', 'America/Argentina/Tucuman'), - ('America/Argentina/Ushuaia', 'America/Argentina/Ushuaia'), - ('America/Aruba', 'America/Aruba'), - ('America/Asuncion', 'America/Asuncion'), - ('America/Atikokan', 'America/Atikokan'), - ('America/Atka', 'America/Atka'), ('America/Bahia', 'America/Bahia'), - ('America/Bahia_Banderas', 'America/Bahia_Banderas'), - ('America/Barbados', 'America/Barbados'), - ('America/Belem', 'America/Belem'), - ('America/Belize', 'America/Belize'), - ('America/Blanc-Sablon', 'America/Blanc-Sablon'), - ('America/Boa_Vista', 'America/Boa_Vista'), - ('America/Bogota', 'America/Bogota'), - ('America/Boise', 'America/Boise'), - ('America/Buenos_Aires', 'America/Buenos_Aires'), - ('America/Cambridge_Bay', 'America/Cambridge_Bay'), - ('America/Campo_Grande', 'America/Campo_Grande'), - ('America/Cancun', 'America/Cancun'), - ('America/Caracas', 'America/Caracas'), - ('America/Catamarca', 'America/Catamarca'), - ('America/Cayenne', 'America/Cayenne'), - ('America/Cayman', 'America/Cayman'), - ('America/Chicago', 'America/Chicago'), - ('America/Chihuahua', 'America/Chihuahua'), - ('America/Coral_Harbour', 'America/Coral_Harbour'), - ('America/Cordoba', 'America/Cordoba'), - ('America/Costa_Rica', 'America/Costa_Rica'), - ('America/Creston', 'America/Creston'), - ('America/Cuiaba', 'America/Cuiaba'), - ('America/Curacao', 'America/Curacao'), - ('America/Danmarkshavn', 'America/Danmarkshavn'), - ('America/Dawson', 'America/Dawson'), - ('America/Dawson_Creek', 'America/Dawson_Creek'), - ('America/Denver', 'America/Denver'), - ('America/Detroit', 'America/Detroit'), - ('America/Dominica', 'America/Dominica'), - ('America/Edmonton', 'America/Edmonton'), - ('America/Eirunepe', 'America/Eirunepe'), - ('America/El_Salvador', 'America/El_Salvador'), - ('America/Ensenada', 'America/Ensenada'), - ('America/Fort_Nelson', 'America/Fort_Nelson'), - ('America/Fort_Wayne', 'America/Fort_Wayne'), - ('America/Fortaleza', 'America/Fortaleza'), - ('America/Glace_Bay', 'America/Glace_Bay'), - ('America/Godthab', 'America/Godthab'), - ('America/Goose_Bay', 'America/Goose_Bay'), - ('America/Grand_Turk', 'America/Grand_Turk'), - ('America/Grenada', 'America/Grenada'), - ('America/Guadeloupe', 'America/Guadeloupe'), - ('America/Guatemala', 'America/Guatemala'), - ('America/Guayaquil', 'America/Guayaquil'), - ('America/Guyana', 'America/Guyana'), - ('America/Halifax', 'America/Halifax'), - ('America/Havana', 'America/Havana'), - ('America/Hermosillo', 'America/Hermosillo'), - ('America/Indiana/Indianapolis', 'America/Indiana/Indianapolis'), - ('America/Indiana/Knox', 'America/Indiana/Knox'), - ('America/Indiana/Marengo', 'America/Indiana/Marengo'), - ('America/Indiana/Petersburg', 'America/Indiana/Petersburg'), - ('America/Indiana/Tell_City', 'America/Indiana/Tell_City'), - ('America/Indiana/Vevay', 'America/Indiana/Vevay'), - ('America/Indiana/Vincennes', 'America/Indiana/Vincennes'), - ('America/Indiana/Winamac', 'America/Indiana/Winamac'), - ('America/Indianapolis', 'America/Indianapolis'), - ('America/Inuvik', 'America/Inuvik'), - ('America/Iqaluit', 'America/Iqaluit'), - ('America/Jamaica', 'America/Jamaica'), - ('America/Jujuy', 'America/Jujuy'), - ('America/Juneau', 'America/Juneau'), - ('America/Kentucky/Louisville', 'America/Kentucky/Louisville'), - ('America/Kentucky/Monticello', 'America/Kentucky/Monticello'), - ('America/Knox_IN', 'America/Knox_IN'), - ('America/Kralendijk', 'America/Kralendijk'), - ('America/La_Paz', - 'America/La_Paz'), ('America/Lima', 'America/Lima'), - ('America/Los_Angeles', 'America/Los_Angeles'), - ('America/Louisville', 'America/Louisville'), - ('America/Lower_Princes', 'America/Lower_Princes'), - ('America/Maceio', 'America/Maceio'), - ('America/Managua', 'America/Managua'), - ('America/Manaus', 'America/Manaus'), - ('America/Marigot', 'America/Marigot'), - ('America/Martinique', 'America/Martinique'), - ('America/Matamoros', 'America/Matamoros'), - ('America/Mazatlan', 'America/Mazatlan'), - ('America/Mendoza', 'America/Mendoza'), - ('America/Menominee', 'America/Menominee'), - ('America/Merida', 'America/Merida'), - ('America/Metlakatla', 'America/Metlakatla'), - ('America/Mexico_City', 'America/Mexico_City'), - ('America/Miquelon', 'America/Miquelon'), - ('America/Moncton', 'America/Moncton'), - ('America/Monterrey', 'America/Monterrey'), - ('America/Montevideo', 'America/Montevideo'), - ('America/Montreal', 'America/Montreal'), - ('America/Montserrat', 'America/Montserrat'), - ('America/Nassau', 'America/Nassau'), - ('America/New_York', 'America/New_York'), - ('America/Nipigon', 'America/Nipigon'), - ('America/Nome', 'America/Nome'), - ('America/Noronha', 'America/Noronha'), - ('America/North_Dakota/Beulah', 'America/North_Dakota/Beulah'), - ('America/North_Dakota/Center', 'America/North_Dakota/Center'), - ('America/North_Dakota/New_Salem', 'America/North_Dakota/New_Salem'), - ('America/Ojinaga', 'America/Ojinaga'), - ('America/Panama', 'America/Panama'), - ('America/Pangnirtung', 'America/Pangnirtung'), - ('America/Paramaribo', 'America/Paramaribo'), - ('America/Phoenix', 'America/Phoenix'), - ('America/Port-au-Prince', 'America/Port-au-Prince'), - ('America/Port_of_Spain', 'America/Port_of_Spain'), - ('America/Porto_Acre', 'America/Porto_Acre'), - ('America/Porto_Velho', 'America/Porto_Velho'), - ('America/Puerto_Rico', 'America/Puerto_Rico'), - ('America/Punta_Arenas', 'America/Punta_Arenas'), - ('America/Rainy_River', 'America/Rainy_River'), - ('America/Rankin_Inlet', 'America/Rankin_Inlet'), - ('America/Recife', 'America/Recife'), - ('America/Regina', 'America/Regina'), - ('America/Resolute', 'America/Resolute'), - ('America/Rio_Branco', 'America/Rio_Branco'), - ('America/Rosario', 'America/Rosario'), - ('America/Santa_Isabel', 'America/Santa_Isabel'), - ('America/Santarem', 'America/Santarem'), - ('America/Santiago', 'America/Santiago'), - ('America/Santo_Domingo', 'America/Santo_Domingo'), - ('America/Sao_Paulo', 'America/Sao_Paulo'), - ('America/Scoresbysund', 'America/Scoresbysund'), - ('America/Shiprock', 'America/Shiprock'), - ('America/Sitka', 'America/Sitka'), - ('America/St_Barthelemy', 'America/St_Barthelemy'), - ('America/St_Johns', 'America/St_Johns'), - ('America/St_Kitts', 'America/St_Kitts'), - ('America/St_Lucia', 'America/St_Lucia'), - ('America/St_Thomas', 'America/St_Thomas'), - ('America/St_Vincent', 'America/St_Vincent'), - ('America/Swift_Current', 'America/Swift_Current'), - ('America/Tegucigalpa', 'America/Tegucigalpa'), - ('America/Thule', 'America/Thule'), - ('America/Thunder_Bay', 'America/Thunder_Bay'), - ('America/Tijuana', 'America/Tijuana'), - ('America/Toronto', 'America/Toronto'), - ('America/Tortola', 'America/Tortola'), - ('America/Vancouver', 'America/Vancouver'), - ('America/Virgin', 'America/Virgin'), - ('America/Whitehorse', 'America/Whitehorse'), - ('America/Winnipeg', 'America/Winnipeg'), - ('America/Yakutat', 'America/Yakutat'), - ('America/Yellowknife', 'America/Yellowknife'), - ('Antarctica/Casey', 'Antarctica/Casey'), - ('Antarctica/Davis', 'Antarctica/Davis'), - ('Antarctica/DumontDUrville', 'Antarctica/DumontDUrville'), - ('Antarctica/Macquarie', 'Antarctica/Macquarie'), - ('Antarctica/Mawson', 'Antarctica/Mawson'), - ('Antarctica/McMurdo', 'Antarctica/McMurdo'), - ('Antarctica/Palmer', 'Antarctica/Palmer'), - ('Antarctica/Rothera', 'Antarctica/Rothera'), - ('Antarctica/South_Pole', 'Antarctica/South_Pole'), - ('Antarctica/Syowa', 'Antarctica/Syowa'), - ('Antarctica/Troll', 'Antarctica/Troll'), - ('Antarctica/Vostok', 'Antarctica/Vostok'), - ('Arctic/Longyearbyen', 'Arctic/Longyearbyen'), - ('Asia/Aden', 'Asia/Aden'), ('Asia/Almaty', 'Asia/Almaty'), - ('Asia/Amman', 'Asia/Amman'), ('Asia/Anadyr', 'Asia/Anadyr'), - ('Asia/Aqtau', 'Asia/Aqtau'), ('Asia/Aqtobe', 'Asia/Aqtobe'), - ('Asia/Ashgabat', 'Asia/Ashgabat'), - ('Asia/Ashkhabad', 'Asia/Ashkhabad'), ('Asia/Atyrau', 'Asia/Atyrau'), - ('Asia/Baghdad', 'Asia/Baghdad'), ('Asia/Bahrain', 'Asia/Bahrain'), - ('Asia/Baku', 'Asia/Baku'), ('Asia/Bangkok', 'Asia/Bangkok'), - ('Asia/Barnaul', 'Asia/Barnaul'), ('Asia/Beirut', 'Asia/Beirut'), - ('Asia/Bishkek', 'Asia/Bishkek'), ('Asia/Brunei', 'Asia/Brunei'), - ('Asia/Calcutta', 'Asia/Calcutta'), ('Asia/Chita', 'Asia/Chita'), - ('Asia/Choibalsan', 'Asia/Choibalsan'), - ('Asia/Chongqing', 'Asia/Chongqing'), - ('Asia/Chungking', - 'Asia/Chungking'), ('Asia/Colombo', 'Asia/Colombo'), - ('Asia/Dacca', 'Asia/Dacca'), ('Asia/Damascus', 'Asia/Damascus'), - ('Asia/Dhaka', 'Asia/Dhaka'), ('Asia/Dili', 'Asia/Dili'), - ('Asia/Dubai', 'Asia/Dubai'), ('Asia/Dushanbe', 'Asia/Dushanbe'), - ('Asia/Famagusta', 'Asia/Famagusta'), ('Asia/Gaza', 'Asia/Gaza'), - ('Asia/Harbin', 'Asia/Harbin'), ('Asia/Hebron', 'Asia/Hebron'), - ('Asia/Ho_Chi_Minh', 'Asia/Ho_Chi_Minh'), - ('Asia/Hong_Kong', 'Asia/Hong_Kong'), ('Asia/Hovd', 'Asia/Hovd'), - ('Asia/Irkutsk', 'Asia/Irkutsk'), ('Asia/Istanbul', 'Asia/Istanbul'), - ('Asia/Jakarta', 'Asia/Jakarta'), ('Asia/Jayapura', 'Asia/Jayapura'), - ('Asia/Jerusalem', 'Asia/Jerusalem'), ('Asia/Kabul', 'Asia/Kabul'), - ('Asia/Kamchatka', 'Asia/Kamchatka'), - ('Asia/Karachi', 'Asia/Karachi'), ('Asia/Kashgar', 'Asia/Kashgar'), - ('Asia/Kathmandu', 'Asia/Kathmandu'), - ('Asia/Katmandu', - 'Asia/Katmandu'), ('Asia/Khandyga', 'Asia/Khandyga'), - ('Asia/Kolkata', 'Asia/Kolkata'), - ('Asia/Krasnoyarsk', 'Asia/Krasnoyarsk'), - ('Asia/Kuala_Lumpur', 'Asia/Kuala_Lumpur'), - ('Asia/Kuching', 'Asia/Kuching'), ('Asia/Kuwait', 'Asia/Kuwait'), - ('Asia/Macao', 'Asia/Macao'), ('Asia/Macau', 'Asia/Macau'), - ('Asia/Magadan', 'Asia/Magadan'), ('Asia/Makassar', 'Asia/Makassar'), - ('Asia/Manila', 'Asia/Manila'), ('Asia/Muscat', 'Asia/Muscat'), - ('Asia/Nicosia', 'Asia/Nicosia'), - ('Asia/Novokuznetsk', 'Asia/Novokuznetsk'), - ('Asia/Novosibirsk', 'Asia/Novosibirsk'), ('Asia/Omsk', 'Asia/Omsk'), - ('Asia/Oral', 'Asia/Oral'), ('Asia/Phnom_Penh', 'Asia/Phnom_Penh'), - ('Asia/Pontianak', 'Asia/Pontianak'), - ('Asia/Pyongyang', 'Asia/Pyongyang'), ('Asia/Qatar', 'Asia/Qatar'), - ('Asia/Qostanay', 'Asia/Qostanay'), - ('Asia/Qyzylorda', - 'Asia/Qyzylorda'), ('Asia/Rangoon', 'Asia/Rangoon'), - ('Asia/Riyadh', 'Asia/Riyadh'), ('Asia/Saigon', 'Asia/Saigon'), - ('Asia/Sakhalin', 'Asia/Sakhalin'), - ('Asia/Samarkand', 'Asia/Samarkand'), ('Asia/Seoul', 'Asia/Seoul'), - ('Asia/Shanghai', 'Asia/Shanghai'), - ('Asia/Singapore', 'Asia/Singapore'), - ('Asia/Srednekolymsk', 'Asia/Srednekolymsk'), - ('Asia/Taipei', 'Asia/Taipei'), ('Asia/Tashkent', 'Asia/Tashkent'), - ('Asia/Tbilisi', 'Asia/Tbilisi'), ('Asia/Tehran', 'Asia/Tehran'), - ('Asia/Tel_Aviv', 'Asia/Tel_Aviv'), ('Asia/Thimbu', 'Asia/Thimbu'), - ('Asia/Thimphu', 'Asia/Thimphu'), ('Asia/Tokyo', 'Asia/Tokyo'), - ('Asia/Tomsk', 'Asia/Tomsk'), - ('Asia/Ujung_Pandang', 'Asia/Ujung_Pandang'), - ('Asia/Ulaanbaatar', 'Asia/Ulaanbaatar'), - ('Asia/Ulan_Bator', - 'Asia/Ulan_Bator'), ('Asia/Urumqi', 'Asia/Urumqi'), - ('Asia/Ust-Nera', 'Asia/Ust-Nera'), - ('Asia/Vientiane', 'Asia/Vientiane'), - ('Asia/Vladivostok', 'Asia/Vladivostok'), - ('Asia/Yakutsk', 'Asia/Yakutsk'), ('Asia/Yangon', 'Asia/Yangon'), - ('Asia/Yekaterinburg', 'Asia/Yekaterinburg'), - ('Asia/Yerevan', 'Asia/Yerevan'), - ('Atlantic/Azores', 'Atlantic/Azores'), - ('Atlantic/Bermuda', 'Atlantic/Bermuda'), - ('Atlantic/Canary', 'Atlantic/Canary'), - ('Atlantic/Cape_Verde', 'Atlantic/Cape_Verde'), - ('Atlantic/Faeroe', 'Atlantic/Faeroe'), - ('Atlantic/Faroe', 'Atlantic/Faroe'), - ('Atlantic/Jan_Mayen', 'Atlantic/Jan_Mayen'), - ('Atlantic/Madeira', 'Atlantic/Madeira'), - ('Atlantic/Reykjavik', 'Atlantic/Reykjavik'), - ('Atlantic/South_Georgia', 'Atlantic/South_Georgia'), - ('Atlantic/St_Helena', 'Atlantic/St_Helena'), - ('Atlantic/Stanley', 'Atlantic/Stanley'), - ('Australia/ACT', 'Australia/ACT'), - ('Australia/Adelaide', 'Australia/Adelaide'), - ('Australia/Brisbane', 'Australia/Brisbane'), - ('Australia/Broken_Hill', 'Australia/Broken_Hill'), - ('Australia/Canberra', 'Australia/Canberra'), - ('Australia/Currie', 'Australia/Currie'), - ('Australia/Darwin', 'Australia/Darwin'), - ('Australia/Eucla', 'Australia/Eucla'), - ('Australia/Hobart', 'Australia/Hobart'), - ('Australia/LHI', 'Australia/LHI'), - ('Australia/Lindeman', 'Australia/Lindeman'), - ('Australia/Lord_Howe', 'Australia/Lord_Howe'), - ('Australia/Melbourne', 'Australia/Melbourne'), - ('Australia/NSW', 'Australia/NSW'), - ('Australia/North', 'Australia/North'), - ('Australia/Perth', 'Australia/Perth'), - ('Australia/Queensland', 'Australia/Queensland'), - ('Australia/South', 'Australia/South'), - ('Australia/Sydney', 'Australia/Sydney'), - ('Australia/Tasmania', 'Australia/Tasmania'), - ('Australia/Victoria', 'Australia/Victoria'), - ('Australia/West', 'Australia/West'), - ('Australia/Yancowinna', 'Australia/Yancowinna'), - ('Brazil/Acre', 'Brazil/Acre'), - ('Brazil/DeNoronha', 'Brazil/DeNoronha'), - ('Brazil/East', 'Brazil/East'), ('Brazil/West', 'Brazil/West'), - ('CET', 'CET'), ('CST6CDT', 'CST6CDT'), - ('Canada/Atlantic', 'Canada/Atlantic'), - ('Canada/Central', 'Canada/Central'), - ('Canada/Eastern', 'Canada/Eastern'), - ('Canada/Mountain', 'Canada/Mountain'), - ('Canada/Newfoundland', 'Canada/Newfoundland'), - ('Canada/Pacific', 'Canada/Pacific'), - ('Canada/Saskatchewan', 'Canada/Saskatchewan'), - ('Canada/Yukon', 'Canada/Yukon'), - ('Chile/Continental', 'Chile/Continental'), - ('Chile/EasterIsland', 'Chile/EasterIsland'), ('Cuba', 'Cuba'), - ('EET', 'EET'), ('EST', 'EST'), ('EST5EDT', 'EST5EDT'), - ('Egypt', 'Egypt'), ('Eire', 'Eire'), ('Etc/GMT', 'Etc/GMT'), - ('Etc/GMT+0', 'Etc/GMT+0'), ('Etc/GMT+1', 'Etc/GMT+1'), - ('Etc/GMT+10', 'Etc/GMT+10'), ('Etc/GMT+11', 'Etc/GMT+11'), - ('Etc/GMT+12', 'Etc/GMT+12'), ('Etc/GMT+2', 'Etc/GMT+2'), - ('Etc/GMT+3', 'Etc/GMT+3'), ('Etc/GMT+4', 'Etc/GMT+4'), - ('Etc/GMT+5', 'Etc/GMT+5'), ('Etc/GMT+6', 'Etc/GMT+6'), - ('Etc/GMT+7', 'Etc/GMT+7'), ('Etc/GMT+8', 'Etc/GMT+8'), - ('Etc/GMT+9', 'Etc/GMT+9'), ('Etc/GMT-0', 'Etc/GMT-0'), - ('Etc/GMT-1', 'Etc/GMT-1'), ('Etc/GMT-10', 'Etc/GMT-10'), - ('Etc/GMT-11', 'Etc/GMT-11'), ('Etc/GMT-12', 'Etc/GMT-12'), - ('Etc/GMT-13', 'Etc/GMT-13'), ('Etc/GMT-14', 'Etc/GMT-14'), - ('Etc/GMT-2', 'Etc/GMT-2'), ('Etc/GMT-3', 'Etc/GMT-3'), - ('Etc/GMT-4', 'Etc/GMT-4'), ('Etc/GMT-5', 'Etc/GMT-5'), - ('Etc/GMT-6', 'Etc/GMT-6'), ('Etc/GMT-7', 'Etc/GMT-7'), - ('Etc/GMT-8', 'Etc/GMT-8'), ('Etc/GMT-9', 'Etc/GMT-9'), - ('Etc/GMT0', 'Etc/GMT0'), ('Etc/Greenwich', 'Etc/Greenwich'), - ('Etc/UCT', 'Etc/UCT'), ('Etc/UTC', 'Etc/UTC'), - ('Etc/Universal', 'Etc/Universal'), ('Etc/Zulu', 'Etc/Zulu'), - ('Europe/Amsterdam', 'Europe/Amsterdam'), - ('Europe/Andorra', 'Europe/Andorra'), - ('Europe/Astrakhan', 'Europe/Astrakhan'), - ('Europe/Athens', 'Europe/Athens'), - ('Europe/Belfast', 'Europe/Belfast'), - ('Europe/Belgrade', 'Europe/Belgrade'), - ('Europe/Berlin', 'Europe/Berlin'), - ('Europe/Bratislava', 'Europe/Bratislava'), - ('Europe/Brussels', 'Europe/Brussels'), - ('Europe/Bucharest', 'Europe/Bucharest'), - ('Europe/Budapest', 'Europe/Budapest'), - ('Europe/Busingen', 'Europe/Busingen'), - ('Europe/Chisinau', 'Europe/Chisinau'), - ('Europe/Copenhagen', 'Europe/Copenhagen'), - ('Europe/Dublin', 'Europe/Dublin'), - ('Europe/Gibraltar', 'Europe/Gibraltar'), - ('Europe/Guernsey', 'Europe/Guernsey'), - ('Europe/Helsinki', 'Europe/Helsinki'), - ('Europe/Isle_of_Man', 'Europe/Isle_of_Man'), - ('Europe/Istanbul', 'Europe/Istanbul'), - ('Europe/Jersey', 'Europe/Jersey'), - ('Europe/Kaliningrad', 'Europe/Kaliningrad'), - ('Europe/Kiev', 'Europe/Kiev'), ('Europe/Kirov', 'Europe/Kirov'), - ('Europe/Lisbon', 'Europe/Lisbon'), - ('Europe/Ljubljana', 'Europe/Ljubljana'), - ('Europe/London', 'Europe/London'), - ('Europe/Luxembourg', 'Europe/Luxembourg'), - ('Europe/Madrid', 'Europe/Madrid'), ('Europe/Malta', 'Europe/Malta'), - ('Europe/Mariehamn', 'Europe/Mariehamn'), - ('Europe/Minsk', 'Europe/Minsk'), ('Europe/Monaco', 'Europe/Monaco'), - ('Europe/Moscow', 'Europe/Moscow'), - ('Europe/Nicosia', 'Europe/Nicosia'), ('Europe/Oslo', 'Europe/Oslo'), - ('Europe/Paris', 'Europe/Paris'), - ('Europe/Podgorica', 'Europe/Podgorica'), - ('Europe/Prague', 'Europe/Prague'), ('Europe/Riga', 'Europe/Riga'), - ('Europe/Rome', 'Europe/Rome'), ('Europe/Samara', 'Europe/Samara'), - ('Europe/San_Marino', 'Europe/San_Marino'), - ('Europe/Sarajevo', 'Europe/Sarajevo'), - ('Europe/Saratov', 'Europe/Saratov'), - ('Europe/Simferopol', 'Europe/Simferopol'), - ('Europe/Skopje', 'Europe/Skopje'), ('Europe/Sofia', 'Europe/Sofia'), - ('Europe/Stockholm', 'Europe/Stockholm'), - ('Europe/Tallinn', 'Europe/Tallinn'), - ('Europe/Tirane', 'Europe/Tirane'), - ('Europe/Tiraspol', 'Europe/Tiraspol'), - ('Europe/Ulyanovsk', 'Europe/Ulyanovsk'), - ('Europe/Uzhgorod', 'Europe/Uzhgorod'), - ('Europe/Vaduz', - 'Europe/Vaduz'), ('Europe/Vatican', 'Europe/Vatican'), - ('Europe/Vienna', 'Europe/Vienna'), - ('Europe/Vilnius', 'Europe/Vilnius'), - ('Europe/Volgograd', 'Europe/Volgograd'), - ('Europe/Warsaw', - 'Europe/Warsaw'), ('Europe/Zagreb', 'Europe/Zagreb'), - ('Europe/Zaporozhye', 'Europe/Zaporozhye'), - ('Europe/Zurich', 'Europe/Zurich'), ('GB', 'GB'), - ('GB-Eire', 'GB-Eire'), ('GMT', 'GMT'), ('GMT+0', 'GMT+0'), - ('GMT-0', 'GMT-0'), ('GMT0', 'GMT0'), ('Greenwich', 'Greenwich'), - ('HST', 'HST'), ('Hongkong', 'Hongkong'), ('Iceland', 'Iceland'), - ('Indian/Antananarivo', 'Indian/Antananarivo'), - ('Indian/Chagos', 'Indian/Chagos'), - ('Indian/Christmas', 'Indian/Christmas'), - ('Indian/Cocos', 'Indian/Cocos'), ('Indian/Comoro', 'Indian/Comoro'), - ('Indian/Kerguelen', 'Indian/Kerguelen'), - ('Indian/Mahe', - 'Indian/Mahe'), ('Indian/Maldives', 'Indian/Maldives'), - ('Indian/Mauritius', 'Indian/Mauritius'), - ('Indian/Mayotte', 'Indian/Mayotte'), - ('Indian/Reunion', 'Indian/Reunion'), ('Iran', 'Iran'), - ('Israel', 'Israel'), ('Jamaica', 'Jamaica'), ('Japan', 'Japan'), - ('Kwajalein', 'Kwajalein'), ('Libya', 'Libya'), ('MET', 'MET'), - ('MST', 'MST'), ('MST7MDT', 'MST7MDT'), - ('Mexico/BajaNorte', 'Mexico/BajaNorte'), - ('Mexico/BajaSur', 'Mexico/BajaSur'), - ('Mexico/General', 'Mexico/General'), ('NZ', 'NZ'), - ('NZ-CHAT', 'NZ-CHAT'), ('Navajo', 'Navajo'), ('PRC', 'PRC'), - ('PST8PDT', 'PST8PDT'), ('Pacific/Apia', 'Pacific/Apia'), - ('Pacific/Auckland', 'Pacific/Auckland'), - ('Pacific/Bougainville', 'Pacific/Bougainville'), - ('Pacific/Chatham', 'Pacific/Chatham'), - ('Pacific/Chuuk', 'Pacific/Chuuk'), - ('Pacific/Easter', 'Pacific/Easter'), - ('Pacific/Efate', 'Pacific/Efate'), - ('Pacific/Enderbury', 'Pacific/Enderbury'), - ('Pacific/Fakaofo', 'Pacific/Fakaofo'), - ('Pacific/Fiji', 'Pacific/Fiji'), - ('Pacific/Funafuti', 'Pacific/Funafuti'), - ('Pacific/Galapagos', 'Pacific/Galapagos'), - ('Pacific/Gambier', 'Pacific/Gambier'), - ('Pacific/Guadalcanal', 'Pacific/Guadalcanal'), - ('Pacific/Guam', 'Pacific/Guam'), - ('Pacific/Honolulu', 'Pacific/Honolulu'), - ('Pacific/Johnston', 'Pacific/Johnston'), - ('Pacific/Kiritimati', 'Pacific/Kiritimati'), - ('Pacific/Kosrae', 'Pacific/Kosrae'), - ('Pacific/Kwajalein', 'Pacific/Kwajalein'), - ('Pacific/Majuro', 'Pacific/Majuro'), - ('Pacific/Marquesas', 'Pacific/Marquesas'), - ('Pacific/Midway', 'Pacific/Midway'), - ('Pacific/Nauru', 'Pacific/Nauru'), ('Pacific/Niue', 'Pacific/Niue'), - ('Pacific/Norfolk', 'Pacific/Norfolk'), - ('Pacific/Noumea', 'Pacific/Noumea'), - ('Pacific/Pago_Pago', 'Pacific/Pago_Pago'), - ('Pacific/Palau', 'Pacific/Palau'), - ('Pacific/Pitcairn', 'Pacific/Pitcairn'), - ('Pacific/Pohnpei', 'Pacific/Pohnpei'), - ('Pacific/Ponape', 'Pacific/Ponape'), - ('Pacific/Port_Moresby', 'Pacific/Port_Moresby'), - ('Pacific/Rarotonga', 'Pacific/Rarotonga'), - ('Pacific/Saipan', 'Pacific/Saipan'), - ('Pacific/Samoa', 'Pacific/Samoa'), - ('Pacific/Tahiti', 'Pacific/Tahiti'), - ('Pacific/Tarawa', 'Pacific/Tarawa'), - ('Pacific/Tongatapu', 'Pacific/Tongatapu'), - ('Pacific/Truk', 'Pacific/Truk'), ('Pacific/Wake', 'Pacific/Wake'), - ('Pacific/Wallis', 'Pacific/Wallis'), ('Pacific/Yap', 'Pacific/Yap'), - ('Poland', 'Poland'), ('Portugal', 'Portugal'), ('ROC', 'ROC'), - ('ROK', 'ROK'), ('Singapore', 'Singapore'), ('Turkey', 'Turkey'), - ('UCT', 'UCT'), ('US/Alaska', 'US/Alaska'), - ('US/Aleutian', 'US/Aleutian'), ('US/Arizona', 'US/Arizona'), - ('US/Central', 'US/Central'), ('US/East-Indiana', 'US/East-Indiana'), - ('US/Eastern', 'US/Eastern'), ('US/Hawaii', 'US/Hawaii'), - ('US/Indiana-Starke', 'US/Indiana-Starke'), - ('US/Michigan', 'US/Michigan'), ('US/Mountain', 'US/Mountain'), - ('US/Pacific', 'US/Pacific'), ('US/Samoa', - 'US/Samoa'), ('UTC', 'UTC'), - ('Universal', 'Universal'), ('W-SU', 'W-SU'), ('WET', 'WET'), - ('Zulu', 'Zulu') + ("Africa/Abidjan", "Africa/Abidjan"), + ("Africa/Accra", "Africa/Accra"), + ("Africa/Addis_Ababa", "Africa/Addis_Ababa"), + ("Africa/Algiers", "Africa/Algiers"), + ("Africa/Asmara", "Africa/Asmara"), + ("Africa/Asmera", "Africa/Asmera"), + ("Africa/Bamako", "Africa/Bamako"), + ("Africa/Bangui", "Africa/Bangui"), + ("Africa/Banjul", "Africa/Banjul"), + ("Africa/Bissau", "Africa/Bissau"), + ("Africa/Blantyre", "Africa/Blantyre"), + ("Africa/Brazzaville", "Africa/Brazzaville"), + ("Africa/Bujumbura", "Africa/Bujumbura"), + ("Africa/Cairo", "Africa/Cairo"), + ("Africa/Casablanca", "Africa/Casablanca"), + ("Africa/Ceuta", "Africa/Ceuta"), + ("Africa/Conakry", "Africa/Conakry"), + ("Africa/Dakar", "Africa/Dakar"), + ("Africa/Dar_es_Salaam", "Africa/Dar_es_Salaam"), + ("Africa/Djibouti", "Africa/Djibouti"), + ("Africa/Douala", "Africa/Douala"), + ("Africa/El_Aaiun", "Africa/El_Aaiun"), + ("Africa/Freetown", "Africa/Freetown"), + ("Africa/Gaborone", "Africa/Gaborone"), + ("Africa/Harare", "Africa/Harare"), + ("Africa/Johannesburg", "Africa/Johannesburg"), + ("Africa/Juba", "Africa/Juba"), + ("Africa/Kampala", "Africa/Kampala"), + ("Africa/Khartoum", "Africa/Khartoum"), + ("Africa/Kigali", "Africa/Kigali"), + ("Africa/Kinshasa", "Africa/Kinshasa"), + ("Africa/Lagos", "Africa/Lagos"), + ("Africa/Libreville", "Africa/Libreville"), + ("Africa/Lome", "Africa/Lome"), + ("Africa/Luanda", "Africa/Luanda"), + ("Africa/Lubumbashi", "Africa/Lubumbashi"), + ("Africa/Lusaka", "Africa/Lusaka"), + ("Africa/Malabo", "Africa/Malabo"), + ("Africa/Maputo", "Africa/Maputo"), + ("Africa/Maseru", "Africa/Maseru"), + ("Africa/Mbabane", "Africa/Mbabane"), + ("Africa/Mogadishu", "Africa/Mogadishu"), + ("Africa/Monrovia", "Africa/Monrovia"), + ("Africa/Nairobi", "Africa/Nairobi"), + ("Africa/Ndjamena", "Africa/Ndjamena"), + ("Africa/Niamey", "Africa/Niamey"), + ("Africa/Nouakchott", "Africa/Nouakchott"), + ("Africa/Ouagadougou", "Africa/Ouagadougou"), + ("Africa/Porto-Novo", "Africa/Porto-Novo"), + ("Africa/Sao_Tome", "Africa/Sao_Tome"), + ("Africa/Timbuktu", "Africa/Timbuktu"), + ("Africa/Tripoli", "Africa/Tripoli"), + ("Africa/Tunis", "Africa/Tunis"), + ("Africa/Windhoek", "Africa/Windhoek"), + ("America/Adak", "America/Adak"), + ("America/Anchorage", "America/Anchorage"), + ("America/Anguilla", "America/Anguilla"), + ("America/Antigua", "America/Antigua"), + ("America/Araguaina", "America/Araguaina"), + ("America/Argentina/Buenos_Aires", "America/Argentina/Buenos_Aires"), + ("America/Argentina/Catamarca", "America/Argentina/Catamarca"), + ("America/Argentina/ComodRivadavia", "America/Argentina/ComodRivadavia"), + ("America/Argentina/Cordoba", "America/Argentina/Cordoba"), + ("America/Argentina/Jujuy", "America/Argentina/Jujuy"), + ("America/Argentina/La_Rioja", "America/Argentina/La_Rioja"), + ("America/Argentina/Mendoza", "America/Argentina/Mendoza"), + ("America/Argentina/Rio_Gallegos", "America/Argentina/Rio_Gallegos"), + ("America/Argentina/Salta", "America/Argentina/Salta"), + ("America/Argentina/San_Juan", "America/Argentina/San_Juan"), + ("America/Argentina/San_Luis", "America/Argentina/San_Luis"), + ("America/Argentina/Tucuman", "America/Argentina/Tucuman"), + ("America/Argentina/Ushuaia", "America/Argentina/Ushuaia"), + ("America/Aruba", "America/Aruba"), + ("America/Asuncion", "America/Asuncion"), + ("America/Atikokan", "America/Atikokan"), + ("America/Atka", "America/Atka"), + ("America/Bahia", "America/Bahia"), + ("America/Bahia_Banderas", "America/Bahia_Banderas"), + ("America/Barbados", "America/Barbados"), + ("America/Belem", "America/Belem"), + ("America/Belize", "America/Belize"), + ("America/Blanc-Sablon", "America/Blanc-Sablon"), + ("America/Boa_Vista", "America/Boa_Vista"), + ("America/Bogota", "America/Bogota"), + ("America/Boise", "America/Boise"), + ("America/Buenos_Aires", "America/Buenos_Aires"), + ("America/Cambridge_Bay", "America/Cambridge_Bay"), + ("America/Campo_Grande", "America/Campo_Grande"), + ("America/Cancun", "America/Cancun"), + ("America/Caracas", "America/Caracas"), + ("America/Catamarca", "America/Catamarca"), + ("America/Cayenne", "America/Cayenne"), + ("America/Cayman", "America/Cayman"), + ("America/Chicago", "America/Chicago"), + ("America/Chihuahua", "America/Chihuahua"), + ("America/Coral_Harbour", "America/Coral_Harbour"), + ("America/Cordoba", "America/Cordoba"), + ("America/Costa_Rica", "America/Costa_Rica"), + ("America/Creston", "America/Creston"), + ("America/Cuiaba", "America/Cuiaba"), + ("America/Curacao", "America/Curacao"), + ("America/Danmarkshavn", "America/Danmarkshavn"), + ("America/Dawson", "America/Dawson"), + ("America/Dawson_Creek", "America/Dawson_Creek"), + ("America/Denver", "America/Denver"), + ("America/Detroit", "America/Detroit"), + ("America/Dominica", "America/Dominica"), + ("America/Edmonton", "America/Edmonton"), + ("America/Eirunepe", "America/Eirunepe"), + ("America/El_Salvador", "America/El_Salvador"), + ("America/Ensenada", "America/Ensenada"), + ("America/Fort_Nelson", "America/Fort_Nelson"), + ("America/Fort_Wayne", "America/Fort_Wayne"), + ("America/Fortaleza", "America/Fortaleza"), + ("America/Glace_Bay", "America/Glace_Bay"), + ("America/Godthab", "America/Godthab"), + ("America/Goose_Bay", "America/Goose_Bay"), + ("America/Grand_Turk", "America/Grand_Turk"), + ("America/Grenada", "America/Grenada"), + ("America/Guadeloupe", "America/Guadeloupe"), + ("America/Guatemala", "America/Guatemala"), + ("America/Guayaquil", "America/Guayaquil"), + ("America/Guyana", "America/Guyana"), + ("America/Halifax", "America/Halifax"), + ("America/Havana", "America/Havana"), + ("America/Hermosillo", "America/Hermosillo"), + ("America/Indiana/Indianapolis", "America/Indiana/Indianapolis"), + ("America/Indiana/Knox", "America/Indiana/Knox"), + ("America/Indiana/Marengo", "America/Indiana/Marengo"), + ("America/Indiana/Petersburg", "America/Indiana/Petersburg"), + ("America/Indiana/Tell_City", "America/Indiana/Tell_City"), + ("America/Indiana/Vevay", "America/Indiana/Vevay"), + ("America/Indiana/Vincennes", "America/Indiana/Vincennes"), + ("America/Indiana/Winamac", "America/Indiana/Winamac"), + ("America/Indianapolis", "America/Indianapolis"), + ("America/Inuvik", "America/Inuvik"), + ("America/Iqaluit", "America/Iqaluit"), + ("America/Jamaica", "America/Jamaica"), + ("America/Jujuy", "America/Jujuy"), + ("America/Juneau", "America/Juneau"), + ("America/Kentucky/Louisville", "America/Kentucky/Louisville"), + ("America/Kentucky/Monticello", "America/Kentucky/Monticello"), + ("America/Knox_IN", "America/Knox_IN"), + ("America/Kralendijk", "America/Kralendijk"), + ("America/La_Paz", "America/La_Paz"), + ("America/Lima", "America/Lima"), + ("America/Los_Angeles", "America/Los_Angeles"), + ("America/Louisville", "America/Louisville"), + ("America/Lower_Princes", "America/Lower_Princes"), + ("America/Maceio", "America/Maceio"), + ("America/Managua", "America/Managua"), + ("America/Manaus", "America/Manaus"), + ("America/Marigot", "America/Marigot"), + ("America/Martinique", "America/Martinique"), + ("America/Matamoros", "America/Matamoros"), + ("America/Mazatlan", "America/Mazatlan"), + ("America/Mendoza", "America/Mendoza"), + ("America/Menominee", "America/Menominee"), + ("America/Merida", "America/Merida"), + ("America/Metlakatla", "America/Metlakatla"), + ("America/Mexico_City", "America/Mexico_City"), + ("America/Miquelon", "America/Miquelon"), + ("America/Moncton", "America/Moncton"), + ("America/Monterrey", "America/Monterrey"), + ("America/Montevideo", "America/Montevideo"), + ("America/Montreal", "America/Montreal"), + ("America/Montserrat", "America/Montserrat"), + ("America/Nassau", "America/Nassau"), + ("America/New_York", "America/New_York"), + ("America/Nipigon", "America/Nipigon"), + ("America/Nome", "America/Nome"), + ("America/Noronha", "America/Noronha"), + ("America/North_Dakota/Beulah", "America/North_Dakota/Beulah"), + ("America/North_Dakota/Center", "America/North_Dakota/Center"), + ("America/North_Dakota/New_Salem", "America/North_Dakota/New_Salem"), + ("America/Ojinaga", "America/Ojinaga"), + ("America/Panama", "America/Panama"), + ("America/Pangnirtung", "America/Pangnirtung"), + ("America/Paramaribo", "America/Paramaribo"), + ("America/Phoenix", "America/Phoenix"), + ("America/Port-au-Prince", "America/Port-au-Prince"), + ("America/Port_of_Spain", "America/Port_of_Spain"), + ("America/Porto_Acre", "America/Porto_Acre"), + ("America/Porto_Velho", "America/Porto_Velho"), + ("America/Puerto_Rico", "America/Puerto_Rico"), + ("America/Punta_Arenas", "America/Punta_Arenas"), + ("America/Rainy_River", "America/Rainy_River"), + ("America/Rankin_Inlet", "America/Rankin_Inlet"), + ("America/Recife", "America/Recife"), + ("America/Regina", "America/Regina"), + ("America/Resolute", "America/Resolute"), + ("America/Rio_Branco", "America/Rio_Branco"), + ("America/Rosario", "America/Rosario"), + ("America/Santa_Isabel", "America/Santa_Isabel"), + ("America/Santarem", "America/Santarem"), + ("America/Santiago", "America/Santiago"), + ("America/Santo_Domingo", "America/Santo_Domingo"), + ("America/Sao_Paulo", "America/Sao_Paulo"), + ("America/Scoresbysund", "America/Scoresbysund"), + ("America/Shiprock", "America/Shiprock"), + ("America/Sitka", "America/Sitka"), + ("America/St_Barthelemy", "America/St_Barthelemy"), + ("America/St_Johns", "America/St_Johns"), + ("America/St_Kitts", "America/St_Kitts"), + ("America/St_Lucia", "America/St_Lucia"), + ("America/St_Thomas", "America/St_Thomas"), + ("America/St_Vincent", "America/St_Vincent"), + ("America/Swift_Current", "America/Swift_Current"), + ("America/Tegucigalpa", "America/Tegucigalpa"), + ("America/Thule", "America/Thule"), + ("America/Thunder_Bay", "America/Thunder_Bay"), + ("America/Tijuana", "America/Tijuana"), + ("America/Toronto", "America/Toronto"), + ("America/Tortola", "America/Tortola"), + ("America/Vancouver", "America/Vancouver"), + ("America/Virgin", "America/Virgin"), + ("America/Whitehorse", "America/Whitehorse"), + ("America/Winnipeg", "America/Winnipeg"), + ("America/Yakutat", "America/Yakutat"), + ("America/Yellowknife", "America/Yellowknife"), + ("Antarctica/Casey", "Antarctica/Casey"), + ("Antarctica/Davis", "Antarctica/Davis"), + ("Antarctica/DumontDUrville", "Antarctica/DumontDUrville"), + ("Antarctica/Macquarie", "Antarctica/Macquarie"), + ("Antarctica/Mawson", "Antarctica/Mawson"), + ("Antarctica/McMurdo", "Antarctica/McMurdo"), + ("Antarctica/Palmer", "Antarctica/Palmer"), + ("Antarctica/Rothera", "Antarctica/Rothera"), + ("Antarctica/South_Pole", "Antarctica/South_Pole"), + ("Antarctica/Syowa", "Antarctica/Syowa"), + ("Antarctica/Troll", "Antarctica/Troll"), + ("Antarctica/Vostok", "Antarctica/Vostok"), + ("Arctic/Longyearbyen", "Arctic/Longyearbyen"), + ("Asia/Aden", "Asia/Aden"), + ("Asia/Almaty", "Asia/Almaty"), + ("Asia/Amman", "Asia/Amman"), + ("Asia/Anadyr", "Asia/Anadyr"), + ("Asia/Aqtau", "Asia/Aqtau"), + ("Asia/Aqtobe", "Asia/Aqtobe"), + ("Asia/Ashgabat", "Asia/Ashgabat"), + ("Asia/Ashkhabad", "Asia/Ashkhabad"), + ("Asia/Atyrau", "Asia/Atyrau"), + ("Asia/Baghdad", "Asia/Baghdad"), + ("Asia/Bahrain", "Asia/Bahrain"), + ("Asia/Baku", "Asia/Baku"), + ("Asia/Bangkok", "Asia/Bangkok"), + ("Asia/Barnaul", "Asia/Barnaul"), + ("Asia/Beirut", "Asia/Beirut"), + ("Asia/Bishkek", "Asia/Bishkek"), + ("Asia/Brunei", "Asia/Brunei"), + ("Asia/Calcutta", "Asia/Calcutta"), + ("Asia/Chita", "Asia/Chita"), + ("Asia/Choibalsan", "Asia/Choibalsan"), + ("Asia/Chongqing", "Asia/Chongqing"), + ("Asia/Chungking", "Asia/Chungking"), + ("Asia/Colombo", "Asia/Colombo"), + ("Asia/Dacca", "Asia/Dacca"), + ("Asia/Damascus", "Asia/Damascus"), + ("Asia/Dhaka", "Asia/Dhaka"), + ("Asia/Dili", "Asia/Dili"), + ("Asia/Dubai", "Asia/Dubai"), + ("Asia/Dushanbe", "Asia/Dushanbe"), + ("Asia/Famagusta", "Asia/Famagusta"), + ("Asia/Gaza", "Asia/Gaza"), + ("Asia/Harbin", "Asia/Harbin"), + ("Asia/Hebron", "Asia/Hebron"), + ("Asia/Ho_Chi_Minh", "Asia/Ho_Chi_Minh"), + ("Asia/Hong_Kong", "Asia/Hong_Kong"), + ("Asia/Hovd", "Asia/Hovd"), + ("Asia/Irkutsk", "Asia/Irkutsk"), + ("Asia/Istanbul", "Asia/Istanbul"), + ("Asia/Jakarta", "Asia/Jakarta"), + ("Asia/Jayapura", "Asia/Jayapura"), + ("Asia/Jerusalem", "Asia/Jerusalem"), + ("Asia/Kabul", "Asia/Kabul"), + ("Asia/Kamchatka", "Asia/Kamchatka"), + ("Asia/Karachi", "Asia/Karachi"), + ("Asia/Kashgar", "Asia/Kashgar"), + ("Asia/Kathmandu", "Asia/Kathmandu"), + ("Asia/Katmandu", "Asia/Katmandu"), + ("Asia/Khandyga", "Asia/Khandyga"), + ("Asia/Kolkata", "Asia/Kolkata"), + ("Asia/Krasnoyarsk", "Asia/Krasnoyarsk"), + ("Asia/Kuala_Lumpur", "Asia/Kuala_Lumpur"), + ("Asia/Kuching", "Asia/Kuching"), + ("Asia/Kuwait", "Asia/Kuwait"), + ("Asia/Macao", "Asia/Macao"), + ("Asia/Macau", "Asia/Macau"), + ("Asia/Magadan", "Asia/Magadan"), + ("Asia/Makassar", "Asia/Makassar"), + ("Asia/Manila", "Asia/Manila"), + ("Asia/Muscat", "Asia/Muscat"), + ("Asia/Nicosia", "Asia/Nicosia"), + ("Asia/Novokuznetsk", "Asia/Novokuznetsk"), + ("Asia/Novosibirsk", "Asia/Novosibirsk"), + ("Asia/Omsk", "Asia/Omsk"), + ("Asia/Oral", "Asia/Oral"), + ("Asia/Phnom_Penh", "Asia/Phnom_Penh"), + ("Asia/Pontianak", "Asia/Pontianak"), + ("Asia/Pyongyang", "Asia/Pyongyang"), + ("Asia/Qatar", "Asia/Qatar"), + ("Asia/Qostanay", "Asia/Qostanay"), + ("Asia/Qyzylorda", "Asia/Qyzylorda"), + ("Asia/Rangoon", "Asia/Rangoon"), + ("Asia/Riyadh", "Asia/Riyadh"), + ("Asia/Saigon", "Asia/Saigon"), + ("Asia/Sakhalin", "Asia/Sakhalin"), + ("Asia/Samarkand", "Asia/Samarkand"), + ("Asia/Seoul", "Asia/Seoul"), + ("Asia/Shanghai", "Asia/Shanghai"), + ("Asia/Singapore", "Asia/Singapore"), + ("Asia/Srednekolymsk", "Asia/Srednekolymsk"), + ("Asia/Taipei", "Asia/Taipei"), + ("Asia/Tashkent", "Asia/Tashkent"), + ("Asia/Tbilisi", "Asia/Tbilisi"), + ("Asia/Tehran", "Asia/Tehran"), + ("Asia/Tel_Aviv", "Asia/Tel_Aviv"), + ("Asia/Thimbu", "Asia/Thimbu"), + ("Asia/Thimphu", "Asia/Thimphu"), + ("Asia/Tokyo", "Asia/Tokyo"), + ("Asia/Tomsk", "Asia/Tomsk"), + ("Asia/Ujung_Pandang", "Asia/Ujung_Pandang"), + ("Asia/Ulaanbaatar", "Asia/Ulaanbaatar"), + ("Asia/Ulan_Bator", "Asia/Ulan_Bator"), + ("Asia/Urumqi", "Asia/Urumqi"), + ("Asia/Ust-Nera", "Asia/Ust-Nera"), + ("Asia/Vientiane", "Asia/Vientiane"), + ("Asia/Vladivostok", "Asia/Vladivostok"), + ("Asia/Yakutsk", "Asia/Yakutsk"), + ("Asia/Yangon", "Asia/Yangon"), + ("Asia/Yekaterinburg", "Asia/Yekaterinburg"), + ("Asia/Yerevan", "Asia/Yerevan"), + ("Atlantic/Azores", "Atlantic/Azores"), + ("Atlantic/Bermuda", "Atlantic/Bermuda"), + ("Atlantic/Canary", "Atlantic/Canary"), + ("Atlantic/Cape_Verde", "Atlantic/Cape_Verde"), + ("Atlantic/Faeroe", "Atlantic/Faeroe"), + ("Atlantic/Faroe", "Atlantic/Faroe"), + ("Atlantic/Jan_Mayen", "Atlantic/Jan_Mayen"), + ("Atlantic/Madeira", "Atlantic/Madeira"), + ("Atlantic/Reykjavik", "Atlantic/Reykjavik"), + ("Atlantic/South_Georgia", "Atlantic/South_Georgia"), + ("Atlantic/St_Helena", "Atlantic/St_Helena"), + ("Atlantic/Stanley", "Atlantic/Stanley"), + ("Australia/ACT", "Australia/ACT"), + ("Australia/Adelaide", "Australia/Adelaide"), + ("Australia/Brisbane", "Australia/Brisbane"), + ("Australia/Broken_Hill", "Australia/Broken_Hill"), + ("Australia/Canberra", "Australia/Canberra"), + ("Australia/Currie", "Australia/Currie"), + ("Australia/Darwin", "Australia/Darwin"), + ("Australia/Eucla", "Australia/Eucla"), + ("Australia/Hobart", "Australia/Hobart"), + ("Australia/LHI", "Australia/LHI"), + ("Australia/Lindeman", "Australia/Lindeman"), + ("Australia/Lord_Howe", "Australia/Lord_Howe"), + ("Australia/Melbourne", "Australia/Melbourne"), + ("Australia/NSW", "Australia/NSW"), + ("Australia/North", "Australia/North"), + ("Australia/Perth", "Australia/Perth"), + ("Australia/Queensland", "Australia/Queensland"), + ("Australia/South", "Australia/South"), + ("Australia/Sydney", "Australia/Sydney"), + ("Australia/Tasmania", "Australia/Tasmania"), + ("Australia/Victoria", "Australia/Victoria"), + ("Australia/West", "Australia/West"), + ("Australia/Yancowinna", "Australia/Yancowinna"), + ("Brazil/Acre", "Brazil/Acre"), + ("Brazil/DeNoronha", "Brazil/DeNoronha"), + ("Brazil/East", "Brazil/East"), + ("Brazil/West", "Brazil/West"), + ("CET", "CET"), + ("CST6CDT", "CST6CDT"), + ("Canada/Atlantic", "Canada/Atlantic"), + ("Canada/Central", "Canada/Central"), + ("Canada/Eastern", "Canada/Eastern"), + ("Canada/Mountain", "Canada/Mountain"), + ("Canada/Newfoundland", "Canada/Newfoundland"), + ("Canada/Pacific", "Canada/Pacific"), + ("Canada/Saskatchewan", "Canada/Saskatchewan"), + ("Canada/Yukon", "Canada/Yukon"), + ("Chile/Continental", "Chile/Continental"), + ("Chile/EasterIsland", "Chile/EasterIsland"), + ("Cuba", "Cuba"), + ("EET", "EET"), + ("EST", "EST"), + ("EST5EDT", "EST5EDT"), + ("Egypt", "Egypt"), + ("Eire", "Eire"), + ("Etc/GMT", "Etc/GMT"), + ("Etc/GMT+0", "Etc/GMT+0"), + ("Etc/GMT+1", "Etc/GMT+1"), + ("Etc/GMT+10", "Etc/GMT+10"), + ("Etc/GMT+11", "Etc/GMT+11"), + ("Etc/GMT+12", "Etc/GMT+12"), + ("Etc/GMT+2", "Etc/GMT+2"), + ("Etc/GMT+3", "Etc/GMT+3"), + ("Etc/GMT+4", "Etc/GMT+4"), + ("Etc/GMT+5", "Etc/GMT+5"), + ("Etc/GMT+6", "Etc/GMT+6"), + ("Etc/GMT+7", "Etc/GMT+7"), + ("Etc/GMT+8", "Etc/GMT+8"), + ("Etc/GMT+9", "Etc/GMT+9"), + ("Etc/GMT-0", "Etc/GMT-0"), + ("Etc/GMT-1", "Etc/GMT-1"), + ("Etc/GMT-10", "Etc/GMT-10"), + ("Etc/GMT-11", "Etc/GMT-11"), + ("Etc/GMT-12", "Etc/GMT-12"), + ("Etc/GMT-13", "Etc/GMT-13"), + ("Etc/GMT-14", "Etc/GMT-14"), + ("Etc/GMT-2", "Etc/GMT-2"), + ("Etc/GMT-3", "Etc/GMT-3"), + ("Etc/GMT-4", "Etc/GMT-4"), + ("Etc/GMT-5", "Etc/GMT-5"), + ("Etc/GMT-6", "Etc/GMT-6"), + ("Etc/GMT-7", "Etc/GMT-7"), + ("Etc/GMT-8", "Etc/GMT-8"), + ("Etc/GMT-9", "Etc/GMT-9"), + ("Etc/GMT0", "Etc/GMT0"), + ("Etc/Greenwich", "Etc/Greenwich"), + ("Etc/UCT", "Etc/UCT"), + ("Etc/UTC", "Etc/UTC"), + ("Etc/Universal", "Etc/Universal"), + ("Etc/Zulu", "Etc/Zulu"), + ("Europe/Amsterdam", "Europe/Amsterdam"), + ("Europe/Andorra", "Europe/Andorra"), + ("Europe/Astrakhan", "Europe/Astrakhan"), + ("Europe/Athens", "Europe/Athens"), + ("Europe/Belfast", "Europe/Belfast"), + ("Europe/Belgrade", "Europe/Belgrade"), + ("Europe/Berlin", "Europe/Berlin"), + ("Europe/Bratislava", "Europe/Bratislava"), + ("Europe/Brussels", "Europe/Brussels"), + ("Europe/Bucharest", "Europe/Bucharest"), + ("Europe/Budapest", "Europe/Budapest"), + ("Europe/Busingen", "Europe/Busingen"), + ("Europe/Chisinau", "Europe/Chisinau"), + ("Europe/Copenhagen", "Europe/Copenhagen"), + ("Europe/Dublin", "Europe/Dublin"), + ("Europe/Gibraltar", "Europe/Gibraltar"), + ("Europe/Guernsey", "Europe/Guernsey"), + ("Europe/Helsinki", "Europe/Helsinki"), + ("Europe/Isle_of_Man", "Europe/Isle_of_Man"), + ("Europe/Istanbul", "Europe/Istanbul"), + ("Europe/Jersey", "Europe/Jersey"), + ("Europe/Kaliningrad", "Europe/Kaliningrad"), + ("Europe/Kiev", "Europe/Kiev"), + ("Europe/Kirov", "Europe/Kirov"), + ("Europe/Lisbon", "Europe/Lisbon"), + ("Europe/Ljubljana", "Europe/Ljubljana"), + ("Europe/London", "Europe/London"), + ("Europe/Luxembourg", "Europe/Luxembourg"), + ("Europe/Madrid", "Europe/Madrid"), + ("Europe/Malta", "Europe/Malta"), + ("Europe/Mariehamn", "Europe/Mariehamn"), + ("Europe/Minsk", "Europe/Minsk"), + ("Europe/Monaco", "Europe/Monaco"), + ("Europe/Moscow", "Europe/Moscow"), + ("Europe/Nicosia", "Europe/Nicosia"), + ("Europe/Oslo", "Europe/Oslo"), + ("Europe/Paris", "Europe/Paris"), + ("Europe/Podgorica", "Europe/Podgorica"), + ("Europe/Prague", "Europe/Prague"), + ("Europe/Riga", "Europe/Riga"), + ("Europe/Rome", "Europe/Rome"), + ("Europe/Samara", "Europe/Samara"), + ("Europe/San_Marino", "Europe/San_Marino"), + ("Europe/Sarajevo", "Europe/Sarajevo"), + ("Europe/Saratov", "Europe/Saratov"), + ("Europe/Simferopol", "Europe/Simferopol"), + ("Europe/Skopje", "Europe/Skopje"), + ("Europe/Sofia", "Europe/Sofia"), + ("Europe/Stockholm", "Europe/Stockholm"), + ("Europe/Tallinn", "Europe/Tallinn"), + ("Europe/Tirane", "Europe/Tirane"), + ("Europe/Tiraspol", "Europe/Tiraspol"), + ("Europe/Ulyanovsk", "Europe/Ulyanovsk"), + ("Europe/Uzhgorod", "Europe/Uzhgorod"), + ("Europe/Vaduz", "Europe/Vaduz"), + ("Europe/Vatican", "Europe/Vatican"), + ("Europe/Vienna", "Europe/Vienna"), + ("Europe/Vilnius", "Europe/Vilnius"), + ("Europe/Volgograd", "Europe/Volgograd"), + ("Europe/Warsaw", "Europe/Warsaw"), + ("Europe/Zagreb", "Europe/Zagreb"), + ("Europe/Zaporozhye", "Europe/Zaporozhye"), + ("Europe/Zurich", "Europe/Zurich"), + ("GB", "GB"), + ("GB-Eire", "GB-Eire"), + ("GMT", "GMT"), + ("GMT+0", "GMT+0"), + ("GMT-0", "GMT-0"), + ("GMT0", "GMT0"), + ("Greenwich", "Greenwich"), + ("HST", "HST"), + ("Hongkong", "Hongkong"), + ("Iceland", "Iceland"), + ("Indian/Antananarivo", "Indian/Antananarivo"), + ("Indian/Chagos", "Indian/Chagos"), + ("Indian/Christmas", "Indian/Christmas"), + ("Indian/Cocos", "Indian/Cocos"), + ("Indian/Comoro", "Indian/Comoro"), + ("Indian/Kerguelen", "Indian/Kerguelen"), + ("Indian/Mahe", "Indian/Mahe"), + ("Indian/Maldives", "Indian/Maldives"), + ("Indian/Mauritius", "Indian/Mauritius"), + ("Indian/Mayotte", "Indian/Mayotte"), + ("Indian/Reunion", "Indian/Reunion"), + ("Iran", "Iran"), + ("Israel", "Israel"), + ("Jamaica", "Jamaica"), + ("Japan", "Japan"), + ("Kwajalein", "Kwajalein"), + ("Libya", "Libya"), + ("MET", "MET"), + ("MST", "MST"), + ("MST7MDT", "MST7MDT"), + ("Mexico/BajaNorte", "Mexico/BajaNorte"), + ("Mexico/BajaSur", "Mexico/BajaSur"), + ("Mexico/General", "Mexico/General"), + ("NZ", "NZ"), + ("NZ-CHAT", "NZ-CHAT"), + ("Navajo", "Navajo"), + ("PRC", "PRC"), + ("PST8PDT", "PST8PDT"), + ("Pacific/Apia", "Pacific/Apia"), + ("Pacific/Auckland", "Pacific/Auckland"), + ("Pacific/Bougainville", "Pacific/Bougainville"), + ("Pacific/Chatham", "Pacific/Chatham"), + ("Pacific/Chuuk", "Pacific/Chuuk"), + ("Pacific/Easter", "Pacific/Easter"), + ("Pacific/Efate", "Pacific/Efate"), + ("Pacific/Enderbury", "Pacific/Enderbury"), + ("Pacific/Fakaofo", "Pacific/Fakaofo"), + ("Pacific/Fiji", "Pacific/Fiji"), + ("Pacific/Funafuti", "Pacific/Funafuti"), + ("Pacific/Galapagos", "Pacific/Galapagos"), + ("Pacific/Gambier", "Pacific/Gambier"), + ("Pacific/Guadalcanal", "Pacific/Guadalcanal"), + ("Pacific/Guam", "Pacific/Guam"), + ("Pacific/Honolulu", "Pacific/Honolulu"), + ("Pacific/Johnston", "Pacific/Johnston"), + ("Pacific/Kiritimati", "Pacific/Kiritimati"), + ("Pacific/Kosrae", "Pacific/Kosrae"), + ("Pacific/Kwajalein", "Pacific/Kwajalein"), + ("Pacific/Majuro", "Pacific/Majuro"), + ("Pacific/Marquesas", "Pacific/Marquesas"), + ("Pacific/Midway", "Pacific/Midway"), + ("Pacific/Nauru", "Pacific/Nauru"), + ("Pacific/Niue", "Pacific/Niue"), + ("Pacific/Norfolk", "Pacific/Norfolk"), + ("Pacific/Noumea", "Pacific/Noumea"), + ("Pacific/Pago_Pago", "Pacific/Pago_Pago"), + ("Pacific/Palau", "Pacific/Palau"), + ("Pacific/Pitcairn", "Pacific/Pitcairn"), + ("Pacific/Pohnpei", "Pacific/Pohnpei"), + ("Pacific/Ponape", "Pacific/Ponape"), + ("Pacific/Port_Moresby", "Pacific/Port_Moresby"), + ("Pacific/Rarotonga", "Pacific/Rarotonga"), + ("Pacific/Saipan", "Pacific/Saipan"), + ("Pacific/Samoa", "Pacific/Samoa"), + ("Pacific/Tahiti", "Pacific/Tahiti"), + ("Pacific/Tarawa", "Pacific/Tarawa"), + ("Pacific/Tongatapu", "Pacific/Tongatapu"), + ("Pacific/Truk", "Pacific/Truk"), + ("Pacific/Wake", "Pacific/Wake"), + ("Pacific/Wallis", "Pacific/Wallis"), + ("Pacific/Yap", "Pacific/Yap"), + ("Poland", "Poland"), + ("Portugal", "Portugal"), + ("ROC", "ROC"), + ("ROK", "ROK"), + ("Singapore", "Singapore"), + ("Turkey", "Turkey"), + ("UCT", "UCT"), + ("US/Alaska", "US/Alaska"), + ("US/Aleutian", "US/Aleutian"), + ("US/Arizona", "US/Arizona"), + ("US/Central", "US/Central"), + ("US/East-Indiana", "US/East-Indiana"), + ("US/Eastern", "US/Eastern"), + ("US/Hawaii", "US/Hawaii"), + ("US/Indiana-Starke", "US/Indiana-Starke"), + ("US/Michigan", "US/Michigan"), + ("US/Mountain", "US/Mountain"), + ("US/Pacific", "US/Pacific"), + ("US/Samoa", "US/Samoa"), + ("UTC", "UTC"), + ("Universal", "Universal"), + ("W-SU", "W-SU"), + ("WET", "WET"), + ("Zulu", "Zulu"), ], - default='UTC', - max_length=100 + default="UTC", + max_length=100, ), - ), + ) ] diff --git a/src/newsreader/news/collection/migrations/0005_auto_20190521_1941.py b/src/newsreader/news/collection/migrations/0005_auto_20190521_1941.py index e9ab3d4..8e3a53f 100644 --- a/src/newsreader/news/collection/migrations/0005_auto_20190521_1941.py +++ b/src/newsreader/news/collection/migrations/0005_auto_20190521_1941.py @@ -5,20 +5,18 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('collection', '0004_collectionrule_timezone'), - ] + dependencies = [("collection", "0004_collectionrule_timezone")] operations = [ migrations.AddField( - model_name='collectionrule', - name='favicon', - field=models.ImageField(blank=True, null=True, upload_to=''), + model_name="collectionrule", + name="favicon", + field=models.ImageField(blank=True, null=True, upload_to=""), ), migrations.AddField( - model_name='collectionrule', - name='source', - field=models.CharField(default='source', max_length=100), + model_name="collectionrule", + name="source", + field=models.CharField(default="source", max_length=100), preserve_default=False, ), ] diff --git a/src/newsreader/news/collection/migrations/0006_collectionrule_error.py b/src/newsreader/news/collection/migrations/0006_collectionrule_error.py index 78843b1..b70b638 100644 --- a/src/newsreader/news/collection/migrations/0006_collectionrule_error.py +++ b/src/newsreader/news/collection/migrations/0006_collectionrule_error.py @@ -5,14 +5,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('collection', '0005_auto_20190521_1941'), - ] + dependencies = [("collection", "0005_auto_20190521_1941")] operations = [ migrations.AddField( - model_name='collectionrule', - name='error', + model_name="collectionrule", + name="error", field=models.CharField(blank=True, max_length=255, null=True), - ), + ) ] diff --git a/src/newsreader/news/collection/models.py b/src/newsreader/news/collection/models.py index 1de9849..03768ac 100644 --- a/src/newsreader/news/collection/models.py +++ b/src/newsreader/news/collection/models.py @@ -1,9 +1,9 @@ -import pytz - from django.conf import settings from django.db import models from django.utils.translation import gettext as _ +import pytz + class CollectionRule(models.Model): name = models.CharField(max_length=100) diff --git a/src/newsreader/news/collection/tests/favicon/builder/mocks.py b/src/newsreader/news/collection/tests/favicon/builder/mocks.py index ce02475..8011472 100644 --- a/src/newsreader/news/collection/tests/favicon/builder/mocks.py +++ b/src/newsreader/news/collection/tests/favicon/builder/mocks.py @@ -1,5 +1,6 @@ from bs4 import BeautifulSoup + simple_mock = BeautifulSoup( """ diff --git a/src/newsreader/news/collection/tests/favicon/builder/tests.py b/src/newsreader/news/collection/tests/favicon/builder/tests.py index d08fce7..c8bd14c 100644 --- a/src/newsreader/news/collection/tests/favicon/builder/tests.py +++ b/src/newsreader/news/collection/tests/favicon/builder/tests.py @@ -1,7 +1,7 @@ -from freezegun import freeze_time - from django.test import TestCase +from freezegun import freeze_time + from newsreader.news.collection.favicon import FaviconBuilder from newsreader.news.collection.tests.factories import CollectionRuleFactory from newsreader.news.collection.tests.favicon.builder.mocks import * diff --git a/src/newsreader/news/collection/tests/favicon/client/mocks.py b/src/newsreader/news/collection/tests/favicon/client/mocks.py index ba79b27..a4c5ee1 100644 --- a/src/newsreader/news/collection/tests/favicon/client/mocks.py +++ b/src/newsreader/news/collection/tests/favicon/client/mocks.py @@ -1,5 +1,6 @@ from bs4 import BeautifulSoup + simple_mock = BeautifulSoup( """ diff --git a/src/newsreader/news/collection/tests/favicon/collector/mocks.py b/src/newsreader/news/collection/tests/favicon/collector/mocks.py index 8e58167..097b1dd 100644 --- a/src/newsreader/news/collection/tests/favicon/collector/mocks.py +++ b/src/newsreader/news/collection/tests/favicon/collector/mocks.py @@ -2,6 +2,7 @@ from time import struct_time from bs4 import BeautifulSoup + feed_mock = { "bozo": 0, "encoding": "utf-8", diff --git a/src/newsreader/news/collection/tests/favicon/collector/tests.py b/src/newsreader/news/collection/tests/favicon/collector/tests.py index 6554de4..a292c16 100644 --- a/src/newsreader/news/collection/tests/favicon/collector/tests.py +++ b/src/newsreader/news/collection/tests/favicon/collector/tests.py @@ -1,14 +1,12 @@ from unittest.mock import MagicMock, patch +from django.test import TestCase +from django.utils import timezone + import pytz 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 ( StreamDeniedException, StreamException, @@ -20,6 +18,8 @@ from newsreader.news.collection.exceptions import ( from newsreader.news.collection.favicon import FaviconCollector from newsreader.news.collection.tests.factories import CollectionRuleFactory +from .mocks import feed_mock, website_mock + class FaviconCollectorTestCase(TestCase): def setUp(self): diff --git a/src/newsreader/news/collection/tests/feed/builder/mock_html.py b/src/newsreader/news/collection/tests/feed/builder/mock_html.py index 788495f..44d46f7 100644 --- a/src/newsreader/news/collection/tests/feed/builder/mock_html.py +++ b/src/newsreader/news/collection/tests/feed/builder/mock_html.py @@ -1,4 +1,4 @@ -html_summary = ''' +html_summary = """
@@ -7,4 +7,4 @@ html_summary = '''
-''' +""" diff --git a/src/newsreader/news/collection/tests/feed/builder/mocks.py b/src/newsreader/news/collection/tests/feed/builder/mocks.py index 631f582..a486626 100644 --- a/src/newsreader/news/collection/tests/feed/builder/mocks.py +++ b/src/newsreader/news/collection/tests/feed/builder/mocks.py @@ -2,877 +2,891 @@ from time import struct_time from .mock_html import html_summary + simple_mock = { - 'bozo': 0, - 'encoding': 'utf-8', - 'entries': [{ - 'author': 'A. Author', - 'guidislink': False, - 'href': '', - 'id': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'link': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '1152', - 'url': 'http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg', - 'width': '2048' - }], - 'published': 'Mon, 20 May 2019 16:07:37 GMT', - 'published_parsed': struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), - 'summary': 'Foreign Minister Mohammad Javad Zarif says the US ' - 'president should try showing Iranians some respect.', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - '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' - } - }], - '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/' + "bozo": 0, + "encoding": "utf-8", + "entries": [ + { + "author": "A. Author", + "guidislink": False, + "href": "", + "id": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "link": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "links": [ + { + "href": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "1152", + "url": "http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg", + "width": "2048", + } + ], + "published": "Mon, 20 May 2019 16:07:37 GMT", + "published_parsed": struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), + "summary": "Foreign Minister Mohammad Javad Zarif says the US " + "president should try showing Iranians some respect.", + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "language": None, + "type": "text/html", + "value": "Foreign Minister Mohammad Javad " + "Zarif says the US president should " + "try showing Iranians some " + "respect.", }, - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'title': 'BBC News - Home', + "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", + }, + } + ], + "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', - 'status': 200, - 'version': 'rss20' + "href": "http://feeds.bbci.co.uk/news/rss.xml", + "status": 200, + "version": "rss20", } multiple_mock = { - 'bozo': 0, - 'encoding': 'utf-8', - 'entries': [ + "bozo": 0, + "encoding": "utf-8", + "entries": [ { - 'author': 'A. Author', - 'guidislink': False, - 'href': '', - 'id': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'link': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '1152', - 'url': 'http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg', - 'width': '2048' - }], - 'published': 'Mon, 20 May 2019 16:07:37 GMT', - 'published_parsed': struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), - 'summary': 'Foreign Minister Mohammad Javad Zarif says the US ' - 'president should try showing Iranians some respect.', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - 'type': 'text/html', - 'value': 'Foreign Minister Mohammad Javad ' - 'Zarif says the US president should ' - 'try showing Iranians some ' - 'respect.' + "author": "A. Author", + "guidislink": False, + "href": "", + "id": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "link": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "links": [ + { + "href": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "1152", + "url": "http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg", + "width": "2048", + } + ], + "published": "Mon, 20 May 2019 16:07:37 GMT", + "published_parsed": struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), + "summary": "Foreign Minister Mohammad Javad Zarif says the US " + "president should try showing Iranians some respect.", + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "language": None, + "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' - } }, { - 'author': 'A. Author', - 'guidislink': False, - 'href': '', - 'id': 'https://www.bbc.co.uk/news/technology-48334739', - 'link': 'https://www.bbc.co.uk/news/technology-48334739', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/technology-48334739', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '432', - 'url': 'http://c.files.bbci.co.uk/4789/production/_107031381_mediaitem107028670.jpg', - 'width': '768' - }], - 'published': 'Mon, 20 May 2019 12:19:19 GMT', - 'published_parsed': struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0,)), - 'summary': "Google's move to end business ties with Huawei will " - 'affect current devices and future purchases.', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - 'type': 'text/html', - 'value': "Google's move to end business ties " - 'with Huawei will affect current ' - 'devices and future purchases.' + "author": "A. Author", + "guidislink": False, + "href": "", + "id": "https://www.bbc.co.uk/news/technology-48334739", + "link": "https://www.bbc.co.uk/news/technology-48334739", + "links": [ + { + "href": "https://www.bbc.co.uk/news/technology-48334739", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "432", + "url": "http://c.files.bbci.co.uk/4789/production/_107031381_mediaitem107028670.jpg", + "width": "768", + } + ], + "published": "Mon, 20 May 2019 12:19:19 GMT", + "published_parsed": struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0)), + "summary": "Google's move to end business ties with Huawei will " + "affect current devices and future purchases.", + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "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' - } }, { - 'author': 'A. Author', - 'guidislink': False, - 'href': '', - 'id': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', - 'link': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '549', - 'url': 'http://c.files.bbci.co.uk/11D67/production/_107036037_lgbtheadjpg.jpg', - 'width': '976' - }], - '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 ' + "author": "A. Author", + "guidislink": False, + "href": "", + "id": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080", + "link": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080", + "links": [ + { + "href": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "549", + "url": "http://c.files.bbci.co.uk/11D67/production/_107036037_lgbtheadjpg.jpg", + "width": "976", + } + ], + "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 ' 'children".', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - 'type': 'text/html', - 'value': 'Police are investigating the ' - 'messages while an MP calls for a ' + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "language": None, + "type": "text/html", + "value": "Police are investigating the " + "messages while an MP calls for a " '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': { - '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', + "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', - 'status': 200, - 'version': 'rss20' + "href": "http://feeds.bbci.co.uk/news/rss.xml", + "status": 200, + "version": "rss20", } mock_without_identifier = { - 'bozo': 0, - 'encoding': 'utf-8', - 'entries': [ + "bozo": 0, + "encoding": "utf-8", + "entries": [ { - 'author': 'A. Author', - 'guidislink': False, - 'href': '', - 'link': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '1152', - 'url': 'http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg', - 'width': '2048' - }], - 'published': 'Mon, 20 May 2019 16:07:37 GMT', - 'published_parsed': struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), - 'summary': 'Foreign Minister Mohammad Javad Zarif says the US ' - 'president should try showing Iranians some respect.', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - 'type': 'text/html', - 'value': 'Foreign Minister Mohammad Javad ' - 'Zarif says the US president should ' - 'try showing Iranians some ' - 'respect.' + "author": "A. Author", + "guidislink": False, + "href": "", + "link": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "links": [ + { + "href": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "1152", + "url": "http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg", + "width": "2048", + } + ], + "published": "Mon, 20 May 2019 16:07:37 GMT", + "published_parsed": struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), + "summary": "Foreign Minister Mohammad Javad Zarif says the US " + "president should try showing Iranians some respect.", + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "language": None, + "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' - } }, { - 'author': 'A. Author', - 'guidislink': False, - 'href': '', - 'id': None, - 'link': 'https://www.bbc.co.uk/news/technology-48334739', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/technology-48334739', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '432', - 'url': 'http://c.files.bbci.co.uk/4789/production/_107031381_mediaitem107028670.jpg', - 'width': '768' - }], - 'published': 'Mon, 20 May 2019 12:19:19 GMT', - 'published_parsed': struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0,)), - 'summary': "Google's move to end business ties with Huawei will " - 'affect current devices and future purchases.', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - 'type': 'text/html', - 'value': "Google's move to end business ties " - 'with Huawei will affect current ' - 'devices and future purchases.' + "author": "A. Author", + "guidislink": False, + "href": "", + "id": None, + "link": "https://www.bbc.co.uk/news/technology-48334739", + "links": [ + { + "href": "https://www.bbc.co.uk/news/technology-48334739", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "432", + "url": "http://c.files.bbci.co.uk/4789/production/_107031381_mediaitem107028670.jpg", + "width": "768", + } + ], + "published": "Mon, 20 May 2019 12:19:19 GMT", + "published_parsed": struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0)), + "summary": "Google's move to end business ties with Huawei will " + "affect current devices and future purchases.", + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "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' - } }, ], - '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', + "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', - 'status': 200, - 'version': 'rss20' + "href": "http://feeds.bbci.co.uk/news/rss.xml", + "status": 200, + "version": "rss20", } mock_without_publish_date = { - 'bozo': 0, - 'encoding': 'utf-8', - 'entries': [ + "bozo": 0, + "encoding": "utf-8", + "entries": [ { - 'author': 'A. Author', - 'guidislink': False, - 'href': '', - 'id': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'link': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '1152', - 'url': 'http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg', - 'width': '2048' - }], - 'published': None, - 'published_parsed': None, - 'summary': 'Foreign Minister Mohammad Javad Zarif says the US ' - 'president should try showing Iranians some respect.', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - 'type': 'text/html', - 'value': 'Foreign Minister Mohammad Javad ' - 'Zarif says the US president should ' - 'try showing Iranians some ' - 'respect.' + "author": "A. Author", + "guidislink": False, + "href": "", + "id": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "link": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "links": [ + { + "href": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "1152", + "url": "http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg", + "width": "2048", + } + ], + "published": None, + "published_parsed": None, + "summary": "Foreign Minister Mohammad Javad Zarif says the US " + "president should try showing Iranians some respect.", + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "language": None, + "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' - } }, { - 'author': 'A. Author', - 'guidislink': False, - 'href': '', - 'id': 'https://www.bbc.co.uk/news/technology-48334739', - 'link': 'https://www.bbc.co.uk/news/technology-48334739', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/technology-48334739', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '432', - 'url': 'http://c.files.bbci.co.uk/4789/production/_107031381_mediaitem107028670.jpg', - 'width': '768' - }], - 'summary': "Google's move to end business ties with Huawei will " - 'affect current devices and future purchases.', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - 'type': 'text/html', - 'value': "Google's move to end business ties " - 'with Huawei will affect current ' - 'devices and future purchases.' + "author": "A. Author", + "guidislink": False, + "href": "", + "id": "https://www.bbc.co.uk/news/technology-48334739", + "link": "https://www.bbc.co.uk/news/technology-48334739", + "links": [ + { + "href": "https://www.bbc.co.uk/news/technology-48334739", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "432", + "url": "http://c.files.bbci.co.uk/4789/production/_107031381_mediaitem107028670.jpg", + "width": "768", + } + ], + "summary": "Google's move to end business ties with Huawei will " + "affect current devices and future purchases.", + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "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' - } }, ], - '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', + "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', - 'status': 200, - 'version': 'rss20' + "href": "http://feeds.bbci.co.uk/news/rss.xml", + "status": 200, + "version": "rss20", } mock_without_url = { - 'bozo': 0, - 'encoding': 'utf-8', - 'entries': [ + "bozo": 0, + "encoding": "utf-8", + "entries": [ { - 'author': 'A. Author', - 'guidislink': False, - 'href': '', - 'id': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'media_thumbnail': [{ - 'height': '1152', - 'url': 'http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg', - 'width': '2048' - }], - 'published': 'Mon, 20 May 2019 16:07:37 GMT', - 'published_parsed': struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), - 'published': None, - 'published_parsed': None, - 'summary': 'Foreign Minister Mohammad Javad Zarif says the US ' - 'president should try showing Iranians some respect.', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - 'type': 'text/html', - 'value': 'Foreign Minister Mohammad Javad ' - 'Zarif says the US president should ' - 'try showing Iranians some ' - 'respect.' + "author": "A. Author", + "guidislink": False, + "href": "", + "id": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "media_thumbnail": [ + { + "height": "1152", + "url": "http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg", + "width": "2048", + } + ], + "published": "Mon, 20 May 2019 16:07:37 GMT", + "published_parsed": struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), + "published": None, + "published_parsed": None, + "summary": "Foreign Minister Mohammad Javad Zarif says the US " + "president should try showing Iranians some respect.", + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "language": None, + "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' - } }, { - 'author': 'A. Author', - 'guidislink': False, - 'href': '', - 'id': 'https://www.bbc.co.uk/news/technology-48334739', - 'link': None, - 'links': [], - 'media_thumbnail': [{ - 'height': '432', - 'url': 'http://c.files.bbci.co.uk/4789/production/_107031381_mediaitem107028670.jpg', - 'width': '768' - }], - 'published': 'Mon, 20 May 2019 16:07:37 GMT', - 'published_parsed': struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), - - 'summary': "Google's move to end business ties with Huawei will " - 'affect current devices and future purchases.', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - 'type': 'text/html', - 'value': "Google's move to end business ties " - 'with Huawei will affect current ' - 'devices and future purchases.' + "author": "A. Author", + "guidislink": False, + "href": "", + "id": "https://www.bbc.co.uk/news/technology-48334739", + "link": None, + "links": [], + "media_thumbnail": [ + { + "height": "432", + "url": "http://c.files.bbci.co.uk/4789/production/_107031381_mediaitem107028670.jpg", + "width": "768", + } + ], + "published": "Mon, 20 May 2019 16:07:37 GMT", + "published_parsed": struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), + "summary": "Google's move to end business ties with Huawei will " + "affect current devices and future purchases.", + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "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' - } }, ], - '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', + "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', - 'status': 200, - 'version': 'rss20' + "href": "http://feeds.bbci.co.uk/news/rss.xml", + "status": 200, + "version": "rss20", } mock_without_body = { - 'bozo': 0, - 'encoding': 'utf-8', - 'entries': [ + "bozo": 0, + "encoding": "utf-8", + "entries": [ { - 'author': 'A. Author', - 'guidislink': False, - 'href': '', - 'id': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'link': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '1152', - 'url': 'http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg', - 'width': '2048' - }], - 'published': 'Mon, 20 May 2019 16:07:37 GMT', - 'published_parsed': struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), - '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' - } + "author": "A. Author", + "guidislink": False, + "href": "", + "id": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "link": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "links": [ + { + "href": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "1152", + "url": "http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg", + "width": "2048", + } + ], + "published": "Mon, 20 May 2019 16:07:37 GMT", + "published_parsed": struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), + "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", + }, }, { - 'author': 'A. Author', - 'guidislink': False, - 'href': '', - 'id': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', - 'link': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '549', - 'url': 'http://c.files.bbci.co.uk/11D67/production/_107036037_lgbtheadjpg.jpg', - 'width': '976' - }], - 'published': 'Mon, 20 May 2019 16:32:38 GMT', - 'published_parsed': struct_time((2019, 5, 20, 16, 32, 38, 0, 140, 0)), - 'summary': None, - 'summary_detail': {}, - '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' + "author": "A. Author", + "guidislink": False, + "href": "", + "id": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080", + "link": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080", + "links": [ + { + "href": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080", + "rel": "alternate", + "type": "text/html", } + ], + "media_thumbnail": [ + { + "height": "549", + "url": "http://c.files.bbci.co.uk/11D67/production/_107036037_lgbtheadjpg.jpg", + "width": "976", + } + ], + "published": "Mon, 20 May 2019 16:32:38 GMT", + "published_parsed": struct_time((2019, 5, 20, 16, 32, 38, 0, 140, 0)), + "summary": None, + "summary_detail": {}, + "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': { - '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', + "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', - 'status': 200, - 'version': 'rss20' + "href": "http://feeds.bbci.co.uk/news/rss.xml", + "status": 200, + "version": "rss20", } mock_without_author = { - 'bozo': 0, - 'encoding': 'utf-8', - 'entries': [ + "bozo": 0, + "encoding": "utf-8", + "entries": [ { - 'guidislink': False, - 'href': '', - 'id': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'link': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '1152', - 'url': 'http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg', - 'width': '2048' - }], - 'published': 'Mon, 20 May 2019 16:07:37 GMT', - 'published_parsed': struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), - 'summary': 'Foreign Minister Mohammad Javad Zarif says the US ' - 'president should try showing Iranians some respect.', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - 'type': 'text/html', - 'value': 'Foreign Minister Mohammad Javad ' - 'Zarif says the US president should ' - 'try showing Iranians some ' - 'respect.' + "guidislink": False, + "href": "", + "id": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "link": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "links": [ + { + "href": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "1152", + "url": "http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg", + "width": "2048", + } + ], + "published": "Mon, 20 May 2019 16:07:37 GMT", + "published_parsed": struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), + "summary": "Foreign Minister Mohammad Javad Zarif says the US " + "president should try showing Iranians some respect.", + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "language": None, + "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' - } }, { - 'author': None, - 'guidislink': False, - 'href': '', - 'id': 'https://www.bbc.co.uk/news/technology-48334739', - 'link': 'https://www.bbc.co.uk/news/technology-48334739', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/technology-48334739', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '432', - 'url': 'http://c.files.bbci.co.uk/4789/production/_107031381_mediaitem107028670.jpg', - 'width': '768' - }], - 'published': 'Mon, 20 May 2019 12:19:19 GMT', - 'published_parsed': struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0,)), - 'summary': "Google's move to end business ties with Huawei will " - 'affect current devices and future purchases.', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - 'type': 'text/html', - 'value': "Google's move to end business ties " - 'with Huawei will affect current ' - 'devices and future purchases.' + "author": None, + "guidislink": False, + "href": "", + "id": "https://www.bbc.co.uk/news/technology-48334739", + "link": "https://www.bbc.co.uk/news/technology-48334739", + "links": [ + { + "href": "https://www.bbc.co.uk/news/technology-48334739", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "432", + "url": "http://c.files.bbci.co.uk/4789/production/_107031381_mediaitem107028670.jpg", + "width": "768", + } + ], + "published": "Mon, 20 May 2019 12:19:19 GMT", + "published_parsed": struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0)), + "summary": "Google's move to end business ties with Huawei will " + "affect current devices and future purchases.", + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "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' - } }, ], - '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', + "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', - 'status': 200, - 'version': 'rss20' + "href": "http://feeds.bbci.co.uk/news/rss.xml", + "status": 200, + "version": "rss20", } -mock_without_entries = { - 'entries': [], -} +mock_without_entries = {"entries": []} mock_with_update_entries = { - 'bozo': 0, - 'encoding': 'utf-8', - 'entries': [ + "bozo": 0, + "encoding": "utf-8", + "entries": [ { - 'author': 'A. Author', - 'guidislink': False, - 'href': '', - 'id': '28f79ae4-8f9a-11e9-b143-00163ef6bee7', - 'link': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '1152', - 'url': 'http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg', - 'width': '2048' - }], - 'published': 'Mon, 20 May 2019 16:07:37 GMT', - 'published_parsed': struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), - 'summary': 'Foreign Minister Mohammad Javad Zarif says the US ' - 'president should try showing Iranians some respect.', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - 'type': 'text/html', - 'value': 'Foreign Minister Mohammad Javad ' - 'Zarif says the US president should ' - 'try showing Iranians some ' - 'respect.' + "author": "A. Author", + "guidislink": False, + "href": "", + "id": "28f79ae4-8f9a-11e9-b143-00163ef6bee7", + "link": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "links": [ + { + "href": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "1152", + "url": "http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg", + "width": "2048", + } + ], + "published": "Mon, 20 May 2019 16:07:37 GMT", + "published_parsed": struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), + "summary": "Foreign Minister Mohammad Javad Zarif says the US " + "president should try showing Iranians some respect.", + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "language": None, + "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' - } }, { - 'author': 'A. Author', - 'guidislink': False, - 'href': '', - 'id': 'a5479c66-8fae-11e9-8422-00163ef6bee7', - 'link': 'https://www.bbc.co.uk/news/technology-48334739', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/technology-48334739', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '432', - 'url': 'http://c.files.bbci.co.uk/4789/production/_107031381_mediaitem107028670.jpg', - 'width': '768' - }], - 'published': 'Mon, 20 May 2019 12:19:19 GMT', - 'published_parsed': struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0,)), - 'summary': "Google's move to end business ties with Huawei will " - 'affect current devices and future purchases.', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - 'type': 'text/html', - 'value': "Google's move to end business ties " - 'with Huawei will affect current ' - 'devices and future purchases.' + "author": "A. Author", + "guidislink": False, + "href": "", + "id": "a5479c66-8fae-11e9-8422-00163ef6bee7", + "link": "https://www.bbc.co.uk/news/technology-48334739", + "links": [ + { + "href": "https://www.bbc.co.uk/news/technology-48334739", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "432", + "url": "http://c.files.bbci.co.uk/4789/production/_107031381_mediaitem107028670.jpg", + "width": "768", + } + ], + "published": "Mon, 20 May 2019 12:19:19 GMT", + "published_parsed": struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0)), + "summary": "Google's move to end business ties with Huawei will " + "affect current devices and future purchases.", + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "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' - } }, { - 'author': 'A. Author', - 'guidislink': False, - 'href': '', - 'id': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', - 'link': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '549', - 'url': 'http://c.files.bbci.co.uk/11D67/production/_107036037_lgbtheadjpg.jpg', - 'width': '976' - }], - '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 ' + "author": "A. Author", + "guidislink": False, + "href": "", + "id": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080", + "link": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080", + "links": [ + { + "href": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "549", + "url": "http://c.files.bbci.co.uk/11D67/production/_107036037_lgbtheadjpg.jpg", + "width": "976", + } + ], + "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 ' 'children".', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - 'type': 'text/html', - 'value': 'Police are investigating the ' - 'messages while an MP calls for a ' + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "language": None, + "type": "text/html", + "value": "Police are investigating the " + "messages while an MP calls for a " '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': { - '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', + "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', - 'status': 200, - 'version': 'rss20' + "href": "http://feeds.bbci.co.uk/news/rss.xml", + "status": 200, + "version": "rss20", } mock_with_html = { - 'bozo': 0, - 'encoding': 'utf-8', - 'entries': [ + "bozo": 0, + "encoding": "utf-8", + "entries": [ { - 'author': 'A. Author', - 'guidislink': False, - 'href': '', - 'id': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'link': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '1152', - 'url': 'http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg', - 'width': '2048' - }], - 'published': 'Mon, 20 May 2019 16:07:37 GMT', - 'published_parsed': struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), - 'summary': html_summary, - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - 'type': 'text/html', - 'value': 'Foreign Minister Mohammad Javad ' - 'Zarif says the US president should ' - 'try showing Iranians some ' - 'respect.' + "author": "A. Author", + "guidislink": False, + "href": "", + "id": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "link": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "links": [ + { + "href": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "1152", + "url": "http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg", + "width": "2048", + } + ], + "published": "Mon, 20 May 2019 16:07:37 GMT", + "published_parsed": struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), + "summary": html_summary, + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "language": None, + "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", + }, + } ], - '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', + "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', - 'status': 200, - 'version': 'rss20' + "href": "http://feeds.bbci.co.uk/news/rss.xml", + "status": 200, + "version": "rss20", } diff --git a/src/newsreader/news/collection/tests/feed/builder/tests.py b/src/newsreader/news/collection/tests/feed/builder/tests.py index 49a130a..6efd432 100644 --- a/src/newsreader/news/collection/tests/feed/builder/tests.py +++ b/src/newsreader/news/collection/tests/feed/builder/tests.py @@ -1,20 +1,20 @@ from datetime import date, datetime, time from unittest.mock import MagicMock +from django.test import TestCase +from django.utils import timezone + import pytz 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.tests.factories import CollectionRuleFactory from newsreader.news.posts.models import Post from newsreader.news.posts.tests.factories import PostFactory +from .mocks import * + class FeedBuilderTestCase(TestCase): def setUp(self): diff --git a/src/newsreader/news/collection/tests/feed/client/mocks.py b/src/newsreader/news/collection/tests/feed/client/mocks.py index 5853eb7..e055e7b 100644 --- a/src/newsreader/news/collection/tests/feed/client/mocks.py +++ b/src/newsreader/news/collection/tests/feed/client/mocks.py @@ -1,61 +1,63 @@ from time import struct_time + simple_mock = { - 'bozo': 0, - 'encoding': 'utf-8', - 'entries': [{ - 'guidislink': False, - 'href': '', - 'id': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'link': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '1152', - 'url': 'http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg', - 'width': '2048' - }], - 'published': 'Mon, 20 May 2019 16:07:37 GMT', - 'published_parsed': struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), - 'summary': 'Foreign Minister Mohammad Javad Zarif says the US ' - 'president should try showing Iranians some respect.', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - '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' - } - }], - '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/' + "bozo": 0, + "encoding": "utf-8", + "entries": [ + { + "guidislink": False, + "href": "", + "id": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "link": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "links": [ + { + "href": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "1152", + "url": "http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg", + "width": "2048", + } + ], + "published": "Mon, 20 May 2019 16:07:37 GMT", + "published_parsed": struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), + "summary": "Foreign Minister Mohammad Javad Zarif says the US " + "president should try showing Iranians some respect.", + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "language": None, + "type": "text/html", + "value": "Foreign Minister Mohammad Javad " + "Zarif says the US president should " + "try showing Iranians some " + "respect.", }, - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'title': 'BBC News - Home', + "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", + }, + } + ], + "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', - 'status': 200, - 'version': 'rss20' + "href": "http://feeds.bbci.co.uk/news/rss.xml", + "status": 200, + "version": "rss20", } diff --git a/src/newsreader/news/collection/tests/feed/client/tests.py b/src/newsreader/news/collection/tests/feed/client/tests.py index e49762d..bd9e4eb 100644 --- a/src/newsreader/news/collection/tests/feed/client/tests.py +++ b/src/newsreader/news/collection/tests/feed/client/tests.py @@ -1,7 +1,5 @@ from unittest.mock import MagicMock, patch -from .mocks import simple_mock - from django.test import TestCase 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.tests.factories import CollectionRuleFactory +from .mocks import simple_mock + class FeedClientTestCase(TestCase): def setUp(self): diff --git a/src/newsreader/news/collection/tests/feed/collector/mocks.py b/src/newsreader/news/collection/tests/feed/collector/mocks.py index 930e977..211f4ef 100644 --- a/src/newsreader/news/collection/tests/feed/collector/mocks.py +++ b/src/newsreader/news/collection/tests/feed/collector/mocks.py @@ -1,430 +1,442 @@ from time import struct_time + multiple_mock = { - 'bozo': 0, - 'encoding': 'utf-8', - 'entries': [ + "bozo": 0, + "encoding": "utf-8", + "entries": [ { - 'guidislink': False, - 'href': '', - 'id': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'link': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '1152', - 'url': 'http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg', - 'width': '2048' - }], - 'published': 'Mon, 20 May 2019 16:07:37 GMT', - 'published_parsed': struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), - 'summary': 'Foreign Minister Mohammad Javad Zarif says the US ' - 'president should try showing Iranians some respect.', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - 'type': 'text/html', - 'value': 'Foreign Minister Mohammad Javad ' - 'Zarif says the US president should ' - 'try showing Iranians some ' - 'respect.' + "guidislink": False, + "href": "", + "id": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "link": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "links": [ + { + "href": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "1152", + "url": "http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg", + "width": "2048", + } + ], + "published": "Mon, 20 May 2019 16:07:37 GMT", + "published_parsed": struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), + "summary": "Foreign Minister Mohammad Javad Zarif says the US " + "president should try showing Iranians some respect.", + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "language": None, + "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, - 'href': '', - 'id': 'https://www.bbc.co.uk/news/technology-48334739', - 'link': 'https://www.bbc.co.uk/news/technology-48334739', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/technology-48334739', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '432', - 'url': 'http://c.files.bbci.co.uk/4789/production/_107031381_mediaitem107028670.jpg', - 'width': '768' - }], - 'published': 'Mon, 20 May 2019 12:19:19 GMT', - 'published_parsed': struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0,)), - 'summary': "Google's move to end business ties with Huawei will " - 'affect current devices and future purchases.', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - 'type': 'text/html', - 'value': "Google's move to end business ties " - 'with Huawei will affect current ' - 'devices and future purchases.' + "guidislink": False, + "href": "", + "id": "https://www.bbc.co.uk/news/technology-48334739", + "link": "https://www.bbc.co.uk/news/technology-48334739", + "links": [ + { + "href": "https://www.bbc.co.uk/news/technology-48334739", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "432", + "url": "http://c.files.bbci.co.uk/4789/production/_107031381_mediaitem107028670.jpg", + "width": "768", + } + ], + "published": "Mon, 20 May 2019 12:19:19 GMT", + "published_parsed": struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0)), + "summary": "Google's move to end business ties with Huawei will " + "affect current devices and future purchases.", + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "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, - 'href': '', - 'id': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', - 'link': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '549', - 'url': 'http://c.files.bbci.co.uk/11D67/production/_107036037_lgbtheadjpg.jpg', - 'width': '976' - }], - '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 ' + "guidislink": False, + "href": "", + "id": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080", + "link": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080", + "links": [ + { + "href": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "549", + "url": "http://c.files.bbci.co.uk/11D67/production/_107036037_lgbtheadjpg.jpg", + "width": "976", + } + ], + "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 ' 'children".', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - 'type': 'text/html', - 'value': 'Police are investigating the ' - 'messages while an MP calls for a ' + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "language": None, + "type": "text/html", + "value": "Police are investigating the " + "messages while an MP calls for a " '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': { - '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', + "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', - 'status': 200, - 'version': 'rss20' + "href": "http://feeds.bbci.co.uk/news/rss.xml", + "status": 200, + "version": "rss20", } empty_mock = { - 'bozo': 0, - 'encoding': 'utf-8', - 'entries': [], - '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', + "bozo": 0, + "encoding": "utf-8", + "entries": [], + "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', - 'status': 200, - 'version': 'rss20' + "href": "http://feeds.bbci.co.uk/news/rss.xml", + "status": 200, + "version": "rss20", } duplicate_mock = { - 'bozo': 0, - 'encoding': 'utf-8', - 'entries': [ + "bozo": 0, + "encoding": "utf-8", + "entries": [ { - 'guidislink': False, - 'href': '', - 'link': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '1152', - 'url': 'http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg', - 'width': '2048' - }], - 'published': 'Mon, 20 May 2019 16:07:37 GMT', - 'published_parsed': struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), - 'summary': 'Foreign Minister Mohammad Javad Zarif says the US ' - 'president should try showing Iranians some respect.', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - 'type': 'text/html', - 'value': 'Foreign Minister Mohammad Javad ' - 'Zarif says the US president should ' - 'try showing Iranians some ' - 'respect.' + "guidislink": False, + "href": "", + "link": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "links": [ + { + "href": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "1152", + "url": "http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg", + "width": "2048", + } + ], + "published": "Mon, 20 May 2019 16:07:37 GMT", + "published_parsed": struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), + "summary": "Foreign Minister Mohammad Javad Zarif says the US " + "president should try showing Iranians some respect.", + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "language": None, + "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, - 'href': '', - 'link': 'https://www.bbc.co.uk/news/technology-48334739', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/technology-48334739', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '432', - 'url': 'http://c.files.bbci.co.uk/4789/production/_107031381_mediaitem107028670.jpg', - 'width': '768' - }], - 'published': 'Mon, 20 May 2019 12:19:19 GMT', - 'published_parsed': struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0,)), - 'summary': "Google's move to end business ties with Huawei will " - 'affect current devices and future purchases.', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - 'type': 'text/html', - 'value': "Google's move to end business ties " - 'with Huawei will affect current ' - 'devices and future purchases.' + "guidislink": False, + "href": "", + "link": "https://www.bbc.co.uk/news/technology-48334739", + "links": [ + { + "href": "https://www.bbc.co.uk/news/technology-48334739", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "432", + "url": "http://c.files.bbci.co.uk/4789/production/_107031381_mediaitem107028670.jpg", + "width": "768", + } + ], + "published": "Mon, 20 May 2019 12:19:19 GMT", + "published_parsed": struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0)), + "summary": "Google's move to end business ties with Huawei will " + "affect current devices and future purchases.", + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "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, - 'href': '', - 'link': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '549', - 'url': 'http://c.files.bbci.co.uk/11D67/production/_107036037_lgbtheadjpg.jpg', - 'width': '976' - }], - '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 ' + "guidislink": False, + "href": "", + "link": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080", + "links": [ + { + "href": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "549", + "url": "http://c.files.bbci.co.uk/11D67/production/_107036037_lgbtheadjpg.jpg", + "width": "976", + } + ], + "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 ' 'children".', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - 'type': 'text/html', - 'value': 'Police are investigating the ' - 'messages while an MP calls for a ' + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "language": None, + "type": "text/html", + "value": "Police are investigating the " + "messages while an MP calls for a " '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': { - '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', + "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', - 'status': 200, - 'version': 'rss20' + "href": "http://feeds.bbci.co.uk/news/rss.xml", + "status": 200, + "version": "rss20", } multiple_update_mock = { - 'bozo': 0, - 'encoding': 'utf-8', - 'entries': [ + "bozo": 0, + "encoding": "utf-8", + "entries": [ { - 'guidislink': False, - 'href': '', - 'id': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'link': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/world-us-canada-48338168', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '1152', - 'url': 'http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg', - 'width': '2048' - }], - 'published': 'Mon, 20 May 2019 16:07:37 GMT', - 'published_parsed': struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), - 'summary': 'Foreign Minister Mohammad Javad Zarif says the US ' - 'president should try showing Iranians some respect.', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - 'type': 'text/html', - 'value': 'Foreign Minister Mohammad Javad ' - 'Zarif says the US president should ' - 'try showing Iranians some ' - 'respect.' + "guidislink": False, + "href": "", + "id": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "link": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "links": [ + { + "href": "https://www.bbc.co.uk/news/world-us-canada-48338168", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "1152", + "url": "http://c.files.bbci.co.uk/7605/production/_107031203_mediaitem107031202.jpg", + "width": "2048", + } + ], + "published": "Mon, 20 May 2019 16:07:37 GMT", + "published_parsed": struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), + "summary": "Foreign Minister Mohammad Javad Zarif says the US " + "president should try showing Iranians some respect.", + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "language": None, + "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, - 'href': '', - 'id': 'https://www.bbc.co.uk/news/technology-48334739', - 'link': 'https://www.bbc.co.uk/news/technology-48334739', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/technology-48334739', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '432', - 'url': 'http://c.files.bbci.co.uk/4789/production/_107031381_mediaitem107028670.jpg', - 'width': '768' - }], - 'published': 'Mon, 20 May 2019 12:19:19 GMT', - 'published_parsed': struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0,)), - 'summary': "Google's move to end business ties with Huawei will " - 'affect current devices and future purchases.', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - 'type': 'text/html', - 'value': "Google's move to end business ties " - 'with Huawei will affect current ' - 'devices and future purchases.' + "guidislink": False, + "href": "", + "id": "https://www.bbc.co.uk/news/technology-48334739", + "link": "https://www.bbc.co.uk/news/technology-48334739", + "links": [ + { + "href": "https://www.bbc.co.uk/news/technology-48334739", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "432", + "url": "http://c.files.bbci.co.uk/4789/production/_107031381_mediaitem107028670.jpg", + "width": "768", + } + ], + "published": "Mon, 20 May 2019 12:19:19 GMT", + "published_parsed": struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0)), + "summary": "Google's move to end business ties with Huawei will " + "affect current devices and future purchases.", + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "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, - 'href': '', - 'id': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', - 'link': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', - 'links': [{ - 'href': 'https://www.bbc.co.uk/news/uk-england-birmingham-48339080', - 'rel': 'alternate', - 'type': 'text/html' - }], - 'media_thumbnail': [{ - 'height': '549', - 'url': 'http://c.files.bbci.co.uk/11D67/production/_107036037_lgbtheadjpg.jpg', - 'width': '976' - }], - '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 ' + "guidislink": False, + "href": "", + "id": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080", + "link": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080", + "links": [ + { + "href": "https://www.bbc.co.uk/news/uk-england-birmingham-48339080", + "rel": "alternate", + "type": "text/html", + } + ], + "media_thumbnail": [ + { + "height": "549", + "url": "http://c.files.bbci.co.uk/11D67/production/_107036037_lgbtheadjpg.jpg", + "width": "976", + } + ], + "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 ' 'children".', - 'summary_detail': { - 'base': 'http://feeds.bbci.co.uk/news/rss.xml', - 'language': None, - 'type': 'text/html', - 'value': 'Police are investigating the ' - 'messages while an MP calls for a ' + "summary_detail": { + "base": "http://feeds.bbci.co.uk/news/rss.xml", + "language": None, + "type": "text/html", + "value": "Police are investigating the " + "messages while an MP calls for a " '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': { - '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', + "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', - 'status': 200, - 'version': 'rss20' + "href": "http://feeds.bbci.co.uk/news/rss.xml", + "status": 200, + "version": "rss20", } diff --git a/src/newsreader/news/collection/tests/feed/collector/tests.py b/src/newsreader/news/collection/tests/feed/collector/tests.py index 0d14730..16008dd 100644 --- a/src/newsreader/news/collection/tests/feed/collector/tests.py +++ b/src/newsreader/news/collection/tests/feed/collector/tests.py @@ -2,20 +2,13 @@ from datetime import date, datetime, time from time import struct_time from unittest.mock import MagicMock, patch +from django.test import TestCase +from django.utils import timezone + import pytz 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 ( StreamDeniedException, 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.tests.factories import PostFactory +from .mocks import ( + duplicate_mock, + empty_mock, + multiple_mock, + multiple_update_mock, +) + class FeedCollectorTestCase(TestCase): def setUp(self): diff --git a/src/newsreader/news/collection/tests/feed/stream/mocks.py b/src/newsreader/news/collection/tests/feed/stream/mocks.py index a098383..9e7d796 100644 --- a/src/newsreader/news/collection/tests/feed/stream/mocks.py +++ b/src/newsreader/news/collection/tests/feed/stream/mocks.py @@ -1,5 +1,6 @@ from time import struct_time + simple_mock = { "bozo": 1, "encoding": "utf-8", diff --git a/src/newsreader/news/collection/tests/feed/stream/tests.py b/src/newsreader/news/collection/tests/feed/stream/tests.py index 3a7811b..8509156 100644 --- a/src/newsreader/news/collection/tests/feed/stream/tests.py +++ b/src/newsreader/news/collection/tests/feed/stream/tests.py @@ -1,7 +1,5 @@ from unittest.mock import MagicMock, patch -from .mocks import simple_mock - from django.test import TestCase 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.tests.factories import CollectionRuleFactory +from .mocks import simple_mock + class FeedStreamTestCase(TestCase): def setUp(self): diff --git a/src/newsreader/news/collection/tests/tests.py b/src/newsreader/news/collection/tests/tests.py index 08bc4e0..c39abea 100644 --- a/src/newsreader/news/collection/tests/tests.py +++ b/src/newsreader/news/collection/tests/tests.py @@ -1,11 +1,9 @@ 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 bs4 import BeautifulSoup + from newsreader.news.collection.base import URLBuilder, WebsiteStream from newsreader.news.collection.exceptions import ( StreamDeniedException, @@ -17,6 +15,8 @@ from newsreader.news.collection.exceptions import ( ) from newsreader.news.collection.tests.factories import CollectionRuleFactory +from .mocks import feed_mock_without_link, simple_feed_mock, simple_mock + class WebsiteStreamTestCase(TestCase): def setUp(self): diff --git a/src/newsreader/news/collection/tests/utils/tests.py b/src/newsreader/news/collection/tests/utils/tests.py index e2f0fcf..0362c71 100644 --- a/src/newsreader/news/collection/tests/utils/tests.py +++ b/src/newsreader/news/collection/tests/utils/tests.py @@ -1,5 +1,7 @@ from unittest.mock import MagicMock, patch +from django.test import TestCase + from requests.exceptions import ConnectionError as RequestConnectionError from requests.exceptions import ( HTTPError, @@ -8,8 +10,6 @@ from requests.exceptions import ( TooManyRedirects, ) -from django.test import TestCase - from newsreader.news.collection.exceptions import ( StreamConnectionError, StreamDeniedException, diff --git a/src/newsreader/news/collection/utils.py b/src/newsreader/news/collection/utils.py index 527587d..0abc367 100644 --- a/src/newsreader/news/collection/utils.py +++ b/src/newsreader/news/collection/utils.py @@ -2,13 +2,13 @@ from datetime import datetime, tzinfo from time import mktime, struct_time from typing import Tuple +from django.utils import timezone + import requests from requests.exceptions import RequestException from requests.models import Response -from django.utils import timezone - from newsreader.news.collection.response_handler import ResponseHandler diff --git a/src/newsreader/news/collection/views.py b/src/newsreader/news/collection/views.py index 91ea44a..dc1ba72 100644 --- a/src/newsreader/news/collection/views.py +++ b/src/newsreader/news/collection/views.py @@ -1,3 +1,4 @@ from django.shortcuts import render + # Create your views here. diff --git a/src/newsreader/news/posts/admin.py b/src/newsreader/news/posts/admin.py index 2ba7c81..3e6940b 100644 --- a/src/newsreader/news/posts/admin.py +++ b/src/newsreader/news/posts/admin.py @@ -4,26 +4,13 @@ from newsreader.news.posts.models import Category, Post class PostAdmin(admin.ModelAdmin): - list_display = ( - "publication_date", - "author", - "rule", - "title", - ) - list_display_links = ("title", ) - list_filter = ("rule", ) + list_display = ("publication_date", "author", "rule", "title") + list_display_links = ("title",) + list_filter = ("rule",) ordering = ("-publication_date", "title") - fields = ( - "title", - "body", - "author", - "publication_date", - "url", - "remote_identifier", - "category", - ) + fields = ("title", "body", "author", "publication_date", "url", "remote_identifier", "category") search_fields = ["title"] diff --git a/src/newsreader/news/posts/apps.py b/src/newsreader/news/posts/apps.py index 2c2b982..d39b3e1 100644 --- a/src/newsreader/news/posts/apps.py +++ b/src/newsreader/news/posts/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class PostsConfig(AppConfig): - name = 'posts' + name = "posts" diff --git a/src/newsreader/news/posts/migrations/0001_initial.py b/src/newsreader/news/posts/migrations/0001_initial.py index 36666b3..c7e7604 100644 --- a/src/newsreader/news/posts/migrations/0001_initial.py +++ b/src/newsreader/news/posts/migrations/0001_initial.py @@ -9,70 +9,57 @@ class Migration(migrations.Migration): initial = True - dependencies = [ - ('collection', '0001_initial'), - ] + dependencies = [("collection", "0001_initial")] operations = [ migrations.CreateModel( - name='Category', + name="Category", fields=[ ( - 'id', + "id", models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name='ID' - ) + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), ), - ('created', models.DateTimeField(auto_now_add=True)), - ('modified', models.DateTimeField(auto_now=True)), - ('name', models.CharField(max_length=50)), + ("created", models.DateTimeField(auto_now_add=True)), + ("modified", models.DateTimeField(auto_now=True)), + ("name", models.CharField(max_length=50)), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.CreateModel( - name='Post', + name="Post", fields=[ ( - 'id', + "id", models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name='ID' - ) + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), ), - ('created', models.DateTimeField(auto_now_add=True)), - ('modified', models.DateTimeField(auto_now=True)), - ('title', models.CharField(max_length=200)), - ('body', models.TextField()), - ('source', models.CharField(max_length=200)), - ('publication_date', models.DateTimeField()), - ('url', models.URLField()), - ('remote_identifier', models.CharField(max_length=500)), + ("created", models.DateTimeField(auto_now_add=True)), + ("modified", models.DateTimeField(auto_now=True)), + ("title", models.CharField(max_length=200)), + ("body", models.TextField()), + ("source", models.CharField(max_length=200)), + ("publication_date", models.DateTimeField()), + ("url", models.URLField()), + ("remote_identifier", models.CharField(max_length=500)), ( - 'category', + "category", models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, - to='posts.Category' - ) + to="posts.Category", + ), ), ( - 'rule', + "rule", models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to='collection.CollectionRule' - ) + on_delete=django.db.models.deletion.CASCADE, to="collection.CollectionRule" + ), ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), ] diff --git a/src/newsreader/news/posts/migrations/0002_auto_20190520_2206.py b/src/newsreader/news/posts/migrations/0002_auto_20190520_2206.py index cb86d51..4365972 100644 --- a/src/newsreader/news/posts/migrations/0002_auto_20190520_2206.py +++ b/src/newsreader/news/posts/migrations/0002_auto_20190520_2206.py @@ -5,16 +5,11 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('posts', '0001_initial'), - ] + dependencies = [("posts", "0001_initial")] operations = [ migrations.AlterModelOptions( - name='category', - options={ - 'verbose_name': 'Category', - 'verbose_name_plural': 'Categories' - }, - ), + name="category", + options={"verbose_name": "Category", "verbose_name_plural": "Categories"}, + ) ] diff --git a/src/newsreader/news/posts/migrations/0003_auto_20190520_2031.py b/src/newsreader/news/posts/migrations/0003_auto_20190520_2031.py index a790477..0905440 100644 --- a/src/newsreader/news/posts/migrations/0003_auto_20190520_2031.py +++ b/src/newsreader/news/posts/migrations/0003_auto_20190520_2031.py @@ -5,14 +5,10 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('posts', '0002_auto_20190520_2206'), - ] + dependencies = [("posts", "0002_auto_20190520_2206")] operations = [ migrations.AlterField( - model_name='category', - name='name', - field=models.CharField(max_length=50, unique=True), - ), + model_name="category", name="name", field=models.CharField(max_length=50, unique=True) + ) ] diff --git a/src/newsreader/news/posts/migrations/0004_auto_20190521_1941.py b/src/newsreader/news/posts/migrations/0004_auto_20190521_1941.py index a14c636..4a0ceb2 100644 --- a/src/newsreader/news/posts/migrations/0004_auto_20190521_1941.py +++ b/src/newsreader/news/posts/migrations/0004_auto_20190521_1941.py @@ -5,18 +5,13 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('posts', '0003_auto_20190520_2031'), - ] + dependencies = [("posts", "0003_auto_20190520_2031")] operations = [ - migrations.RemoveField( - model_name='post', - name='source', - ), + migrations.RemoveField(model_name="post", name="source"), migrations.AddField( - model_name='post', - name='author', + model_name="post", + name="author", field=models.CharField(blank=True, max_length=100, null=True), ), ] diff --git a/src/newsreader/news/posts/migrations/0005_auto_20190608_1054.py b/src/newsreader/news/posts/migrations/0005_auto_20190608_1054.py index 96c9d8c..9a5e03a 100644 --- a/src/newsreader/news/posts/migrations/0005_auto_20190608_1054.py +++ b/src/newsreader/news/posts/migrations/0005_auto_20190608_1054.py @@ -5,19 +5,13 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('posts', '0004_auto_20190521_1941'), - ] + dependencies = [("posts", "0004_auto_20190521_1941")] operations = [ + migrations.AlterField(model_name="post", name="body", field=models.TextField(blank=True)), migrations.AlterField( - model_name='post', - name='body', - field=models.TextField(blank=True), - ), - migrations.AlterField( - model_name='post', - name='remote_identifier', + model_name="post", + name="remote_identifier", field=models.CharField(blank=True, max_length=500, null=True), ), ] diff --git a/src/newsreader/news/posts/migrations/0006_auto_20190608_1520.py b/src/newsreader/news/posts/migrations/0006_auto_20190608_1520.py index 8215ea9..7a5f7ec 100644 --- a/src/newsreader/news/posts/migrations/0006_auto_20190608_1520.py +++ b/src/newsreader/news/posts/migrations/0006_auto_20190608_1520.py @@ -5,29 +5,23 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('posts', '0005_auto_20190608_1054'), - ] + dependencies = [("posts", "0005_auto_20190608_1054")] operations = [ migrations.AlterField( - model_name='post', - name='body', - field=models.TextField(blank=True, null=True), + model_name="post", name="body", field=models.TextField(blank=True, null=True) ), migrations.AlterField( - model_name='post', - name='publication_date', + model_name="post", + name="publication_date", field=models.DateTimeField(blank=True, null=True), ), migrations.AlterField( - model_name='post', - name='title', + model_name="post", + name="title", field=models.CharField(blank=True, max_length=200, null=True), ), migrations.AlterField( - model_name='post', - name='url', - field=models.URLField(blank=True, null=True), + model_name="post", name="url", field=models.URLField(blank=True, null=True) ), ] diff --git a/src/newsreader/news/posts/models.py b/src/newsreader/news/posts/models.py index 0528187..fd2c6c1 100644 --- a/src/newsreader/news/posts/models.py +++ b/src/newsreader/news/posts/models.py @@ -15,9 +15,7 @@ class Post(TimeStampedModel): rule = models.ForeignKey(CollectionRule, on_delete=models.CASCADE) remote_identifier = models.CharField(max_length=500, blank=True, null=True) - category = models.ForeignKey( - 'Category', blank=True, null=True, on_delete=models.PROTECT - ) + category = models.ForeignKey("Category", blank=True, null=True, on_delete=models.PROTECT) def __str__(self): return "Post-{}".format(self.pk) diff --git a/src/newsreader/news/posts/tests/factories.py b/src/newsreader/news/posts/tests/factories.py index d059335..a961b4f 100644 --- a/src/newsreader/news/posts/tests/factories.py +++ b/src/newsreader/news/posts/tests/factories.py @@ -19,8 +19,8 @@ class PostFactory(factory.django.DjangoModelFactory): title = factory.Faker("sentence") body = factory.Faker("paragraph") author = factory.Faker("name") - publication_date = factory.Faker('date_time_this_year', tzinfo=pytz.utc) - url = factory.Faker('url') + publication_date = factory.Faker("date_time_this_year", tzinfo=pytz.utc) + url = factory.Faker("url") remote_identifier = factory.Faker("url") rule = factory.SubFactory(CollectionRuleFactory) diff --git a/src/newsreader/news/posts/views.py b/src/newsreader/news/posts/views.py index 91ea44a..dc1ba72 100644 --- a/src/newsreader/news/posts/views.py +++ b/src/newsreader/news/posts/views.py @@ -1,3 +1,4 @@ from django.shortcuts import render + # Create your views here. diff --git a/src/newsreader/urls.py b/src/newsreader/urls.py index fdd5749..ed82d43 100644 --- a/src/newsreader/urls.py +++ b/src/newsreader/urls.py @@ -1,6 +1,5 @@ from django.contrib import admin from django.urls import include, path -urlpatterns = [ - path("admin/", admin.site.urls), -] + +urlpatterns = [path("admin/", admin.site.urls)] diff --git a/src/newsreader/wsgi.py b/src/newsreader/wsgi.py index 4c5ea26..ffe4b3e 100644 --- a/src/newsreader/wsgi.py +++ b/src/newsreader/wsgi.py @@ -11,6 +11,7 @@ import os 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()