def send_telegram(Ldest, itemType, get_graph, key):
    # Telegram settings | Configuracao do Telegram #########################################################################
    api_id0 = PropertiesReaderX(
        path.format('configScripts.properties')).getValue(
            'PathSectionTelegram', 'api.id')
    api_hash0 = PropertiesReaderX(
        path.format('configScripts.properties')).getValue(
            'PathSectionTelegram', 'api.hash')

    try:
        api_id = int(decrypt(key, api_id0))
    except:
        api_id = api_id0

    try:
        api_hash = str(decrypt(key, api_hash0))
    except:
        api_hash = api_hash0

    app = Client("SendGraph", api_id=api_id, api_hash=api_hash)

    msg = body.replace("\\n", "")
    saudacao = salutation
    Saudacao = PropertiesReaderX(
        path.format('configScripts.properties')).getValue(
            'PathSectionTelegram', 'salutation.telegram')

    if re.search("(sim|s|yes|y)", str(Saudacao).lower()):
        if saudacao:
            saudacao = salutation + " {0} \n\n"
    else:
        saudacao = ""

    with app:
        for dest in Ldest:
            dest = dest.lower()
            if re.search("user#|chat#|\'|\"", dest):
                if "#" in dest:
                    dest = dest.split("#")[1]

                elif dest.startswith("\"") or dest.startswith("\'"):
                    dest = dest.replace("\"", "").replace("\'", "")

            elif dest.startswith("@"):
                dest = dest[1:]

            flag = True
            while flag:
                try:
                    Contatos = app.get_contacts()
                    for contato in Contatos:
                        Id = f"{contato.id}"
                        nome = f"{contato.first_name}"
                        if contato.last_name:
                            nome += f" {contato.last_name}"

                        username = contato.username.lower()
                        if username:
                            if username in dest or dest in Id or dest in nome.lower(
                            ):
                                dest = nome
                                flag = False
                                break
                        else:
                            if dest in Id or dest in nome.lower():
                                dest = nome
                                flag = False
                                break
                except:
                    pass

                try:
                    if flag:
                        Dialogos = app.iter_dialogs()
                        for dialogo in Dialogos:
                            Id = f"{dialogo.chat.id}"
                            if dialogo.chat.title:
                                nome = f"{dialogo.chat.title}"
                            else:
                                nome = f"{dialogo.chat.first_name}"
                                if dialogo.chat.last_name:
                                    nome += f" {dialogo.chat.last_name}"

                            username = dialogo.chat.username
                            if username:
                                if username in dest or dest in Id or dest in nome.lower(
                                ):
                                    dest = nome
                                    flag = False
                                    break
                            else:
                                if dest in Id or dest in nome.lower():
                                    dest = nome
                                    flag = False
                                    break
                except:
                    flag = False
                    try:
                        if re.match("^([0-9-]+)$", dest):
                            dest = int(dest)
                        chat = app.get_chat(dest)
                        Id = "{}".format(chat.id)

                        if chat.title:
                            dest = f"{chat.title}"
                        else:
                            dest = f"{chat.first_name}"
                            if chat.last_name:
                                dest += f" {chat.last_name}"

                    except Exception as msg:
                        # print(msg.args[0])
                        log.writelog(f'{msg.args[0]}', arqLog, "ERROR")
                        exit()

            Id = int(Id)
            sendMsg = """{}{}\n{}""".format(saudacao.format(dest), sys.argv[2],
                                            msg)
            if re.search("(0|3)", itemType):
                try:
                    graph = '{0}/{1}.png'.format(graph_path, itemid)
                    with open(graph, 'wb') as png:
                        png.write(get_graph.content)
                except BaseException as e:
                    log.writelog(
                        '{1} >> An error occurred at save graph file in {0} | Ocorreu um erro ao salvar o grafico no diretório {0}'
                        .format(graph_path, str(e)), arqLog, "WARNING")
                    logout_api()
                    exit()

                try:
                    app.send_photo(Id,
                                   graph,
                                   caption=sendMsg,
                                   parse_mode="html")
                    # print('Telegram sent photo message successfully | Telegram com gráfico enviado com sucesso ({0})'.format(dest))
                    log.writelog(
                        'Telegram sent photo message successfully | Telegram com gráfico enviado com sucesso ({0})'
                        .format(dest), arqLog, "INFO")
                except Exception as e:
                    # print('Telegram FAIL at sending photo message | FALHA ao enviar mensagem com gráfico pelo telegram\n%s' % e)
                    log.writelog(
                        '{0} >> Telegram FAIL at sending photo message | FALHA ao enviar mensagem com gráfico pelo telegram ({1})'
                        .format(e, dest), arqLog, "ERROR")
                    logout_api()
                    exit()

                try:
                    os.remove(graph)
                except Exception as e:
                    # print(e)
                    log.writelog('{0}'.format(str(e)), arqLog, "ERROR")

            else:
                try:
                    app.send_message(Id, sendMsg, parse_mode="html")
                    # print('Telegram sent successfully | Telegram enviado com sucesso ({0})'.format(dest))
                    log.writelog(
                        'Telegram sent successfully | Telegram enviado com sucesso ({0})'
                        .format(dest), arqLog, "INFO")
                except Exception as e:
                    # print('Telegram FAIL at sending photo message | FALHA ao enviar a mensagem com gráfico pelo telegram\n%s' % e)
                    log.writelog(
                        '{0} >> Telegram FAIL at sending message | FALHA ao enviar a mensagem pelo telegram ({1})'
                        .format(e, dest), arqLog, "ERROR")
                    logout_api()
                    exit()

            if re.search("(sim|s|yes|y)", str(Ack).lower()):
                if nograph not in argvs:
                    ack(dest, "Telegram enviado com sucesso ({0})")
