def open_datarequest(id): data_dict = {'id': id} context = _get_context() # Basic initialization c.datarequest = {} try: check_access(OPEN_DATAREQUEST, context, data_dict) c.datarequest = get_action(SHOW_DATAREQUEST)(context, data_dict) if c.datarequest.get('closed', False) is False: return abort(403, _('This data request is already open')) else: data_dict = {} data_dict['id'] = id data_dict['organization_id'] = c.datarequest.get('organization_id') get_action(OPEN_DATAREQUEST)(context, data_dict) return redirect_to(url_for('datarequest.show', id=data_dict['id'])) except ValidationError as e: log.warn(e) errors_summary = _get_errors_summary(e.error_dict) return abort(403, errors_summary) except ObjectNotFound as e: log.warn(e) return abort(404, _('Data Request %s not found') % id) except NotAuthorized as e: log.warn(e) return abort( 403, _('You are not authorized to open the Data Request %s' % id))
def validator(key, data, errors, context): # if there was an error before calling our validator # don't bother with our validation if errors[key]: return value = data[key] if value is not missing: if isinstance(value, basestring): value = [value] elif not isinstance(value, list): errors[key].append(_('expecting list of strings')) return else: value = [] choice_values = static_choice_values if not choice_values: choice_order = [c['value'] for c in sh.scheming_field_choices(field)] choice_values = set(choice_order) selected = set() for element in value: if element in choice_values: selected.add(element) continue errors[key].append(_('unexpected choice "%s"') % element) if not errors[key]: data[key] = json.dumps([v for v in (static_choice_order if static_choice_values else choice_order) if v in selected]) if field.get('required') and not selected: errors[key].append(_('Select at least one'))
def scheming_valid_json_object(value, context): """Store a JSON object as a serialized JSON string It accepts two types of inputs: 1. A valid serialized JSON string (it must be an object or a list) 2. An object that can be serialized to JSON """ if not value: return elif isinstance(value, six.string_types): try: loaded = json.loads(value) if not isinstance(loaded, dict): raise Invalid( _('Unsupported value for JSON field: {}').format(value) ) return value except (ValueError, TypeError) as e: raise Invalid(_('Invalid JSON string: {}').format(e)) elif isinstance(value, dict): try: return json.dumps(value) except (ValueError, TypeError) as e: raise Invalid(_('Invalid JSON object: {}').format(e)) else: raise Invalid( _('Unsupported type for JSON field: {}').format(type(value)) )
def validate_date_inputs(field, key, data, extras, errors, context): date_error = _('Date format incorrect') time_error = _('Time format incorrect') date = None def get_input(suffix): inpt = key[0] + '_' + suffix new_key = (inpt,) + tuple(x for x in key if x != key[0]) value = extras.get(inpt) data[new_key] = value errors[new_key] = [] if value: del extras[inpt] if field.get('required'): not_empty(new_key, data, errors, context) return (new_key, value) date_key, value = get_input('date') value_full = '' if value: try: value_full = value date = h.date_str_to_datetime(value) except (TypeError, ValueError), e: errors[date_key].append(date_error)
def get_validation_badge(resource, in_listing=False): if in_listing and not asbool( config.get('ckanext.validation.show_badges_in_listings', True)): return '' if not resource.get('validation_status'): return '' messages = { 'success': _('Valid data'), 'failure': _('Invalid data'), 'error': _('Error during validation'), 'unknown': _('Data validation unknown'), } if resource['validation_status'] in ['success', 'failure', 'error']: status = resource['validation_status'] else: status = 'unknown' validation_url = url_for('validation_read', id=resource['package_id'], resource_id=resource['id']) badge_url = url_for_static( '/images/badges/data-{}-flat.svg'.format(status)) return u''' <a href="{validation_url}" class="validation-badge"> <img src="{badge_url}" alt="{alt}" title="{title}"/> </a>'''.format(validation_url=validation_url, badge_url=badge_url, alt=messages[status], title=resource.get('validation_timestamp', ''))
def scheming_valid_json_object(value, context): """Store a JSON object as a serialized JSON string It accepts two types of inputs: 1. A valid serialized JSON string (it must be an object or a list) 2. An object that can be serialized to JSON """ if not value: return elif isinstance(value, basestring): try: loaded = json.loads(value) if not isinstance(loaded, dict): raise Invalid( _('Unsupported value for JSON field: {}').format(value) ) return value except (ValueError, TypeError) as e: raise Invalid(_('Invalid JSON string: {}').format(e)) elif isinstance(value, dict): try: return json.dumps(value) except (ValueError, TypeError) as e: raise Invalid(_('Invalid JSON object: {}').format(e)) else: raise Invalid( _('Unsupported type for JSON field: {}').format(type(value)) ) return value
def validate_date_inputs(field, key, data, extras, errors, context): date_error = _('Date format incorrect') time_error = _('Time format incorrect') date = None def get_input(suffix): inpt = key[0] + '_' + suffix new_key = (inpt, ) + tuple(x for x in key if x != key[0]) value = extras.get(inpt) data[new_key] = value errors[new_key] = [] if value: del extras[inpt] if field.get('required'): not_empty(new_key, data, errors, context) return (new_key, value) date_key, value = get_input('date') value_full = '' if value: try: value_full = value date = h.date_str_to_datetime(value) except (TypeError, ValueError), e: errors[date_key].append(date_error)
def validator(key, data, errors, context): if errors[key]: return model = context['model'] session = context['session'] package = context.get('package') query = session.query(model.Package.state).filter_by(title=data[key]) if package: package_id = package.id else: package_id = data.get(key[:-1] + ('id',)) if package_id and package_id is not missing: query = query.filter(model.Package.id != package_id) result = query.first() if result and result.state != 'DELETED': errors[key].append(_('That Title is already in use.')) value = data[key] if len(value) < PACKAGE_NAME_MIN_LENGTH: raise Invalid( _('Title "%s" length is less than minimum %s') % (value, PACKAGE_NAME_MIN_LENGTH) ) if len(value) > PACKAGE_NAME_MAX_LENGTH: raise Invalid( _('Title "%s" length is more than maximum %s') % (value, PACKAGE_NAME_MAX_LENGTH) )
def validator(key, data, errors, context): # if there was an error before calling our validator # don't bother with our validation if errors[key]: return value = data[key] if value is not missing: if isinstance(value, basestring): value = [value] elif not isinstance(value, list): errors[key].append(_('expecting list of strings')) return else: value = [] selected = set() for element in value: if element in choice_values: selected.add(element) continue errors[key].append(_('unexpected choice "%s"') % element) if not errors[key]: data[key] = json.dumps([ c['value'] for c in field['choices'] if c['value'] in selected ]) if field.get('required') and not selected: errors[key].append(_('Select at least one'))
def refresh_view(id): try: context = {'model': model, 'user': tk.c.user, 'session': model.Session} tk.get_action('harvest_job_create')(context, { 'source_id': id, 'run': True }) h.flash_success( _('Harvest will start shortly. Refresh this page for updates.')) except tk.ObjectNotFound: return tk.abort(404, _('Harvest source not found')) except tk.NotAuthorized: return tk.abort(401, _not_auth_message()) except HarvestSourceInactiveError: h.flash_error( _('Cannot create new harvest jobs on inactive ' 'sources. First, please change the source status ' 'to "active".')) except HarvestJobExists: h.flash_notice( _('A harvest job has already been scheduled for ' 'this source')) except Exception as e: msg = 'An error occurred: [%s]' % str(e) h.flash_error(msg) return h.redirect_to( h.url_for('{0}_admin'.format(DATASET_TYPE_NAME), id=id))
def powerview_id_exists(value, context): session = context['session'] result = session.query(PowerView).get(value) if not result: raise Invalid('%s: %s' % (_('Not found'), _('PowerView'))) return value
def resource_download(package_type, id, resource_id, filename=None): ''' Provide a download by either redirecting the user to the url stored or downloading the uploaded file from S3. ''' context = { 'model': model, 'session': model.Session, 'user': c.user or c.author, 'auth_user_obj': c.userobj } try: rsc = get_action('resource_show')(context, {'id': resource_id}) get_action('package_show')(context, {'id': id}) except NotFound: return abort(404, _('Resource not found')) except NotAuthorized: return abort(401, _('Unauthorized to read resource %s') % id) if 'url' not in rsc: return abort(404, _('No download is available')) elif rsc.get('url_type') == 'upload': upload = uploader.get_resource_uploader(rsc) bucket_name = ckan_config.get('ckanext.s3filestore.aws_bucket_name') if filename is None: filename = os.path.basename(rsc['url']) key_path = upload.get_path(rsc['id'], filename) if filename is None: log.warn("Key '%s' not found in bucket '%s'", key_path, bucket_name) try: url = upload.get_signed_url_to_key(key_path) return redirect(url) except ClientError as ex: if ex.response['Error']['Code'] in ['NoSuchKey', '404']: # attempt fallback if ckan_config.get( 'ckanext.s3filestore.filesystem_download_fallback', False): log.info('Attempting filesystem fallback for resource %s', resource_id) url = toolkit.url_for( u's3_resource.filesystem_resource_download', id=id, resource_id=resource_id, filename=filename) return redirect(url) return abort(404, _('Resource data not found')) else: raise ex # if we're trying to download a link resource, just redirect to it return redirect(rsc['url'])
def validate_date_inputs(field, key, data, extras, errors, context): date_error = _('Date format incorrect') time_error = _('Time format incorrect') date = None def get_input(suffix): inpt = key[0] + '_' + suffix new_key = (inpt,) + tuple(x for x in key if x != key[0]) key_value = extras.get(inpt) data[new_key] = key_value errors[new_key] = [] if key_value: del extras[inpt] if field.get('required'): not_empty(new_key, data, errors, context) return new_key, key_value date_key, value = get_input('date') value_full = '' if value: try: value_full = value date = h.date_str_to_datetime(value) except (TypeError, ValueError) as e: errors[date_key].append(date_error) time_key, value = get_input('time') if value: if not value_full: errors[date_key].append( _('Date is required when a time is provided')) else: try: value_full += ' ' + value date = h.date_str_to_datetime(value_full) except (TypeError, ValueError) as e: errors[time_key].append(time_error) tz_key, value = get_input('tz') if value: if value not in pytz.all_timezones: errors[tz_key].append('Invalid timezone') else: if isinstance(date, datetime.datetime): date = pytz.timezone(value).localize(date) return date
def validator(key, data, errors, context): value = data[key] date_error = _('Date format incorrect') time_error = _('Time format incorrect') date = None if isinstance(value, datetime.datetime): return value if value is not missing: try: date = h.date_str_to_datetime(value) except (TypeError, ValueError), e: raise Invalid(date_error)
def cioos_get_facets(package_type='dataset'): ''' get all dataset for the given package type, including private ones. This function works similarly to code found in ckan/ckan/controllers/package.py in that it does a search of all datasets and populates the following globals for later use: c.facet_titles c.search_facets ''' facets = OrderedDict() default_facet_titles = { 'organization': _('Organizations'), 'groups': _('Groups'), 'tags': _('Tags'), 'res_format': _('Formats'), 'license_id': _('Licenses'), } for facet in toolkit.h.facets(): if facet in default_facet_titles: facets[facet] = default_facet_titles[facet] else: facets[facet] = facet # Facet titles for plugin in p.PluginImplementations(p.IFacets): facets = plugin.dataset_facets(facets, package_type) c.facet_titles = facets data_dict = { 'facet.field': list(facets.keys()), 'rows': 0, 'include_private': toolkit.asbool(config.get('ckan.search.default_include_private', True)), } context = { 'model': model, 'session': model.Session, 'user': c.user, 'for_view': True, 'auth_user_obj': c.userobj } query = get_action('package_search')(context, data_dict) c.search_facets = query['search_facets']
def render_datacite_xml(id): context = {'model': model, 'session': model.Session, 'user': g.user, 'for_view': True, 'auth_user_obj': g.userobj} data_dict = {'id': id} try: toolkit.check_access('package_update', context, data_dict) except toolkit.ObjectNotFound: toolkit.abort(404, _('Dataset not found')) except toolkit.NotAuthorized: toolkit.abort(403, _('User %r not authorized to view datacite xml for %s') % (g.user, id)) pkg = toolkit.get_action('package_show')(data_dict={'id': id}) return toolkit.render('package/datacite.html', extra_vars={'pkg_dict': pkg})
def clear_view(id): try: context = {'model': model, 'user': tk.c.user, 'session': model.Session} tk.get_action('harvest_source_clear')(context, {'id': id}) h.flash_success(_('Harvest source cleared')) except tk.ObjectNotFound: return tk.abort(404, _('Harvest source not found')) except tk.NotAuthorized: return tk.abort(401, _not_auth_message()) except Exception as e: msg = 'An error occurred: [%s]' % str(e) h.flash_error(msg) return h.redirect_to( h.url_for('{0}_admin'.format(DATASET_TYPE_NAME), id=id))
def validator(value): if value != '': # only run validator if value was entered if field['field_name'] == 'latitude': if float(value) < -90.0 or float(value) > 90.0: raise Invalid( _('Invalid latitude coordinates. Must be between the values of -90.0 and 90.0 inclusive.' )) elif field['field_name'] == 'longitude': if float(value) < -180.0 or float(value) > 180.0: raise Invalid( _('Invalid longitude coordinates. Must be between the values of -180.0 and 180.0 inclusive.' )) else: raise Invalid(_('Invalid field_name')) return value
def filesystem_resource_download(package_type, id, resource_id, filename=None): """ A fallback view action to download resources from the filesystem. A copy of the action from `ckan.views.resource:download`. Provide a direct download by either redirecting the user to the url stored or downloading an uploaded file directly. """ context = { u'model': model, u'session': model.Session, u'user': g.user, u'auth_user_obj': g.userobj } preview = request.args.get(u'preview', False) try: rsc = get_action(u'resource_show')(context, {u'id': resource_id}) get_action(u'package_show')(context, {u'id': id}) except NotFound: return abort(404, _(u'Resource not found')) except NotAuthorized: return abort(401, _('Unauthorised to read resource %s') % resource_id) mimetype, enc = mimetypes.guess_type(rsc.get('url', '')) if rsc.get(u'url_type') == u'upload': if hasattr(DefaultResourceUpload, 'download'): upload = DefaultResourceUpload(rsc) try: return upload.download(rsc['id'], filename) except OSError: # includes FileNotFoundError return abort(404, _('Resource data not found')) path = get_storage_path() storage_path = os.path.join(path, 'resources') directory = os.path.join(storage_path, resource_id[0:3], resource_id[3:6]) filepath = os.path.join(directory, resource_id[6:]) if preview: return flask.send_file(filepath, mimetype=mimetype) else: return flask.send_file(filepath) elif u'url' not in rsc: return abort(404, _(u'No download is available')) return redirect(rsc[u'url'])
def composite_not_empty_subfield(key, subfield_label, value, errors): ''' Function equivalent to ckan.lib.navl.validators.not_empty but for subfields (custom message including subfield) ''' if not value or value is missing: errors[key].append(_('Missing value at required subfield ' + subfield_label)) raise StopOnError
def info(self): return {'name': 'wmts_view', 'title': 'wmts', 'icon': 'map-marker', 'iframed': True, 'default_title': toolkit._('WMTS'), }
def info(self): return {'name': 'geojson_view', 'title': 'GeoJSON', 'icon': 'map-marker', 'iframed': True, 'default_title': toolkit._('GeoJSON'), }
def job_list_view(source): try: context = {'model': model, 'user': tk.c.user} harvest_source = tk.get_action('harvest_source_show')(context, { 'id': source }) jobs = tk.get_action('harvest_job_list')( context, { 'source_id': harvest_source['id'] }) return tk.render( 'source/job/list.html', extra_vars={ 'harvest_source': harvest_source, 'jobs': jobs }, ) except tk.ObjectNotFound: return tk.abort(404, _('Harvest source not found')) except tk.NotAuthorized: return tk.abort(401, _not_auth_message()) except Exception as e: msg = 'An error occurred: [%s]' % str(e) return tk.abort(500, msg)
def update(context, data_dict): '''Update a PowerView. By default, only sysadmins can update PowerViews. But the setting `ckanext.powerview.allow_user_create` allows any logged in user to update powerviews they own. ''' if not toolkit.asbool(config.get('ckanext.powerview.allow_user_create', False)): return {'success': False} else: user = context.get('user') user_obj = model.User.get(user) powerview = PowerView.get(id=data_dict['id']) # Check resources for res_id in data_dict.get('resources', []): try: toolkit.check_access('resource_show', context, data_dict={'id': res_id}) except NotAuthorized: return { 'success': False, 'msg': _('User {0} not authorized to read resource {1}' .format(user, res_id)) } if powerview and user and powerview.created_by == user_obj.id: return {'success': True} return {'success': False}
def create(context, data_dict): '''Create a PowerView. By default, only sysadmins can create a PowerView. But the setting `ckanext.powerview.allow_user_create` allows any logged in user to create powerviews. ''' allow_user_create = toolkit.asbool( config.get('ckanext.powerview.allow_user_create', False)) if not allow_user_create: return {'success': False} user = context.get('user') # Check resources for res_id in data_dict.get('resources', []): try: toolkit.check_access('resource_show', context, data_dict={'id': res_id}) except NotAuthorized: return { 'success': False, 'msg': _('User {0} not authorized to read resource {1}' .format(user, res_id)) } return {'success': True}
def job_show_view(id, source_dict=False, is_last=False): try: context = {'model': model, 'user': tk.c.user} job = tk.get_action('harvest_job_show')(context, {'id': id}) job_report = tk.get_action('harvest_job_report')(context, {'id': id}) if not source_dict: source_dict = tk.get_action('harvest_source_show')( context, { 'id': job['source_id'] }) return tk.render( 'source/job/read.html', extra_vars={ 'harvest_source': source_dict, 'job': job, 'job_report': job_report, 'is_last_job': is_last, }, ) except tk.ObjectNotFound: return tk.abort(404, _('Harvest job not found')) except tk.NotAuthorized: return tk.abort(401, _not_auth_message()) except Exception as e: msg = 'An error occurred: [%s]' % str(e) return tk.abort(500, msg)
def longitude_validator(key, data, errors, context): """Checks if the given longitude value is a valid negative float number.""" value = _float_validator(key, data, errors, context) if not value or value > 0.0: raise Invalid(_('Longitude requires a negative number. Found "%s"') % value)
def validator(key, data, errors, context): value = data[key] date = None if value: if isinstance(value, datetime.datetime): date = sh.scheming_datetime_to_utc(value) else: try: date = sh.date_tz_str_to_datetime(value) except (TypeError, ValueError) as e: raise Invalid(_('Date format incorrect')) else: extras = data.get(('__extras',)) if not extras or (key[0] + '_date' not in extras and key[0] + '_time' not in extras): if field.get('required'): not_empty(key, data, errors, context) else: date = validate_date_inputs( field, key, data, extras, errors, context) if isinstance(date, datetime.datetime): date = sh.scheming_datetime_to_utc(date) data[key] = date
def object_show_view(id, ref_type, response): try: context = {'model': model, 'user': tk.c.user} if ref_type == 'object': obj = tk.get_action('harvest_object_show')(context, {'id': id}) elif ref_type == 'dataset': obj = tk.get_action('harvest_object_show')(context, { 'dataset_id': id }) # Check content type. It will probably be either XML or JSON try: if obj['content']: content = obj['content'] elif 'original_document' in obj['extras']: content = obj['extras']['original_document'] else: return tk.abort(404, _('No content found')) try: etree.fromstring(re.sub(r'<\?xml(.*)\?>', '', content)) except UnicodeEncodeError: etree.fromstring( re.sub(r'<\?xml(.*)\?>', '', content.encode('utf-8'))) response.content_type = 'application/xml; charset=utf-8' if '<?xml' not in content.split('\n')[0]: content = u'<?xml version="1.0" encoding="UTF-8"?>\n' + content except xml_parser_exception: try: json.loads(obj['content']) response.content_type = 'application/json; charset=utf-8' except ValueError: # Just return whatever it is pass response.headers['Content-Length'] = len(content) return (response, six.ensure_str(content)) except tk.ObjectNotFound as e: return tk.abort(404, _(str(e))) except tk.NotAuthorized: return tk.abort(401, _not_auth_message()) except Exception as e: msg = 'An error occurred: [%s]' % str(e) return tk.abort(500, msg)
def validator(value): if value is missing or not value: return value choices = sh.scheming_field_choices(field) for c in choices: if value == c['value']: return value raise Invalid(_('unexpected choice "%s"') % value)
def info(self): return { "name": "geojson_view", "title": "GeoJSON", "icon": "map-marker", "iframed": True, "default_title": toolkit._("GeoJSON"), }
def show(context, data_dict): ''' Checks access to both the powerview, and its contained resources. If the user can view the powerview, but can't view one of its resources, they won't have access to the powerview. ''' powerview = PowerView.get(id=data_dict['id']) if not powerview: return {'success': False} powerview = powerview.as_dict() user = context.get('user') # Check resources first for res_id in powerview['resources']: try: toolkit.check_access('resource_show', context, data_dict={'id': res_id}) except NotAuthorized: return { 'success': False, 'msg': _('User {0} not authorized to read resource {1}' .format(user, res_id)) } # Resource check okay, so is powerview public? if not powerview['private']: return {'success': True} elif user: # Private powerview, so check user has permission user_obj = model.User.get(user) authorized = user_has_permission_for_powerview(user_obj, powerview) if authorized: return {'success': True} else: return { 'success': False, 'msg': _('User {0} not authorized to read powerview {1}' .format(user, powerview['id']))} # powerview is private and there's no user return {'success': False}
def info(self): return { "name": "wmts_view", "title": "wmts", "icon": "map-marker", "iframed": True, "default_title": toolkit._("WMTS"), }
def job_abort_view(source, id): try: context = {'model': model, 'user': tk.c.user} tk.get_action('harvest_job_abort')(context, {'id': id}) h.flash_success(_('Harvest job stopped')) except tk.ObjectNotFound: return tk.abort(404, _('Harvest job not found')) except tk.NotAuthorized: return tk.abort(401, _not_auth_message()) except Exception as e: msg = 'An error occurred: [%s]' % str(e) return tk.abort(500, msg) return h.redirect_to( h.url_for('{0}_admin'.format(DATASET_TYPE_NAME), id=source))
def info(self): return { 'name': 'geojson_view', 'title': 'GeoJSON', 'icon': 'map-marker', 'iframed': True, 'default_title': toolkit._('GeoJSON'), }
def info(self): return { 'name': 'wmts_view', 'title': 'wmts', 'icon': 'map-marker', 'iframed': True, 'default_title': toolkit._('WMTS'), }
def has_user_permission_for_some_org(context, data_dict): user = context.get('user', '') permission = data_dict.get('permission', '') if authz.has_user_permission_for_some_org(user, permission): return {'success': True} else: return {'success': False, 'msg': _('User {0} has no {1} permission for any organisation'.format(user, permission))}
def validator(value): if value is missing or not value: return value choices = sh.scheming_field_choices(field) for c in choices: # We want the value check to be case insensitive if value.upper() == c['value'].upper(): return value raise Invalid(_('unexpected choice "%s"') % value)
def has_user_permission_for_org(context, data_dict): user = context.get('user', '') org_id = data_dict.get('org_id', '') permission = data_dict.get('permission', '') if authz.has_user_permission_for_group_or_org(org_id, user, permission): return {'success': True} else: return {'success': False, 'msg': _('User {0} is not authorized to {1} for organisation {2}'.format(user, permission, org_id))}
def resource_ids_in_list(value, context): '''Validate resource id list.''' # value must be a list if not isinstance(value, list): raise Invalid(_('Not a list')) # remove duplicates value = list(set(value)) for i in value: # item must be a string if not isinstance(i, basestring): raise Invalid('%s: %s' % (_('Not a string'), i)) # item must be a resource id that exists resource_id_exists(i, context) return value
def info(self): return {'name': 'geo_view', 'title': 'Map viewer (OpenLayers)', 'icon': 'globe', 'iframed': True, 'default_title': toolkit._('Map viewer'), 'schema': { 'feature_hoveron': [ignore_empty, boolean_validator], 'feature_style': [ignore_empty] }, }
def validator(key, data, errors, context): value = data[key] date = None if value: if isinstance(value, datetime.datetime): date = sh.scheming_datetime_to_UTC(value) else: try: date = sh.date_tz_str_to_datetime(value) except (TypeError, ValueError), e: raise Invalid(_('Date format incorrect'))
def scheming_language_text(text, prefer_lang=None): """ :param text: {lang: text} dict or text string :param prefer_lang: choose this language version if available Convert "language-text" to users' language by looking up languag in dict or using gettext if not a dict """ if not text: return u'' assert text != {} if hasattr(text, 'get'): try: if prefer_lang is None: prefer_lang = lang() except TypeError: pass # lang() call will fail when no user language available else: try: return text[prefer_lang] except KeyError: pass default_locale = config.get('ckan.locale_default', 'en') try: return text[default_locale] except KeyError: pass l, v = sorted(text.items())[0] return v if isinstance(text, str): text = text.decode('utf-8') t = _(text) return t
return (new_key, value) date_key, value = get_input('date') value_full = '' if value != '': try: value_full = value date = h.date_str_to_datetime(value) except (TypeError, ValueError), e: return errors[date_key].append(date_error) time_key, value = get_input('time') if value != '': if value_full == '': return errors[date_key].append(_('Date is required when a time is provided')) try: value_full += ' ' + value date = h.date_str_to_datetime(value_full) except (TypeError, ValueError), e: return errors[time_key].append(time_error) data[key] = date return validator def scheming_multiple_choice_output(value): """ return stored json as a proper list """
date_key, value = get_input('date') value_full = '' if value: try: value_full = value date = h.date_str_to_datetime(value) except (TypeError, ValueError), e: errors[date_key].append(date_error) time_key, value = get_input('time') if value: if not value_full: errors[date_key].append( _('Date is required when a time is provided')) else: try: value_full += ' ' + value date = h.date_str_to_datetime(value_full) except (TypeError, ValueError), e: errors[time_key].append(time_error) tz_key, value = get_input('tz') if value: if value not in pytz.all_timezones: errors[tz_key].append('Invalid timezone') else: if isinstance(date, datetime.datetime): date = pytz.timezone(value).localize(date)