Spaces:
Sleeping
Sleeping
update
Browse files
app.js
CHANGED
|
@@ -2,61 +2,39 @@ 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; // Hugging Face will set this dynamically
|
| 9 |
-
|
| 10 |
-
if (!port) {
|
| 11 |
-
console.error("❌ PORT not defined");
|
| 12 |
-
process.exit(1);
|
| 13 |
-
}
|
| 14 |
-
|
| 15 |
-
app.listen(port, () => {
|
| 16 |
-
console.log(`✅ Server listening on port ${port}`);
|
| 17 |
-
});
|
| 18 |
|
|
|
|
|
|
|
| 19 |
|
|
|
|
|
|
|
| 20 |
|
| 21 |
app.use(bodyParser.urlencoded({ extended: true }));
|
| 22 |
app.use(express.static('public'));
|
|
|
|
| 23 |
|
| 24 |
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
|
| 25 |
|
| 26 |
app.get('/', (req, res) => {
|
| 27 |
-
res.sendFile(
|
| 28 |
});
|
| 29 |
|
| 30 |
app.post('/analyze', async (req, res) => {
|
| 31 |
-
const
|
| 32 |
const language = req.body.language;
|
| 33 |
|
| 34 |
-
const systemPrompt = `
|
| 35 |
-
You are an expert OSINT analyst with 20 years of experience in real-time analysis of
|
| 36 |
-
|
| 37 |
-
Always operate within the principles of journalistic ethics, digital safety, and compliance with legal standards (e.g., GDPR, UN Human Rights). Your outputs must be evidence-based, unbiased, and free from speculation.
|
| 38 |
-
|
| 39 |
-
Your responsibilities include:
|
| 40 |
-
|
| 41 |
-
1. Content summarization:
|
| 42 |
-
- Extract key facts, sentiments, and narrative threads.
|
| 43 |
-
- Identify recurring keywords, hashtags, or propaganda themes.
|
| 44 |
-
- Include timestamps for relevant developments.
|
| 45 |
-
|
| 46 |
-
2. Influence classification:
|
| 47 |
-
- Group actors by tone (e.g., hostile, neutral, supportive).
|
| 48 |
-
- Detect and categorize bots, influencers, journalists, and unknown accounts.
|
| 49 |
-
|
| 50 |
-
3. Contextualization:
|
| 51 |
-
- Provide geopolitical or situational framing when relevant (e.g., protests, conflicts).
|
| 52 |
-
- Identify hate speech, disinformation, or manipulated content.
|
| 53 |
-
|
| 54 |
-
4. Format your response as a valid JSON object, using the following schema:
|
| 55 |
-
|
| 56 |
-
\`\`\`json
|
| 57 |
{
|
| 58 |
"summary": "...",
|
| 59 |
-
"top_topics": ["..."
|
| 60 |
"notable_users": [
|
| 61 |
{
|
| 62 |
"username": "@example",
|
|
@@ -67,8 +45,8 @@ Your responsibilities include:
|
|
| 67 |
"network_analysis": {
|
| 68 |
"clusters": [
|
| 69 |
{
|
| 70 |
-
"label": "
|
| 71 |
-
"nodes": ["@a", "@b"
|
| 72 |
"summary": "..."
|
| 73 |
}
|
| 74 |
]
|
|
@@ -78,38 +56,42 @@ Your responsibilities include:
|
|
| 78 |
"neutral": 45,
|
| 79 |
"negative": 22
|
| 80 |
},
|
| 81 |
-
"risk_flags": ["
|
| 82 |
"timestamp_range": {
|
| 83 |
-
"from": "
|
| 84 |
-
"to": "
|
| 85 |
}
|
| 86 |
}
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
Now analyze the following content in the \${language} language:
|
| 90 |
`;
|
| 91 |
|
| 92 |
-
|
| 93 |
try {
|
| 94 |
-
|
| 95 |
-
model
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
const
|
| 103 |
-
const
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
|
|
|
|
|
|
| 114 |
}
|
| 115 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
import dotenv from 'dotenv';
|
| 3 |
import bodyParser from 'body-parser';
|
| 4 |
import { GoogleGenerativeAI } from '@google/generative-ai';
|
| 5 |
+
import fs from 'fs';
|
| 6 |
+
import path from 'path';
|
| 7 |
+
import { fileURLToPath } from 'url';
|
| 8 |
+
import { exec } from 'child_process';
|
| 9 |
|
| 10 |
dotenv.config();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
|
| 12 |
+
const app = express();
|
| 13 |
+
const port = process.env.PORT || 7860;
|
| 14 |
|
| 15 |
+
const __filename = fileURLToPath(import.meta.url);
|
| 16 |
+
const __dirname = path.dirname(__filename);
|
| 17 |
|
| 18 |
app.use(bodyParser.urlencoded({ extended: true }));
|
| 19 |
app.use(express.static('public'));
|
| 20 |
+
app.use('/mnt', express.static('/mnt'));
|
| 21 |
|
| 22 |
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
|
| 23 |
|
| 24 |
app.get('/', (req, res) => {
|
| 25 |
+
res.sendFile(path.join(__dirname, 'index.html'));
|
| 26 |
});
|
| 27 |
|
| 28 |
app.post('/analyze', async (req, res) => {
|
| 29 |
+
const inputText = req.body.input_text;
|
| 30 |
const language = req.body.language;
|
| 31 |
|
| 32 |
+
const systemPrompt = `
|
| 33 |
+
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. Your outputs are structured, neutral, evidence-based, and free from speculation or bias.
|
| 34 |
+
Always format your output using the following JSON structure:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
{
|
| 36 |
"summary": "...",
|
| 37 |
+
"top_topics": ["..."],
|
| 38 |
"notable_users": [
|
| 39 |
{
|
| 40 |
"username": "@example",
|
|
|
|
| 45 |
"network_analysis": {
|
| 46 |
"clusters": [
|
| 47 |
{
|
| 48 |
+
"label": "Cluster A",
|
| 49 |
+
"nodes": ["@a", "@b"],
|
| 50 |
"summary": "..."
|
| 51 |
}
|
| 52 |
]
|
|
|
|
| 56 |
"neutral": 45,
|
| 57 |
"negative": 22
|
| 58 |
},
|
| 59 |
+
"risk_flags": ["..."],
|
| 60 |
"timestamp_range": {
|
| 61 |
+
"from": "YYYY-MM-DDTHH:mmZ",
|
| 62 |
+
"to": "YYYY-MM-DDTHH:mmZ"
|
| 63 |
}
|
| 64 |
}
|
| 65 |
+
Analyze the following content in ${language}:
|
|
|
|
|
|
|
| 66 |
`;
|
| 67 |
|
|
|
|
| 68 |
try {
|
| 69 |
+
const model = genAI.getGenerativeModel({ model: 'models/gemini-1.5-flash' });
|
| 70 |
+
const result = await model.generateContent({
|
| 71 |
+
contents: [
|
| 72 |
+
{ role: 'user', parts: [{ text: systemPrompt }] },
|
| 73 |
+
{ role: 'user', parts: [{ text: inputText }] }
|
| 74 |
+
]
|
| 75 |
+
});
|
| 76 |
+
|
| 77 |
+
const raw = result.response.text();
|
| 78 |
+
const jsonStart = raw.indexOf('{');
|
| 79 |
+
const jsonEnd = raw.lastIndexOf('}');
|
| 80 |
+
const jsonString = raw.slice(jsonStart, jsonEnd + 1);
|
| 81 |
+
const osintData = JSON.parse(jsonString);
|
| 82 |
+
|
| 83 |
+
fs.writeFileSync('data.json', JSON.stringify(osintData));
|
| 84 |
+
exec('python3 render_report.py', () => {
|
| 85 |
+
res.sendFile(path.join(__dirname, '/mnt/data/OSINT_Report.html'));
|
| 86 |
+
});
|
| 87 |
+
|
| 88 |
+
} catch (error) {
|
| 89 |
+
console.error(error);
|
| 90 |
+
res.status(500).send('Error processing OSINT report.');
|
| 91 |
}
|
| 92 |
});
|
| 93 |
+
|
| 94 |
+
app.listen(port, () => {
|
| 95 |
+
console.log(`✅ Server running on http://localhost:${port}`);
|
| 96 |
+
});
|
| 97 |
+
|