Exemple #2
0
class Tracker:
    def __init__(self, api_id, api_hash, phone):
        self.client = Client(session_name='session',
                             api_id=api_id,
                             api_hash=api_hash,
                             phone_number=phone)

        self.flush_queue = Queue()

    @timer
    def update_user_info(self):
        all_users = self.client.get_contacts()

        user_info_changed_count = 0

        for user in all_users:
            user_row_dict = {
                'user_id': user.id,
                'first_name': user.first_name,
                'last_name': user.last_name,
                'user_name': user.username,
                'bio': get_user_bio(user.username),
                'trackable_online': any([user.status.online,
                                         user.status.date]),
                'last_modified': datetime.now()
            }

            db_user: UserInfo = tracker_session.query(UserInfo).filter(
                UserInfo.user_id == user.id).scalar()

            if db_user is None:  # if there are no such user in db
                tracker_session.add(UserInfo(**user_row_dict))
            elif not rows_equal(  # if there are such user in db
                    db_user,  # but the info has changed
                    UserInfo(**user_row_dict),
                    skip_fields=('last_modified', )):
                user_info_changed_count += 1
                diffs = get_rows_difference(db_user,
                                            UserInfo(**user_row_dict),
                                            skip_fields=('last_modified', ))
                for diff in diffs:  # find what changed and write difference
                    tracker_session.add(
                        UserInfoHistory(user_id=user.id,
                                        time=datetime.now(),
                                        changed_field=diff[0],
                                        old_value=diff[1],
                                        new_value=user_row_dict[diff[0]]))
                for k, v in user_row_dict.items():
                    setattr(db_user, k, v)

        tracker_session.flush()

        if user_info_changed_count:
            log.warn(
                f'While updating user info {user_info_changed_count} users'
                f' changed info')

    def on_changed_status(self, _: Client, user_status: UserStatus):
        user = tracker_session.query(LastOnline).filter(
            LastOnline.user_id == user_status.user_id).scalar()

        new_status = parse_user_status(user_status)

        if user is None:
            tracker_session.add(
                LastOnline(user_id=user_status.user_id,
                           time=datetime.now(),
                           last_status=new_status))
            tracker_session.flush()
        elif user.last_status == new_status:
            log.warn('User online status was doubled, skipping'
                     f' uid: {user_status.user_id}')
            # TODO: sometimes we dont get a message about someone going offline
            # TODO: make sure we dont leave someone hanging online for 100 hours
            # TODO: because of unclosed online status
            # Hint: if we get doubled message just save that online sess as
            # 300 secs sess
        else:
            log.warn(f'User {user_status.user_id} is now {new_status}')
            user.last_status = new_status
            self.flush_queue.put(
                OnlineHistory(user_id=user_status.user_id,
                              time=datetime.now(),
                              new_status=new_status))
            tracker_session.flush()

    @staticmethod
    def flush_worker(queue: Queue):
        while True:
            q_contents = queue.get()
            tracker_session.add(q_contents)
            tracker_session.flush()

    @timer
    def update_user_photos(self):
        for contact in self.client.get_contacts():
            photos = self.client.get_user_profile_photos(contact.id).photos
            if not len(photos):
                continue
            st = photos[0]
            self.client.download_media(
                message=st,
                file_name=f'pics/{contact.id}-{str(datetime.now())}.jpg')

    def start(self):
        self.client.add_handler(UserStatusHandler(self.on_changed_status))

        flush_worker = Process(target=self.flush_worker,
                               args=(self.flush_queue, ))
        flush_worker.start()

        sch.every(1).minute.do(self.update_user_info)
        sch.every(1).hours.do(self.update_user_photos)

        self.client.start()

        while True:
            sch.run_pending()
            sleep(0.5)