from flask import Flask, request, jsonify, render_template_string, session, redirect import urllib.request import re import sqlite3 import datetime app = Flask(__name__) app.secret_key = 'ctteen-admin-secret-2024' ADMIN_PASSWORD = "Okan4715!" DB_PATH = "analyses.db" ANTISEMITIC_PATTERNS = [ { "keyword": "jewish conspiracy", "explanation": "This phrase promotes the false and dangerous conspiracy theory that Jewish people secretly control world events.", "trending": True, "trending_note": "This trope has surged on social media following recent global events.", "counter": "Jewish people do not operate secret conspiracies. This is a centuries-old antisemitic myth used to scapegoat Jewish communities and has been debunked repeatedly by historians and scholars." }, { "keyword": "jews control", "explanation": "This phrase falsely claims Jewish people have secret control over institutions like banks, media, or governments.", "trending": True, "trending_note": "Variants of this conspiracy theory are among the most widely spread antisemitic tropes online.", "counter": "The claim that Jewish people control major institutions is a harmful stereotype with no basis in fact. It echoes propaganda historically used to justify persecution and genocide." }, { "keyword": "jewish agenda", "explanation": "This implies Jewish people have a secret plan to manipulate society, a classic antisemitic conspiracy theory.", "trending": False, "trending_note": "", "counter": "There is no Jewish agenda. This phrase falsely portrays Jewish people as a unified scheming group rather than a diverse community of individuals with varied beliefs and values." }, { "keyword": "holocaust never happened", "explanation": "Holocaust denial rejects the historical fact that six million Jewish people were systematically murdered by Nazi Germany.", "trending": True, "trending_note": "Holocaust denial content has increased significantly on unmoderated platforms.", "counter": "The Holocaust is one of the most thoroughly documented events in human history, confirmed by thousands of survivors, military records, and physical evidence. Denying it is both factually wrong and deeply harmful." }, { "keyword": "holocaust denial", "explanation": "Denying the Holocaust erases the genocide of six million Jewish people and causes immense harm to survivors and their families.", "trending": True, "trending_note": "Holocaust denial content has increased significantly on unmoderated platforms.", "counter": "The Holocaust is one of the most thoroughly documented events in human history. Denying it has been criminalized in many countries and causes immense pain to survivors and their descendants." }, { "keyword": "zionist conspiracy", "explanation": "Using Zionist as a substitute for Jewish people to push conspiracy theories is a recognizable form of antisemitism.", "trending": True, "trending_note": "This framing has become increasingly common as a way to disguise antisemitism as political commentary.", "counter": "Zionism is the belief in Jewish self-determination. Using it as a stand-in for antisemitic conspiracy theories conflates political criticism with ethnic hatred and targets Jewish identity." }, { "keyword": "jewish bankers", "explanation": "This phrase invokes the antisemitic stereotype that Jewish people manipulate global finances for personal gain.", "trending": False, "trending_note": "", "counter": "The greedy Jewish banker trope is a centuries-old antisemitic stereotype with no factual basis. It was used extensively in Nazi propaganda to justify persecution and remains deeply harmful today." }, { "keyword": "jewish media control", "explanation": "This phrase falsely claims Jewish people secretly control media to manipulate public opinion.", "trending": True, "trending_note": "Claims about Jewish media control have spiked across multiple social platforms recently.", "counter": "Jewish people do not control the media. This conspiracy theory has been used for over a century to justify discrimination and violence against Jewish communities worldwide." }, { "keyword": "kill jews", "explanation": "This is a direct and explicit call for violence against Jewish people.", "trending": False, "trending_note": "", "counter": "This is an explicit incitement to violence against Jewish people and should be reported to law enforcement and the platform immediately. This is not protected speech." }, { "keyword": "death to jews", "explanation": "This is an explicit call for violence and genocide against Jewish people.", "trending": False, "trending_note": "", "counter": "This is an explicit threat of violence against Jewish people. Report this to law enforcement and the platform hosting it immediately. This content may be illegal in your jurisdiction." }, { "keyword": "dirty jew", "explanation": "This is a racial slur that dehumanizes Jewish people using degrading language.", "trending": False, "trending_note": "", "counter": "This is a dehumanizing slur targeting Jewish people. Language like this has historically preceded acts of violence and discrimination against Jewish communities." }, { "keyword": "filthy jew", "explanation": "This is a dehumanizing slur that uses degrading language to attack Jewish identity.", "trending": False, "trending_note": "", "counter": "Dehumanizing slurs targeting Jewish people have historically been used to justify violence and discrimination. This language should be reported and challenged wherever it appears." }, { "keyword": "stupid jew", "explanation": "This is a slur combining ethnic hatred with degrading language targeting Jewish people.", "trending": False, "trending_note": "", "counter": "Ethnic slurs targeting Jewish people are a form of hate speech regardless of intent. This language contributes to a culture of discrimination and should be reported." }, { "keyword": "jews are evil", "explanation": "Attributing evil as an inherent trait of all Jewish people is classic antisemitic dehumanization.", "trending": False, "trending_note": "", "counter": "Attributing negative moral traits to an entire ethnic or religious group is prejudice. Jewish people are a diverse community and cannot be characterized as a monolith." }, { "keyword": "jews are greedy", "explanation": "This perpetuates the antisemitic stereotype that Jewish people are inherently dishonest or obsessed with money.", "trending": False, "trending_note": "", "counter": "Attributing greed to an entire ethnic or religious group is prejudice. This stereotype has been used to justify discrimination against Jewish people for centuries." }, { "keyword": "jews are subhuman", "explanation": "This is explicit dehumanization of Jewish people, the kind of language that directly precedes genocide.", "trending": False, "trending_note": "", "counter": "Describing any group of people as subhuman is among the most dangerous forms of hate speech. This language was central to Nazi propaganda and must be reported to law enforcement immediately." }, { "keyword": "all jews are", "explanation": "Attributing any negative characteristic to all Jewish people as a monolithic group is antisemitic stereotyping.", "trending": False, "trending_note": "", "counter": "Jewish people are an incredibly diverse community spanning many nationalities, backgrounds, and beliefs. Negative generalizations about the entire group are prejudice, plain and simple." }, { "keyword": "jewish manipulation", "explanation": "This accuses Jewish people as a group of deceptively controlling others, a classic antisemitic trope.", "trending": False, "trending_note": "", "counter": "Accusing Jewish people of collective manipulation is a harmful stereotype rooted in antisemitic conspiracy theories. It falsely portrays an entire community as inherently deceptive." }, { "keyword": "jewish problem", "explanation": "This phrase mirrors Nazi rhetoric about Jewish people being a problem to be solved, language that preceded genocide.", "trending": False, "trending_note": "", "counter": "The framing of Jewish people as a problem is language directly drawn from Nazi ideology that led to the Holocaust. This rhetoric is extremely dangerous and should be reported immediately." }, { "keyword": "hate jews", "explanation": "An explicit expression of hatred toward Jewish people as a group.", "trending": False, "trending_note": "", "counter": "Expressions of hatred toward any ethnic or religious group contribute to discrimination and violence. This content should be reported to the platform immediately." }, { "keyword": "jew is a", "explanation": "Using Jew as a pejorative descriptor is a form of antisemitic slur usage.", "trending": False, "trending_note": "", "counter": "Using Jewish identity as a negative descriptor is a form of antisemitism. This language should be challenged and reported." }, { "keyword": "jew is evil", "explanation": "Attributing evil to Jewish identity is explicit antisemitic dehumanization.", "trending": False, "trending_note": "", "counter": "Attributing negative moral traits to Jewish identity is antisemitism. This language has historically been used to justify persecution of Jewish communities." } ] ANTISEMITIC_KEYWORDS = [p["keyword"] for p in ANTISEMITIC_PATTERNS] JEWISH_CONTEXT_WORDS = [ "jew ", " jew", "jewish", "zionist", "synagogue", "rabbi", "kosher", "torah", "talmud", "holocaust", "antisemit", "semit", "yarmulke", "menorah", "passover", "hanukkah", "bar mitzvah", "bat mitzvah" ] def init_db(): conn = sqlite3.connect(DB_PATH) c = conn.cursor() c.execute('''CREATE TABLE IF NOT EXISTS analyses ( id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp TEXT, input_type TEXT, input_preview TEXT, result_type TEXT, confidence REAL, flags TEXT )''') conn.commit() conn.close() def save_analysis(input_type, input_preview, result_type, confidence, flags): conn = sqlite3.connect(DB_PATH) c = conn.cursor() c.execute('INSERT INTO analyses (timestamp, input_type, input_preview, result_type, confidence, flags) VALUES (?,?,?,?,?,?)', (datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), input_type, input_preview[:300], result_type, confidence, ', '.join(flags))) conn.commit() conn.close() def get_stats(): conn = sqlite3.connect(DB_PATH) c = conn.cursor() c.execute('SELECT COUNT(*) FROM analyses') total = c.fetchone()[0] c.execute("SELECT COUNT(*) FROM analyses WHERE result_type='antisemitic'") antisemitic = c.fetchone()[0] c.execute("SELECT COUNT(*) FROM analyses WHERE result_type='hate'") hate = c.fetchone()[0] c.execute("SELECT COUNT(*) FROM analyses WHERE result_type='clean'") clean = c.fetchone()[0] conn.close() return {'total': total, 'antisemitic': antisemitic, 'hate': hate, 'clean': clean} def get_all_analyses(): conn = sqlite3.connect(DB_PATH) c = conn.cursor() c.execute('SELECT * FROM analyses ORDER BY id DESC LIMIT 500') rows = c.fetchall() conn.close() return rows from transformers import pipeline classifier = pipeline("text-classification", model="facebook/roberta-hate-speech-dynabench-r4-target") def classify_text(text): result = classifier(text[:512])[0] label = result['label'] score = round(result['score'] * 100, 2) text_lower = text.lower() matched_patterns = [p for p in ANTISEMITIC_PATTERNS if p["keyword"] in text_lower] triggered_keywords = [p["keyword"] for p in matched_patterns] has_jewish_context = any(word in text_lower for word in JEWISH_CONTEXT_WORDS) is_antisemitic = len(matched_patterns) > 0 or (label == "hate" and has_jewish_context) is_general_hate = label == "hate" and not is_antisemitic if is_antisemitic: explanations = [] counters = [] trending_notes = [] is_trending = False for p in matched_patterns: explanations.append({"phrase": p["keyword"], "explanation": p["explanation"]}) counters.append(p["counter"]) if p["trending"]: is_trending = True trending_notes.append(p["trending_note"]) if not matched_patterns: explanations.append({"phrase": "context detected", "explanation": "The AI model detected antisemitic language based on context and tone."}) counters.append("Antisemitic language causes real harm to Jewish communities. If you encounter this content online, report it to the platform and the ADL.") return { 'type': 'antisemitic', 'icon': '⚠', 'title': 'Antisemitic Content Detected', 'confidence': score, 'flags': triggered_keywords, 'explanations': explanations, 'counter': counters[0] if counters else "", 'is_trending': is_trending, 'trending_note': trending_notes[0] if trending_notes else "", 'message': 'This text contains antisemitic language specifically targeting Jewish people.' } elif is_general_hate: return { 'type': 'hate', 'icon': '!', 'title': 'General Hate Speech Detected', 'confidence': score, 'flags': [], 'explanations': [], 'counter': '', 'is_trending': False, 'trending_note': '', 'message': 'This text contains hateful language targeting a group of people, but does not appear to be specifically antisemitic. All forms of hate speech are harmful and should be reported.' } else: return { 'type': 'clean', 'icon': '✓', 'title': 'No Hate Content Detected', 'confidence': score, 'flags': [], 'explanations': [], 'counter': '', 'is_trending': False, 'trending_note': '', 'message': 'This text appears to be free of antisemitic or hateful language.' } MAIN_HTML = """ Shield — Free AI Antisemitism Detector
Built for Jewish Communities

Detect Hate.
Protect Communities.

Paste any text or scan any URL to instantly identify antisemitic content using advanced artificial intelligence.

0
Analyzed This Session
0
Antisemitic Found
0
General Hate Found
0
Clean

The tool will fetch and analyze the text content from the URL you provide.

Analyzing with AI...
Confidence
No analyses yet this session. Start by analyzing some text above.

Why We Built This

Antisemitic incidents have risen sharply in recent years. Jewish students, communities, and organizations need tools to identify and document hate before it spreads and causes real harm.

View ADL Incident Report →

What To Do Next

If you find antisemitic content, screenshot it immediately — platforms often remove content quickly. Then report it to the platform directly and to the ADL using the link below.

Report to ADL →

Two-Layer Detection

Combines a RoBERTa AI model trained on thousands of examples with a specialized antisemitism pattern database for maximum accuracy.

Antisemitism vs. General Hate

Specifically distinguishes between content targeting Jewish people and general hate speech so you always know exactly what you are dealing with.

URL Scanning

Paste any public URL and the tool will fetch and analyze the text content automatically — articles, forums, social posts, and more.

Private Session History

Your analysis history is private to your current session only and never shared with other users. Refresh the page to start a clean session.

Link copied to clipboard!
""" ADMIN_LOGIN_HTML = """ Admin — Shield

Admin Panel

Shield — Antisemitism Detector

Incorrect password. Try again.
""" ADMIN_DASHBOARD_HTML = """ Admin Dashboard — Shield

Dashboard

Complete history of all analyses ever performed on Shield.

{{ stats.total }}
Total Analyzed
{{ stats.antisemitic }}
Antisemitic
{{ stats.hate }}
General Hate
{{ stats.clean }}
Clean

Full Analysis History

{{ stats.total }} total records
{% if analyses %} {% for row in analyses %} {% endfor %}
#TimestampTypeResultConfidenceInput PreviewFlagged Phrases
{{ row[0] }} {{ row[1] }} {{ row[2] }} {{ row[4] }} {{ row[5] }}%
{{ row[3] }}
{{ row[6] if row[6] else '—' }}
{% else %}
No analyses yet.
{% endif %}
""" @app.route('/') def home(): return render_template_string(MAIN_HTML) @app.route('/analyze', methods=['POST']) def analyze(): data = request.get_json() text = data.get('text', '').strip() if not text: return jsonify({'error': 'No text provided'}) result = classify_text(text) save_analysis('text', text, result['type'], result['confidence'], result['flags']) return jsonify(result) @app.route('/analyze-url', methods=['POST']) def analyze_url(): data = request.get_json() url = data.get('url', '').strip() if not url: return jsonify({'error': 'No URL provided'}) try: req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'}) with urllib.request.urlopen(req, timeout=10) as response: html = response.read().decode('utf-8', errors='ignore') clean = re.sub(r'<[^>]+>', ' ', html) clean = re.sub(r'\s+', ' ', clean).strip() clean = clean[:2000] result = classify_text(clean) result['scraped_text'] = clean[:200] + '...' save_analysis('url', url, result['type'], result['confidence'], result['flags']) return jsonify(result) except Exception as e: return jsonify({'error': f'Could not scan URL: {str(e)}'}) @app.route('/admin') def admin(): return render_template_string(ADMIN_LOGIN_HTML) @app.route('/admin/login', methods=['POST']) def admin_login(): data = request.get_json() if data.get('password') == ADMIN_PASSWORD: session['admin'] = True return jsonify({'success': True}) return jsonify({'success': False}) @app.route('/admin/dashboard') def admin_dashboard(): if not session.get('admin'): return redirect('/admin') stats = get_stats() analyses = get_all_analyses() return render_template_string(ADMIN_DASHBOARD_HTML, stats=stats, analyses=analyses) @app.route('/admin/logout') def admin_logout(): session.pop('admin', None) return redirect('/admin') if __name__ == '__main__': init_db() app.run(host='0.0.0.0', port=7860)