Ejemplo n.º 1
0
    def fdump(self, opts):
        print("te.fdump")
        data = list()
        kw = dict()

        qs = Transaction.objects.all()

        if 'tstamp' in opts:
            dt = myutils.unixtime2dt(opts['tstamp'])
            qs = qs.filter(created__gre=dt)

        for f in [
                'machine', 'model_name', 'rid', 'prid', 'srid', 'name', 'value'
        ]:
            if not f in opts:
                continue
            if isinstance(opts[f], list):
                kw[f + '__in'] = opts[f]
            else:
                kw[f] = opts[f]

        qs = qs.filter(**kw)

        for t in qs:
            data.append(t.data())
        return data
Ejemplo n.º 2
0
 def reinit(cls):
     print("deleted", cls.objects.all().delete())
     dt = myutils.unixtime2dt(0)
     for srv in cls.srv:
         ts = TransactionServer(machine=srv['machine'],
                                url=srv['url'],
                                private=srv['private'],
                                netprocess=srv['netprocess'],
                                lastupdate=dt)
         print(ts)
         ts.save()
Ejemplo n.º 3
0
    def restore_helper(self, o, data):

        skipfields = ['id']

        rid = data['rid']

        print(data)

        if isinstance(o, ModelBase):
            print("find by rid:", rid)
            try:
                p = o.objects.get(rid=rid)
            except ObjectDoesNotExist:
                print("Create", o)
                o = o()

        # now o is always instance

        print("restore rid", rid)

        for f in o._meta.get_fields():

            if f.name in skipfields:
                continue

            if not f.is_relation:
                if f.name in data:
                    if isinstance(f, models.fields.DateTimeField) and data[
                            f.name] is not None:
                        setattr(o, f.name, myutils.unixtime2dt(data[f.name]))
                    else:
                        # no datetime, simple field
                        setattr(o, f.name, data[f.name])
                else:
                    print("missing key {} in data".format(f.name))
                # print "{} = {}".format(f.name,repr(getattr(o,f.name)))
            elif isinstance(f, models.ForeignKey):
                relmodel = f.related_model
                relname = f.related_model.__name__
                # try to get relrid
                # maybe in parents
                rel_instance = self.rid2instance(f.related_model, None,
                                                 data['_parents'])
                print("FK to {} {} {}".format(repr(relname), relmodel,
                                              rel_instance))
                print(data)
                setattr(o, f.name, rel_instance)

        return o
Ejemplo n.º 4
0
    def load_transaction(self, o, t, fmethod=None):
        def trans(o, fmethod, name, value):
            mname = o.__class__.__name__
            # print "TRANS {} {} : {} ({}={})".format(mname, o, fmethod, name, value)

            kwargs = dict()
            kwargs['__'.join(fmethod[1:])] = value

            try:
                rel_o = o._meta.get_field(name).related_model.objects.get(
                    **kwargs)
            except ObjectDoesNotExist as e:
                raise TransactionWarning("{} {} {}={} EXCEPTION: {}".format(
                    mname, fmethod, name, value, str(e)))

            return rel_o

        if isinstance(fmethod, tuple):
            if fmethod[0] == 'DT':
                # print "DT {} = {}".format(t['name'],repr(t['value']))
                if t['value'] is None:
                    setattr(o, t['name'], None)
                else:
                    setattr(o, t['name'], myutils.unixtime2dt(int(t['value'])))
            elif fmethod[0] == 'INT':
                setattr(o, t['name'], int(t['value']))
            elif fmethod[0] == 'BOOL':
                try:
                    val = json.loads(t['value'])
                except ValueError as e:
                    print("json decode error. value: {}".format(
                        repr(t['value'])))
                setattr(o, t['name'], val)
            elif fmethod[0] == 'ignore':
                pass
            elif fmethod[0] == 'trans':
                value = trans(o, fmethod, t['name'], t['value'])
                setattr(o, t['name'], value)
            else:
                raise TransactionError(
                    'load_transaction: unknown fmethod {}'.format(
                        repr(fmethod[0])))
        elif fmethod is None:
            setattr(o, t['name'], t['value'])
        else:
            raise TransactionError('unknown type of field method {}'.format(
                repr(fmethod)))
Ejemplo n.º 5
0
    def dump(self, timestamp=None, srid=None):
        data = list()

        if srid is not None:
            qs = Transaction.objects.filter(srid=srid)
        elif timestamp is not None:
            dt = myutils.unixtime2dt(timestamp)
            qs = Transaction.objects.filter(created__gte=dt)
        else:
            qs = Transaction.objects.all()

        for t in qs:
            data.append(t.data())

        #   hier = ['srid','model_name','rid']
        # return list2dict(data, hier)
        return data
