From 8bb4c6f7275ff6fb833b73b31b8f921ef9210cb0 Mon Sep 17 00:00:00 2001 From: jae Date: Wed, 15 Apr 2026 18:50:19 +0000 Subject: [PATCH] feat: rename PROPAGANDA to UNREDACTED, add nav block-reveal animation and global search --- api/app.py | 62 +++--- api/data/navigation.json | 4 +- api/data/{propaganda.json => unredacted.json} | 0 css/awesomelist.css | 2 +- css/{propaganda.css => unredacted.css} | 206 +++++++++++++++++- depot/index.html | 4 +- depot/{propaganda.html => unredacted.html} | 14 +- js/nav.js | 93 ++++++++ js/{propaganda.js => unredacted.js} | 190 +++++++++++++++- redownload_missing.sh | 37 ++++ 10 files changed, 562 insertions(+), 50 deletions(-) rename api/data/{propaganda.json => unredacted.json} (100%) rename css/{propaganda.css => unredacted.css} (81%) rename depot/{propaganda.html => unredacted.html} (87%) rename js/{propaganda.js => unredacted.js} (81%) create mode 100644 redownload_missing.sh diff --git a/api/app.py b/api/app.py index 5c90db5..a5f3b30 100644 --- a/api/app.py +++ b/api/app.py @@ -7,7 +7,7 @@ from pathlib import Path from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart -from flask import Flask, request, jsonify, abort, send_file +from flask import Flask, request, jsonify, abort, send_file, redirect from flask_cors import CORS import jwt import requests as req @@ -1526,29 +1526,29 @@ def api_govdomains_stats(): }) -# ─── Propaganda: Declassified Document Archive ──────── -_propaganda_cache = None -_propaganda_mtime = 0 +# ─── Unredacted: Declassified Document Archive ──────── +_unredacted_cache = None +_unredacted_mtime = 0 -def _load_propaganda(): - global _propaganda_cache, _propaganda_mtime - p = DATA_DIR / 'propaganda.json' +def _load_unredacted(): + global _unredacted_cache, _unredacted_mtime + p = DATA_DIR / 'unredacted.json' if not p.exists(): return {'categories': []} mt = p.stat().st_mtime - if _propaganda_cache is None or mt != _propaganda_mtime: + if _unredacted_cache is None or mt != _unredacted_mtime: with open(p, encoding='utf-8') as f: - _propaganda_cache = json.load(f) - _propaganda_mtime = mt - return _propaganda_cache + _unredacted_cache = json.load(f) + _unredacted_mtime = mt + return _unredacted_cache -@app.route('/api/propaganda') -def get_propaganda(): - return jsonify(_load_propaganda()) +@app.route('/api/unredacted') +def get_unredacted(): + return jsonify(_load_unredacted()) -@app.route('/api/propaganda/categories') -def get_propaganda_categories(): - db = _load_propaganda() +@app.route('/api/unredacted/categories') +def get_unredacted_categories(): + db = _load_unredacted() cats = [] for c in db.get('categories', []): n_countries = len(c.get('countries', [])) @@ -1565,18 +1565,18 @@ def get_propaganda_categories(): }) return jsonify({'categories': cats}) -@app.route('/api/propaganda/category/') -def get_propaganda_category(cat_id): - db = _load_propaganda() +@app.route('/api/unredacted/category/') +def get_unredacted_category(cat_id): + db = _load_unredacted() for c in db.get('categories', []): if c['id'] == cat_id: return jsonify(c) abort(404, f'Category {cat_id} not found') -@app.route('/api/propaganda/upload', methods=['POST']) +@app.route('/api/unredacted/upload', methods=['POST']) @require_auth -def upload_propaganda_doc(): - """Upload a PDF to the propaganda archive. Future admin use.""" +def upload_unredacted_doc(): + """Upload a PDF to the unredacted archive. Future admin use.""" try: if 'file' not in request.files: return jsonify({'error': 'No file uploaded'}), 400 @@ -1587,8 +1587,7 @@ def upload_propaganda_doc(): return jsonify({'error': 'category and collection required'}), 400 if not f.filename.lower().endswith('.pdf'): return jsonify({'error': 'Only PDF files accepted'}), 400 - # Save file — this saves locally; on VPS would save to /propaganda/docs/ - save_dir = Path('/var/www/jaeswift-homepage/propaganda/docs') / cat_id / col_id + save_dir = Path('/var/www/jaeswift-homepage/unredacted/docs') / cat_id / col_id save_dir.mkdir(parents=True, exist_ok=True) dest = save_dir / f.filename f.save(str(dest)) @@ -1596,5 +1595,18 @@ def upload_propaganda_doc(): except Exception as e: return jsonify({'error': str(e)}), 500 +# ─── Legacy redirects: /api/propaganda → /api/unredacted ──────── +@app.route('/api/propaganda') +def redirect_propaganda(): + return redirect('/api/unredacted', code=301) + +@app.route('/api/propaganda/categories') +def redirect_propaganda_categories(): + return redirect('/api/unredacted/categories', code=301) + +@app.route('/api/propaganda/category/') +def redirect_propaganda_category(cat_id): + return redirect(f'/api/unredacted/category/{cat_id}', code=301) + if __name__ == '__main__': app.run(host='0.0.0.0', port=5000, debug=False) diff --git a/api/data/navigation.json b/api/data/navigation.json index 4210f33..ca30168 100644 --- a/api/data/navigation.json +++ b/api/data/navigation.json @@ -86,8 +86,8 @@ "description": "16,000+ free resources catalogued" }, { - "label": "PROPAGANDA", - "url": "/depot/propaganda", + "label": "UNREDACTED", + "url": "/depot/unredacted", "description": "Classified documents & briefings" }, { diff --git a/api/data/propaganda.json b/api/data/unredacted.json similarity index 100% rename from api/data/propaganda.json rename to api/data/unredacted.json diff --git a/css/awesomelist.css b/css/awesomelist.css index a5d71b5..5dd4ad2 100644 --- a/css/awesomelist.css +++ b/css/awesomelist.css @@ -1,5 +1,5 @@ /* ═══════════════════════════════════════════════════════ - AWESOME LISTS // Propaganda Resource Database + AWESOME LISTS // Unredacted Resource Database ═══════════════════════════════════════════════════════ */ .al-container { diff --git a/css/propaganda.css b/css/unredacted.css similarity index 81% rename from css/propaganda.css rename to css/unredacted.css index c57fe3b..f7f6950 100644 --- a/css/propaganda.css +++ b/css/unredacted.css @@ -1,5 +1,5 @@ /* ═══════════════════════════════════════════════════════ - PROPAGANDA — Declassified Document Archive + UNREDACTED — Declassified Document Archive ═══════════════════════════════════════════════════════ */ /* ─── Stats Bar ──────────────────────────────────────── */ @@ -879,4 +879,208 @@ .prop-grid { grid-template-columns: repeat(3, 1fr); } + grid-template-columns: repeat(3, 1fr); + } +} + +/* ═══════════════════════════════════════════════════════ + GLOBAL ARCHIVE SEARCH + ═══════════════════════════════════════════════════════ */ + +.ur-search-container { + margin: 1.5rem 0 2rem; +} + +.ur-search-bar { + display: flex; + align-items: center; + background: #0a0a0a; + border: 1px solid #00cc33; + border-radius: 2px; + padding: 0; + position: relative; + box-shadow: 0 0 8px rgba(0, 204, 51, 0.15), inset 0 0 20px rgba(0, 0, 0, 0.5); + transition: border-color 0.2s, box-shadow 0.2s; +} + +.ur-search-bar:focus-within { + border-color: #00ff41; + box-shadow: 0 0 15px rgba(0, 204, 51, 0.3), inset 0 0 20px rgba(0, 0, 0, 0.5); +} + +.ur-search-icon { + color: #00cc33; + font-size: 1.2rem; + padding: 0.75rem 0 0.75rem 1rem; + opacity: 0.7; + pointer-events: none; +} + +.ur-search-input { + flex: 1; + background: transparent; + border: none; + color: #e0e0e0; + font-family: 'JetBrains Mono', monospace; + font-size: 0.85rem; + letter-spacing: 0.08em; + padding: 0.75rem 0.75rem; + outline: none; + text-transform: uppercase; +} + +.ur-search-input::placeholder { + color: #555; + letter-spacing: 0.1em; +} + +.ur-search-clear { + color: #888; + font-size: 1rem; + padding: 0.75rem 1rem; + cursor: pointer; + transition: color 0.2s; +} + +.ur-search-clear:hover { + color: #ff4444; +} + +.ur-search-status { + margin-top: 0.75rem; + min-height: 1.2rem; +} + +.ur-search-count { + font-family: 'JetBrains Mono', monospace; + font-size: 0.75rem; + letter-spacing: 0.12em; + color: #00cc33; + text-transform: uppercase; +} + +.ur-search-none { + font-family: 'JetBrains Mono', monospace; + font-size: 0.75rem; + letter-spacing: 0.1em; + color: #ff6b35; + text-transform: uppercase; +} + +.ur-search-results { + margin-top: 0.5rem; +} + +.ur-results-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); + gap: 1rem; +} + +.ur-result-card { + background: linear-gradient(135deg, rgba(0, 204, 51, 0.04), rgba(0, 0, 0, 0.4)); + border: 1px solid rgba(0, 204, 51, 0.15); + border-radius: 2px; + padding: 1rem 1.2rem; + cursor: pointer; + transition: border-color 0.2s, background 0.2s, transform 0.15s; + position: relative; +} + +.ur-result-card::before { + content: ''; + position: absolute; + top: 0; left: 0; + width: 3px; + height: 100%; + background: #00cc33; + opacity: 0; + transition: opacity 0.2s; +} + +.ur-result-card:hover { + border-color: rgba(0, 204, 51, 0.4); + background: linear-gradient(135deg, rgba(0, 204, 51, 0.08), rgba(0, 0, 0, 0.5)); + transform: translateY(-1px); +} + +.ur-result-card:hover::before { + opacity: 1; +} + +.ur-result-header { + display: flex; + align-items: flex-start; + gap: 0.6rem; + margin-bottom: 0.6rem; +} + +.ur-result-icon { + font-size: 1.1rem; + flex-shrink: 0; + margin-top: 0.1rem; +} + +.ur-result-title { + font-family: 'JetBrains Mono', monospace; + font-size: 0.82rem; + font-weight: 600; + color: #e0e0e0; + letter-spacing: 0.04em; + line-height: 1.3; +} + +.ur-result-meta { + display: flex; + flex-wrap: wrap; + gap: 0.4rem; + margin-bottom: 0.6rem; +} + +.ur-result-badge { + font-family: 'JetBrains Mono', monospace; + font-size: 0.6rem; + letter-spacing: 0.08em; + padding: 0.2rem 0.5rem; + border-radius: 1px; + text-transform: uppercase; + background: rgba(0, 204, 51, 0.1); + color: #00cc33; + border: 1px solid rgba(0, 204, 51, 0.2); +} + +.ur-result-badge-country { + background: rgba(255, 193, 7, 0.08); + color: #ffc107; + border-color: rgba(255, 193, 7, 0.2); +} + +.ur-result-badge-col { + background: rgba(100, 149, 237, 0.08); + color: #6495ed; + border-color: rgba(100, 149, 237, 0.2); +} + +.ur-result-desc { + font-family: 'JetBrains Mono', monospace; + font-size: 0.72rem; + color: #888; + line-height: 1.5; + letter-spacing: 0.02em; +} + +mark.ur-highlight { + background: rgba(0, 204, 51, 0.25); + color: #00ff41; + padding: 0 2px; + border-radius: 1px; +} + +@media (max-width: 768px) { + .ur-results-grid { + grid-template-columns: 1fr; + } + .ur-search-input { + font-size: 0.78rem; + } } diff --git a/depot/index.html b/depot/index.html index 2d059e0..ac30ac4 100644 --- a/depot/index.html +++ b/depot/index.html @@ -42,9 +42,9 @@
The largest classified index of free resources on the internet — catalogued by type.
ENTER →
- +
-
PROPAGANDA
+
UNREDACTED
Recovered publications and documents preserved in digital format. Browse on-site.
ENTER →
diff --git a/depot/propaganda.html b/depot/unredacted.html similarity index 87% rename from depot/propaganda.html rename to depot/unredacted.html index 4217638..51f48ee 100644 --- a/depot/propaganda.html +++ b/depot/unredacted.html @@ -3,13 +3,13 @@ - JAESWIFT // PROPAGANDA — Declassified Document Archive + JAESWIFT // UNREDACTED — Declassified Document Archive - + @@ -36,18 +36,18 @@ / DEPOT / - PROPAGANDA + UNREDACTED
DEPOT // DECLASSIFIED ARCHIVE
-

