Fix the CLI in py3

This commit is contained in:
Eevee (Alex Munroe) 2015-10-05 16:29:21 -07:00
parent 17999c5b1a
commit 0ff24b4dc8
3 changed files with 22 additions and 13 deletions

View file

@ -3,9 +3,11 @@ from __future__ import print_function
import csv import csv
import fnmatch import fnmatch
import io
import os.path import os.path
import sys import sys
import six
import sqlalchemy.sql.util import sqlalchemy.sql.util
import sqlalchemy.types import sqlalchemy.types
@ -196,16 +198,20 @@ def load(session, tables=[], directory=None, drop_tables=False, verbose=False, s
try: try:
csvpath = "%s/%s.csv" % (directory, table_name) csvpath = "%s/%s.csv" % (directory, table_name)
csvfile = open(csvpath, 'rb') csvfile = open(csvpath, 'r')
except IOError: except IOError:
# File doesn't exist; don't load anything! # File doesn't exist; don't load anything!
print_done('missing?') print_done('missing?')
continue continue
csvsize = os.stat(csvpath).st_size # XXX This is wrong for files with multi-line fields, but Python 3
# doesn't allow .tell() on a file that's currently being iterated
# (because the result is completely bogus). Oh well.
csvsize = sum(1 for line in csvfile)
csvfile.seek(0)
reader = csv.reader(csvfile, lineterminator='\n') reader = csv.reader(csvfile, lineterminator='\n')
column_names = [unicode(column) for column in reader.next()] column_names = [six.text_type(column) for column in next(reader)]
if not safe and engine.dialect.name == 'postgresql': if not safe and engine.dialect.name == 'postgresql':
# Postgres' CSV dialect works with our data, if we mark the not-null # Postgres' CSV dialect works with our data, if we mark the not-null
@ -253,10 +259,12 @@ def load(session, tables=[], directory=None, drop_tables=False, verbose=False, s
session.commit() session.commit()
new_rows[:] = [] new_rows[:] = []
progress = "%d%%" % (100 * csvfile.tell() // csvsize) progress = "%d%%" % (100 * csvpos // csvsize)
print_status(progress) print_status(progress)
csvpos = 0
for csvs in reader: for csvs in reader:
csvpos += 1
row_data = {} row_data = {}
for column_name, value in zip(column_names, csvs): for column_name, value in zip(column_names, csvs):
@ -271,7 +279,7 @@ def load(session, tables=[], directory=None, drop_tables=False, verbose=False, s
value = False value = False
else: else:
value = True value = True
else: elif isinstance(value, bytes):
# Otherwise, unflatten from bytes # Otherwise, unflatten from bytes
value = value.decode('utf-8') value = value.decode('utf-8')
@ -394,7 +402,7 @@ def dump(session, tables=[], directory=None, verbose=False, langs=None):
else: else:
filename = '%s/%s.csv' % (directory, table_name) filename = '%s/%s.csv' % (directory, table_name)
writer = csv.writer(open(filename, 'wb'), lineterminator='\n') writer = csv.writer(io.open(filename, 'w', newline=''), lineterminator='\n')
columns = [col.name for col in table.columns] columns = [col.name for col in table.columns]
@ -434,7 +442,7 @@ def dump(session, tables=[], directory=None, verbose=False, langs=None):
elif val == False: elif val == False:
val = '0' val = '0'
else: else:
val = unicode(val).encode('utf-8') val = six.text_type(val).encode('utf-8')
csvs.append(val) csvs.append(val)

View file

@ -25,6 +25,7 @@ from __future__ import print_function
import binascii import binascii
import csv import csv
import io
import os import os
import re import re
from collections import defaultdict from collections import defaultdict
@ -257,11 +258,11 @@ class Translations(object):
def reader_for_class(self, cls, reader_class=csv.reader): def reader_for_class(self, cls, reader_class=csv.reader):
tablename = cls.__table__.name tablename = cls.__table__.name
csvpath = os.path.join(self.csv_directory, tablename + '.csv') csvpath = os.path.join(self.csv_directory, tablename + '.csv')
return reader_class(open(csvpath, 'rb'), lineterminator='\n') return reader_class(open(csvpath, 'r'), lineterminator='\n')
def writer_for_lang(self, lang): def writer_for_lang(self, lang):
csvpath = os.path.join(self.translation_directory, '%s.csv' % lang) csvpath = os.path.join(self.translation_directory, '%s.csv' % lang)
return csv.writer(open(csvpath, 'wb'), lineterminator='\n') return csv.writer(io.open(csvpath, 'w', newline=''), lineterminator='\n')
def yield_source_messages(self, language_id=None): def yield_source_messages(self, language_id=None):
"""Yield all messages from source CSV files """Yield all messages from source CSV files
@ -302,7 +303,7 @@ class Translations(object):
""" """
path = os.path.join(self.csv_directory, 'translations', '%s.csv' % lang) path = os.path.join(self.csv_directory, 'translations', '%s.csv' % lang)
try: try:
file = open(path, 'rb') file = open(path, 'r')
except IOError: except IOError:
return () return ()
return yield_translation_csv_messages(file) return yield_translation_csv_messages(file)
@ -353,11 +354,11 @@ class Translations(object):
count += 1 count += 1
if count > 1000: if count > 1000:
for translation_class, key_data in everything.items(): for translation_class, key_data in everything.items():
yield translation_class, key_data.values() yield translation_class, list(key_data.values())
count = 0 count = 0
everything.clear() everything.clear()
for translation_class, data_dict in everything.items(): for translation_class, data_dict in everything.items():
yield translation_class, data_dict.values() yield translation_class, list(data_dict.values())
def group_by_object(stream): def group_by_object(stream):
"""Group stream by object """Group stream by object

View file

@ -21,7 +21,7 @@ def main(*argv):
# XXX there must be a better way to get Unicode argv # XXX there must be a better way to get Unicode argv
# XXX this doesn't work on Windows durp # XXX this doesn't work on Windows durp
enc = sys.stdin.encoding or 'utf8' enc = sys.stdin.encoding or 'utf8'
args = [_.decode(enc) for _ in args] args = [_.decode(enc) if isinstance(_, bytes) else _ for _ in args]
# Find the command as a function in this file # Find the command as a function in this file
func = globals().get("command_%s" % command, None) func = globals().get("command_%s" % command, None)