Ran 2to3 on pillar + some manual fixups
The 'manual fixups' are: - incorrect use of dict.items() where dict.iteritems() was meant; this results in list(dict.items()), which I changed to dict.items(). - removal of 'from __future__ import' lines, which 2to3 changes into empty lines; I removed the empty lines.
This commit is contained in:
parent
10b3318419
commit
663627358f
@ -360,12 +360,12 @@ class PillarServer(Eve):
|
||||
if node_type:
|
||||
node_type = node_type.replace('_', ' ').title()
|
||||
if doc_name:
|
||||
description = u'%s "%s" was deleted.' % (node_type, doc_name)
|
||||
description = '%s "%s" was deleted.' % (node_type, doc_name)
|
||||
else:
|
||||
description = u'This %s was deleted.' % (node_type, )
|
||||
description = 'This %s was deleted.' % (node_type, )
|
||||
else:
|
||||
if doc_name:
|
||||
description = u'"%s" was deleted.' % doc_name
|
||||
description = '"%s" was deleted.' % doc_name
|
||||
else:
|
||||
description = None
|
||||
|
||||
@ -441,7 +441,7 @@ class PillarServer(Eve):
|
||||
web.setup_app(self)
|
||||
authentication.setup_app(self)
|
||||
|
||||
for ext in self.pillar_extensions.itervalues():
|
||||
for ext in self.pillar_extensions.values():
|
||||
self.log.info('Setting up extension %s', ext.name)
|
||||
ext.setup_app(self)
|
||||
|
||||
|
@ -18,7 +18,7 @@ log = logging.getLogger(__name__)
|
||||
HOME_PROJECT_USERS = set()
|
||||
|
||||
# Users with any of these roles will get full write access to their home project.
|
||||
HOME_PROJECT_WRITABLE_USERS = {u'subscriber', u'demo'}
|
||||
HOME_PROJECT_WRITABLE_USERS = {'subscriber', 'demo'}
|
||||
|
||||
HOME_PROJECT_DESCRIPTION = ('# Your home project\n\n'
|
||||
'This is your home project. It allows synchronisation '
|
||||
@ -30,7 +30,7 @@ HOME_PROJECT_SUMMARY = 'This is your home project. Here you can sync your Blende
|
||||
# 'as a pastebin for text, images and other assets, and '
|
||||
# 'allows synchronisation of your Blender settings.')
|
||||
# HOME_PROJECT_SUMMARY = 'This is your home project. Pastebin and Blender settings sync in one!'
|
||||
SYNC_GROUP_NODE_NAME = u'Blender Sync'
|
||||
SYNC_GROUP_NODE_NAME = 'Blender Sync'
|
||||
SYNC_GROUP_NODE_DESC = ('The [Blender Cloud Addon](https://cloud.blender.org/services'
|
||||
'#blender-addon) will synchronize your Blender settings here.')
|
||||
|
||||
@ -135,8 +135,8 @@ def create_home_project(user_id, write_access):
|
||||
# This allows people to comment on shared images and see comments.
|
||||
node_type_comment = assign_permissions(
|
||||
node_type_comment,
|
||||
subscriber_methods=[u'GET', u'POST'],
|
||||
world_methods=[u'GET'])
|
||||
subscriber_methods=['GET', 'POST'],
|
||||
world_methods=['GET'])
|
||||
|
||||
project['node_types'] = [
|
||||
node_type_group,
|
||||
@ -215,7 +215,7 @@ def home_project():
|
||||
write_access = write_access_with_roles(roles)
|
||||
create_home_project(user_id, write_access)
|
||||
|
||||
resp, _, _, status, _ = get('projects', category=u'home', user=user_id)
|
||||
resp, _, _, status, _ = get('projects', category='home', user=user_id)
|
||||
if status != 200:
|
||||
return utils.jsonify(resp), status
|
||||
|
||||
@ -248,8 +248,8 @@ def home_project_permissions(write_access):
|
||||
"""
|
||||
|
||||
if write_access:
|
||||
return [u'GET', u'PUT', u'POST', u'DELETE']
|
||||
return [u'GET']
|
||||
return ['GET', 'PUT', 'POST', 'DELETE']
|
||||
return ['GET']
|
||||
|
||||
|
||||
def has_home_project(user_id):
|
||||
|
@ -86,7 +86,7 @@ def upsert_user(db_user, blender_id_user_id):
|
||||
:type: (ObjectId, int)
|
||||
"""
|
||||
|
||||
if u'subscriber' in db_user.get('groups', []):
|
||||
if 'subscriber' in db_user.get('groups', []):
|
||||
log.error('Non-ObjectID string found in user.groups: %s', db_user)
|
||||
raise wz_exceptions.InternalServerError('Non-ObjectID string found in user.groups: %s' % db_user)
|
||||
|
||||
@ -117,8 +117,8 @@ def upsert_user(db_user, blender_id_user_id):
|
||||
if status == 422:
|
||||
# Probably non-unique username, so retry a few times with different usernames.
|
||||
log.info('Error creating new user: %s', r)
|
||||
username_issue = r.get('_issues', {}).get(u'username', '')
|
||||
if u'not unique' in username_issue:
|
||||
username_issue = r.get('_issues', {}).get('username', '')
|
||||
if 'not unique' in username_issue:
|
||||
# Retry
|
||||
db_user['username'] = authentication.make_unique_username(db_user['email'])
|
||||
continue
|
||||
|
@ -61,13 +61,13 @@ class ValidateCustomFields(Validator):
|
||||
Only validates the dict values, not the keys. Modifies the given dict in-place.
|
||||
"""
|
||||
|
||||
assert dict_valueschema[u'type'] == u'dict'
|
||||
assert dict_valueschema['type'] == 'dict'
|
||||
assert isinstance(dict_property, dict)
|
||||
|
||||
for key, val in dict_property.items():
|
||||
item_schema = {u'item': dict_valueschema}
|
||||
item_prop = {u'item': val}
|
||||
dict_property[key] = self.convert_properties(item_prop, item_schema)[u'item']
|
||||
item_schema = {'item': dict_valueschema}
|
||||
item_prop = {'item': val}
|
||||
dict_property[key] = self.convert_properties(item_prop, item_schema)['item']
|
||||
|
||||
def _validate_valid_properties(self, valid_properties, field, value):
|
||||
from pillar.api.utils import project_get_node_type
|
||||
|
@ -723,7 +723,7 @@ users = {
|
||||
|
||||
# By default don't include the 'auth' field. It can still be obtained
|
||||
# using projections, though, so we block that in hooks.
|
||||
'datasource': {'projection': {u'auth': 0}},
|
||||
'datasource': {'projection': {'auth': 0}},
|
||||
|
||||
'schema': users_schema
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ def process_file(gcs, file_id, local_file):
|
||||
mime_category, src_file['format'] = src_file['content_type'].split('/', 1)
|
||||
|
||||
# Prevent video handling for non-admins.
|
||||
if not user_has_role(u'admin') and mime_category == 'video':
|
||||
if not user_has_role('admin') and mime_category == 'video':
|
||||
if src_file['format'].startswith('x-'):
|
||||
xified = src_file['format']
|
||||
else:
|
||||
|
@ -29,7 +29,7 @@ def change_file_storage_backend(file_id, dest_backend):
|
||||
Files on the original backend are not deleted automatically.
|
||||
"""
|
||||
|
||||
dest_backend = unicode(dest_backend)
|
||||
dest_backend = str(dest_backend)
|
||||
file_id = ObjectId(file_id)
|
||||
|
||||
# Fetch file document
|
||||
|
@ -87,7 +87,7 @@ def generate_and_store_token(user_id, days=15, prefix=''):
|
||||
|
||||
|
||||
def hash_password(password, salt):
|
||||
if isinstance(salt, unicode):
|
||||
if isinstance(salt, str):
|
||||
salt = salt.encode('utf-8')
|
||||
encoded_password = base64.b64encode(hashlib.sha256(password).digest())
|
||||
return bcrypt.hashpw(encoded_password, salt)
|
||||
|
@ -1,7 +1,7 @@
|
||||
import base64
|
||||
import functools
|
||||
import logging
|
||||
import urlparse
|
||||
import urllib.parse
|
||||
|
||||
import pymongo.errors
|
||||
import rsa.randnum
|
||||
@ -20,7 +20,7 @@ from pillar.api.utils.gcs import update_file_name
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
blueprint = Blueprint('nodes_api', __name__)
|
||||
ROLES_FOR_SHARING = {u'subscriber', u'demo'}
|
||||
ROLES_FOR_SHARING = {'subscriber', 'demo'}
|
||||
|
||||
|
||||
def only_for_node_type_decorator(*required_node_type_names):
|
||||
@ -138,7 +138,7 @@ def make_world_gettable(node):
|
||||
log.debug('Ensuring the world can read node %s', node_id)
|
||||
|
||||
world_perms = set(node.get('permissions', {}).get('world', []))
|
||||
world_perms.add(u'GET')
|
||||
world_perms.add('GET')
|
||||
world_perms = list(world_perms)
|
||||
|
||||
result = nodes_coll.update_one({'_id': node_id},
|
||||
@ -164,7 +164,7 @@ def create_short_code(node):
|
||||
def short_link_info(short_code):
|
||||
"""Returns the short link info in a dict."""
|
||||
|
||||
short_link = urlparse.urljoin(current_app.config['SHORT_LINK_BASE_URL'], short_code)
|
||||
short_link = urllib.parse.urljoin(current_app.config['SHORT_LINK_BASE_URL'], short_code)
|
||||
|
||||
return {
|
||||
'short_code': short_code,
|
||||
@ -349,7 +349,7 @@ def node_set_default_picture(node, original=None):
|
||||
# Find the colour map, defaulting to the first image map available.
|
||||
image_file_id = None
|
||||
for image in props.get('files', []):
|
||||
if image_file_id is None or image.get('map_type') == u'color':
|
||||
if image_file_id is None or image.get('map_type') == 'color':
|
||||
image_file_id = image.get('file')
|
||||
else:
|
||||
log.debug('Not setting default picture on node type %s content type %s',
|
||||
|
@ -11,20 +11,20 @@ from pillar.api.utils import authorization, authentication, jsonify
|
||||
from . import register_patch_handler
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
ROLES_FOR_COMMENT_VOTING = {u'subscriber', u'demo'}
|
||||
COMMENT_VOTING_OPS = {u'upvote', u'downvote', u'revoke'}
|
||||
VALID_COMMENT_OPERATIONS = COMMENT_VOTING_OPS.union({u'edit'})
|
||||
ROLES_FOR_COMMENT_VOTING = {'subscriber', 'demo'}
|
||||
COMMENT_VOTING_OPS = {'upvote', 'downvote', 'revoke'}
|
||||
VALID_COMMENT_OPERATIONS = COMMENT_VOTING_OPS.union({'edit'})
|
||||
|
||||
|
||||
@register_patch_handler(u'comment')
|
||||
@register_patch_handler('comment')
|
||||
def patch_comment(node_id, patch):
|
||||
assert_is_valid_patch(node_id, patch)
|
||||
user_id = authentication.current_user_id()
|
||||
|
||||
if patch[u'op'] in COMMENT_VOTING_OPS:
|
||||
if patch['op'] in COMMENT_VOTING_OPS:
|
||||
result, node = vote_comment(user_id, node_id, patch)
|
||||
else:
|
||||
assert patch[u'op'] == u'edit', 'Invalid patch operation %s' % patch[u'op']
|
||||
assert patch['op'] == 'edit', 'Invalid patch operation %s' % patch['op']
|
||||
result, node = edit_comment(user_id, node_id, patch)
|
||||
|
||||
return jsonify({'_status': 'OK',
|
||||
@ -95,9 +95,9 @@ def vote_comment(user_id, node_id, patch):
|
||||
return update
|
||||
|
||||
actions = {
|
||||
u'upvote': upvote,
|
||||
u'downvote': downvote,
|
||||
u'revoke': revoke,
|
||||
'upvote': upvote,
|
||||
'downvote': downvote,
|
||||
'revoke': revoke,
|
||||
}
|
||||
action = actions[patch['op']]
|
||||
mongo_update = action()
|
||||
@ -141,7 +141,7 @@ def edit_comment(user_id, node_id, patch):
|
||||
log.warning('User %s wanted to patch non-existing node %s' % (user_id, node_id))
|
||||
raise wz_exceptions.NotFound('Node %s not found' % node_id)
|
||||
|
||||
if node['user'] != user_id and not authorization.user_has_role(u'admin'):
|
||||
if node['user'] != user_id and not authorization.user_has_role('admin'):
|
||||
raise wz_exceptions.Forbidden('You can only edit your own comments.')
|
||||
|
||||
# Use Eve to PATCH this node, as that also updates the etag.
|
||||
@ -173,8 +173,8 @@ def assert_is_valid_patch(node_id, patch):
|
||||
raise wz_exceptions.BadRequest("PATCH should have a key 'op' indicating the operation.")
|
||||
|
||||
if op not in VALID_COMMENT_OPERATIONS:
|
||||
raise wz_exceptions.BadRequest(u'Operation should be one of %s',
|
||||
u', '.join(VALID_COMMENT_OPERATIONS))
|
||||
raise wz_exceptions.BadRequest('Operation should be one of %s',
|
||||
', '.join(VALID_COMMENT_OPERATIONS))
|
||||
|
||||
if op not in COMMENT_VOTING_OPS:
|
||||
# We can't check here, we need the node owner for that.
|
||||
|
@ -28,7 +28,7 @@ def before_inserting_projects(items):
|
||||
"""
|
||||
|
||||
# Allow admin users to do whatever they want.
|
||||
if user_has_role(u'admin'):
|
||||
if user_has_role('admin'):
|
||||
return
|
||||
|
||||
for item in items:
|
||||
@ -70,7 +70,7 @@ def protect_sensitive_fields(document, original):
|
||||
"""When not logged in as admin, prevents update to certain fields."""
|
||||
|
||||
# Allow admin users to do whatever they want.
|
||||
if user_has_role(u'admin'):
|
||||
if user_has_role('admin'):
|
||||
return
|
||||
|
||||
def revert(name):
|
||||
|
@ -16,7 +16,7 @@ blueprint_api = Blueprint('projects_api', __name__)
|
||||
|
||||
|
||||
@blueprint_api.route('/create', methods=['POST'])
|
||||
@authorization.require_login(require_roles={u'admin', u'subscriber', u'demo'})
|
||||
@authorization.require_login(require_roles={'admin', 'subscriber', 'demo'})
|
||||
def create_project(overrides=None):
|
||||
"""Creates a new project."""
|
||||
|
||||
@ -65,7 +65,7 @@ def project_manage_users():
|
||||
project = projects_collection.find_one({'_id': project_id})
|
||||
|
||||
# Check if the current_user is owner of the project, or removing themselves.
|
||||
if not authorization.user_has_role(u'admin'):
|
||||
if not authorization.user_has_role('admin'):
|
||||
remove_self = target_user_id == current_user_id and action == 'remove'
|
||||
if project['user'] != current_user_id and not remove_self:
|
||||
utils.abort_with_error(403)
|
||||
|
@ -13,7 +13,7 @@ blueprint = Blueprint('service', __name__)
|
||||
log = logging.getLogger(__name__)
|
||||
signal_user_changed_role = blinker.NamedSignal('badger:user_changed_role')
|
||||
|
||||
ROLES_WITH_GROUPS = {u'admin', u'demo', u'subscriber'}
|
||||
ROLES_WITH_GROUPS = {'admin', 'demo', 'subscriber'}
|
||||
|
||||
# Map of role name to group ID, for the above groups.
|
||||
role_to_group_id = {}
|
||||
@ -38,7 +38,7 @@ def fetch_role_to_group_id_map():
|
||||
|
||||
|
||||
@blueprint.route('/badger', methods=['POST'])
|
||||
@authorization.require_login(require_roles={u'service', u'badger'}, require_all=True)
|
||||
@authorization.require_login(require_roles={'service', 'badger'}, require_all=True)
|
||||
def badger():
|
||||
if request.mimetype != 'application/json':
|
||||
log.debug('Received %s instead of application/json', request.mimetype)
|
||||
@ -117,7 +117,7 @@ def do_badger(action, user_email, role):
|
||||
|
||||
|
||||
@blueprint.route('/urler/<project_id>', methods=['GET'])
|
||||
@authorization.require_login(require_roles={u'service', u'urler'}, require_all=True)
|
||||
@authorization.require_login(require_roles={'service', 'urler'}, require_all=True)
|
||||
def urler(project_id):
|
||||
"""Returns the URL of any project."""
|
||||
|
||||
@ -189,7 +189,7 @@ def create_service_account(email, roles, service, update_existing=None):
|
||||
raise ValueError('User %s already exists' % email)
|
||||
|
||||
# Compute the new roles, and assign.
|
||||
roles = list(set(roles).union({u'service'}).union(user['roles']))
|
||||
roles = list(set(roles).union({'service'}).union(user['roles']))
|
||||
user['roles'] = list(roles)
|
||||
|
||||
# Let the caller perform any required updates.
|
||||
@ -204,7 +204,7 @@ def create_service_account(email, roles, service, update_existing=None):
|
||||
expected_status = 200
|
||||
else:
|
||||
# Create a user with the correct roles.
|
||||
roles = list(set(roles).union({u'service'}))
|
||||
roles = list(set(roles).union({'service'}))
|
||||
user = {'username': email,
|
||||
'groups': [],
|
||||
'roles': roles,
|
||||
|
@ -60,7 +60,7 @@ def check_user_access(request, lookup):
|
||||
current_user_id = current_user['user_id'] if current_user else None
|
||||
|
||||
# Admins can do anything and get everything, except the 'auth' block.
|
||||
if user_has_role(u'admin'):
|
||||
if user_has_role('admin'):
|
||||
return
|
||||
|
||||
if not lookup and not current_user:
|
||||
@ -74,7 +74,7 @@ def check_user_access(request, lookup):
|
||||
def check_put_access(request, lookup):
|
||||
"""Only allow PUT to the current user, or all users if admin."""
|
||||
|
||||
if user_has_role(u'admin'):
|
||||
if user_has_role('admin'):
|
||||
return
|
||||
|
||||
current_user = g.get('current_user')
|
||||
@ -94,7 +94,7 @@ def after_fetching_user(user):
|
||||
current_user_id = current_user['user_id'] if current_user else None
|
||||
|
||||
# Admins can do anything and get everything, except the 'auth' block.
|
||||
if user_has_role(u'admin'):
|
||||
if user_has_role('admin'):
|
||||
return
|
||||
|
||||
# Only allow full access to the current user.
|
||||
|
@ -1,7 +1,7 @@
|
||||
import copy
|
||||
import hashlib
|
||||
import json
|
||||
import urllib
|
||||
import urllib.request, urllib.parse, urllib.error
|
||||
|
||||
import datetime
|
||||
import functools
|
||||
@ -103,7 +103,7 @@ def skip_when_testing(func):
|
||||
@functools.wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
if current_app.config['TESTING']:
|
||||
log.debug('Skipping call to %s(...) due to TESTING', func.func_name)
|
||||
log.debug('Skipping call to %s(...) due to TESTING', func.__name__)
|
||||
return None
|
||||
|
||||
return func(*args, **kwargs)
|
||||
@ -145,19 +145,18 @@ def gravatar(email, size=64):
|
||||
parameters = {'s': str(size), 'd': 'mm'}
|
||||
return "https://www.gravatar.com/avatar/" + \
|
||||
hashlib.md5(str(email)).hexdigest() + \
|
||||
"?" + urllib.urlencode(parameters)
|
||||
"?" + urllib.parse.urlencode(parameters)
|
||||
|
||||
|
||||
|
||||
class MetaFalsey(type):
|
||||
def __nonzero__(cls):
|
||||
def __bool__(cls):
|
||||
return False
|
||||
__bool__ = __nonzero__ # for Python 3
|
||||
|
||||
|
||||
class DoesNotExist(object):
|
||||
class DoesNotExist(object, metaclass=MetaFalsey):
|
||||
"""Returned as value by doc_diff if a value does not exist."""
|
||||
__metaclass__ = MetaFalsey
|
||||
|
||||
|
||||
def doc_diff(doc1, doc2, falsey_is_equal=True):
|
||||
@ -175,7 +174,7 @@ def doc_diff(doc1, doc2, falsey_is_equal=True):
|
||||
"""
|
||||
|
||||
for key in set(doc1.keys()).union(set(doc2.keys())):
|
||||
if isinstance(key, basestring) and key[0] == u'_':
|
||||
if isinstance(key, str) and key[0] == '_':
|
||||
continue
|
||||
|
||||
val1 = doc1.get(key, DoesNotExist)
|
||||
|
@ -124,7 +124,7 @@ def store_token(user_id, token, token_expiry, oauth_subclient_id=False):
|
||||
:returns: the token document from MongoDB
|
||||
"""
|
||||
|
||||
assert isinstance(token, (str, unicode)), 'token must be string type, not %r' % type(token)
|
||||
assert isinstance(token, str), 'token must be string type, not %r' % type(token)
|
||||
|
||||
token_data = {
|
||||
'user': user_id,
|
||||
|
@ -238,22 +238,22 @@ def merge_permissions(*args):
|
||||
asdict0 = {permission[field_name]: permission['methods'] for permission in from0}
|
||||
asdict1 = {permission[field_name]: permission['methods'] for permission in from1}
|
||||
|
||||
keys = set(asdict0.keys() + asdict1.keys())
|
||||
keys = set(asdict0.keys()).union(set(asdict1.keys()))
|
||||
for key in maybe_sorted(keys):
|
||||
methods0 = asdict0.get(key, [])
|
||||
methods1 = asdict1.get(key, [])
|
||||
methods = maybe_sorted(set(methods0).union(set(methods1)))
|
||||
effective.setdefault(plural_name, []).append({field_name: key, u'methods': methods})
|
||||
effective.setdefault(plural_name, []).append({field_name: key, 'methods': methods})
|
||||
|
||||
merge(u'user')
|
||||
merge(u'group')
|
||||
merge('user')
|
||||
merge('group')
|
||||
|
||||
# Gather permissions for world
|
||||
world0 = args[0].get('world', [])
|
||||
world1 = args[1].get('world', [])
|
||||
world_methods = set(world0).union(set(world1))
|
||||
if world_methods:
|
||||
effective[u'world'] = maybe_sorted(world_methods)
|
||||
effective['world'] = maybe_sorted(world_methods)
|
||||
|
||||
# Recurse for longer merges
|
||||
if len(args) > 2:
|
||||
@ -380,4 +380,4 @@ def user_matches_roles(require_roles=set(),
|
||||
def is_admin(user):
|
||||
"""Returns True iff the given user has the admin role."""
|
||||
|
||||
return user_has_role(u'admin', user)
|
||||
return user_has_role('admin', user)
|
||||
|
@ -173,7 +173,7 @@ class GoogleCloudStorageBucket(Bucket):
|
||||
"""Set the ContentDisposition metadata so that when a file is downloaded
|
||||
it has a human-readable name.
|
||||
"""
|
||||
blob.content_disposition = u'attachment; filename="{0}"'.format(name)
|
||||
blob.content_disposition = 'attachment; filename="{0}"'.format(name)
|
||||
blob.patch()
|
||||
|
||||
def copy_blob(self, blob, to_bucket):
|
||||
@ -215,11 +215,11 @@ def update_file_name(node):
|
||||
if node['properties'].get('status', '') == 'processing':
|
||||
return
|
||||
|
||||
def _format_name(name, override_ext, size=None, map_type=u''):
|
||||
def _format_name(name, override_ext, size=None, map_type=''):
|
||||
root, _ = os.path.splitext(name)
|
||||
size = u'-{}'.format(size) if size else u''
|
||||
map_type = u'-{}'.format(map_type) if map_type else u''
|
||||
return u'{}{}{}{}'.format(root, size, map_type, override_ext)
|
||||
size = '-{}'.format(size) if size else ''
|
||||
map_type = '-{}'.format(map_type) if map_type else ''
|
||||
return '{}{}{}{}'.format(root, size, map_type, override_ext)
|
||||
|
||||
def _update_name(file_id, file_props):
|
||||
files_collection = current_app.data.driver.db['files']
|
||||
@ -229,7 +229,7 @@ def update_file_name(node):
|
||||
return
|
||||
|
||||
# For textures -- the map type should be part of the name.
|
||||
map_type = file_props.get('map_type', u'')
|
||||
map_type = file_props.get('map_type', '')
|
||||
|
||||
storage = GoogleCloudStorageBucket(str(node['project']))
|
||||
blob = storage.Get(file_doc['file_path'], to_dict=False)
|
||||
|
@ -21,7 +21,7 @@ def generate_local_thumbnails(name_base, src):
|
||||
save_to_base, _ = os.path.splitext(src)
|
||||
name_base, _ = os.path.splitext(name_base)
|
||||
|
||||
for size, settings in thumbnail_settings.iteritems():
|
||||
for size, settings in thumbnail_settings.items():
|
||||
dst = '{0}-{1}{2}'.format(save_to_base, size, '.jpg')
|
||||
name = '{0}-{1}{2}'.format(name_base, size, '.jpg')
|
||||
|
||||
@ -143,7 +143,7 @@ def get_video_data(filepath):
|
||||
res_y=video_stream['height'],
|
||||
)
|
||||
if video_stream['sample_aspect_ratio'] != '1:1':
|
||||
print '[warning] Pixel aspect ratio is not square!'
|
||||
print('[warning] Pixel aspect ratio is not square!')
|
||||
|
||||
return outdata
|
||||
|
||||
@ -190,14 +190,14 @@ def ffmpeg_encode(src, format, res_y=720):
|
||||
dst = os.path.splitext(src)
|
||||
dst = "{0}-{1}p.{2}".format(dst[0], res_y, format)
|
||||
args.append(dst)
|
||||
print "Encoding {0} to {1}".format(src, format)
|
||||
print("Encoding {0} to {1}".format(src, format))
|
||||
returncode = subprocess.call([current_app.config['BIN_FFMPEG']] + args)
|
||||
if returncode == 0:
|
||||
print "Successfully encoded {0}".format(dst)
|
||||
print("Successfully encoded {0}".format(dst))
|
||||
else:
|
||||
print "Error during encode"
|
||||
print "Code: {0}".format(returncode)
|
||||
print "Command: {0}".format(current_app.config['BIN_FFMPEG'] + " " + " ".join(args))
|
||||
print("Error during encode")
|
||||
print("Code: {0}".format(returncode))
|
||||
print("Command: {0}".format(current_app.config['BIN_FFMPEG'] + " " + " ".join(args)))
|
||||
dst = None
|
||||
# return path of the encoded video
|
||||
return dst
|
||||
|
@ -55,11 +55,11 @@ def _load_user(token):
|
||||
|
||||
login_user = UserClass(token)
|
||||
login_user.email = db_user['email']
|
||||
login_user.objectid = unicode(db_user['_id'])
|
||||
login_user.objectid = str(db_user['_id'])
|
||||
login_user.username = db_user['username']
|
||||
login_user.gravatar = utils.gravatar(db_user['email'])
|
||||
login_user.roles = db_user.get('roles', [])
|
||||
login_user.groups = [unicode(g) for g in db_user['groups'] or ()]
|
||||
login_user.groups = [str(g) for g in db_user['groups'] or ()]
|
||||
login_user.full_name = db_user.get('full_name', '')
|
||||
|
||||
return login_user
|
||||
|
@ -3,7 +3,7 @@
|
||||
Run commands with 'flask <command>'
|
||||
"""
|
||||
|
||||
from __future__ import print_function, division
|
||||
|
||||
|
||||
import copy
|
||||
import logging
|
||||
@ -57,7 +57,7 @@ def setup_db(admin_email):
|
||||
print("Created user {0}".format(user['_id']))
|
||||
|
||||
# Create a default project by faking a POST request.
|
||||
with current_app.test_request_context(data={'project_name': u'Default Project'}):
|
||||
with current_app.test_request_context(data={'project_name': 'Default Project'}):
|
||||
from flask import g
|
||||
from pillar.api.projects import routes as proj_routes
|
||||
|
||||
@ -89,7 +89,7 @@ def find_duplicate_users():
|
||||
blender_id = blender_ids[0]
|
||||
found_users[blender_id].append(user)
|
||||
|
||||
for blender_id, users in found_users.iteritems():
|
||||
for blender_id, users in found_users.items():
|
||||
if len(users) == 1:
|
||||
continue
|
||||
|
||||
@ -344,14 +344,14 @@ def create_badger_account(email, badges):
|
||||
this account can assign and revoke.
|
||||
"""
|
||||
|
||||
create_service_account(email, [u'badger'], {'badger': badges.strip().split()})
|
||||
create_service_account(email, ['badger'], {'badger': badges.strip().split()})
|
||||
|
||||
|
||||
@manager_setup.command
|
||||
def create_urler_account(email):
|
||||
"""Creates a new service account that can fetch all project URLs."""
|
||||
|
||||
create_service_account(email, [u'urler'], {})
|
||||
create_service_account(email, ['urler'], {})
|
||||
|
||||
|
||||
@manager_setup.command
|
||||
@ -704,7 +704,7 @@ def upgrade_attachment_schema(proj_url=None, all_projects=False):
|
||||
'properties.attachments': {'$exists': True},
|
||||
})
|
||||
for node in nodes:
|
||||
attachments = node[u'properties'][u'attachments']
|
||||
attachments = node['properties']['attachments']
|
||||
if isinstance(attachments, dict):
|
||||
# This node has already been upgraded.
|
||||
continue
|
||||
@ -713,9 +713,9 @@ def upgrade_attachment_schema(proj_url=None, all_projects=False):
|
||||
new_atts = {}
|
||||
for field_info in attachments:
|
||||
for attachment in field_info.get('files', []):
|
||||
new_atts[attachment[u'slug']] = {u'oid': attachment[u'file']}
|
||||
new_atts[attachment['slug']] = {'oid': attachment['file']}
|
||||
|
||||
node[u'properties'][u'attachments'] = new_atts
|
||||
node['properties']['attachments'] = new_atts
|
||||
|
||||
# Use Eve to PUT, so we have schema checking.
|
||||
db_node = remove_private_keys(node)
|
||||
@ -774,11 +774,11 @@ def create_blog(proj_url):
|
||||
blog = nodes_coll.find_one({'node_type': 'blog', 'project': proj_id})
|
||||
if not blog:
|
||||
blog = {
|
||||
u'node_type': node_type_blog['name'],
|
||||
u'name': u'Blog',
|
||||
u'description': u'',
|
||||
u'properties': {},
|
||||
u'project': proj_id,
|
||||
'node_type': node_type_blog['name'],
|
||||
'name': 'Blog',
|
||||
'description': '',
|
||||
'properties': {},
|
||||
'project': proj_id,
|
||||
}
|
||||
r, _, _, status = post_internal('nodes', blog)
|
||||
if status != 201:
|
||||
|
@ -81,7 +81,7 @@ FILE_LINK_VALIDITY = defaultdict(
|
||||
)
|
||||
|
||||
# Roles with full GET-access to all variations of files.
|
||||
FULL_FILE_ACCESS_ROLES = {u'admin', u'subscriber', u'demo'}
|
||||
FULL_FILE_ACCESS_ROLES = {'admin', 'subscriber', 'demo'}
|
||||
|
||||
# Client and Subclient IDs for Blender ID
|
||||
BLENDER_ID_CLIENT_ID = 'SPECIAL-SNOWFLAKE-57'
|
||||
@ -119,7 +119,7 @@ SHORT_CODE_LENGTH = 6 # characters
|
||||
# People are allowed this many bytes per uploaded file.
|
||||
FILESIZE_LIMIT_BYTES_NONSUBS = 32 * 2 ** 20
|
||||
# Unless they have one of those roles.
|
||||
ROLES_FOR_UNLIMITED_UPLOADS = {u'subscriber', u'demo', u'admin'}
|
||||
ROLES_FOR_UNLIMITED_UPLOADS = {'subscriber', 'demo', 'admin'}
|
||||
|
||||
|
||||
#############################################
|
||||
|
@ -18,9 +18,7 @@ can then be registered to the application at app creation time:
|
||||
import abc
|
||||
|
||||
|
||||
class PillarExtension(object):
|
||||
__metaclass__ = abc.ABCMeta
|
||||
|
||||
class PillarExtension(object, metaclass=abc.ABCMeta):
|
||||
@abc.abstractproperty
|
||||
def name(self):
|
||||
"""The name of this extension.
|
||||
|
@ -3,8 +3,6 @@
|
||||
This is for user-generated stuff, like comments.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import bleach
|
||||
import CommonMark
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
"""PillarSDK subclass for direct Flask-internal calls."""
|
||||
|
||||
import logging
|
||||
import urlparse
|
||||
import urllib.parse
|
||||
from flask import current_app
|
||||
|
||||
import pillarsdk
|
||||
@ -23,8 +23,8 @@ class FlaskInternalApi(pillarsdk.Api):
|
||||
self.requests_to_flask_kwargs(kwargs)
|
||||
|
||||
# Leave out the query string and fragment from the URL.
|
||||
split_url = urlparse.urlsplit(url)
|
||||
path = urlparse.urlunsplit(split_url[:-2] + (None, None))
|
||||
split_url = urllib.parse.urlsplit(url)
|
||||
path = urllib.parse.urlunsplit(split_url[:-2] + (None, None))
|
||||
try:
|
||||
response = client.open(path=path, query_string=split_url.query, method=method,
|
||||
**kwargs)
|
||||
|
@ -1,9 +1,5 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import base64
|
||||
import copy
|
||||
import json
|
||||
@ -16,7 +12,7 @@ import sys
|
||||
try:
|
||||
from urllib.parse import urlencode
|
||||
except ImportError:
|
||||
from urllib import urlencode
|
||||
from urllib.parse import urlencode
|
||||
|
||||
from bson import ObjectId, tz_util
|
||||
|
||||
@ -46,7 +42,7 @@ MY_PATH = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
TEST_EMAIL_USER = 'koro'
|
||||
TEST_EMAIL_ADDRESS = '%s@testing.blender.org' % TEST_EMAIL_USER
|
||||
TEST_FULL_NAME = u'врач Сергей'
|
||||
TEST_FULL_NAME = 'врач Сергей'
|
||||
TEST_SUBCLIENT_TOKEN = 'my-subclient-token-for-pillar'
|
||||
BLENDER_ID_USER_RESPONSE = {'status': 'success',
|
||||
'user': {'email': TEST_EMAIL_ADDRESS,
|
||||
@ -207,9 +203,9 @@ class AbstractPillarTest(TestMinimal):
|
||||
'roles': list(roles),
|
||||
'settings': {'email_communications': 1},
|
||||
'auth': [{'token': '',
|
||||
'user_id': unicode(ctd.BLENDER_ID_TEST_USERID),
|
||||
'user_id': str(ctd.BLENDER_ID_TEST_USERID),
|
||||
'provider': 'blender-id'}],
|
||||
'full_name': u'คนรักของผัดไทย',
|
||||
'full_name': 'คนรักของผัดไทย',
|
||||
'email': TEST_EMAIL_ADDRESS
|
||||
})
|
||||
|
||||
|
@ -11,55 +11,55 @@ EXAMPLE_PROJECT_READONLY_GROUP2_ID = ObjectId('564733b56dcaf85da2faee8a')
|
||||
EXAMPLE_PROJECT_ID = ObjectId('5672beecc0261b2005ed1a33')
|
||||
EXAMPLE_PROJECT_OWNER_ID = ObjectId('552b066b41acdf5dec4436f2')
|
||||
|
||||
EXAMPLE_FILE = {u'_id': ObjectId('5672e2c1c379cf0007b31995'),
|
||||
u'_updated': datetime.datetime(2016, 3, 25, 10, 28, 24, tzinfo=tz_util.utc),
|
||||
u'height': 2048,
|
||||
u'name': 'c2a5c897769ce1ef0eb10f8fa1c472bcb8e2d5a4.png', u'format': 'png',
|
||||
u'variations': [
|
||||
{u'format': 'jpg', u'height': 160, u'width': 160, u'length': 8558,
|
||||
u'link': 'http://localhost:8002/file-variant-h', u'content_type': 'image/jpeg',
|
||||
u'md5': '--', u'file_path': 'c2a5c897769ce1ef0eb10f8fa1c472bcb8e2d5a4-b.jpg',
|
||||
u'size': 'b'},
|
||||
{u'format': 'jpg', u'height': 2048, u'width': 2048, u'length': 819569,
|
||||
u'link': 'http://localhost:8002/file-variant-h', u'content_type': 'image/jpeg',
|
||||
u'md5': '--', u'file_path': 'c2a5c897769ce1ef0eb10f8fa1c472bcb8e2d5a4-h.jpg',
|
||||
u'size': 'h'},
|
||||
{u'format': 'jpg', u'height': 64, u'width': 64, u'length': 8195,
|
||||
u'link': 'http://localhost:8002/file-variant-t', u'content_type': 'image/jpeg',
|
||||
u'md5': '--', u'file_path': 'c2a5c897769ce1ef0eb10f8fa1c472bcb8e2d5a4-t.jpg',
|
||||
u'size': 't'},
|
||||
EXAMPLE_FILE = {'_id': ObjectId('5672e2c1c379cf0007b31995'),
|
||||
'_updated': datetime.datetime(2016, 3, 25, 10, 28, 24, tzinfo=tz_util.utc),
|
||||
'height': 2048,
|
||||
'name': 'c2a5c897769ce1ef0eb10f8fa1c472bcb8e2d5a4.png', 'format': 'png',
|
||||
'variations': [
|
||||
{'format': 'jpg', 'height': 160, 'width': 160, 'length': 8558,
|
||||
'link': 'http://localhost:8002/file-variant-h', 'content_type': 'image/jpeg',
|
||||
'md5': '--', 'file_path': 'c2a5c897769ce1ef0eb10f8fa1c472bcb8e2d5a4-b.jpg',
|
||||
'size': 'b'},
|
||||
{'format': 'jpg', 'height': 2048, 'width': 2048, 'length': 819569,
|
||||
'link': 'http://localhost:8002/file-variant-h', 'content_type': 'image/jpeg',
|
||||
'md5': '--', 'file_path': 'c2a5c897769ce1ef0eb10f8fa1c472bcb8e2d5a4-h.jpg',
|
||||
'size': 'h'},
|
||||
{'format': 'jpg', 'height': 64, 'width': 64, 'length': 8195,
|
||||
'link': 'http://localhost:8002/file-variant-t', 'content_type': 'image/jpeg',
|
||||
'md5': '--', 'file_path': 'c2a5c897769ce1ef0eb10f8fa1c472bcb8e2d5a4-t.jpg',
|
||||
'size': 't'},
|
||||
],
|
||||
u'filename': 'brick_dutch_soft_bump.png',
|
||||
u'project': EXAMPLE_PROJECT_ID,
|
||||
u'width': 2048, u'length': 6227670,
|
||||
u'user': ObjectId('56264fc4fa3a250344bd10c5'),
|
||||
u'content_type': 'image/png',
|
||||
u'_etag': '044ce3aede2e123e261c0d8bd77212f264d4f7b0',
|
||||
u'_created': datetime.datetime(2015, 12, 17, 16, 28, 49, tzinfo=tz_util.utc),
|
||||
u'md5': '',
|
||||
u'file_path': 'c2a5c897769ce1ef0eb10f8fa1c472bcb8e2d5a4.png',
|
||||
u'backend': 'pillar',
|
||||
u'link': 'http://localhost:8002/file',
|
||||
u'link_expires': datetime.datetime(2016, 3, 22, 9, 28, 22, tzinfo=tz_util.utc)}
|
||||
'filename': 'brick_dutch_soft_bump.png',
|
||||
'project': EXAMPLE_PROJECT_ID,
|
||||
'width': 2048, 'length': 6227670,
|
||||
'user': ObjectId('56264fc4fa3a250344bd10c5'),
|
||||
'content_type': 'image/png',
|
||||
'_etag': '044ce3aede2e123e261c0d8bd77212f264d4f7b0',
|
||||
'_created': datetime.datetime(2015, 12, 17, 16, 28, 49, tzinfo=tz_util.utc),
|
||||
'md5': '',
|
||||
'file_path': 'c2a5c897769ce1ef0eb10f8fa1c472bcb8e2d5a4.png',
|
||||
'backend': 'pillar',
|
||||
'link': 'http://localhost:8002/file',
|
||||
'link_expires': datetime.datetime(2016, 3, 22, 9, 28, 22, tzinfo=tz_util.utc)}
|
||||
|
||||
EXAMPLE_PROJECT = {
|
||||
u'_created': datetime.datetime(2015, 12, 17, 13, 22, 56, tzinfo=tz_util.utc),
|
||||
u'_etag': u'cc4643e98d3606f87bbfaaa200bfbae941b642f3',
|
||||
u'_id': EXAMPLE_PROJECT_ID,
|
||||
u'_updated': datetime.datetime(2016, 1, 7, 18, 59, 4, tzinfo=tz_util.utc),
|
||||
u'category': u'assets',
|
||||
u'description': u'Welcome to this curated collection of Blender Institute textures and image '
|
||||
u'resources. This collection is an on-going project, as with each project we '
|
||||
u'create a number of textures based on our own resources (photographs, scans, '
|
||||
u'etc.) or made completely from scratch. At the moment you can find all the '
|
||||
u'textures from the past Open Projects that were deemed re-usable. \r\n\r\n'
|
||||
u'People who have contributed to these textures:\r\n\r\nAndrea Weikert, Andy '
|
||||
u'Goralczyk, Basse Salmela, Ben Dansie, Campbell Barton, Enrico Valenza, Ian '
|
||||
u'Hubert, Kjartan Tysdal, Manu J\xe4rvinen, Massimiliana Pulieso, Matt Ebb, '
|
||||
u'Pablo Vazquez, Rob Tuytel, Roland Hess, Sarah Feldlaufer, S\xf6nke M\xe4ter',
|
||||
u'is_private': False,
|
||||
u'name': u'Unittest project',
|
||||
u'node_types': [
|
||||
'_created': datetime.datetime(2015, 12, 17, 13, 22, 56, tzinfo=tz_util.utc),
|
||||
'_etag': 'cc4643e98d3606f87bbfaaa200bfbae941b642f3',
|
||||
'_id': EXAMPLE_PROJECT_ID,
|
||||
'_updated': datetime.datetime(2016, 1, 7, 18, 59, 4, tzinfo=tz_util.utc),
|
||||
'category': 'assets',
|
||||
'description': 'Welcome to this curated collection of Blender Institute textures and image '
|
||||
'resources. This collection is an on-going project, as with each project we '
|
||||
'create a number of textures based on our own resources (photographs, scans, '
|
||||
'etc.) or made completely from scratch. At the moment you can find all the '
|
||||
'textures from the past Open Projects that were deemed re-usable. \r\n\r\n'
|
||||
'People who have contributed to these textures:\r\n\r\nAndrea Weikert, Andy '
|
||||
'Goralczyk, Basse Salmela, Ben Dansie, Campbell Barton, Enrico Valenza, Ian '
|
||||
'Hubert, Kjartan Tysdal, Manu J\xe4rvinen, Massimiliana Pulieso, Matt Ebb, '
|
||||
'Pablo Vazquez, Rob Tuytel, Roland Hess, Sarah Feldlaufer, S\xf6nke M\xe4ter',
|
||||
'is_private': False,
|
||||
'name': 'Unittest project',
|
||||
'node_types': [
|
||||
PILLAR_NAMED_NODE_TYPES['group_texture'],
|
||||
PILLAR_NAMED_NODE_TYPES['group'],
|
||||
PILLAR_NAMED_NODE_TYPES['asset'],
|
||||
@ -69,36 +69,36 @@ EXAMPLE_PROJECT = {
|
||||
PILLAR_NAMED_NODE_TYPES['post'],
|
||||
PILLAR_NAMED_NODE_TYPES['texture'],
|
||||
],
|
||||
u'nodes_blog': [],
|
||||
u'nodes_featured': [],
|
||||
u'nodes_latest': [],
|
||||
u'permissions': {u'groups': [{u'group': EXAMPLE_ADMIN_GROUP_ID,
|
||||
u'methods': [u'GET', u'POST', u'PUT', u'DELETE']}],
|
||||
u'users': [],
|
||||
u'world': [u'GET']},
|
||||
u'picture_header': ObjectId('5673f260c379cf0007b31bc4'),
|
||||
u'picture_square': ObjectId('5673f256c379cf0007b31bc3'),
|
||||
u'status': u'published',
|
||||
u'summary': u'Texture collection from all Blender Institute open projects.',
|
||||
u'url': u'textures',
|
||||
u'user': EXAMPLE_PROJECT_OWNER_ID}
|
||||
'nodes_blog': [],
|
||||
'nodes_featured': [],
|
||||
'nodes_latest': [],
|
||||
'permissions': {'groups': [{'group': EXAMPLE_ADMIN_GROUP_ID,
|
||||
'methods': ['GET', 'POST', 'PUT', 'DELETE']}],
|
||||
'users': [],
|
||||
'world': ['GET']},
|
||||
'picture_header': ObjectId('5673f260c379cf0007b31bc4'),
|
||||
'picture_square': ObjectId('5673f256c379cf0007b31bc3'),
|
||||
'status': 'published',
|
||||
'summary': 'Texture collection from all Blender Institute open projects.',
|
||||
'url': 'textures',
|
||||
'user': EXAMPLE_PROJECT_OWNER_ID}
|
||||
|
||||
EXAMPLE_NODE = {
|
||||
u'_id': ObjectId('572761099837730efe8e120d'),
|
||||
u'picture': ObjectId('572761f39837730efe8e1210'),
|
||||
u'description': u'',
|
||||
u'node_type': u'asset',
|
||||
u'user': ObjectId('57164ca1983773118cbaf779'),
|
||||
u'properties': {
|
||||
u'status': u'published',
|
||||
u'content_type': u'image',
|
||||
u'file': ObjectId('572761129837730efe8e120e')
|
||||
'_id': ObjectId('572761099837730efe8e120d'),
|
||||
'picture': ObjectId('572761f39837730efe8e1210'),
|
||||
'description': '',
|
||||
'node_type': 'asset',
|
||||
'user': ObjectId('57164ca1983773118cbaf779'),
|
||||
'properties': {
|
||||
'status': 'published',
|
||||
'content_type': 'image',
|
||||
'file': ObjectId('572761129837730efe8e120e')
|
||||
},
|
||||
u'_updated': datetime.datetime(2016, 5, 2, 14, 19, 58, 0, tzinfo=tz_util.utc),
|
||||
u'name': u'Image test',
|
||||
u'project': EXAMPLE_PROJECT_ID,
|
||||
u'_created': datetime.datetime(2016, 5, 2, 14, 19, 37, 0, tzinfo=tz_util.utc),
|
||||
u'_etag': u'6b8589b42c880e3626f43f3e82a5c5b946742687'
|
||||
'_updated': datetime.datetime(2016, 5, 2, 14, 19, 58, 0, tzinfo=tz_util.utc),
|
||||
'name': 'Image test',
|
||||
'project': EXAMPLE_PROJECT_ID,
|
||||
'_created': datetime.datetime(2016, 5, 2, 14, 19, 37, 0, tzinfo=tz_util.utc),
|
||||
'_etag': '6b8589b42c880e3626f43f3e82a5c5b946742687'
|
||||
}
|
||||
|
||||
BLENDER_ID_TEST_USERID = 1533
|
||||
|
@ -8,4 +8,4 @@ TESTING = True
|
||||
CDN_STORAGE_USER = 'u41508580125621'
|
||||
|
||||
FILESIZE_LIMIT_BYTES_NONSUBS = 20 * 2 ** 10
|
||||
ROLES_FOR_UNLIMITED_UPLOADS = {u'subscriber', u'demo', u'admin'}
|
||||
ROLES_FOR_UNLIMITED_UPLOADS = {'subscriber', 'demo', 'admin'}
|
||||
|
@ -1,7 +1,5 @@
|
||||
"""Our custom Jinja filters and other template stuff."""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import logging
|
||||
|
||||
import flask
|
||||
|
@ -304,8 +304,8 @@ def feeds_blogs():
|
||||
updated = post._updated if post._updated else post._created
|
||||
url = url_for_node(node=post)
|
||||
content = post.properties.content[:500]
|
||||
content = u'<p>{0}... <a href="{1}">Read more</a></p>'.format(content, url)
|
||||
feed.add(post.name, unicode(content),
|
||||
content = '<p>{0}... <a href="{1}">Read more</a></p>'.format(content, url)
|
||||
feed.add(post.name, str(content),
|
||||
content_type='html',
|
||||
author=author,
|
||||
url=url,
|
||||
|
@ -25,7 +25,7 @@ def render_attachments(node, field_value):
|
||||
node_attachments = node.properties.attachments or {}
|
||||
if isinstance(node_attachments, list):
|
||||
log.warning('Old-style attachments property found on node %s. Ignoring them, '
|
||||
'will result in attachments not being found.', node[u'_id'])
|
||||
'will result in attachments not being found.', node['_id'])
|
||||
return field_value
|
||||
|
||||
if not node_attachments:
|
||||
@ -37,7 +37,7 @@ def render_attachments(node, field_value):
|
||||
try:
|
||||
att = node_attachments[slug]
|
||||
except KeyError:
|
||||
return u'[attachment "%s" not found]' % slug
|
||||
return '[attachment "%s" not found]' % slug
|
||||
return render_attachment(att)
|
||||
|
||||
return shortcode_re.sub(replace, field_value)
|
||||
@ -46,8 +46,8 @@ def render_attachments(node, field_value):
|
||||
def render_attachment(attachment):
|
||||
"""Renders an attachment as HTML"""
|
||||
|
||||
oid = ObjectId(attachment[u'oid'])
|
||||
collection = attachment.collection or u'files'
|
||||
oid = ObjectId(attachment['oid'])
|
||||
collection = attachment.collection or 'files'
|
||||
|
||||
renderers = {
|
||||
'files': render_attachment_file
|
||||
@ -56,8 +56,8 @@ def render_attachment(attachment):
|
||||
try:
|
||||
renderer = renderers[collection]
|
||||
except KeyError:
|
||||
log.error(u'Unable to render attachment from collection %s', collection)
|
||||
return u'Unable to render attachment'
|
||||
log.error('Unable to render attachment from collection %s', collection)
|
||||
return 'Unable to render attachment'
|
||||
|
||||
return renderer(attachment)
|
||||
|
||||
@ -66,7 +66,7 @@ def render_attachment_file(attachment):
|
||||
"""Renders a file attachment."""
|
||||
|
||||
api = system_util.pillar_api()
|
||||
sdk_file = pillarsdk.File.find(attachment[u'oid'], api=api)
|
||||
sdk_file = pillarsdk.File.find(attachment['oid'], api=api)
|
||||
|
||||
file_renderers = {
|
||||
'image': render_attachment_file_image
|
||||
@ -119,7 +119,7 @@ def attachment_form_group_set_data(db_prop_value, schema_prop, field_list):
|
||||
while len(field_list):
|
||||
field_list.pop_entry()
|
||||
|
||||
for slug, att_data in sorted(db_prop_value.iteritems()):
|
||||
for slug, att_data in sorted(db_prop_value.items()):
|
||||
file_select_form_group = _attachment_build_single_field(schema_prop)
|
||||
subform = file_select_form_group()
|
||||
|
||||
|
@ -243,7 +243,7 @@ def comments_rate(comment_id, operation):
|
||||
|
||||
"""
|
||||
|
||||
if operation not in {u'revoke', u'upvote', u'downvote'}:
|
||||
if operation not in {'revoke', 'upvote', 'downvote'}:
|
||||
raise wz_exceptions.BadRequest('Invalid operation')
|
||||
|
||||
api = system_util.pillar_api()
|
||||
|
@ -33,7 +33,7 @@ def iter_node_properties(node_type):
|
||||
node_schema = node_type['dyn_schema'].to_dict()
|
||||
form_schema = node_type['form_schema'].to_dict()
|
||||
|
||||
for prop_name, prop_schema in node_schema.iteritems():
|
||||
for prop_name, prop_schema in node_schema.items():
|
||||
prop_fschema = form_schema.get(prop_name, {})
|
||||
|
||||
if not prop_fschema.get('visible', True):
|
||||
|
@ -142,7 +142,7 @@ def view(node_id):
|
||||
return 'GET' in node.permissions.world
|
||||
|
||||
if current_user.is_authenticated:
|
||||
allowed_roles = {u'subscriber', u'demo', u'admin'}
|
||||
allowed_roles = {'subscriber', 'demo', 'admin'}
|
||||
return bool(allowed_roles.intersection(current_user.roles or ()))
|
||||
|
||||
return False
|
||||
@ -330,7 +330,7 @@ def edit(node_id):
|
||||
|
||||
log.debug('set_properties(..., prefix=%r, set_data=%r) called', prefix, set_data)
|
||||
|
||||
for prop, schema_prop in dyn_schema.iteritems():
|
||||
for prop, schema_prop in dyn_schema.items():
|
||||
prop_name = "{0}{1}".format(prefix, prop)
|
||||
|
||||
if prop_name not in form:
|
||||
@ -376,7 +376,7 @@ def edit(node_id):
|
||||
for file_data in db_prop_value:
|
||||
file_form_class = build_file_select_form(subschema)
|
||||
subform = file_form_class()
|
||||
for key, value in file_data.iteritems():
|
||||
for key, value in file_data.items():
|
||||
setattr(subform, key, value)
|
||||
field_list.append_entry(subform)
|
||||
|
||||
@ -481,7 +481,7 @@ def ensure_lists_exist_as_empty(node_doc, node_type):
|
||||
|
||||
node_properties = node_doc.setdefault('properties', {})
|
||||
|
||||
for prop, schema in node_type.dyn_schema.to_dict().iteritems():
|
||||
for prop, schema in node_type.dyn_schema.to_dict().items():
|
||||
if schema['type'] != 'list':
|
||||
continue
|
||||
|
||||
@ -563,7 +563,7 @@ def redirect_to_context(node_id):
|
||||
|
||||
|
||||
def url_for_node(node_id=None, node=None):
|
||||
assert isinstance(node_id, (basestring, type(None)))
|
||||
assert isinstance(node_id, (str, type(None)))
|
||||
|
||||
api = system_util.pillar_api()
|
||||
|
||||
@ -583,7 +583,7 @@ def url_for_node(node_id=None, node=None):
|
||||
|
||||
|
||||
# Import of custom modules (using the same nodes decorator)
|
||||
import custom.comments
|
||||
import custom.groups
|
||||
import custom.storage
|
||||
import custom.posts
|
||||
from . import custom.comments
|
||||
from . import custom.groups
|
||||
from . import custom.storage
|
||||
from . import custom.posts
|
||||
|
@ -449,7 +449,7 @@ def edit(project_url):
|
||||
url=project.url,
|
||||
summary=project.summary,
|
||||
description=project.description,
|
||||
is_private=u'GET' not in project.permissions.world,
|
||||
is_private='GET' not in project.permissions.world,
|
||||
category=project.category,
|
||||
status=project.status,
|
||||
)
|
||||
@ -471,7 +471,7 @@ def edit(project_url):
|
||||
if form.is_private.data:
|
||||
project.permissions.world = []
|
||||
else:
|
||||
project.permissions.world = [u'GET']
|
||||
project.permissions.world = ['GET']
|
||||
|
||||
project.update(api=api)
|
||||
# Reattach the pictures
|
||||
@ -721,7 +721,7 @@ def project_update_nodes_list(node, project_id=None, list_name='latest'):
|
||||
elif not project_id:
|
||||
return None
|
||||
project_id = node.project
|
||||
if type(project_id) is not unicode:
|
||||
if type(project_id) is not str:
|
||||
project_id = node.project._id
|
||||
api = system_util.pillar_api()
|
||||
project = Project.find(project_id, api=api)
|
||||
|
@ -1,6 +1,6 @@
|
||||
import logging
|
||||
import string
|
||||
import urlparse
|
||||
import urllib.parse
|
||||
|
||||
from flask import Blueprint, redirect, current_app
|
||||
from werkzeug.exceptions import NotFound
|
||||
@ -54,7 +54,7 @@ def redirect_with_short_code(short_code):
|
||||
|
||||
# Redirect to 'theatre' view for the node.
|
||||
url = url_for_node(node=node)
|
||||
url = urlparse.urljoin(url, '?t')
|
||||
url = urllib.parse.urljoin(url, '?t')
|
||||
|
||||
log.debug('Found short code %s, redirecting to %s', short_code, url)
|
||||
return redirect(url, code=307)
|
||||
|
@ -2,7 +2,7 @@ import json
|
||||
import logging
|
||||
import httplib2 # used by the oauth2 package
|
||||
import requests
|
||||
import urlparse
|
||||
import urllib.parse
|
||||
|
||||
from flask import (abort, Blueprint, current_app, flash, redirect,
|
||||
render_template, request, session, url_for)
|
||||
@ -274,15 +274,15 @@ def user_roles_update(user_id):
|
||||
groups = set(user.groups or [])
|
||||
|
||||
if grant_subscriber:
|
||||
roles.add(u'subscriber')
|
||||
roles.add('subscriber')
|
||||
groups.add(group_subscriber._id)
|
||||
elif u'admin' not in roles:
|
||||
elif 'admin' not in roles:
|
||||
# Don't take away roles from admins.
|
||||
roles.discard(u'subscriber')
|
||||
roles.discard('subscriber')
|
||||
groups.discard(group_subscriber._id)
|
||||
|
||||
if grant_demo:
|
||||
roles.add(u'demo')
|
||||
roles.add('demo')
|
||||
groups.add(group_demo._id)
|
||||
|
||||
# Only send an API request when the user has actually changed
|
||||
@ -316,7 +316,7 @@ def fetch_blenderid_user():
|
||||
:rtype: dict
|
||||
"""
|
||||
|
||||
bid_url = urlparse.urljoin(current_app.config['BLENDER_ID_ENDPOINT'], 'api/user')
|
||||
bid_url = urllib.parse.urljoin(current_app.config['BLENDER_ID_ENDPOINT'], 'api/user')
|
||||
log.debug('Fetching user info from %s', bid_url)
|
||||
|
||||
try:
|
||||
|
@ -1,6 +1,6 @@
|
||||
import datetime
|
||||
import hashlib
|
||||
import urllib
|
||||
import urllib.request, urllib.parse, urllib.error
|
||||
import logging
|
||||
import traceback
|
||||
import sys
|
||||
@ -52,7 +52,7 @@ def gravatar(email, size=64):
|
||||
parameters = {'s': str(size), 'd': 'mm'}
|
||||
return "https://www.gravatar.com/avatar/" + \
|
||||
hashlib.md5(str(email)).hexdigest() + \
|
||||
"?" + urllib.urlencode(parameters)
|
||||
"?" + urllib.parse.urlencode(parameters)
|
||||
|
||||
|
||||
def datetime_now():
|
||||
@ -73,7 +73,7 @@ def pretty_date(time, detail=False, now=None):
|
||||
# Normalize the 'time' parameter so it's always a datetime.
|
||||
if type(time) is int:
|
||||
time = datetime.datetime.fromtimestamp(time, tz=pillarsdk.utils.utc)
|
||||
elif isinstance(time, basestring):
|
||||
elif isinstance(time, str):
|
||||
time = dateutil.parser.parse(time)
|
||||
|
||||
now = now or datetime.datetime.now(tz=time.tzinfo)
|
||||
@ -184,10 +184,10 @@ def is_valid_id(some_id):
|
||||
:rtype: bool
|
||||
"""
|
||||
|
||||
if not isinstance(some_id, basestring):
|
||||
if not isinstance(some_id, str):
|
||||
return False
|
||||
|
||||
if isinstance(some_id, unicode):
|
||||
if isinstance(some_id, str):
|
||||
try:
|
||||
some_id = some_id.encode('ascii')
|
||||
except UnicodeEncodeError:
|
||||
|
@ -32,7 +32,7 @@ class CustomFileSelectWidget(HiddenInput):
|
||||
if file_format and file_format == 'image':
|
||||
file_format_regex = '^image\/(gif|jpe?g|png|tif?f|tga)$'
|
||||
|
||||
button = [u'<div class="form-upload-file">']
|
||||
button = ['<div class="form-upload-file">']
|
||||
|
||||
if field.data:
|
||||
api = system_util.pillar_api()
|
||||
@ -42,64 +42,64 @@ class CustomFileSelectWidget(HiddenInput):
|
||||
except ResourceNotFound:
|
||||
pass
|
||||
else:
|
||||
button.append(u'<div class="form-upload-file-meta-container">')
|
||||
button.append('<div class="form-upload-file-meta-container">')
|
||||
|
||||
filename = Markup.escape(file_item.filename)
|
||||
if file_item.content_type.split('/')[0] == 'image':
|
||||
# If a file of type image is available, display the preview
|
||||
button.append(u'<img class="preview-thumbnail" src="{0}" />'.format(
|
||||
button.append('<img class="preview-thumbnail" src="{0}" />'.format(
|
||||
file_item.thumbnail('s', api=api)))
|
||||
|
||||
button.append(u'<ul class="form-upload-file-meta">')
|
||||
button.append('<ul class="form-upload-file-meta">')
|
||||
# File name
|
||||
button.append(u'<li class="name">{0}</li>'.format(filename))
|
||||
button.append('<li class="name">{0}</li>'.format(filename))
|
||||
# File size
|
||||
button.append(u'<li class="size">({0} MB)</li>'.format(
|
||||
button.append('<li class="size">({0} MB)</li>'.format(
|
||||
round((file_item.length / 1024) * 0.001, 2)))
|
||||
# Image resolution (if image)
|
||||
if file_item.content_type.split('/')[0] == 'image':
|
||||
button.append(u'<li class="dimensions">{0}x{1}</li>'.format(
|
||||
button.append('<li class="dimensions">{0}x{1}</li>'.format(
|
||||
file_item.width, file_item.height))
|
||||
button.append(u'</ul>')
|
||||
button.append(u'<ul class="form-upload-file-actions">')
|
||||
button.append('</ul>')
|
||||
button.append('<ul class="form-upload-file-actions">')
|
||||
# Download button for original file
|
||||
button.append(u'<li class="original">'
|
||||
u'<a href="{}" class="file_original"> '
|
||||
u'<i class="pi-download"></i>Original</a></li>'
|
||||
button.append('<li class="original">'
|
||||
'<a href="{}" class="file_original"> '
|
||||
'<i class="pi-download"></i>Original</a></li>'
|
||||
.format(file_item.link))
|
||||
# Delete button
|
||||
button.append(u'<li class="delete">'
|
||||
u'<a href="#" class="file_delete" '
|
||||
u'data-field-name="{field_name}" '
|
||||
u'data-file_id="{file_id}"> '
|
||||
u'<i class="pi-trash"></i> Delete</a></li>'.format(
|
||||
button.append('<li class="delete">'
|
||||
'<a href="#" class="file_delete" '
|
||||
'data-field-name="{field_name}" '
|
||||
'data-file_id="{file_id}"> '
|
||||
'<i class="pi-trash"></i> Delete</a></li>'.format(
|
||||
field_name=field.name, file_id=field.data))
|
||||
button.append(u'</ul>')
|
||||
button.append(u'</div>')
|
||||
button.append('</ul>')
|
||||
button.append('</div>')
|
||||
|
||||
upload_url = u'%sstorage/stream/{project_id}' % current_app.config[
|
||||
upload_url = '%sstorage/stream/{project_id}' % current_app.config[
|
||||
'PILLAR_SERVER_ENDPOINT']
|
||||
|
||||
button.append(u'<input class="fileupload" type="file" name="file" '
|
||||
u'data-url="{url}" '
|
||||
u'data-field-name="{name}" '
|
||||
u'data-field-slug="{slug}" '
|
||||
u'data-token="{token}" '
|
||||
u'data-file-format="{file_format}">'
|
||||
u'<div class="form-upload-progress"> '
|
||||
u'<div class="form-upload-progress-bar" role="progressbar" '
|
||||
u'aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" '
|
||||
u'style="width: 0%;"> '
|
||||
u'</div> '
|
||||
u'</div>'.format(url=upload_url,
|
||||
button.append('<input class="fileupload" type="file" name="file" '
|
||||
'data-url="{url}" '
|
||||
'data-field-name="{name}" '
|
||||
'data-field-slug="{slug}" '
|
||||
'data-token="{token}" '
|
||||
'data-file-format="{file_format}">'
|
||||
'<div class="form-upload-progress"> '
|
||||
'<div class="form-upload-progress-bar" role="progressbar" '
|
||||
'aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" '
|
||||
'style="width: 0%;"> '
|
||||
'</div> '
|
||||
'</div>'.format(url=upload_url,
|
||||
name=field.name,
|
||||
slug=field.name.replace('oid', 'slug'),
|
||||
token=Markup.escape(current_user.id),
|
||||
file_format=Markup.escape(file_format_regex)))
|
||||
|
||||
button.append(u'</div>')
|
||||
button.append('</div>')
|
||||
|
||||
return HTMLString(html + u''.join(button))
|
||||
return HTMLString(html + ''.join(button))
|
||||
|
||||
|
||||
class FileSelectField(StringField):
|
||||
@ -112,7 +112,7 @@ def build_file_select_form(schema):
|
||||
class FileSelectForm(Form):
|
||||
pass
|
||||
|
||||
for field_name, field_schema in schema.iteritems():
|
||||
for field_name, field_schema in schema.items():
|
||||
if field_schema['type'] == 'boolean':
|
||||
field = BooleanField()
|
||||
elif field_schema['type'] == 'string':
|
||||
@ -142,19 +142,19 @@ class CustomFormFieldWidget(object):
|
||||
def __call__(self, field, **kwargs):
|
||||
html = []
|
||||
kwargs.setdefault('id', field.id)
|
||||
html.append(u'<div %s>' % html_params(**kwargs))
|
||||
hidden = u''
|
||||
html.append('<div %s>' % html_params(**kwargs))
|
||||
hidden = ''
|
||||
for subfield in field:
|
||||
if subfield.type == 'HiddenField':
|
||||
hidden += text_type(subfield)
|
||||
else:
|
||||
html.append(u'<div><span>%s</span>%s%s</div>' % (
|
||||
html.append('<div><span>%s</span>%s%s</div>' % (
|
||||
text_type(subfield.label), hidden, text_type(subfield)))
|
||||
hidden = u''
|
||||
html.append(u'</div>')
|
||||
hidden = ''
|
||||
html.append('</div>')
|
||||
if hidden:
|
||||
html.append(hidden)
|
||||
return HTMLString(u''.join(html))
|
||||
return HTMLString(''.join(html))
|
||||
|
||||
|
||||
class CustomFormField(FormField):
|
||||
|
Loading…
x
Reference in New Issue
Block a user