|
import requests |
|
import typing |
|
from typing import Optional |
|
from datetime import datetime, timezone, timedelta |
|
import discord |
|
from discord.ext import commands |
|
from discord import app_commands |
|
from PIL import Image, ImageDraw, ImageFont, ImageColor, ImageFilter, ImageSequence |
|
import json |
|
from web3 import Web3 |
|
from eth_utils import to_checksum_address |
|
import threading |
|
|
|
|
|
api_key = "4H655NPT5229MKFE2NNHIS2GNZ3U4UTGT2" |
|
|
|
|
|
with open("token.txt", "r", encoding='utf-8') as f: |
|
token = f.read() |
|
|
|
|
|
|
|
def first_time(timestamp): |
|
timestamp = int(timestamp) |
|
dt_object = datetime.fromtimestamp(timestamp, timezone.utc) |
|
|
|
|
|
kst = timezone(timedelta(hours=9)) |
|
dt_kst = dt_object.astimezone(kst) |
|
|
|
t = dt_kst.strftime('%Y-%m-%d') |
|
return str(t) |
|
|
|
|
|
def web3_find(token_id): |
|
|
|
INFURA_URL = "https://polygon-mainnet.infura.io/v3/16185d569adf4d00a04f2d2a200cf231" |
|
web3 = Web3(Web3.HTTPProvider(INFURA_URL)) |
|
|
|
|
|
token_contract_address = "0xA4B37bE40F7b231Ee9574c4b16b7DDb7EAcDC99B" |
|
token_id |
|
|
|
|
|
contract_abi = [ |
|
{ |
|
"constant": True, |
|
"inputs": [{"name": "_tokenId", "type": "uint256"}], |
|
"name": "tokenURI", |
|
"outputs": [{"name": "", "type": "string"}], |
|
"payable": False, |
|
"stateMutability": "view", |
|
"type": "function" |
|
}, |
|
] |
|
|
|
|
|
contract = web3.eth.contract(address=token_contract_address, abi=contract_abi) |
|
|
|
|
|
token_uri = contract.functions.tokenURI(token_id).call() |
|
|
|
|
|
metadata_response = requests.get(token_uri) |
|
metadata = metadata_response.json() |
|
|
|
|
|
nft_name = metadata.get("name", "Name not found") |
|
|
|
print(f"NFT Name: {nft_name}") |
|
return nft_name |
|
|
|
|
|
|
|
def obj_srch(account_address): |
|
|
|
contract_address = "0xA4B37bE40F7b231Ee9574c4b16b7DDb7EAcDC99B" |
|
url = f"https://api.polygonscan.com/api?module=account&action=tokenbalance&contractaddress={contract_address}&address={account_address}&tag=latest&apikey={api_key}" |
|
|
|
|
|
response = requests.get(url) |
|
|
|
|
|
if response.status_code == 200: |
|
data = response.json() |
|
balance = data.get('result') |
|
if balance is not None: |
|
|
|
real_balance = int(balance) |
|
print(f"๊ณ์ ์ฃผ์ {account_address}๋(์) ํ ํฐ ์ปจํธ๋ํธ {contract_address}์ NFT๋ฅผ {real_balance}๊ฐ ๊ฐ์ง๊ณ ์์ต๋๋ค.") |
|
return real_balance |
|
else: |
|
print("NFT ์์ก ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.") |
|
else: |
|
print("API ์์ฒญ์ ์คํจํ์ต๋๋ค.") |
|
|
|
|
|
|
|
def como_srch(account_address): |
|
tok = "0x58AeABfE2D9780c1bFcB713Bf5598261b15dB6e5" |
|
url = f"https://api.polygonscan.com/api?module=account&action=tokenbalance&contractaddress={tok}&address={account_address}&tag=latest&apikey={api_key}" |
|
response = requests.get(url) |
|
|
|
|
|
if response.status_code == 200: |
|
data = response.json() |
|
|
|
balance = data.get('result') |
|
if balance is not None: |
|
real_balance = int(balance) / 10 ** 18 |
|
print(f"๊ณ์ ์ฃผ์ {account_address}๋(์) ํ ํฐ ์ฃผ์ {tok}์ ํ ํฐ์ {int(real_balance)}๊ฐ ๊ฐ์ง๊ณ ์์ต๋๋ค.") |
|
return int(real_balance) |
|
else: |
|
print("ํ ํฐ ์๋ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.") |
|
else: |
|
print("API ์์ฒญ์ ์คํจํ์ต๋๋ค.") |
|
|
|
|
|
def ad2id(input_str): |
|
|
|
input_str = str(input_str) |
|
input_str = to_checksum_address(input_str) |
|
print(input_str) |
|
|
|
base_url = "https://cache.nova.gd/user/v1" |
|
users = [] |
|
error_message = None |
|
|
|
try: |
|
if input_str.startswith("0x"): |
|
url = f"{base_url}/by-address/{input_str}" |
|
response = requests.get(url) |
|
if response.status_code == 200: |
|
users = response.json() |
|
else: |
|
error_message = f"Request failed with status code {response.status_code}" |
|
except Exception as e: |
|
error_message = str(e) |
|
|
|
if error_message: |
|
return "Error" |
|
|
|
if not users: |
|
return "Mint" |
|
|
|
formatted_result = "".join(f"{user['nickname']}" for i, user in enumerate(users)) |
|
return formatted_result |
|
|
|
|
|
def ad_srch(input_str): |
|
if len(input_str) < 4: |
|
return "4๊ธ์ ์ด์์ผ๋ก ์์ฑํด์ฃผ์ธ์." |
|
|
|
base_url = "https://cache.nova.gd/user/v1" |
|
|
|
url = f"{base_url}/search?query={input_str}" |
|
response = requests.get(url) |
|
data = response.json() |
|
|
|
|
|
address = data['results'][0]['address'] |
|
|
|
print(address) |
|
return address |
|
|
|
|
|
def como_txt(text): |
|
image_size = (180, 50) |
|
image = Image.new('RGBA', image_size, (255, 255, 255, 0)) |
|
draw = ImageDraw.Draw(image) |
|
font = ImageFont.truetype("Helvetica_Neue_LT_Std_75_Bold.otf", 50) |
|
text_color = (200, 200, 200) |
|
|
|
|
|
text_bbox = draw.textbbox((0, 0), text, font=font) |
|
text_width = text_bbox[2] - text_bbox[0] |
|
text_height = text_bbox[3] - text_bbox[1] |
|
|
|
|
|
text_x = (image_size[0] - text_width) / 2 |
|
text_y = (image_size[1] - text_height) / 2 |
|
draw.text((text_x, text_y), text, fill=text_color, font=font) |
|
|
|
return image |
|
|
|
|
|
def acom(input_str): |
|
if len(input_str) < 4: |
|
return ["4๊ธ์ ์ด์์ผ๋ก ์์ฑํด์ฃผ์ธ์."] |
|
|
|
base_url = "https://cache.nova.gd/user/v1" |
|
|
|
url = f"{base_url}/search?query={input_str}" |
|
response = requests.get(url) |
|
data = response.json() |
|
users = data.get("results", []) |
|
|
|
if response.status_code != 200: |
|
raise Exception(f"Request failed with status code {response.status_code}") |
|
|
|
if not users: |
|
return ["๊ฒ์ ๊ฒฐ๊ณผ ์์"] |
|
|
|
|
|
result_list = [user['nickname'] for user in users[:25]] |
|
return result_list |
|
|
|
|
|
|
|
|
|
def names(text, img, x = 124, y = 26): |
|
text = str(text) |
|
image = img |
|
draw = ImageDraw.Draw(image) |
|
font = ImageFont.truetype("Helvetica_Neue_LT_Std_75_Bold.otf", 42) |
|
text_color = (208, 211, 214) |
|
draw.text((x, y), text, fill=text_color, font=font) |
|
return image |
|
|
|
|
|
|
|
async def name_auto(interaction: discord.Interaction, current: str) -> typing.List[app_commands.Choice[str]]: |
|
acs = acom(current) |
|
matching_files = acs |
|
return [app_commands.Choice(name=num, value=num) for num in matching_files] |
|
|
|
def find_trans(account_address, number): |
|
API_ENDPOINT = "https://api.polygonscan.com/api" |
|
API_KEY = "4H655NPT5229MKFE2NNHIS2GNZ3U4UTGT2" |
|
|
|
|
|
token_contract_address = "0xa4b37be40f7b231ee9574c4b16b7ddb7eacdc99b" |
|
|
|
|
|
params = { |
|
"module": "account", |
|
"action": "tokennfttx", |
|
"contractaddress": token_contract_address, |
|
"address": account_address, |
|
"page": 1, |
|
"offset": number, |
|
"sort": "desc", |
|
"apikey": API_KEY |
|
} |
|
|
|
response = requests.get(API_ENDPOINT, params=params) |
|
data = response.json() |
|
print(data) |
|
|
|
if data["status"] == "1" and data["result"]: |
|
nft_list = data["result"][:number] |
|
token_ids = [nft["tokenID"] for nft in nft_list] |
|
token_from = [nft["from"] for nft in nft_list] |
|
token_to = [nft["to"] for nft in nft_list] |
|
|
|
return token_ids, token_from, token_to |
|
else: |
|
print("No recent NFT transfers found.") |
|
return [], [], [] |
|
|
|
|
|
def find_first(account_address, number = 1): |
|
API_ENDPOINT = "https://api.polygonscan.com/api" |
|
API_KEY = "4H655NPT5229MKFE2NNHIS2GNZ3U4UTGT2" |
|
|
|
|
|
token_contract_address = "0xa4b37be40f7b231ee9574c4b16b7ddb7eacdc99b" |
|
|
|
|
|
params = { |
|
"module": "account", |
|
"action": "tokennfttx", |
|
"contractaddress": token_contract_address, |
|
"address": account_address, |
|
"page": 1, |
|
"offset": number, |
|
"sort": "asc", |
|
"apikey": API_KEY |
|
} |
|
|
|
response = requests.get(API_ENDPOINT, params=params) |
|
data = response.json() |
|
print(data) |
|
|
|
if data["status"] == "1" and data["result"]: |
|
nft_list = data["result"][:number] |
|
timeStamp = [nft["timeStamp"] for nft in nft_list] |
|
return timeStamp |
|
else: |
|
print("No recent NFT transfers found.") |
|
return [] |
|
|
|
|
|
|
|
def center_txt(base_img, text, x,y, x1, y1, fs): |
|
image_size = (x1, y1) |
|
image = Image.new('RGBA', image_size, (255, 255, 255, 0)) |
|
draw = ImageDraw.Draw(image) |
|
font = ImageFont.truetype("Helvetica_Neue_LT_Std_75_Bold.otf", fs) |
|
text_color = (200, 200, 200) |
|
|
|
|
|
text_bbox = draw.textbbox((0, 0), text, font=font) |
|
text_width = text_bbox[2] - text_bbox[0] |
|
text_height = text_bbox[3] - text_bbox[1] |
|
|
|
|
|
text_x = (image_size[0] - text_width) / 2 |
|
text_y = (image_size[1] - text_height) / 2 |
|
draw.text((text_x, text_y), text, fill=text_color, font=font) |
|
base_img.paste(image, (x,y), image) |
|
return base_img |
|
|
|
|
|
red_arr = Image.open("red_arr.png") |
|
blue_arr = Image.open("blue_arr.png") |
|
|
|
def run(): |
|
intents = discord.Intents.all() |
|
bot = commands.Bot(command_prefix="!", intents=intents) |
|
|
|
@bot.event |
|
async def on_ready(): |
|
bot.tree.copy_global_to(guild=discord.Object(id=1207625911709597737)) |
|
await bot.tree.sync(guild=discord.Object(id=1192532796967751790)) |
|
await bot.tree.sync(guild=discord.Object(id=1207625911709597737)) |
|
print("ready") |
|
|
|
@app_commands.autocomplete(name=name_auto) |
|
@bot.tree.command() |
|
async def me(interaction: discord.Interaction, name: str): |
|
await interaction.response.defer() |
|
did = interaction.user.id |
|
nid = ad_srch(name) |
|
nid = str(nid) |
|
print(nid) |
|
|
|
como = como_srch(nid) |
|
como_img = como_txt(str(como)) |
|
base_img = Image.open("base_img2.png") |
|
name_paste_position = (219, 295) |
|
base_img.paste(como_img, name_paste_position, como_img) |
|
|
|
obj = obj_srch(nid) |
|
como_img = como_txt(str(obj)) |
|
name_paste_position = (219, 205) |
|
base_img.paste(como_img, name_paste_position, como_img) |
|
|
|
base_img = names(name, base_img) |
|
token_ids, token_from, token_to = find_trans(nid, 4) |
|
token_name = [None] * len(token_ids) |
|
for i in range(len(token_ids)): |
|
token_name[i] = web3_find(int(token_ids[i])) |
|
|
|
|
|
token_from_name = [0,0,0,0] |
|
token_from_name[0] = ad2id(token_from[0]) |
|
token_from_name[1] = ad2id(token_from[1]) |
|
token_from_name[2] = ad2id(token_from[2]) |
|
token_from_name[3] = ad2id(token_from[3]) |
|
|
|
token_to_name = [0, 0, 0, 0] |
|
token_to_name[0] = ad2id(token_to[0]) |
|
token_to_name[1] = ad2id(token_to[1]) |
|
token_to_name[2] = ad2id(token_to[2]) |
|
token_to_name[3] = ad2id(token_to[3]) |
|
|
|
print(token_from_name[0]) |
|
print(token_from_name[1]) |
|
print(token_from_name[2]) |
|
base_img = center_txt(base_img, token_from_name[0], 463, 143, 327, 50, 42) |
|
base_img = center_txt(base_img, token_from_name[1], 463, 288, 327, 50, 42) |
|
base_img = center_txt(base_img, token_from_name[2], 463, 436, 327, 50, 42) |
|
base_img = center_txt(base_img, token_from_name[3], 463, 583, 327, 50, 42) |
|
|
|
base_img = center_txt(base_img, token_to_name[0], 909, 143, 327, 50, 42) |
|
base_img = center_txt(base_img, token_to_name[1], 909, 288, 327, 50, 42) |
|
base_img = center_txt(base_img, token_to_name[2], 909, 436, 327, 50, 42) |
|
base_img = center_txt(base_img, token_to_name[3], 909, 583, 327, 50, 42) |
|
|
|
base_img = center_txt(base_img, token_name[0], 457, 207, 785, 50, 44) |
|
base_img = center_txt(base_img, token_name[1], 457, 346, 785, 50, 44) |
|
base_img = center_txt(base_img, token_name[2], 457, 494, 785, 50, 44) |
|
base_img = center_txt(base_img, token_name[3], 457, 642, 785, 50, 44) |
|
|
|
timeStamp = find_first(nid) |
|
timeStamp = first_time(timeStamp[0]) |
|
print(timeStamp) |
|
base_img = names(timeStamp, base_img, 640, 66) |
|
|
|
|
|
print(str(token_from[0])) |
|
print(str(nid)) |
|
if str(token_from[0]) == str(nid).lower(): |
|
base_img.paste(blue_arr, (823, 152), blue_arr) |
|
else: |
|
base_img.paste(red_arr, (823, 152), red_arr) |
|
|
|
if str(token_from[1]) == str(nid).lower(): |
|
base_img.paste(blue_arr, (823, 297), blue_arr) |
|
else: |
|
base_img.paste(red_arr, (823, 297), red_arr) |
|
|
|
if str(token_from[2]) == str(nid).lower(): |
|
base_img.paste(blue_arr, (823, 444), blue_arr) |
|
else: |
|
base_img.paste(red_arr, (823, 444), red_arr) |
|
|
|
if str(token_from[3]) == str(nid).lower(): |
|
base_img.paste(blue_arr, (823, 592), blue_arr) |
|
else: |
|
base_img.paste(red_arr, (823, 592), red_arr) |
|
|
|
base_img.save("img.png") |
|
|
|
|
|
|
|
await interaction.followup.send(f"", ephemeral=False, file=discord.File("img.png")) |
|
bot.run(token) |
|
import gradio as gr |
|
|
|
def greet(name): |
|
return "Hello " + name + "!" |
|
|
|
demo = gr.Interface(fn=greet, inputs="textbox", outputs="textbox") |
|
if __name__ == "__main__": |
|
t1 = threading.Thread(target=demo.launch) |
|
t2 = threading.Thread(target=run) |
|
|
|
t1.start() |
|
t2.start() |
|
|
|
t1.join() |
|
t2.join() |