FTBucket 現行仕様書
対象リポジトリ:
ftbucket(PHP実装) 作成日: 2026-03-09
概要
FTBucketはふたば☆ちゃんねるのスレッドをサーバーサイドでアーカイブするWebアプリケーション。 スレッドHTMLと添付画像をサーバーにダウンロード・保存し、zip/mht形式での再配布と一覧閲覧を提供する。
ライセンス: GPLv2
システム構成
ディレクトリレイアウト
src/
├── config.php 設定・共通関数
├── index.php 一覧画面
├── scrapshot.php スレッド取得エントリポイント
├── download.php ダウンロードページ
├── remove.php スレッド削除
├── admin.php 管理画面(一括削除)
├── json_api.php JSON REST API
├── json_api.php JSON REST API
├── cron_get.php 自動更新 cron スクリプト
├── cron_del.php 自動削除 cron スクリプト
├── contact.php 削除連絡
├── editmeta.php メタ情報編集
├── autotag.php 自動タグ付け定義
├── blacklist.php ブラックリスト定義
├── cont/ スレッドコンテンツ格納ディレクトリ
├── meta/ メタデータDB格納
├── zip/ 生成済みzip/mhtファイル格納
├── lock/ ロックファイル格納
├── json/ JSONキャッシュ格納
└── phplib/ ライブラリ群
├── common.php 汎用関数
├── crawl.php クロール制御
├── meta_dao.php メタデータDAO
├── const.php システム定数
├── pager.php ページャ
├── result.php 結果ページ生成
├── session.php セッション管理
├── signature.php RSA署名
├── filehashing.php 画像ハッシュ
├── imgfinder.php 類似画像検索連携
├── FileDownloader.php ダウンロード処理
├── TurnstileBlocker.php Bot対策
├── cronlock.php cron多重起動防止
├── fsutil.php ファイルシステムユーティリティ
├── crawl/ クロール実装
│ ├── pget.php クロールディスパッチャ
│ ├── pget_old.php 旧クロール実装
│ ├── pget_new.php 新クロール実装
│ └── pullthread.php リモートバケットからの取得
├── archive/ アーカイブ生成
│ ├── pzip.php zip生成
│ └── mht.lib.php mht生成
├── dba/ データベース抽象化層
│ ├── textfinder.php 全文検索ディスパッチャ
│ ├── fts_flatdb.php 全文検索(SQLite FTS)
│ ├── DBA_chunkfile2.php デフォルトKVS
│ ├── DBA_sqlite3.php SQLite KVS
│ └── DBA_qdbm.php QDBM KVS
├── analyze/
│ └── naivebayes_cache.php ベイズ分類器
└── storage/ 外部ストレージ連携
データモデル
スレッドメタ情報 (info)
各スレッドごとに以下のフィールドを持つ連想配列を KVS に保存する。
| フィールド | 型 | 説明 |
|---|---|---|
url |
string | ふたばスレッドの元URL (キー) |
title |
string | スレッドタイトル |
res |
string | 1レス目の本文HTML |
res_count |
int | レス数 |
thumb |
string | サムネイル画像の相対URL |
store_url |
string | 保存済みHTMLの相対URL |
date |
int | 最終更新Unix timestamp |
first_date |
int | 初回保存Unix timestamp |
user_update |
int | 最終ユーザー操作timestamp |
user_ip |
string | 初回登録者IP |
user_host |
string | 初回登録者ホスト名 |
user_regid |
string | 初回登録者セッションID |
du |
int | ディスク使用量(bytes) |
lost |
int | ロストカウント(0=生存, N=ロスト回数) |
ng |
bool | NGフラグ |
tags |
array | [[タグ文字列, 登録ホスト名], ...] |
alluserid |
array | ストック登録者IDリスト |
contacts |
array | 削除連絡 [[理由, ホスト], ...] |
samefiles |
array | 重複ファイルパスリスト |
other_files |
int | 添付ファイル数 |
has_thumb |
bool | サムネイル存在フラグ |
has_catalog |
bool | カタログ画像存在フラグ |
catalog_path |
string | カタログ画像相対URL |
htmlhash |
string | ソースHTMLのSHA1ハッシュ |
src1res_day |
string | 1レス目の日付文字列 |
src1res_time |
string | 1レス目の時刻文字列 |
mht_publish_path |
string | 外部ストレージ公開MHTパス |
zip_publish_path |
string | 外部ストレージ公開ZIPパス |
コンテンツディレクトリ構造
スレッドURLから生成したパス名 (saniPath) をキーにディレクトリを作成する。
cont/{saniPath}/
├── index.htm 加工済みスレッドHTML (SJIS→UTF8変換済み)
├── img/ スレッド画像
├── thumb/ サムネイル画像
└── other/
├── index.htm.gz 取得元のオリジナルHTML (SJIS gzip)
├── crawl.json クロール情報JSON
└── catalog.jpg カタログ用画像
URLからパス名への変換
saniPath(basename) = basename.replace("/", "_").replace(".htm", "")
例: http://may.2chan.net/b/res/12345.htm
→ may.2chan.net_b_res_12345
KVS (Key-Value Store) 抽象化層
設定ファイル meta/dbaconf.dat によってバックエンドを切り替え可能。
| バックエンド | ファイル | 説明 |
|---|---|---|
chunkfile2 |
meta/chunk2/ |
デフォルト。ファイルシステムベースの独自実装 |
sqlite3 |
meta/allinfo.sqlite |
SQLite3 |
qdbm |
meta/allinfo.qdb |
QDBM (古い環境向け) |
シリアライザは PHP serialize() または MessagePack を選択可能。
主要機能
1. スレッド取得 (scrapshot.php)
エンドポイント: GET /scrapshot.php?rooturl={url}
処理フロー:
- URL正規化・バリデーション (
URLREGX正規表現でふたばURLのみ許可) - ブラックリストチェック
- ロックファイルによる同一スレッドの排他制御
- クールタイムチェック (
COOLTIME秒以内の再取得をブロック) execDownload()によるクロール実行- 親バケット (
REMOTEROOT) がある場合はそこから取得 - なければふたばに直接アクセス
- 親バケット (
- メタ情報の保存
- 自動タグ付け
- 上限数チェック・古いスレッドの自動削除 (
LIMITCAP) - 画像検索・ファイルハッシュ登録
クロール処理 (cust_pget):
- ふたばからSJISのHTMLを取得
- UTF8に変換して
index.htmとして保存 - オリジナルSJIS HTMLを gzip圧縮して
other/index.htm.gzに保存 - 画像・サムネイルを
img/,thumb/にダウンロード - 削除済み画像の同期 (
IMGDIR_SYNC)
2. 一覧表示 (index.php)
エンドポイント: GET /index.php
GETパラメータ:
p- ページ番号s- 検索キーワード (AND/OR対応、|でOR、スペースでAND)f- 全文検索フラグmode- 表示モード (l=リスト,c=カタログ,cm=ミニカタログ)favo- お気に入りのみ表示w- 添付ありフラグで絞込in- 類似画像元URLで絞込ord- ソート順切替
テンプレートエンジン: Smarty (独自組み込み版)
3. ダウンロード (download.php)
エンドポイント: GET /download.php?rooturl={url} (ページ表示)
エンドポイント: GET /download.php?rooturl={url}&type={zip|mht}&dlname={name} (ファイルDL)
zip/mhtは以下の2つのファイル名で提供:
- URLベース名:
{saniPath}.zip - タイトルベース名:
{日付}_{スレID}_{タイトル}.zip
ZIPONTHEFLY=true の場合はファイル保存せずオンザフライ生成。
Bot対策: Turnstile認証 (USE_TURNSTILE_BLOCKER)、レートリミット
4. 削除 (remove.php)
エンドポイント: POST /remove.php
削除条件 (いずれかを満たす場合):
FIRSTUSERDEL=trueかつ初回登録者と同一IP+セッションID- 管理者パスワード (
RMPASSWD) が一致
STOCKLISTが有効な場合、まずストックから外し、ログ自体の削除は別途実行。
5. 管理画面 (admin.php)
エンドポイント: GET/POST /admin.php
機能:
- スレッド一覧表示(検索・絞込対応)
- チェックボックスによる一括削除
- タグ一括削除
6. 自動更新 (cron_get.php)
crontabから定期実行するスクリプト。
処理:
- ロストでないスレッド、または最近ロストしたスレッドを更新リストに追加
- 各スレッドをロックしながら
execDownload()で更新 - DBの最適化
親バケット (REMOTEROOT) が設定されている場合:
- 親バケットの
json_api.php?action=readallurlからURL一覧を取得 - 親バケットに存在しないスレッドはスキップ
7. 自動削除 (cron_del.php)
crontabから定期実行するスクリプト。
LIFETIME 秒を経過したスレッドを削除する。
LIFETIME_TYPE による基準時刻の選択:
0: 最終更新時刻1: 最終ユーザー操作時刻2: 初回登録時刻
8. JSON API (json_api.php)
エンドポイント: GET/POST /json_api.php?action={action}
| action | 説明 |
|---|---|
readallurl |
全スレッドURLリスト |
readallinfo |
全スレッドメタ情報リスト |
readurlinfo |
指定URLのメタ情報 |
readalltag |
全タグリスト (termで絞込) |
readtag |
指定URLのタグリスト |
setng |
NGフラグ設定 (要パスワード) |
readurlitemlist |
指定URLのコンテンツファイルリスト |
readconfig |
設定情報 |
publickey |
RSA公開鍵 |
bayestags |
ベイズタグ予測 |
レスポンス: JSON (gzip圧縮転送対応)
9. マルチバケット連携
REMOTEROOT (キャッシュ親バケット):
- スレッド取得時に親バケットと同期
- 親バケット経由でスレッドを取得
- cron_get で親バケットのURL一覧と同期
SUBSCRIBES (読み取り専用購読先バケットリスト):
- 自分・キャッシュ・ふたばのどこにもない場合のフォールバック取得先
- 親バケットは更新しない
設定項目一覧
src/config.php の $APPCONST 配列で設定。
| キー | デフォルト | 説明 |
|---|---|---|
TITLE |
"FTBucket" | サイトタイトル |
URLREGX |
ふたば全体 | 許可するスレッドURLの正規表現 |
RMPASSWD |
md5("passwd") | 管理者パスワード(md5) |
LIFETIME |
0 | スレッド生存秒数(0=無制限) |
LIFETIME_TYPE |
0 | 生存基準時刻種別 |
PAGECAP |
20 | 1ページのスレッド数 |
LIMITCAP |
2000 | 最大保存スレッド数(0=無制限) |
COOLTIME |
10 | 連続更新防止秒数 |
THUMB |
true | 一覧にサムネイル表示 |
USEZIP |
true | zip/mhtダウンロード有効 |
ZIPONTHEFLY |
false | オンザフライzip生成 |
RMADLINK |
true | 広告削除 |
IMGDIR_SYNC |
true | 削除済み画像の同期 |
USELIGHTBOX |
false | lightbox使用 |
REMOTEROOT |
"" | 親バケットURL |
SUBSCRIBES |
[] | 購読先バケットURLリスト |
REBUILDLOG |
true | 取り込み時ログ再変換 |
USECONTACT |
false | 削除連絡機能 |
MAILTOCONTACT |
"" | 連絡先メールアドレス |
AUTOBOARDNAME |
false | 板名自動タグ付け |
USESEARCHSV |
false | 全文検索有効 |
USEFTSDB |
false | FTS5全文検索 |
BAYESIANTAG |
false | ベイズ自動タグ予測 |
USEIMGFINDER |
false | 類似画像検索連携 |
MANUALUPDATE |
true | 手動更新有効 |
STOCKLIST |
false | ストック一覧機能 |
WITHFILE |
false | 添付あり絞込機能 |
FIRSTUSERDEL |
true | 初回登録者削除許可 |
USEFILEHASHING |
false | 画像重複排除 |
CONTDIRREADONLY |
false | contディレクトリ読取専用 |
DEFAULT_VIEW_MODE |
"l" | デフォルト表示モード |
VIEWORDER |
false | 表示順再ソート |
USESIGNATURE |
false | RSA署名機能 |
USE_ANALYTICS_LOG |
false | 解析ログ記録 |
DISKFREELIMIT |
0 | 最小空きディスク容量(bytes) |
USE_REMOTE_ZIP_PULL |
false | リモートからZIPを取得 |
USEFULLCACHE |
false | 一覧キャッシュ |
DOWNLOAD_LINK_MODE |
1 | DLリンク表示モード |
USE_TURNSTILE_BLOCKER |
false | Turnstile Bot対策 |
BOT_LIMIT_SHORT_TERM |
100 | 10分間の許容DL数 |
BOT_LIMIT_LONG_TERM |
1000 | 24時間の許容DL数 |
セッション管理
- PHPセッション使用
user_regid: セッションに紐付いたランダムID (ユーザー識別用)- Cookie
VIEWMODE: 表示モード保存 - Cookie
FAVOARG: お気に入り表示設定保存
全文検索
USESEARCHSV=true で有効。バックエンドは2種類:
- FlatDB (
USEFTSDB=false): SQLite の LIKE 検索 - FTSDB (
USEFTSDB=true): SQLite FTS5 を使用した高速全文検索
検索対象: スレッド内の全 <blockquote> テキスト
検索構文: | でOR条件、スペース(全角/半角)でAND条件
アーカイブ形式
ZIP
cont/配下の全ファイルを zip 圧縮- ファイル名:
{saniPath}.zipまたは{日付}_{スレID}_{タイトル}.zip
MHT (MIME HTML)
- HTMLと画像を単一ファイルにまとめたMHT形式
- base64エンコードで画像を埋め込み
ロック機構
- スレッドごとに
lock/{saniPath}.lockファイルでflock排他制御 - 塩辛瓶 (ふたば画像サーバー) へのアクセスは
SIO_LOCKで全バケット共有ロック - cron スクリプトの多重起動防止:
CronLockクラス
Bot対策
USE_TURNSTILE_BLOCKER=true で有効:
- Cloudflare Turnstile によるCAPTCHA
- レートリミット: 10分/24時間の許容DL数設定
- ブラックリストIP拒否
- User-Agent ブロックリスト
署名機能
USESIGNATURE=true で有効:
- RSAキーペアによるスレッドコンテンツの署名
other/signature.gzにgzip圧縮署名を保存- JSON API
publickeyアクションで公開鍵を提供
外部依存
- PHP 7.4以上
- PHP拡張:
mbstring,hash,zlib(必須) - PHP拡張:
sqlite3(全文検索・ベイズ・ファイルハッシュ機能で必要) - PHP拡張:
msgpack(高速シリアライズ、オプション) - Smarty (テンプレートエンジン、ソース同梱)
- PEAR2 HTTP/Request2 (一部クロール処理、ソース同梱)