Esempio n. 1
0
    def __exit__(self, exc_type, exc_value, traceback):
        if exc_value is None:
            # commit operation
            if self.sid is None:
                # Outer transaction
                try:
                    transaction.commit(self.using)
                except:
                    transaction.rollback(self.using)
                    raise
                finally:
                    self._leave_transaction_management()
            else:
                # Inner savepoint
                try:
                    transaction.savepoint_commit(self.sid, self.using)
                except:
                    transaction.savepoint_rollback(self.sid, self.using)
                    raise
        else:
            # rollback operation
            if self.sid is None:
                # Outer transaction
                transaction.rollback(self.using)
                self._leave_transaction_management()
            else:
                # Inner savepoint
                transaction.savepoint_rollback(self.sid, self.using)

        # Returning False here means we did not gobble up the exception, so the
        # exception process should continue.
        return False
Esempio n. 2
0
	def FetchOrCreate(cls,s):
		"""
		Find an entry for this set of intolerances, check the cache first.
		Otherwise check the database, if necessary creating a new item.
		"""
		if s in cls.__cache:
			return cls.__cache[s];
		
		while True:
			created =False
			try:
				sid = transaction.savepoint()
				e, created = cls.objects.get_or_create(intolerant_for_extension = s)
				transaction.savepoint_commit(sid)
			except DatabaseError:
				transaction.savepoint_rollback(sid)
				time.sleep(0.1)
				continue
			except IntegrityError:
				transaction.savepoint_rollback(sid)
				time.sleep(0.1)
				continue
			break;

		if not created:
			cls.__cache[s]=e
		return e;
Esempio n. 3
0
	def FetchOrCreateItem(cls,**params):
		"""
		Either find an existing entry matching the config & results in the
		params dictionary, or create a new entry.
		"""
		key = cls._CalculateKey(**params)
		
		if key in cls.__cache:
			return cls.__cache[key];
		
		params1 = dict(params)
		params1.pop("servername",None)
		params1.pop("part_of_run", None)
		
		while True:
			created =False
			try:
				sid = transaction.savepoint()
				item,created = ProbeCommonResultEntry.objects.get_or_create(key=key, defaults=params1)
				transaction.savepoint_commit(sid)
			except DatabaseError:
				transaction.savepoint_rollback(sid)
				time.sleep(0.1)
				continue
			except IntegrityError:
				transaction.savepoint_rollback(sid)
				time.sleep(0.1)
				continue
			break;
		
		if not created:
			cls.__cache[key] = item
		return item
def create_or_update(model, filter_attrs, new_attrs={}, skip_attrs=[], using=None):
    '''
    If an object is found matching filter attrs, then update
    the object with new_attrs else create the object with filter_attrs and
    new_attrs. new_attrs overrides filter_attrs. 
    To leave some keys from filter_attrs unused, specify them in skip_attrs
    (such as auto-created slug fields or to use default values).
    Returns tuple (object, created) where created is True if object is created.
    '''
    from django.db.utils import IntegrityError
    try:
        obj = model.objects.get(**filter_attrs)
    except model.DoesNotExist:
        create_attrs = filter_attrs.copy()
        # remove fields that aren't to be changed
        for k in skip_attrs:
            del create_attrs[k]
        # remove entries that use related fields
        for k in create_attrs.keys():
            if "__" in k:
                del create_attrs[k]
        create_attrs.update(new_attrs)
        try:
            obj = model(**create_attrs)
            sid = transaction.savepoint(using=using)
            obj.save(force_insert=True, using=using)
            transaction.savepoint_commit(sid, using=using)
            return (obj, True)
        except IntegrityError, e:
            transaction.savepoint_rollback(sid, using=using)
            try:
                obj = model.objects.get(**filter_attrs)
                return (obj, False)
            except model.DoesNotExist:
                raise e
Esempio n. 5
0
	def GetIPLock(cls,run, ip_address, server_item):
		"""
		Obtain a lock for this particular IP address in this run
		If an entry already exists, report that back, along with the entry  
		"""

		while True:
			try:
				ip = IP_Address.objects.extra(where=['"probedata2_ip_address"."ip_address" = INET(E\''+ip_address+'\')'])[0]
			except (IP_Address.DoesNotExist, IndexError):
				try:
					sid = transaction.savepoint()
					ip = IP_Address.objects.create(ip_address=ip_address);
					ip.Construct()
					sid = transaction.savepoint_commit(sid)
				except:
					sid = transaction.savepoint_rollback(sid)
					continue
			break;
		while True:
			try:
				sid = transaction.savepoint()
				(probedalready,created) = cls.objects.get_or_create(
													part_of_run=run, 
													ip_address=ip,
													port = server_item.port,
													protocol =server_item.protocol,
													defaults={"server":server_item})
				sid = transaction.savepoint_commit(sid)
			except:
				sid = transaction.savepoint_rollback(sid)
				time.sleep(0.1)
				continue;
			break;
		return (probedalready,created)
    def save(self, actor, organization, ip_address):
        om = super(InviteOrganizationMemberForm, self).save(commit=False)
        om.organization = organization
        om.type = OrganizationMemberType.MEMBER

        try:
            existing = OrganizationMember.objects.filter(organization=organization, user__email__iexact=om.email)[0]
        except IndexError:
            pass
        else:
            return existing, False

        sid = transaction.savepoint(using="default")
        try:
            om.save()
        except IntegrityError:
            transaction.savepoint_rollback(sid, using="default")
            return OrganizationMember.objects.get(email__iexact=om.email, organization=organization), False
        transaction.savepoint_commit(sid, using="default")

        AuditLogEntry.objects.create(
            organization=organization,
            actor=actor,
            ip_address=ip_address,
            target_object=om.id,
            event=AuditLogEntryEvent.MEMBER_INVITE,
            data=om.get_audit_log_data(),
        )

        om.send_invite_email()

        return om, True
Esempio n. 7
0
 def get_or_create(self, **kwargs):
     """
     Looks up an object with the given kwargs, creating one if necessary.
     Returns a tuple of (object, created), where created is a boolean
     specifying whether an object was created.
     """
     assert kwargs, \
             'get_or_create() must be passed at least one keyword argument'
     defaults = kwargs.pop('defaults', {})
     try:
         return self.get(**kwargs), False
     except self.model.DoesNotExist:
         try:
             params = dict([(k, v) for k, v in kwargs.items() if '__' not in k])
             params.update(defaults)
             obj = self.model(**params)
             sid = transaction.savepoint()
             obj.save(force_insert=True)
             transaction.savepoint_commit(sid)
             return obj, True
         except IntegrityError, e:
             transaction.savepoint_rollback(sid)
             try:
                 return self.get(**kwargs), False
             except self.model.DoesNotExist:
                 raise e
Esempio n. 8
0
    def save(self, *args, **kwargs):
        if not self.pk and not self.slug:
            self.slug = self.slugify(self.name)
            if django.VERSION >= (1, 2):
                from django.db import router

                using = kwargs.get("using") or router.db_for_write(type(self), instance=self)
                # Make sure we write to the same db for all attempted writes,
                # with a multi-master setup, theoretically we could try to
                # write and rollback on different DBs
                kwargs["using"] = using
                trans_kwargs = {"using": using}
            else:
                trans_kwargs = {}
            i = 0
            while True:
                i += 1
                try:
                    sid = transaction.savepoint(**trans_kwargs)
                    res = super(TagBase, self).save(*args, **kwargs)
                    transaction.savepoint_commit(sid, **trans_kwargs)
                    return res
                except IntegrityError:
                    transaction.savepoint_rollback(sid, **trans_kwargs)
                    self.slug = self.slugify(self.name, i)
        else:
            return super(TagBase, self).save(*args, **kwargs)
Esempio n. 9
0
    def bulk_insert(cursor, rpm_nevra, filename, srpm_nevra=None):
        nvra = parse_nvra(rpm_nevra)
        if srpm_nevra:
            srpm_name = parse_nvra(srpm_nevra)["name"]
        else:
            srpm_name = nvra["name"]

        sql = add_returning("""INSERT INTO %s (name, epoch, version, release, arch, srpm_nevra, srpm_name, filename)
                               VALUES (%%s, %%s, %%s, %%s, %%s, %%s, %%s, %%s)""" % RPM._meta.db_table)

        try:
            sid = transaction.savepoint()
            RPM.check_srpm_nevra(rpm_nevra, srpm_nevra)
            cursor.execute(sql, [nvra["name"], nvra["epoch"], nvra["version"], nvra["release"],
                                 nvra["arch"], srpm_nevra, srpm_name, filename])
            if connection.features.can_return_id_from_insert:
                insert_id = connection.ops.fetch_returned_insert_id(cursor)
            else:
                insert_id = connection.ops.last_insert_id(cursor, RPM._meta.db_table, "id")
        except (IntegrityError, ValidationError):
            transaction.savepoint_rollback(sid)
            cursor.execute("""SELECT %s FROM %s WHERE name=%%s AND epoch=%%s AND
                              version=%%s and release=%%s AND arch=%%s""" % ("id", RPM._meta.db_table),
                           [nvra["name"], nvra["epoch"], nvra["version"], nvra["release"], nvra["arch"]])
            insert_id = int(cursor.fetchone()[0])
        transaction.savepoint_commit(sid)
        return insert_id
 def forwards(self, orm):
     
     # Changing field 'Tale.slug'
     db.alter_column('tales_tale', 'slug', self.gf('django.db.models.fields.SlugField')(max_length=100, unique=True, null=True, db_index=False))
     if not db.dry_run:
         orm.Tale.objects.all().update(slug=None)
     
     # Adding unique constraint on 'Tale', fields ['slug']
     db.create_unique('tales_tale', ['slug'])
     if not db.dry_run:
         for tale in orm.Tale.objects.order_by('pk'):
             tale.slug = slugify(tale.title)
             i = 0
             while True:
                 i += 1
                 try:
                     sid = transaction.savepoint()
                     tale.save()
                     transaction.savepoint_commit(sid)
                     break
                 except IntegrityError:
                     transaction.savepoint_rollback(sid)
                     tale.slug = slugify(tale.title, i)
 
         # Removing null=True. We need it only for update.
         db.alter_column('tales_tale', 'slug', self.gf('django.db.models.fields.SlugField')(max_length=100, unique=True, null=False, db_index=False))
Esempio n. 11
0
 def __exit__(self, exc_type, exc_value, traceback):
     if exc_value is None:
         # commit operation
         if self.sid is None:
             # Outer transaction
             try:
                 transaction.commit(self.using)
             except:
                 transaction.rollback(self.using)
                 raise
             finally:
                 self._leave_transaction_management()
         else:
             # Inner savepoint
             try:
                 transaction.savepoint_commit(self.sid, self.using)
             except:
                 transaction.savepoint_rollback(self.sid, self.using)
                 raise
     else:
         # rollback operation
         if self.sid is None:
             # Outer transaction
             transaction.rollback(self.using)
             self._leave_transaction_management()
         else:
             # Inner savepoint
             transaction.savepoint_rollback(self.sid, self.using)
     
     return False
def save_company_information(request):
    # pdb.set_trace()
    sid = transaction.savepoint()
    try:
        if request.method == "POST":
            company_obj = Company(
                company_name = request.POST.get('company_name'),
                company_email       = request.POST.get('company_email'),
                company_phone_no   = request.POST.get('contact_number'),
                company_address   = request.POST.get('address_line'),
                company_city   = request.POST.get('city'),
                company_state   = request.POST.get('state'),
                company_country   = request.POST.get('country'),
                company_pincode   = request.POST.get('pincode'),
                company_creation_date=datetime.datetime.now()
                )
            company_obj.save()
            print "done"
            company_obj.company_unique_id=str('CO'+ datetime.date.today().strftime('%d%m%y') + str(company_obj.company_id).zfill(4))
            company_obj.save()
            transaction.savepoint_commit(sid)
            data = {'success': 'true', 'company_id':company_obj.company_id, 'company_name':company_obj.company_name }
        else:
            print 'Invalid Request'
            transaction.savepoint_rollback(sid)
            data = {'sucess': 'false' , ExceptionLabel.ERROR_MESSAGE :'Invalid Request'}
    except Exception, e:
        transaction.savepoint_rollback(sid)
        print 'error',e
        data = {'sucess': 'false', ExceptionLabel.ERROR_MESSAGE :'Server Error'}
def save_manager_information(request):
    sid = transaction.savepoint()
    try:
        if request.method == "POST":
            rm_obj = RelationShipManager(
                rm_first_name = request.POST.get('first_name'),
                rm_last_name       = request.POST.get('last_name'),
                rm_email   = request.POST.get('manager_email'),
                rm_contactno   = request.POST.get('manager_number'),
                rm_status   = 1,
                rm_creation_date=datetime.datetime.now()
                )
            rm_obj.save()
            print "done"
            rm_obj.rm_unique_id=str('RM'+ datetime.date.today().strftime('%d%m%y') + str(rm_obj.relationship_manager_id).zfill(4))
            rm_obj.save()
            transaction.savepoint_commit(sid)
            data = {'success': 'true', 'manager_id':rm_obj.relationship_manager_id, 'manager_name':rm_obj.rm_first_name +" "+ rm_obj.rm_last_name  }
        else:
            print 'Invalid Request'
            data = {'sucess': 'false' , ExceptionLabel.ERROR_MESSAGE :'Invalid Request'}
    except Exception, e:
        transaction.savepoint_rollback(sid)
        print 'error',e
        data = {'sucess': 'false', ExceptionLabel.ERROR_MESSAGE :'Server Error'}
 def unregisterAgentForServiceToday(self,ani,connection=0,date=None):
     """
     """
     log.info("in unregisterAgentForServiceToday for agent.ani: " + ani)
     assert(ani)
     today = date or datetime.date.today()        
     sid = None
     try:
         #verify agent is active
         if (self.isANICurrentlyActive(ani)):
             log.info("in unregisterAgentForServiceToday. Agent exists and currently active. About to set as inactive")
             log.info(today.__str__())
             #unregister agent
             agent = Agents.objects.filter(ani=ani, connection_status=1).extra(where=["added between %s and %s"],
                                                                   params=["%s 00:00:00" % (today.__str__()), "%s 24:00:00" % (today.__str__())])[0]
             #set agent as off
             log.info(agent)
             agent.connection_status=0
             log.info("agent connection status:%s ani: %s " % (agent.connection_status,agent.ani))
             assert(agent.connection_status == connection)
             log.info("in unregisterAgentForServiceToday about to save agent")
             agent.save()
             log.info("in unregisterAgentForServiceToday agent saved")
             sid = transaction.savepoint()
             transaction.savepoint_commit(sid)
             return agent
         else:
             #agent was not registered for service
             return None
     except Exception as e:
         log.info("services.gateway.unregisterAgentForServiceToday: " + e)
         transaction.savepoint_rollback(sid)
         return None
def migrate_app(sender, *args, **kwargs):
    """
    Migrate all models of this app registered
    """
    from .registration import registry
    if 'app_config' not in kwargs:
        return
    app_config = kwargs['app_config']

    app_name = app_config.label

    fields = [fld for fld in registry._field_registry.keys() if fld.startswith(app_name)]

    sid = transaction.savepoint()
    for fld in fields:
        model_name, field_name = fld.split('.')[1:]
        if field_exists(app_name, model_name, field_name):
            continue
        model = app_config.get_model(model_name)
        try:
            with connection.schema_editor() as schema_editor:
                schema_editor.add_field(model, registry._field_registry[fld])
                transaction.savepoint_commit(sid)
        except ProgrammingError:
            transaction.savepoint_rollback(sid)
            continue
Esempio n. 16
0
 def _importconcepts(self, job, options):
   if not options['csv'] or not os.path.exists(options['csv']):
     logger.debug('%s does not exist', options['csv'])
     return
   logger.debug('executing "import concepts" on csv %s' % options['csv'])
   total = sum(1 for line in open(options['csv']))
   # stqrt importing here
   f = open(options['csv'], 'rb')
   rows = unicodecsv.DictReader(f, encoding='utf-8')
   #rows = unicodecsv.DictReader(f)
   # get number of rows
   logger.debug('%s lines in csv file, starting import' % total)
   
   with transaction.atomic():
     
     for step,row in enumerate(rows):
       job.completion = 1.0*step/total
       job.save()
       
       Segment.objects.filter(corpus=job.corpus, cluster=row[u'segment__cluster']).update(cluster=row[u'cluster'].strip(), status=(Segment.OUT if len(row[u'exclude'].strip()) > 0 else Segment.IN))
       sid = transaction.savepoint()
       if(step % 50 == 0):
         logger.debug('import line %s of %s' % (step, total))
         transaction.savepoint_commit(sid)
       
   self._tfidf(job, options)
