Example #1
0
def set_chat_id(email, tgname, chat_id):

    try:
        profile = None
        log.info(
            f"set chat id email: {email} tgname: {tgname} chat_id: {chat_id}")
        # find profile
        if email:
            # do not use tgname in this search!
            profile = Profile.objects.get(user__email=email)
        else:
            if tgname:
                # case-insensitive search for telegram_name
                profile = Profile.objects.get(telegram_name__iexact=tgname)
            else:
                profile = Profile.objects.get(telegram_name=str(chat_id))

        log.info(f"got profile: {profile}")

        # verify profile
        if profile.telegram_name.lower() != tgname.lower(
        ) and profile.telegram_name != str(chat_id):
            if tgname:
                return 'Set telegram name {} in profile'.format(tgname)
            else:
                return 'Set telegram name {} in profile'.format(chat_id)

        rs = RemoteServer(ci=profile.ci)
        if tgname:
            jr = rs.api_admin_tglink(email, tgname, chat_id)
        else:
            jr = rs.api_admin_tglink(email, chat_id, chat_id)

        r = json.loads(jr)

        # sync if needed
        if rs.ci != myci():
            for username in r['sync']:
                data = rs.get_user(username)
                ie = Impex()
                ie.set_verbosity(0)
                ie.preimport_cleanup(data)
                ie.import_data(data)

        return r['msg']

    except Profile.DoesNotExist as e:
        log.info('Not found profile for tg user {}. Try little later?'.format(
            tgname))
        if tgname:
            return "Telegram user with name '{}' not known in Okerr. Sorry. Please set this name in okerr profile first and try little later.".format(
                tgname)
        else:
            return "Telegram user with id {} not known in Okerr. Sorry. Please set this id in okerr profile first and try little later.".format(
                chat_id)

    except Profile.MultipleObjectsReturned as e:
        log.error('Multiple profiles for tg user {}'.format(tgname))
        return "More then one telegram user '{}' in Okerr. Use /on <email> command.".format(
            tgname)
Example #2
0
def UNUSED_handle_sync(url, overwrite, verbosity):
    ci = myci()
    
    rurl = urllib.parse.urljoin(url,'/api/admin/cilist')
    r = requests.get(rurl)
    if r.status_code == 200:
        userlist = r.text.split('\n')
    else:
        raise Exception('Error code: {} from url {}'.format(r.status_code, rurl))
        
    for email in userlist:
        if not email:
            continue
        try:
            luser = User.objects.get(email=email)
            profile = luser.profile
            if profile.ci == ci and not overwrite:
                raise Exception('user: {} ci: {} is mine and not overwrite!'.format(email, ci))
        except User.DoesNotExist:
            pass
        except Profile.DoesNotExist:
            # no profile. okay. we will re-create it. it's safe - we dont have profile anyway
            pass
    
        data = get_content(url = url, email = email)

        #overwrite always True here, because we always overwrite other-ci and check for local-ci above
        handle_import(data, True, verbosity) 
Example #3
0
    def add_arguments(self,parser):
        read_group = parser.add_argument_group('Read')
        read_group.add_argument('--list', action='store_true', help='list all profiles')
        read_group.add_argument('--info', action='store_true', help='brief summary info')
        read_group.add_argument('--cilist', metavar='ci', type=int, nargs='?', default=None, const=myci(), 
            help='list profiles for this ci (default, my: {})'.format(myci()))
        read_group.add_argument('--cluster', default=False, action='store_true', help='list cluster users')        
        read_group.add_argument('--hostinfo', metavar='host', nargs='?', const='*',default=None, help='hostinfo')        
        read_group.add_argument('--compare', default=False, action='store_true', help='compare users on all machines in cluster')        


        manage_group = parser.add_argument_group('Manage')
        manage_group.add_argument('--export', default=False, action='store_true', help='export profile for --user')
        manage_group.add_argument('--import', action='store_true', default=False, help='load one profile from (--file) OR (--url and --user)')
        manage_group.add_argument('--sync', metavar='MACHINE_URL', default=None, help='sync with remote url, e.g https://alpha.okerr.com/')
        manage_group.add_argument('--syncmap', action='store_true', default=False, help='sync according to map')
        manage_group.add_argument('--setci', type=int, metavar='CI', default=None, const=myci(), nargs='?', help='set ci for --user')
        manage_group.add_argument('--takeci', type=int, metavar='CI', default=None, help='set my ci for all users with this ci')
        manage_group.add_argument('--reanimate', default=False, action='store_true', help='reanimate everything for --user or all local')        

        wipe_group = parser.add_argument_group('Delete')
        wipe_group.add_argument('--ciwipe', metavar='ci', type=int, nargs='?', default = None, const=False, help='drop profiles for other ci')
        wipe_group.add_argument('--otherciwipe', default=False, action='store_true', help='drop profiles for all other ci')
        wipe_group.add_argument('--wipe', default = False, action='store_true', help='Wipe one user') 

        opts_group = parser.add_argument_group('Options')
