From 6ef999a93c05695245d00543ae3bb05972816b2f Mon Sep 17 00:00:00 2001 From: Cesar Del Solar Date: Sat, 20 Jan 2018 00:31:41 -0500 Subject: [PATCH 1/4] 2to3 automigrate Lots of Python 3 changes --- .gitignore | 1 + .pylintrc | 7 + .vscode/settings.json | 7 + Dockerfile | 2 +- base_pkg.dockerfile | 4 +- circle.yml | 2 +- .../accounts/migrations/0001_initial.py | 2 +- ..._remove_aerolithprofile_wordwallsmedals.py | 2 +- djAerolith/accounts/models.py | 2 +- .../management/commands/dumpdata_chunks.py | 10 +- .../management/commands/fix_america_2016.py | 14 +- .../management/commands/get_toughie_info.py | 6 +- djAerolith/base/migrations/0001_initial.py | 2 +- .../migrations/0002_auto_20150914_2227.py | 2 +- .../migrations/0003_auto_20151001_0908.py | 2 +- .../migrations/0004_auto_20160112_0014.py | 2 +- .../migrations/0005_auto_20160112_2329.py | 2 +- .../migrations/0006_auto_20160112_2333.py | 2 +- .../base/migrations/0007_maintenance.py | 2 +- .../migrations/0008_savedlist_category.py | 2 +- .../migrations/0009_auto_20170824_0722.py | 2 +- djAerolith/base/models.py | 19 +-- djAerolith/base/tests/test_wordlist_api.py | 4 +- djAerolith/base/utils.py | 2 +- djAerolith/base/views.py | 6 +- djAerolith/djaerolith/__init__.py | 0 djAerolith/{ => djaerolith}/asgi.py | 2 +- djAerolith/{ => djaerolith}/routing.py | 2 +- djAerolith/{ => djaerolith}/settings.py | 15 +- djAerolith/{ => djaerolith}/urls.py | 3 +- djAerolith/{ => djaerolith}/wsgi.py | 2 +- .../flashcards/migrations/0001_initial.py | 2 +- .../migrations/0002_auto_20150914_1924.py | 2 +- djAerolith/flashcards/views.py | 2 +- djAerolith/lib/dates.py | 8 +- djAerolith/lib/tests/test_word_db.py | 8 +- djAerolith/lib/word_db_helper.py | 38 ++--- djAerolith/manage.py | 4 +- djAerolith/prod_requirements.txt | 4 +- djAerolith/registration_app/forms.py | 45 +----- .../tablegame/migrations/0001_initial.py | 2 +- .../migrations/0002_auto_20160113_0944.py | 2 +- djAerolith/tablegame/models.py | 2 +- djAerolith/test_requirements.txt | 3 +- djAerolith/whitleyCards/views.py | 2 +- djAerolith/wordwalls/api.py | 7 +- djAerolith/wordwalls/challenges.py | 10 +- djAerolith/wordwalls/game.py | 8 +- .../commands/awardChallengeMedals.py | 17 +- .../management/commands/cleanTablegame.py | 4 +- .../commands/clean_temp_word_lists.py | 2 +- .../commands/fix_saved_list_size_counts.py | 6 +- .../management/commands/genNamedLists.py | 6 +- .../commands/migrate_default_lexica.py | 2 +- .../wordwalls/migrations/0001_initial.py | 2 +- .../0002_wordwallsgamemodel_word_list.py | 2 +- .../migrations/0003_auto_20150919_1648.py | 2 +- .../migrations/0004_auto_20151016_1822.py | 2 +- .../migrations/0005_auto_20160112_0014.py | 2 +- .../migrations/0006_auto_20160112_2330.py | 2 +- .../migrations/0007_auto_20160113_0944.py | 2 +- .../migrations/0008_auto_20160126_2057.py | 2 +- .../0009_dailychallengename_num_questions.py | 2 +- .../migrations/0010_auto_20170301_0923.py | 2 +- ...hallengeleaderboardentry_additionaldata.py | 2 +- .../migrations/0012_auto_20170304_0055.py | 2 +- .../0013_dailychallenge_category.py | 2 +- djAerolith/wordwalls/models.py | 26 +-- djAerolith/wordwalls/rpc.py | 2 +- djAerolith/wordwalls/socket_consumers.py | 11 +- .../wordwalls/newtable/saved_list_dialog.jsx | 1 - .../wordwalls/templatetags/aerolith_markup.py | 6 +- djAerolith/wordwalls/templatetags/verbatim.py | 4 +- djAerolith/wordwalls/tests/mixins.py | 2 +- djAerolith/wordwalls/tests/test_basics.py | 6 +- .../wordwalls/tests/test_file_upload.py | 26 ++- djAerolith/wordwalls/tests/test_game_logic.py | 150 +++++++++--------- djAerolith/wordwalls/views.py | 23 ++- fabfile.py | 4 +- webolith.sublime-project | 1 + 80 files changed, 282 insertions(+), 324 deletions(-) create mode 100644 .pylintrc create mode 100644 .vscode/settings.json create mode 100644 djAerolith/djaerolith/__init__.py rename djAerolith/{ => djaerolith}/asgi.py (56%) rename djAerolith/{ => djaerolith}/routing.py (92%) rename djAerolith/{ => djaerolith}/settings.py (96%) rename djAerolith/{ => djaerolith}/urls.py (99%) rename djAerolith/{ => djaerolith}/wsgi.py (75%) diff --git a/.gitignore b/.gitignore index 127f5a15..8f44ecc9 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,4 @@ kubernetes/deploy-configs/prod-*.yaml djAerolith/htmlcov vars.sh coverage +__pycache__ \ No newline at end of file diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 00000000..a8265dac --- /dev/null +++ b/.pylintrc @@ -0,0 +1,7 @@ +[MASTER] +init-hook='base_dir="djAerolith"; import sys,os,re; _re=re.search(r".+\/" + base_dir, os.getcwd()); project_dir = _re.group() if _re else os.path.join(os.getcwd(), base_dir); sys.path.append(project_dir)' + +[MESSAGES CONTROL] +# Find available symbolic names in: +# https://docs.pylint.org/features.html +disable=missing-docstring \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..c2bd2f69 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "python.linting.flake8Enabled": false, + "python.pythonPath": "/Library/Frameworks/Python.framework/Versions/3.6/bin/python3", + "python.linting.pylintArgs": [ + "--load-plugins=pylint_django" + ], +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 3ce6f92b..4fcf2f1c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,4 +6,4 @@ WORKDIR /opt/webolith/djAerolith EXPOSE 8000 # Run command in exec form because /bin/sh does not pass signals to its children. -CMD ["daphne", "-b", "0.0.0.0", "asgi:channel_layer"] \ No newline at end of file +CMD ["daphne", "-b", "0.0.0.0", "djaerolith.asgi:channel_layer"] \ No newline at end of file diff --git a/base_pkg.dockerfile b/base_pkg.dockerfile index 77bcf3d3..ccc3c47c 100644 --- a/base_pkg.dockerfile +++ b/base_pkg.dockerfile @@ -1,6 +1,6 @@ # Base image that we can base the prod image on. -FROM python:2-alpine +FROM python:3-alpine MAINTAINER Cesar Del Solar ENV PYTHONUNBUFFERED 1 @@ -11,4 +11,4 @@ COPY djAerolith/prod_requirements.txt /opt/prod_requirements.txt RUN pip install --upgrade pip RUN pip install -r /opt/prod_requirements.txt -# Prod image can import this image, and build on top of it. \ No newline at end of file +# Prod image can import this image, and build on top of it. diff --git a/circle.yml b/circle.yml index b18fb769..36c57cb8 100644 --- a/circle.yml +++ b/circle.yml @@ -8,7 +8,7 @@ machine: - docker - redis python: - version: 2.7.12 + version: 3.6.2 environment: REPO: /home/ubuntu/$CIRCLE_PROJECT_REPONAME PGSQL_DB_NAME: circle_test diff --git a/djAerolith/accounts/migrations/0001_initial.py b/djAerolith/accounts/migrations/0001_initial.py index bb9b0c1a..7aedfccc 100644 --- a/djAerolith/accounts/migrations/0001_initial.py +++ b/djAerolith/accounts/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations import accounts.models diff --git a/djAerolith/accounts/migrations/0002_remove_aerolithprofile_wordwallsmedals.py b/djAerolith/accounts/migrations/0002_remove_aerolithprofile_wordwallsmedals.py index eb9aef08..215d2cd2 100644 --- a/djAerolith/accounts/migrations/0002_remove_aerolithprofile_wordwallsmedals.py +++ b/djAerolith/accounts/migrations/0002_remove_aerolithprofile_wordwallsmedals.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import migrations, models diff --git a/djAerolith/accounts/models.py b/djAerolith/accounts/models.py index 8c12ba1a..f6a94f1f 100644 --- a/djAerolith/accounts/models.py +++ b/djAerolith/accounts/models.py @@ -67,7 +67,7 @@ class AerolithProfile(models.Model): avatarUrl = models.CharField(null=True, blank=True, max_length=512) additional_data = models.TextField(default='{}', blank=True) - def __unicode__(self): + def __str__(self): return "Profile for " + self.user.username diff --git a/djAerolith/base/management/commands/dumpdata_chunks.py b/djAerolith/base/management/commands/dumpdata_chunks.py index 93998509..97a1c488 100644 --- a/djAerolith/base/management/commands/dumpdata_chunks.py +++ b/djAerolith/base/management/commands/dumpdata_chunks.py @@ -38,8 +38,8 @@ def handle(self, *app_labels, **options): from django.db.models import get_app, get_apps, get_model output_folder = options.get('output_folder') - print "Output folder:", output_folder - print "NOTE: See --output-folder option" + print("Output folder:", output_folder) + print("NOTE: See --output-folder option") max_records_per_chunk = options.get('max_records_per_chunk') format = options.get('format') indent = options.get('indent') @@ -92,7 +92,7 @@ def handle(self, *app_labels, **options): if model is None: raise CommandError("Unknown model: %s.%s" % (app_label, model_label)) - if app in app_list.keys(): + if app in list(app_list.keys()): if app_list[app] and model not in app_list[app]: app_list[app].append(model) else: @@ -124,7 +124,7 @@ def get_objects_into_chunks(max_records_per_chunk): # Collate the objects to be serialized. model_count = 0 - for model in sort_dependencies(app_list.items()): + for model in sort_dependencies(list(app_list.items())): model_count += 1 if model in excluded_models: @@ -148,7 +148,7 @@ def get_objects_into_chunks(max_records_per_chunk): chunk_count += 1 dump_file_name = output_folder + "/%04d_%04d.json" % (model_count, chunk_count) - print "Dumping file: %s [%d/%d] for %s" % (dump_file_name, chunk_count, chunks_total, model.__name__) + print("Dumping file: %s [%d/%d] for %s" % (dump_file_name, chunk_count, chunks_total, model.__name__)) output = serializers.serialize(format, output_objects, indent=indent, use_natural_keys=use_natural_keys) try: diff --git a/djAerolith/base/management/commands/fix_america_2016.py b/djAerolith/base/management/commands/fix_america_2016.py index 37083f7f..de89b216 100644 --- a/djAerolith/base/management/commands/fix_america_2016.py +++ b/djAerolith/base/management/commands/fix_america_2016.py @@ -71,11 +71,11 @@ def migrate_users_to_America(): defaultLexicon__lexiconName='America2016') ct = profiles.count() america = Lexicon.objects.get(lexiconName='America') - print 'Need to migrate {0} profiles'.format(ct) + print('Need to migrate {0} profiles'.format(ct)) for profile in profiles: profile.defaultLexicon = america profile.save() - print 'Migrated {0} profiles'.format(ct) + print('Migrated {0} profiles'.format(ct)) def migrate_lists_to_America(): @@ -83,19 +83,19 @@ def migrate_lists_to_America(): lists = WordList.objects.filter( lexicon__lexiconName='America2016' ) - print 'Need to migrate {0} lists'.format(lists.count()) - print 'Non-temp lists are' + print('Need to migrate {0} lists'.format(lists.count())) + print('Non-temp lists are') for wl in lists: if not wl.is_temporary: - print wl + print(wl) america = Lexicon.objects.get(lexiconName='America') for wl in lists: wl.lexicon = america try: wl.save() except IntegrityError: - print "Could not migrate list; name collision: {0}".format(wl) - print 'Migrated the lists!' + print("Could not migrate list; name collision: {0}".format(wl)) + print('Migrated the lists!') class Command(BaseCommand): diff --git a/djAerolith/base/management/commands/get_toughie_info.py b/djAerolith/base/management/commands/get_toughie_info.py index 89224cd3..88828290 100644 --- a/djAerolith/base/management/commands/get_toughie_info.py +++ b/djAerolith/base/management/commands/get_toughie_info.py @@ -68,14 +68,14 @@ def handle(self, *args, **options): america_bingos[row[0]] = [] america_bingos[row[0]].append(bingo) - print '%s uniq owl2_bingos, %s uniq america_bingos' % ( - len(owl2_bingos), len(america_bingos)) + print('%s uniq owl2_bingos, %s uniq america_bingos' % ( + len(owl2_bingos), len(america_bingos))) with open('/tmp/toughies.csv', 'wb') as csvfile: writer = csv.writer(csvfile) writer.writerow(['Alphagram', 'probability', 'difficulty']) self.toughiez(Americadb, america_bingos, difficulty_cutoff, probability_cutoff, writer) - print '----' + print('----') self.toughiez(OWL2db, owl2_bingos, difficulty_cutoff, probability_cutoff, writer) diff --git a/djAerolith/base/migrations/0001_initial.py b/djAerolith/base/migrations/0001_initial.py index 70b819c1..2c9cbb54 100644 --- a/djAerolith/base/migrations/0001_initial.py +++ b/djAerolith/base/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations from django.conf import settings diff --git a/djAerolith/base/migrations/0002_auto_20150914_2227.py b/djAerolith/base/migrations/0002_auto_20150914_2227.py index a39ac372..d4e17bca 100644 --- a/djAerolith/base/migrations/0002_auto_20150914_2227.py +++ b/djAerolith/base/migrations/0002_auto_20150914_2227.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/djAerolith/base/migrations/0003_auto_20151001_0908.py b/djAerolith/base/migrations/0003_auto_20151001_0908.py index 079a771e..1219ac22 100644 --- a/djAerolith/base/migrations/0003_auto_20151001_0908.py +++ b/djAerolith/base/migrations/0003_auto_20151001_0908.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/djAerolith/base/migrations/0004_auto_20160112_0014.py b/djAerolith/base/migrations/0004_auto_20160112_0014.py index 30a910bc..a174b438 100644 --- a/djAerolith/base/migrations/0004_auto_20160112_0014.py +++ b/djAerolith/base/migrations/0004_auto_20160112_0014.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations import base.validators diff --git a/djAerolith/base/migrations/0005_auto_20160112_2329.py b/djAerolith/base/migrations/0005_auto_20160112_2329.py index 94c7db28..daad3ccd 100644 --- a/djAerolith/base/migrations/0005_auto_20160112_2329.py +++ b/djAerolith/base/migrations/0005_auto_20160112_2329.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/djAerolith/base/migrations/0006_auto_20160112_2333.py b/djAerolith/base/migrations/0006_auto_20160112_2333.py index d3e18ec6..4c6f7828 100644 --- a/djAerolith/base/migrations/0006_auto_20160112_2333.py +++ b/djAerolith/base/migrations/0006_auto_20160112_2333.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/djAerolith/base/migrations/0007_maintenance.py b/djAerolith/base/migrations/0007_maintenance.py index 1f429d54..de1b702f 100644 --- a/djAerolith/base/migrations/0007_maintenance.py +++ b/djAerolith/base/migrations/0007_maintenance.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import migrations, models diff --git a/djAerolith/base/migrations/0008_savedlist_category.py b/djAerolith/base/migrations/0008_savedlist_category.py index 998277d1..bd039846 100644 --- a/djAerolith/base/migrations/0008_savedlist_category.py +++ b/djAerolith/base/migrations/0008_savedlist_category.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.1 on 2017-06-28 16:35 -from __future__ import unicode_literals + from django.db import migrations, models diff --git a/djAerolith/base/migrations/0009_auto_20170824_0722.py b/djAerolith/base/migrations/0009_auto_20170824_0722.py index 32eb01c6..f87d06e4 100644 --- a/djAerolith/base/migrations/0009_auto_20170824_0722.py +++ b/djAerolith/base/migrations/0009_auto_20170824_0722.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.1 on 2017-08-24 07:22 -from __future__ import unicode_literals + from django.conf import settings from django.db import migrations, models diff --git a/djAerolith/base/models.py b/djAerolith/base/models.py index 38e7a418..0bc30adb 100644 --- a/djAerolith/base/models.py +++ b/djAerolith/base/models.py @@ -1,5 +1,3 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- # Aerolith 2.0: A web-based word game website # Copyright (C) 2011 Cesar Del Solar # @@ -18,7 +16,6 @@ # To contact the author, please email delsolar at gmail dot com -import string import random import json import uuid @@ -40,7 +37,7 @@ # XXX: This handles both the Spanish and English case, but alphagrammize # will need to be reworked with lexicon-specific ordering if we add # non-latin letters. -SORT_STRING_ORDER = u'ABC1DEFGHIJKL2MNÑOPQR3STUVWXYZ?' +SORT_STRING_ORDER = 'ABC1DEFGHIJKL2MNÑOPQR3STUVWXYZ?' SORT_MAP = {} @@ -55,7 +52,7 @@ def alphagrammize(word): make_sort_map() l = list(word.upper()) l.sort(key=lambda y: SORT_MAP[y]) - return string.join(l, '') + return ''.join(l) class Maintenance(models.Model): @@ -70,7 +67,7 @@ class Lexicon(models.Model): # alphagrams per word length lengthCounts = models.CharField(max_length=256) - def __unicode__(self): + def __str__(self): return self.lexiconName @@ -144,7 +141,7 @@ def initialize_list(self, questions, lexicon, user, shuffle=False, self.goneThruOnce = False self.questionIndex = 0 self.origQuestions = json.dumps(questions) - self.curQuestions = json.dumps(range(num_questions)) + self.curQuestions = json.dumps(list(range(num_questions))) self.missed = json.dumps([]) self.firstMissed = json.dumps([]) self.version = 2 @@ -260,8 +257,8 @@ def to_python_reduced(self, last_saved_human=False): 'category': self.category, } - def __unicode__(self): - return u"(%s) %s%s (Saved %s)" % ( + def __str__(self): + return "(%s) %s%s (Saved %s)" % ( self.lexicon.lexiconName, self.name, '*' if self.goneThruOnce else '', @@ -295,8 +292,8 @@ class AlphagramTag(models.Model): alphagram = models.CharField(max_length=15) tag = models.CharField(choices=WORD_TAGS, max_length=2) - def __unicode__(self): - return u'%s\'s tag (%s - %s)' % (self.user, self.alphagram, self.tag) + def __str__(self): + return '%s\'s tag (%s - %s)' % (self.user, self.alphagram, self.tag) class Meta: unique_together = ('user', 'lexicon', 'alphagram') diff --git a/djAerolith/base/tests/test_wordlist_api.py b/djAerolith/base/tests/test_wordlist_api.py index 456bc00a..bf78b346 100644 --- a/djAerolith/base/tests/test_wordlist_api.py +++ b/djAerolith/base/tests/test_wordlist_api.py @@ -33,7 +33,7 @@ def test_lists_delete(self): resp = self.client.delete('/base/api/saved_lists/', data=json.dumps([2, 7217]), content_type='application/json') - self.assertEqual(resp.content, '"OK"') + self.assertEqual(resp.content, b'"OK"') resp = self.client.get('/base/api/saved_lists/') content = json.loads(resp.content) self.assertEqual(len(content['lists']), 4) @@ -45,7 +45,7 @@ def test_lists_delete_bad_id(self): resp = self.client.delete('/base/api/saved_lists/', data=json.dumps([2, 7218]), content_type='application/json') - self.assertEqual('"List id 7218 was not found."', resp.content) + self.assertEqual(b'"List id 7218 was not found."', resp.content) resp = self.client.get('/base/api/saved_lists/') content = json.loads(resp.content) # No changes were made. diff --git a/djAerolith/base/utils.py b/djAerolith/base/utils.py index 197a5e05..cd662467 100644 --- a/djAerolith/base/utils.py +++ b/djAerolith/base/utils.py @@ -12,7 +12,7 @@ class UserListParseException(Exception): pass -def get_alphas_from_words(contents, max_words): +def get_alphas_from_words(contents: str, max_words): """ Get all the alphagrams from the given words. Return a list of Alphagram objects. diff --git a/djAerolith/base/views.py b/djAerolith/base/views.py index 929bbd29..5f6b4cd9 100644 --- a/djAerolith/base/views.py +++ b/djAerolith/base/views.py @@ -195,7 +195,7 @@ def saved_list(request, id): # Again, reset will not actually save, so this is a GET. # Sync or PUT take care of saving. l_obj['questionIndex'] = 0 - l_obj['curQuestions'] = range(l_obj['numAlphagrams']) + l_obj['curQuestions'] = list(range(l_obj['numAlphagrams'])) l_obj['numCurAlphagrams'] = l_obj['numAlphagrams'] l_obj['firstMissed'] = [] l_obj['numFirstMissed'] = 0 @@ -211,10 +211,10 @@ def saved_list(request, id): def save_stars(request, stars, sl): origQuestions = json.loads(sl.origQuestions) - for qidx, star_obj in stars.iteritems(): + for qidx, star_obj in stars.items(): alph = origQuestions[int(qidx)]['q'] if star_obj['s'] == 0: - logger.debug(u'Creating user tag for %s: %s - %s (%s) ', + logger.debug('Creating user tag for %s: %s - %s (%s) ', request.user, alph, sl.lexicon, star_obj['t']) AlphagramTag.objects.update_or_create( user=request.user, lexicon=sl.lexicon, alphagram=alph, diff --git a/djAerolith/djaerolith/__init__.py b/djAerolith/djaerolith/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/djAerolith/asgi.py b/djAerolith/djaerolith/asgi.py similarity index 56% rename from djAerolith/asgi.py rename to djAerolith/djaerolith/asgi.py index 462e4804..16cf10e3 100644 --- a/djAerolith/asgi.py +++ b/djAerolith/djaerolith/asgi.py @@ -1,6 +1,6 @@ import os from channels.asgi import get_channel_layer -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings") +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djaerolith.settings") channel_layer = get_channel_layer() diff --git a/djAerolith/routing.py b/djAerolith/djaerolith/routing.py similarity index 92% rename from djAerolith/routing.py rename to djAerolith/djaerolith/routing.py index ddb9b2e0..df82944d 100644 --- a/djAerolith/routing.py +++ b/djAerolith/djaerolith/routing.py @@ -1,6 +1,6 @@ from channels.routing import include from wordwalls.routing import socket_routing -routing = [ +routes = [ include(socket_routing, path=r'^/wordwalls-socket'), ] diff --git a/djAerolith/settings.py b/djAerolith/djaerolith/settings.py similarity index 96% rename from djAerolith/settings.py rename to djAerolith/djaerolith/settings.py index b4174f01..304ae965 100644 --- a/djAerolith/settings.py +++ b/djAerolith/djaerolith/settings.py @@ -106,7 +106,7 @@ def tobool(val): # Make this unique, and don't share it with anybody. SECRET_KEY = os.environ.get('SECRET_KEY') -PROJECT_ROOT = os.path.realpath(os.path.dirname(__file__)) +PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) STATICFILES_DIRS = [os.path.join(PROJECT_ROOT, 'static')] STATICFILES_FINDERS = ( @@ -127,7 +127,7 @@ def tobool(val): #'debug_toolbar.middleware.DebugToolbarMiddleware', ) -ROOT_URLCONF = 'urls' +ROOT_URLCONF = 'djaerolith.urls' TEMPLATES = [ { @@ -180,6 +180,7 @@ def tobool(val): 'social_django', 'channels', 'channels_presence', + 'captcha', #'debug_toolbar', #'locking' # Uncomment the next line to enable admin documentation: @@ -254,7 +255,7 @@ def tobool(val): 'CONFIG': { 'hosts': [(os.environ.get('REDIS_HOST', 'redis'), 6379)], }, - 'ROUTING': 'routing.routing', + 'ROUTING': 'djaerolith.routing.routes', } } SEND_BROKEN_LINK_EMAILS = False @@ -333,12 +334,14 @@ def tobool(val): # LOGGING config NOCAPTCHA = tobool(os.environ.get('NOCAPTCHA', False)) -RECAPTCHA_PUBLIC_KEY = "6LctSMUSAAAAAAe-qMSIt5Y-iTw5hcFRsk2BPYl2" -RECAPTCHA_PRIVATE_KEY = os.environ.get('RECAPTCHA_PRIVATE_KEY') + +if os.environ.get('RECAPTCHA_PRIVATE_KEY'): + RECAPTCHA_PUBLIC_KEY = "6LctSMUSAAAAAAe-qMSIt5Y-iTw5hcFRsk2BPYl2" + RECAPTCHA_PRIVATE_KEY = os.environ.get('RECAPTCHA_PRIVATE_KEY') ALLOWED_HOSTS = ['.aerolith.org', '*'] -RECAPTCHA_SSL = os.environ.get('RECAPTCHA_SSL') +RECAPTCHA_USE_SSL = os.environ.get('RECAPTCHA_SSL') # See SessionIdleTimeout middleware SESSION_COOKIE_AGE = 60 * 60 * 24 * 30 diff --git a/djAerolith/urls.py b/djAerolith/djaerolith/urls.py similarity index 99% rename from djAerolith/urls.py rename to djAerolith/djaerolith/urls.py index 6f077481..e4ede555 100644 --- a/djAerolith/urls.py +++ b/djAerolith/djaerolith/urls.py @@ -25,9 +25,10 @@ #from registration.forms import RegistrationFormUniqueEmail from django.contrib.auth import views as auth_views from django.views.generic import TemplateView -from registration_app.forms import get_registration_form from registration.backends.simple.views import RegistrationView +from registration_app.forms import get_registration_form + from views import (health, login_error, new_social_user, js_error, test_500, healthz, trigger500, jwt_req) from accounts.views import social, username_change diff --git a/djAerolith/wsgi.py b/djAerolith/djaerolith/wsgi.py similarity index 75% rename from djAerolith/wsgi.py rename to djAerolith/djaerolith/wsgi.py index d71b3b73..5f77a0be 100644 --- a/djAerolith/wsgi.py +++ b/djAerolith/djaerolith/wsgi.py @@ -1,6 +1,6 @@ import os -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings") +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djaerolith.settings") # This application object is used by the development server # as well as any WSGI server configured to use this file. diff --git a/djAerolith/flashcards/migrations/0001_initial.py b/djAerolith/flashcards/migrations/0001_initial.py index 30bb4b6f..599feac0 100644 --- a/djAerolith/flashcards/migrations/0001_initial.py +++ b/djAerolith/flashcards/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations from django.conf import settings diff --git a/djAerolith/flashcards/migrations/0002_auto_20150914_1924.py b/djAerolith/flashcards/migrations/0002_auto_20150914_1924.py index c7525038..c3119224 100644 --- a/djAerolith/flashcards/migrations/0002_auto_20150914_1924.py +++ b/djAerolith/flashcards/migrations/0002_auto_20150914_1924.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/djAerolith/flashcards/views.py b/djAerolith/flashcards/views.py index 55d0e998..051b5934 100644 --- a/djAerolith/flashcards/views.py +++ b/djAerolith/flashcards/views.py @@ -75,7 +75,7 @@ def new_quiz(request): body = json.loads(request.body) params = validate_params(body['min'], body['max'], body['length'], body['lex']) - if isinstance(params, basestring): + if isinstance(params, str): return response(params, status=400) p_min, p_max, length, lexicon = params diff --git a/djAerolith/lib/dates.py b/djAerolith/lib/dates.py index 803ca2a0..1a66531e 100644 --- a/djAerolith/lib/dates.py +++ b/djAerolith/lib/dates.py @@ -20,19 +20,19 @@ def pretty_date(now, time): if second_diff < 10: return _("just now") if second_diff < 60: - return _("%(seconds)s seconds ago") % {'seconds': second_diff} + return _("%(seconds)d seconds ago") % {'seconds': second_diff} if second_diff < 120: return _("a minute ago") if second_diff < 3600: - return _("%(minutes)s minutes ago") % {'minutes': second_diff / 60} + return _("%(minutes)d minutes ago") % {'minutes': second_diff / 60} if second_diff < 7200: return _("an hour ago") if second_diff < 86400: - return _("%(hours)s hours ago") % {'hours': second_diff / 3600} + return _("%(hours)d hours ago") % {'hours': second_diff / 3600} if day_diff == 1: return _("Yesterday") if day_diff < 7: - return _("%(day_diff)s days ago") % {'day_diff': day_diff} + return _("%(day_diff)d days ago") % {'day_diff': day_diff} if day_diff < 31: return ungettext('%(week)d week ago', '%(week)d weeks ago', day_diff / 7) % {'week': day_diff / 7} diff --git a/djAerolith/lib/tests/test_word_db.py b/djAerolith/lib/tests/test_word_db.py index a4211d48..5987f7f5 100644 --- a/djAerolith/lib/tests/test_word_db.py +++ b/djAerolith/lib/tests/test_word_db.py @@ -1,5 +1,3 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- """ Test the word database util functions. @@ -68,11 +66,11 @@ def setUp(self): self.db = WordDB(lexicon_name='FISE09') def test_word_data(self): - word = self.db.get_word_data(u'ÑAME') - self.assertEqual(word.word, u'ÑAME') + word = self.db.get_word_data('ÑAME') + self.assertEqual(word.word, 'ÑAME') self.assertEqual(word.lexicon_symbols, '') self.assertEqual(word.front_hooks, '') self.assertEqual(word.back_hooks, 'S') self.assertEqual(word.inner_front_hook, True) self.assertEqual(word.inner_back_hook, False) - self.assertEqual(word.alphagram, u'AEMÑ') + self.assertEqual(word.alphagram, 'AEMÑ') diff --git a/djAerolith/lib/word_db_helper.py b/djAerolith/lib/word_db_helper.py index 3597bf39..7b04e2f2 100644 --- a/djAerolith/lib/word_db_helper.py +++ b/djAerolith/lib/word_db_helper.py @@ -47,10 +47,10 @@ def __init__(self, word, alphagram=None, definition=None, front_hooks=None, self.inner_back_hook = True if inner_back_hook == 1 else False def __repr__(self): - return stdout_encode(self.__unicode__()) + return stdout_encode(self.__str__()) - def __unicode__(self): - return u'{%s}' % self.word + def __str__(self): + return '{%s}' % self.word def __eq__(self, other): return self.word == other.word @@ -70,10 +70,10 @@ def __ne__(self, other): return not self.__eq__(other) def __repr__(self): - return stdout_encode(self.__unicode__()) + return stdout_encode(self.__str__()) - def __unicode__(self): - return u'{%s} (%s)' % (self.alphagram, self.probability) + def __str__(self): + return '{%s} (%s)' % (self.alphagram, self.probability) class Questions(object): @@ -139,10 +139,10 @@ def alphagram_string_list(self): return [a.alphagram.alphagram for a in self.questions] def __repr__(self): - return stdout_encode(self.__unicode__()) + return stdout_encode(self.__str__()) - def __unicode__(self): - return u'{}' % self.questions + def __str__(self): + return '{}' % self.questions class Question(object): @@ -188,10 +188,10 @@ def set_from_obj(self, obj): self.set_answers_from_word_list(obj['a']) def __repr__(self): - return stdout_encode(self.__unicode__()) + return stdout_encode(self.__str__()) - def __unicode__(self): - return u'' % (self.alphagram, + def __str__(self): + return '' % (self.alphagram, self.answers) @@ -379,7 +379,7 @@ def get_questions_from_alph_dicts(self, alph_objects): word_to_alphagram_dict[word] = this_q questions.append(this_q) # Populate all words fully with information from the database. - words_pop = self.get_words_data(word_to_alphagram_dict.keys()) + words_pop = self.get_words_data(list(word_to_alphagram_dict.keys())) # Then, modify the question for each word. for word in words_pop: @@ -445,10 +445,10 @@ def render(self): raise NotImplementedError def __repr__(self): - return u'<{}>'.format(self.__unicode__()) + return '<{}>'.format(self.__str__()) - def __unicode__(self): - return u'{}.{} {} {}'.format(self.table, self.column, + def __str__(self): + return '{}.{} {} {}'.format(self.table, self.column, self.condition, self.condition_params) @@ -525,10 +525,10 @@ def execution_context(self): return self.query_string, self.bind_params def __repr__(self): - return u'<{}>'.format(self.__unicode__()) + return '<{}>'.format(self.__str__()) - def __unicode__(self): - return u'query_string="{query}" bind_params={bind_params}'.format( + def __str__(self): + return 'query_string="{query}" bind_params={bind_params}'.format( query=self.query_string, bind_params=self.bind_params) diff --git a/djAerolith/manage.py b/djAerolith/manage.py index f08bb32f..bdad76fc 100755 --- a/djAerolith/manage.py +++ b/djAerolith/manage.py @@ -20,8 +20,8 @@ import os, sys if __name__ == "__main__": - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings") + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djaerolith.settings") from django.core.management import execute_from_command_line - execute_from_command_line(sys.argv) \ No newline at end of file + execute_from_command_line(sys.argv) diff --git a/djAerolith/prod_requirements.txt b/djAerolith/prod_requirements.txt index 30ba6685..e30be856 100644 --- a/djAerolith/prod_requirements.txt +++ b/djAerolith/prod_requirements.txt @@ -6,13 +6,11 @@ Markdown django-registration-redux gargoyle-yplan requests -recaptcha-client -wsgiref +django-recaptcha redis jsonschema social-auth-app-django requests-oauthlib -python-openid psycopg2 Fabric PyYAML diff --git a/djAerolith/registration_app/forms.py b/djAerolith/registration_app/forms.py index 59c2b0f7..1e7e980e 100644 --- a/djAerolith/registration_app/forms.py +++ b/djAerolith/registration_app/forms.py @@ -1,52 +1,17 @@ +from captcha.fields import ReCaptchaField + from django.contrib.auth.models import User from django.conf import settings from django import forms -from django.utils.encoding import smart_unicode +from django.utils.encoding import smart_text from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext from django.utils.safestring import mark_safe -from recaptcha.client import captcha from django.core.exceptions import ValidationError from registration.forms import RegistrationFormUniqueEmail -class ReCaptcha(forms.widgets.Widget): - recaptcha_challenge_name = 'recaptcha_challenge_field' - recaptcha_response_name = 'recaptcha_response_field' - - def render(self, name, value, attrs=None): - return mark_safe(u'%s' % captcha.displayhtml( - settings.RECAPTCHA_PUBLIC_KEY, use_ssl=settings.RECAPTCHA_SSL)) - - def value_from_datadict(self, data, files, name): - return [data.get(self.recaptcha_challenge_name, None), - data.get(self.recaptcha_response_name, None)] - - -class ReCaptchaField(forms.CharField): - default_error_messages = { - 'captcha_invalid': _(u'You seem to be a computer, please try again') - } - - def __init__(self, *args, **kwargs): - self.widget = ReCaptcha - self.required = True - super(ReCaptchaField, self).__init__(*args, **kwargs) - - def clean(self, values): - super(ReCaptchaField, self).clean(values[1]) - recaptcha_challenge_value = smart_unicode(values[0]) - recaptcha_response_value = smart_unicode(values[1]) - check_captcha = captcha.submit( - recaptcha_challenge_value, - recaptcha_response_value, settings.RECAPTCHA_PRIVATE_KEY, {}) - if not check_captcha.is_valid: - raise forms.utils.ValidationError( - self.error_messages['captcha_invalid']) - return values[0] - - class RecaptchaRegistrationForm(RegistrationFormUniqueEmail): recaptcha = ReCaptchaField(label="Please prove you're not a computer") @@ -59,6 +24,6 @@ def clean_username(self): def get_registration_form(debug): - if debug: - return RegistrationFormUniqueEmail + # if debug: + # return RegistrationFormUniqueEmail return RecaptchaRegistrationForm diff --git a/djAerolith/tablegame/migrations/0001_initial.py b/djAerolith/tablegame/migrations/0001_initial.py index 05736ac6..1a18ee3c 100644 --- a/djAerolith/tablegame/migrations/0001_initial.py +++ b/djAerolith/tablegame/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations from django.conf import settings diff --git a/djAerolith/tablegame/migrations/0002_auto_20160113_0944.py b/djAerolith/tablegame/migrations/0002_auto_20160113_0944.py index 89a55c02..ea774536 100644 --- a/djAerolith/tablegame/migrations/0002_auto_20160113_0944.py +++ b/djAerolith/tablegame/migrations/0002_auto_20160113_0944.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import migrations, models diff --git a/djAerolith/tablegame/models.py b/djAerolith/tablegame/models.py index 220c96c4..cd874f45 100644 --- a/djAerolith/tablegame/models.py +++ b/djAerolith/tablegame/models.py @@ -47,7 +47,7 @@ class GenericTableGameModel(models.Model): playerType = models.IntegerField(choices=PLAYER_TYPES) # table number will be a primary id - def __unicode__(self): + def __str__(self): return "Table game #%d - last activity: %s" % (self.pk, self.lastActivity) diff --git a/djAerolith/test_requirements.txt b/djAerolith/test_requirements.txt index ed9f9cc1..75b5c3c7 100644 --- a/djAerolith/test_requirements.txt +++ b/djAerolith/test_requirements.txt @@ -1 +1,2 @@ -coverage \ No newline at end of file +coverage +pylint \ No newline at end of file diff --git a/djAerolith/whitleyCards/views.py b/djAerolith/whitleyCards/views.py index 04f1e8d3..0cee4d3c 100644 --- a/djAerolith/whitleyCards/views.py +++ b/djAerolith/whitleyCards/views.py @@ -228,7 +228,7 @@ def getQuizChunkFromSavedList(slpk, minIndex, option): origQuestions = json.loads(sl.origQuestions) questions = [origQuestions[i] for i in questionIndices] data = getQuizChunkByQuestions(sl.lexicon, questions, minIndex) - print questions, data + print(questions, data) return data[0], data[1], data[2], sl.numFirstMissed diff --git a/djAerolith/wordwalls/api.py b/djAerolith/wordwalls/api.py index cb596289..8ed6f5c3 100644 --- a/djAerolith/wordwalls/api.py +++ b/djAerolith/wordwalls/api.py @@ -319,15 +319,16 @@ def default_lists(request): @require_GET def tables(request): rooms = Room.objects.exclude(channel_name=LOBBY_CHANNEL_NAME) - tables = [] + ret_tables = [] for room in rooms: try: - tables.append(WordwallsGameModel.objects.get(pk=room.channel_name)) + ret_tables.append( + WordwallsGameModel.objects.get(pk=room.channel_name)) except WordwallsGameModel.DoesNotExist: pass return response({ - 'tables': [table_info(table) for table in tables] + 'tables': [table_info(table) for table in ret_tables] }) diff --git a/djAerolith/wordwalls/challenges.py b/djAerolith/wordwalls/challenges.py index 53bdf549..4079ca91 100644 --- a/djAerolith/wordwalls/challenges.py +++ b/djAerolith/wordwalls/challenges.py @@ -49,7 +49,7 @@ def generate_dc_questions(challenge_name, lex, challenge_date): min_p = 1 # lengthCounts is a dictionary of strings as keys max_p = json.loads(lex.lengthCounts)[str(word_length)] - r = range(min_p, max_p + 1) + r = list(range(min_p, max_p + 1)) random.shuffle(r) # Just the first 50 elements for the daily challenge. return (db.get_questions_for_probability_list(r[:50], word_length), @@ -69,7 +69,7 @@ def generate_dc_questions(challenge_name, lex, challenge_date): for lgt in (7, 8): min_p = 1 max_p = json.loads(lex.lengthCounts)[str(lgt)] - r = range(min_p, max_p + 1) + r = list(range(min_p, max_p + 1)) random.shuffle(r) questions.extend( db.get_questions_for_probability_list(r[:50], lgt)) @@ -115,7 +115,7 @@ def generate_blank_bingos_challenge(lex): try: challs = gen_blank_challenges(length, lex.lexiconName, 2, 25, 5) except MacondoError: - logger.exception(u'[event=macondoerror]') + logger.exception('[event=macondoerror]') return bingos for chall in challs: question = Question(Alphagram(chall['q']), []) @@ -156,7 +156,7 @@ def generate_word_builder_challenge(lex, lmin, lmax): question, num_answers = gen_build_challenge( lmin, lmax, lex.lexiconName, require_word, min_sols, max_sols) except MacondoError: - logger.exception(u'[event=macondoerror]') + logger.exception('[event=macondoerror]') return q_struct ret_question = Question(Alphagram(question['q']), []) ret_question.set_answers_from_word_list(question['a']) @@ -211,7 +211,7 @@ def gen_toughies_by_challenge(challenge_name, num, min_date, max_date, lex): mb_dict[alphagram] = alphagram, perc_correct logger.debug('Created missed bingo dictionary...') # Sort by difficulty in reverse order (most difficult first) - alphs = sorted(mb_dict.items(), key=lambda x: x[1][1], reverse=True)[:num] + alphs = sorted(list(mb_dict.items()), key=lambda x: x[1][1], reverse=True)[:num] logger.debug('Sorted by difficulty, returning...') # And just return the alphagram portion. return [Alphagram(a[0]) for a in alphs] diff --git a/djAerolith/wordwalls/game.py b/djAerolith/wordwalls/game.py index 9a3ac1e4..0244ec83 100644 --- a/djAerolith/wordwalls/game.py +++ b/djAerolith/wordwalls/game.py @@ -71,7 +71,7 @@ def maybe_modify_list_name(self, list_name, user): user=user, is_temporary=False).filter(name=list_name) repeat = 1 while user_lists.count() > 0: - list_name = u'{0} ({1})'.format(orig_list_name, repeat) + list_name = '{0} ({1})'.format(orig_list_name, repeat) user_lists = WordList.objects.filter( user=user, is_temporary=False).filter(name=list_name) repeat += 1 @@ -586,7 +586,7 @@ def get_add_params(self, tablenum): def give_up_and_save(self, user, tablenum, listname): logger.debug( - u'table %s - User %s called give_up_and_save with params: %s', + 'table %s - User %s called give_up_and_save with params: %s', tablenum, user, listname) if self.give_up(user, tablenum) is True: return self.save(user, tablenum, listname) @@ -615,7 +615,7 @@ def validate_can_save(self, tablenum, listname, wgm, state): 'been deleted. Please load or create a new list.') def save(self, user, tablenum, listname): - logger.info(u'user=%s, tablenum=%s, listname=%s, event=save', + logger.info('user=%s, tablenum=%s, listname=%s, event=save', user, tablenum, listname) wgm = self.get_wgm(tablenum) if not wgm: @@ -642,7 +642,7 @@ def save_word_list_result(self, word_list, listname, state, wgm, user, # Maybe we want a way to "save as" another list; think about # a list copy. word_list.name = listname - logger.info(u'Saving word_list, name is %s (%s)', word_list.name, + logger.info('Saving word_list, name is %s (%s)', word_list.name, type(word_list.name)) if make_permanent_list: word_list.is_temporary = False diff --git a/djAerolith/wordwalls/management/commands/awardChallengeMedals.py b/djAerolith/wordwalls/management/commands/awardChallengeMedals.py index 6e95d2a0..65ebc56b 100644 --- a/djAerolith/wordwalls/management/commands/awardChallengeMedals.py +++ b/djAerolith/wordwalls/management/commands/awardChallengeMedals.py @@ -1,5 +1,6 @@ # Awards challenge medals. import logging +from operator import itemgetter from django.core.management.base import BaseCommand from django.utils import timezone @@ -37,7 +38,7 @@ def award_medals(self, leaderboard, dryrun): logger.debug('Dry run, not saving leaderboard.') return # Do not award medals; too few players. - lbes = sorted(lbes, cmp=sort_cmp) + lbes = sorted(lbes, key=itemgetter('score', 'tr'), reverse=True) if leaderboard.challenge.name == self.toughies: # Award extra medal. medals = [Medal.TYPE_PLATINUM, Medal.TYPE_GOLD, Medal.TYPE_SILVER, @@ -76,22 +77,12 @@ def handle(self, *args, **options): for lb in lbs: award = True if lb.challenge.name == self.toughies: - chDate = toughies_challenge_date(today) + ch_date = toughies_challenge_date(today) # Toughies challenge still ongoing - if chDate == lb.challenge.date: + if ch_date == lb.challenge.date: award = False logger.debug('%s: Toughies still ongoing, do not award.', lb) if not award: continue self.award_medals(lb, options['dry-run']) - - -def sort_cmp(e1, e2): - if e1.score == e2.score: - return int(e2.timeRemaining - e1.timeRemaining) - else: - return int(e2.score - e1.score) - # Otherwise, randomly award to someone if time and score are the same. - # It's not necessarily alphabetical, but based on the vagaries of the - # hash function :P diff --git a/djAerolith/wordwalls/management/commands/cleanTablegame.py b/djAerolith/wordwalls/management/commands/cleanTablegame.py index 4dda01b9..bda71686 100644 --- a/djAerolith/wordwalls/management/commands/cleanTablegame.py +++ b/djAerolith/wordwalls/management/commands/cleanTablegame.py @@ -25,8 +25,8 @@ def handle(self, *args, **options): delDate = timezone.now() - timedelta(days=days) wgms = WordwallsGameModel.objects.filter(lastActivity__lt=delDate) numObjs = len(wgms) - print "Found", numObjs, "objects to delete" + print("Found", numObjs, "objects to delete") if numObjs > 0: for wgm in wgms.iterator(): - print "Delete", wgm + print("Delete", wgm) wgm.delete() diff --git a/djAerolith/wordwalls/management/commands/clean_temp_word_lists.py b/djAerolith/wordwalls/management/commands/clean_temp_word_lists.py index 3455860b..d3eec77b 100644 --- a/djAerolith/wordwalls/management/commands/clean_temp_word_lists.py +++ b/djAerolith/wordwalls/management/commands/clean_temp_word_lists.py @@ -18,5 +18,5 @@ def handle(self, *args, **options): wls = WordList.objects.filter(lastSaved__lt=del_date, is_temporary=True) num_objs = len(wls) - print "Found", num_objs, "objects to delete" + print("Found", num_objs, "objects to delete") wls.delete() diff --git a/djAerolith/wordwalls/management/commands/fix_saved_list_size_counts.py b/djAerolith/wordwalls/management/commands/fix_saved_list_size_counts.py index 590787e2..1251c620 100644 --- a/djAerolith/wordwalls/management/commands/fix_saved_list_size_counts.py +++ b/djAerolith/wordwalls/management/commands/fix_saved_list_size_counts.py @@ -9,7 +9,7 @@ class Command(BaseCommand): def handle(self, *args, **options): profiles = AerolithProfile.objects.all() - print('Processing %s profiles' % profiles.count()) + print(('Processing %s profiles' % profiles.count())) for profile in profiles: word_lists = WordList.objects.filter(user=profile.user, is_temporary=False) @@ -21,7 +21,7 @@ def handle(self, *args, **options): print('This should not be') if ct != profile.wordwallsSaveListSize: - print('Mismatch for user %s, expected %s, got %s' % - (profile.user, ct, profile.wordwallsSaveListSize)) + print(('Mismatch for user %s, expected %s, got %s' % + (profile.user, ct, profile.wordwallsSaveListSize))) profile.wordwallsSaveListSize = ct profile.save() diff --git a/djAerolith/wordwalls/management/commands/genNamedLists.py b/djAerolith/wordwalls/management/commands/genNamedLists.py index 157161e8..97affd7a 100644 --- a/djAerolith/wordwalls/management/commands/genNamedLists.py +++ b/djAerolith/wordwalls/management/commands/genNamedLists.py @@ -1,5 +1,3 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- """Generate the "named" default Aerolith lists.""" import json @@ -265,9 +263,9 @@ def create_spanish_lists(): qs = get_questions_by_condition( db, min_prob, max_prob, i, - lambda a: re.search(ur'[123Ñ]', a)) + lambda a: re.search(r'[123Ñ]', a)) create_named_list(lex, len(qs), i, False, json.dumps(qs), - u'(ᴄʜ)(ʟʟ)(ʀʀ)Ñ ' + mapa_amigable[i]) + '(ᴄʜ)(ʟʟ)(ʀʀ)Ñ ' + mapa_amigable[i]) if i == 7: # 4+ vowel 7s diff --git a/djAerolith/wordwalls/management/commands/migrate_default_lexica.py b/djAerolith/wordwalls/management/commands/migrate_default_lexica.py index f7a33e92..d98605ef 100644 --- a/djAerolith/wordwalls/management/commands/migrate_default_lexica.py +++ b/djAerolith/wordwalls/management/commands/migrate_default_lexica.py @@ -25,4 +25,4 @@ def handle(self, *args, **options): profile.save() count += 1 - print 'Migrated %s profiles from %s to %s' % (count, lex1, lex2) + print('Migrated %s profiles from %s to %s' % (count, lex1, lex2)) diff --git a/djAerolith/wordwalls/migrations/0001_initial.py b/djAerolith/wordwalls/migrations/0001_initial.py index 94c664a7..7b93fe79 100644 --- a/djAerolith/wordwalls/migrations/0001_initial.py +++ b/djAerolith/wordwalls/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations from django.conf import settings diff --git a/djAerolith/wordwalls/migrations/0002_wordwallsgamemodel_word_list.py b/djAerolith/wordwalls/migrations/0002_wordwallsgamemodel_word_list.py index 0dde9be3..91337e46 100644 --- a/djAerolith/wordwalls/migrations/0002_wordwallsgamemodel_word_list.py +++ b/djAerolith/wordwalls/migrations/0002_wordwallsgamemodel_word_list.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/djAerolith/wordwalls/migrations/0003_auto_20150919_1648.py b/djAerolith/wordwalls/migrations/0003_auto_20150919_1648.py index 2ec81a03..d414c33d 100644 --- a/djAerolith/wordwalls/migrations/0003_auto_20150919_1648.py +++ b/djAerolith/wordwalls/migrations/0003_auto_20150919_1648.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/djAerolith/wordwalls/migrations/0004_auto_20151016_1822.py b/djAerolith/wordwalls/migrations/0004_auto_20151016_1822.py index c06b0dc1..e3ec8053 100644 --- a/djAerolith/wordwalls/migrations/0004_auto_20151016_1822.py +++ b/djAerolith/wordwalls/migrations/0004_auto_20151016_1822.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/djAerolith/wordwalls/migrations/0005_auto_20160112_0014.py b/djAerolith/wordwalls/migrations/0005_auto_20160112_0014.py index 1d286dcf..f38d06d5 100644 --- a/djAerolith/wordwalls/migrations/0005_auto_20160112_0014.py +++ b/djAerolith/wordwalls/migrations/0005_auto_20160112_0014.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations import base.validators diff --git a/djAerolith/wordwalls/migrations/0006_auto_20160112_2330.py b/djAerolith/wordwalls/migrations/0006_auto_20160112_2330.py index 7314d82f..abb922d1 100644 --- a/djAerolith/wordwalls/migrations/0006_auto_20160112_2330.py +++ b/djAerolith/wordwalls/migrations/0006_auto_20160112_2330.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/djAerolith/wordwalls/migrations/0007_auto_20160113_0944.py b/djAerolith/wordwalls/migrations/0007_auto_20160113_0944.py index d5b3700d..dffc6422 100644 --- a/djAerolith/wordwalls/migrations/0007_auto_20160113_0944.py +++ b/djAerolith/wordwalls/migrations/0007_auto_20160113_0944.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import migrations, models diff --git a/djAerolith/wordwalls/migrations/0008_auto_20160126_2057.py b/djAerolith/wordwalls/migrations/0008_auto_20160126_2057.py index 80eed109..6f85af3d 100644 --- a/djAerolith/wordwalls/migrations/0008_auto_20160126_2057.py +++ b/djAerolith/wordwalls/migrations/0008_auto_20160126_2057.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import migrations, models diff --git a/djAerolith/wordwalls/migrations/0009_dailychallengename_num_questions.py b/djAerolith/wordwalls/migrations/0009_dailychallengename_num_questions.py index aee05f4b..0391a7b1 100644 --- a/djAerolith/wordwalls/migrations/0009_dailychallengename_num_questions.py +++ b/djAerolith/wordwalls/migrations/0009_dailychallengename_num_questions.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import migrations, models diff --git a/djAerolith/wordwalls/migrations/0010_auto_20170301_0923.py b/djAerolith/wordwalls/migrations/0010_auto_20170301_0923.py index 92adcece..c9ef6cf3 100644 --- a/djAerolith/wordwalls/migrations/0010_auto_20170301_0923.py +++ b/djAerolith/wordwalls/migrations/0010_auto_20170301_0923.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import migrations, models from django.conf import settings diff --git a/djAerolith/wordwalls/migrations/0011_remove_dailychallengeleaderboardentry_additionaldata.py b/djAerolith/wordwalls/migrations/0011_remove_dailychallengeleaderboardentry_additionaldata.py index 6d08816e..2144cadb 100644 --- a/djAerolith/wordwalls/migrations/0011_remove_dailychallengeleaderboardentry_additionaldata.py +++ b/djAerolith/wordwalls/migrations/0011_remove_dailychallengeleaderboardentry_additionaldata.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import migrations, models diff --git a/djAerolith/wordwalls/migrations/0012_auto_20170304_0055.py b/djAerolith/wordwalls/migrations/0012_auto_20170304_0055.py index 5abcb009..8b9cd3cc 100644 --- a/djAerolith/wordwalls/migrations/0012_auto_20170304_0055.py +++ b/djAerolith/wordwalls/migrations/0012_auto_20170304_0055.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import migrations, models import django.db.models.deletion diff --git a/djAerolith/wordwalls/migrations/0013_dailychallenge_category.py b/djAerolith/wordwalls/migrations/0013_dailychallenge_category.py index 148980e2..67113ce5 100644 --- a/djAerolith/wordwalls/migrations/0013_dailychallenge_category.py +++ b/djAerolith/wordwalls/migrations/0013_dailychallenge_category.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.1 on 2017-06-28 16:35 -from __future__ import unicode_literals + from django.db import migrations, models diff --git a/djAerolith/wordwalls/models.py b/djAerolith/wordwalls/models.py index b6b86a3a..3be64e7f 100644 --- a/djAerolith/wordwalls/models.py +++ b/djAerolith/wordwalls/models.py @@ -23,7 +23,7 @@ from base.models import Lexicon, WordList from base.validators import named_list_format_validator from tablegame.models import GenericTableGameModel -from channels_presence.models import Room + logger = logging.getLogger(__name__) @@ -41,7 +41,7 @@ class DailyChallengeName(models.Model): orderPriority = models.IntegerField(default=1) num_questions = models.IntegerField(default=50) - def __unicode__(self): + def __str__(self): return self.name class Meta: @@ -71,7 +71,7 @@ class DailyChallenge(models.Model): category = models.CharField(choices=CHALLENGE_CATEGORIES, max_length=2, default=CATEGORY_ANAGRAM) - def __unicode__(self): + def __str__(self): return "%s %s (%s)" % (self.date, self.name.name, self.lexicon.lexiconName) @@ -86,8 +86,8 @@ class DailyChallengeLeaderboard(models.Model): maxScore = models.IntegerField() medalsAwarded = models.BooleanField(default=False) - def __unicode__(self): - return "Leaderboard: " + self.challenge.__unicode__() + def __str__(self): + return "Leaderboard: " + self.challenge.__str__() class DailyChallengeLeaderboardEntry(models.Model): @@ -98,9 +98,9 @@ class DailyChallengeLeaderboardEntry(models.Model): # only qualify for award if entry is in allowable range qualifyForAward = models.BooleanField(default=True) - def __unicode__(self): - return "%s --- %s %d (%d s.)" % ( - self.board.challenge.__unicode__(), self.user.username, + def __str__(self): + return '{0} --- {1} {2} ({3} s.)'.format( + self.board.challenge.__str__(), self.user.username, self.score, self.timeRemaining) class Meta: @@ -133,9 +133,9 @@ class Meta: verbose_name = 'Daily Challenge Missed Bingo' verbose_name_plural = 'Daily Challenge Missed Bingos' - def __unicode__(self): + def __str__(self): return "%s, %s, %d" % ( - self.challenge.__unicode__(), + self.challenge.__str__(), self.alphagram_string, self.numTimesMissed) @@ -171,9 +171,9 @@ class Medal(models.Model): leaderboard = models.ForeignKey(DailyChallengeLeaderboard) medal_type = models.CharField(choices=MEDAL_TYPES, max_length=2) - def __unicode__(self): - return u'%s: %s (%s)'.format(self.user, self.medal_type, - self.leaderboard) + def __str__(self): + return '{0}: {1} ({2})'.format(self.user, self.medal_type, + self.leaderboard) class Meta: unique_together = ('user', 'leaderboard') diff --git a/djAerolith/wordwalls/rpc.py b/djAerolith/wordwalls/rpc.py index ed532810..146368bb 100644 --- a/djAerolith/wordwalls/rpc.py +++ b/djAerolith/wordwalls/rpc.py @@ -79,7 +79,7 @@ def table_rpc(request, tableid): try: ret = handler(request.user, tableid, params) except RPCError as e: - return bad_rpc_response(req_id, unicode(e)) + return bad_rpc_response(req_id, str(e)) return rpc_response(req_id, ret) diff --git a/djAerolith/wordwalls/socket_consumers.py b/djAerolith/wordwalls/socket_consumers.py index 855a79ca..7cdaef13 100644 --- a/djAerolith/wordwalls/socket_consumers.py +++ b/djAerolith/wordwalls/socket_consumers.py @@ -74,13 +74,14 @@ def users_in(room): def table_info(table): state = json.loads(table.currentGameState) + word_list_name = state['temp_list_name'] + if table.word_list and not table.word_list.is_temporary: + word_list_name = table.word_list.name table_obj = { 'lexicon': table.lexicon.lexiconName, 'host': table.host.username, 'users': [user.username for user in table.inTable.all()], - 'wordList': ( - table.word_list.name if not table.word_list.is_temporary - else state['temp_list_name']), + 'wordList': word_list_name, 'tablenum': table.pk, 'secondsPerRound': state['timerSecs'], 'questionsPerRound': state['questionsToPull'], @@ -248,7 +249,7 @@ def table_join(message, contents): # Also, send the user the current time left / game state if the game # is already going. state = wwg.midgame_state(tableid) - if not state['going'] or not wwg.is_multiplayer(): + if not state['going'] or not wwg.is_multiplayer(tableid): return message.reply_channel.send({ 'text': json.dumps({ @@ -280,7 +281,7 @@ def end_packet(message, contents): state = json.loads(wgm.currentGameState) answers = state['answerHash'] if set(wrong_words) != set(answers.keys()): - logger.warning(u'[event=non-matching-fe] answers=%s wrong_words=%s ' + logger.warning('[event=non-matching-fe] answers=%s wrong_words=%s ' 'app_version=%s user=%s room=%s', answers, wrong_words, contents['contents']['appVersion'], message.user, room) diff --git a/djAerolith/wordwalls/static/js/wordwalls/newtable/saved_list_dialog.jsx b/djAerolith/wordwalls/static/js/wordwalls/newtable/saved_list_dialog.jsx index b03752a7..3f0ff1dc 100644 --- a/djAerolith/wordwalls/static/js/wordwalls/newtable/saved_list_dialog.jsx +++ b/djAerolith/wordwalls/static/js/wordwalls/newtable/saved_list_dialog.jsx @@ -155,7 +155,6 @@ class SavedListDialog extends React.Component { onDrop={this.onDrop} multiple={false} maxSize={1000000} - accept="text/plain" style={{ display: 'none' }} />