From dd767f146b266461040e1bea01b6f0b5f3d8166d Mon Sep 17 00:00:00 2001 From: Dalibor Pavlovic Date: Wed, 17 Nov 2021 16:50:38 +0100 Subject: [PATCH 1/7] Upgrade Django>=2.0,<=2.2 --- Dockerfile | 2 +- examples/explore/exploreproj/settings.py | 4 ++-- examples/explore/exploreproj/urls.py | 2 +- multigtfs/models/agency.py | 2 -- multigtfs/models/block.py | 3 --- multigtfs/models/fare.py | 2 -- multigtfs/models/fare_rule.py | 2 -- multigtfs/models/feed.py | 2 -- multigtfs/models/feed_info.py | 2 -- multigtfs/models/fields/seconds.py | 2 -- multigtfs/models/frequency.py | 2 -- multigtfs/models/route.py | 2 -- multigtfs/models/service.py | 2 -- multigtfs/models/service_date.py | 2 -- multigtfs/models/shape.py | 3 --- multigtfs/models/stop.py | 2 -- multigtfs/models/stop_time.py | 2 -- multigtfs/models/transfer.py | 2 -- multigtfs/models/trip.py | 2 -- multigtfs/models/zone.py | 2 -- requirements.txt | 4 ++-- setup.py | 2 +- 22 files changed, 7 insertions(+), 43 deletions(-) diff --git a/Dockerfile b/Dockerfile index d4ba0ab..a99f09f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ ENV PYTHONUNBUFFERED 1 RUN apt-get update RUN apt-get install -y binutils libproj-dev gdal-bin postgresql-client -RUN pip install "django>=1.11,<2.0" psycopg2 +RUN pip install "django>=2.0,<=2.2" "psycopg2==2.8.6" RUN mkdir /code RUN mkdir /feeds diff --git a/examples/explore/exploreproj/settings.py b/examples/explore/exploreproj/settings.py index 5f30f6c..8764412 100644 --- a/examples/explore/exploreproj/settings.py +++ b/examples/explore/exploreproj/settings.py @@ -18,7 +18,7 @@ # SECURITY WARNING: don't run with debug turned on in production! DEBUG = config('DEBUG', default=True, cast=bool) -ALLOWED_HOSTS = config('ALLOWED_HOSTS', default='', cast=Csv()) +ALLOWED_HOSTS = config('ALLOWED_HOSTS', default='localhost', cast=Csv()) # Application definition INSTALLED_APPS = [ @@ -37,7 +37,7 @@ default='', cast=Csv())) INSTALLED_APPS.extend(LOCAL_INSTALLED_APPS) -MIDDLEWARE_CLASSES = ( +MIDDLEWARE = ( 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', diff --git a/examples/explore/exploreproj/urls.py b/examples/explore/exploreproj/urls.py index 09c7e7a..b00b6cd 100644 --- a/examples/explore/exploreproj/urls.py +++ b/examples/explore/exploreproj/urls.py @@ -5,7 +5,7 @@ admin.autodiscover() urlpatterns = [ - url(r'^admin/', include(admin.site.urls)), + url(r'^admin/', admin.site.urls), url(r'^$', TemplateView.as_view(template_name="explore/home.html"), name='home'), url(r'', include('exploreapp.urls')) diff --git a/multigtfs/models/agency.py b/multigtfs/models/agency.py index 4c1f833..740ff4e 100644 --- a/multigtfs/models/agency.py +++ b/multigtfs/models/agency.py @@ -15,13 +15,11 @@ from __future__ import unicode_literals -from django.utils.encoding import python_2_unicode_compatible from jsonfield import JSONField from multigtfs.models.base import models, Base -@python_2_unicode_compatible class Agency(Base): """One or more transit agencies that provide the data in this feed. diff --git a/multigtfs/models/block.py b/multigtfs/models/block.py index da9f8b0..85adc84 100644 --- a/multigtfs/models/block.py +++ b/multigtfs/models/block.py @@ -15,12 +15,9 @@ from __future__ import unicode_literals -from django.utils.encoding import python_2_unicode_compatible - from multigtfs.models.base import models, Base -@python_2_unicode_compatible class Block(Base): """Represents a fare zone. diff --git a/multigtfs/models/fare.py b/multigtfs/models/fare.py index 638d999..9b3440a 100644 --- a/multigtfs/models/fare.py +++ b/multigtfs/models/fare.py @@ -14,13 +14,11 @@ # limitations under the License. from __future__ import unicode_literals -from django.utils.encoding import python_2_unicode_compatible from jsonfield import JSONField from multigtfs.models.base import models, Base -@python_2_unicode_compatible class Fare(Base): """A fare class""" diff --git a/multigtfs/models/fare_rule.py b/multigtfs/models/fare_rule.py index 2bdf38f..ef6026e 100644 --- a/multigtfs/models/fare_rule.py +++ b/multigtfs/models/fare_rule.py @@ -14,13 +14,11 @@ # limitations under the License. from __future__ import unicode_literals -from django.utils.encoding import python_2_unicode_compatible from jsonfield import JSONField from multigtfs.models.base import models, Base -@python_2_unicode_compatible class FareRule(Base): """Associate a Fare with a Route and/or Zones""" fare = models.ForeignKey('Fare', on_delete=models.CASCADE) diff --git a/multigtfs/models/feed.py b/multigtfs/models/feed.py index e2323ad..941dd9e 100644 --- a/multigtfs/models/feed.py +++ b/multigtfs/models/feed.py @@ -21,7 +21,6 @@ from django.contrib.gis.db import models from django.db.models.signals import post_save -from django.utils.encoding import python_2_unicode_compatible from django.utils.six import string_types from jsonfield import JSONField @@ -43,7 +42,6 @@ logger = logging.getLogger(__name__) -@python_2_unicode_compatible class Feed(models.Model): """Represents a single GTFS feed. diff --git a/multigtfs/models/feed_info.py b/multigtfs/models/feed_info.py index 531711c..27b4ff9 100644 --- a/multigtfs/models/feed_info.py +++ b/multigtfs/models/feed_info.py @@ -14,13 +14,11 @@ # limitations under the License. from __future__ import unicode_literals -from django.utils.encoding import python_2_unicode_compatible from jsonfield import JSONField from multigtfs.models.base import models, Base -@python_2_unicode_compatible class FeedInfo(Base): """Information about the feed diff --git a/multigtfs/models/fields/seconds.py b/multigtfs/models/fields/seconds.py index 4db2a12..a093790 100644 --- a/multigtfs/models/fields/seconds.py +++ b/multigtfs/models/fields/seconds.py @@ -18,10 +18,8 @@ from __future__ import unicode_literals from django.db.models import Field -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Seconds(object): '''A GTFS seconds value, formatted as HH:MM:SS in the GTFS feed''' diff --git a/multigtfs/models/frequency.py b/multigtfs/models/frequency.py index e7f1cad..138c701 100644 --- a/multigtfs/models/frequency.py +++ b/multigtfs/models/frequency.py @@ -14,14 +14,12 @@ # limitations under the License. from __future__ import unicode_literals -from django.utils.encoding import python_2_unicode_compatible from jsonfield import JSONField from multigtfs.models.base import models, Base from multigtfs.models.fields import SecondsField -@python_2_unicode_compatible class Frequency(Base): """Description of a trip that repeats without fixed stop times""" trip = models.ForeignKey('Trip', on_delete=models.CASCADE) diff --git a/multigtfs/models/route.py b/multigtfs/models/route.py index d5acd5f..164b3dd 100644 --- a/multigtfs/models/route.py +++ b/multigtfs/models/route.py @@ -15,13 +15,11 @@ from __future__ import unicode_literals from django.contrib.gis.geos import MultiLineString -from django.utils.encoding import python_2_unicode_compatible from jsonfield import JSONField from multigtfs.models.base import models, Base -@python_2_unicode_compatible class Route(Base): """A transit route diff --git a/multigtfs/models/service.py b/multigtfs/models/service.py index 1ad76fc..3dac8d2 100644 --- a/multigtfs/models/service.py +++ b/multigtfs/models/service.py @@ -14,13 +14,11 @@ # limitations under the License. from __future__ import unicode_literals -from django.utils.encoding import python_2_unicode_compatible from jsonfield import JSONField from multigtfs.models.base import models, Base -@python_2_unicode_compatible class Service(Base): """Dates that a route is active. diff --git a/multigtfs/models/service_date.py b/multigtfs/models/service_date.py index b53eed6..db35664 100644 --- a/multigtfs/models/service_date.py +++ b/multigtfs/models/service_date.py @@ -14,13 +14,11 @@ # limitations under the License. from __future__ import unicode_literals -from django.utils.encoding import python_2_unicode_compatible from jsonfield import JSONField from multigtfs.models.base import models, Base -@python_2_unicode_compatible class ServiceDate(Base): """Dates that a route is active. diff --git a/multigtfs/models/shape.py b/multigtfs/models/shape.py index dc77040..201edd8 100644 --- a/multigtfs/models/shape.py +++ b/multigtfs/models/shape.py @@ -18,13 +18,11 @@ from django.contrib.gis.geos import LineString from django.db.models.signals import post_save from django.dispatch import receiver -from django.utils.encoding import python_2_unicode_compatible from jsonfield import JSONField from multigtfs.models.base import models, Base -@python_2_unicode_compatible class Shape(Base): """The path the vehicle takes along the route. @@ -60,7 +58,6 @@ class Meta: _rel_to_feed = 'feed' -@python_2_unicode_compatible class ShapePoint(Base): """A point along the shape""" shape = models.ForeignKey( diff --git a/multigtfs/models/stop.py b/multigtfs/models/stop.py index 3609f5f..15573a4 100644 --- a/multigtfs/models/stop.py +++ b/multigtfs/models/stop.py @@ -18,7 +18,6 @@ from django.db.models.signals import post_save from django.dispatch import receiver -from django.utils.encoding import python_2_unicode_compatible from django.utils.six import StringIO from jsonfield import JSONField @@ -28,7 +27,6 @@ logger = getLogger(__name__) -@python_2_unicode_compatible class Stop(Base): """A stop or station diff --git a/multigtfs/models/stop_time.py b/multigtfs/models/stop_time.py index 9ad8525..f479922 100644 --- a/multigtfs/models/stop_time.py +++ b/multigtfs/models/stop_time.py @@ -14,7 +14,6 @@ # limitations under the License. from __future__ import unicode_literals -from django.utils.encoding import python_2_unicode_compatible from jsonfield import JSONField from multigtfs.models.base import models, Base @@ -23,7 +22,6 @@ from multigtfs.models.fields import SecondsField -@python_2_unicode_compatible class StopTime(Base): """A specific stop on a route on a trip. diff --git a/multigtfs/models/transfer.py b/multigtfs/models/transfer.py index fe7ceb2..7cde081 100644 --- a/multigtfs/models/transfer.py +++ b/multigtfs/models/transfer.py @@ -14,13 +14,11 @@ # limitations under the License. from __future__ import unicode_literals -from django.utils.encoding import python_2_unicode_compatible from jsonfield import JSONField from multigtfs.models.base import models, Base -@python_2_unicode_compatible class Transfer(Base): """Create additional rules for transfers between ambiguous stops. diff --git a/multigtfs/models/trip.py b/multigtfs/models/trip.py index 12c71ad..46c2d53 100644 --- a/multigtfs/models/trip.py +++ b/multigtfs/models/trip.py @@ -15,13 +15,11 @@ from __future__ import unicode_literals from django.contrib.gis.geos import LineString -from django.utils.encoding import python_2_unicode_compatible from jsonfield import JSONField from multigtfs.models.base import models, Base -@python_2_unicode_compatible class Trip(Base): """A trip along a route diff --git a/multigtfs/models/zone.py b/multigtfs/models/zone.py index e132db8..70ffa5c 100644 --- a/multigtfs/models/zone.py +++ b/multigtfs/models/zone.py @@ -14,12 +14,10 @@ # limitations under the License. from __future__ import unicode_literals -from django.utils.encoding import python_2_unicode_compatible from multigtfs.models.base import models, Base -@python_2_unicode_compatible class Zone(Base): """Represents a fare zone. diff --git a/requirements.txt b/requirements.txt index e3f72ba..9b9047b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ -Django>=1.8 -jsonfield==1.0.3 +Django>=2.0,<=2.2 +jsonfield==3.1.0 diff --git a/setup.py b/setup.py index 8c80fa9..a2d0153 100755 --- a/setup.py +++ b/setup.py @@ -77,7 +77,7 @@ def get_long_description(): license='Apache License 2.0', url='https://github.com/tulsawebdevs/django-multi-gtfs', packages=find_packages(), - install_requires=['Django>=1.8', 'jsonfield>=0.9.20'], + install_requires=['Django>=2.0,<=2.2', 'jsonfield>=0.9.20'], keywords=['django', 'gtfs'], test_suite="run_tests", # Ignored, but makes pyroma happy cmdclass={'test': my_test}, From a48d0b0e84fe535103b3834b8fb41deb3ff3d987 Mon Sep 17 00:00:00 2001 From: Dalibor Pavlovic Date: Mon, 22 Nov 2021 15:39:34 +0100 Subject: [PATCH 2/7] Remove django.utils.six --- multigtfs/compat.py | 17 +++++------------ multigtfs/models/base.py | 16 ++++++++-------- multigtfs/models/feed.py | 3 +-- multigtfs/models/stop.py | 2 +- multigtfs/tests/test_agency.py | 2 +- multigtfs/tests/test_fare.py | 2 +- multigtfs/tests/test_fare_rule.py | 2 +- multigtfs/tests/test_feed.py | 9 ++++----- multigtfs/tests/test_feed_info.py | 2 +- multigtfs/tests/test_frequency.py | 2 +- multigtfs/tests/test_route.py | 2 +- multigtfs/tests/test_service.py | 2 +- multigtfs/tests/test_service_date.py | 2 +- multigtfs/tests/test_shape.py | 2 +- multigtfs/tests/test_stop.py | 2 +- multigtfs/tests/test_stop_time.py | 2 +- multigtfs/tests/test_transfer.py | 2 +- multigtfs/tests/test_trip.py | 2 +- 18 files changed, 32 insertions(+), 41 deletions(-) diff --git a/multigtfs/compat.py b/multigtfs/compat.py index 4d608f8..d7858c8 100644 --- a/multigtfs/compat.py +++ b/multigtfs/compat.py @@ -7,7 +7,6 @@ from zipfile import ZipFile, ZIP_DEFLATED from django import get_version -from django.utils.six import PY3, binary_type, text_type DJ_VERSION = LooseVersion(get_version()) @@ -47,15 +46,12 @@ def bom_prefix_csv(text): - Python 2 returns a UTF-8 encoded bytestring - Python 3 returns unicode text """ - if PY3: - return BOM_UTF8.decode('utf-8') + text - else: - return BOM_UTF8 + text.encode('utf-8') + return BOM_UTF8.decode('utf-8') + text def force_utf8(text): """Encode as UTF-8 bytestring if it isn't already.""" - if isinstance(text, binary_type): + if isinstance(text, bytes): return text else: return text.encode('utf-8') @@ -79,11 +75,8 @@ def opener_from_zipfile(zipfile): def opener(filename): inner_file = zipfile.open(filename) - if PY3: - from io import TextIOWrapper - return TextIOWrapper(inner_file) - else: - return inner_file + from io import TextIOWrapper + return TextIOWrapper(inner_file) return opener @@ -97,7 +90,7 @@ def write_text_rows(writer, rows): # Python 2 csv does badly with unicode outside of ASCII new_row = [] for item in row: - if isinstance(item, text_type): + if isinstance(item, str): new_row.append(item.encode('utf-8')) else: new_row.append(item) diff --git a/multigtfs/models/base.py b/multigtfs/models/base.py index 8054999..3771653 100644 --- a/multigtfs/models/base.py +++ b/multigtfs/models/base.py @@ -22,7 +22,7 @@ from django.contrib.gis.db import models from django.db.models.fields.related import ManyToManyField -from django.utils.six import StringIO, text_type, PY3 +from io import StringIO from multigtfs.compat import ( get_blank_value, write_text_rows, Manager, QuerySet) @@ -30,7 +30,7 @@ logger = getLogger(__name__) re_point = re.compile(r'(?Ppoint)\[(?P\d)\]') batch_size = 1000 -CSV_BOM = BOM_UTF8.decode('utf-8') if PY3 else BOM_UTF8 +CSV_BOM = BOM_UTF8.decode('utf-8') class BaseQuerySet(QuerySet): @@ -142,14 +142,14 @@ def get_instance(value): if value.strip(): related = field.related_model key1 = "{}:{}".format(related.__name__, rel_name) - key2 = text_type(value) + key2 = str(value) # Load existing objects if key1 not in cache: pairs = related.objects.filter( **{related._rel_to_feed: feed}).values_list( rel_name, 'id') - cache[key1] = dict((text_type(x), i) for x, i in pairs) + cache[key1] = dict((str(x), i) for x, i in pairs) # Create new? if key2 not in cache[key1]: @@ -333,7 +333,7 @@ def export_txt(cls, feed): csv_writer = writer(out, lineterminator='\n') # Write header row - header_row = [text_type(c) for c in columns] + header_row = [str(c) for c in columns] header_row.extend(extra_columns) write_text_rows(csv_writer, [header_row]) @@ -360,7 +360,7 @@ def export_txt(cls, feed): pairs = field_type.objects.in_feed( feed).values_list('id', subfield_name) cache[field_name] = dict( - (i, text_type(x)) for i, x in pairs) + (i, str(x)) for i, x in pairs) cache[field_name][None] = u'' model_to_field_name[model_name] = field_name @@ -387,13 +387,13 @@ def export_txt(cls, feed): field = getattr(obj, field_name) if obj else '' if isinstance(field, date): formatted = field.strftime(u'%Y%m%d') - row.append(text_type(formatted)) + row.append(str(formatted)) elif isinstance(field, bool): row.append(1 if field else 0) elif field is None: row.append(u'') else: - row.append(text_type(field)) + row.append(str(field)) for col in extra_columns: row.append(obj.extra_data.get(col, u'')) rows.append(row) diff --git a/multigtfs/models/feed.py b/multigtfs/models/feed.py index 941dd9e..7d05732 100644 --- a/multigtfs/models/feed.py +++ b/multigtfs/models/feed.py @@ -21,7 +21,6 @@ from django.contrib.gis.db import models from django.db.models.signals import post_save -from django.utils.six import string_types from jsonfield import JSONField from multigtfs.compat import open_writable_zipfile, opener_from_zipfile @@ -76,7 +75,7 @@ def import_gtfs(self, gtfs_obj): # Determine the type of gtfs_obj opener = None filelist = None - if isinstance(gtfs_obj, string_types) and os.path.isdir(gtfs_obj): + if isinstance(gtfs_obj, str) and os.path.isdir(gtfs_obj): opener = open filelist = [] for dirpath, dirnames, filenames in os.walk(gtfs_obj): diff --git a/multigtfs/models/stop.py b/multigtfs/models/stop.py index 15573a4..723d0b8 100644 --- a/multigtfs/models/stop.py +++ b/multigtfs/models/stop.py @@ -18,7 +18,7 @@ from django.db.models.signals import post_save from django.dispatch import receiver -from django.utils.six import StringIO +from io import StringIO from jsonfield import JSONField from multigtfs.models.base import models, Base diff --git a/multigtfs/tests/test_agency.py b/multigtfs/tests/test_agency.py index 2ab414e..8df5246 100644 --- a/multigtfs/tests/test_agency.py +++ b/multigtfs/tests/test_agency.py @@ -16,7 +16,7 @@ from __future__ import unicode_literals from django.test import TestCase -from django.utils.six import StringIO +from io import StringIO from multigtfs.models import Agency, Feed from multigtfs.compat import bom_prefix_csv diff --git a/multigtfs/tests/test_fare.py b/multigtfs/tests/test_fare.py index 4060d69..9089d43 100644 --- a/multigtfs/tests/test_fare.py +++ b/multigtfs/tests/test_fare.py @@ -16,7 +16,7 @@ from __future__ import unicode_literals from django.test import TestCase -from django.utils.six import StringIO +from io import StringIO from multigtfs.models import Feed, Fare diff --git a/multigtfs/tests/test_fare_rule.py b/multigtfs/tests/test_fare_rule.py index 3e7a5a1..90eebcd 100644 --- a/multigtfs/tests/test_fare_rule.py +++ b/multigtfs/tests/test_fare_rule.py @@ -16,7 +16,7 @@ from __future__ import unicode_literals from django.test import TestCase -from django.utils.six import StringIO +from io import StringIO from multigtfs.models import Feed, Fare, FareRule, Route, Zone diff --git a/multigtfs/tests/test_feed.py b/multigtfs/tests/test_feed.py index 3472ea1..5e16ac0 100644 --- a/multigtfs/tests/test_feed.py +++ b/multigtfs/tests/test_feed.py @@ -21,7 +21,6 @@ import zipfile from django.test import TestCase -from django.utils.six import text_type from multigtfs.models import ( Agency, Block, Fare, FareRule, Feed, FeedInfo, Frequency, @@ -463,8 +462,8 @@ def test_export_gtfs_test2(self): # Sometimes 5.2500, sometimes 5.25 fare_a = Fare.objects.get(fare_id='a') fare_p = Fare.objects.get(fare_id='p') - s_fare_a = text_type(fare_a.price).encode('utf-8') - s_fare_p = text_type(fare_p.price).encode('utf-8') + s_fare_a = str(fare_a.price).encode('utf-8') + s_fare_p = str(fare_p.price).encode('utf-8') fare_out = z_out.read('fare_attributes.txt') self.assertEqual(fare_out, b'''\ fare_id,price,currency_type,payment_method,transfers @@ -735,7 +734,7 @@ def test_export_gtfs_test3(self): ''') # Sometimes 1.5000, sometimes 1.5 fare_a = Fare.objects.get(fare_id='adult') - s_fare_a = text_type(fare_a.price).encode('utf-8') + s_fare_a = str(fare_a.price).encode('utf-8') fare_out = z_out.read('fare_attributes.txt') self.assertEqual(fare_out, b'''\ fare_id,price,currency_type,payment_method,transfers,transfer_duration @@ -832,7 +831,7 @@ def test_export_gtfs_test4(self): ''') # Sometimes 2.5000, sometimes 2.5 fare_b = Fare.objects.get(fare_id='B') - s_fare_b = text_type(fare_b.price).encode('utf-8') + s_fare_b = str(fare_b.price).encode('utf-8') fare_out = z_out.read('fare_attributes.txt') self.assertEqual(fare_out, b'''\ fare_id,price,currency_type,payment_method,transfers,transfer_duration diff --git a/multigtfs/tests/test_feed_info.py b/multigtfs/tests/test_feed_info.py index f8f37b5..e77a83c 100644 --- a/multigtfs/tests/test_feed_info.py +++ b/multigtfs/tests/test_feed_info.py @@ -17,7 +17,7 @@ from datetime import date from django.test import TestCase -from django.utils.six import StringIO +from io import StringIO from multigtfs.models import Feed, FeedInfo diff --git a/multigtfs/tests/test_frequency.py b/multigtfs/tests/test_frequency.py index 4151ac3..f6e782a 100644 --- a/multigtfs/tests/test_frequency.py +++ b/multigtfs/tests/test_frequency.py @@ -19,7 +19,7 @@ from django.core.serializers import serialize from django.test import TestCase -from django.utils.six import StringIO +from io import StringIO from multigtfs.models import Feed, Frequency, Route, Service, Trip from multigtfs.models.fields import Seconds diff --git a/multigtfs/tests/test_route.py b/multigtfs/tests/test_route.py index dacf127..3934674 100644 --- a/multigtfs/tests/test_route.py +++ b/multigtfs/tests/test_route.py @@ -16,7 +16,7 @@ from __future__ import unicode_literals from django.test import TestCase -from django.utils.six import StringIO +from io import StringIO from multigtfs.models import Feed, Agency, Route, Trip diff --git a/multigtfs/tests/test_service.py b/multigtfs/tests/test_service.py index 20d82f6..469092d 100644 --- a/multigtfs/tests/test_service.py +++ b/multigtfs/tests/test_service.py @@ -17,7 +17,7 @@ from datetime import date from django.test import TestCase -from django.utils.six import StringIO +from io import StringIO from multigtfs.models import Feed, Service diff --git a/multigtfs/tests/test_service_date.py b/multigtfs/tests/test_service_date.py index ab7325c..b917bfe 100644 --- a/multigtfs/tests/test_service_date.py +++ b/multigtfs/tests/test_service_date.py @@ -17,7 +17,7 @@ from datetime import date from django.test import TestCase -from django.utils.six import StringIO +from io import StringIO from multigtfs.models import Feed, Service, ServiceDate diff --git a/multigtfs/tests/test_shape.py b/multigtfs/tests/test_shape.py index d6311f9..6a42551 100644 --- a/multigtfs/tests/test_shape.py +++ b/multigtfs/tests/test_shape.py @@ -17,7 +17,7 @@ from django.contrib.gis.geos import MultiLineString from django.test import TestCase -from django.utils.six import StringIO +from io import StringIO from multigtfs.models import Feed, Route, Shape, ShapePoint, Trip diff --git a/multigtfs/tests/test_stop.py b/multigtfs/tests/test_stop.py index da40824..566ad91 100644 --- a/multigtfs/tests/test_stop.py +++ b/multigtfs/tests/test_stop.py @@ -17,7 +17,7 @@ from django.contrib.gis.geos import MultiLineString from django.test import TestCase -from django.utils.six import StringIO +from io import StringIO from multigtfs.compat import bom_prefix_csv, force_utf8 from multigtfs.models import Feed, Route, Stop, StopTime, Trip, Zone diff --git a/multigtfs/tests/test_stop_time.py b/multigtfs/tests/test_stop_time.py index aba429e..cd4d877 100644 --- a/multigtfs/tests/test_stop_time.py +++ b/multigtfs/tests/test_stop_time.py @@ -17,7 +17,7 @@ from datetime import time from django.test import TestCase -from django.utils.six import StringIO +from io import StringIO from multigtfs.models import Feed, Route, Stop, StopTime, Trip diff --git a/multigtfs/tests/test_transfer.py b/multigtfs/tests/test_transfer.py index d7760ce..f4f9e68 100644 --- a/multigtfs/tests/test_transfer.py +++ b/multigtfs/tests/test_transfer.py @@ -16,7 +16,7 @@ from __future__ import unicode_literals from django.test import TestCase -from django.utils.six import StringIO +from io import StringIO from multigtfs.models import Feed, Stop, Transfer diff --git a/multigtfs/tests/test_trip.py b/multigtfs/tests/test_trip.py index 681cd8c..e2e656c 100644 --- a/multigtfs/tests/test_trip.py +++ b/multigtfs/tests/test_trip.py @@ -17,7 +17,7 @@ from datetime import date, time from django.test import TestCase -from django.utils.six import StringIO +from io import StringIO from multigtfs.models import ( Block, Feed, Route, Service, Shape, Stop, StopTime, Trip) From ea93c7f0ff77b61bdddb3f7a954a63ff2f38c2c1 Mon Sep 17 00:00:00 2001 From: Dalibor Pavlovic Date: Mon, 22 Nov 2021 15:59:14 +0100 Subject: [PATCH 3/7] Upgrade Django>=2.2,<=3.2 --- requirements.txt | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 9b9047b..d0809db 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ -Django>=2.0,<=2.2 +Django>=2.2 jsonfield==3.1.0 diff --git a/setup.py b/setup.py index a2d0153..970196d 100755 --- a/setup.py +++ b/setup.py @@ -77,7 +77,7 @@ def get_long_description(): license='Apache License 2.0', url='https://github.com/tulsawebdevs/django-multi-gtfs', packages=find_packages(), - install_requires=['Django>=2.0,<=2.2', 'jsonfield>=0.9.20'], + install_requires=['Django>=2.2', 'jsonfield>=0.9.20'], keywords=['django', 'gtfs'], test_suite="run_tests", # Ignored, but makes pyroma happy cmdclass={'test': my_test}, From 8b83f9493660be9661bc99c9611a1f5fd00c7aea Mon Sep 17 00:00:00 2001 From: Dalibor Pavlovic Date: Tue, 23 Nov 2021 10:06:54 +0100 Subject: [PATCH 4/7] Remove jsonfield --- Dockerfile | 2 +- multigtfs/migrations/0001_initial.py | 29 ++++++++++++++-------------- multigtfs/models/agency.py | 4 +--- multigtfs/models/fare.py | 4 +--- multigtfs/models/fare_rule.py | 4 +--- multigtfs/models/feed.py | 4 +--- multigtfs/models/feed_info.py | 4 +--- multigtfs/models/frequency.py | 4 +--- multigtfs/models/route.py | 4 +--- multigtfs/models/service.py | 4 +--- multigtfs/models/service_date.py | 4 +--- multigtfs/models/shape.py | 4 +--- multigtfs/models/stop.py | 4 +--- multigtfs/models/stop_time.py | 4 +--- multigtfs/models/transfer.py | 4 +--- multigtfs/models/trip.py | 4 +--- 16 files changed, 29 insertions(+), 58 deletions(-) diff --git a/Dockerfile b/Dockerfile index a99f09f..fbd50f5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ ENV PYTHONUNBUFFERED 1 RUN apt-get update RUN apt-get install -y binutils libproj-dev gdal-bin postgresql-client -RUN pip install "django>=2.0,<=2.2" "psycopg2==2.8.6" +RUN pip install "django>=2.2" "psycopg2" RUN mkdir /code RUN mkdir /feeds diff --git a/multigtfs/migrations/0001_initial.py b/multigtfs/migrations/0001_initial.py index 8ce5dc0..b151e09 100644 --- a/multigtfs/migrations/0001_initial.py +++ b/multigtfs/migrations/0001_initial.py @@ -3,7 +3,6 @@ from __future__ import unicode_literals from django.db import models, migrations -import jsonfield.fields import django.contrib.gis.db.models.fields import multigtfs.models.fields.seconds @@ -25,7 +24,7 @@ class Migration(migrations.Migration): ('lang', models.CharField(help_text='ISO 639-1 code for the primary language', max_length=2, blank=True)), ('phone', models.CharField(help_text='Voice telephone number', max_length=255, blank=True)), ('fare_url', models.URLField(help_text='URL for purchasing tickets online', blank=True)), - ('extra_data', jsonfield.fields.JSONField(default={}, null=True, blank=True)), + ('extra_data', models.JSONField(default={}, null=True, blank=True)), ], options={ 'db_table': 'agency', @@ -54,7 +53,7 @@ class Migration(migrations.Migration): ('payment_method', models.IntegerField(default=1, help_text='When is the fare paid?', choices=[(0, 'Fare is paid on board.'), (1, 'Fare must be paid before boarding.')])), ('transfers', models.IntegerField(default=None, help_text='Are transfers permitted?', null=True, blank=True, choices=[(0, 'No transfers permitted on this fare.'), (1, 'Passenger may transfer once.'), (2, 'Passenger may transfer twice.'), (None, 'Unlimited transfers are permitted.')])), ('transfer_duration', models.IntegerField(help_text='Time in seconds until a ticket or transfer expires', null=True, blank=True)), - ('extra_data', jsonfield.fields.JSONField(default={}, null=True, blank=True)), + ('extra_data', models.JSONField(default={}, null=True, blank=True)), ], options={ 'db_table': 'fare', @@ -65,7 +64,7 @@ class Migration(migrations.Migration): name='FareRule', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('extra_data', jsonfield.fields.JSONField(default={}, null=True, blank=True)), + ('extra_data', models.JSONField(default={}, null=True, blank=True)), ], options={ 'db_table': 'fare_rules', @@ -78,7 +77,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('name', models.CharField(max_length=255)), ('created', models.DateTimeField(auto_now_add=True)), - ('meta', jsonfield.fields.JSONField(default={}, null=True, blank=True)), + ('meta', models.JSONField(default={}, null=True, blank=True)), ], options={ 'db_table': 'feed', @@ -95,7 +94,7 @@ class Migration(migrations.Migration): ('start_date', models.DateField(help_text='Date that feed starts providing reliable data.', null=True, blank=True)), ('end_date', models.DateField(help_text='Date that feed stops providing reliable data.', null=True, blank=True)), ('version', models.CharField(help_text='Version of feed.', max_length=255, blank=True)), - ('extra_data', jsonfield.fields.JSONField(default={}, null=True, blank=True)), + ('extra_data', models.JSONField(default={}, null=True, blank=True)), ('feed', models.ForeignKey(to='multigtfs.Feed', on_delete=django.db.models.deletion.CASCADE)), ], options={ @@ -112,7 +111,7 @@ class Migration(migrations.Migration): ('end_time', multigtfs.models.fields.seconds.SecondsField(help_text='Time that the service ends at the specified frequency')), ('headway_secs', models.IntegerField(help_text='Time in seconds before returning to same stop')), ('exact_times', models.CharField(blank=True, help_text='Should frequency-based trips be exactly scheduled?', max_length=1, choices=[(0, 'Trips are not exactly scheduled'), (1, 'Trips are exactly scheduled from start time')])), - ('extra_data', jsonfield.fields.JSONField(default={}, null=True, blank=True)), + ('extra_data', models.JSONField(default={}, null=True, blank=True)), ], options={ 'db_table': 'frequency', @@ -133,7 +132,7 @@ class Migration(migrations.Migration): ('color', models.CharField(help_text='Color of route in hex', max_length=6, blank=True)), ('text_color', models.CharField(help_text='Color of route text in hex', max_length=6, blank=True)), ('geometry', django.contrib.gis.db.models.fields.MultiLineStringField(help_text='Geometry cache of Trips', srid=4326, null=True, blank=True)), - ('extra_data', jsonfield.fields.JSONField(default={}, null=True, blank=True)), + ('extra_data', models.JSONField(default={}, null=True, blank=True)), ('agency', models.ForeignKey(blank=True, to='multigtfs.Agency', help_text='Agency for this route.', null=True, on_delete=django.db.models.deletion.CASCADE)), ('feed', models.ForeignKey(to='multigtfs.Feed', on_delete=django.db.models.deletion.CASCADE)), ], @@ -156,7 +155,7 @@ class Migration(migrations.Migration): ('sunday', models.BooleanField(default=True, help_text='Is the route active on Sunday?')), ('start_date', models.DateField(null=True, blank=True)), ('end_date', models.DateField(null=True, blank=True)), - ('extra_data', jsonfield.fields.JSONField(default={}, null=True, blank=True)), + ('extra_data', models.JSONField(default={}, null=True, blank=True)), ('feed', models.ForeignKey(to='multigtfs.Feed', on_delete=django.db.models.deletion.CASCADE)), ], options={ @@ -170,7 +169,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('date', models.DateField(help_text='Date that the service differs from the norm.')), ('exception_type', models.IntegerField(default=1, help_text='Is service added or removed on this date?', choices=[(1, 'Added'), (2, 'Removed')])), - ('extra_data', jsonfield.fields.JSONField(default={}, null=True, blank=True)), + ('extra_data', models.JSONField(default={}, null=True, blank=True)), ('service', models.ForeignKey(to='multigtfs.Service', on_delete=django.db.models.deletion.CASCADE)), ], options={ @@ -198,7 +197,7 @@ class Migration(migrations.Migration): ('point', django.contrib.gis.db.models.fields.PointField(help_text='WGS 84 latitude/longitude of shape point', srid=4326)), ('sequence', models.IntegerField()), ('traveled', models.FloatField(help_text='Distance of point from start of shape', null=True, blank=True)), - ('extra_data', jsonfield.fields.JSONField(default={}, null=True, blank=True)), + ('extra_data', models.JSONField(default={}, null=True, blank=True)), ('shape', models.ForeignKey(related_name='points', to='multigtfs.Shape', on_delete=django.db.models.deletion.CASCADE)), ], options={ @@ -219,7 +218,7 @@ class Migration(migrations.Migration): ('location_type', models.CharField(blank=True, help_text='Is this a stop or station?', max_length=1, choices=[('0', 'Stop'), ('1', 'Station')])), ('timezone', models.CharField(help_text='Timezone of the stop', max_length=255, blank=True)), ('wheelchair_boarding', models.CharField(blank=True, help_text='Is wheelchair boarding possible?', max_length=1, choices=[('0', 'No information'), ('1', 'Some wheelchair boarding'), ('2', 'No wheelchair boarding')])), - ('extra_data', jsonfield.fields.JSONField(default={}, null=True, blank=True)), + ('extra_data', models.JSONField(default={}, null=True, blank=True)), ('feed', models.ForeignKey(to='multigtfs.Feed', on_delete=django.db.models.deletion.CASCADE)), ('parent_station', models.ForeignKey(blank=True, to='multigtfs.Stop', help_text='The station associated with the stop', null=True, on_delete=django.db.models.deletion.CASCADE)), ], @@ -239,7 +238,7 @@ class Migration(migrations.Migration): ('pickup_type', models.CharField(blank=True, help_text='How passengers are picked up', max_length=1, choices=[('0', 'Regularly scheduled pickup'), ('1', 'No pickup available'), ('2', 'Must phone agency to arrange pickup'), ('3', 'Must coordinate with driver to arrange pickup')])), ('drop_off_type', models.CharField(blank=True, help_text='How passengers are picked up', max_length=1, choices=[('0', 'Regularly scheduled drop off'), ('1', 'No drop off available'), ('2', 'Must phone agency to arrange drop off'), ('3', 'Must coordinate with driver to arrange drop off')])), ('shape_dist_traveled', models.FloatField(help_text='Distance of stop from start of shape', null=True, verbose_name='shape distance traveled', blank=True)), - ('extra_data', jsonfield.fields.JSONField(default={}, null=True, blank=True)), + ('extra_data', models.JSONField(default={}, null=True, blank=True)), ('stop', models.ForeignKey(to='multigtfs.Stop', on_delete=django.db.models.deletion.CASCADE)), ], options={ @@ -253,7 +252,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('transfer_type', models.IntegerField(default=0, help_text='What kind of transfer?', blank=True, choices=[(0, 'Recommended transfer point'), (1, 'Timed transfer point (vehicle will wait)'), (2, 'min_transfer_time needed to successfully transfer'), (3, 'No transfers possible')])), ('min_transfer_time', models.IntegerField(help_text='How many seconds are required to transfer?', null=True, blank=True)), - ('extra_data', jsonfield.fields.JSONField(default={}, null=True, blank=True)), + ('extra_data', models.JSONField(default={}, null=True, blank=True)), ('from_stop', models.ForeignKey(related_name='transfer_from_stop', to='multigtfs.Stop', help_text='Stop where a connection between routes begins.', on_delete=django.db.models.deletion.CASCADE)), ('to_stop', models.ForeignKey(related_name='transfer_to_stop', to='multigtfs.Stop', help_text='Stop where a connection between routes ends.', on_delete=django.db.models.deletion.CASCADE)), ], @@ -273,7 +272,7 @@ class Migration(migrations.Migration): ('geometry', django.contrib.gis.db.models.fields.LineStringField(help_text='Geometry cache of Shape or Stops', srid=4326, null=True, blank=True)), ('wheelchair_accessible', models.CharField(blank=True, help_text='Are there accommodations for riders with wheelchair?', max_length=1, choices=[('0', 'No information'), ('1', 'Some wheelchair accommodation'), ('2', 'No wheelchair accommodation')])), ('bikes_allowed', models.CharField(blank=True, help_text='Are bicycles allowed?', max_length=1, choices=[('0', 'No information'), ('1', 'Some bicycle accommodation'), ('2', 'No bicycles allowed')])), - ('extra_data', jsonfield.fields.JSONField(default={}, null=True, blank=True)), + ('extra_data', models.JSONField(default={}, null=True, blank=True)), ('block', models.ForeignKey(blank=True, to='multigtfs.Block', help_text='Block of sequential trips that this trip belongs to.', null=True, on_delete=django.db.models.deletion.CASCADE)), ('route', models.ForeignKey(to='multigtfs.Route', on_delete=django.db.models.deletion.CASCADE)), ('service', models.ForeignKey(blank=True, to='multigtfs.Service', null=True, on_delete=django.db.models.deletion.CASCADE)), diff --git a/multigtfs/models/agency.py b/multigtfs/models/agency.py index 740ff4e..7b68586 100644 --- a/multigtfs/models/agency.py +++ b/multigtfs/models/agency.py @@ -15,8 +15,6 @@ from __future__ import unicode_literals -from jsonfield import JSONField - from multigtfs.models.base import models, Base @@ -45,7 +43,7 @@ class Agency(Base): help_text="Voice telephone number") fare_url = models.URLField( blank=True, help_text="URL for purchasing tickets online") - extra_data = JSONField(default={}, blank=True, null=True) + extra_data = models.JSONField(default=dict, blank=True, null=True) def __str__(self): return u"%d-%s" % (self.feed.id, self.agency_id) diff --git a/multigtfs/models/fare.py b/multigtfs/models/fare.py index 9b3440a..6a7124b 100644 --- a/multigtfs/models/fare.py +++ b/multigtfs/models/fare.py @@ -14,8 +14,6 @@ # limitations under the License. from __future__ import unicode_literals -from jsonfield import JSONField - from multigtfs.models.base import models, Base @@ -47,7 +45,7 @@ class Fare(Base): transfer_duration = models.IntegerField( null=True, blank=True, help_text="Time in seconds until a ticket or transfer expires") - extra_data = JSONField(default={}, blank=True, null=True) + extra_data = models.JSONField(default=dict, blank=True, null=True) def __str__(self): return u"%d-%s(%s %s)" % ( diff --git a/multigtfs/models/fare_rule.py b/multigtfs/models/fare_rule.py index ef6026e..65150b6 100644 --- a/multigtfs/models/fare_rule.py +++ b/multigtfs/models/fare_rule.py @@ -14,8 +14,6 @@ # limitations under the License. from __future__ import unicode_literals -from jsonfield import JSONField - from multigtfs.models.base import models, Base @@ -37,7 +35,7 @@ class FareRule(Base): 'Zone', null=True, blank=True, on_delete=models.SET_NULL, related_name='fare_contains', help_text="Fare class is valid for travel withing this zone.") - extra_data = JSONField(default={}, blank=True, null=True) + extra_data = models.JSONField(default=dict, blank=True, null=True) def __str__(self): u = "%d-%s" % (self.fare.feed.id, self.fare.fare_id) diff --git a/multigtfs/models/feed.py b/multigtfs/models/feed.py index 7d05732..f2eda19 100644 --- a/multigtfs/models/feed.py +++ b/multigtfs/models/feed.py @@ -21,8 +21,6 @@ from django.contrib.gis.db import models from django.db.models.signals import post_save -from jsonfield import JSONField - from multigtfs.compat import open_writable_zipfile, opener_from_zipfile from .agency import Agency from .fare import Fare @@ -49,7 +47,7 @@ class Feed(models.Model): """ name = models.CharField(max_length=255) created = models.DateTimeField(auto_now_add=True) - meta = JSONField(default={}, blank=True, null=True) + meta = models.JSONField(default=dict, blank=True, null=True) class Meta: db_table = 'feed' diff --git a/multigtfs/models/feed_info.py b/multigtfs/models/feed_info.py index 27b4ff9..7569779 100644 --- a/multigtfs/models/feed_info.py +++ b/multigtfs/models/feed_info.py @@ -14,8 +14,6 @@ # limitations under the License. from __future__ import unicode_literals -from jsonfield import JSONField - from multigtfs.models.base import models, Base @@ -43,7 +41,7 @@ class FeedInfo(Base): version = models.CharField( max_length=255, blank=True, help_text="Version of feed.") - extra_data = JSONField(default={}, blank=True, null=True) + extra_data = models.JSONField(default=dict, blank=True, null=True) def __str__(self): return '%s-%s' % (self.feed.id, self.publisher_name) diff --git a/multigtfs/models/frequency.py b/multigtfs/models/frequency.py index 138c701..b063f26 100644 --- a/multigtfs/models/frequency.py +++ b/multigtfs/models/frequency.py @@ -14,8 +14,6 @@ # limitations under the License. from __future__ import unicode_literals -from jsonfield import JSONField - from multigtfs.models.base import models, Base from multigtfs.models.fields import SecondsField @@ -34,7 +32,7 @@ class Frequency(Base): choices=(('0', 'Trips are not exactly scheduled'), ('1', 'Trips are exactly scheduled from start time')), help_text="Should frequency-based trips be exactly scheduled?") - extra_data = JSONField(default={}, blank=True, null=True) + extra_data = models.JSONField(default=dict, blank=True, null=True) def __str__(self): return str(self.trip) diff --git a/multigtfs/models/route.py b/multigtfs/models/route.py index 164b3dd..4df2648 100644 --- a/multigtfs/models/route.py +++ b/multigtfs/models/route.py @@ -15,8 +15,6 @@ from __future__ import unicode_literals from django.contrib.gis.geos import MultiLineString -from jsonfield import JSONField - from multigtfs.models.base import models, Base @@ -65,7 +63,7 @@ class Route(Base): geometry = models.MultiLineStringField( null=True, blank=True, help_text='Geometry cache of Trips') - extra_data = JSONField(default={}, blank=True, null=True) + extra_data = models.JSONField(default=dict, blank=True, null=True) def update_geometry(self): """Update the geometry from the Trips""" diff --git a/multigtfs/models/service.py b/multigtfs/models/service.py index 3dac8d2..936e63a 100644 --- a/multigtfs/models/service.py +++ b/multigtfs/models/service.py @@ -14,8 +14,6 @@ # limitations under the License. from __future__ import unicode_literals -from jsonfield import JSONField - from multigtfs.models.base import models, Base @@ -52,7 +50,7 @@ class Service(Base): help_text="Is the route active on Sunday?") start_date = models.DateField(null=True, blank=True) end_date = models.DateField(null=True, blank=True) - extra_data = JSONField(default={}, blank=True, null=True) + extra_data = models.JSONField(default=dict, blank=True, null=True) def __str__(self): return "%d-%s" % (self.feed.id, self.service_id) diff --git a/multigtfs/models/service_date.py b/multigtfs/models/service_date.py index db35664..600b180 100644 --- a/multigtfs/models/service_date.py +++ b/multigtfs/models/service_date.py @@ -14,8 +14,6 @@ # limitations under the License. from __future__ import unicode_literals -from jsonfield import JSONField - from multigtfs.models.base import models, Base @@ -30,7 +28,7 @@ class ServiceDate(Base): exception_type = models.IntegerField( default=1, choices=((1, 'Added'), (2, 'Removed')), help_text="Is service added or removed on this date?") - extra_data = JSONField(default={}, blank=True, null=True) + extra_data = models.JSONField(default=dict, blank=True, null=True) def __str__(self): return ( diff --git a/multigtfs/models/shape.py b/multigtfs/models/shape.py index 201edd8..4add540 100644 --- a/multigtfs/models/shape.py +++ b/multigtfs/models/shape.py @@ -18,8 +18,6 @@ from django.contrib.gis.geos import LineString from django.db.models.signals import post_save from django.dispatch import receiver -from jsonfield import JSONField - from multigtfs.models.base import models, Base @@ -68,7 +66,7 @@ class ShapePoint(Base): traveled = models.FloatField( null=True, blank=True, help_text='Distance of point from start of shape') - extra_data = JSONField(default={}, blank=True, null=True) + extra_data = models.JSONField(default=dict, blank=True, null=True) def __str__(self): return "%s-%d" % (self.shape, self.sequence) diff --git a/multigtfs/models/stop.py b/multigtfs/models/stop.py index 723d0b8..cd35aa4 100644 --- a/multigtfs/models/stop.py +++ b/multigtfs/models/stop.py @@ -19,8 +19,6 @@ from django.db.models.signals import post_save from django.dispatch import receiver from io import StringIO -from jsonfield import JSONField - from multigtfs.models.base import models, Base @@ -69,7 +67,7 @@ class Stop(Base): ('1', 'Some wheelchair boarding'), ('2', 'No wheelchair boarding')), help_text='Is wheelchair boarding possible?') - extra_data = JSONField(default={}, blank=True, null=True) + extra_data = models.JSONField(default=dict, blank=True, null=True) def __str__(self): return "%d-%s" % (self.feed_id, self.stop_id) diff --git a/multigtfs/models/stop_time.py b/multigtfs/models/stop_time.py index f479922..f0fb429 100644 --- a/multigtfs/models/stop_time.py +++ b/multigtfs/models/stop_time.py @@ -14,8 +14,6 @@ # limitations under the License. from __future__ import unicode_literals -from jsonfield import JSONField - from multigtfs.models.base import models, Base from multigtfs.models.stop import Stop from multigtfs.models.trip import Trip @@ -57,7 +55,7 @@ class StopTime(Base): "shape distance traveled", null=True, blank=True, help_text='Distance of stop from start of shape') - extra_data = JSONField(default={}, blank=True, null=True) + extra_data = models.JSONField(default=dict, blank=True, null=True) def __str__(self): return "%s-%s-%s" % (self.trip, self.stop.stop_id, self.stop_sequence) diff --git a/multigtfs/models/transfer.py b/multigtfs/models/transfer.py index 7cde081..58bfbeb 100644 --- a/multigtfs/models/transfer.py +++ b/multigtfs/models/transfer.py @@ -14,8 +14,6 @@ # limitations under the License. from __future__ import unicode_literals -from jsonfield import JSONField - from multigtfs.models.base import models, Base @@ -42,7 +40,7 @@ class Transfer(Base): min_transfer_time = models.IntegerField( null=True, blank=True, help_text="How many seconds are required to transfer?") - extra_data = JSONField(default={}, blank=True, null=True) + extra_data = models.JSONField(default=dict, blank=True, null=True) def __str__(self): return "%s-%s" % (self.from_stop, self.to_stop.stop_id) diff --git a/multigtfs/models/trip.py b/multigtfs/models/trip.py index 46c2d53..543005b 100644 --- a/multigtfs/models/trip.py +++ b/multigtfs/models/trip.py @@ -15,8 +15,6 @@ from __future__ import unicode_literals from django.contrib.gis.geos import LineString -from jsonfield import JSONField - from multigtfs.models.base import models, Base @@ -65,7 +63,7 @@ class Trip(Base): ('1', 'Some bicycle accommodation'), ('2', 'No bicycles allowed')), help_text='Are bicycles allowed?') - extra_data = JSONField(default={}, blank=True, null=True) + extra_data = models.JSONField(default=dict, blank=True, null=True) def update_geometry(self, update_parent=True): """Update the geometry from the Shape or Stops""" From 67a4d029761c45c7903dbe7e14d5533d359eed6a Mon Sep 17 00:00:00 2001 From: Dalibor Pavlovic Date: Wed, 24 Nov 2021 11:19:32 +0100 Subject: [PATCH 5/7] Fix from_db_value --- multigtfs/models/fields/seconds.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/multigtfs/models/fields/seconds.py b/multigtfs/models/fields/seconds.py index a093790..1bfde27 100644 --- a/multigtfs/models/fields/seconds.py +++ b/multigtfs/models/fields/seconds.py @@ -67,7 +67,7 @@ class SecondsField(Field): description = 'Seconds since start of the day' - def from_db_value(self, value, expression, connection, context): + def from_db_value(self, value, expression, connection): '''Handle data loaded from database.''' if value is None: return value From c675f49504015735c90fbf74e971787b7cc61491 Mon Sep 17 00:00:00 2001 From: Dalibor Pavlovic Date: Wed, 24 Nov 2021 11:30:16 +0100 Subject: [PATCH 6/7] Fix "seconds" test --- multigtfs/tests/test_frequency.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/multigtfs/tests/test_frequency.py b/multigtfs/tests/test_frequency.py index f6e782a..45c3325 100644 --- a/multigtfs/tests/test_frequency.py +++ b/multigtfs/tests/test_frequency.py @@ -130,14 +130,14 @@ def test_serialize(self): headway_secs=1800) actual = loads(serialize('json', Frequency.objects.all())) expected = [{ - u"pk": f.id, - u"model": u"multigtfs.frequency", - u"fields": { - u"exact_times": u"", - u"extra_data": u"{}", - u"start_time": u"05:00:00", - u"headway_secs": 1800, - u"trip": self.trip.id, - u"end_time": u"25:00:00"}}] + "pk": f.id, + "model": "multigtfs.frequency", + "fields": { + "exact_times": "", + "extra_data": {}, + "start_time": "05:00:00", + "headway_secs": 1800, + "trip": self.trip.id, + "end_time": "25:00:00"}}] self.maxDiff = None self.assertEqual(expected, actual) From c0c89ca5264986cf4c1dcd8dc2e40d379cb7cfc6 Mon Sep 17 00:00:00 2001 From: Dalibor Pavlovic Date: Thu, 7 Apr 2022 15:59:33 +0200 Subject: [PATCH 7/7] Edit tests and setup for Django 3.2, Python 3.7 and above, Postgres 10 --- .travis.yml | 51 +++++++-------------------------------------- Dockerfile | 4 ++-- multigtfs/compat.py | 14 ++----------- requirements.txt | 3 +-- setup.py | 26 +++++------------------ tox.ini | 15 ++----------- 6 files changed, 20 insertions(+), 93 deletions(-) diff --git a/.travis.yml b/.travis.yml index b3fd0ba..76a4868 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,11 @@ language: python -dist: trusty +dist: bionic sudo: false addons: - postgresql: 9.5 + postgresql: "10" apt: packages: - - postgresql-9.5-postgis-2.3 + - postgresql-10-postgis-2.4 install: pip install tox coveralls script: tox -e $TOX_ENV after_success: coveralls @@ -16,46 +16,11 @@ before_script: - psql -U postgres -d multigtfs -c "CREATE EXTENSION IF NOT EXISTS postgis; CREATE EXTENSION IF NOT EXISTS postgis_topology;" matrix: include: - - env: TOX_ENV=py27-django18-postgis - python: "2.7" - - env: TOX_ENV=py34-django18-postgis - python: "3.4" - - env: TOX_ENV=py27-django19-postgis - python: "2.7" - - env: TOX_ENV=py35-django19-postgis - python: "3.5" - - env: TOX_ENV=py27-django110-postgis - python: "2.7" - - env: TOX_ENV=py35-django110-postgis - python: "3.5" - - env: TOX_ENV=py27-django111-postgis - python: "2.7" - - env: TOX_ENV=py36-django111-postgis - python: "3.6" - - env: TOX_ENV=py35-django20-postgis - python: "3.5" - - env: TOX_ENV=py36-django20-postgis - python: "3.6" - - env: TOX_ENV=py35-django21-postgis - python: "3.5" - - env: TOX_ENV=py36-django21-postgis - python: "3.6" - - env: TOX_ENV=py35-django22-postgis - python: "3.5" - - env: TOX_ENV=py37-django22-postgis + - env: TOX_ENV=py37-django-32-postgis python: "3.7" - sudo: required - dist: xenial - - env: TOX_ENV=py35-django-master-postgis - python: "3.5" - - env: TOX_ENV=py36-django-master-postgis - python: "3.6" - - env: TOX_ENV=py37-django-master-postgis - python: "3.7" - sudo: required - dist: xenial + - env: TOX_ENV=py38-django-32-postgis + python: "3.8" + - env: TOX_ENV=py39-django-32-postgis + python: "3.9" allow_failures: # Django master is allowed to fail - - env: TOX_ENV=py35-django-master-postgis - - env: TOX_ENV=py36-django-master-postgis - - env: TOX_ENV=py37-django-master-postgis diff --git a/Dockerfile b/Dockerfile index fbd50f5..fe3338c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,9 @@ -FROM python:3.6 +FROM python:3.7-buster ENV PYTHONUNBUFFERED 1 RUN apt-get update RUN apt-get install -y binutils libproj-dev gdal-bin postgresql-client -RUN pip install "django>=2.2" "psycopg2" +RUN pip install "django>=2.2,<4.0" "psycopg2" RUN mkdir /code RUN mkdir /feeds diff --git a/multigtfs/compat.py b/multigtfs/compat.py index d7858c8..878eb4f 100644 --- a/multigtfs/compat.py +++ b/multigtfs/compat.py @@ -4,6 +4,7 @@ """ from codecs import BOM_UTF8 from distutils.version import LooseVersion +from io import TextIOWrapper from zipfile import ZipFile, ZIP_DEFLATED from django import get_version @@ -75,7 +76,6 @@ def opener_from_zipfile(zipfile): def opener(filename): inner_file = zipfile.open(filename) - from io import TextIOWrapper return TextIOWrapper(inner_file) return opener @@ -97,16 +97,6 @@ def write_text_rows(writer, rows): writer.writerow(new_row) -# The GeoQuerySet is deprecated in Django 1.8 -# https://docs.djangoproject.com/en/dev/releases/1.9/#django-contrib-gis -# The GeoManager is deprecated in Django 1.9 -# https://docs.djangoproject.com/en/dev/releases/1.9/#geomanager-and-geoqueryset-custom-methods -# They are removed in Django 2.0 -# https://docs.djangoproject.com/en/dev/releases/2.0/#features-removed-in-2-0 -if DJ_VERSION >= LooseVersion('2.0'): - from django.db.models import Manager, QuerySet -else: - from django.contrib.gis.db.models import GeoManager as Manager - from django.contrib.gis.db.models.query import GeoQuerySet as QuerySet +from django.db.models import Manager, QuerySet assert Manager assert QuerySet diff --git a/requirements.txt b/requirements.txt index d0809db..807ac90 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1 @@ -Django>=2.2 -jsonfield==3.1.0 +Django>=3.2,<4.0 diff --git a/setup.py b/setup.py index 970196d..c813356 100755 --- a/setup.py +++ b/setup.py @@ -58,13 +58,7 @@ def get_long_description(): return long_description -# Handle Py2/Py3 issue -if sys.version_info > (3, 0): - # In Py3, package data is dict w/ text key - package_data = {'multigtfs': ['tests/fixtures/*.zip']} -else: - # In Py2, package data is dict w/ binary string - package_data = {b'multigtfs': ['tests/fixtures/*.zip']} +package_data = {'multigtfs': ['tests/fixtures/*.zip']} setup( @@ -77,7 +71,7 @@ def get_long_description(): license='Apache License 2.0', url='https://github.com/tulsawebdevs/django-multi-gtfs', packages=find_packages(), - install_requires=['Django>=2.2', 'jsonfield>=0.9.20'], + install_requires=['Django>=3.2,<4.0'], keywords=['django', 'gtfs'], test_suite="run_tests", # Ignored, but makes pyroma happy cmdclass={'test': my_test}, @@ -86,24 +80,14 @@ def get_long_description(): "Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Framework :: Django", - "Framework :: Django :: 1.8", - "Framework :: Django :: 1.9", - "Framework :: Django :: 1.10", - "Framework :: Django :: 1.11", - "Framework :: Django :: 2.0", - "Framework :: Django :: 2.1", - "Framework :: Django :: 2.2", + "Framework :: Django :: 3.2", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.4", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", "Topic :: Software Development :: Libraries :: Python Modules", ], include_package_data=True, diff --git a/tox.ini b/tox.ini index ec41456..e30cd69 100644 --- a/tox.ini +++ b/tox.ini @@ -1,10 +1,6 @@ [tox] envlist = - py{27,34}-django18-{postgis,spatiallite} - py{27,34,35}-django{19,110}-{postgis,spatiallite} - py{27,34,35,36}-django111-{postgis,spatiallite} - py{35,36}-django20-{postgis,spatiallite} - py{35,36,37}-django{21,22,-master}-{postgis,spatiallite} + py{37,38,39}-django{32,-master}-{postgis,spatiallite} [flake8] exclude = .tox/*,.build/*,.dist/*,build/* @@ -14,17 +10,10 @@ passenv = TRAVIS TRAVIS_JOB_ID TRAVIS_BRANCH setenv = postgis: MULTIGTFS_TEST_POSTGIS = 1 deps= - django18: Django>=1.8,<1.9 - django19: Django>=1.9,<1.10 - django110: Django>=1.10,<1.11 - django111: Django>=1.11,<2.0 - django20: Django>=2.0,<2.1 - django21: Django>=2.1,<2.2 - django22: Django>=2.2,<3.0 + django32: Django>=3.2,<4.0 django-master: https://github.com/django/django/archive/master.tar.gz postgis: psycopg2 nose django-nose - jsonfield coveralls commands=coverage run --source multigtfs ./run_tests.py