fixes
This commit is contained in:
1 parent
bb941cff43
commit
6a821c7512
7 files changed
+1768
-326
No files matched your search
@@ -1,3 +1,165 @@
|
||||
# compare_filesize_drupal6
|
||||
# Drupal 6 – duże obrazy, lokalizacja tematów i bezpieczna optymalizacja
|
||||
|
||||
Rozbudowana wersja `compare_filesize_drupal6`. Działa **poza Drupalem**, w Pythonie 3.9+; potrzebuje dostępu do MySQL/MariaDB i katalogu plików.
|
||||
|
||||
## Co robi
|
||||
|
||||
- Wyszukuje największe pliki i największe rozdzielczości (JPG, PNG, GIF – GIF wyłącznie do analizy).
|
||||
- Wskazuje, **w jakim temacie, poście lub komentarzu** pojawia się obraz. Raport pokazuje `nid`, `cid`, tytuł, typ zawartości, URL do wpisu, URL do edycji i źródło powiązania.
|
||||
- Szuka połączeń przez `upload.fid` i pola `*_fid` w tabelach CCK/ImageField/FileField; obsługuje aktualne rewizje (`vid`) i opcjonalne tabele załączników komentarzy (`cid` + `fid`).
|
||||
- Szuka obrazów w `node_revisions.body` i `node_revisions.teaser`, `comments.comment`, opcjonalnie też w tekstowych polach CCK. Rozróżnia **pewne** dopasowania identyfikatora `fid` lub pełnej ścieżki od **możliwych** trafień po samej nazwie pliku.
|
||||
- Generuje link do oryginalnego pliku (jeżeli publiczny) i pomocniczy link do Drupal Search (jeżeli moduł Search jest aktywny).
|
||||
- Generuje CSV (polskie kolumny, Excel, UTF-8 BOM) i JSON.
|
||||
- Symuluje dokładną optymalizację w **dry-run**, bez zapisu źródłowego pliku i bazy.
|
||||
- Przy `--apply` zachowuje oryginał w oddzielnym katalogu, przygotowuje nowy obraz do atomowej podmiany, zapisuje `files.filesize`, a przy błędzie próbuje odtworzyć oryginał i wartości bazy.
|
||||
- Wykrywa duplikaty SHA-256 i pliki na dysku, których nie ma w analizowanym zestawieniu z bazy.
|
||||
|
||||
## Instalacja
|
||||
|
||||
```bash
|
||||
unzip compare_filesize_drupal6-extended.zip
|
||||
cd compare_filesize_drupal6
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
cp config.example.py config.py
|
||||
```
|
||||
|
||||
W `config.py` ustaw:
|
||||
|
||||
```python
|
||||
DB_CONFIG = {
|
||||
'host': 'localhost',
|
||||
'port': 3306,
|
||||
'database': 'drupal6_db',
|
||||
'user': 'drupal_user',
|
||||
'password': 'twoje_haslo',
|
||||
'charset': 'utf8',
|
||||
}
|
||||
FILES_BASE_PATH = '/var/www/drupal/sites/default/files'
|
||||
PUBLIC_FILES_PATH = 'sites/default/files'
|
||||
DRUPAL_ROOT = '/var/www/drupal'
|
||||
DRUPAL_BASE_URL = 'https://forum.example.org'
|
||||
DB_TABLE_PREFIX = ''
|
||||
```
|
||||
|
||||
**Ważne:** `FILES_BASE_PATH` to lokalizacja rzeczywistych plików, a `PUBLIC_FILES_PATH` to fragment zapisany zwykle w `files.filepath`. Jeśli pliki są np. w `/var/www/drupal/files`, zmień obie wartości. Można też podać je w CLI: `--public-files-path`, `--drupal-root`. Gdy Drupal pracuje bez clean URLs, dodaj `--no-clean-urls`.
|
||||
|
||||
## 1. Znajdź tematy i komentarze z największymi obrazami
|
||||
|
||||
```bash
|
||||
python main.py --find-usage --top 50 --report-csv najwieksze-z-linkami.csv
|
||||
```
|
||||
|
||||
Przykładowe wiersze (fikcyjne):
|
||||
|
||||
```text
|
||||
1. 18.42 MB 4200x5900 fid=1234 scans/mapa.jpg
|
||||
-> Archiwalne skany (forum, nid=812, pewne)
|
||||
LINK: https://forum.example.org/node/812
|
||||
EDYCJA: https://forum.example.org/node/812/edit
|
||||
SKAD: upload.fid, tresc wpisu (sciezka)
|
||||
-> Zdjęcie w komentarzu (forum, nid=920, cid=42, pewne)
|
||||
LINK: https://forum.example.org/node/920#comment-42
|
||||
```
|
||||
|
||||
CSV zawiera jedną linię dla każdego znalezionego miejsca. Gdy powiązania brak, w CSV zostaje plik, jego `fid`, rozmiar i propozycja wyszukiwania nazwą w Drupal Search.
|
||||
|
||||
### Tylko skany lub wybrane pliki
|
||||
|
||||
```bash
|
||||
python main.py --find-usage --top 100 --path-contains skan --report-csv skany.csv
|
||||
python main.py --find-usage --fid 1234 --report-csv jeden-obraz.csv
|
||||
python main.py --find-usage --min-size-mb 5 --usage-scope all --report-csv wieksze-niz-5mb.csv
|
||||
```
|
||||
|
||||
`--usage-scope top` szuka tylko w `--top N` największych obrazach; `optimizable` – w obrazach przekraczających limity; `all` – w całym filtrowanym zestawieniu. Przy bardzo dużych bazach `all` może oznaczać długi skan treści. `--no-text-scan` wyłącza szukanie w treściach i zostawia szybsze powiązania `fid`. `--scan-cck-text` rozszerza skan na tekstowe pola CCK.
|
||||
|
||||
## 2. Dokładny dry-run optymalizacji
|
||||
|
||||
```bash
|
||||
python main.py \
|
||||
--find-usage --usage-scope optimizable \
|
||||
--optimize --dry-run --optimize-top 20 \
|
||||
--max-width 2400 --max-height 3200 --max-file-mb 2 \
|
||||
--report-csv plan.csv --report-json plan.json
|
||||
```
|
||||
|
||||
Dostaniesz rzeczywisty przewidywany rozmiar po rekompresji (test wykonany na pliku tymczasowym). **Nie zmieni to oryginałów ani SQL.** `--top` dotyczy wyświetlania; `--optimize-top` ogranicza liczbę obrazów poddawanych testowi/zmniejszaniu.
|
||||
|
||||
## 3. Zmniejsz np. pierwsze 10 obrazów i aktualizuj bazę
|
||||
|
||||
**Najpierw zrób pełen backup bazy danych i katalogu plików** oraz przetestuj na kopii. Następnie:
|
||||
|
||||
```bash
|
||||
python main.py \
|
||||
--optimize --apply \
|
||||
--optimize-top 10 --max-changes 10 \
|
||||
--backup-dir /srv/backups/drupal6-images \
|
||||
--max-width 2400 --max-height 3200 --max-file-mb 2 \
|
||||
--report-csv wykonane.csv --report-json wykonane.json
|
||||
```
|
||||
|
||||
Każda udana zmiana:
|
||||
|
||||
1. Zapisuje oryginał w osobnym katalogu (automatycznie tworzony podfolder uruchomienia).
|
||||
2. Zastępuje obraz tylko jeżeli nowy plik jest mniejszy o co najmniej `--min-gain-percent` (domyślnie 5%).
|
||||
3. Aktualizuje `files.filesize` dla wszystkich `fid` wskazujących na tę samą ścieżkę.
|
||||
4. W przypadku błędu SQL próbuje odtworzyć oryginalny plik i rozmiar w DB (także przy MyISAM – kompensacja aktualizacji).
|
||||
|
||||
`--apply` jest wymagane do każdego zapisu. Samo `--optimize` lub `--update-db` nie wykonuje zmian. **Realna optymalizacja zawsze aktualizuje rozmiar w DB**, także bez `--update-db`.
|
||||
|
||||
Jeżeli chcesz wyłącznie zsynchronizować rozmiary plików w istniejącym `files`:
|
||||
|
||||
```bash
|
||||
python main.py --update-db --dry-run
|
||||
python main.py --update-db --apply
|
||||
```
|
||||
|
||||
`--update-db` w połączeniu z `--optimize --apply` dodatkowo koryguje rozmiary tych plików, które *nie zostały* zoptymalizowane.
|
||||
|
||||
## Zasady jakości i bezpieczeństwa
|
||||
|
||||
- **JPEG:** zachowuje rozszerzenie i ścieżkę, skaluje proporcjonalnie filtrem LANCZOS, zapisuje z wysoką jakością 92/89/86/85 (`--jpeg-quality`, `--min-jpeg-quality`). Nie schodzi poniżej skonfigurowanej jakości, nawet gdy cel 2 MB nie zostanie osiągnięty. JPEG jest formatem stratnym – każda ponowna kompresja może zmienić piksele.
|
||||
- **PNG:** zachowuje format oraz kanał przezroczystości, używa kompresji **bezstratnej**. Nie konwertuje PNG do JPEG i nie zmienia rozszerzeń, bo mogłoby to popsuć stare linki w Drupalu. Duży PNG ze skanem może pozostać duży, jeśli kompresja bezstratna nic nie da. Konwersja do JPEG wymagałaby osobnej, kontrolowanej migracji i aktualizacji odnośników.
|
||||
- **Skan tekstowy:** domyślny limit **2400 × 3200 px** zamiast starego 1920 × 1080. Przed decyzją sprawdź czytelność drobnego druku w próbce i w razie potrzeby zwiększ limity lub pomiń plik.
|
||||
- **GIF/animacje, nieobsługiwane formaty, niezgodności formatu i rozszerzenia:** pomijane przy zapisie. Symlinki i hardlinki też są pomijane.
|
||||
- Kopia oryginału wymagana jest przy `--optimize --apply`, a lokalizacja kopii **musi być poza** `FILES_BASE_PATH` i poza katalogiem WWW Drupala (jeśli ustawiono `DRUPAL_ROOT`).
|
||||
- Weryfikacja czasu modyfikacji i inode chroni przed zmianą pliku w trakcie skanowania; zalecane jest wykonywanie pracy w oknie serwisowym.
|
||||
- Zachowuje ICC, DPI, EXIF (z prawidłową obsługą orientacji) i tekstowe metadane PNG w obsługiwanych formatach, ale nie gwarantuje zachowania każdego niestandardowego segmentu metadanych.
|
||||
- Aktualizowany jest tylko `files.filesize` – nie są zmieniane ścieżki, `fid`, treści postów ani załączniki. Zmiana dużego obrazka może wymagać ręcznego odświeżenia wygenerowanych miniatur przez ImageCache.
|
||||
- Kopia wykonana przez samo narzędzie obejmuje **obraz**, nie całą bazę. MyISAM nie zapewnia transakcji; procedura przywracania jest best-effort. Pełny backup DB i plików przed zmianami jest obowiązkowy.
|
||||
|
||||
## Pozostałe opcje
|
||||
|
||||
```bash
|
||||
python main.py --find-duplicates
|
||||
python main.py --show-deleted --exclude-folders imagecache styles
|
||||
python main.py --find-usage --no-clean-urls --site-url https://example.org/drupal
|
||||
python main.py --help
|
||||
```
|
||||
|
||||
Uwaga do `--show-deleted`: pokazuje pliki na dysku **bez pasującego wpisu `files` w analizowanym zestawieniu**, nie zaś potwierdzenie, że plik naprawdę nie występuje w treści. Przy filtrach (`--path-contains`, `--min-size-mb`, `--fid`) plik odfiltrowany może zostać pokazany jako „spoza zestawienia”. Nic nie jest usuwane.
|
||||
|
||||
### Ograniczenia wyszukiwania
|
||||
|
||||
- Powiązania po `fid` są najbardziej jednoznaczne; wyszukiwanie po samej nazwie pliku bywa niejednoznaczne – w raporcie `pewnosc=mozliwe`.
|
||||
- Tekst przeszukiwany jest w **aktualnych rewizjach** węzłów i komentarzach. Nie szuka w archiwalnych rewizjach ani w niestandardowych zewnętrznych modułach przechowywania treści bez włączonego skanu CCK.
|
||||
- Link do nieopublikowanego wpisu lub komentarza może wymagać konta z prawami administracyjnymi. Raport to zaznacza.
|
||||
- **Drupal 6 stronicuje komentarze**: `node/NID#comment-CID` może nie przewinąć do komentarza z dalszej strony. Jeżeli masz zainstalowany moduł [Permalink dla Drupal 6](https://www.drupal.org/project/permalink), dodaj `--comment-permalinks`, aby generować `comment/CID#comment-CID`, które kieruje na właściwą stronę komentarzy. Bez tego modułu nie używaj tej flagi. Niezależnie od typu linku raport pokazuje `nid` i `cid`.
|
||||
- Nie ma gwarancji odnalezienia obrazów w niestandardowych relacjach tworzonych przez własne moduły, w CSS i w HTML poza bazą.
|
||||
- W przypadku prywatnego systemu plików adres bezpośredni do pliku może nie działać; odnośnik do tematu nadal powinien wskazać miejsce.
|
||||
|
||||
## Testy
|
||||
|
||||
```bash
|
||||
python -m unittest discover -s tests -v
|
||||
```
|
||||
|
||||
Testy z lokalną, symulowaną bazą weryfikują powiązania Upload/CCK, obecne rewizje, komentarze, brak zmian w dry-run, aktualizację `files.filesize`, backup, przywracanie po błędzie SQL, format PNG i ścieżki katalogów. **Nie zastępują próby na kopii konkretnej instalacji Drupal 6**.
|
||||
|
||||
### Źródła struktury bazy Drupal 6
|
||||
|
||||
- [Oficjalny migrator Drupal 6 Upload](https://api.drupal.org/api/drupal/core%21modules%21file%21src%21Plugin%21migrate%21source%21d6%21Upload.php/8.9.x) – `upload.fid`, `upload.nid`, `upload.vid`.
|
||||
- [Oficjalny migrator komentarzy D6](https://api.drupal.org/api/drupal/core%21modules%21comment%21src%21Plugin%21migrate%21source%21d6%21Comment.php/class/Comment/main) – tabela `comments`, `cid`, `nid`, status komentarza.
|
||||
- [CCK 6](https://api.druphelp.com/api/cck/content.module/6) – `content_type_*`, `content_field_*`.
|
||||
Reference in new issue
Block a user