PROPAGANDA

+

UNREDACTED

> Declassified documents, intelligence briefings, and government files. Browse the archive.

-
-
INITIALISING PROPAGANDA ARCHIVE...
+
+
INITIALISING UNREDACTED ARCHIVE...
@@ -66,6 +66,6 @@ - + diff --git a/js/nav.js b/js/nav.js index 520cb52..171a701 100644 --- a/js/nav.js +++ b/js/nav.js @@ -87,6 +87,8 @@ initMobileDropdowns(); // Inject shared wrapper for SOL price + wallet, then inject both + // Start UNREDACTED block-reveal animation + initUnredactedAnimation(); injectSolWalletGroup(); } catch (err) { console.warn('Nav load failed, keeping existing:', err); @@ -449,6 +451,97 @@ if (dd) dd.classList.add('hidden'); } + // ─── UNREDACTED Block-Reveal Animation ────────────────────── + function initUnredactedAnimation() { + // Find the UNREDACTED dropdown link + const allLinks = document.querySelectorAll('.dropdown-link'); + let targetLink = null; + for (const link of allLinks) { + // Check the first text node or childNode text for UNREDACTED + const txt = link.childNodes[0]; + if (txt && txt.nodeType === 3 && txt.textContent.trim() === 'UNREDACTED') { + targetLink = link; + break; + } + } + if (!targetLink) return; + + const WORD = 'UNREDACTED'; + const LEN = WORD.length; + const FRAME_MS = 90; + const HOLD_REVEALED = 2000; + const HOLD_REDACTED = 1000; + const BLOCK = '\u2588'; // █ + + // Wrap the text node in a span so we can animate just the label text + const originalText = targetLink.childNodes[0]; + const animSpan = document.createElement('span'); + animSpan.className = 'unredacted-anim'; + animSpan.textContent = WORD; + targetLink.replaceChild(animSpan, originalText); + + // Add minimal CSS for the animation + const style = document.createElement('style'); + style.textContent = ` + .unredacted-anim { font-family: inherit; } + .unredacted-anim .ur-block { color: #00cc33; opacity: 0.35; } + `; + document.head.appendChild(style); + + function renderFrame(revealCount) { + // revealCount = number of letters revealed from the left + let html = ''; + for (let i = 0; i < LEN; i++) { + if (i < revealCount) { + html += WORD[i]; + } else { + html += '' + BLOCK + ''; + } + } + animSpan.innerHTML = html; + } + + let frame = 0; + let direction = 1; // 1 = revealing, -1 = redacting + let holdTimer = null; + + function tick() { + if (direction === 1) { + // Forward reveal + renderFrame(frame); + frame++; + if (frame > LEN) { + // Fully revealed — hold + animSpan.textContent = WORD; + direction = 0; + holdTimer = setTimeout(() => { + direction = -1; + frame = LEN; + holdTimer = null; + }, HOLD_REVEALED); + } + } else if (direction === -1) { + // Reverse redact + frame--; + renderFrame(frame); + if (frame <= 0) { + // Fully redacted — hold + direction = 0; + holdTimer = setTimeout(() => { + direction = 1; + frame = 0; + holdTimer = null; + }, HOLD_REDACTED); + } + } + // direction === 0 means we're holding, do nothing + } + + // Start fully redacted + renderFrame(0); + setInterval(tick, FRAME_MS); + } + // Run on DOM ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => { diff --git a/js/propaganda.js b/js/unredacted.js similarity index 81% rename from js/propaganda.js rename to js/unredacted.js index 7b312ec..6c4fe2c 100644 --- a/js/propaganda.js +++ b/js/unredacted.js @@ -1,23 +1,23 @@ /* ═══════════════════════════════════════════════════════ - PROPAGANDA — Declassified Document Archive + UNREDACTED — Declassified Document Archive SPA Engine with hash routing & PDF.js viewer ═══════════════════════════════════════════════════════ */ (function () { 'use strict'; - const ROOT = document.getElementById('propagandaRoot'); - const PDF_BASE = '/propaganda/docs'; + const ROOT = document.getElementById('unredactedRoot'); + const PDF_BASE = '/unredacted/docs'; let DATA = null; // ─── Data Loading ──────────────────────────────────── async function loadData() { try { - const r = await fetch('/api/propaganda'); + const r = await fetch('/api/unredacted'); if (!r.ok) throw new Error(`HTTP ${r.status}`); DATA = await r.json(); } catch (e) { - console.error('PROPAGANDA: data load failed', e); + console.error('UNREDACTED: data load failed', e); ROOT.innerHTML = `
⚠️
DATA FEED OFFLINE
@@ -121,10 +121,21 @@
DOCUMENTS${stats.docs}
`; - html += breadcrumb([{ label: 'PROPAGANDA' }]); + html += breadcrumb([{ label: 'UNREDACTED' }]); + // ─── Global Search Bar ──────────────────────────────── + html += `
+ +
+
+
`; + + html += '
'; html += ''; - html += '
'; DATA.categories.forEach(cat => { const nCountries = countCountries(cat); @@ -144,7 +155,11 @@ }); html += '
'; + html += '
'; // close #urCategorySection ROOT.innerHTML = html; + + // ─── Bind search events ──────────────────────────────── + initSearchListeners(); } // ─── View: Category (Country Selector + Collections) ── @@ -156,7 +171,7 @@ html += `
DECLASSIFIED // ${esc(cat.name)} // ACCESS GRANTED
`; html += breadcrumb([ - { label: 'PROPAGANDA', hash: '' }, + { label: 'UNREDACTED', hash: '' }, { label: cat.name } ]); @@ -251,7 +266,7 @@ html += `
DECLASSIFIED // ${esc(col.name).toUpperCase()} // ACCESS GRANTED
`; html += breadcrumb([ - { label: 'PROPAGANDA', hash: '' }, + { label: 'UNREDACTED', hash: '' }, { label: cat.name, hash: `category/${catId}` }, { label: `${country.flag || ''} ${country.name}`, hash: `country/${catId}/${countryCode}` }, { label: col.name } @@ -309,7 +324,7 @@ html += `
DECLASSIFIED // ${esc(doc.title).toUpperCase()}
`; html += breadcrumb([ - { label: 'PROPAGANDA', hash: '' }, + { label: 'UNREDACTED', hash: '' }, { label: cat.name, hash: `category/${catId}` }, { label: `${country.flag || ''} ${country.name}`, hash: `country/${catId}/${countryCode}` }, { label: col.name, hash: `collection/${catId}/${countryCode}/${colId}` }, @@ -582,7 +597,7 @@ }); pdfAllText.push({ pageNum: i, text: fullText, items: tc.items, itemOffsets: itemOffsets }); } - console.log('PROPAGANDA: Extracted text from ' + pdfAllText.length + ' pages'); + console.log('UNREDACTED: Extracted text from ' + pdfAllText.length + ' pages'); } // ─── Search Controls Init ──────────────────────────── @@ -781,6 +796,157 @@ } + // ─── Global Archive Search ───────────────────────────── + let searchDebounceTimer = null; + + function initSearchListeners() { + const input = document.getElementById('urSearchInput'); + const clearBtn = document.getElementById('urSearchClear'); + if (!input) return; + + input.addEventListener('input', () => { + clearTimeout(searchDebounceTimer); + const val = input.value.trim(); + clearBtn.style.display = val.length > 0 ? 'inline-block' : 'none'; + searchDebounceTimer = setTimeout(() => { + globalArchiveSearch(val); + }, 300); + }); + + clearBtn.addEventListener('click', () => { + input.value = ''; + clearBtn.style.display = 'none'; + globalArchiveSearch(''); + input.focus(); + }); + + input.addEventListener('keydown', (e) => { + if (e.key === 'Escape') { + input.value = ''; + clearBtn.style.display = 'none'; + globalArchiveSearch(''); + } + }); + } + + function globalArchiveSearch(query) { + const resultsEl = document.getElementById('urSearchResults'); + const statusEl = document.getElementById('urSearchStatus'); + const catSection = document.getElementById('urCategorySection'); + if (!resultsEl || !statusEl) return; + + if (!query || query.length === 0) { + resultsEl.innerHTML = ''; + statusEl.innerHTML = ''; + if (catSection) catSection.style.display = ''; + return; + } + + const q = query.toLowerCase(); + const results = []; + + if (!DATA || !DATA.categories) return; + + DATA.categories.forEach(cat => { + (cat.countries || []).forEach(cn => { + (cn.collections || []).forEach(col => { + (col.documents || []).forEach(doc => { + const fields = [ + doc.title || '', + doc.description || '', + col.name || '', + cat.name || '', + cn.name || '', + doc.year ? String(doc.year) : '', + doc.classification || '' + ]; + const combined = fields.join(' ').toLowerCase(); + if (combined.includes(q)) { + results.push({ + doc, + catName: cat.name, + catId: cat.id, + catIcon: cat.icon || '📁', + countryName: cn.name, + countryCode: cn.code, + countryFlag: cn.flag || '', + colName: col.name, + colId: col.id + }); + } + }); + + // Also match collection-level (even if no docs match) + const colFields = [col.name || '', col.description || '', cat.name || '', cn.name || ''].join(' ').toLowerCase(); + if (colFields.includes(q) && !results.find(r => r.colId === col.id && r.catId === cat.id && r.countryCode === cn.code && !r.doc.id)) { + // Check if we already added docs from this collection + const hasDocResults = results.some(r => r.colId === col.id && r.catId === cat.id && r.countryCode === cn.code); + if (!hasDocResults) { + results.push({ + doc: { title: col.name, description: col.description || 'Collection in ' + cat.name, id: '__col__' }, + catName: cat.name, + catId: cat.id, + catIcon: cat.icon || '📁', + countryName: cn.name, + countryCode: cn.code, + countryFlag: cn.flag || '', + colName: col.name, + colId: col.id, + isCollection: true + }); + } + } + }); + }); + }); + + // Hide categories when searching + if (catSection) catSection.style.display = 'none'; + + if (results.length === 0) { + statusEl.innerHTML = 'NO MATCHING DOCUMENTS // REFINE SEARCH PARAMETERS'; + resultsEl.innerHTML = ''; + return; + } + + statusEl.innerHTML = `FOUND ${results.length} MATCHING DOCUMENT${results.length === 1 ? '' : 'S'}`; + + let html = '
'; + results.forEach(r => { + const title = highlightMatch(esc(r.doc.title || 'Untitled'), q); + const desc = r.doc.description ? highlightMatch(esc(truncateText(r.doc.description, 160)), q) : ''; + const hash = r.isCollection + ? `country/${r.catId}/${r.countryCode}` + : `doc/${r.catId}/${r.countryCode}/${r.colId}/${r.doc.id}`; + + html += `
+
+ ${r.catIcon} + ${title} +
+
+ ${esc(r.catName)} + ${r.countryFlag} ${esc(r.countryName)} + ${esc(r.colName)} +
+ ${desc ? `
${desc}
` : ''} +
`; + }); + html += '
'; + resultsEl.innerHTML = html; + } + + function highlightMatch(text, query) { + if (!query) return text; + const regex = new RegExp('(' + query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + ')', 'gi'); + return text.replace(regex, '$1'); + } + + function truncateText(text, maxLen) { + if (text.length <= maxLen) return text; + return text.substring(0, maxLen).replace(/\s+\S*$/, '') + '...'; + } + // ─── Not Found / Empty ──────────────────────────────── function renderNotFound(msg) { ROOT.innerHTML = `
@@ -840,7 +1006,7 @@ // ─── Init ───────────────────────────────────────────── async function init() { - ROOT.innerHTML = '
INITIALISING PROPAGANDA ARCHIVE...
'; + ROOT.innerHTML = '
INITIALISING UNREDACTED ARCHIVE...
'; await loadData(); if (DATA) { window.addEventListener('hashchange', route); diff --git a/redownload_missing.sh b/redownload_missing.sh new file mode 100644 index 0000000..a49537b --- /dev/null +++ b/redownload_missing.sh @@ -0,0 +1,37 @@ +#!/bin/bash +# Re-download missing UK MOD UFO PDFs +MASTER_DIR="/var/www/jaeswift-homepage/propaganda/docs/ufo-uap/uk-mod-complete" +BASE_DIR="/var/www/jaeswift-homepage/propaganda/docs/ufo-uap" + +echo "[$(date)] Re-downloading 53 missing files" + +wget --tries=5 \ + --wait=1 \ + --random-wait \ + --timeout=60 \ + --directory-prefix="$MASTER_DIR" \ + --no-check-certificate \ + --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \ + "https://documents.theblackvault.com/documents/ufos/UK/aug-2009-highlights-guide.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-1948.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-1958-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-1959.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-1960.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-1961.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-1962.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-1963.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-1964.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-1965.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-1970.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-1972.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-1974.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-1975.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-1976.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-1984-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-1985-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-1986-1-2.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-1987-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-1997-1-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-1999-1-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2005-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2006-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2018-1-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2019-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2020-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2021-1-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2022-1-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2023-1-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2024-1-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2025-1-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2026-1-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2027-1-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2028-1-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2030-1-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2031-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2032-1-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2033-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2034-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2035-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2036-1-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2037-1-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2038-1-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2039-1-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2040-1-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2041-1-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2043-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2044-1-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2046-1-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2047-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2048-1-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2049-1-1.pdf" "https://documents.theblackvault.com/documents/ufos/UK/defe-24-2050-1-1.pdf" + +echo "[$(date)] Re-download complete" + +# Recreate ALL symlinks +for f in "$MASTER_DIR"/defe-24-*.pdf; do + [ -f "$f" ] && ln -sf "$f" "$BASE_DIR/uk-mod-ufo-desk/$(basename $f)" +done + +for f in "$MASTER_DIR"/defe-31-*.pdf; do + [ -f "$f" ] && ln -sf "$f" "$BASE_DIR/di55-ufo-archive/$(basename $f)" +done + +[ -f "$MASTER_DIR/defe-24-1948.pdf" ] && ln -sf "$MASTER_DIR/defe-24-1948.pdf" "$BASE_DIR/rendlesham-forest/defe-24-1948.pdf" + +for f in aug-2009-highlights-guide.pdf highlights-guide-09-08-11.pdf mar-2011-highlights-guide.pdf uk2009.pdf; do + [ -f "$MASTER_DIR/$f" ] && ln -sf "$MASTER_DIR/$f" "$BASE_DIR/highlights-and-guides/$f" +done + +echo "[$(date)] Symlinks recreated" +DOWN=$(ls -1 "$MASTER_DIR"/*.pdf 2>/dev/null | wc -l) +SIZE=$(du -sh "$MASTER_DIR" | cut -f1) +echo "[$(date)] Total: ${DOWN}/112 files (${SIZE})"