def get_deploy_context(): from cubane.media.models import Media image_sizes = {} image_sizes['xxx_large'] = 2400 image_sizes['xx_large'] = 1600 for image in settings.IMAGE_SIZES: name = image.replace('-', '_') image_sizes[name] = settings.IMAGE_SIZES[image] disable_device_ratio = 'true' if settings.DISABLE_DEVICE_RATIO else 'false' shapes = Media.get_shape_list() image_art_direction = Media.get_art_direction() # generate list of choke-points image_size_list = [ image_sizes.get('xxx_large'), image_sizes.get('xx_large'), image_sizes.get('x_large'), image_sizes.get('large'), image_sizes.get('medium'), image_sizes.get('small'), image_sizes.get('x_small'), image_sizes.get('xx_small'), image_sizes.get('xxx_small') ] # names of image shapes image_size_names = [ 'xxx-large', 'xx-large', 'x-large', 'large', 'medium', 'small', 'x-small', 'xx-small', 'xxx-small' ] # list of aspect ratios poer shape aspect_ratio_by_shape = dict([(shape.get('name'), shape.get('ratio_percent')) for shape in shapes]) return { 'image_sizes': image_sizes, 'disable_device_ratio': disable_device_ratio, 'shapes': shapes, 'MEDIA_URL': settings.MEDIA_URL, 'MEDIA_API_URL': settings.MEDIA_API_URL, 'image_art_direction': image_art_direction, 'image_art_direction_json': to_json(image_art_direction), 'image_size_list_json': to_json(image_size_list), 'image_size_names_json': to_json(image_size_names), 'aspect_ratio_by_shape': to_json(aspect_ratio_by_shape) }
def test_encode_model_with_model_as_member(self): m = self._create_object(1, 'Foo') s = to_json(m, fields=['id', 'parent_model', 'title']) self.assertEqual( s, '{"parent_model":{"updated_by":null,"seq":0,"title":"Bar","text":null,"image":null,"created_by":null,"deleted_on":null,"created_on":null,"updated_on":null,"deleted_by":null,"id":null},"id":1,"title":"Foo"}' )
def test_encode_model_instance_should_be_object_literal(self): m = self._create_object(123, 'Foo', save=False) s = to_json(m) self.assertEqual(s, '{"updated_by":null,"seq":0,"title":"Foo","text":null,"image":null,"created_by":null,' + \ '"deleted_on":null,"created_on":null,"updated_on":null,' + \ '"deleted_by":null,"id":123}' )
def test_encode_raw_queryset_should_be_list_of_object_literals(self): m1 = self._create_object(1, 'Foo') m2 = self._create_object(2, 'Bar') m = TestModel.objects.raw('select * from testapp_testmodel') s = to_json(m, fields=['id', 'title']) self.assertEqual(s, '[{"id":1,"title":"Foo"},{"id":2,"title":"Bar"}]') m1.delete() m2.delete()
def test_encode_list_of_models_should_be_list_of_object_literals(self): m1 = self._create_object(1, 'Foo') m2 = self._create_object(2, 'Bar') m = list(TestModel.objects.order_by('id')) s = to_json(m, fields=['id', 'title']) self.assertEqual(s, '[{"id":1,"title":"Foo"},{"id":2,"title":"Bar"}]') m1.delete() m2.delete()
def set_dashboard(self, v): """ Set dashboard information for the current user. """ if v: self.dashboard_json = to_json(v) else: self.dashboard_json = None self.invalidate_dashboard_cache()
def render(self, context): json = to_json(get_url_patterns(get_resolver(None).url_patterns)) script = \ "<script>" + \ "(function(g){" + \ "if(!('cubane' in g))g.cubane = {};" + \ "if(!('urls' in g.cubane))g.cubane.urls = {};" + \ "g.cubane.urls.patterns = " + json + ";" + \ "}(this));" + \ "</script>" return mark_safe(script);
def _report_status(self): """ Write status to status file. """ file_put_contents( os.path.join(settings.PUBLIC_HTML_ROOT, self.STATUS_FILENAME), to_json({ 'totalRecords': self._total_records, 'recordCounter': self._record_counter, 'message': self._message, 'stopped': self._stopped }))
def variety_option_ids(self): """ Return a list of all possible variety combinations that is used by javascript on the front-end in order to determine valid combinations while choosing variety options. """ from cubane.ishop.templatetags.shop_tags import get_shop_price result = [] for combination in self._combinations: price = combination.get('sku').price if not price: price = self._product.price result.append({ 'ids': combination.get('ids'), 'price': { 'value': price, 'display': get_shop_price(price) } }) return to_json(result)
def test_encode_dict_should_be_object_literal(self): s = to_json({'a': 'X', 'b': 'Y'}) self.assertEqual(s, '{"a":"X","b":"Y"}')
def test_encode_list_should_be_list(self): s = to_json(['a', 'b', 'c']) self.assertEqual(s, '["a","b","c"]')
def test_encode_timedelta_should_be_string_in_correct_timedelta_format( self): s = to_json(timedelta(days=1)) self.assertEqual(s, '"1 day, 0:00:00"')
def test_encode_date_should_be_string_in_correct_date_format(self): s = to_json(date(2041, 5, 3)) self.assertEqual(s, '"2041-05-03"')
def test_encode_datetime_should_be_string_in_correct_datetime_format(self): s = to_json(datetime(2041, 5, 3, 14, 16, 55)) self.assertEqual(s, '"2041-05-03 14:16:55"')
def test_encode_model_with_incorrect_fields(self): m = self._create_object(1, 'Foo') s = to_json(m, fields='bar') self.assertEqual(s, '{}')
def test_encode_model_instance_with_fields_should_only_encode_given_fields( self): m = self._create_object(123, 'Foo', save=False) s = to_json(m, fields=['id', 'title']) self.assertEqual(s, '{"id":123,"title":"Foo"}')
def test_encode_int_should_be_number(self): s = to_json(34) self.assertEqual(s, '34')
def test_encode_model_attribute_path(self): m = self._create_object(1, 'foo') s = to_json(m, fields=['id', '_meta.verbose_name']) self.assertEqual(s, '{"_meta.verbose_name":"Test Model","id":1}')
def sku(self, request): # get product product_id = request.GET.get('pk') product = get_object_or_404(get_product_model(), pk=product_id) # get varieties _varieties = Variety.objects.prefetch_related( Prefetch('options', queryset=VarietyOption.objects.order_by('title')) ).filter(sku=True).exclude(options=None).exclude( style=Variety.STYLE_ATTRIBUTE).order_by('title').distinct() skus = ProductSKU.objects.filter(product=product) assigned_option_ids = [ a.variety_option.id for a in VarietyAssignment.objects.select_related('variety_option') .filter(product=product, variety_option__variety__sku=True) ] # initial dataset currently present initial = {} for sku in skus: initial[sku.pk] = sku initial[sku.pk].errors = [] # determine barcode system cms_settings = get_cms_settings() barcode_system = cms_settings.get_barcode_system(product) # create template form form_template = ProductSKUForm() form_template.configure(request, barcode_system) def has_var(prefix, name): return 'f-%s-%s' % (prefix, name) in request.POST def get_var(prefix, name, default=None): return request.POST.get('f-%s-%s' % (prefix, name), default) def get_int_var(prefix, name, default=None): return parse_int(get_var(prefix, name), default) # construct list of variety option names varieties = [] variety_index = {} for variety in _varieties: variety_index[variety.id] = { 'id': variety.id, 'title': variety.title, 'sku': variety.sku, 'options': {} } item = { 'id': variety.id, 'title': variety.title, 'sku': variety.sku, 'options': [], 'n_assigned_options': 0 } for option in variety.options.all(): variety_index[variety.id].get('options')[option.id] = { 'id': option.id, 'title': option.title, 'fullTitle': '%s: <em>%s</em>' % (variety.title, option.title) } item.get('options').append({ 'id': option.id, 'title': option.title, 'assigned': option.id in assigned_option_ids }) if option.pk in assigned_option_ids: item['n_assigned_options'] += 1 varieties.append(item) # sort varieties by number of assigned options, so that varieties that # have been assigned are at the top of the list. The rest remains sorted # alphabetically... varieties.sort(key=lambda x: -x.get('n_assigned_options', 0)) # validation is_valid = True if request.method == 'POST': # process sku records prefixes = request.POST.getlist('skus') assigned_option_ids = [] skus_to_save = [] sku_code_processed = [] barcodes_processed = [] for index, prefix in enumerate(prefixes): # extract relevant informatioin from post for # individual combination _id = get_var(prefix, '_id') d = { 'enabled': get_var(prefix, 'enabled') == 'on', 'sku': get_var(prefix, 'sku'), 'barcode': get_var(prefix, 'barcode'), 'price': get_var(prefix, 'price'), 'stocklevel': get_int_var(prefix, 'stocklevel', 0) } # parse assigned variety options from request data n_variety_option = 1 d['variety_options'] = [] while len(d['variety_options']) <= 16: _name = 'vo_%d' % n_variety_option if has_var(prefix, _name): d['variety_options'].append(get_int_var(prefix, _name)) n_variety_option += 1 else: break # make sure that sku, barcode and price are None # instead of empty if _id == '': _id = None if d.get('sku') == '': d['sku'] = None if d.get('barcode') == '': d['barcode'] = None if d.get('price') == '': d['price'] = None # construct form based on this data and validate form = ProductSKUForm(d) form.configure(request, barcode_system) # get variety options variety_options = VarietyOption.objects.filter( pk__in=d.get('variety_options')) # create or edit? sku = initial.get(_id, None) if sku is None: sku = ProductSKU.objects.get_by_variety_options( product, variety_options) # still not found? -> create new item if sku is None: sku = ProductSKU() sku.product = product # remember the sku record to be saved once we processed # everything. We will not save anything until everything # is considered to be valid. skus_to_save.append(sku) # mark any assigned variety options as selected, so that they # indeed remain selected, even if they have actually not been # properly assigned yet because if from errors for example for _variety in varieties: _options = _variety.get('options') for _option in _options: for _assigned_option in variety_options: if _option.get('id') == _assigned_option.pk: _option['assigned'] = True break # inject error information and keep track of error states sku.errors = [] if form.is_valid(): # update data from from d = form.cleaned_data else: for field, error in form.errors.items(): sku.errors.append({'field': field, 'error': error[0]}) is_valid = False # copy original data or cleaned data sku.enabled = d.get('enabled', False) sku.sku = d.get('sku') sku.barcode = d.get('barcode') sku.price = d.get('price') sku.stocklevel = d.get('stocklevel', 0) # keep track of variety options that should be assigned due to # SKU's that are enabled if sku.enabled: assigned_option_ids.extend( [option.pk for option in variety_options]) # set variety options (saved later) sku._variety_options = variety_options # verify uniqueness of the SKU code if not self._verify_sku(product, sku, sku_code_processed, initial): is_valid = False # verify uniqueness of barcode if not self._verify_barcode(product, sku, barcodes_processed, initial): is_valid = False # maintain changed data in initial data set, so that all # changes make theire way back into the view, even through # we might not have saved changes due to errors _id = ('idx_%d' % index) if sku.pk is None else sku.pk initial[_id] = sku # process if everything is valid if request.method == 'POST' and is_valid: # create missing option assignments assigned_option_ids = list( set(filter(lambda x: x is not None, assigned_option_ids))) for option_id in assigned_option_ids: try: assignment = VarietyAssignment.objects.get( product=product, variety_option__pk=option_id) except VarietyAssignment.DoesNotExist: VarietyAssignment.objects.create( product=product, variety_option_id=option_id) # remove deprecated option assignments deprecated_assignments = VarietyAssignment.objects.select_related( 'variety_option').filter( product=product, variety_option__variety__sku=True).exclude( variety_option__pk__in=assigned_option_ids) for deprecated_assignment in deprecated_assignments: deprecated_assignment.delete() # save changes to sku records. Null sku, so that we would not # collide when making updates sku_ids_saved = [] for sku in skus_to_save: # save product sku itself sku._sku = sku.sku sku.sku = None sku.save() sku_ids_saved.append(sku.id) # assign and save variety options sku.variety_options = sku._variety_options # remove all previous SKU deprecated_skus = ProductSKU.objects.filter( product=product).exclude(pk__in=sku_ids_saved) for deprecated_sku in deprecated_skus: deprecated_sku.delete() # apply new sku names, which is now safe to do for sku in skus_to_save: if request.settings.sku_is_barcode: sku.sku = sku.barcode else: sku.sku = sku._sku sku.save() # redirect and message if request.method == 'POST' and is_valid: messages.add_message( request, messages.SUCCESS, 'Product Varieties and SKUs saved for <em>%s</em>.' % product.title) if request.POST.get('cubane_save_and_continue') is None: return self._redirect(request, 'index') else: return self._redirect(request, 'sku', product) # materialise current initial data _initial = {} for _id, _sku in initial.items(): _initial[_id] = model_to_dict(_sku) if _sku.pk is None: _initial[_id]['variety_options'] = [ option.pk for option in _sku._variety_options ] else: _initial[_id]['variety_options'] = [ option.pk for option in _sku.variety_options.all() ] _initial[_id]['errors'] = _sku.errors if hasattr(_sku, 'errors') else [] # template context return { 'product': product, 'varieties': varieties, 'initial': to_json(_initial), 'variety_index_json': to_json(variety_index), 'form_template': form_template }
def test_should_encode_human_readable(self): s = to_json({'foo': 'bar'}, compact=False) self.assertFalse(len(re.findall(r'[\n\s]', s)) == 0)
def test_should_encode_compact(self): s = to_json({'foo': 'bar'}) self.assertTrue(len(re.findall(r'[\n\s]', s)) == 0)
def test_encode_custom_datatype_fallback(self): with self.assertRaises(TypeError): to_json(CustomDataType())
def test_encode_model_with_get_json_fieldnames(self): m = self._create_object(1, 'Foo', model=TestModelWithJsonFields) s = to_json(m) self.assertEqual(s, '{"id":1,"title":"Foo"}')
def test_encode_country_instance_should_encode_country_properties(self): s = to_json(Country.objects.get(iso='GB')) self.assertEqual( '{"calling_code":"44","flag_state":false,"landlocked":false,"name":"UNITED KINGDOM","printable_name":"United Kingdom","numcode":826,"iso3":"GBR","iso":"GB"}', s)
def test_encode_float_should_be_number(self): s = to_json(float(34.1)) self.assertEqual(s, '34.1')
def test_encode_decimal_should_be_number(self): s = to_json(Decimal('34.1')) self.assertEqual(s, '34.1')
def test_encode_none_should_be_null(self): s = to_json(None) self.assertEqual(s, 'null')
def test_encode_model_rewrite_attribute_names(self): m = self._create_object(1, 'Foo') s = to_json(m, fields={'id': 'identifier', 'title': 'name'}) self.assertEqual(s, '{"identifier":1,"name":"Foo"}')
def _create_log(self, message, instance=None, previous_instance=None, action=None, instance_label=None, model=None): """ Create a new changelog entry. """ log = ChangeLog() log.title = self._get_title(message, instance, instance_label)[:255] log.created_on = datetime.datetime.now() log.action = action # user if hasattr(self._request, 'user') and self._request.user.pk is not None: log.user = self._request.user # determine changes or list of values changes = self.get_changes(instance, previous_instance) log.changes = to_json(changes) # ignore if there are no changes if previous_instance is not None and not changes: return None # annotate log entries if the only change that would happen is to # update the last modification timestamp... log.no_changes = False if isinstance(instance, DateTimeBase): if len(changes) == 1 and changes[0]['n'] == 'updated_on': log.no_changes = True # create unique hash identifier log.hashcode = self._generate_hashcode() # connect instance if present if instance is not None: log.content_type = self._get_content_type(instance.__class__) log.target_id = instance.pk # pk must exist and must be numeric if log.target_id is None: raise ValueError(( 'Creating changelog entry for instance of type \'%s\' failed: ' + 'Instance pk cannot be None. Did you not call save() before request.changelog.create() ?' ) % instance.__class__.__name__) try: int(log.target_id) except: # Creating changelog entry for instance failed: # Instance pk must be numeric. silently fail return None elif model is not None: log.content_type = self._get_content_type(model) # call changelog handler on instance if log and instance and hasattr(instance, 'on_changelog'): instance.on_changelog(action) return log
def test_encode_string_should_be_string(self): s = to_json('Foo') self.assertEqual(s, '"Foo"')