Basti1110 commited on
Commit
6f9ff59
·
verified ·
1 Parent(s): f013ed8

Upload 6 files

Browse files
Files changed (6) hide show
  1. Dockerfile +11 -0
  2. app.js +99 -0
  3. index.html +25 -0
  4. json_viewer.js +15 -0
  5. package.json +14 -0
  6. space.yaml +1 -0
Dockerfile ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM node:18
2
+
3
+ WORKDIR /app
4
+
5
+ COPY . .
6
+
7
+ RUN npm install
8
+
9
+ EXPOSE 7860
10
+
11
+ CMD ["npm", "start"]
app.js ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import express from 'express';
2
+ import dotenv from 'dotenv';
3
+ import bodyParser from 'body-parser';
4
+ import { GoogleGenerativeAI } from '@google/generative-ai';
5
+
6
+ dotenv.config();
7
+ const app = express();
8
+ const port = process.env.PORT || 7860;
9
+
10
+ app.use(bodyParser.urlencoded({ extended: true }));
11
+ app.use(express.static('public'));
12
+
13
+ const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
14
+
15
+ app.get('/', (req, res) => {
16
+ res.sendFile(process.cwd() + '/index.html');
17
+ });
18
+
19
+ app.post('/analyze', async (req, res) => {
20
+ const userContent = req.body.input_text;
21
+ const language = req.body.language;
22
+
23
+ const systemPrompt = `
24
+ You are an expert OSINT intelligence analyst with 20 years of experience in real-time analysis of social media platforms such as Twitter/X, Telegram, and Reddit. Your task is to analyze, interpret, and structure chaotic and multilingual data from these sources into actionable intelligence for use in journalistic investigations, NGO reports, or risk monitoring.
25
+
26
+ You always operate within the framework of journalistic ethics, digital safety, and compliance with privacy and legal norms (e.g., GDPR, UN Human Rights).
27
+
28
+ Your outputs are structured, neutral, evidence-based, and free from speculation or bias.
29
+
30
+ Summarize content:
31
+ - Extract key points, sentiments, and narratives from noisy data.
32
+ - Detect recurring keywords, hashtags, topics, or propaganda themes.
33
+ - Identify emerging or trending developments with timestamps.
34
+
35
+ Classify influence:
36
+ - Group sources by tone (e.g., neutral, hostile, supportive).
37
+ - Identify influential users, bots, or actors based on repetition, reach, and tone.
38
+
39
+ Geo-political & ethical context:
40
+ - Provide geopolitical framing if needed (e.g., warzones, protests).
41
+ - Detect hate speech, misinformation, or manipulated media.
42
+
43
+ Structure the report:
44
+ - Always return JSON objects in the following format:
45
+
46
+ {
47
+ "summary": "...",
48
+ "top_topics": ["...", "..."],
49
+ "notable_users": [
50
+ {
51
+ "username": "@example",
52
+ "type": "influencer | bot | journalist | unknown",
53
+ "activity_summary": "..."
54
+ }
55
+ ],
56
+ "network_analysis": {
57
+ "clusters": [
58
+ {
59
+ "label": "Pro-X Sentiment",
60
+ "nodes": ["@a", "@b", "@c"],
61
+ "summary": "..."
62
+ }
63
+ ]
64
+ },
65
+ "sentiment_overview": {
66
+ "positive": 33,
67
+ "neutral": 45,
68
+ "negative": 22
69
+ },
70
+ "risk_flags": ["misinformation", "calls for violence", "bot amplification"],
71
+ "timestamp_range": {
72
+ "from": "2025-05-19T10:00Z",
73
+ "to": "2025-05-19T14:00Z"
74
+ }
75
+ }
76
+
77
+ Analyze the following content in ${language} language:
78
+ `;
79
+
80
+ try {
81
+ const model = genAI.getGenerativeModel({ model: 'gemini-pro' });
82
+ const contents = [
83
+ { role: 'user', parts: [{ text: systemPrompt }] },
84
+ { role: 'user', parts: [{ text: userContent }] },
85
+ ];
86
+ const result = await model.generateContent({ contents });
87
+ const output = result.response.text();
88
+ res.send(`<pre style="white-space: pre-wrap; font-family: monospace;">${output}</pre><a href="/">← Back</a>
89
+ <form method="POST" action="/download-pdf">
90
+ <input type="hidden" name="json_output" id="json_output">
91
+ <button onclick="document.getElementById('json_output').value=document.querySelector('pre').innerText"
92
+ class="mt-4 bg-green-600 text-white py-2 px-4 rounded hover:bg-green-700 transition">Download PDF</button>
93
+ </form>
94
+ <script src="json_viewer.js"></script>`);
95
+ } catch (err) {
96
+ console.error(err);
97
+ res.status(500).send('❌ Error: ' + err.message);
98
+ }
99
+ });
index.html ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
6
+ <title>OSINT Analyzer</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ </head>
9
+ <body class="bg-gray-100 font-sans">
10
+ <div class="max-w-3xl mx-auto mt-10 p-6 bg-white shadow-xl rounded-xl">
11
+ <h1 class="text-2xl font-bold mb-4 text-center">🔍 OSINT Analyzer</h1>
12
+ <form action="/analyze" method="POST">
13
+ <textarea name="input_text" rows="12" required class="w-full p-3 border rounded focus:outline-none focus:ring" placeholder="Paste tweets, Telegram messages, Reddit threads, or news articles..."></textarea>
14
+ <select name="language" class="mt-4 w-full p-2 border rounded focus:outline-none focus:ring">
15
+ <option value="en">English</option>
16
+ <option value="de">German</option>
17
+ <option value="es">Spanish</option>
18
+ <option value="fr">French</option>
19
+ <option value="ru">Russian</option>
20
+ </select>
21
+ <button type="submit" class="mt-4 w-full bg-blue-600 text-white py-2 rounded hover:bg-blue-700 transition">Analyze</button>
22
+ </form>
23
+ </div>
24
+ </body>
25
+ </html>
json_viewer.js ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ function formatJSON() {
3
+ const pre = document.querySelector('pre');
4
+ try {
5
+ const rawText = pre.textContent;
6
+ const jsonStart = rawText.indexOf('{');
7
+ const jsonEnd = rawText.lastIndexOf('}');
8
+ const jsonText = rawText.slice(jsonStart, jsonEnd + 1);
9
+ const obj = JSON.parse(jsonText);
10
+ pre.innerHTML = '<code>' + JSON.stringify(obj, null, 2) + '</code>';
11
+ } catch (e) {
12
+ console.error("Invalid JSON output");
13
+ }
14
+ }
15
+ window.onload = formatJSON;
package.json ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "type": "module",
3
+ "name": "osint-analyzer",
4
+ "version": "1.0.0",
5
+ "scripts": {
6
+ "start": "node app.js"
7
+ },
8
+ "dependencies": {
9
+ "express": "^4.18.2",
10
+ "dotenv": "^16.3.1",
11
+ "@google/generative-ai": "^0.4.0",
12
+ "body-parser": "^1.20.2"
13
+ }
14
+ }
space.yaml ADDED
@@ -0,0 +1 @@
 
 
1
+ sdk: docker