Esempio n. 17
0
    def save(self, force_insert=False, force_update=False, using=None):
        sid = transaction.savepoint()
        if self.pk is None:
            i = 1
            while self.pk is None:

                if i > 10:
                    sleep(0.001)

                if i > 20:
                    # Protection from infinite loop
                    raise IntegrityError("Too many iterations while generating " "unique Invoice number.")

                try:
                    self.created_on = datetime.utcnow()
                    self.created_on = self.created_on - timedelta(microseconds=self.created_on.microsecond % 100)

                    self.payment_no = (
                        self.created_on.hour * 3600 + self.created_on.minute * 60 + self.created_on.second
                    ) * 10000 + (self.created_on.microsecond // 100)
                    super(Invoice, self).save(force_insert, force_update)

                except IntegrityError:
                    transaction.savepoint_rollback(sid)

                i += 1
        else:
            super(Invoice, self).save(force_insert, force_update)

        transaction.savepoint_commit(sid)
        transaction.commit()
Esempio n. 18
0
def restore_models(zip_config, models_to_restore):
    """
    Add models in tuple of tuples models_to_restore to merengue database
    (ModelClass, "file_name")
    """
    sid = transaction.savepoint()
    try:
        models = set()
        for model_to_restore, file_name in models_to_restore:
            model_to_restore.objects.all().delete()  # we first delete all objects to avoid duplication problems
            format = 'xml'
            fixtures_file_name = "%s.%s" % (file_name, format)
            fixtures_data = zip_config.read(fixtures_file_name)
            fixtures = serializers.deserialize(format, fixtures_data)
            has_objects = False
            for fixture in fixtures:
                if fixture:
                    has_objects = True
                    fixture.save()
                models.add(fixture.object.__class__)
        # HACK: If we found even one object in a fixture, we need to reset
        # the database sequences.
        if has_objects:
            sequence_reset_sql(models)
    except:
        transaction.savepoint_rollback(sid)
        raise
    else:
        transaction.savepoint_commit(sid)
Esempio n. 19
0
    def save(self, *args, **kwargs):
        if not self.pk and not self.slug:
            self.slug = self.slugify(self.name)
            using = kwargs.get("using") or router.db_for_write(
                type(self), instance=self)
            # Make sure we write to the same db for all attempted writes,
            # with a multi-master setup, theoretically we could try to
            # write and rollback on different DBs
            kwargs["using"] = using
            trans_kwargs = {"using": using}
            i = 0
            while 1:
                i += 1
                try:
                    sid = transaction.savepoint(**trans_kwargs)
                    res = super(TagBase, self).save(*args, **kwargs)
                    transaction.savepoint_commit(sid, **trans_kwargs)
                except IntegrityError, e:
                    if 'slug' not in e.message:
                        raise

                    transaction.savepoint_rollback(sid, **trans_kwargs)
                    self.slug = self.slugify(self.name, i)
                else:
                    return res
def reset_password_confirm(request,password_reset_token):
    args = {}
    args.update(csrf(request))
    args['link_expired'] = False 
    args['password_reset_token'] = password_reset_token
    try:
        user_profile = get_object_or_404(UserProfile,password_token=password_reset_token)
        if request.method == 'POST':
            form = PasswordResetConfirmForm(request.POST)
            args['form'] = form
            if form.is_valid():
                try:
                    save_point = transaction.savepoint()
                    if user_profile.user.check_password(form.cleaned_data['password2']):
                       raise forms.ValidationError('New password should not be the same as old password')
                    user_profile.user.set_password(form.cleaned_data['password2'])
                    user_profile.user.save()
                    user_profile.password_token=None
                    user_profile.save()
                except forms.ValidationError as e:
                    transaction.savepoint_rollback(save_point)
                    messages.add_message(request,messages.ERROR,e.message)
                except:
                    transaction.savepoint_rollback(save_point)
                    err_message = (sys.exc_info()[1])
                    messages.add_message(request,messages.ERROR,err_message)
                else:
                    transaction.savepoint_commit(save_point)
                    messages.add_message(request,messages.SUCCESS,'Password has been successfully changed and the link has been expired')
                    args['link_expired'] = True               
        else:
            args['form'] = PasswordResetConfirmForm()
    except Http404 as e:
        args['link_expired'] = True
    return render_to_response('reset_password_confirm.html', args, context_instance=RequestContext(request))
Esempio n. 21
0
    def create_qark(attrs=None):
        """
        """

        # Wrap the creation of the facet and its attributes in a transaction savepoint
        # and ensure that a transaction is active
        assert transaction.is_managed(), "A managed transaction is required to create a Fact"
        sid = transaction.savepoint()

        try:
            # Create a QArk and save it; make sure it is new
            qark = QArk(nextrev=1)
            qark.save(force_insert=True)

            # Look up the id's of any attributes specified by name

            # Find all of the Facets by looking up the attributes specified

            # Create each of the attributes

            for attrdict in attrs:
                # Create a QArkAttr and save it; make sure it's new; and add it to the QArk
                attr = QArkAttr.create_qarkattr(**attrdict)
                attr.qark = qark
                attr.rev = 0
                attr.save(force_insert=True)

            return qark

        except:
            transaction.savepoint_rollback(sid)
            # TODO: Need an exception here that is meaningful to what went wrong
            raise
        else:
            transaction.savepoint_commit(sid)
Esempio n. 22
0
 def __exit__(self, exc_type, exc_value, traceback):
     if exc_type is None:
         transaction.savepoint_commit(self._sid, using=self._using)
         return True
     else:
         transaction.savepoint_rollback(self._sid, using=self._using)
         return False
Esempio n. 23
0
def _select_lang(request, context, call_func):
    """
    Select language before start updating.
    """
    if Language.on_site.count() == 0:
        messages.error(request, _("Error: On this site exist no language!"))
        return HttpResponseRedirect(reverse("PyLucidUpdate-menu"))

    if request.method == 'POST':
        form = UpdateForm(request.POST)
        if form.is_valid():
            language = form.cleaned_data["language"]
            sid = transaction.savepoint()
            try:
                response = call_func(request, language)
            except Exception, err:
                transaction.savepoint_rollback(sid)
                LogEntry.objects.log_action(
                    "pylucid_update",
                    context["title"],
                    request,
                    "Error: %s" % err,
                    long_message=traceback.format_exc())
                raise
            else:
                transaction.savepoint_commit(sid)
                LogEntry.objects.log_action("pylucid_update", context["title"],
                                            request, "successful")
            return response
Esempio n. 24
0
    def update_or_create(cls, player_id, **kwargs):
        """
        更新または追加を行う.

        :param string player_id: プレイヤーID
        :param **kwargs: get_or_create と同様
        :return: object, created, updated
        """
        obj, created = cls.get_or_create(player_id, **kwargs)
        if created:
            return obj, True, False

        defaults = kwargs.pop("defaults", {})
        params = dict([(k, v) for k, v in kwargs.items() if "__" not in k])
        params.update(defaults)
        for attr, val in params.items():
            if hasattr(obj, attr):
                setattr(obj, attr, val)

        try:
            sid = transaction.savepoint()
            obj.save(force_update=True)
            transaction.savepoint_commit(sid)
            return obj, False, True
        except IntegrityError, e:
            transaction.savepoint_rollback(sid)
            try:
                return cls.objects.partition(player_id).get(**kwargs), False, False
            except cls.DoesNotExist:
                raise IntegrityError, e
def save_room_information(request):
    sid = transaction.savepoint()
    try:
        print 'Hello'
        # pdb.set_trace()
        if request.method == "POST":
            print 'Request Accepted ',request
            apt_room_obj = PropertyRoom(
                room_number                 = request.POST.get('room_number'),
                room_type                   = request.POST.get('room_type'),
                # no_of_occupant_allowed      = request.POST.get('no_of_occupants'),
                room_status                 = 0,
                room_active_status          = 1,
                room_creation_date          =datetime.datetime.now(),
            )

            apt_room_obj.save()
            print "done"
            transaction.savepoint_commit(sid)
            data = {'success': 'true', 'update':'false', 'room_id':apt_room_obj.room_id, 'room_number': apt_room_obj.room_number, 'room_type': apt_room_obj.room_type
             # 'occupant_cnt' : apt_room_obj.no_of_occupant_allowed 
             }
        else:
            print 'Invalid Request'
            # transaction.savepoint_rollback(sid)
            data = {'sucess': 'false' , ExceptionLabel.ERROR_MESSAGE :'Invalid Request'}
    except Exception, e:
        print 'error',e
        transaction.savepoint_rollback(sid)
        data = {'sucess': 'false', ExceptionLabel.ERROR_MESSAGE :'Server Error'}
Esempio n. 26
0
def get_or_create(model, commit=True, **kwargs):
    assert kwargs, \
                'get_or_create() must be passed at least one keyword argument'
    defaults = kwargs.pop('defaults', {})
    lookup = kwargs.copy()
    for f in model._meta.fields:
        if f.attname in lookup:
            lookup[f.name] = lookup.pop(f.attname)
    try:
        return get_object(model, **lookup), False
    except model.DoesNotExist:
        try:
            params = dict([(k, v) for k, v in kwargs.items() if '__' not in k])
            params.update(defaults)
            obj = model(**params)
            if commit:
                sid = transaction.savepoint()
                obj.save(force_insert=True)
                transaction.savepoint_commit(sid)
            return obj, True
        except IntegrityError:
            if commit:
                transaction.savepoint_rollback(sid)
            exc_info = sys.exc_info()
            try:
                return get_object(model, **lookup), False
            except model.DoesNotExist:
                # Re-raise the IntegrityError with its original traceback.
                raise exc_info[1], None, exc_info[2]
Esempio n. 27
0
def register(item_class, activate=None):
    """ Register a item in the registry """
    # all process will be in a unique transaction, we don't want to get
    # half committed

    if activate is None:
        activate = item_class.active_by_default

    if settings.CACHES['default']['BACKEND'].startswith('johnny'):
        invalidate_registereditem()

    sid = transaction.savepoint()
    try:
        if not issubclass(item_class, RegistrableItem):
            raise RegistryError('item class "%s" to be registered is not '
                                'a RegistrableItem subclass' % item_class)

        if item_class.singleton:
            # check not exists duplicated items
            if have_registered_items(item_class):
                raise AlreadyRegistered('item class "%s" is already registered'
                                        % item_class)
        registered_item = _register_new_item(item_class, activate)
    except:
        transaction.savepoint_rollback(sid)
        raise
    else:
        transaction.savepoint_commit(sid)
        item_registered.send(sender=item_class, registered_item=registered_item)
    return registered_item
Esempio n. 28
0
def wipe_site(request):
    """ Delete all PageTree, PageMeta, PagePlugin for the current site. """
    current_site = Site.objects.get_current()
    title = _("Wipe all page data on '%s'." % current_site.name)
    context = {"title": title, "site": current_site}
    out = SimpleStringIO()

    if request.method == 'POST':
        form = WipeSiteConfirm(request.POST)
        if form.is_valid():

            sid = transaction.savepoint()
            try:
                Preference.objects.all().filter(site=current_site).delete()
                PageTree.on_site.all().delete()
            except Exception, err:
                transaction.savepoint_rollback(sid)
                LogEntry.objects.log_action(
                    "pylucid_update",
                    title,
                    request,
                    "Error: %s" % err,
                    long_message=traceback.format_exc())
                raise
            else:
                transaction.savepoint_commit(sid)
                LogEntry.objects.log_action("pylucid_update", title, request,
                                            "successful")
                messages.info(request, "Wipe site data successful")

            return HttpResponseRedirect(reverse("PyLucidUpdate-menu"))
Esempio n. 29
0
def connect_user(request, access_token=None, facebook_graph=None):
    '''
    Given a request either
    
    - (if authenticated) connect the user
    - login
    - register
    '''
    #TODO, instead of using access_token this should probably accept a facebook_graph as well
    user = None
    facebook = facebook_graph or get_facebook_graph(request, access_token)
    assert facebook.is_authenticated()
    facebook_data = facebook.facebook_profile_data()
    force_registration = request.REQUEST.get('force_registration') or request.REQUEST.get('force_registration_hard')
    
    logger.debug('force registration is set to %s', force_registration)
    if request.user.is_authenticated() and not force_registration:
        action = CONNECT_ACTIONS.CONNECT
        user = _connect_user(request, facebook)
    else:
        email = facebook_data.get('email', False)
        email_verified = facebook_data.get('verified', False)
        kwargs = {}
        if email and email_verified:
            kwargs = {'facebook_email': email}
        authenticated_user = authenticate(facebook_id=facebook_data['id'], **kwargs)
        if authenticated_user and not force_registration:
            action = CONNECT_ACTIONS.LOGIN

            ## Has the user registered without Facebook, using the verified FB email address?
            # It is after all quite common to use email addresses for usernames
            if not authenticated_user.get_profile().facebook_id:
                update = True
            else:
                update = getattr(authenticated_user, 'fb_update_required', False)
            user = _login_user(request, facebook, authenticated_user, update=update)
        else:
            action = CONNECT_ACTIONS.REGISTER
            user = _register_user(request, facebook)
            
    #store likes and friends if configured
    
    sid = transaction.savepoint()
    try:
        if facebook_settings.FACEBOOK_STORE_LIKES:
            likes = facebook.get_likes()
            facebook.store_likes(user, likes)
        if facebook_settings.FACEBOOK_STORE_FRIENDS:
            friends = facebook.get_friends()
            facebook.store_friends(user, friends)
        transaction.savepoint_commit(sid)
    except IntegrityError, e:
        logger.warn(u'Integrity error encountered during registration, probably a double submission %s' % e, 
            exc_info=sys.exc_info(), extra={
            'request': request,
            'data': {
                 'body': unicode(e),
             }
        })
        transaction.savepoint_rollback(sid)
def reset_password(request):
    args = {}
    args.update(csrf(request))
    if request.method == 'POST':
        form = PasswordResetForm(request.POST)
        args['form'] = form
        if form.is_valid():
            try:
                save_point = transaction.savepoint()
                password_reset_token = generate_activation_key(form.cleaned_data['email'])
                user = User.objects.get(email=form.cleaned_data['email'])
                user.userprofile.password_token = password_reset_token
                user.userprofile.save() 
                email_subject = 'Password reset confirmation'
                email_body = "Hi %s, to reset the password, click this link http://127.0.0.1:8000/reset_password_confirm/%s" % (user.username, password_reset_token)
                send_mail(email_subject, email_body, settings.EMAIL_HOST_USER, [user.email], fail_silently=False)
            except:
                transaction.savepoint_rollback(save_point)
                err_message = (sys.exc_info()[1])
                messages.add_message(request,messages.ERROR,err_message)
            else:
                transaction.savepoint_commit(save_point)
                messages.add_message(request,messages.SUCCESS,'The Password reset confirmation link has been sent to your email')
                args['form'] = PasswordResetForm()        
    else:
        args['form'] = PasswordResetForm()
    return render_to_response('reset_password.html', args, context_instance=RequestContext(request))
Esempio n. 31
0
    def create(self, validated_data):
        # 获取当前保存订单时需要的信息
        user = self.context['request'].user
        order_id = timezone.now().strftime('%Y%m%d%H%M%S') + ('%09d' % user.id)
        address = validated_data.get('address')
        pay_method = validated_data.get('pay_method')

        # 从第一次操作数据库开始, 明显开启一次事务
        with transaction.atomic():

            # 在操作数据之前创建一个保存点, 表示回滚/提交到此
            save_id = transaction.savepoint()
            # 防止其他错误(服务器挂了)暴力回滚整体try
            try:
                # 保存订单基本信息 OrderInfo(一)
                order = OrderInfo.objects.create(
                    order_id=order_id,
                    user=user,
                    address=address,
                    total_count=0,
                    total_amount=Decimal('0.00'),
                    freight=Decimal('10.00'),
                    pay_method=pay_method,
                    status=OrderInfo.ORDER_STATUS_ENUM["UNPAID"]
                    if pay_method == OrderInfo.PAY_METHODS_ENUM['ALIPAY'] else
                    OrderInfo.ORDER_STATUS_ENUM["UNSEND"])

                # 查出订单商品信息, 构建新数据, 然后sku表减库存, 加销量 goods表加销量

                # 创建链接redis对象
                redis_conn = get_redis_connection('cart')
                # 拿出购物车所有数据
                redis_cart = redis_conn.hgetall('cart_%s' % user.id)
                redis_selected = redis_conn.smembers('selected_%s' % user.id)

                # 构建购物车中已勾选的新数据
                carts = {}
                for sku_id in redis_selected:
                    carts[int(sku_id)] = int(redis_cart[sku_id])

                # 获取购物车已勾选的所有sku对象
                sku_ids = carts.keys()
                for sku_id in sku_ids:
                    while True:
                        sku = SKU.objects.get(id=sku_id)

                        # 获取原始库存/销量
                        origin_stock = sku.stock
                        origin_sales = sku.sales

                        # 当前购买数量
                        cart_sku_count = carts.get(sku_id)

                        # 判断库存是否充足
                        if cart_sku_count > origin_stock:
                            # 出错就回滚到保存点
                            transaction.savepoint_rollback(save_id)
                            raise serializers.ValidationError('库存不足')

                        # sku减库存加销量
                        new_stock = origin_stock - cart_sku_count
                        new_sales = origin_sales + cart_sku_count

                        # 同步到数据库
                        # 更新之前先使用原始数据查询该商品记录在不在, 如果在就更新, 不在会返回0
                        result = SKU.objects.filter(id=sku_id,
                                                    stock=origin_stock,
                                                    sales=origin_sales).update(
                                                        stock=new_stock,
                                                        sales=new_sales)
                        if result == 0:
                            # 不能直接抛出异常, 要让返回循环让用户再进行上面的库存判断,在数据成功保存/抛出库存不足后异常后跳出循环
                            continue

                        # 获取spu对象, 修改spu销量
                        sku.goods.sales += cart_sku_count
                        # 同步到数据库
                        sku.goods.save()

                        # 提交的订单中的商品表添加数据
                        OrderGoods.objects.create(order=order,
                                                  sku=sku,
                                                  count=cart_sku_count,
                                                  price=sku.price)
                        # 修改订单默认计数
                        order.total_count += cart_sku_count
                        # 修改默认总价
                        order.total_amount += (cart_sku_count * sku.price)
                        # 跳出循环
                        break

                # 最后给总价加上运费
                order.total_amount += order.freight
                # 同步到数据库
                order.save()
            # 捕获try出来的异常
            except serializers.ValidationError:
                raise
            except Exception:

                transaction.savepoint_rollback(save_id)
                raise

            # 执行成功 提交事务到保存点
            transaction.savepoint_commit(save_id)

        # 清空购物车中已结算的商品
        pl = redis_conn.pipeline()
        pl.hdel('cart_%s' % user.id, *redis_selected)
        pl.srem('selected_%s' % user.id, *redis_selected)
        pl.execute()

        return order
Esempio n. 32
0
    def post(self, request):
        """订单创建"""
        # 获取登录用户
        user = request.user
        if not user.is_authenticated:
            # 用户未登录
            return JsonResponse({'res': 0, 'errmsg': '请先登录'})

        # 获取参数 sku_ids
        addr_id = request.POST.get('addr_id')
        pay_method = request.POST.get('pay_method')
        sku_ids = request.POST.get('sku_ids')

        # 数据校验
        if not all([addr_id, pay_method, sku_ids]):
            return JsonResponse({'res': 1, 'errmsg': '数据不完整'})

        if pay_method not in OrderInfo.PAY_METHODS.keys():
            return JsonResponse({'res': 2, 'errmsg': '非法支付方式'})

        try:
            addr = Address.objects.get(id=addr_id)
        except Address.DoesNotExist:
            # 地址不存在
            return JsonResponse({'res': 3, 'errmsg': '地址不存在'})

        # 创建订单核心业务
        # 1.向df_order_info表中添加记录
        # 组织参数
        order_id = datetime.now().strftime('%Y%m%d%H%M%S') + str(user.id)  # 订单id
        transit_price = 10  # 运费
        total_count = 0  # 总数目
        total_price = 0  # 总金额

        # 事务处理
        # 设置事务保存点
        save_id = transaction.savepoint()

        try:
            order = OrderInfo.objects.create(
                order_id=order_id,
                user=user,
                addr=addr,
                pay_method=pay_method,
                total_count=total_count,
                total_price=total_price,
                transit_price=transit_price
            )

            # 2.用户订单中有几个商品,向df_order_goods表中添加几条记录
            conn = get_redis_connection('default')
            cart_key = 'cart_%d' % user.id

            sku_ids = sku_ids.split(',')
            for sku_id in sku_ids:
                # 获取商品信息
                try:
                    # 订单并发:悲观锁
                    # select * from df_goods_sku where id=sku_id for update;
                    sku = GoodsSKU.objects.select_for_update().get(id=sku_id)
                except GoodsSKU.DoesNotExist:
                    # 商品不存在
                    transaction.savepoint_rollback(save_id)
                    return JsonResponse({'res': 4, 'errmsg': '商品不存在'})

                # 从redis中获取用户所要购买的商品数目
                count = conn.hget(cart_key, sku_id)

                # 判断商品库存
                if int(count) > sku.stock:
                    transaction.savepoint_rollback(save_id)
                    return JsonResponse({'res': 6, 'errmsg': '商品库存不足'})

                OrderGoods.objects.create(
                    order=order,
                    sku=sku,
                    count=count,
                    price=sku.price
                )

                # 更新商品库存和销量
                sku.stock -= int(count)
                sku.sales += int(count)
                sku.save()

                # 累积计算订单商品总数量和总价格
                amount = sku.price * int(count)
                total_count += int(count)
                total_price += amount

            # 更新订单信息表中商品总数量和总价格
            order.total_count = total_count
            order.total_price = total_price
            order.save()
        except Exception as e:
            # print(e)
            transaction.savepoint_rollback(save_id)
            return JsonResponse({'res': 7, 'errmsg': '下单失败'})

        # 提交事务
        transaction.savepoint_commit(save_id)

        # 3.清除用户购物车中对应的记录
        conn.hdel(cart_key, *sku_ids)

        # 返回应答
        return JsonResponse({'res': 5, 'message': '更新成功'})
Esempio n. 33
0
    def post(self, request, pk=None):
        sid = transaction.savepoint()
        try:
            if self.request.method == "POST" and self.request.is_ajax():
                json_dict = json.loads(request.body.decode('utf-8'))
                item, batches = json_dict['item'], json_dict[
                    'batches']  #NEW UPDATED ITEM = #NEW BATCH DICT
                try:
                    item_obj = Item.objects.get(
                        pk=pk)  #GETTING THE ITEM FROM DB
                except Exception as e:
                    errors = {
                        'item_errors': "Error: No Item/Batch Object Found"
                    }
                    logger.error(str(e))
                    return JsonResponse(errors, status=400)

                for batch_obj in batches:
                    if batch_obj['deleted'] == 1:
                        try:
                            batch_instance = Batch.objects.get(
                                item_id=item_obj,
                                batch_no=batch_obj['batch_no'])
                            item_obj.handle_ItemQty_Stock_OnSub(
                                batch_instance.strip, batch_instance.nos)
                            batch_instance.delete()
                        except Exception as e:
                            logger.error(str(e))

                    elif batch_obj['deleted'] == 0:
                        strip_new, nos_new = int(batch_obj['strip']), int(
                            batch_obj['nos'])

                        #If batch Exists in Database
                        if Batch.objects.filter(
                                item_id=item_obj,
                                batch_no=batch_obj['batch_no']).exists():
                            batch_qs = Batch.objects.get(
                                item_id=item_obj,
                                batch_no=batch_obj['batch_no'])
                            serializer_batch = BatchSerialzer(
                                batch_qs,
                                data=batch_obj,
                                item_id=item_obj.id,
                                many=False)
                            strip_old, nos_old = batch_qs.strip, batch_qs.nos

                            item_obj.handle_ItemQty_Stock_OnAdd(
                                strip_new - strip_old, nos_new - nos_old)
                            batch_qs.handle_BatchQty_Stock_OnAdd(
                                strip_new - strip_old, nos_new - nos_old)

                        else:  #CREATE THE NEW BATCH
                            serializer_batch = BatchSerialzer(
                                data=batch_obj,
                                item_id=item_obj.id,
                                many=False)
                            item_obj.handle_ItemQty_Stock_OnAdd(
                                strip_new, nos_new)

                        if serializer_batch.is_valid():  #SAVE THE BATCH
                            batch_obj = serializer_batch.save()
                        else:
                            errors = {
                                "batch_error": serializer_batch.errors,
                            }
                            transaction.savepoint_rollback(sid)
                            logger.error(errors)
                            return JsonResponse(errors, status=400)

                serializer_item = ItemSerialzer(item_obj, data=item)
                if serializer_item.is_valid():
                    item = serializer_item.save()
                    transaction.savepoint_commit(sid)
                    response = {
                        'url': item.get_absolute_url(),
                    }
                    return JsonResponse(response, status=200)
                else:
                    errors = {
                        'item_errors': serializer_item.errors,
                    }
                    transaction.savepoint_rollback(sid)
                logger.error(errors)
                return JsonResponse(errors, status=400)

        except Exception as e:
            logger.error(str(e))
            transaction.savepoint_rollback(sid)
            return JsonResponse({"errors": "Something went wrong"}, status=400)
Esempio n. 34
0
    def import_data_inner(self, dataset, dry_run, raise_errors,
                          using_transactions, **kwargs):
        result = self.get_result_class()()
        result.diff_headers = self.get_diff_headers()
        result.totals = OrderedDict([(RowResult.IMPORT_TYPE_NEW, 0),
                                     (RowResult.IMPORT_TYPE_UPDATE, 0),
                                     (RowResult.IMPORT_TYPE_DELETE, 0),
                                     (RowResult.IMPORT_TYPE_SKIP, 0),
                                     (RowResult.IMPORT_TYPE_ERROR, 0),
                                     ('total', len(dataset))])

        if using_transactions:
            # when transactions are used we want to create/update/delete object
            # as transaction will be rolled back if dry_run is set
            sp1 = savepoint()

        try:
            self.before_import(dataset, using_transactions, dry_run, **kwargs)
        except Exception as e:
            logging.exception(e)
            tb_info = traceback.format_exc()
            result.base_errors.append(self.get_error_result_class()(e,
                                                                    tb_info))
            if raise_errors:
                if using_transactions:
                    savepoint_rollback(sp1)
                raise

        instance_loader = self._meta.instance_loader_class(self, dataset)

        # Update the total in case the dataset was altered by before_import()
        result.totals['total'] = len(dataset)

        for row in dataset.dict:
            row_result = self.import_row(row, instance_loader,
                                         using_transactions, dry_run, **kwargs)
            if row_result.errors:
                result.totals[row_result.IMPORT_TYPE_ERROR] += 1
                if raise_errors:
                    if using_transactions:
                        savepoint_rollback(sp1)
                    raise row_result.errors[-1].error
            else:
                result.totals[row_result.import_type] += 1
            if (row_result.import_type != RowResult.IMPORT_TYPE_SKIP
                    or self._meta.report_skipped):
                result.append_row_result(row_result)

        try:
            self.after_import(dataset, result, using_transactions, dry_run,
                              **kwargs)
        except Exception as e:
            logging.exception(e)
            tb_info = traceback.format_exc()
            result.base_errors.append(self.get_error_result_class()(e,
                                                                    tb_info))
            if raise_errors:
                if using_transactions:
                    savepoint_rollback(sp1)
                raise

        if using_transactions:
            if dry_run or result.has_errors():
                savepoint_rollback(sp1)
            else:
                savepoint_commit(sp1)

        return result
Esempio n. 35
0
def ingest(
    protocol,
    datafile,
    project_id,
    profile_id,
    request=None,
    dry_run=False,
    clear_existing=False,
    bulk_validation=False,
    bulk_submission=False,
    validation_suppressants=None,
    serializer_class=None,
):

    output = dict()

    if protocol == BENTHICPIT_PROTOCOL:
        serializer = BenthicPITCSVSerializer
    elif protocol == FISHBELT_PROTOCOL:
        serializer = FishBeltCSVSerializer
    elif protocol == BLEACHINGQC_PROTOCOL:
        serializer = BleachingCSVSerializer
    else:
        return None, output

    reader = csv.DictReader(datafile)
    context = _create_context(request, profile_id)
    rows = _append_required_columns(reader, project_id, profile_id)
    project_choices = get_ingest_project_choices(project_id)

    profile = Profile.objects.get_or_none(id=profile_id)
    if profile is None:
        raise ValueError("Profile does not exist")

    s = serializer(data=rows,
                   many=True,
                   project_choices=project_choices,
                   context=context)

    is_valid = s.is_valid()
    errors = s.formatted_errors

    if is_valid is False:
        output["errors"] = errors
        return None, output

    with transaction.atomic():
        sid = transaction.savepoint()
        new_records = None
        successful_save = False
        try:
            if clear_existing:
                # Fetch ids to be deleted before deleting
                # because it's being done in a thread and
                # we want to avoid deleting new collect records.
                delete_ids = [
                    cr.id for cr in CollectRecord.objects.filter(
                        project_id=project_id,
                        profile=profile,
                        data__protocol=protocol)
                ]
                clear_collect_records(delete_ids)
            new_records = s.save()
            successful_save = True
        finally:
            if dry_run is True or successful_save is False:
                transaction.savepoint_rollback(sid)
            else:
                transaction.savepoint_commit(sid)

    is_bulk_invalid = False
    if dry_run is False and bulk_validation or bulk_submission:
        record_ids = [str(r.pk) for r in new_records]
        validation_output = validate_collect_records(profile, record_ids,
                                                     serializer_class,
                                                     validation_suppressants)
        output["validate"] = validation_output
        statuses = [v.get("status") for v in validation_output.values()]
        if WARN in statuses or ERROR in statuses:
            is_bulk_invalid = True

    if dry_run is False and bulk_submission and not is_bulk_invalid:
        submit_output = submit_collect_records(profile, record_ids,
                                               validation_suppressants)
        output["submit"] = submit_output

    return new_records, output
    def set_value(
        cls, key, value, with_transaction=True, subspecifier_value=None, other_attribs={}, stop_if_existing=False
    ):
        """
        Set a new value in the DB, possibly associated to the given subspecifier.

        :note: This method also stored directly in the DB.

        :param key: a string with the key to create (must be a level-0
          attribute, that is it cannot contain the separator cls._sep).
        :param value: the value to store (a basic data type or a list or a dict)
        :param subspecifier_value: must be None if this class has no
          subspecifier set (e.g., the DbSetting class).
          Must be the value of the subspecifier (e.g., the dbnode) for classes
          that define it (e.g. DbAttribute and DbExtra)
        :param with_transaction: True if you want this function to be managed
          with transactions. Set to False if you already have a manual
          management of transactions in the block where you are calling this
          function (useful for speed improvements to avoid recursive
          transactions)
        :param other_attribs: a dictionary of other parameters, to store
          only on the level-zero attribute (e.g. for description in DbSetting).
        :param stop_if_existing: if True, it will stop with an
           UniquenessError exception if the new entry would violate an
           uniqueness constraint in the DB (same key, or same key+node,
           depending on the specific subclass). Otherwise, it will
           first delete the old value, if existent. The use with True is
           useful if you want to use a given attribute as a "locking" value,
           e.g. to avoid to perform an action twice on the same node.
           Note that, if you are using transactions, you may get the error
           only when the transaction is committed.
        """
        cls.validate_key(key)

        try:
            if with_transaction:
                sid = transaction.savepoint()

            # create_value returns a list of nodes to store
            to_store = cls.create_value(key, value, subspecifier_value=subspecifier_value, other_attribs=other_attribs)

            if to_store:
                # if not stop_if_existing:
                #     # Delete the olf values if stop_if_existing is False,
                #     # otherwise don't delete them and hope they don't
                #     # exist. If they exist, I'll get an UniquenessError
                #
                #     ## NOTE! Be careful in case the extra/attribute to
                #     ## store is not a simple attribute but a list or dict:
                #     ## like this, it should be ok because if we are
                #     ## overwriting an entry it will stop anyway to avoid
                #     ## to overwrite the main entry, but otherwise
                #     ## there is the risk that trailing pieces remain
                #     ## so in general it is good to recursively clean
                #     ## all sub-items.
                #     cls.del_value(key,
                #                   subspecifier_value=subspecifier_value)
                for my_obj in to_store:
                    my_obj.save()

                # cls.objects.bulk_create(to_store)

            if with_transaction:
                transaction.savepoint_commit(sid)
        except BaseException as exc:  # All exceptions including CTRL+C, ...
            from django.db.utils import IntegrityError
            from aiida.common.exceptions import UniquenessError

            if with_transaction:
                transaction.savepoint_rollback(sid)
            if isinstance(exc, IntegrityError) and stop_if_existing:
                raise UniquenessError(
                    'Impossible to create the required '
                    'entry '
                    "in table '{}', "
                    'another entry already exists and the creation would '
                    'violate an uniqueness constraint.\nFurther details: '
                    '{}'.format(cls.__name__, exc)
                )
            raise
Esempio n. 37
0
    def post(self, request):
        user = request.user
        if not user.is_authenticated:
            return JsonResponse({'res': 0, 'errmsg': '用户未登陆'})
        addr_id = request.POST.get('addr_id')
        pay_style = request.POST.get('pay_style')
        sku_ids = request.POST.get('sku_ids')
        if not all([addr_id, pay_style, sku_ids]):
            return JsonResponse({'res': 1, 'errmsg': '数据不完整'})
        if pay_style not in OrderInfo.PAY_METHODS.keys():
            return JsonResponse({'res': 2, 'errmsg': '非法的支付方式'})
        try:
            addr = Address.objects.get(id=addr_id)
        except Address.DoesNotExist():
            return JsonResponse({'res': 3, 'errmsg': '地址非法'})

        order_id = datetime.now().strftime('%Y%m%d%H%M%S') + str(user.id)
        transit_price = 12
        total_count = 0
        total_price = 0
        save_id = transaction.savepoint()
        try:
            order = OrderInfo.objects.create(order_id=order_id,
                                             user=user,
                                             addr=addr,
                                             pay_method=pay_style,
                                             total_count=total_count,
                                             total_price=total_price,
                                             transit_price=transit_price)
            sku_ids = sku_ids.split(',')
            conn = get_redis_connection('default')

            cart_key = 'cart_%d' % user.id

            for sku_id in sku_ids:
                try:
                    sku = GoodsSKU.objects.select_for_update().get(id=sku_id)
                except:
                    return JsonResponse({'res': 4, 'errmsg': '商品不存在'})
                count = conn.hget(cart_key, sku_id)
                if int(count) > sku.stock:
                    return JsonResponse({'res': 6, 'errmsg': '库存不足'})
                OrderGoods.objects.create(order=order,
                                          sku=sku,
                                          count=count,
                                          price=sku.price)
                sku.stock - +int(count)
                sku.sales += int(count)
                sku.save()
                amount = sku.price * int(count)
                total_count += int(count)
                total_price += amount

            order.total_count = total_count
            order.total_price = total_price
            order.save()
        except Exception as e:
            transaction.savepoint_rollback(save_id)
        transaction.savepoint_commit(save_id)
        conn.hdel(cart_key, *sku_ids)
        return JsonResponse({'res': 5, 'message': '创建成功'})
Esempio n. 38
0
    def post(self, request):
        '''订单创建'''
        # 判断用户是否登录
        user = request.user
        if not user.is_authenticated():
            # 用户未登录
            return JsonResponse({'res': 0, 'errmsg': '用户未登录'})

        # 接收参数: 收货地址id,支付方式id,商品id
        addr_id = request.POST.get('addr_id')
        pay_method = request.POST.get('pay_method')
        sku_ids = request.POST.get('sku_ids')  # 1,3

        # 校验参数
        if not all([addr_id, pay_method, sku_ids]):
            return JsonResponse({'res': 1, 'errmsg': '参数不完整'})

        # 校验支付方式
        if pay_method not in OrderInfo.PAY_METHODS.keys():
            return JsonResponse({'res': 2, 'errmsg': '非法的支付方式'})

        # 校验地址
        try:
            addr = Address.objects.get(id=addr_id)
        except Address.DoesNotExist:
            # 地址不存在
            return JsonResponse({'res': 3, 'errmsg': '地址非法'})

        # todo: 创建订单核心业务

        # 组织参数
        # 订单id: 20171122181630+用户id
        order_id = datetime.now().strftime('%Y%m%d%H%M%S') + str(user.id)

        # 运费
        transit_price = 10

        # 总数目和总金额
        total_count = 0
        total_price = 0

        # 设置事务保存点
        save_id = transaction.savepoint()
        try:
            # todo: 向df_order_info表中添加一条记录
            order = OrderInfo.objects.create(order_id=order_id,
                                             user=user,
                                             addr=addr,
                                             pay_method=pay_method,
                                             total_count=total_count,
                                             total_price=total_price,
                                             transit_price=transit_price)

            # todo: 用户的订单中有几个商品,需要向df_order_goods表中加入几条记录
            conn = get_redis_connection('default')
            cart_key = 'cart_%d' % user.id

            sku_ids = sku_ids.split(',')
            for sku_id in sku_ids:
                # 获取商品的信息
                try:
                    # select * from df_goods_sku where id=sku_id for update;  悲观锁,解决高并发时库存数量问题
                    sku = GoodsSKU.objects.select_for_update().get(id=sku_id)
                except:
                    # 商品不存在, 回滚到事务保存点:save_id
                    transaction.savepoint_rollback(save_id)
                    return JsonResponse({'res': 4, 'errmsg': '商品不存在'})

                # 从redis中获取用户所要购买的商品的数量
                count = conn.hget(cart_key, sku_id)

                # todo: 判断商品的库存
                if int(count) > sku.stock:
                    # 回滚到事务保存点:save_id
                    transaction.savepoint_rollback(save_id)
                    return JsonResponse({'res': 6, 'errmsg': '商品库存不足'})

                # todo: 向df_order_goods表中添加一条记录
                OrderGoods.objects.create(order=order,
                                          sku=sku,
                                          count=count,
                                          price=sku.price)

                # todo: 更新商品的库存和销量
                sku.stock -= int(count)
                sku.sales += int(count)
                sku.save()

                # todo: 累加计算订单商品的总数量和总价格
                amount = sku.price * int(count)
                total_count += int(count)
                total_price += amount

            # todo: 更新订单信息表中的商品的总数量和总价格
            order.total_count = total_count
            order.total_price = total_price
            order.save()
        except Exception as e:
            # 如果上面不成功,回滚
            transaction.savepoint_rollback(save_id)
            return JsonResponse({'res': 7, 'message': '下单失败'})

        # 提交事务,下单生效
        transaction.savepoint_commit(save_id)

        # todo: 清除用户购物车中对应的记录,*具有拆包的作用
        conn.hdel(cart_key, *sku_ids)
        # 返回应答
        return JsonResponse({'res': 5, 'message': '创建成功'})
Esempio n. 39
0
    def get(self, request, *args, **kwargs):
        """
        获取服务检测信息
        ---
        parameters:
            - name: tenantName
              description: 租户名
              required: true
              type: string
              paramType: path
            - name: serviceAlias
              description: 服务别名
              required: true
              type: string
              paramType: path
            - name: check_uuid
              description: 检测id
              required: true
              type: string
              paramType: query

        """
        sid = None
        try:
            check_uuid = request.GET.get("check_uuid", None)
            if not check_uuid:
                return Response(general_message(400, "params error",
                                                "参数错误,请求参数应该包含请求的ID"),
                                status=400)
            code, msg, data = app_check_service.get_service_check_info(
                self.tenant, self.service.service_region, check_uuid)
            # 如果已创建完成
            if self.service.create_status == "complete":
                # 删除原有build类型env,保存新检测build类型env
                save_code, save_msg = app_check_service.upgrade_service_env_info(
                    self.tenant, self.service, data)
                if save_code != 200:
                    logger.debug('======构建时运行参数更新失败=====>{0}'.format(save_msg))

                # 重新检测后对端口做加法
                save_code, save_msg = app_check_service.add_service_check_port(
                    self.tenant, self.service, data)
                if save_code != 200:
                    logger.debug('======对检测出来的端口做加法=====>{0}'.format(save_msg))
                check_brief_info = app_check_service.wrap_service_check_info(
                    self.service, data)
                return Response(
                    general_message(200,
                                    "success",
                                    "请求成功",
                                    bean=check_brief_info))
            # 开启保存点
            sid = transaction.savepoint()
            logger.debug("start save check info ! {0}".format(
                self.service.create_status))
            save_code, save_msg = app_check_service.save_service_check_info(
                self.tenant, self.service, data)
            if save_code != 200:
                transaction.savepoint_rollback(sid)
                data["check_status"] = "failure"
                save_error = {
                    "error_type": "check info save error",
                    "solve_advice": "修改相关信息后重新尝试",
                    "error_info": "{}".format(save_msg)
                }
                if data["error_infos"]:
                    data["error_infos"].append(save_error)
                else:
                    data["error_infos"] = [save_error]
            else:
                transaction.savepoint_commit(sid)
            logger.debug("check result = {0}".format(data))
            check_brief_info = app_check_service.wrap_service_check_info(
                self.service, data)
            result = general_message(200,
                                     "success",
                                     "请求成功",
                                     bean=check_brief_info)
        except Exception as e:
            logger.exception(e)
            result = error_message(e.message)
            if sid:
                transaction.savepoint_rollback(sid)
        return Response(result, status=result["code"])
Esempio n. 40
0
    def post(self, request):
        '''提交订单'''
        # 1.接收参数(address_id + pay_method)
        dict = json.loads(request.body.decode())
        address_id = dict.get('address_id')
        pay_method = dict.get('pay_method')

        # 2.总体检验 + 单个检验
        if not all([address_id, pay_method]):
            return JsonResponse({'code': 400, 'errmsg': "必传参数有为空的"})
        # 单个检验
        try:
            address = Address.objects.get(id=address_id)
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': "address_id有误"})

        if pay_method not in [
                OrderInfo.PAY_METHODS_ENUM['CASH'],
                OrderInfo.PAY_METHODS_ENUM['ALIPAY']
        ]:
            return JsonResponse({'code': 400, 'errmsg': "address_id有误"})

        order_id = timezone.localtime().strftime(
            '%Y%m%d%H%M%S') + '%09d' % request.user.id

        # 开启事务:
        with transaction.atomic():
            # 设置保存点:
            save_id = transaction.savepoint()

            # 3.往订单基本表(order_info)中保存数据
            order = OrderInfo.objects.create(
                order_id=order_id,
                user=request.user,
                address=address,
                total_count=0,
                total_amount=Decimal('0.00'),
                freight=Decimal('10.00'),
                pay_method=pay_method,
                status=1 if pay_method == 2 else 2)
            # 4.链接redis, 获取链接对象
            redis_conn = get_redis_connection('carts')

            # 5.通过链接对象, 从hash中获取count
            item_dict = redis_conn.hgetall('carts_%s' % request.user.id)

            # 6.通过链接对象, 从set中获取订单中的商品id(sku_id)
            selected_item = redis_conn.smembers('selected_%s' %
                                                request.user.id)

            dict = {}
            # 7.把hash: count和set:  sku_id 放到一起(dict)
            for sku_id in selected_item:
                dict[int(sku_id)] = int(item_dict[sku_id])

            # 8.把dict的所有的key取出来: sku_ids
            sku_ids = dict.keys()

            # 9.把sku_ids遍历, 获取每一个sku_id
            for sku_id in sku_ids:

                while True:

                    # 10.通过sku_id获取对应的商品sku
                    sku = SKU.objects.get(id=sku_id)

                    # 11.从dict中取出该id对应的count(卖出的数量)
                    count = dict.get(sku.id)

                    origin_stock = sku.stock
                    origin_sales = sku.sales

                    # 12.判断count(卖出的数量)和库存关系
                    if sku.stock < count:
                        transaction.savepoint_rollback(save_id)
                        return JsonResponse({'code': 400, 'errmsg': "库存不足"})

                    # 13.如果库存够, 把sku的库存减少. 销量增加. 保存
                    # sku.stock -= count
                    # sku.sales += count
                    # sku.save()
                    new_stock = origin_stock - count
                    new_sales = origin_sales + count
                    result = SKU.objects.filter(
                        id=sku_id, stock=origin_stock).update(stock=new_stock,
                                                              sales=new_sales)

                    if result == 0:
                        # 没有更新:
                        continue

                    # 14.把sku对应的(spu)的销量增加. 保存
                    sku.spu.sales += count
                    sku.spu.save()

                    # 15.往订单商品表(OrderGoods)中增加数据.
                    OrderGoods.objects.create(order=order,
                                              sku=sku,
                                              count=count,
                                              price=sku.price)

                    # 16.取出订单, 更新订单的总数量 + 总金额
                    order.total_count += count
                    order.total_amount += (count * sku.price)

                    # 跳出死循环:
                    break

            # 17.更新订单的总金额(运费)
            order.total_amount += order.freight
            # 18.保存订单
            order.save()

            # 撤销保存点(可以不做)
            transaction.savepoint_commit(save_id)

        # 19.删除redis中购物车的相关记录(这些商品从购物车去除)
        redis_conn.hdel('carts_%s' % request.user.id, *selected_item)
        redis_conn.srem('selected_%s' % request.user.id, *selected_item)

        # 20.拼接参数, 返回
        return JsonResponse({
            'code': 0,
            'errmsg': 'ok',
            'order_id': order.order_id
        })
Esempio n. 41
0
    def post(self, request, *args, **kwargs):
        """
        添加团队
        ---
        parameters:
            - name: tenant_name
              description: 团队名
              required: true
              type: string
              paramType: form
            - name: enterprise_id
              description: 企业ID
              required: true
              type: string
              paramType: form
            - name: useable_regions
              description: 可用数据中心 ali-sh,ali-hz
              required: false
              type: string
              paramType: form
        """
        sid = None
        try:
            tenant_name = request.data.get("tenant_name", None)
            if not tenant_name:
                return Response(
                    generate_result("1003", "team name is none", "团对名称不能为空"))
            enterprise_id = request.data.get("enterprise_id", None)
            if not enterprise_id:
                return Response(
                    generate_result("1003", "enterprise id is none",
                                    "企业ID不能为空"))
            enter = enterprise_services.get_enterprise_by_enterprise_id(
                enterprise_id)
            if not enter:
                return Response(
                    generate_result("0404", "enterprise not found",
                                    "企业在云帮不存在"))

            team = console_team_service.get_team_by_team_alias_and_eid(
                tenant_name, enterprise_id)
            if team:
                return Response(
                    generate_result("0409", "team alias is exist",
                                    "团队别名{0}在该企业已存在".format(tenant_name)))

            creater = request.data.get("creater", None)
            if not creater:
                return Response(
                    generate_result("0412", "please specify owner", "请指定拥有者"))
            user = user_repo.get_user_by_username(creater)
            useable_regions = request.data.get("useable_regions", "")
            logger.debug("team name {0}, usable regions {1}".format(
                tenant_name, useable_regions))
            regions = []
            if useable_regions:
                regions = useable_regions.split(",")
            # 开启保存点
            sid = transaction.savepoint()
            code, msg, team = console_team_service.create_team(
                user, enter, regions, tenant_name)
            # 创建用户在团队的权限
            perm_info = {
                "user_id": user.user_id,
                "tenant_id": team.ID,
                "identity": "owner",
                "enterprise_id": enter.pk
            }
            console_perm_service.add_user_tenant_perm(perm_info)

            for r in regions:
                code, msg, tenant_region = console_region_service.create_tenant_on_region(
                    team.tenant_name, r)
                if code != 200:
                    logger.error(msg)
                    if sid:
                        transaction.savepoint_rollback(sid)
                    return Response(generate_result("0500", "add team error",
                                                    msg),
                                    status=code)

            transaction.savepoint_commit(sid)

            bean = {
                "tenant_name": team.tenant_name,
                "tenant_id": team.tenant_id,
                "tenant_alias": team.tenant_alias,
                "user_num": 1
            }
            result = generate_result("0000", "success", "租户添加成功", bean=bean)
        except TenantOverFlowError as e:
            result = generate_result("7001", "tenant over flow",
                                     "{}".format(e.message))
        except TenantExistError as e:
            result = generate_result("7002", "tenant exist",
                                     "{}".format(e.message))
        except NoEnableRegionError as e:
            result = generate_result("7003", "no enable region",
                                     "{}".format(e.message))
        except UserNotExistError as e:
            result = generate_result("7004", "not user",
                                     "{}".format(e.message))
        except Exception as e:
            logger.exception(e)
            if sid:
                transaction.savepoint_rollback(sid)
            result = generate_error_result()
        return Response(result)
Esempio n. 42
0
    def post(self, request):
        '''订单创建'''
        # 判断用户是否登录
        user = request.user
        if not user.is_authenticated():
            # 用户未登录
            return JsonResponse({'res': 0, 'errmsg': '用户未登录'})

        # 接收参数: 收货地址id,支付方式id,商品id
        addr_id = request.POST.get('addr_id')
        pay_method = request.POST.get('pay_method')
        sku_ids = request.POST.get('sku_ids')  # 1,3

        # 校验参数
        if not all([addr_id, pay_method, sku_ids]):
            return JsonResponse({'res': 1, 'errmsg': '参数不完整'})

        # 校验支付方式
        if pay_method not in OrderInfo.PAY_METHODS.keys():
            return JsonResponse({'res': 2, 'errmsg': '非法的支付方式'})

        # 校验地址
        try:
            addr = Address.objects.get(id=addr_id)
        except Address.DoesNotExist:
            # 地址不存在
            return JsonResponse({'res': 3, 'errmsg': '地址非法'})

        # todo: 创建订单核心业务

        # 组织参数
        # 订单id: 20171122181630+用户id
        order_id = datetime.now().strftime('%Y%m%d%H%M%S') + str(user.id)

        # 运费
        transit_price = 10

        # 总数目和总金额
        total_count = 0
        total_price = 0

        # 设置事务保存点
        save_id = transaction.savepoint()
        try:
            # todo: 向df_order_info表中添加一条记录
            order = OrderInfo.objects.create(order_id=order_id,
                                             user=user,
                                             addr=addr,
                                             pay_method=pay_method,
                                             total_count=total_count,
                                             total_price=total_price,
                                             transit_price=transit_price)

            # todo: 用户的订单中有几个商品,需要向df_order_goods表中加入几条记录
            conn = get_redis_connection('default')
            cart_key = 'cart_%d' % user.id

            sku_ids = sku_ids.split(',')
            for sku_id in sku_ids:
                for i in range(3):  # 尝试3次下单
                    # 获取商品的信息
                    try:
                        sku = GoodsSKU.objects.get(id=sku_id)
                    except:
                        # 商品不存在, 回滚到事务保存点:save_id
                        transaction.savepoint_rollback(save_id)
                        return JsonResponse({'res': 4, 'errmsg': '商品不存在'})

                    # 从redis中获取用户所要购买的商品的数量
                    count = conn.hget(cart_key, sku_id)

                    # todo: 判断商品的库存
                    if int(count) > sku.stock:
                        # 回滚到事务保存点:save_id
                        transaction.savepoint_rollback(save_id)
                        return JsonResponse({'res': 6, 'errmsg': '商品库存不足'})

                    # todo: 更新商品的库存和销量
                    orgin_stock = sku.stock  # 商品的原库存
                    new_stock = orgin_stock - int(count)  # 更新之后的库存
                    new_sales = sku.sales + int(count)  # 更新之后的销量

                    # 更新good_sku数据表:update (df_goods_sku) set (stock=new_stock, sales=new_sales)
                    # where (id=sku_id and stock = orgin_stock)
                    # 返回更新的数据条数,根据id和库存去查商品  查到对应商品并更新:返回1条数据  查不到(库存被其他用户购买发生改变):返回0条数据
                    res = GoodsSKU.objects.filter(
                        id=sku_id, stock=orgin_stock).update(stock=new_stock,
                                                             sales=new_sales)
                    if res == 0:  # 如果更新的数据条数为0,表示库存发生了改变,其他用户刚购买了此商品
                        if i == 2:  # 尝试的第3次时,
                            transaction.savepoint_rollback(save_id)  # 事务回滚
                            return JsonResponse({'res': 7, 'errmsg': '下单失败2'})
                        continue  # 结束本次循环,重新读取被其他用户购买之后的库存数,重新下单

                    # todo: 向df_order_goods表中添加一条记录
                    OrderGoods.objects.create(order=order,
                                              sku=sku,
                                              count=count,
                                              price=sku.price)

                    # todo: 累加计算订单商品的总数量和总价格
                    amount = sku.price * int(count)
                    total_count += int(count)
                    total_price += amount

                    break  # 如果下单成功跳出后续的循环

            # todo: 更新订单信息表中的商品的总数量和总价格
            order.total_count = total_count
            order.total_price = total_price
            order.save()
        except Exception as e:
            # 如果上面不成功,回滚
            transaction.savepoint_rollback(save_id)
            return JsonResponse({'res': 7, 'message': '下单失败'})

        # 提交事务,下单生效
        transaction.savepoint_commit(save_id)

        # todo: 清除用户购物车中对应的记录,*具有拆包的作用
        conn.hdel(cart_key, *sku_ids)
        # 返回应答
        return JsonResponse({'res': 5, 'message': '创建成功'})
Esempio n. 43
0
    def post(self, request):
        # 接收数据
        data = json.loads(request.body.decode())
        address_id = data.get('address_id')
        pay_method = data.get('pay_method')
        # 验证数据
        if not all([address_id, pay_method]):
            return JsonResponse({'code': RETCODE.PARAMERR, 'errmsg': '参数不全'})
        # 数据入库
        #     1 先写入订单基本信息
        #         1.1 获取用户信息
        user = request.user
        #         1.2 获取地址信息
        try:
            address = Address.objects.get(id=address_id, user=user)
        except Address.DoesNotExist:
            return JsonResponse({'code': RETCODE.PARAMERR, 'errmsg': '地址不正确'})
        #         1.3  order_id   年月日时分秒+9位用户id
        from django.utils import timezone
        # Y year
        # m month
        # d day
        # H Hour
        # M Minute
        # S Second
        # f 微秒
        order_id = timezone.localtime().strftime(
            '%Y%m%d%H%M%S') + '%09d' % user.id
        #         1.4  总数量(0),总金额(0),运费
        total_count = 0  #总数量
        from decimal import Decimal
        total_amount = Decimal('0')  #总金额
        freight = Decimal('10.00')  #运费
        # 小数是以 无限接近于真实值的形式存在
        # 100/3 = 33.33
        # 33.33*3=99.99
        # 33.33   33.33   33.34

        #         1.5  支付方式
        # if pay_method not in [1,2]:
        #     return JsonResponse({'code':RETCODE.PARAMERR,'errmsg':'支付方式错误'})

        # 增加了代码的可读性
        if pay_method not in [
                OrderInfo.PAY_METHODS_ENUM['CASH'],
                OrderInfo.PAY_METHODS_ENUM['ALIPAY']
        ]:
            return JsonResponse({'code': RETCODE.PARAMERR, 'errmsg': '支付方式错误'})
        #         1.6  支付状态 由支付方式决定
        if pay_method == OrderInfo.PAY_METHODS_ENUM['CASH']:
            # 现金支付
            status = OrderInfo.ORDER_STATUS_ENUM['UNSEND']
        else:
            #支付宝
            status = OrderInfo.ORDER_STATUS_ENUM['UNPAID']

        from django.db import transaction
        # with 语句就是针对于特定(部分)代码进行事务
        with transaction.atomic():

            # ① 创建事务的保存点
            savepoint = transaction.savepoint()
            try:
                order_info = OrderInfo.objects.create(
                    order_id=order_id,
                    user=user,
                    address=address,
                    total_count=total_count,
                    total_amount=total_amount,
                    freight=freight,
                    pay_method=pay_method,
                    status=status)

                #     2 再写入订单商品信息
                #         2.1 获取redis中,指定用户的选中信息 [1,2]
                redis_conn = get_redis_connection('carts')
                id_counts = redis_conn.hgetall('carts_%s' % user.id)
                selected_ids = redis_conn.smembers('selected_%s' % user.id)

                #选中商品的id
                #selected_dict
                selected_dict = {}
                for id in selected_ids:
                    selected_dict[int(id)] = int(id_counts[id])

                # selected_dict = {sku_id:count,sku_id:count,....}

                #         2.2 根据id查询商品信息
                for sku_id, count in selected_dict.items():
                    while True:
                        sku = SKU.objects.get(id=sku_id)
                        #         2.3 判断商品库存是否充足
                        if sku.stock < count:
                            #说明库存不足
                            #② 回滚
                            transaction.savepoint_rollback(savepoint)

                            return JsonResponse({
                                'code': RETCODE.STOCKERR,
                                'errmsg': '库存不足'
                            })
                        #         2.4 商品库存减少,销量增加
                        # import time
                        # time.sleep(7)

                        # sku.stock -= count
                        # sku.sales += count
                        # sku.save()

                        # 乐观锁
                        # 乐观锁 第一步,先记录库存
                        old_stock = sku.stock
                        # 乐观所 第二步 计算更新后的数据
                        new_stock = sku.stock - count
                        new_sales = sku.sales + count
                        #更新前,再判断一次,相同则更新数据
                        # 乐观所 第三步,更新前,再判断一次,相同则更新数据
                        rect = SKU.objects.filter(
                            id=sku_id, stock=old_stock).update(stock=new_stock,
                                                               sales=new_sales)

                        if rect == 0:
                            continue
                            #说明修改失败
                            # transaction.savepoint_rollback(savepoint)
                            # return JsonResponse({'code':RETCODE.STOCKERR,'errmsg':'下单失败'})

                        #         2.5 将商品信息写入到订单商品信息表中
                        OrderGoods.objects.create(order=order_info,
                                                  sku=sku,
                                                  count=count,
                                                  price=sku.price)
                        #         2.6 累加计算,总数量和总金额
                        order_info.total_count += count
                        order_info.total_amount += (count * sku.price)

                        break
                #
                #     3.更新订单基本信息中的总数量和总金额
                order_info.save()
            except Exception as e:
                transaction.savepoint_rollback(savepoint)
            else:
                # ③ 提交
                transaction.savepoint_commit(savepoint)

        #     4.选中的数据应该删除
        # redis_conn.hdel('carts_%s'%user.id,*selected_ids)
        # redis_conn.srem('selected_%s'%user.id,*selected_ids)
        # 返回相应
        return JsonResponse({
            'code': RETCODE.OK,
            'errmsg': 'ok',
            'order_id': order_info.order_id,
            'payment_amount': order_info.total_amount,
            'pay_method': order_info.pay_method
        })
Esempio n. 44
0
    def save(self, project, raw=False):
        # TODO: culprit should default to "most recent" frame in stacktraces when
        # it's not provided.
        project = Project.objects.get_from_cache(id=project)

        data = self.data.copy()

        # First we pull out our top-level (non-data attr) kwargs
        event_id = data.pop('event_id')
        message = data.pop('message')
        level = data.pop('level')

        culprit = data.pop('culprit', None) or ''
        time_spent = data.pop('time_spent', None)
        logger_name = data.pop('logger', None)
        server_name = data.pop('server_name', None)
        site = data.pop('site', None)
        checksum = data.pop('checksum', None)
        platform = data.pop('platform', None)
        release = data.pop('release', None)

        date = datetime.fromtimestamp(data.pop('timestamp'))
        date = date.replace(tzinfo=timezone.utc)

        kwargs = {
            'message': message,
            'platform': platform,
        }

        event = Event(project=project,
                      event_id=event_id,
                      data=data,
                      time_spent=time_spent,
                      datetime=date,
                      **kwargs)

        # Calculate the checksum from the first highest scoring interface
        if checksum:
            hashes = [checksum]
        else:
            hashes = get_hashes_for_event(event)

        # TODO(dcramer): remove checksum usage
        event.checksum = hashes[0]

        group_kwargs = kwargs.copy()
        group_kwargs.update({
            'culprit': culprit,
            'logger': logger_name,
            'level': level,
            'last_seen': date,
            'first_seen': date,
            'time_spent_total': time_spent or 0,
            'time_spent_count': time_spent and 1 or 0,
        })

        tags = data['tags']
        tags.append(('level', LOG_LEVELS[level]))
        if logger_name:
            tags.append(('logger', logger_name))
        if server_name:
            tags.append(('server_name', server_name))
        if site:
            tags.append(('site', site))
        if release:
            # TODO(dcramer): we should ensure we create Release objects
            tags.append(('sentry:release', release))

        for plugin in plugins.for_project(project):
            added_tags = safe_execute(plugin.get_tags, event)
            if added_tags:
                tags.extend(added_tags)

        result = safe_execute(self._save_aggregate,
                              event=event,
                              tags=tags,
                              hashes=hashes,
                              **group_kwargs)
        if result is None:
            return

        group, is_new, is_regression, is_sample = result

        using = group._state.db

        event.group = group

        # save the event unless its been sampled
        if not is_sample:
            sid = transaction.savepoint(using=using)
            try:
                event.save()
            except IntegrityError:
                transaction.savepoint_rollback(sid, using=using)
                return event
            transaction.savepoint_commit(sid, using=using)

        sid = transaction.savepoint(using=using)
        try:
            EventMapping.objects.create(project=project,
                                        group=group,
                                        event_id=event_id)
        except IntegrityError:
            transaction.savepoint_rollback(sid, using=using)
            return event
        transaction.savepoint_commit(sid, using=using)
        transaction.commit_unless_managed(using=using)

        if not raw:
            post_process_group.delay(
                group=group,
                event=event,
                is_new=is_new,
                is_sample=is_sample,
                is_regression=is_regression,
            )

        index_event.delay(event)

        # TODO: move this to the queue
        if is_regression and not raw:
            regression_signal.send_robust(sender=Group, instance=group)

        return event
Esempio n. 45
0
    def post(self, request):
        '''订单创建'''
        # 判断用户是否登录
        user = request.user
        if not user.is_authenticated():
            # 用户未登录
            return JsonResponse({'res': 0, 'errmsg': '用户未登录'})

        # 接收参数
        addr_id = request.POST.get('addr_id')
        pay_method = request.POST.get('pay_method')
        sku_ids = request.POST.get('sku_ids')

        print(pay_method)
        print(sku_ids)
        print(addr_id)

        # 校验参数
        if not all([addr_id, pay_method, sku_ids]):
            return JsonResponse({'res': 1, 'errmsg': '数据不完整'})

        # 校验支付方式
        if pay_method not in OrderInfo.PAY_METHODS.keys():
            return JsonResponse({'res': 2, 'errmsg': '非法的支付方式'})

        # 校验地址
        try:
            addr = Address.objects.get(id=addr_id)
        except Address.DoesNotExist:
            # 地址不存在
            return JsonResponse({'res': 3, 'errmsg': '地址非法'})

        print(addr)
        # 创建订单核心业务

        # 组织参数
        # 订单id:20171122181630+用户id
        order_id = datetime.now().strftime('%Y%m%d%H%M%S') + str(user.id)
        transit_price = 10

        # 总数目和总金额
        total_count = 0
        total_price = 0

        # 设置事务保存点
        save_id = transaction.savepoint()
        try:
            # 向df_order_info表中添加信息
            order = OrderInfo.objects.create(order_id=order_id,
                                             user=user,
                                             addr=addr,
                                             pay_method=pay_method,
                                             total_count=total_count,
                                             total_price=total_price,
                                             transit_prices=transit_price)

            # 用户的订单中有几个商品,需要向df_order_goods表中加入几条记录
            conn = get_redis_connection('default')
            cart_key = 'cart_%d' % user.id
            sku_ids = sku_ids.split(',')
            for sku_id in sku_ids:
                for i in range(3):
                    # 获取商品的信息
                    try:
                        sku = GoodsSKU.objects.get(id=sku_id)
                    except:
                        # 商品不存在
                        transaction.savepoint_rollback(save_id)
                        return JsonResponse({'res': 4, 'errmsg': '商品不存在'})

                    # 从redis中获取用户所要购买的商品和数量
                    count = conn.hget(cart_key, sku_id)

                    # #判断商品的库存
                    if int(count) > sku.stock:
                        transaction.savepoint_rollback(save_id)
                        return JsonResponse({'res': 6, 'errmsg': '商品库存不足'})

                    # 更新商品的库存和销量
                    origin_stock = sku.stock
                    new_stock = origin_stock - int(count)
                    new_sales = sku.sales + int(count)

                    # print('user:%d times:%d stock:%d' %(user.id,i,sku.stock))
                    # import time
                    # time.sleep(10)

                    #update df_goods_sku set stock=new_stock,sales=new_sales
                    #where id =sku_id and stock = origin_stock
                    #返回受影响的行数
                    res = GoodsSKU.objects.filter(id=sku_id,
                                                  stock=origin_stock).update(
                                                      stock=new_stock,
                                                      sales=new_sales)
                    if res == 0:
                        if i == 2:
                            #尝试的第三次失败
                            transaction.savepoint_rollback(save_id)
                            return JsonResponse({'res': 7, 'errmsg': '下单失败2'})
                        continue

                    # 向df_order_goods表中加入记录
                    OrderGoods.objects.create(order=order,
                                              sku=sku,
                                              count=count,
                                              price=sku.price)

                    # 累加计算订单商品的总数目和总价格
                    amount = sku.price * int(count)
                    total_count += int(count)
                    total_price += amount

                    #跳出循环
                    break

            # 更新订单信息表中的商品总数量和总价格
            order.total_count = total_count
            order.total_price = total_price
            order.save()
        except Exception as e:
            transaction.savepoint_rollback(save_id)
            return JsonResponse({'res': 7, 'errmsg': '下单失败'})

        # 提交事务
        transaction.savepoint_commit(save_id)

        # 清除用户购物车中对应的记录
        conn.hdel(cart_key, *sku_ids)

        # 返回应答
        return JsonResponse({'res': 5, 'message': '创建成功'})
Esempio n. 46
0
    def post(self, request):
        # 判断用户是否登录
        user = request.user
        if not user.is_authenticated:
            # 用户未登录
            return JsonResponse({'res': 0, 'errmsg': '用户未登录'})

        # 接受参数
        addr_id = request.POST.get('addr_id')
        pay_method = request.POST.get('pay_method')
        sku_ids = request.POST.get('sku_ids')

        # 校验参数
        if not all([addr_id, pay_method, sku_ids]):
            return JsonResponse({'res': 1, 'errmsg': '数据不完整'})

        # 校验支付方式
        if pay_method not in OrderInfo.PAY_METHODS.keys():
            return JsonResponse({'res': 2, 'errmsg': '非法的支付方式'})

        # 校验地址
        try:
            addr = Address.object.get(id=addr_id)
        except Address.DoesNotExist:
            # 地址不存在
            return JsonResponse({'res': 3, 'errmsg': '地址不存在'})

        # todo: 创建订单核心业务

        # 组织参数
        # 订单id: 年月日时分秒+用户id
        order_id = datetime.now().strftime('%Y%m%d%H%M%S')+str(user.id)

        # 运费
        transit_price = 10

        # 总数目和总金额
        total_count = 0
        total_price = 0

        # 设置事务保存点
        save_id = transaction.savepoint()
        try:
            # todo: 向df_order_info表汇总添加一条记录
            order = OrderInfo.objects.create(order_id=order_id,
                                             user=user,
                                             addr=addr,
                                             pay_method=pay_method,
                                             total_count=total_count,
                                             total_price=total_price,
                                             transit_price=transit_price)

            # todo: 向df_order_goods表中加入记录
            conn = get_redis_connection('default')
            cart_key = 'cart_%d' % user.id

            sku_ids = sku_ids.split(',')
            for sku_id in sku_ids:
                # 获取商品的信息
                try:
                    # select * from df_goods_sku where id=sku_id for update;
                    sku = GoodsSKU.objects.select_for_update().get(id=sku_id)
                except:
                    # 商品不存在
                    transaction.savepoint_rollback(save_id)
                    return JsonResponse({'res': 4, 'errmsg': '商品不存在'})

                print('user:%d stock:%d' % (user.id, sku.stock))
                import time
                time.sleep(10)

                # 从redis中获取用户所要购买的商品的数量
                count = conn.hget(cart_key, sku_id)

                # todo: 判断商品的库存
                if int(count) > sku.stock:
                    transaction.savepoint_rollback(save_id)
                    return JsonResponse({'res': 6, 'errmsg': '商品库存不足'})

                # 添加记录
                OrderGoods.objects.create(order=order,
                                          sku=sku,
                                          count=count,
                                          price=sku.price)

                # todo: 更新商品的库存和销量
                sku.stock -= int(count)
                sku.sales += int(count)
                sku.save()

                # todo: 计算订单商品的总数量和总价格
                amount = sku.price*int(count)
                total_count += int(count)
                total_price += amount

            # todo: 更新订单信息表中的商品的总数量和总价格
            order.total_count = total_count
            order.total_price = total_price
            order.save()
        except Exception as e:
            transaction.savepoint_rollback(save_id)
            return JsonResponse({'res': 7, 'errmsg': '库存不足'})

        # 提交事务
        transaction.savepoint_commit(save_id)

        # todo: 删除购物车中对应的记录
        conn.hdel(cart_key, *sku_ids)

        # 返回应答
        return JsonResponse({'res': 5, 'message': '创建成功'})
    def create(self, validated_data):
        """
        保存订单
        """
        # 获取当前下单用户
        user = self.context['request'].user

        # 组织订单编号 20170903153611+user.id
        # timezone.now() -> datetime
        order_id = timezone.now().strftime('%Y%m%d%H%M%S') + ('%09d' % user.id)

        address = validated_data['address']
        pay_method = validated_data['pay_method']

        # 生成订单
        with transaction.atomic():
            # 创建一个保存点
            save_id = transaction.savepoint()

            try:
                # 创建订单信息
                order = OrderInfo.objects.create(
                    order_id=order_id,
                    user=user,
                    address=address,
                    total_count=0,
                    total_amount=Decimal(0),
                    freight=Decimal(10),
                    pay_method=pay_method,
                    status=OrderInfo.ORDER_STATUS_ENUM['UNSEND']
                    if pay_method == OrderInfo.PAY_METHODS_ENUM['CASH'] else
                    OrderInfo.ORDER_STATUS_ENUM['UNPAID'])
                # 获取购物车信息
                redis_conn = get_redis_connection("cart")
                redis_cart = redis_conn.hgetall("cart_%s" % user.id)
                cart_selected = redis_conn.smembers('cart_selected_%s' %
                                                    user.id)

                # 将bytes类型转换为int类型
                cart = {}
                for sku_id in cart_selected:
                    cart[int(sku_id)] = int(redis_cart[sku_id])

                # # 一次查询出所有商品数据
                # skus = SKU.objects.filter(id__in=cart.k0eys())

                # 处理订单商品
                sku_id_list = cart.keys()
                for sku_id in sku_id_list:
                    while True:
                        sku = SKU.objects.get(id=sku_id)

                        sku_count = cart[sku.id]

                        # 判断库存
                        origin_stock = sku.stock  # 原始库存
                        origin_sales = sku.sales  # 原始销量

                        if sku_count > origin_stock:
                            transaction.savepoint_rollback(save_id)
                            raise serializers.ValidationError('商品库存不足')

                        # 用于演示并发下单
                        import time
                        time.sleep(5)

                        # 减少库存
                        # sku.stock -= sku_count
                        # sku.sales += sku_count
                        # sku.save()
                        new_stock = origin_stock - sku_count
                        new_sales = origin_sales + sku_count

                        # 根据原始库存条件更新,返回更新的条目数,乐观锁
                        ret = SKU.objects.filter(id=sku.id,
                                                 stock=origin_stock).update(
                                                     stock=new_stock,
                                                     sales=new_sales)
                        if ret == 0:
                            continue

                        # 累计商品的SPU 销量信息
                        sku.goods.sales += sku_count
                        sku.goods.save()

                        # 累计订单基本信息的数据
                        order.total_count += sku_count  # 累计总金额
                        order.total_amount += (sku.price * sku_count)  # 累计总额

                        # 保存订单商品
                        OrderGoods.objects.create(
                            order=order,
                            sku=sku,
                            count=sku_count,
                            price=sku.price,
                        )

                        # 更新成功
                        break

                # 更新订单的金额数量信息
                order.total_amount += order.freight
                order.save()

            except serializers.ValidationError:
                raise
            except Exception as e:
                logger.error(e)
                transaction.savepoint_rollback(save_id)
                raise

            # 提交事务
            transaction.savepoint_commit(save_id)

            # 更新redis中保存的购物车数据
            pl = redis_conn.pipeline()
            pl.hdel('cart_%s' % user.id, *cart_selected)
            pl.srem('cart_selected_%s' % user.id, *cart_selected)
            pl.execute()
            return order
Esempio n. 48
0
    def post(self, request):
        """
         保存订单数据
         1. 订单基本信息表 和 订单商品表
        """

        # # 1. 接收参数
        transport_id = request.POST.get('transport')
        sku_ids = request.POST.getlist('sku_ids')
        address_id = request.POST.get('address')

        # 接收用户的id
        user_id = request.session.get("ID")
        user = Users.objects.get(pk=user_id)

        # 验证数据的合法性
        try:
            transport_id = int(transport_id)
            address_id = int(address_id)
            sku_ids = [int(i) for i in sku_ids]
        except:
            return JsonResponse(json_msg(2, "参数错误!"))

        # 验证收货地址和运输方式存在
        try:
            address = UserAddress.objects.get(pk=address_id)
        except UserAddress.DoesNotExist:
            return JsonResponse(json_msg(3, "收货地址不存在!"))

        try:
            transport = Transport.objects.get(pk=transport_id)
        except Transport.DoesNotExist:
            return JsonResponse(json_msg(4, "运输方式不存在!"))

        # 2. 操作数据
        # 创建保存点
        sid = transaction.savepoint()

        # >>>1 . 操作订单基本信息表
        order_sn = "{}{}{}".format(datetime.now().strftime("%Y%m%d%H%M%S"), user_id, random.randrange(10000, 99999))
        address_info = "{}{}{}-{}".format(address.hcity, address.hproper, address.harea, address.brief)
        try:
            order = Order.objects.create(
                user=user,
                order_sn=order_sn,
                transport_price=transport.price,
                transport=transport.name,
                username=address.username,
                phone=address.phone,
                address=address_info
            )
        except:
            return JsonResponse(json_msg(8, "创建订单基本数据失败!"))

        # >>>2. 操作订单商品表
        # 操作redis
        r = get_redis_connection()
        cart_key = get_cart_key(user_id)

        # 准备个变量保存商品总金额
        goods_total_price = 0

        for sku_id in sku_ids:
            # 获取商品对象
            try:
                # .select_for_update()悲观锁,解决并发问题
                goods_sku = GoodsSKU.objects.select_for_update().get(pk=sku_id, is_delete=False, is_on_sale=True)
            except GoodsSKU.DoesNotExist:
                # 回滚数据
                transaction.savepoint_rollback(sid)
                return JsonResponse(json_msg(5, "商品不存在!"))

            # 获取购物车中商品的数量
            # redis 基于内存的存储,有可能数据会丢失
            try:
                count = r.hget(cart_key, sku_id)
                count = int(count)
            except:
                # 回滚数据
                transaction.savepoint_rollback(sid)
                return JsonResponse(json_msg(6, "购物车中数量不存在!"))

            # 判断库存是否足够
            if goods_sku.stock < count:
                # 回滚数据
                transaction.savepoint_rollback(sid)
                return JsonResponse(json_msg(7, "库存不足!"))

            # 保存订单商品表
            order_goods = OrderGoods.objects.create(
                order=order,
                goods_sku=goods_sku,
                price=goods_sku.price,
                count=count
            )

            # 添加商品总金额
            goods_total_price += goods_sku.price * count

            # 扣除库存, 销量增加
            goods_sku.stock -= count
            goods_sku.sale_num += count
            goods_sku.save()

        # 3. 反过头来操作订单基本信息表 商品总金额 和 订单总金额
        # 订单总金额
        try:
            order_price = goods_total_price + transport.price
            order.goods_total_price = goods_total_price
            order.order_price = order_price
            order.save()
        except:
            # 回滚
            transaction.savepoint_rollback(sid)
            return JsonResponse(json_msg(9, "更新订单失败!"))
        # 4. 清空redis中的购物车数据(对应sku_id)
        r.hdel(cart_key, *sku_ids)

        # 下单成功, 提交事务
        transaction.savepoint_commit(sid)
        # 3. 合成响应
        return JsonResponse(json_msg(0, "创建订单成功!", data=order_sn))
Esempio n. 49
0
    def post(self, request):
        '''订单创建'''
        # 判断用户是否登陆
        user = request.user
        if not user.is_authenticated():
            # 用户未登录
            return JsonResponse({'res': 0, 'errmsg': '用户未登录'})

        # 接收参数
        adder_id = request.POST.get('addr_id')
        pay_method = request.POST.get('pay_method')
        sku_ids = request.POST.get('sku_ids')

        # 参数校验
        if not all([adder_id, pay_method, sku_ids]):
            return JsonResponse({'res': 1, 'errmsg': '数据出错'})

        # 校验支付方式
        if pay_method not in OrderInfo.PAY_METHOD.keys():
            return JsonResponse({'res': 2, 'errmsg': '非法支付方式'})

        # 校验地址
        try:
            addr = Address.objects.get(id=adder_id)
        except Address.DoesNotExist:
            return JsonResponse({'res': 3, 'errmsg': '地址非法'})

        # todo:创建订单核心业务
        # 组织参数
        # 订单id:
        order_id = datetime.now().strftime('%Y%m%d%H%M%S') + str(user.id)

        # 运费
        transit_price = 10

        # 总数目与总价格
        total_count = 0
        total_price = 0

        # 设置事物保存点
        save_id = transaction.savepoint()
        try:
            # todo:向df_order_info表中添加一条记录
            order = OrderInfo.objects.create(
                order_id=order_id,
                user=user,
                addr=addr,
                pay_method=pay_method,
                total_count=total_count,
                total_price=total_price,
                transit_price=transit_price,
            )

            # todo: 用户订单有几个商品, 需要向df_order_goods表中加入几条记录
            conn = get_redis_connection('default')
            cart_key = 'cart_%d' % user.id
            sku_ids = sku_ids.split(',')
            for sku_id in sku_ids:
                # 获取商品的信息
                try:
                    # select * from df_goods_sku where id=sku_id for update;
                    sku = GoodsSKU.objects.select_for_update().get(
                        id=sku_id)  # 加锁
                except GoodsSKU.DoesNotExist:
                    # 商品不存在,回滚保存点
                    transaction.savepoint_rollback(save_id)
                    return JsonResponse({'res': 4, 'errmsg': '商品不存在'})
                # 从redis中拿出商品的数目
                count = conn.hget(cart_key, sku_id)

                # todo: 判断商品的库存
                if int(count) > sku.stock:
                    transaction.savepoint_rollback(save_id)
                    return JsonResponse({'res': 5, 'errmsg': '商品库存不足'})

                # todo:向df_order_goods表中添加一条记录
                OrderGoods.objects.create(order=order_id,
                                          sku=sku,
                                          count=count,
                                          price=sku.price)

                # 更新商品的库存与销量
                sku.stock -= int(count)
                sku.sales += int(count)
                sku.save()

                # 累加计算订单商品的总数目和总价格
                amount = sku.price * int(count)
                total_count += int(count)
                total_price += amount

            # todo:更新订单信息表中商品的总数量和总价格
            order.total_count = total_count
            order.total_price = total_price
            order.save()

        except Exception:
            transaction.savepoint_rollback(save_id)
            return JsonResponse({'res': 7, 'message': '下单失败'})

        # 提交事务
        transaction.savepoint_commit(save_id)
        # todo:清除购物车中·对应的记录
        conn.hdel(cart_key, *sku_ids)

        # 返回应答
        return JsonResponse({'res': 6, 'message': '订单创建成功'})
Esempio n. 50
0
    def import_data_inner(self, dataset, dry_run, raise_errors,
                          using_transactions, collect_failed_rows, **kwargs):
        result = self.get_result_class()()
        result.diff_headers = self.get_diff_headers()
        result.total_rows = len(dataset)

        if using_transactions:
            # when transactions are used we want to create/update/delete object
            # as transaction will be rolled back if dry_run is set
            sp1 = savepoint()

        try:
            with atomic_if_using_transaction(using_transactions):
                self.before_import(dataset, using_transactions, dry_run,
                                   **kwargs)
        except Exception as e:
            logger.debug(e, exc_info=e)
            tb_info = traceback.format_exc()
            result.append_base_error(self.get_error_result_class()(e, tb_info))
            if raise_errors:
                raise

        instance_loader = self._meta.instance_loader_class(self, dataset)

        # Update the total in case the dataset was altered by before_import()
        result.total_rows = len(dataset)

        if collect_failed_rows:
            result.add_dataset_headers(dataset.headers)

        for i, row in enumerate(dataset.dict, 1):
            with atomic_if_using_transaction(using_transactions):
                row_result = self.import_row(
                    row,
                    instance_loader,
                    using_transactions=using_transactions,
                    dry_run=dry_run,
                    row_number=i,
                    raise_errors=raise_errors,
                    **kwargs)
            result.increment_row_result_total(row_result)

            if row_result.errors:
                if collect_failed_rows:
                    result.append_failed_row(row, row_result.errors[0])
                if raise_errors:
                    raise row_result.errors[-1].error
            elif row_result.validation_error:
                result.append_invalid_row(i, row, row_result.validation_error)
                if collect_failed_rows:
                    result.append_failed_row(row, row_result.validation_error)
                if raise_errors:
                    raise row_result.validation_error
            if (row_result.import_type != RowResult.IMPORT_TYPE_SKIP
                    or self._meta.report_skipped):
                result.append_row_result(row_result)

        if self._meta.use_bulk:
            # bulk persist any instances which are still pending
            with atomic_if_using_transaction(using_transactions):
                self.bulk_create(using_transactions, dry_run, raise_errors)
                self.bulk_update(using_transactions, dry_run, raise_errors)
                self.bulk_delete(using_transactions, dry_run, raise_errors)

        try:
            with atomic_if_using_transaction(using_transactions):
                self.after_import(dataset, result, using_transactions, dry_run,
                                  **kwargs)
        except Exception as e:
            logger.debug(e, exc_info=e)
            tb_info = traceback.format_exc()
            result.append_base_error(self.get_error_result_class()(e, tb_info))
            if raise_errors:
                raise

        if using_transactions:
            if dry_run or result.has_errors():
                savepoint_rollback(sp1)
            else:
                savepoint_commit(sp1)

        return result
Esempio n. 51
0
def order_handle(request):
    tran_id = transaction.savepoint()
    #接受购物车编号

    cart_ids = request.POST.get('cart_ids')
    # print(cart_ids)
    # print('输出cart_ids')

    try:
        #创建订单对象
        order = OrderInfo()
        now = datetime.now()
        uid = request.session['user_id']
        order.oid = '%s%d' % (now.strftime('%Y%m%d%H%M%S'), uid)
        order.user_id = uid

        order.odate = now
        # print('在total之前')
        order.ototal = Decimal(request.POST.get('total'))
        # print('在total之后')
        order.save()

        #创建详单对象
        # print('创建详单')
        cart_ids1 = [int(item) for item in cart_ids.split(',')]  #[45, 46]
        # print(cart_ids1)

        for id1 in cart_ids1:
            detail = OrderDetailInfo()
            detail.order = order
            #查询购物车信息
            # print('查询购物车信息')
            cart = CartInfo.objects.get(id=id1)
            #盘攒商品库存
            # print('盘赞商品库存')
            goods = cart.goods
            if goods.gkucun >= cart.count:  #如果库存大于购买数量
                #判断商品库存
                # print('判断商品库存')
                goods.gkucun = cart.goods.gkucun - cart.count
                goods.save()
                #完善订单信息
                # print('完善订单信息')
                detail.goods_id = goods.id
                detail.price = goods.gprice
                detail.count = cart.count
                detail.save()
                # print('保存订单信息')
                #删除购物车数据
                cart.delete()
                # print('删除订单信息')
            else:  #如果库存小于购买数量
                transaction.savepoint_rollback(tran_id)
                return redirect('/cart/')
                #return HttpResponse('no')
        transaction.savepoint_commit(tran_id)
    except Exception as e:
        print('===================%s' % e)
        transaction.savepoint_rollback(tran_id)

    # return HttpResponse('ok')
    # print('ok')
    return redirect('/user/order/')
Esempio n. 52
0
    def post(request, lang):

        sid = transaction.savepoint()

        if lang == 'ja':
            form = VideoForm(request.POST)
            video_model = Video()
        else:
            form = VideoEnForm(request.POST)
            video_model = VideoEn()
        if form.errors:
            messages.add_message(request, messages.INFO,
                                 dict(form.errors.items()))

        if form.is_valid():
            try:
                res_video = video_model.create_video({
                    'published_at':
                    form.cleaned_data.get('published_at'),
                    'title':
                    form.cleaned_data.get('title'),
                    'text':
                    form.cleaned_data.get('text'),
                    'youtube_id':
                    form.cleaned_data.get('youtube_id'),
                })
                add_introductions = form.cleaned_data.get('introductions')
                if add_introductions:
                    video_model.add_introduction(res_video.id,
                                                 add_introductions)
                add_categories = form.cleaned_data.get('categories')
                if add_categories:
                    video_model.add_category(res_video.id, add_categories)
                add_topics = form.cleaned_data.get('topics')
                if add_topics:
                    video_model.add_topic(res_video.id, add_topics)

                transaction.savepoint_commit(sid)

                return HttpResponseRedirect('/{}/admin/videos'.format(lang))

            except:
                transaction.savepoint_rollback(sid)
                pass

        if lang == 'ja':
            topic_model = Topic()
            introduction_model = Introduction()
        else:
            topic_model = TopicEn()
            introduction_model = IntroductionEn()

        select_categories = []
        if form.cleaned_data.get('categories'):
            category_ids = list(map(int, form.cleaned_data.get('categories')))
            select_categories = Category.get_by_ids(category_ids)

        select_introductions = []
        if form.cleaned_data.get('introductions'):
            title_ids = list(map(int, form.cleaned_data.get('introductions')))
            select_introductions = introduction_model.get_by_ids(title_ids)

        select_topics = []
        if form.cleaned_data.get('topics'):
            topic_ids = list(map(int, form.cleaned_data.get('topics')))
            select_topics = topic_model.get_by_ids(topic_ids)

        select_videos = []
        if form.cleaned_data.get('videos'):
            video_ids = list(map(int, form.cleaned_data.get('videos')))
            select_videos = video_model.get_by_ids(video_ids)

        groups = Group.get_all()

        return TemplateResponse(
            request, 'video_create.html', {
                'title': '新規投稿 | 動画 | FEED App 管理',
                'select_categories': select_categories,
                'select_introductions': select_introductions,
                'select_topics': select_topics,
                'select_videos': select_videos,
                'groups': groups,
                'form_data': form.cleaned_data,
                'error_messages': get_error_message(request),
                'lang': lang,
            })
Esempio n. 53
0
    def post(self, request):
        # 创建订单

        # 判断用户是否登录
        user = request.user
        if not user.is_authenticated():
            return JsonResponse({'res': 0, 'errmsg': '用户未登录'})

        # 接收数据
        addr_id = request.POST.get('addr_id')
        pay_method = request.POST.get('pay_method')
        sku_ids = request.POST.get('sku_ids')

        # 判断数据是否完整
        if not all([addr_id, pay_method, sku_ids]):
            return JsonResponse({'res': 1, 'errmsg': '数据不完整'})

        # 校验支付方式
        if pay_method not in OrderInfo.PAY_METHODS.keys():
            return JsonResponse({'res': 2, 'errmsg': '非法的支付方式'})

        # 校验地址
        try:
            addr = Address.objects.get(id=addr_id)
        except Exception as e:
            # 地址不存在
            return JsonResponse({'res': 3, 'errmsg': '地址不存在'})

        # 创建订单核心
        # 组织参数
        # 订单id:20190605231212+用户id

        order_id = datetime.now().strftime('%Y%m%d%H%M%S') + str(user.id)

        # 运费
        transit_price = 10

        # 总数目和总金额
        total_count = 0
        total_price = 0

        # 设置事物保存点
        save_id = transaction.savepoint()

        try:

            # 向df_order_info插入一条数据
            order = OrderInfo.objects.create(order_id=order_id,
                                             user=user,
                                             addr=addr,
                                             pay_method=pay_method,
                                             total_price=total_price,
                                             total_count=total_count,
                                             transit_price=transit_price)

            # 向df_order_goods表中插入几条数据
            conn = get_redis_connection('default')
            cart_key = 'cart_%d' % user.id

            sku_ids = sku_ids.split(',')
            for sku_id in sku_ids:
                # 获取商品的信息
                for i in range(3):
                    try:
                        # sku = GoodsSKU.objects.select_for_update().get(id=sku_id)  解决并发冲突 --> 悲观锁
                        sku = GoodsSKU.objects.get(id=sku_id)
                    except Exception as e:
                        # 商品不存在
                        transaction.savepoint_rollback(save_id)
                        return JsonResponse({'res': 4, 'errmsg': '商品不存在'})

                    # 从redis中获取用户所要购买的商品的数量
                    count = conn.hget(cart_key, sku_id)

                    # 判断商品的库存
                    if int(count) > sku.stock:
                        transaction.savepoint_rollback(save_id)
                        return JsonResponse({'res': 6, 'errmsg': '商品库存不足'})

                    # 更新商品的库存和销量
                    orgin_stock = sku.stock
                    new__stock = orgin_stock - int(count)
                    new_sales = sku.sales + int(count)

                    # 返回受影响的行
                    res = GoodsSKU.objects.filter(
                        id=sku_id, stock=orgin_stock).update(stock=new__stock,
                                                             sales=new_sales)
                    if res == 0:
                        if i == 2:
                            # 尝试第三次
                            transaction.savepoint_rollback(save_id)
                            return JsonResponse({'res': 7, 'errmsg': '下单失败'})
                        continue

                    # 向df_order_goods表中插入1条数据
                    OrderGoods.objects.create(order=order,
                                              sku=sku,
                                              count=count,
                                              price=sku.price)

                    # 累加订单商品的总数量和总金额
                    amount = sku.price * int(count)
                    total_count += int(count)
                    total_price += amount

                    # 跳出循环
                    break

            # 更新订单信息表中的商品总数量和总金额
            order.total_price = total_price
            order.total_count = total_count
            order.save()

        except Exception as e:
            transaction.savepoint_rollback(save_id)
            return JsonResponse({'res': 7, 'errmsg': '下单失败'})

        # 提交事物
        transaction.savepoint_commit(save_id)

        # 清楚用户购物车中对应的记录
        conn.hdel(cart_key, *sku_ids)

        # 返回应答
        return JsonResponse({'res': 5, 'message': '创建成功'})
Esempio n. 54
0
    def post(self, request):
        user = request.user

        if not user.is_authenticated:
            return JsonResponse({'res': 0, 'errmsg': '用户未登录!'})

        addr_id = request.POST.get('addr_id')
        pay_method = request.POST.get('pay_method')
        sku_ids = request.POST.get('sku_ids')

        if not all([addr_id, pay_method, sku_ids]):
            return JsonResponse({'res': 1, 'errmsg': '参数不完整!'})

        # todo 校验支付方式
        if pay_method not in OrderInfo.PAY_METHODS.keys():
            return JsonResponse({'res': 2, 'errmsg': '非法的支付方式!'})

        try:
            addr = Address.objects.get(pk=addr_id)
        except Address.DoesNotExist:
            return JsonResponse({'res': 3, 'errmsg': '地址非法'})

        # TODO: 创建订单
        order_id = datetime.now().strftime('%Y%m%d%H%M%S') + str(user.id)
        # 运费
        transit_price = 10  # 假数据, 写死
        total_count = 0
        total_price = 0
        coon = get_redis_connection('default')
        cart_key = 'cart_%d' % user.id
        # 设置保存点
        save_id = transaction.savepoint()
        try:
            # TODO  想订单信息表中添加一条记录
            order = OrderInfo.objects.create(order_id=order_id,
                                             user=user,
                                             addr=addr,
                                             pay_method=pay_method,
                                             total_count=total_count,
                                             total_price=total_price,
                                             transit_price=transit_price)

            # todo 用户的订单中有几个商品就要添加几条记录
            sku_ids = sku_ids.split(',')
            for sku_id in sku_ids:
                try:
                    sku = GoodsSKU.objects.select_for_update().get(
                        id=sku_id)  # 悲观锁
                except GoodsSKU.DoesNotExist:
                    transaction.savepoint_rollback(save_id)
                    return JsonResponse({'res': 4, 'errmsg': '商品不存在!'})

                # 获取商品的数目
                count = coon.hget(cart_key, sku_id)

                # todo 判断商品的库存
                if int(count) > sku.stock:
                    transaction.savepoint_rollback(save_id)
                    return JsonResponse({'res': 6, 'errmsg': '商品库存不足'})

                # todo to订单信息表中添加一条记录
                OrderGoods.objects.create(
                    order=order,
                    sku=sku,
                    count=int(count),
                    price=sku.price,
                )

                # todo 更新商品的库存销量和库存
                sku.stock -= int(count)
                sku.sales += int(count)
                sku.save()

                # todo 累加计算商品的订单的总数量和总价格
                amount = sku.price * int(count)
                total_count += int(count)
                total_price += amount

            # todo 更新订单信息表中的商品的总数量和价格
            order.total_count = total_count
            order.total_price = total_price
            order.save()
        except Exception:
            transaction.savepoint_rollback(save_id)
            return JsonResponse({'res': 7, 'errmsg': '下单失败!'})
        # 提交
        transaction.savepoint_commit(save_id)
        # todo 清楚用户的购物车记录
        coon.hdel(cart_key, *sku_ids)

        return JsonResponse({'res': 5, 'message': '创建成功!'})
Esempio n. 55
0
    def import_data(self,
                    dataset,
                    dry_run=False,
                    raise_errors=False,
                    use_transactions=None,
                    **kwargs):
        """
        Imports data from ``tablib.Dataset``. Refer to :doc:`import_workflow`
        for a more complete description of the whole import process.

        :param dataset: A ``tablib.Dataset``

        :param raise_errors: Whether errors should be printed to the end user
            or raised regularly.

        :param use_transactions: If ``True`` import process will be processed
            inside transaction.

        :param dry_run: If ``dry_run`` is set, or error occurs, transaction
            will be rolled back.
        """
        result = self.get_result_class()()
        result.diff_headers = self.get_diff_headers()
        result.totals = OrderedDict([(RowResult.IMPORT_TYPE_NEW, 0),
                                     (RowResult.IMPORT_TYPE_UPDATE, 0),
                                     (RowResult.IMPORT_TYPE_DELETE, 0),
                                     (RowResult.IMPORT_TYPE_SKIP, 0),
                                     (RowResult.IMPORT_TYPE_ERROR, 0),
                                     ('total', len(dataset))])

        if use_transactions is None:
            use_transactions = self.get_use_transactions()

        if use_transactions is True:
            # when transactions are used we want to create/update/delete object
            # as transaction will be rolled back if dry_run is set
            real_dry_run = False
            sp1 = savepoint()
        else:
            real_dry_run = dry_run

        try:
            self.before_import(dataset, real_dry_run, **kwargs)
        except Exception as e:
            logging.exception(e)
            tb_info = traceback.format_exc()
            result.base_errors.append(self.get_error_result_class()(e,
                                                                    tb_info))
            if raise_errors:
                if use_transactions:
                    savepoint_rollback(sp1)
                raise

        instance_loader = self._meta.instance_loader_class(self, dataset)

        # Update the total in case the dataset was altered by before_import()
        result.totals['total'] = len(dataset)

        for row in dataset.dict:
            row_result = self.import_row(row, instance_loader, real_dry_run,
                                         **kwargs)
            if row_result.errors:
                result.totals[row_result.IMPORT_TYPE_ERROR] += 1
                if raise_errors:
                    if use_transactions:
                        savepoint_rollback(sp1)
                    raise row_result.errors[-1].error
            else:
                result.totals[row_result.import_type] += 1
            if (row_result.import_type != RowResult.IMPORT_TYPE_SKIP
                    or self._meta.report_skipped):
                result.append_row_result(row_result)

        try:
            self.after_import(dataset, result, real_dry_run, **kwargs)
        except Exception as e:
            logging.exception(e)
            tb_info = traceback.format_exc()
            result.base_errors.append(self.get_error_result_class()(e,
                                                                    tb_info))
            if raise_errors:
                if use_transactions:
                    savepoint_rollback(sp1)
                raise

        if use_transactions:
            if dry_run or result.has_errors():
                savepoint_rollback(sp1)
            else:
                savepoint_commit(sp1)

        return result
Esempio n. 56
0
    def post(self, request):
        user = request.user
        # 获取数据  前端发送的数据类型是json字符串
        data = json.loads(request.body.decode())
        title = data.get('title')  # 标题
        price = data.get('price')  # 价格
        area_id = data.get('area_id')  # 城区id
        address = data.get('address')  # 房屋地址
        room_count = data.get('room_count')  # 房屋数目
        acreage = data.get('acreage')  # 房屋面积
        unit = data.get('unit')  # 房屋单元,如:几室几厅
        capacity = data.get('capacity')  # 房屋容纳的人数
        beds = data.get('beds')  # 房屋床铺的配置
        deposit = data.get('deposit')  #  房屋押金
        min_days = data.get('min_days')  # 最少入住天数
        max_days = data.get('max_days')  #  最大入住天数,0表示不限制
        # 类型是列表可能为空 不需要去判断这个数据是否存在
        facility_ids = data.get('facility')  #  用户选择的设施信息id列表,如:[7, 8]
        # 验证数据
        if not all([
                title, price, area_id, address, room_count, acreage, unit,
                capacity, beds, deposit, min_days, max_days
        ]):
            return http.JsonResponse({"errno": RET.PARAMERR, "errmsg": "参数错误"})
        # 最少入住天数不能小于0
        if eval(min_days) < 0 or eval(max_days) < 0:
            return http.JsonResponse({"errno": RET.PARAMERR, "errmsg": "参数错误"})
        try:
            # 将 price 和 deposit进行数据类型转换因为获取的这两个数据是字符串类型, 数据库中是int
            # 数据里这两个单位是分
            price = int(float(price) * 100)
            deposit = int(float(deposit) * 100)
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({"errno": RET.PARAMERR, "errmsg": "参数错误"})

        # 因为添加数据的时候 对同一个对象会操作两次 使用事件
        with transaction.atomic():
            save_id = transaction.savepoint()
            # 保存数据
            try:
                house = House.objects.create(user=user,
                                             title=title,
                                             price=price,
                                             area_id=area_id,
                                             address=address,
                                             room_count=room_count,
                                             acreage=acreage,
                                             unit=unit,
                                             capacity=capacity,
                                             beds=beds,
                                             deposit=deposit,
                                             min_days=min_days,
                                             max_days=max_days)
            except DatabaseError as e:
                logger.error(e)
                transaction.savepoint_rollback(save_id)
                return http.JsonResponse({
                    "errno": RET.DBERR,
                    "errmsg": "数据库保存失败"
                })

            # 添加设施  房间表和设施表是多对多的关系  facility_ids 中保存的是设施的id
            try:
                if facility_ids:
                    # facility_ids 不为空 则查找对应的设施名字 in表示范围查询, 是否包含在范围内
                    facilitys = Facility.objects.filter(id__in=facility_ids)
                    for facility in facilitys:
                        house.facility.add(facility)
            except DatabaseError as e:
                logger.error(e)
                transaction.savepoint_rollback(save_id)
                return http.JsonResponse({
                    "errno": RET.DBERR,
                    "errmsg": "数据库保存失败"
                })
            transaction.savepoint_commit(save_id)
        return http.JsonResponse({
            "errno": RET.OK,
            "errmsg": "发布成功",
            "data": {
                "house_id": house.id
            }
        })
    def update(self, request, project_pk, pk=None):
        errors = {}
        is_valid = True
        nested_data = dict(
            sample_event=request.data.get("sample_event"),
            quadrat_collection=request.data.get("quadrat_collection"),
            observers=request.data.get("observers"),
            obs_quadrat_benthic_percent=request.data.get(
                "obs_quadrat_benthic_percent"),
            obs_colonies_bleached=request.data.get("obs_colonies_bleached"),
        )
        bleaching_qc_data = {
            k: v
            for k, v in request.data.items() if k not in nested_data
        }
        bleaching_qc_id = bleaching_qc_data["id"]

        context = dict(request=request)

        # Save models in a transaction
        sid = transaction.savepoint()
        try:
            bleaching_qc = BleachingQuadratCollection.objects.get(
                id=bleaching_qc_id)

            # Observers
            check, errs = save_one_to_many(
                foreign_key=("transectmethod", bleaching_qc_id),
                database_records=bleaching_qc.observers.all(),
                data=request.data.get("observers") or [],
                serializer_class=ObserverSerializer,
                context=context,
            )
            if check is False:
                is_valid = False
                errors["observers"] = errs

            # Observations - Colonies Bleached
            check, errs = save_one_to_many(
                foreign_key=("bleachingquadratcollection", bleaching_qc_id),
                database_records=bleaching_qc.obscoloniesbleached_set.all(),
                data=request.data.get("obs_colonies_bleached") or [],
                serializer_class=ObsColoniesBleachedSerializer,
                context=context,
            )
            if check is False:
                is_valid = False
                errors["obs_colonies_bleached"] = errs

            # Observations - Quadrat Benthic Percent
            check, errs = save_one_to_many(
                foreign_key=("bleachingquadratcollection", bleaching_qc_id),
                database_records=bleaching_qc.obsquadratbenthicpercent_set.all(
                ),
                data=request.data.get("obs_quadrat_benthic_percent") or [],
                serializer_class=ObsQuadratBenthicPercentSerializer,
                context=context,
            )
            if check is False:
                is_valid = False
                errors["obs_quadrat_benthic_percent"] = errs

            # Sample Event
            check, errs = save_model(
                data=nested_data["sample_event"],
                serializer_class=SampleEventSerializer,
                context=context,
            )
            if check is False:
                is_valid = False
                errors["sample_event"] = errs

            # Quadrat Collection
            check, errs = save_model(
                data=nested_data["quadrat_collection"],
                serializer_class=QuadratCollectionSerializer,
                context=context,
            )
            if check is False:
                is_valid = False
                errors["quadrat_collection"] = errs

            # Bleaching Quadrat Collection
            check, errs = save_model(
                data=bleaching_qc_data,
                serializer_class=BleachingQuadratCollectionSerializer,
                context=context,
            )
            if check is False:
                is_valid = False
                errors["bleaching_quadrat_collection"] = errs

            if is_valid is False:
                transaction.savepoint_rollback(sid)
                return Response(data=errors,
                                status=status.HTTP_400_BAD_REQUEST)

            clean_sample_event_models(nested_data["sample_event"])

            transaction.savepoint_commit(sid)
            bleaching_qc = BleachingQuadratCollection.objects.get(
                id=bleaching_qc_id)
            return Response(
                BleachingQuadratCollectionMethodSerializer(bleaching_qc).data,
                status=status.HTTP_200_OK,
            )
        except:
            transaction.savepoint_rollback(sid)
            raise
Esempio n. 58
0
def get_or_create_map(generator, args):
    """
    A wrapper function for a map generator which protects against race
    conditions in map generation. You should use this instead of calling a
    generator directly.
    
    @param generator: The generator to use
    @param args: Any extra arguments to pass to the generator function
    
    This assumes that generator is functional, i.e. its return value is
    determined solely by its arguments. In the case that a map is requested
    again before the original map generation has finished, the following
    happens:
    * Nothing has yet been saved to the database as we have to wait for the
      metadata to come back. Hence, we get a DoesNotExist.
    * The map is regenerated. Due to the atomic nature of filesystem writes
      we can guarantee that we won't get a funnily spliced file written by
      the function f.
    * The first call saves the GeneratedMap instance to the database.
    * The second call attempts to do the same, but it would result in a
      duplicate primary key, and so it throws an IntegrityError.
    * Due to the functional nature of f, we know we have the correct metadata
      for the map that has been generated, and that it will match that
      already stored in the database. As such, we can leave the database
      alone and return the metadata just generated.
    Assuming that if we get a DoesNotExist that there won't be one by the
    time we come to write leads to a race condition given the non-zero
    duration of f. Subsequent attempts to get the map with that hash then
    throws a MultipleObjectsReturned exception. Yes, this did happen. Seven
    times, no less.
    """

    start_time = time.time()
    
    # Generate a hash based on the arguments for this map
    hash = hashlib.sha224(pickle.dumps(repr(args))).hexdigest()[:16]
    
    # Try fetching the map if it already exists
    try:
        generated_map = GeneratedMap.objects.get(hash=hash)
        generated_map.last_accessed = datetime.utcnow()
        generated_map.save()
        metadata = generated_map.metadata
        
        # Except if the current map is marked as faulty (e.g., missing OSM tile,
        # in which case we delete it and raise DoesNotExist to get it
        # regenerated)
        if generated_map.faulty:
            generated_map.delete()
            logger.debug("Found previously generated map: %s, but it's " + \
                         "faulty, so regenerating", hash)
            raise GeneratedMap.DoesNotExist()
        else:
            logger.debug("Found previously generated map: %s", hash)
            
    
    # If it doesn't exist, generate it
    except GeneratedMap.DoesNotExist:
        generated_map_dir = get_generated_map_dir()
        if not os.path.exists(generated_map_dir):
            os.makedirs(generated_map_dir)
        try:
            # Call the generator to generate it
            metadata = generator(filename=os.path.join(generated_map_dir, hash),
                                 *args)
        except MapGenerationError as e:
            # If a map generation error occurs, then mark this map as faulty
            # this means that it is deleted next time it is requested, forcing
            # it to be re-generated next time (hopefully the error is transient)
            metadata = e.metadata
            faulty = True
        else:
            # If no exception was raised, we mark it as non-faulty
            faulty = False
        
        generated_map = GeneratedMap(
            hash = hash,
            generated = datetime.utcnow(),
            last_accessed = datetime.utcnow(),
            faulty = faulty,
        )
        generated_map.metadata = metadata
        
        # This may fail, so we use a transaction savepoint in case we need to
        # roll back the transaction - not doing this causes any future database
        # queries to fail
        savepoint = transaction.savepoint()
        try:
            generated_map.save()
        except IntegrityError:
            # This means a race error was generated, but because of the
            # functional nature of generator, we can carry on here
            logger.debug("Map generated: %s, took %.5f seconds (with race)",
                         hash, time.time()-start_time)
            transaction.savepoint_rollback(savepoint)
        else:
            logger.debug("Map generated: %s, took %.5f seconds",
                         hash, time.time()-start_time)
            transaction.savepoint_commit(savepoint)
        
        # If there are any maps older than a week, regenerate them
        to_delete = GeneratedMap.objects.filter(
          generated__lt=datetime.now()-timedelta(weeks=1)).order_by('generated')
        if to_delete.count() > 0:
            # But only clear up 50 at a time
            try:
                youngest = to_delete[0].last_accessed
                to_delete = to_delete[:50]
                for generated_map in to_delete:
                    generated_map.delete()
                age = (datetime.now()-youngest)
                age = age.days*24 + age.seconds/3600.0
                logger.info("Cleared out old maps, youngest is %f hours", age)
            except IndexError:
                logger.info("Maps disappeared whilst trying to delete - race condition?", exc_info=True)
    
    return hash, metadata
Esempio n. 59
0
def addon_view_or_download_file(auth, path, provider, **kwargs):
    extras = request.args.to_dict()
    extras.pop('_', None)  # Clean up our url params a bit
    action = extras.get('action', 'view')
    node = kwargs.get('node') or kwargs['project']

    node_addon = node.get_addon(provider)

    provider_safe = markupsafe.escape(provider)
    path_safe = markupsafe.escape(path)
    project_safe = markupsafe.escape(node.project_or_component)

    if not path:
        raise HTTPError(httplib.BAD_REQUEST)

    if not isinstance(node_addon, BaseStorageAddon):
        raise HTTPError(
            httplib.BAD_REQUEST,
            data={
                'message_short':
                'Bad Request',
                'message_long':
                'The {} add-on containing {} is no longer connected to {}.'.
                format(provider_safe, path_safe, project_safe)
            })

    if not node_addon.has_auth:
        raise HTTPError(
            httplib.UNAUTHORIZED,
            data={
                'message_short':
                'Unauthorized',
                'message_long':
                'The {} add-on containing {} is no longer authorized.'.format(
                    provider_safe, path_safe)
            })

    if not node_addon.complete:
        raise HTTPError(
            httplib.BAD_REQUEST,
            data={
                'message_short':
                'Bad Request',
                'message_long':
                'The {} add-on containing {} is no longer configured.'.format(
                    provider_safe, path_safe)
            })

    savepoint_id = transaction.savepoint()
    file_node = BaseFileNode.resolve_class(provider,
                                           BaseFileNode.FILE).get_or_create(
                                               node, path)

    # Note: Cookie is provided for authentication to waterbutler
    # it is overriden to force authentication as the current user
    # the auth header is also pass to support basic auth
    version = file_node.touch(
        request.headers.get('Authorization'),
        **dict(extras, cookie=request.cookies.get(settings.COOKIE_NAME)))

    if version is None:
        # File is either deleted or unable to be found in the provider location
        # Rollback the insertion of the file_node
        transaction.savepoint_rollback(savepoint_id)
        if not file_node.pk:
            redirect_file_node = BaseFileNode.load(path)
            # Allow osfstorage to redirect if the deep url can be used to find a valid file_node
            if redirect_file_node and redirect_file_node.provider == 'osfstorage' and not redirect_file_node.is_deleted:
                return redirect(
                    redirect_file_node.node.web_url_for(
                        'addon_view_or_download_file',
                        path=redirect_file_node._id,
                        provider=redirect_file_node.provider))
            raise HTTPError(httplib.NOT_FOUND,
                            data={
                                'message_short':
                                'File Not Found',
                                'message_long':
                                'The requested file could not be found.'
                            })
        return addon_deleted_file(file_node=file_node, path=path, **kwargs)
    else:
        transaction.savepoint_commit(savepoint_id)

    # TODO clean up these urls and unify what is used as a version identifier
    if request.method == 'HEAD':
        return make_response(('', httplib.FOUND, {
            'Location':
            file_node.generate_waterbutler_url(
                **dict(extras,
                       direct=None,
                       version=version.identifier,
                       _internal=extras.get('mode') == 'render'))
        }))

    if action == 'download':
        format = extras.get('format')
        _, extension = os.path.splitext(file_node.name)
        # avoid rendering files with the same format type.
        if format and '.{}'.format(format) != extension:
            return redirect('{}/export?format={}&url={}'.format(
                MFR_SERVER_URL, format,
                urllib.quote(
                    file_node.generate_waterbutler_url(
                        **dict(extras,
                               direct=None,
                               version=version.identifier,
                               _internal=extras.get('mode') == 'render')))))
        return redirect(
            file_node.generate_waterbutler_url(
                **dict(extras,
                       direct=None,
                       version=version.identifier,
                       _internal=extras.get('mode') == 'render')))

    if action == 'get_guid':
        draft_id = extras.get('draft')
        draft = DraftRegistration.load(draft_id)
        if draft is None or draft.is_approved:
            raise HTTPError(httplib.BAD_REQUEST,
                            data={
                                'message_short':
                                'Bad Request',
                                'message_long':
                                'File not associated with required object.'
                            })
        guid = file_node.get_guid(create=True)
        guid.referent.save()
        return dict(guid=guid._id)

    if len(request.path.strip('/').split('/')) > 1:
        guid = file_node.get_guid(create=True)
        return redirect(
            furl.furl('/{}/'.format(guid._id)).set(args=extras).url)
    return addon_view_file(auth, node, file_node, version)
    def import_data(self,
                    dataset,
                    dry_run=False,
                    raise_errors=False,
                    use_transactions=None,
                    **kwargs):
        """
        Imports data from ``dataset``.

        ``use_transactions``
            If ``True`` import process will be processed inside transaction.
            If ``dry_run`` is set, or error occurs, transaction will be rolled
            back.
        """
        result = Result()
        result.diff_headers = self.get_diff_headers()

        if use_transactions is None:
            use_transactions = self.get_use_transactions()

        if use_transactions is True:
            # when transactions are used we want to create/update/delete object
            # as transaction will be rolled back if dry_run is set
            real_dry_run = False
            sp1 = savepoint()
        else:
            real_dry_run = dry_run

        try:
            self.before_import(dataset, real_dry_run, **kwargs)
        except Exception as e:
            logging.exception(e)
            tb_info = traceback.format_exc(2)
            result.base_errors.append(Error(repr(e), tb_info))
            if raise_errors:
                if use_transactions:
                    savepoint_rollback(sp1)
                raise

        instance_loader = self._meta.instance_loader_class(self, dataset)

        for row in dataset.dict:
            try:
                row_result = RowResult()
                instance, new = self.get_or_init_instance(instance_loader, row)
                if new:
                    row_result.import_type = RowResult.IMPORT_TYPE_NEW
                else:
                    row_result.import_type = RowResult.IMPORT_TYPE_UPDATE
                row_result.new_record = new
                original = deepcopy(instance)
                if self.for_delete(row, instance):
                    if new:
                        row_result.import_type = RowResult.IMPORT_TYPE_SKIP
                        row_result.diff = self.get_diff(
                            None, None, real_dry_run)
                    else:
                        row_result.import_type = RowResult.IMPORT_TYPE_DELETE
                        self.delete_instance(instance, real_dry_run)
                        row_result.diff = self.get_diff(
                            original, None, real_dry_run)
                else:
                    self.import_obj(instance, row, real_dry_run)
                    if self.skip_row(instance, original):
                        row_result.import_type = RowResult.IMPORT_TYPE_SKIP
                    else:
                        self.save_instance(instance, real_dry_run)
                        self.save_m2m(instance, row, real_dry_run)
                        # Add object info to RowResult for LogEntry
                        row_result.object_repr = force_text(instance)
                        row_result.object_id = instance.pk
                    row_result.diff = self.get_diff(original, instance,
                                                    real_dry_run)
            except Exception as e:
                # There is no point logging a transaction error for each row
                # when only the original error is likely to be relevant
                if not isinstance(e, TransactionManagementError):
                    logging.exception(e)
                tb_info = traceback.format_exc(2)
                row_result.errors.append(Error(e, tb_info, row))
                if raise_errors:
                    if use_transactions:
                        savepoint_rollback(sp1)
                    six.reraise(*sys.exc_info())
            if (row_result.import_type != RowResult.IMPORT_TYPE_SKIP
                    or self._meta.report_skipped):
                result.rows.append(row_result)

        if use_transactions:
            if dry_run or result.has_errors():
                savepoint_rollback(sp1)
            else:
                savepoint_commit(sp1)

        return result