mirror of
https://github.com/cupcakearmy/docker-instabot.git
synced 2024-12-22 07:16:24 +00:00
new code
This commit is contained in:
parent
1e7086e0cf
commit
e71a95b7a3
0
bot/src/__init__.py
Normal file → Executable file
0
bot/src/__init__.py
Normal file → Executable file
0
bot/src/check_status.py
Normal file → Executable file
0
bot/src/check_status.py
Normal file → Executable file
0
bot/src/feed_scanner.py
Normal file → Executable file
0
bot/src/feed_scanner.py
Normal file → Executable file
0
bot/src/follow_protocol.py
Normal file → Executable file
0
bot/src/follow_protocol.py
Normal file → Executable file
624
bot/src/instabot.py
Normal file → Executable file
624
bot/src/instabot.py
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
0
bot/src/likers_graber_protocol.py
Normal file → Executable file
0
bot/src/likers_graber_protocol.py
Normal file → Executable file
9
bot/src/likers_protocol.py
Normal file → Executable file
9
bot/src/likers_protocol.py
Normal file → Executable file
@ -14,10 +14,11 @@ def likers_protocol(self):
|
|||||||
log_string = "Current Index = %i of %i medias" % (
|
log_string = "Current Index = %i of %i medias" % (
|
||||||
self.current_index, len(self.media_by_user))
|
self.current_index, len(self.media_by_user))
|
||||||
self.write_log(log_string)
|
self.write_log(log_string)
|
||||||
|
|
||||||
if self.media_by_user[self.
|
|
||||||
current_index]["likes"]["count"] >= 10 and self.media_by_user[self.
|
|
||||||
current_index]["likes"]["count"] < 100:
|
if self.media_by_user[self.current_index]["likes"]["count"] >= 10 \
|
||||||
|
and self.media_by_user[self.current_index]["likes"]["count"] < 100:
|
||||||
get_user_id_post_page(
|
get_user_id_post_page(
|
||||||
self, self.media_by_user[self.current_index]["code"])
|
self, self.media_by_user[self.current_index]["code"])
|
||||||
username_checker(self)
|
username_checker(self)
|
||||||
|
0
bot/src/new_auto_mod_like2.py
Normal file → Executable file
0
bot/src/new_auto_mod_like2.py
Normal file → Executable file
16
bot/src/new_auto_mod_likeall.py
Normal file → Executable file
16
bot/src/new_auto_mod_likeall.py
Normal file → Executable file
@ -1,17 +1,21 @@
|
|||||||
|
import pprint
|
||||||
|
|
||||||
def new_like_all_exist_media(self):
|
def new_like_all_exist_media(self):
|
||||||
i = self.current_index
|
i = self.current_index
|
||||||
# Media count by this user.
|
# Media count by this user.
|
||||||
l_c = self.media_by_user[i]['likes']['count']
|
#print(*self.media_by_user[i]['node'])
|
||||||
|
#quit()
|
||||||
|
l_c = self.media_by_user[i]['node']['edge_liked_by']['count']
|
||||||
if l_c <= self.media_max_like and l_c >= self.media_min_like:
|
if l_c <= self.media_max_like and l_c >= self.media_min_like:
|
||||||
log_string = "Trying to like media: %s" %\
|
log_string = "Trying to like media: %s" %\
|
||||||
(self.media_by_user[i]['id'])
|
(self.media_by_user[i]['node']['id'])
|
||||||
self.write_log(log_string)
|
self.write_log(log_string)
|
||||||
like = self.like(self.media_by_user[i]['id'])
|
like = self.like(self.media_by_user[i]['node']['id'])
|
||||||
if like != 0:
|
if like != 0:
|
||||||
if like.status_code == 200:
|
if like.status_code == 200:
|
||||||
log_string = "Liked: %s. Likes: #%i." %\
|
log_string = "Liked: %s. Likes: #%i." %\
|
||||||
(self.media_by_user[i]['id'],
|
(self.media_by_user[i]['node']['id'],
|
||||||
self.media_by_user[i]['likes']['count'])
|
self.media_by_user[i]['node']['edge_liked_by']['count'])
|
||||||
self.write_log(log_string)
|
self.write_log(log_string)
|
||||||
elif like.status_code == 400:
|
elif like.status_code == 400:
|
||||||
log_string = "Not liked: %i" \
|
log_string = "Not liked: %i" \
|
||||||
@ -25,5 +29,5 @@ def new_like_all_exist_media(self):
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
print('Too much liker for this media!!! LC = %i' % (l_c))
|
print('Too many likes on this media LC = %i' % (l_c))
|
||||||
return True
|
return True
|
||||||
|
0
bot/src/new_auto_mod_unfollow2.py
Normal file → Executable file
0
bot/src/new_auto_mod_unfollow2.py
Normal file → Executable file
2
bot/src/new_unfollow.py
Normal file → Executable file
2
bot/src/new_unfollow.py
Normal file → Executable file
@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from .sql_updates import insert_unfollow_count
|
||||||
|
|
||||||
def new_unfollow(self, user_id, user_name):
|
def new_unfollow(self, user_id, user_name):
|
||||||
""" Send http request to unfollow """
|
""" Send http request to unfollow """
|
||||||
@ -12,6 +13,7 @@ def new_unfollow(self, user_id, user_name):
|
|||||||
log_string = "Unfollow: %s #%i." % (user_name,
|
log_string = "Unfollow: %s #%i." % (user_name,
|
||||||
self.unfollow_counter)
|
self.unfollow_counter)
|
||||||
self.write_log(log_string)
|
self.write_log(log_string)
|
||||||
|
insert_unfollow_count(self, user_id=user_id)
|
||||||
return unfollow
|
return unfollow
|
||||||
except:
|
except:
|
||||||
self.write_log("Exept on unfollow!")
|
self.write_log("Exept on unfollow!")
|
||||||
|
0
bot/src/post_page.py
Normal file → Executable file
0
bot/src/post_page.py
Normal file → Executable file
11
bot/src/recent_feed.py
Normal file → Executable file
11
bot/src/recent_feed.py
Normal file → Executable file
@ -3,6 +3,7 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import json
|
import json
|
||||||
import time
|
import time
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
def get_media_id_recent_feed(self):
|
def get_media_id_recent_feed(self):
|
||||||
@ -11,12 +12,16 @@ def get_media_id_recent_feed(self):
|
|||||||
log_string = "%s : Get media id on recent feed \n %s" % (
|
log_string = "%s : Get media id on recent feed \n %s" % (
|
||||||
self.user_login, now_time.strftime("%d.%m.%Y %H:%M"))
|
self.user_login, now_time.strftime("%d.%m.%Y %H:%M"))
|
||||||
self.write_log(log_string)
|
self.write_log(log_string)
|
||||||
url = 'https://www.instagram.com/?__a=1'
|
url = 'https://www.instagram.com/'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
r = self.s.get(url)
|
r = self.s.get(url)
|
||||||
all_data = json.loads(r.text)
|
jsondata = re.search('additionalDataLoaded\(\'feed\',({.*})\);', r.text).group(1)
|
||||||
|
all_data = json.loads(jsondata.strip())
|
||||||
|
|
||||||
self.media_on_feed = list(all_data['graphql']['user']['edge_web_feed_timeline']['edges'])
|
self.media_on_feed = list(all_data['user']['edge_web_feed_timeline']['edges'])
|
||||||
log_string = "Media in recent feed = %i" % (
|
log_string = "Media in recent feed = %i" % (
|
||||||
len(self.media_on_feed))
|
len(self.media_on_feed))
|
||||||
self.write_log(log_string)
|
self.write_log(log_string)
|
||||||
|
52
bot/src/sql_updates.py
Normal file → Executable file
52
bot/src/sql_updates.py
Normal file → Executable file
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import sqlite3
|
import sqlite3
|
||||||
from datetime import datetime, time
|
from datetime import datetime, time, timedelta
|
||||||
|
|
||||||
def check_and_update(self):
|
def check_and_update(self):
|
||||||
""" At the Program start, i does look for the sql updates """
|
""" At the Program start, i does look for the sql updates """
|
||||||
@ -23,7 +23,7 @@ def check_and_update(self):
|
|||||||
if not table_column_status:
|
if not table_column_status:
|
||||||
qry = """
|
qry = """
|
||||||
CREATE TABLE "usernames_new" ( `username_id` varchar ( 300 ), `username` TEXT );
|
CREATE TABLE "usernames_new" ( `username_id` varchar ( 300 ), `username` TEXT );
|
||||||
INSERT INTO "usernames_new" (username_id) Select username from usernames;
|
INSERT INTO "usernames_new" (username) Select username from usernames;
|
||||||
DROP TABLE "usernames";
|
DROP TABLE "usernames";
|
||||||
ALTER TABLE "usernames_new" RENAME TO "usernames";
|
ALTER TABLE "usernames_new" RENAME TO "usernames";
|
||||||
"""
|
"""
|
||||||
@ -45,7 +45,7 @@ def check_and_update(self):
|
|||||||
#table_column_status = [o for o in table_info if o[1] == "last_followed_time"]
|
#table_column_status = [o for o in table_info if o[1] == "last_followed_time"]
|
||||||
#if not table_column_status:
|
#if not table_column_status:
|
||||||
# self.follows_db_c.execute("ALTER TABLE usernames ADD COLUMN last_followed_time TEXT")
|
# self.follows_db_c.execute("ALTER TABLE usernames ADD COLUMN last_followed_time TEXT")
|
||||||
|
|
||||||
|
|
||||||
def check_already_liked(self, media_id):
|
def check_already_liked(self, media_id):
|
||||||
""" controls if media already liked before """
|
""" controls if media already liked before """
|
||||||
@ -61,6 +61,13 @@ def check_already_followed(self, user_id):
|
|||||||
return 1
|
return 1
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
def check_already_unfollowed(self, user_id):
|
||||||
|
""" controls if user was already unfollowed before """
|
||||||
|
if self.follows_db_c.execute("SELECT EXISTS(SELECT 1 FROM usernames WHERE username_id='"+
|
||||||
|
user_id + "' AND unfollow_count > 0 LIMIT 1)").fetchone()[0] > 0:
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
|
|
||||||
def insert_media(self, media_id, status):
|
def insert_media(self, media_id, status):
|
||||||
""" insert media to medias """
|
""" insert media to medias """
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
@ -112,6 +119,45 @@ def get_username_random(self):
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def get_username_to_unfollow_random(self):
|
||||||
|
""" Gets random username that is older than follow_time and has zero unfollow_count """
|
||||||
|
now_time = datetime.now()
|
||||||
|
cut_off_time = now_time - timedelta(seconds=self.follow_time)
|
||||||
|
username = self.follows_db_c.execute("SELECT * FROM usernames WHERE \
|
||||||
|
DATETIME(last_followed_time) < DATETIME('"+str(cut_off_time)+"') \
|
||||||
|
AND unfollow_count=0 ORDER BY RANDOM() LIMIT 1").fetchone()
|
||||||
|
if username:
|
||||||
|
return username
|
||||||
|
else:
|
||||||
|
username = self.follows_db_c.execute("SELECT * FROM usernames WHERE \
|
||||||
|
unfollow_count=0 ORDER BY RANDOM() LIMIT 1").fetchone()
|
||||||
|
if username:
|
||||||
|
return username
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def get_username_row_count(self):
|
||||||
|
""" Gets the number of usernames in table """
|
||||||
|
count = self.follows_db_c.execute("select count(*) from usernames").fetchone()
|
||||||
|
if count:
|
||||||
|
return count[0]
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_if_userid_exists(self, userid):
|
||||||
|
""" Checks if username exists """
|
||||||
|
#print("select count(*) from usernames WHERE username_id = " + userid)
|
||||||
|
count = self.follows_db_c.execute("select count(*) from usernames WHERE username_id = " + userid).fetchone()
|
||||||
|
if count:
|
||||||
|
if count[0] > 0:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
def check_and_insert_user_agent(self, user_agent):
|
def check_and_insert_user_agent(self, user_agent):
|
||||||
""" Check user agent """
|
""" Check user agent """
|
||||||
qry = "SELECT settings_val from settings where settings_name = 'USERAGENT'"
|
qry = "SELECT settings_val from settings where settings_name = 'USERAGENT'"
|
||||||
|
0
bot/src/unfollow_protocol.py
Normal file → Executable file
0
bot/src/unfollow_protocol.py
Normal file → Executable file
0
bot/src/unfollowpub.py
Normal file → Executable file
0
bot/src/unfollowpub.py
Normal file → Executable file
15
bot/src/user_feed.py
Normal file → Executable file
15
bot/src/user_feed.py
Normal file → Executable file
@ -15,22 +15,13 @@ def get_media_id_user_feed(self):
|
|||||||
if self.is_checked != True:
|
if self.is_checked != True:
|
||||||
get_user_info(self, self.current_user)
|
get_user_info(self, self.current_user)
|
||||||
if self.is_fake_account != True and self.is_active_user != False and self.is_selebgram != True or self.is_by_tag != False:
|
if self.is_fake_account != True and self.is_active_user != False and self.is_selebgram != True or self.is_by_tag != False:
|
||||||
url = 'https://www.instagram.com/%s/?__a=1' % (self.current_user)
|
url = 'https://www.instagram.com/%s/' % (self.current_user)
|
||||||
else:
|
|
||||||
log_string = "======> Get media id by Tag <======"
|
|
||||||
url = 'https://www.instagram.com/explore/tags/%s/?__a=1' % (
|
|
||||||
random.choice(self.tag_list))
|
|
||||||
self.write_log(log_string)
|
self.write_log(log_string)
|
||||||
|
|
||||||
if self.login_status == 1 and self.is_fake_account != True and self.is_active_user != False and self.is_selebgram != True or self.is_by_tag != False:
|
if self.login_status == 1 and self.is_fake_account != True and self.is_active_user != False and self.is_selebgram != True or self.is_by_tag != False:
|
||||||
try:
|
try:
|
||||||
r = self.s.get(url)
|
|
||||||
all_data = json.loads(r.text)
|
self.media_by_user = list(self.current_user_info['edge_owner_to_timeline_media']['edges'])
|
||||||
|
|
||||||
if self.is_by_tag != True:
|
|
||||||
self.media_by_user = list(all_data['user']['media']['nodes'])
|
|
||||||
else:
|
|
||||||
self.media_by_user = list(all_data['graphql']['hashtag']['edge_hashtag_to_media']['edges'])
|
|
||||||
log_string = "Get media by user success!"
|
log_string = "Get media by user success!"
|
||||||
self.write_log(log_string)
|
self.write_log(log_string)
|
||||||
except:
|
except:
|
||||||
|
2
bot/src/user_feed_protocol.py
Normal file → Executable file
2
bot/src/user_feed_protocol.py
Normal file → Executable file
@ -22,7 +22,7 @@ def user_feed_protocol(self):
|
|||||||
return 0
|
return 0
|
||||||
if self.is_follower is not False:
|
if self.is_follower is not False:
|
||||||
print(
|
print(
|
||||||
"@@@@@@@@@@@@@@ This is your follower B****h!!! @@@@@@@@@@@@@")
|
"This is your follower")
|
||||||
self.is_follower_number += 1
|
self.is_follower_number += 1
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
return
|
return
|
||||||
|
145
bot/src/user_info.py
Normal file → Executable file
145
bot/src/user_info.py
Normal file → Executable file
@ -4,84 +4,85 @@ import datetime
|
|||||||
import json
|
import json
|
||||||
import random
|
import random
|
||||||
import time
|
import time
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
def get_user_info(self, username):
|
def get_user_info(self, username):
|
||||||
if self.login_status:
|
current_user = username
|
||||||
now_time = datetime.datetime.now()
|
log_string = "Getting user info : %s" % current_user
|
||||||
log_string = "%s : Get user info \n%s" % (
|
self.write_log(log_string)
|
||||||
self.user_login, now_time.strftime("%d.%m.%Y %H:%M"))
|
if self.login_status == 1:
|
||||||
self.write_log(log_string)
|
url_tag = self.url_user_detail % (current_user)
|
||||||
if self.login_status == 1:
|
if self.login_status == 1:
|
||||||
url = 'https://www.instagram.com/%s/?__a=1' % (username)
|
r = self.s.get(url_tag)
|
||||||
try:
|
if r.text.find('The link you followed may be broken, or the page may have been removed.') != -1:
|
||||||
r = self.s.get(url)
|
log_string = "Looks like account was deleted, skipping : %s" % current_user
|
||||||
|
self.write_log(log_string)
|
||||||
|
insert_unfollow_count(self, user_id=current_id)
|
||||||
|
time.sleep(3)
|
||||||
|
return False
|
||||||
|
all_data = json.loads(re.search('window._sharedData = (.*?);</script>', r.text, re.DOTALL).group(1))['entry_data']['ProfilePage'][0]
|
||||||
|
|
||||||
user_info = json.loads(r.text)
|
user_info = all_data['graphql']['user']
|
||||||
|
self.current_user_info = user_info
|
||||||
|
i = 0
|
||||||
|
log_string = "Checking user info.."
|
||||||
|
self.write_log(log_string)
|
||||||
|
|
||||||
log_string = "Checking user info.."
|
follows = user_info['edge_follow']['count']
|
||||||
self.write_log(log_string)
|
follower = user_info['edge_followed_by']['count']
|
||||||
|
media = user_info['edge_owner_to_timeline_media']['count']
|
||||||
|
follow_viewer = user_info['follows_viewer']
|
||||||
|
followed_by_viewer = user_info[
|
||||||
|
'followed_by_viewer']
|
||||||
|
requested_by_viewer = user_info[
|
||||||
|
'requested_by_viewer']
|
||||||
|
has_requested_viewer = user_info[
|
||||||
|
'has_requested_viewer']
|
||||||
|
log_string = "Follower : %i" % (follower)
|
||||||
|
self.write_log(log_string)
|
||||||
|
log_string = "Following : %s" % (follows)
|
||||||
|
self.write_log(log_string)
|
||||||
|
log_string = "Media : %i" % (media)
|
||||||
|
self.write_log(log_string)
|
||||||
|
if follows == 0 or follower / follows > 2:
|
||||||
|
self.is_selebgram = True
|
||||||
|
self.is_fake_account = False
|
||||||
|
self.write_log(' >>>This is probably Selebgram account')
|
||||||
|
elif follower == 0 or follows / follower > 2:
|
||||||
|
self.is_fake_account = True
|
||||||
|
self.is_selebgram = False
|
||||||
|
self.write_log(' >>>This is probably Fake account')
|
||||||
|
else:
|
||||||
|
self.is_selebgram = False
|
||||||
|
self.is_fake_account = False
|
||||||
|
self.write_log(' >>>This is a normal account')
|
||||||
|
|
||||||
follows = user_info['user']['follows']['count']
|
if media > 0 and follows / media < 25 and follower / media < 25:
|
||||||
follower = user_info['user']['followed_by']['count']
|
self.is_active_user = True
|
||||||
if self.is_self_checking is not False:
|
self.write_log(' >>>This user is active')
|
||||||
self.self_following = follows
|
else:
|
||||||
self.self_follower = follower
|
self.is_active_user = False
|
||||||
self.is_self_checking = False
|
self.write_log(' >>>This user is passive')
|
||||||
self.is_checked = True
|
|
||||||
return 0
|
if follow_viewer or has_requested_viewer:
|
||||||
media = user_info['user']['media']['count']
|
self.is_follower = True
|
||||||
follow_viewer = user_info['user']['follows_viewer']
|
self.write_log(" >>>This account is following you")
|
||||||
followed_by_viewer = user_info['user']['followed_by_viewer']
|
else:
|
||||||
requested_by_viewer = user_info['user'][
|
self.is_follower = False
|
||||||
'requested_by_viewer']
|
self.write_log(' >>>This account is NOT following you')
|
||||||
has_requested_viewer = user_info['user'][
|
|
||||||
'has_requested_viewer']
|
if followed_by_viewer or requested_by_viewer:
|
||||||
log_string = "Follower : %i" % (follower)
|
self.is_following = True
|
||||||
self.write_log(log_string)
|
self.write_log(' >>>You are following this account')
|
||||||
log_string = "Following : %s" % (follows)
|
|
||||||
self.write_log(log_string)
|
else:
|
||||||
log_string = "Media : %i" % (media)
|
self.is_following = False
|
||||||
self.write_log(log_string)
|
self.write_log(' >>>You are NOT following this account')
|
||||||
|
|
||||||
if follows == 0 or follower / follows > 2:
|
|
||||||
self.is_selebgram = True
|
|
||||||
self.is_fake_account = False
|
|
||||||
print(' >>>This is probably Selebgram account')
|
|
||||||
elif follower == 0 or follows / follower > 2:
|
|
||||||
self.is_fake_account = True
|
|
||||||
self.is_selebgram = False
|
|
||||||
print(' >>>This is probably Fake account')
|
|
||||||
else:
|
else:
|
||||||
self.is_selebgram = False
|
logging.exception("Except on auto_unfollow!")
|
||||||
self.is_fake_account = False
|
time.sleep(3)
|
||||||
print(' >>>This is a normal account')
|
return False
|
||||||
|
else:
|
||||||
if media > 0 and follows / media < 10 and follower / media < 10:
|
|
||||||
self.is_active_user = True
|
|
||||||
print(' >>>This user is active')
|
|
||||||
else:
|
|
||||||
self.is_active_user = False
|
|
||||||
print(' >>>This user is passive')
|
|
||||||
|
|
||||||
if follow_viewer or has_requested_viewer:
|
|
||||||
self.is_follower = True
|
|
||||||
print(" >>>This account is following you")
|
|
||||||
else:
|
|
||||||
self.is_follower = False
|
|
||||||
print(' >>>This account is NOT following you')
|
|
||||||
|
|
||||||
if followed_by_viewer or requested_by_viewer:
|
|
||||||
self.is_following = True
|
|
||||||
print(' >>>You are following this account')
|
|
||||||
else:
|
|
||||||
self.is_following = False
|
|
||||||
print(' >>>You are NOT following this account')
|
|
||||||
self.is_checked = True
|
|
||||||
except:
|
|
||||||
self.media_on_feed = []
|
|
||||||
self.write_log("Except on get_info!")
|
|
||||||
time.sleep(20)
|
|
||||||
return 0
|
return 0
|
||||||
else:
|
|
||||||
return 0
|
|
||||||
|
2
bot/src/userinfo.py
Normal file → Executable file
2
bot/src/userinfo.py
Normal file → Executable file
@ -39,7 +39,7 @@ class UserInfo:
|
|||||||
def get_user_id_by_login(self, user_name):
|
def get_user_id_by_login(self, user_name):
|
||||||
url_info = self.url_user_info % (user_name)
|
url_info = self.url_user_info % (user_name)
|
||||||
info = self.s.get(url_info)
|
info = self.s.get(url_info)
|
||||||
json_info = json.loads(re.search('{"activity.+show_app', info.text, re.DOTALL).group(0)+'":""}')
|
json_info = json.loads(re.search('window._sharedData = (.*?);</script>', info.text, re.DOTALL).group(1))
|
||||||
id_user = json_info['entry_data']['ProfilePage'][0]['graphql']['user']['id']
|
id_user = json_info['entry_data']['ProfilePage'][0]['graphql']['user']['id']
|
||||||
return id_user
|
return id_user
|
||||||
|
|
||||||
|
0
bot/src/username_checker.py
Normal file → Executable file
0
bot/src/username_checker.py
Normal file → Executable file
Loading…
Reference in New Issue
Block a user