def compare_profile(self, profile): ''' Compara il profilo con un altro profilo per verificare se appartengono alla stessa persona Params: @profile: Profilo da comparare Return: Valore di accuratezza tra i profili, più è alto maggiore la similarità ''' # Variabili locali match = 0 # Compara i dati dei profili if self.phone is not None and profile.phone is not None: if self.phone.number == profile.phone.number: match += 1 # Ottiene il nome completo del profilo corrente this_fullname = concat(self.first_name, self.last_name).lower() if self.full_name is not None: this_fullname = self.full_name.lower() # Ottiene il nome completo del profilo comparato profile_fullname = concat( profile.first_name, profile.last_name).lower() if profile.full_name is not None: profile_fullname = profile.full_name.lower() if this_fullname in profile_fullname or profile_fullname in this_fullname: match += 1 # Compara i volti dei profili if len(self._face_encodings) > 0: for face_encoding in profile._face_encodings: results = face_recognition.compare_faces( self._face_encodings, face_encoding) match += results.count(True) # Compara le immagini tramite hash per identificare quelle similari for cmp_hash in self._perceptual_hashes: for new_hash in profile._perceptual_hashes: if photohash.hashes_are_similar(cmp_hash, new_hash): match += 1 return match
async def join_polizei(event: ChatAction.Event) -> None: """Plugin to ban users with blacklisted strings in their bio.""" # avoid flood waits from chats mass adding users and don't check users leaving if not event.user_joined: return client: Client = event.client try: chat: Channel = await event.get_chat() except ChannelPrivateError: return db: Database = client.db tags = await Tags.from_event(event) bancmd = tags.get('gbancmd') polizei_tag = tags.get('polizei') if polizei_tag == 'exclude': return ban_type, ban_reason = False, False bio_blacklist = await db.blacklists.bio.get_all() mhash_blacklist = await db.blacklists.mhash.get_all() try: user: UserFull = await client( GetFullUserRequest(await event.get_input_user())) except TypeError as e: logger.error(e) return for item in bio_blacklist: if user.about and item.value in user.about and not item.retired: ban_type, ban_reason = db.blacklists.bio.hex_type, item.index if user.profile_photo: try: dl_photo = await client.download_file(user.profile_photo) except constants.DOWNLOAD_ERRORS: dl_photo = None if dl_photo: photo_hash = await hash_photo(dl_photo) for mhash in mhash_blacklist: if mhash and not mhash.retired: if hashes_are_similar(mhash.value, photo_hash, tolerance=2): ban_type, ban_reason = db.blacklists.mhash.hex_type, mhash.index if ban_type and ban_reason: await _banuser(event, event.user.id, bancmd, ban_type, ban_reason)
def add_profile(self, profile): ''' Aggiunge un profilo social all'elenco di profili associati all'utente Params: @profile: Profilo da associare ''' # Aggiunge i dati del profilo alla persona if self.first_name is None and profile.first_name is not None: if len(profile.first_name) >= NAME_MIN_LENGHT and not any( map(str.isdigit, profile.first_name)): self.first_name = profile.first_name if self.last_name is None and profile.last_name is not None: if len(profile.last_name) >= NAME_MIN_LENGHT and not any( map(str.isdigit, profile.first_name)): self.last_name = profile.last_name if profile.phone is not None: self.phones.append(profile.phone) # Aggiunge i luoghi visitati dalla persona self.locations.extend(profile.locations) # Aggiunge i nuovi volti self.face_encodings.extend(profile._face_encodings) # Aggiunge gli hash delle nuove immagini for new_hash in profile._perceptual_hashes: for cmp_hash in self.perceptual_hashes: if photohash.hashes_are_similar(cmp_hash, new_hash): self.perceptual_hashes.append(new_hash) break # Ordina la lista dalla locazione più recente a quella meno recente if len(profile.locations) > 0: self.locations.sort(key=lambda loc: loc.utc_time, reverse=True) # Aggiunge il profilo self.profiles.append(profile)
async def _check_message(event): # pylint: disable = R0911 client: Client = event.client msg: Message = event.message user_id = msg.from_id if user_id is None: return False, False try: result = await client(GetParticipantRequest(event.chat_id, user_id)) if isinstance(result.participant, ChannelParticipantAdmin): return False, False except (ValueError, TypeError, UserNotParticipantError, ChatAdminRequiredError): return False, False # no need to ban bots as they can only be added by users anyway user = await client.get_cached_entity(user_id) if user is None or user.bot: return False, False # commands used in bots to blacklist items, these will be used by admins # so they shouldnt be banned for it blacklisting_commands = [ '/addblacklist', ] for cmd in blacklisting_commands: if msg.text and msg.text.startswith(cmd): return False, False db: Database = client.db # tld_blacklist = db.ab_tld_blacklist.get_all() inline_bot = msg.via_bot_id if inline_bot is not None: result = await db.blacklists.channel.get_by_value(inline_bot) if result: return db.blacklists.channel.hex_type, result.index if msg.buttons: _buttons = await msg.get_buttons() button: MessageButton for button in itertools.chain.from_iterable(_buttons): if button.url: _, chat_id, _ = await helpers.resolve_invite_link(button.url) result = await db.blacklists.channel.get_by_value(chat_id) if result: return db.blacklists.channel.hex_type, result.index domain = await client.resolve_url(button.url) result = await db.blacklists.domain.get_by_value(domain) if result: return db.blacklists.domain.hex_type, result.index # tld_index = await _check_tld(domain, tld_blacklist) # if tld_index: # return db.ab_tld_blacklist.hex_type, tld_index face_domain = await helpers.netloc(button.url) result = await db.blacklists.domain.get_by_value(face_domain) if result: return db.blacklists.domain.hex_type, result.index elif domain in constants.TELEGRAM_DOMAINS: _entity = await client.get_cached_entity(domain) if _entity: result = await db.blacklists.channel.get_by_value(_entity) if result: return db.blacklists.channel.hex_type, result.index entities = msg.get_entities_text() for entity, text in entities: # pylint: disable = R1702 _, chat_id, _ = await helpers.resolve_invite_link(text) result = await db.blacklists.channel.get_by_value(chat_id) if result: return db.blacklists.channel.hex_type, result.index domain = '' face_domain = '' channel = '' _entity = None if isinstance(entity, MessageEntityUrl): try: domain = await client.resolve_url(text) except ValueError: pass face_domain = await helpers.netloc(text) if domain in constants.TELEGRAM_DOMAINS: # remove any query parameters like ?start= # replace @ since some spammers started using it, only Telegram X supports it url = await client.resolve_url(text, base_domain=False) username = url.split('?')[0].replace('@', '') _entity = username elif isinstance(entity, MessageEntityTextUrl): domain = await client.resolve_url(entity.url) face_domain = await helpers.netloc(entity.url) if domain in constants.TELEGRAM_DOMAINS: url = await client.resolve_url(entity.url, base_domain=False) username = url.split('?')[0].replace('@', '') _entity = username elif isinstance(entity, MessageEntityMention): _entity = text if _entity: try: try: full_entity = await client.get_cached_entity(_entity) except (FloodWaitError, *GET_ENTITY_ERRORS): full_entity = None if full_entity: channel = full_entity.id try: profile_photo = await client.download_profile_photo(full_entity, bytes) except constants.DOWNLOAD_ERRORS: profile_photo = None if profile_photo: try: photo_hash = await hash_photo(profile_photo) for mhash in await db.blacklists.mhash.get_all(): if mhash and not mhash.retired: if hashes_are_similar(mhash.value, photo_hash, tolerance=2): return db.blacklists.mhash.hex_type, mhash.index except UnidentifiedImageError: pass except (*constants.GET_ENTITY_ERRORS, ChannelPrivateError): pass # urllib doesnt like urls without a protocol if not face_domain: face_domain = await helpers.netloc(f'http://{domain}') if domain: result = await db.blacklists.domain.get_by_value(domain) if result: return db.blacklists.domain.hex_type, result.index # else: # tld_index = await _check_tld(domain, tld_blacklist) # if tld_index: # return db.ab_tld_blacklist.hex_type, tld_index if face_domain: result = await db.blacklists.domain.get_by_value(face_domain) if result: return db.blacklists.domain.hex_type, result.index # else: # tld_index = await _check_tld(face_domain, tld_blacklist) # if tld_index: # return db.ab_tld_blacklist.hex_type, tld_index if channel: result = await db.blacklists.channel.get_by_value(channel) if result: return db.blacklists.channel.hex_type, result.index if msg.raw_text: for string in await db.blacklists.string.get_all(): if string.value in msg.raw_text and not string.retired: return db.blacklists.string.hex_type, string.index if msg.file: # avoid a DoS when getting large files ten_mib = (1024 ** 2) * 10 # Only download files to avoid downloading photos if msg.document and msg.file.size < ten_mib: try: dl_file = await msg.download_media(bytes) except constants.DOWNLOAD_ERRORS: dl_file = None if dl_file: filehash = helpers.hash_file(dl_file) result = await db.blacklists.file.get_by_value(filehash) if result: return db.blacklists.file.hex_type, result.index else: pass if msg.photo: try: dl_photo = await msg.download_media(bytes) except constants.DOWNLOAD_ERRORS: dl_photo = None if dl_photo: try: photo_hash = await hash_photo(dl_photo) except UnidentifiedImageError: photo_hash = None if photo_hash: for mhash in await db.blacklists.mhash.get_all(): if not mhash.retired: if hashes_are_similar(mhash.value, photo_hash, tolerance=2): return db.blacklists.mhash.hex_type, mhash.index return False, False