Ejemplo n.º 6
0
    def sync(self, opts=None, ro=False, verbosity=1, skip=False):

        te = TransactionEngine()

        if opts is None:
            ls = myutils.dt2unixtime(self.lastupdate)
            url = self.action_url('sync', ls)
        else:
            url = self.action_url('fsync', opts)

        if verbosity >= 2:
            print("URL:", url)

        r = requests.get(url)

        if r.status_code != 200:
            print("ERROR! Couldn't get from {} (HTTP code: {})".format(
                url, r.status_code))
            return
        data = json.loads(r.text)

        last = 0
        for t in data:
            if t['created'] > last:
                last = t['created']

        print("got", len(data), "transactions from", self.machine)

        #with django.db.transaction.atomic():
        msg = te.load(data, ro=ro, verbosity=verbosity, skip=skip)

        if opts is None and not ro:
            # update lastupdate only in real run
            self.lastupdate = myutils.unixtime2dt(last)

        return msg
Ejemplo n.º 7
0
class TransactionServer(models.Model):
    lastupdate = models.DateTimeField(default=myutils.unixtime2dt(0))
    machine = models.CharField(max_length=100, default='')
    url = models.CharField(max_length=100, default='')
    netprocess = models.BooleanField(default=True)
    private = models.BooleanField(default=False)

    srv = [
        {
            'machine': 'alpha',
            'url': 'https://alpha.okerr.com/',
            'netprocess': True,
            'private': False
        },
        {
            'machine': 'braconnier',
            'url': 'http://localhost:8000/',
            'netprocess': False,
            'private': True
        },
        {
            'machine': 'charlie',
            'url': 'https://charlie.okerr.com/',
            'netprocess': True,
            'private': False
        },
    ]

    def __unicode__(self):
        return "{} {} {}".format(self.machine, self.url, self.lastupdate)

    # transactionserver.action_url
    def action_url(self, action, *args):

        if action == 'sync':
            urltpl = urllib.parse.urljoin(self.url, '/api/sync/{}')
        elif action == 'sdump':
            urltpl = urllib.parse.urljoin(self.url, '/api/sdump/{}')
        elif action == 'setci':
            urltpl = urllib.parse.urljoin(self.url, '/api/setci')
        elif action == 'fsync':
            url = '/api/fsync'
            for a, v in args[0].iteritems():
                if isinstance(v, list):
                    for vv in v:
                        url += '/{}={}'.format(a, vv)
                else:
                    url += '/{}={}'.format(a, v)
            url = urllib.parse.urljoin(self.url, url)
            return url
        else:
            print("unknown action", repr(action))
            return None

        # print "tpl: {} args: {}".format(urltpl, list(args))
        url = urltpl.format(*args)
        return url

    # transactionserver.ciserver
    @staticmethod
    def ciserver(ci=None):

        if ci is None:
            ci = myci()

        sname = settings.CLUSTER[ci]
        tsrv = TransactionServer.objects.get(machine=sname)
        return tsrv

    # transactionserver.reinit
    @classmethod
    def reinit(cls):
        print("deleted", cls.objects.all().delete())
        dt = myutils.unixtime2dt(0)
        for srv in cls.srv:
            ts = TransactionServer(machine=srv['machine'],
                                   url=srv['url'],
                                   private=srv['private'],
                                   netprocess=srv['netprocess'],
                                   lastupdate=dt)
            print(ts)
            ts.save()

    # transactionserver.sync_map
    @classmethod
    def sync_map(cls, ro=False, verbosity=1):
        # print "sync map",settings.HOSTNAME
        out = dict()
        if ro:
            print("read-only")
        if settings.HOSTNAME in settings.SYNC_MAP:
            for machine in settings.SYNC_MAP[settings.HOSTNAME]:
                print("sync", settings.HOSTNAME, "from", machine)
                tsrv = cls.objects.get(machine=machine)
                msg = tsrv.sync(ro=ro, verbosity=verbosity)
                out[tsrv.machine] = msg
                tsrv.save()
        return out

    # transactionserver.cron
    @classmethod
    def cron(cls):
        # return cls.sync_map()
        return None

    # transactionserver.sync
    def sync(self, opts=None, ro=False, verbosity=1, skip=False):

        te = TransactionEngine()

        if opts is None:
            ls = myutils.dt2unixtime(self.lastupdate)
            url = self.action_url('sync', ls)
        else:
            url = self.action_url('fsync', opts)

        if verbosity >= 2:
            print("URL:", url)

        r = requests.get(url)

        if r.status_code != 200:
            print("ERROR! Couldn't get from {} (HTTP code: {})".format(
                url, r.status_code))
            return
        data = json.loads(r.text)

        last = 0
        for t in data:
            if t['created'] > last:
                last = t['created']

        print("got", len(data), "transactions from", self.machine)

        #with django.db.transaction.atomic():
        msg = te.load(data, ro=ro, verbosity=verbosity, skip=skip)

        if opts is None and not ro:
            # update lastupdate only in real run
            self.lastupdate = myutils.unixtime2dt(last)

        return msg

    # transactionserver.ssync
    def ssync(self, srid, ro=False, verbose=False):
        """
            sync only one SRID (profile)
        """

        te = TransactionEngine()

        url = self.action_url('sdump', srid)

        r = requests.get(url)
        if r.status_code != 200:
            print("ERROR! Couldn't get from {} (HTTP code: {})".format(
                url, r.status_code))
            return
        data = json.loads(r.text)

        print("got", len(data), "transactions from", self.machine)
        with django.db.transaction.atomic():
            te.load(data, ro=ro)

    # transactionserver.setci
    def setci(self, ci, email):
        data = {'ci': ci, 'email': email}
        url = self.action_url('setci', email)
        r = requests.post(url, data)
        if r.status_code != 200:
            print("Error! status: {} url: {}".format(r.status_code, url))
        else:
            print("remote:", r.text)

    # transactionserver.take
    def take(self, srid):
        ci = myci()
        self.setci(ci, srid)
        self.ssync(srid)
