Skip to content

Commit

Permalink
ported to py3.4
Browse files Browse the repository at this point in the history
  • Loading branch information
laiyonghao committed Oct 24, 2015
1 parent fa2ce26 commit a85902b
Show file tree
Hide file tree
Showing 11 changed files with 68 additions and 39 deletions.
29 changes: 19 additions & 10 deletions README.rst
Expand Up @@ -36,23 +36,32 @@ Adding to the project settings::
# [...] Any other application
)

And adding the urlconf in your project urls.py::

# qbe
url(r'^qbe/', include('django_qbe.urls')),

Add the context processor ``django.core.context_processors.static``::

TEMPLATE_CONTEXT_PROCESSORS = (
# [...] django context processors
'django.core.context_processors.static',
# [...] Any other context processors
)
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
# [...] django context processors
'django.template.context_processors.static',
# [...] Any other context processors
],
},
},
]

See the `Django documentation on static files`__ for details.

__ staticfiles_

And adding the urlconf in your project urls.py::

# qbe
url(r'^qbe/', include('django_qbe.urls')),

That's all. Then you can access to http://host:port/qbe
However, you can add a link from your admin page changing the admin index
template fo your AdminSite::
Expand Down
8 changes: 6 additions & 2 deletions django_qbe/exports.py
@@ -1,7 +1,11 @@
from future import standard_library
standard_library.install_aliases()
from builtins import str
from builtins import object
# -*- coding: utf-8 -*-
import codecs
import csv
from StringIO import StringIO
from io import StringIO

from django.http import HttpResponse
from django.utils.datastructures import SortedDict
Expand Down Expand Up @@ -45,7 +49,7 @@ def __init__(self, f, dialect=csv.excel_tab, encoding="utf-8", **kwds):
self.encoder = codecs.getincrementalencoder(encoding)()

def writerow(self, row):
self.writer.writerow([unicode(s).encode("utf-8") for s in row])
self.writer.writerow([str(s).encode("utf-8") for s in row])
# Fetch UTF-8 output from the queue ...
data = self.queue.getvalue()
data = data.decode("utf-8")
Expand Down
8 changes: 5 additions & 3 deletions django_qbe/forms.py
@@ -1,4 +1,6 @@
# -*- coding: utf-8 -*-
from __future__ import print_function
from builtins import range
import collections
from django import forms
from django.db import connections
Expand Down Expand Up @@ -133,7 +135,7 @@ def clean(self):
params) = self.get_query_parts()
if not selects:
validation_message = _(u"At least you must check a row to get.")
raise forms.ValidationError, validation_message
raise forms.ValidationError(validation_message)
self._selects = selects
self._aliases = aliases
self._froms = froms
Expand Down Expand Up @@ -225,7 +227,7 @@ def get_query_parts(self):
wheres.append(u"%s %s"
% (lookup_cast(operator) % db_field,
db_operator))
elif operator in self._custom_operators.keys():
elif operator in list(self._custom_operators.keys()):
CustOperator = self._custom_operators[operator]
custom_operator = CustOperator(db_field, operator, over)

