150 lines
4.6 KiB
Python
Executable File
150 lines
4.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Cleanup Public Nouns NFT Data
|
|
|
|
This script removes all Public Nouns NFT data from the database,
|
|
including NFT holdings, the data source entry, and contacts that
|
|
were created solely because of their Public Nouns NFT holdings.
|
|
|
|
Usage:
|
|
python cleanup_public_nouns.py
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import argparse
|
|
from dotenv import load_dotenv
|
|
|
|
# Add parent directory to path to import utils
|
|
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
from utils.db_connector import DatabaseConnector
|
|
from utils.logger import setup_logger
|
|
|
|
# Load environment variables
|
|
load_dotenv()
|
|
|
|
# Setup logging
|
|
logger = setup_logger("cleanup_public_nouns")
|
|
|
|
def cleanup_public_nouns_data(contract_address="0x93ecac71499147627DFEc6d0E494d50fCFFf10EE", collection_name="Public Nouns"):
|
|
"""
|
|
Remove all Public Nouns NFT data from the database.
|
|
|
|
Args:
|
|
contract_address: The contract address of the Public Nouns NFT
|
|
collection_name: The name of the collection
|
|
"""
|
|
logger.info(f"Cleaning up data for {collection_name} ({contract_address})")
|
|
|
|
db = DatabaseConnector()
|
|
|
|
# First, identify contacts that only have Public Nouns NFT holdings
|
|
query = """
|
|
WITH public_nouns_contacts AS (
|
|
SELECT DISTINCT "contactId"
|
|
FROM "NftHolding"
|
|
WHERE "contractAddress" = %(contract_address)s
|
|
),
|
|
contacts_with_other_data AS (
|
|
-- Contacts with other NFT holdings
|
|
SELECT DISTINCT "contactId"
|
|
FROM "NftHolding"
|
|
WHERE "contractAddress" != %(contract_address)s
|
|
|
|
UNION
|
|
|
|
-- Contacts with token holdings
|
|
SELECT DISTINCT "contactId"
|
|
FROM "TokenHolding"
|
|
|
|
UNION
|
|
|
|
-- Contacts with DAO memberships
|
|
SELECT DISTINCT "contactId"
|
|
FROM "DaoMembership"
|
|
|
|
UNION
|
|
|
|
-- Contacts with notes
|
|
SELECT DISTINCT "contactId"
|
|
FROM "Note"
|
|
|
|
UNION
|
|
|
|
-- Contacts with tags
|
|
SELECT DISTINCT "contactId"
|
|
FROM "TagsOnContacts"
|
|
),
|
|
contacts_to_delete AS (
|
|
SELECT "contactId"
|
|
FROM public_nouns_contacts
|
|
WHERE "contactId" NOT IN (SELECT "contactId" FROM contacts_with_other_data)
|
|
)
|
|
SELECT id FROM "Contact"
|
|
WHERE id IN (SELECT "contactId" FROM contacts_to_delete)
|
|
"""
|
|
|
|
contacts_to_delete = db.execute_query(query, {"contract_address": contract_address})
|
|
contact_ids_to_delete = [contact["id"] for contact in contacts_to_delete]
|
|
|
|
logger.info(f"Found {len(contact_ids_to_delete)} contacts to delete")
|
|
|
|
# Delete NFT holdings for this contract
|
|
query = """
|
|
DELETE FROM "NftHolding"
|
|
WHERE "contractAddress" = %(contract_address)s
|
|
RETURNING id
|
|
"""
|
|
result = db.execute_query(query, {"contract_address": contract_address})
|
|
deleted_holdings = len(result)
|
|
logger.info(f"Deleted {deleted_holdings} NFT holdings")
|
|
|
|
# Delete contacts that only had Public Nouns NFT holdings
|
|
if contact_ids_to_delete:
|
|
placeholders = ", ".join([f"%(id{i})s" for i in range(len(contact_ids_to_delete))])
|
|
params = {f"id{i}": contact_id for i, contact_id in enumerate(contact_ids_to_delete)}
|
|
|
|
query = f"""
|
|
DELETE FROM "Contact"
|
|
WHERE id IN ({placeholders})
|
|
RETURNING id
|
|
"""
|
|
result = db.execute_query(query, params)
|
|
deleted_contacts = len(result)
|
|
logger.info(f"Deleted {deleted_contacts} contacts")
|
|
|
|
# Delete scraping jobs for this collection
|
|
query = """
|
|
DELETE FROM "ScrapingJob"
|
|
WHERE "sourceName" = %(source_name)s
|
|
RETURNING id
|
|
"""
|
|
result = db.execute_query(query, {"source_name": f"NFT:{collection_name}"})
|
|
deleted_jobs = len(result)
|
|
logger.info(f"Deleted {deleted_jobs} scraping jobs")
|
|
|
|
# Delete data source
|
|
query = """
|
|
DELETE FROM "DataSource"
|
|
WHERE name = %(source_name)s
|
|
RETURNING id
|
|
"""
|
|
result = db.execute_query(query, {"source_name": f"NFT:{collection_name}"})
|
|
deleted_sources = len(result)
|
|
logger.info(f"Deleted {deleted_sources} data sources")
|
|
|
|
logger.info("Cleanup completed successfully")
|
|
|
|
def main():
|
|
"""Main entry point for the script."""
|
|
parser = argparse.ArgumentParser(description="Clean up Public Nouns NFT data")
|
|
parser.add_argument("--contract", default="0x93ecac71499147627DFEc6d0E494d50fCFFf10EE",
|
|
help="NFT contract address")
|
|
parser.add_argument("--name", default="Public Nouns", help="NFT collection name")
|
|
|
|
args = parser.parse_args()
|
|
|
|
cleanup_public_nouns_data(args.contract, args.name)
|
|
|
|
if __name__ == "__main__":
|
|
main() |