

import requests
import os
import datetime
import time
import math
import json
import pathlib
import shutil
import decimal
import traceback
import pandas as pd
import numpy as np
import sys
import threading
import copy
import asyncio
import random
import re
class BaseVariableFunction:
    def __init__(self, scriptfile):
        # 获取当前脚本的名字
        self.scriptfilename = pathlib.Path(scriptfile).name
        # 获取脚本所在目录的绝对路径
        self.script_directory = pathlib.Path(scriptfile).resolve().parent
        self.src_directory = self.script_directory.parent
        # 获取项目所在目录的绝对路径
        self.project_directory = self.src_directory.parent

        self.src_directory = self.project_directory/"src/"
        self.code_path = self.project_directory / 'src/code/'
        self.library_path = self.project_directory / 'src/library/'
        self.librarydata_path = self.project_directory / 'src/librarydata/'
        self.base_library_file = self.code_path / 'base_library.json'
        self.newpair_from_dexscreener_path = self.librarydata_path/"newpair_from_dexscreener/"
        self.dalao_ori_tran_txhash_solscan_path = self.librarydata_path / \
            "dalao_ori_tran_txhash_solscan/"
        self.dalao_solscan_info_path = self.librarydata_path / \
            "dalao_solscan_info/"
            
        self.dalao_tran_txhash_path = self.librarydata_path/"dalao_tran_txhash/"

        self.newpair_merge_path = self.librarydata_path/"newpair_merge/"
        self.browsercookie_path = self.library_path/"browsercookie/"

        self.dalao_from_dexscreener_path = self.librarydata_path / \
            "dalao_from_dexscreener/"
        self.dalao_merge_path = self.librarydata_path/"dalao_merge/"

        self.dalao_merge_defined_path = self.librarydata_path/"dalao_merge_defined/"
        
        self.dalao_ori_tran_dexscreen_path = self.librarydata_path/"dalao_ori_tran_dexscreen/"
        
        
        self.dalao_ori_tran_defined_path = self.librarydata_path/"dalao_ori_tran_defined/"
        self.dalao_ori_tran_gmgnOrdex_path = self.librarydata_path/"dalao_ori_tran_gmgnOrdex/"
        self.dalao_tran_gmgnOrdex_path = self.librarydata_path/"dalao_tran_gmgnOrdex/"
        self.dune_excution_path = self.librarydata_path/"dune_excution/"
        self.dune_token_graph_path = self.librarydata_path/"dune_token_graph/"
        self.ana_dalao_relation_by_solscan_path =  self.librarydata_path/"ana_dalao_relation_by_solscan/"
        
        
        
        
        
        
        self.dalao_tran_defined_path = self.librarydata_path/"dalao_tran_defined/"
        
        self.analysis_token_path  =self.library_path / "analysis_token/"
        
        
 
        self.dalao_transfer_solanafm_path = self.librarydata_path / \
            "dalao_transfer_solanafm/"
        self.dalao_tokentransfer_solanafm_path = self.librarydata_path / \
            "dalao_tokentransfer_solanafm/"
        self.dalao_transaction_st_solanafm_path = self.librarydata_path / \
            "dalao_transaction_st_solanafm/"
        self.dalao_configtoken_st_solanafm_path = self.librarydata_path / \
            "dalao_configtoken_st_solanafm/"

        self.dalao_activities_solscan_path = self.librarydata_path / \
            "dalao_activities_solscan/"
            
        self.dalao_activities_gmgn_path = self.librarydata_path / \
            "dalao_activities_gmgn/"
        self.dalao_ori_pnl_gmgn_path = self.librarydata_path / \
            "dalao_ori_pnl_gmgn/"
        self.dalao_pnl_gmgn_path = self.librarydata_path / \
            "dalao_pnl_gmgn/"
        self.dalao_total_ana_gmgn_path = self.librarydata_path / "dalao_total_ana_gmgn/"
         
        self.dalao_config_st_solscan_path = self.librarydata_path / \
            "dalao_config_st_solscan/"
        self.dalao_profit_st_solscan_path = self.librarydata_path / "dalao_profit_st_solscan/"
        self.dalao_total_ana_solscan_path = self.librarydata_path / "dalao_total_ana_solscan/"

        self.dalao_ana_solscan_path = self.librarydata_path / "dalao_ana_solscan/"

        self.dalao_ana_fm_path = self.librarydata_path / "dalao_ana_fm/"
        self.new_dalao_ana_fm_path = self.librarydata_path / "new_dalao_ana_fm/"

        self.dalao_total_ana_fm_path = self.librarydata_path / "dalao_total_ana_fm/"
        self.dalao_profit_st_fm_path = self.librarydata_path / "dalao_profit_st_fm/"
        self.new_dalao_total_ana_fm_path = self.librarydata_path / "new_dalao_total_ana_fm/"
        self.dalao_signatures_path = self.librarydata_path / "dalao_signatures/"
        self.dalao_transaction_path = self.librarydata_path / "dalao_transaction/"
        self.dalao_ori_st_path = self.librarydata_path / "dalao_ori_st/"
        self.dalao_configtoken_st_path = self.librarydata_path / "dalao_configtoken_st/"
        self.dalao_profit_st_path = self.librarydata_path / "dalao_profit_st/"
        self.dalao_ana_path = self.librarydata_path / "dalao_ana/"
 

        self.solana_fm_headers = {
            "accept": "application/json",
            "content-type": "application/json",
            # "ApiKey": "sk_live_5a2d94637a2942e294e91ea58f070f3a"
      
            
        }
        self.arr_drop_token_froselecteddalao = [
            
            "DZM5CXzHXzUaxQVdf4LVFXTgAR7XBMpXxoyakPJVpump",
            "83sjxMqcV9ynx4sSEjwL3NqNB7AoyiQLqdnuNHFXpump",
            "2TQHtfEzqXpMYFaBGaURCBwhVRSBLTRvSpciVLmApump",
            "H3Zh6Lq8SnwoZMQCic3omRvxHGbvv5z1hcZ4fGxhpump",
            "8UzSrHEkoPofAFSmUh5k2pnxJrX1FV68bNXsQH7fpump",

 
                                            ]
        self.mywalletaddress="Cft4hKtC3dVftfqmL2MCALpeCq7oWM7qpftNfVVUzA7h"
        self.headers = {
            "accept": "application/json",
            "content-type": "application/json"
        }
        self.str_token_address="A8C3xuqscfmyLrte3VmTqrAq8kgMASius9AFNANwpump"

        self.arr_pub_address = [
            "5DGhcY7QKci7BhpAqboHYT3weVPcyNAwUVN8JYCL8viT",
            "5Q544fKrFoe6tsEbD7S8EmxGTJYAKtTVhAW5Q5pge4j1",
            "EAiYEwo7N2WLfFwNsnxVKxH4ZehVBTbVbzsd59yREqAv",
            "9nnLbotNTcUhvbrsA6Mdkx45Sm82G35zo28AqUvjExn8",
            "6U91aKa8pmMxkJwBCfPTmUEfZi6dHe7DcFq2ALvB2tbB",
            "4Agisox25EQTQ5LSgmETfMXrLZKZodmePMvnVoqQQFw5",
            "5eDWEqd9LuedRwXCaVkghFjyRTT2aMeEr667y65bzmEu",
            "5WU2HTcgGKf6EVBVqBxVaXNRndh8Stqj8dKqpdZeTBZL",
            "F7KnmZuzqpZnbXaGnSt8DvuPsHS6N8LK1uRzLDwEkipX",
            "62kLsCvpEVXr54qJGqgoqrbaEK8Y17eDZtXWEnS2JDzD",
            "AC8FeLuP5ysJSYY4RUtUh9R2JXdpT4ZxnMBGmAC8Rrdj",
            "Fm3DL8T4whBCk5yHLUTG6HGRbrzm3rsDkaRPF4GVVRuC",
        ]
        
        self.arr_duneapi=['W7zTOtVucO0CepixObF7MgGGTzqUYqbM']
        
        self.PROVIDER_NAME_BY_ADDRESS = [[
  ["DSwpgjMvXhtGn6BsbqmacdBZyfLj6jSWf3HJpdJtmg6N", "Dexlab"],
  ["BSwp6bEBihVLdqJRKGgzjcGLHkcTuzmSo1TQkHepzH8p", "Bonkswap"],
  ["Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB", "Meteora"],
  ["FLUXubRmkEi2q6K3Y9kBPg9248ggaZVsoSFhtJHSrm1X", "FluxBeam"],
  ["HyaB3W9q6XdA5xwpU4XnSZV94htfmbmqJXZcEbRaJutt", "Invariant"],
  ["PERPHjGBqRHArX4DySjwM6UJHiR3sWAatqfdBS2qQJu", "Perps"],
  ["treaf4wWBBty3fHdyBpo35Mz84M8k3heKXmjmi9vFt5", "Helium Network"],
  ["DjVE6JNiYqPL2QXyCUUh8rNjHrbz9hXHNYt99MQ59qw1", "Orca V1"],
  ["CURVGoZn8zycx6FXwwevgBTB2gVvdbGTEpvMJDbgs2t4", "Aldrin V2"],
  ["LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo", "Meteora DLMM"],
  ["PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY", "Phoenix"],
  ["SSwapUtytfBdBn1b9NUGG6foMVPtcWgpRU32HToDUZr", "Saros"],
  ["AMM55ShdkoGRB5jVYPjWziwk8m5MpwyDgsMWHaMSQWH6", "Aldrin"],
  ["9tKE7Mbmj4mxDjWatikzGAtkoWosiiZX9y6J4Hfm2R8H", "Oasis"],
  ["MERLuDFBMmsHnsBPZw2sDQZHvXFMwp8EdjudcU2HKky", "Mercurial"],
  ["SwaPpA9LAaLfeLi3a68M4DjnLqgtticKg6CnyNwgAC8", "Token Swap"],
  ["srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX", "Openbook"],
  ["CLMM9tUoggJu2wagPkkqs9eFG4BWhVBZWkP1qv3Sp7tR", "Crema"],
  ["DecZY86MU5Gj7kppfUCEmd4LbXXuyZH1yHaP2NTqdiZB", "Saber (Decimals)"],
  ["CTMAxxk34HjKWxQ3QLZK1HpaLXmBveao3ESePXbiyfzh", "Cropper"],
  ["CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK", "Raydium CLMM"],
  ["whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc", "Whirlpool"],
  ["PSwapMdSai8tjrEXcxFeQth87xC4rRsa4VA5mhGhXkP", "Penguin"],
  ["EewxydAPCCVuNEyrVN68PuSYdQ7wKn27V9Gjeoi8dy3S", "Lifinity V1"],
  ["C1onEW2kPetmHmwe74YC1ESx3LnFEpVau6g2pg4fHycr", "Clone Protocol"],
  ["2wT8Yq49kHgDzXuPxZSaeLaH1qbmGXtEyPy64bL7aD3c", "Lifinity V2"],
  ["Dooar9JkhdZ7J3LHN3A7YCuoGRUggXhQaG4kijfLGU2j", "StepN"],
  ["9W959DqEETiGZocYWCQPaJ6sBmUzgfxXfqGeTEdp3aQP", "Orca V2"],
  ["opnb2LAfJYbRMAHHvqjCwQxanZn7ReEHp1k81EohpZb", "OpenBook V2"],
  ["MarBmsSgKXdrN1egZf5sqe1TMai9K1rChYNDJgjq7aD", "Marinade"],
  ["GFXsSL5sSaDfNFQUYsHekbWBW1TsFdjDYzACh62tEHxn", "GooseFX"],
  ["SSwpkEEcbUqx4vtoEByFjSkhKdCT862DNVb52nZg1UZ", "Saber"],
  ["stkitrT1Uoy18Dk1fTrgPw8W6MVzoCfYoAFT4MLsmhq", "Sanctum"],
  ["675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8", "Raydium"],
  
#     - dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH # drift v2
#   - jupoNjAxXgZ4rjzxzPMP4oxduvQsQtZzyknqvzYNrNu # Jupiter limit
#   - PERPHjGBqRHArX4DySjwM6UJHiR3sWAatqfdBS2qQJu # Jupiter perp
#   - JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4 # Jupiter swap
#   - PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY # Phoenix
  
]]



    def makedirpath(self, folder):
        pathlib.Path(folder).mkdir(exist_ok=True)

    def rmfolder(self, folder):
        if pathlib.Path(folder).exists():
            shutil.rmtree(folder)

    def open_base_library(self):

        with self.base_library_file.open(mode='r', encoding='utf-8') as f:
            self.base_library = json.load(f)
        return self.base_library

    def readcsvfiles_2df(self, csv_path):

        csv_file_list = [f for f in os.listdir(csv_path) if f.endswith(".csv")]
        merge_df = pd.DataFrame()
        for csv_file in csv_file_list:
            new_df = pd.read_csv(
                csv_path / csv_file, dtype=object)

            merge_df = pd.concat([merge_df, new_df]).reset_index(drop=True)

        return merge_df

    def ISO8601_str_to_timestamp(self, datetime_str):
        # 将'2023-08-28T12:43:52Z' 结构的str 转化为utc的时间戳(单位:秒)
        # Define the format of the input datetime string
        # Adjust the format as per your input datetime string
        format_str = '%Y-%m-%dT%H:%M:%SZ'
        # 解析'2023-08-12T22:22:50Z' 并转换为0时区的时间
        dt = datetime.datetime.strptime(datetime_str, format_str).replace(
            tzinfo=datetime.timezone.utc)
        # Convert the datetime object to a timestamp (number of seconds since the epoch)
        timestamp = int(dt.timestamp())
        return timestamp

    def init_req_dict(self, param_sort="asc", offsettimes_max=10, key_idx=None, address=None, action=None, actiontype=None,  apikey=None, remainder_retry_times_max=5, startrange=27000000, endrange=99000000, timeout=30):
        # 一个dict 对应一个address 的某一个block范围 一次性的，用完如果end>start 就remove 这个dict  如果一个address 有两个block range 那么会有两个dict
        # requests_dict key 為空列表 ，使用append 進行添加
        # requests_dict 進行初始化定義
        # timeout ,請求request 的超時時間
        # start 初始化以及每次reset重置的start
        # remainder_retry_times_max 初始以及重置的初始 可以重傳次數
        # tokencontract_params_list 請求bscscan api的參數設置
        # offsettimes_max  允許的 offset 最大次數，默認一次offset 請求10000條
        # req_response 接受響應列表
        # offsettimes  記錄此add的offset 次數，等於offsettimes_max 就要停止報錯
        # need_remove 此項的響應是否處理完成，如果處理完成(多次超時報錯或數據不對，或者分析完成)，為True，
        #   可以刪除，相應的tokencontracts 列表中的tradersadds 也需要remove此項索引被其他未完成的覆蓋
        # remainder_retry_times 出現超時或請求錯誤可以進行重傳，此爲還可以重傳的次數
        # key_idx 由于是异步执行函数 所有dict 会放在一dict 中 key_idx 就是当前dict在总的dict的索引当前dict 完成，就可以在总dict删除这个索引

        if address is None:
            raise Exception("not set address")
        if key_idx is None:
            raise Exception("not set key_idx")

        requests_dict = {}
        requests_dict["key_idx"] = key_idx
        requests_dict["address"] = address
        requests_dict["timeout"] = timeout
        requests_dict["startrange"] = startrange
        requests_dict["endrange"] = endrange
        requests_dict["remainder_retry_times_max"] = remainder_retry_times_max
        requests_dict["offsettimes_max"] = offsettimes_max
        # 上面部分是无论发送了多少次请求都不变得
        # 正在请求中 isrequseting=True 避免之前的没有结果，有发起新的请求
        requests_dict["isrequseting"] = False
        requests_dict["req_params"] = {}
        requests_dict["req_response"] = None
        requests_dict["req_pd"] = None
        requests_dict["offsettimes"] = 0
        requests_dict["need_remove"] = False
        requests_dict["isfirstreq"] = True
        requests_dict["remainder_retry_times"] = remainder_retry_times_max

        requests_dict["req_params"] = {
            "module": "account",

            "address": address,
            "page": 1,
            # "offset": 10000,
            "startrange": startrange,
            "endrange": endrange,
            "limit": 100,
            "sort": param_sort,
            "apikey": apikey
        }

        return requests_dict

    def handle_IF_tokenresponse_NOTOK(self, tokenresponse,  cur_conadd, key_idx, requests_dict, req_dict_total):
        # 對於相應正常，結果不正常的，可能是沒有交易記錄 可能是訪問頻率過高等，
        # 對於部分不OK的情況，可以分別處理
        # { "status": "0", "message": "No transactions found", "result": [] }
        # { "status": "0", "message": "NOTOK", "result": "Max rate limit reached, please use API Key for higher rate limit" }
        # { "status": "0", "message": "NOTOK", "result": "Contract source code not verified" }
        # {'status': '0', 'message': 'NOTOK', 'result': 'Error! Invalid contract address format'}
        # {'status': '0', 'message': 'Query Timeout occured. Please select a smaller result dataset',result': None}
        print(
            f"tokenresponse message NOTOK  {cur_conadd} \n", "tokenresponse=", tokenresponse, '\n', end='')
        # print("test tokenresponse",
        #       tokenresponse["message"], tokenresponse["result"])
        if (1 == 2):
            print("i dont know")

        else:
            raise Exception(
                'tokenresponse message NOTOK And No matched method')

    def judge_req_completed(self, requests_dict,  key_idx, cur_conadd, req_dict_total):
        if requests_dict["req_params"]["endrange"] <= requests_dict["req_params"]["startrange"]:
            # 如果接下来的block 范围有问题 startblcok >end 说明已经获取完毕 ，不用再获取了
            print(
                f"{cur_conadd} startblcok >end 结束\n", end='')
            requests_dict["need_remove"] = True
            if req_dict_total.get(key_idx) is not None:
                print(f"remove  {cur_conadd} {key_idx}\n", end='')
                del req_dict_total[key_idx]

    def get_current_timestamp(self):

        timestamp = math.floor(time.time())
        return timestamp

    def analysis_lastdays(self, df, now_unix_time, intervaldays=30):
        if len(df) == 0:
            return 0, 0, 0, 0, 0, 0, 0, 0, 0
        # need consider df may null if use iloc
        lastdf = df[df["TokenFirstTime"] >=
                    now_unix_time - 3600*24*intervaldays]
        # 去除那些earnper为-10的
        lastdf = lastdf[lastdf['cost_main'] != 0]
        lastdf = lastdf.reset_index(drop=True)
        if len(lastdf) == 0:
            return 0, 0, 0, 0,  0, 0, 0, 0, 0
        last_cost_sum = lastdf['cost_main'].sum()
        last_earn_sum = lastdf['earn_main'].sum()
        last_cost_median = lastdf['cost_main'].median()
        last_cost_mean = lastdf['cost_main'].mean()
        last_earnper = last_earn_sum / last_cost_sum if last_cost_sum != 0 else -10
        last_trans_amount = len(lastdf)
        lastdf['earn_percent'] = np.where(
            lastdf['cost_main'] != 0,
            lastdf['earn_main'] / lastdf['cost_main'],
            -10,
        )
        # last_earncount_per = (len(lastdf[(
        #     lastdf['earn_percent'] >= 0.05)]) / len(lastdf) if len(lastdf) != 0 else 0)
        earnmain_max = lastdf['earn_main'].max()
        last_earn_difmax_sum = last_earn_sum - earnmain_max
        last_cost_difmax_sum = last_cost_sum - \
            lastdf[lastdf['earn_main'] == earnmain_max]['cost_main'].to_list()[
                0]
        last_dif_earnper = (
            last_earn_difmax_sum / last_cost_difmax_sum if last_cost_difmax_sum != 0 else -10
        )
        return (
            last_cost_sum,
            last_earn_sum,
            last_earnper,
            last_cost_difmax_sum,
            last_earn_difmax_sum,
            last_dif_earnper,
            last_cost_median,
            last_cost_mean,
            # last_earncount_per,
            last_trans_amount
        )

    def analysis_lastdays_noaddouttoken(self, df, now_unix_time, intervaldays=30):
        if len(df) == 0:
            return 0, 0, 0, 0, 0,  0, 0, 0, 0
        # need consider df may null if use iloc
        lastdf = df[df["TokenFirstTime"] >=
                    now_unix_time - 3600*24*intervaldays]
        # 去除那些earnper为-10的
        lastdf = lastdf[lastdf['cost_main'] != 0]
        lastdf = lastdf.reset_index(drop=True)
        if len(lastdf) == 0:
            return 0, 0, 0, 0, 0,  0, 0, 0, 0
        last_cost_sum = lastdf['cost_main'].sum()
        last_earn_sum = lastdf["earn_main_noaddouttoken"].sum()
        last_cost_median = lastdf['cost_main'].median()
        last_cost_mean = lastdf['cost_main'].mean()
        last_earnper = last_earn_sum / last_cost_sum if last_cost_sum != 0 else -10
        last_trans_amount = len(lastdf)
        lastdf['earn_percent'] = np.where(
            lastdf['cost_main'] != 0,
            lastdf["earn_main_noaddouttoken"] / lastdf['cost_main'],
            -10,
        )

        earnmain_max = lastdf["earn_main_noaddouttoken"].max()
        last_earn_difmax_sum = last_earn_sum - earnmain_max
        last_cost_difmax_sum = last_cost_sum - \
            lastdf[lastdf['earn_main_noaddouttoken'] == earnmain_max]['cost_main'].to_list()[
                0]
        last_dif_earnper = (
            last_earn_difmax_sum / last_cost_difmax_sum if last_cost_difmax_sum != 0 else -10
        )
        return (
            last_cost_sum,
            last_earn_sum,
            last_earnper,
            last_cost_difmax_sum,
            last_earn_difmax_sum,
            last_dif_earnper,
            last_cost_median,
            last_cost_mean,
            # last_earncount_per,
            last_trans_amount
        )
    def pick_random_user_agent(self):
        user_agents = [
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36",
            "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36",
            "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36",
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36",
            "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36",
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:97.0) Gecko/20100101 Firefox/97.0",
            "Mozilla/5.0 (X11; Linux i686; rv:97.0) Gecko/20100101 Firefox/97.0",
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 12.2; rv:97.0) Gecko/20100101 Firefox/97.0",
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15",
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36 OPR/83.0.4254.27",
            "Mozilla/5.0 (Windows NT 10.0; WOW64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36 OPR/83.0.4254.27",
            "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36 OPR/83.0.4254.27"
        ]
        header = {"user-agent": random.choice(user_agents)}
        return header
    def makescreenurl( self,urlname,urlparam):
        _url = urlname + urlparam
        return '=HYPERLINK("{}","{}")'.format(_url, "url_"+urlparam)
    def makeurl( self,url,url_show):
        return '=HYPERLINK("{}","{}")'.format(url,  url_show)