#        opts_group.add_argument('--batch', '-b', action='store_true', help='batch mode (show briefly)')
        opts_group.add_argument('--user', default=None, help='user email')        
        opts_group.add_argument('-f','--file', metavar='FILENAME', default=None, help='work with this file')
        opts_group.add_argument('--url', metavar='URL', default=None, help='work with this URL. e.g. https://alpha.okerr.com/')
        opts_group.add_argument('--overwrite',action='store_true', default=False, help='delete old profile when importing')
        opts_group.add_argument('--dblog',action='store_true', default=False, help='log db queries')
        opts_group.add_argument('--remote', default=False, action='store_true', help='do remote operations if needed')
        opts_group.add_argument('--clone', default=False, action='store_true', help='modify imported data for cloning (e.g. set unused textids)')
        opts_group.add_argument('--skip', nargs='*', default=list(), help='modify imported data for cloning (e.g. set unused textids)')
Example #4
0
    def sync(self, url, overwrite=True):    

        rs = RemoteServer(url = url)

        User = get_user_model()
        Profile = self.get_model('Profile')
        
        
        ci = myci()
        rci = rs.get_ci()
        
        userlist = rs.get_userlist()

        for email in userlist:
            if not email:
                continue
            log.info('sync user {} from {} rci: {}'.format(email, url2host(url), rci))
            self.vprint(2, 'sync user {} from {}'.format(email, url2host(url)))            
            profile = None
            
            # get local user
            try:
                profile = Profile.objects.get(user__email=email)
                                
                if profile.ci == ci and not overwrite:
                    log.error('sync: user {} ci: {} is mine!!'.format(email, ci))
                    raise Exception('user: {} ci: {} is mine and not overwrite!'.format(email, ci))                            
            except User.DoesNotExist:
                pass
            except Profile.DoesNotExist:
                # no profile. okay. we will re-create it. it's safe - we dont have profile anyway
                pass
            
            try:
                data = rs.get_user(email)
            except (requests.exceptions.RequestException, RemoteServerExc) as e:
                log.warning('sync error (user {} from {}): {}'.format(email, rs.name, str(e)))
                continue

            # delete this user before importing
            if profile:
                if overwrite:
                    # log.debug("ZZZ luser.delete (profile: {})".format(profile))
                    profile.predelete()
                    profile.delete()
                else:
                    # do not import this user, because it's local and not overwrite
                    continue

            #log.debug("ZZZ import data")
            self.import_data(data)

        self.delete_deleted(rs)
Example #5
0
def cmd_debug(update, ctx):
    bot = ctx.bot
    args = ctx.args

    reg_command(update, ctx)

    chat_id = update.message.chat_id
    tgname = update.message.from_user.username

    log.info('debug @{} #{}'.format(tgname, chat_id))

    bot.send_message(chat_id=update.message.chat_id,
                     text="You are @{}, chat_id: {}".format(tgname, chat_id))

    for p in Profile.objects.filter(telegram_name=tgname):
        bot.send_message(chat_id=update.message.chat_id,
                         text="Profile {} @{}, chat_id: {} ci: {}/{}".format(
                             p.user.username, p.telegram_name,
                             p.telegram_chat_id, p.ci, myci()))