Ejemplo n.º 8
0
    def d2o(self, d, model, parents=None):

        debug = False
        debugmodels = []
        if model.__name__ in debugmodels:
            debug = True

        if debug:
            print("d2o {}".format(model.__name__))

        def backtrans(mname, fname, trans,value,parents):
            
            #print "backtrans mname: {} fname: {} trans: {} value: {} parents: {}".format(
            #    mname, fname, trans, value, parents                
            #   )
            
            if value is None:
                return None
            
            field = trans.split(':')[1].split('.')[1]
            
            f = model._meta.get_field(fname)
            rmodel = f.related_model
            
            kw = dict()
            kw[field] = value
            
            if trans.startswith('ptrans'):
                pmname = trans.split(':')[2]
                #print "pmname",pmname
                rfname = self.get_fk_field_to(rmodel, parents[pmname].__class__)
                #print "rfname:",rfname
                kw[rfname] = parents[pmname]
            
            #print "rmodel:", rmodel
            #print "backtrans rmodelget:", kw
            
            try:
                ri = rmodel.objects.get(**kw)
            except ObjectDoesNotExist as e:
                log.error('EXCEPTION {}: {}. kw: {}'.format(type(e), e, str(kw)))
            return ri

        mname = model.__name__
        
        if parents is None:
            parents = dict()

        # self.learn(model)
        o = model()

        m = self.models[mname]

        for fname, ftype in m['fields'].items():
            if ftype is None:
                #print "Set {} = {}".format(fname, d[fname])
                
                # with this check we can add new fields
                if fname in d:
                    setattr(o, fname, d[fname])
            elif ftype == 'ignore':
                pass
            elif ftype == 'DT':
                if fname in d:
                    val = d[fname]
                else:
                    val = None
                if val is None:
                     setattr(o, fname, None)
                else:
                    setattr(o, fname, myutils.unixtime2dt(d[fname]))

            elif ftype == 'parent':
                #print "procces {}: {}.{} parents: {}".format(mname, fname, ftype, parents)
                #print json.dumps(m, indent=4)
                f = model._meta.get_field(fname)
                setattr(o,fname, self.get_parent(model, fname, parents))
            elif ftype.startswith('trans:') or ftype.startswith('ptrans:'):
                # print "{} {} {}".format(ftype, d, fname)
                setattr(o, fname, backtrans(mname, fname, ftype, d[fname], parents))
            else:
                raise ValueError("d2o: dont know how to handle ftype {} for {}.{}".format(ftype, mname, fname))

        if m['trans_last_sync']:
            o.trans_last_sync = timezone.now()


        if m['post_import']:
            # print "PI",mname
            self.vprint(3, "post_import {}: {}".format(mname,o))
            o.post_import(d)
        else:
            if m['__bulk']:
                self.bulk_save_add(o)
            else:
                # print "SAVE",mname,o
                o.save()
        
        if not mname in self.processed:
            self.processed[mname] = 1
        else:
            self.processed[mname] += 1
        
        #if m['reanimate']:
        #    self.reanimate.append(o)
        
        chparents = dict(parents)
        if mname in chparents:
            raise ValueError
        chparents[mname] = o

        # addparent
        for pfield in m['__addparent']:
            p = getattr(o, pfield)
            pmname = p.__class__.__name__
            if pmname in chparents:
                raise ValueError
            chparents[pmname] = p

                
        for chs in m['__children']:
            # print "Process children structure:",json.dumps(chs, indent=4)
            chmname = chs['model']
            chm = self.get_model(chmname)
            
            if chmname in d:
                for chres in d[chmname]:
                    # print chres
                    # self.d2o(chres, chm, chparents)
                    self.delay_d2o(chmname, chres, chparents)

        if debug:
            print("d2o finished:", o)