Expand Down Expand Up @@ -307,7 +309,7 @@ def get_results(self, limit=None, offset=None, query=None, admin_name=None,
else:
sql = query
if settings.DEBUG:
print sql
print(sql)
cursor = self._db_connection.cursor()
cursor.execute(sql, tuple(self._params))
query_results = cursor.fetchall()
Expand Down
5 changes: 3 additions & 2 deletions django_qbe/operators.py
@@ -1,7 +1,9 @@
from builtins import object
from django.conf import settings
from django.db import connections
from django.db.models.fields import Field
from django.utils.importlib import import_module
from future.utils import with_metaclass

DATABASES = settings.DATABASES

Expand Down Expand Up @@ -39,7 +41,7 @@ def get_operators(self):
return self.operators


class CustomOperator:
class CustomOperator(with_metaclass(OperatorMount, object)):
"""
Mount point for operators which refer to actions that can be performed.
Expand All @@ -52,7 +54,6 @@ class CustomOperator:
label The label that will be displayed in the criteria dropdown
======== ========================================================
"""
__metaclass__ = OperatorMount

def __init__(self, db_field, operator, value, db_alias="default"):
self.params = []
Expand Down
2 changes: 1 addition & 1 deletion django_qbe/savedqueries/management/commands/qbe_export.py
Expand Up @@ -11,7 +11,7 @@


class Command(BaseCommand):
available_formats = ", ".join(formats.keys())
available_formats = ", ".join(list(formats.keys()))
option_list = BaseCommand.option_list + (
make_option('--output',
dest='output',
Expand Down
3 changes: 2 additions & 1 deletion django_qbe/savedqueries/models.py
@@ -1,3 +1,4 @@
from builtins import object
import pickle
from django.db import models
from django.utils.translation import ugettext_lazy as _
Expand All @@ -21,7 +22,7 @@ class SavedQuery(models.Model):
editable=False)
date_updated = models.DateTimeField(_("date updated"), editable=False)

class Meta:
class Meta(object):
verbose_name = _("Saved query")
verbose_name_plural = _("Saved queries")

Expand Down
5 changes: 4 additions & 1 deletion django_qbe/templatetags/qbe_tags.py
@@ -1,4 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import division
from builtins import range
from past.utils import old_div
from django import template
from django.utils.safestring import mark_safe

Expand Down Expand Up @@ -29,7 +32,7 @@ def _get_range_markup(range_from, range_to):
if total_pages < rows_per_page or not rows_per_page:
pages = 1
else:
pages = (total_pages / rows_per_page)
pages = (old_div(total_pages, rows_per_page))
if total_pages % rows_per_page != 0:
pages += 1
output = []
Expand Down
2 changes: 1 addition & 1 deletion django_qbe/urls.py
Expand Up @@ -12,7 +12,7 @@
url(r'^bookmark/$', 'qbe_bookmark', name="qbe_bookmark"),
url(r'^proxy/$', 'qbe_proxy', name="qbe_proxy"),
url(r'^auto/$', 'qbe_autocomplete', name="qbe_autocomplete"),
url(r'^(?P<query_hash>(.*))/results\.(?P<format>(%s))$' % "|".join(formats.keys()), 'qbe_export', name="qbe_export"),
url(r'^(?P<query_hash>(.*))/results\.(?P<format>(%s))$' % "|".join(list(formats.keys())), 'qbe_export', name="qbe_export"),
url(r'^(?P<query_hash>(.*))/results/$', 'qbe_results', name="qbe_results"),
url(r'^(?P<query_hash>(.*))/$', 'qbe_form', name="qbe_form"),
)
38 changes: 23 additions & 15 deletions django_qbe/utils.py
@@ -1,11 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import print_function
from __future__ import division
from past.builtins import cmp
from builtins import zip
from builtins import filter
from builtins import range
from past.utils import old_div
import base64
import pickle
import random
from collections import deque
from copy import copy
from hashlib import md5
from json import dumps
from functools import reduce
try:
from itertools import combinations
except ImportError:
Expand All @@ -14,7 +22,7 @@ def combinations(items, n):
if n == 0:
yield []
else:
for i in xrange(len(items)):
for i in range(len(items)):
for cc in combinations(items[i + 1:], n - 1):
yield [items[i]] + cc

Expand Down Expand Up @@ -66,7 +74,7 @@ def qbe_models(admin_site=None, only_admin_models=False, json=False):
app_models_with_no_includes = get_models(include_auto_created=False,
include_deferred=False)
if admin_site:
admin_models = [m for m, a in admin_site._registry.items()]
admin_models = [m for m, a in list(admin_site._registry.items())]
else:
admin_models = []
if only_admin_models:
Expand Down Expand Up @@ -191,8 +199,8 @@ def add_relation(model, field, extras=""):
def qbe_graph(admin_site=None, directed=False):
models = qbe_models(admin_site)
graph = {}
for k, v in models.items():
for l, w in v.items():
for k, v in list(models.items()):
for l, w in list(v.items()):
key = "%s.%s" % (k, l)
if key not in graph:
graph[key] = []
Expand Down Expand Up @@ -266,11 +274,11 @@ def qbe_tree(graph, nodes, root=None):
def remove_leafs(tree, nodes):

def get_leafs(tree, nodes):
return [node for node, edges in tree.items()
return [node for node, edges in list(tree.items())
if len(edges) < 2 and node not in nodes]

def delete_edge_leafs(tree, leaf):
for node, edges in tree.items():
for node, edges in list(tree.items()):
for node_edge, neighbor, neighbor_edge in edges:
if leaf == neighbor:
edge = (node_edge, neighbor, neighbor_edge)
Expand All @@ -290,7 +298,7 @@ def delete_edge_leafs(tree, leaf):

def qbe_forest(graph, nodes):
forest = []
for node, edges in graph.items():
for node, edges in list(graph.items()):
tree, are_all = qbe_tree(graph, copy(nodes), root=node)
if are_all and tree not in forest:
forest.append(tree)
Expand Down Expand Up @@ -365,7 +373,7 @@ def _combine(items, val=None, paths=None, length=None):

def visited_path(x):
return x not in paths
path = filter(visited_path, path)
path = list(filter(visited_path, path))
paths.extend(path)
return paths

Expand All @@ -383,7 +391,7 @@ def combine(items, k=None):
if k is not None:
k = k % length
# Python division by default is integer division (~ floor(a/b))
indices = [(k % (lengths[i] * repeats[i])) / repeats[i]
indices = [old_div((k % (lengths[i] * repeats[i])), repeats[i])
for i in range(length_items)]
return [items[i][indices[i]] for i in range(length_items)]
else:
Expand All @@ -392,14 +400,14 @@ def combine(items, k=None):
row = []
for subset in item:
row.extend([subset] * repeats[i])
times = length / len(row)
times = old_div(length, len(row))
matrix.append(row * times)
# Transpose the matrix or return the columns instead rows
return zip(*matrix)
return list(zip(*matrix))


def graphs_join(graphs):
print "Combine % elements" % len(graphs)
print("Combine % elements" % len(graphs))
return []


Expand All @@ -423,15 +431,15 @@ def autocomplete_graph(admin_site, current_models, directed=False):
def pickle_encode(session_dict):
"Returns the given session dictionary pickled and encoded as a string."
pickled = pickle.dumps(session_dict, pickle.HIGHEST_PROTOCOL)
return base64.encodestring(pickled + get_query_hash(pickled))
return base64.encodestring(pickled + get_query_hash(pickled).encode())


# Adapted from django.contrib.sessions.backends.base
def pickle_decode(session_data):
# The '+' character is translated to ' ' in request
session_data = session_data.replace(" ", "+")
# The length of the encoded string should be a multiple of 4
while (((len(session_data) / 4.0) - (len(session_data) / 4)) != 0):
while (((old_div(len(session_data), 4.0)) - (old_div(len(session_data), 4))) != 0):
session_data += u"="
encoded_data = base64.decodestring(session_data)
pickled, tamper_check = encoded_data[:-32], encoded_data[-32:]
Expand All @@ -447,4 +455,4 @@ def pickle_decode(session_data):


def get_query_hash(data):
return md5(data + settings.SECRET_KEY).hexdigest()
return md5(data + str.encode(settings.SECRET_KEY)).hexdigest()
5 changes: 3 additions & 2 deletions django_qbe/widgets.py
@@ -1,3 +1,4 @@
from builtins import object
# -*- coding: utf-8 -*-
from django.forms.util import flatatt
from django.forms.widgets import MultiWidget, Select, TextInput, Widget
Expand Down Expand Up @@ -51,7 +52,7 @@ def render(self, name, value=None, attrs=None, prelabel=None):

class CriteriaInput(MultiWidget):

class Media:
class Media(object):
js = ('django_qbe/js/qbe.widgets.js', )

def __init__(self, *args, **kwargs):
Expand All @@ -62,7 +63,7 @@ def __init__(self, *args, **kwargs):

# inject custom operators
ALL_OPERATOR_CHOICES = OPERATOR_CHOICES
for operator_slug, operator in custom_operators.items():
for operator_slug, operator in list(custom_operators.items()):
ALL_OPERATOR_CHOICES += ((operator_slug, operator.label),)

widgets = [Select(choices=ALL_OPERATOR_CHOICES), TextInput()]
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Expand Up @@ -40,5 +40,5 @@ def find_version(*parts):
zip_safe=False,
packages=find_packages(),
include_package_data=True,
install_requires=['django-picklefield'],
install_requires=['future', 'six', 'django-picklefield'],
)

0 comments on commit a85902b

Please sign in to comment.