Example #6
0
    def cron(cls):

        modelcrontime = 1800 # 30min
        modelcrontime_big = 86400 # 2        
        if cls.lastcron and int(time.time()) < cls.lastcron+modelcrontime:
            # print "skip cronjob ({} < {} + {}, will run in {} seconds)".\
            #    format(int(time.time()),cls.lastcron,modelcrontime,cls.lastcron+modelcrontime-int(time.time()))
            return
                
        cls.lastcron=int(time.time())        
        cls.syncmap()

        if int(time.time()) > cls.lastcron_big+modelcrontime_big:
            if hasattr(settings,'IMPORT_PROFILE') and settings.IMPORT_PROFILE:
                User = get_user_model()
                filename = os.path.join(settings.BASE_DIR, settings.IMPORT_PATH, settings.IMPORT_PROFILE)
                with open(filename, "r") as infile:
                    data = json.load(infile)
                if data['ci'] == myci():
                    # only if we should use this user
                    try:
                        user = User.objects.get(email=data['email'])
                        # delete user if exist
                        if user.profile:
                            print(user.profile)
                            user.profile.predelete()
                            user.profile.delete()
                        else:
                            # user.delete()
                            pass
                    except User.DoesNotExist:
                        # no such user, great!
                        pass
                    ie = Impex()
                    ie.set_verbosity(0)
                    ie.import_data(data)
                    log.info("cron reimported user {}".format(data['email']))
                else:
                    # print("not our ci")
                    pass

            cls.lastcron_big = int(time.time())
Example #7
0
def lock(pid, numi=50):
    """
        lock numi records.
        we lock by setting lockpid to non-null (random) value.
        we cannot set to PID
        npname - netprocess name
    """
    now = timezone.now()

    remote = True

    # hostname = 'charlie'
    # hostname = settings.HOSTNAME

    my_ci = myci()

    # nested_q=Indicator.objects.filter(lockpid__isnull=True, ci=my_ci, problem=False, disabled=False, dead=False, deleted_at__isnull=True, scheduled__lte=now, cm__remote=remote).exclude(last_fail_machine=machine).values_list('pk', flat=True)[:numi]

    nested_q = Indicator.objects.filter(
        lockpid__isnull=True,
        ci=my_ci,
        problem=False,
        disabled=False,
        dead=False,
        deleted_at__isnull=True,
        scheduled__lte=now,
        cm__remote=remote).order_by('scheduled').values_list('pk',
                                                             flat=True)[:numi]

    nlocked = Indicator.objects.filter(pk__in=list(nested_q),
                                       lockpid__isnull=True,
                                       ci=my_ci,
                                       disabled=False,
                                       deleted_at__isnull=True,
                                       scheduled__lte=now,
                                       cm__remote=remote).update(lockpid=pid,
                                                                 lockat=now)
    return nlocked
