pull down to refresh

Thank you Qwen QwQ for being actually pretty good at writing python code so I don't have to.
Sharing so y'all can have your own sovereign shitlist.

code

# Copyright (C) 2025 opti <optimism@stacker.news>
# This work is free. You can redistribute it and/or modify it under the
# terms of the Do What The Fuck You Want To Public License, Version 2,
# as published by Sam Hocevar. See http://www.wtfpl.net/ for more details.
import sqlite3
import sys
import re
import argparse
from datetime import datetime

DB_FILE = 'publications.db'

def sanitize_input(s):
    """Sanitize input"""
    return re.sub(r'[^0-9A-Za-z:./ ]', '', s.strip())

def create_table(conn):
    with conn:
        conn.execute('''
            CREATE TABLE IF NOT EXISTS publications (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                name TEXT NOT NULL UNIQUE,
                url TEXT NOT NULL UNIQUE,
                reason TEXT NOT NULL,
                timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
            )
        ''')

def insert_publication(conn, name, url, reason):
    with conn:
        conn.execute('''
            INSERT INTO publications (name, url, reason)
            VALUES (?, ?, ?)
        ''', (name, url, reason))

def get_all_publications(conn):
    with conn:
        return conn.execute('SELECT * FROM publications').fetchall()

def main():
    parser = argparse.ArgumentParser(description='Track unreliable news publications')
    subparsers = parser.add_subparsers(dest='command')

    # Add command
    add_parser = subparsers.add_parser('add', help='Add a publication')
    add_parser.add_argument('name', help='Publication name')
    add_parser.add_argument('url', help='Publication URL')
    add_parser.add_argument('reason', help='Reason for listing')

    # List command
    subparsers.add_parser('list', help='List all publications')

    args = parser.parse_args()
    conn = sqlite3.connect(DB_FILE)
    create_table(conn)

    if args.command == 'add':
        # Sanitize inputs
        name = sanitize_input(args.name)
        url = sanitize_input(args.url)
        reason = sanitize_input(args.reason)

        # Validate sanitized inputs
        if not name or not url or not reason:
            print("Error: All fields must contain valid characters after sanitization")
            sys.exit(1)

        try:
            insert_publication(conn, name, url, reason)
            print(f"Added: {name}, {url}, {reason}")
        except sqlite3.IntegrityError:
            print("Error: Publication name or URL already exists")

    elif args.command == 'list':
        publications = get_all_publications(conn)
        if not publications:
            print("No publications recorded")
        else:
            for pub in publications:
                print(f"Name: {pub[1]}, URL: {pub[2]}, Reason: {pub[3]}, Timestamp: {pub[4]}")
    
    else:
        parser.print_help()

if __name__ == '__main__':
    main()

proof-of-it-works:

(env) opti@box shitlist % python3 publication_shitlist.py add benzinga benzinga.com "shitcoiners"
Added: benzinga, benzinga.com, shitcoiners
(env) opti@box shitlist % python3 publication_shitlist.py list
Name: benzinga, URL: benzinga.com, Reason: shitcoiners, Timestamp: 2025-04-16 15:27:23