Example #8
0
    def handle(self, *args, **options):
        #print "options:",options
        
        user = None
        profile = None

        if options['verbosity'] >= 1:
            log = logging.getLogger('okerr')
            log.setLevel(logging.DEBUG)
            log.addHandler(logging.StreamHandler())

        # prepare data
        try:
            if options['user'] and not options['clone']:
                email = options['user']
                user = User.objects.get(email=options['user'])
                profile = user.profile
        except User.DoesNotExist:
            print("No such user")
        except Profile.DoesNotExist:
            print("No such profile")
    

        if options['dblog']:
            l = logging.getLogger('django.db.backends')
            l.setLevel(logging.DEBUG)
            l.addHandler(logging.StreamHandler())
                

        if options['skip']:
            for s in options['skip']:
                RemoteServer.skip(s)


        if options['hostinfo']:
            if options['hostinfo'] == 'all':
                rs = RemoteServer.me()
                for rrs in rs.all_rs():
                    print("== Hostinfo for %s" % rrs)
                    print(rrs.hostinfo())
                
            else:
                rs = RemoteServer(name = options['hostinfo'])
                print(rs.hostinfo())
            return

        if options['cluster']:
            print(json.dumps(settings.MACHINES, indent=4))                           
            return

        if options['compare']:
            ul = dict()
            users = list()
            badusers = list()
            me = RemoteServer.me()
            for rs in me.all_rs():
                ul[rs.name] = rs.list()
            
            for ulist in list(ul.values()):
                for u in ulist:
                    email = u['user']
                    if not email in users:
                        users.append(email)



            mnames = sorted(ul.keys())
            fmt = "{:<50}|{:1}| " + "{:<15}| " * (len(mnames))                        
            
            titles = list()
            for m in mnames:
                rs = RemoteServer(name = m)
                print(rs, rs.ci)
                titles.append("{} ({})".format(rs.name, rs.ci))
            print(fmt.format('EMAIL','X', *titles))
            print(fmt.format('-'*50,'-',*["-"*15 for x in range(len(mnames))]))
            
            
            for username in users:
                cil = list()
                for m in mnames:                    
                    urec = [urec for urec in ul[m] if urec['user'] == username]
                    if urec:
                        cil.append(urec[0]['ci'])
                    else:
                        cil.append('-')
            
                if cil[1:] == cil[:-1]:
                    cil.insert(0,'')
                    if options['verbosity']>=1:
                        print(fmt.format(username, *cil))
                else:
                    cil.insert(0,'X')
                    print(fmt.format(username, *cil))
                    
            

            return


        if options['reanimate']:
            if profile:
                print("single reanimate", profile)
                profile.reanimate()
            else:
                for p in Profile.objects.filter(ci = myci()):
                    print("reanimate",p)
                    p.reanimate()
            return

        if options['info']:
            print("Host: {} Cluster: {} ci: {}".format(repr(settings.HOSTNAME), repr(settings.CLUSTER_NAME), myci()))
            print("Profiles: {} / {}".format(Profile.objects.filter(ci=myci()).count(), Profile.objects.count()))
            return

        if options['list']:
            for p in Profile.objects.all():
                    print(p.ci, p.user.username)
        elif options['cilist'] is not None:
            for p in Profile.objects.filter(ci=options['cilist']).all():
                print(p.user.username)
        elif options['wipe']:
            if not (user or profile):
                print("need either user ({}) or profile ({})".format(user, profile))
            if user:
                user.delete()
            if profile:
                profile.delete()
            print("deleted")
        elif options['ciwipe'] is not None:
            if options['ciwipe'] == myci():
                print("cannot ciwipe for my own ci {}".format(myci()))
                return
            for p in Profile.objects.filter(ci=options['ciwipe']).all():
                if options['verbosity']>=1:
                    print("delete {} ci: {}".format(p, p.ci))
                p.user.delete()
                p.delete()
        elif options['otherciwipe']:
            ci = myci()
            for p in Profile.objects.all():
                if p.ci == ci:
                    if options['verbosity']>=1:
                        print("skip profile {} ci: {}".format(p, p.ci))
                else:
                    if options['verbosity']>=1:
                        print("delete {} ci: {}".format(p, p.ci))
                    p.user.delete()
                    p.delete()
        
        elif options['export']:
            if profile:
                handle_export(profile, options['file'], options['verbosity'])       
            else:
                print("Need --user")
 
        elif options['import']:
            data = get_content(filename = options['file'], url = options['url'], email = options['user'])
            if options['clone']:
                data = clone(data, options['user'])                        
            handle_import(data, options['overwrite'], options['verbosity'])
 
        elif options['sync']:
            handle_sync(options['sync'], options['overwrite'], options['verbosity'])
 
        elif options['syncmap']:            
                ie = Impex()
                ie.set_verbosity(options['verbosity'])
                ie.syncmap()
                return

        elif options['takeci'] is not None:            
            for profile in Profile.objects.filter(ci=options['takeci']):
                print("process profile", profile)
                ## profile = Profile.objects.get(user__email = options['user'])
                setci_local(profile, myci())
                if options['remote']:
                    setci_remote(profile.user.username, myci())
                else:
                    print("skip remote, because no --remote")
            return
            
        elif options['setci'] is not None:            
            if options['user']:
                profile = Profile.objects.get(user__email = options['user'])
                setci_local(profile, options['setci'])
                if options['remote']:
                    setci_remote(options['user'], options['setci'])
                else:
                    print("skip remote, because no --remote")
            else:
                print("need --user")
            return

        
        
            print("setci {} for user {}".format(options['setci'], email))
            # change for profile and projects
            ci = options['setci']
            
            profile.set_ci(options['setci'])
            profile.save()
        else:
            print("Whaat?")