私たちの多くは、サーバー上のファイルを変更せずに、ローカルツールを使用してWebサイトの外観を変更できることを認識しています。 これを行うにはさまざまな方法がありますが、最も一般的なのはユーザースクリプトとスタイルであり、ブラウザによってロードされたページに自動的に適用されます。 もちろん、そのような編集の可能性は非常に限られており、データベースへの非標準のクエリを必要とする深刻な問題を解決するには、この方法は機能しません。
ただし、この場合でも、すべてがそれほど絶望的ではないことが判明する場合があります。 この記事では、トピックや投稿の既読ステータスの表示を修正するphpBB2フォーラムエンジン用のローカルアドインを作成した経験について説明します。 この試みの結果は完全に機能する製品でしたが、今では常に使用していますが、この記事を執筆する目的は製品のプレゼンテーションではなく、問題を解決するアプローチの説明です。 私は受け取ったプログラムのコードを投稿しますが、タスクの詳細のため、特定のサイトのエンジンの予備的な(そしてかなり骨の折れる)構成なしでは、それは十分に普遍的ではなく、そのまま使用できません。 がっかりしないように、事前に警告することにしました。
そして今、問題文に関するより詳細に示します。
3番目のバージョンはphpBBの現在のバージョンであると長い間考えられてきましたが、2番目のバージョンはまだインターネット上で非常に一般的です。 私のツールが戦うように設計されているphpBB2の弱点のリストを以下に示します。
- ログインまたはブラウザを再起動した後、および一定時間非アクティブになった後、未読トピックはすべて自動的に既読としてマークされます。
- トピックを開くと、開いているページに関係なく、トピック全体が読み取られます。
- 読み取りステータスは、シリアル化された配列としてクッキーに保存されます。 Cookieの最大サイズは通常4 KBに制限されているため、約140トピックのステータスのみを保存できます。 アクティブなフォーラムの場合、これはごくわずかです。
肩をすくめる人もいますが、実際問題は何ですか? しかし問題は、すべての事項に遅れないようにしたい場合、未読のトピックとメッセージを(基本スキンの)オレンジリーフでマークすると、どのトピックが更新され、どのトピックが更新されていないかをすばやく確認できることです。 あなたは、たとえば、脇にそれらを更新するためにフォーラムに移動し、任意のメッセージに迅速に対応し、残りの部分を読んですることになりましたことを決定した場合は、未読の状態に次の訪問は廃棄される、そしてそれぞれの最後の訪問だったときに思い出して、手動で新しいメッセージを探すことが必要です特定のトピック、および投稿の日付またはテキストを探し、その瞬間からその中に登場したもの。 また、常にすべてのトピックを一度に読んだとしても、これは保証ではありません。結局、ブラウザーがクラッシュしたり、コンピューターがクラッシュしたり、ライトが消えたりする可能性があります(すべてのユーザーがUPSを持っているわけではありません)。
もちろん、問題に対する最も正しい解決策はフォーラムエンジンを変更することですが、実際にはこれは常に可能とはほど遠いものです。 したがって、私はこの問題を自分で、クライアント側で解決しようとすることにしました。 もちろん、サーバー上のデータベースに直接アクセスすることなく、完全に理想的なソリューションに疑問の余地はありません。 具体的には、ほとんどの場合、正確に(あなたが彼のテーマのすべてのページのフルセットをダウンロードし、分析しない限り、それは長い時間です)正しくホームページにアイコンを表示するために特定のサブフォーラムで未読の存在/不在を決定することはできません。 それにもかかわらず、いくつかの重要な改善を達成することはかなり可能です。
合計アドインアーキテクチャは以下のとおりである。各被験者のための最後の訪問のタイムスタンプを格納し、プラスフォーラムのすべてのページを通過するプロキシサーバーを実行しているローカルデータベースに格納されているクライアントマシン上で、修正ラベルは、実際の状況に応じてテーマやメッセージを持っていますローカルデータベースから取得した読み取り値(およびもちろん、必要に応じてこのデータベースを更新します)。
基本形式として、「00000000000000」という形式の行のセットを持つテキストファイルを選択しました。 各行は1つのトピック、行番号(ゼロからカウント)-トピックの識別子、およびUNIX時間形式での最後の訪問のタイムスタンプに対応し、行のコンテンツとして記録されます。 ゼロトピックはないため、ゼロ行は特別な方法で使用されます。フォーラム全体の日付/時刻が保存されるため、すべてのフォーラムトピックを一度に既読としてマークできます。 したがって、各トピックについて、最後の訪問のリアルタイムは、一般的なフォーラムと特にこのトピックの2つの値の最大値と見なされます。
なぜ私は、テキスト形式で停止しましたか? まず、必要に応じて、バイナリエディターを使用せずにエラーを修正するのに便利です。 第二に、私のプロキシサーバーはパールで書かれており、バイナリファイルよりもテキストファイルで作業する方が便利です。 テキスト文字列から数値を解析することは、リソースを大量に消費する操作ではなく、文字列の長さが固定されているため、ファイル全体を行ごとに読み取らずに、インデックスで目的のレコードに直接移動できます。
プロキシサーバーの実装に関しては、その上でテキストを操作するのが非常に便利であるという理由で、パール言語が選択されました(そしてもちろん、HTMLの解析が重要な部分になります)。 私の基準では、結果として得られる速度はかなり許容できることが判明しました(いずれにせよ、別の言語に切り替えることによる潜在的なパフォーマンスの向上は、労力と時間のコストほど重要ではないようです)。 プロキシサーバーはそのポートをリッスンし、ブラウザーから要求を受信すると、ターゲットサーバーに要求を送信し、応答を読み取り、受信したページのコンテンツをブラウザーに送信します。 その途中で、ページはフィルターを通過し、その動作は宛先アドレスに依存します。 これは我々が必要とするフォーラムの一つであり
、viewtopic.phpスクリプト 、viewforum.php、index.phpの (またはフォーラムのちょうどルートURL)の一つではなく、何でもある場合、フィルタは、日付に基づいて、ラベルやメッセージを交換し、ページを解析するために開始します/ローカルデータベースから取得した最後の訪問の時間。 そうでない場合、フィルターは機能せず、変更されていないコンテンツをブラウザーに送信します。
最も困難で予測不可能な部分は解析です。 問題は、特定のフォーラムごとに異なるテーマと拡張機能をインストールできるため、サーバーから受信したページのHTMLコードが非常に広い範囲で変化することです。 さまざまなフォーラムの機能を考慮するために、phpBB2エンジンの主要な構造的機能のみをハードコーディングし、起動時にプロキシサーバーによって読み込まれる個別のモジュールに特定の信号線を配置し、各フォーラムを独自のルールセットに従って処理できるようにしました。 もちろん、新しいフォーラムのサポートを追加する必要がある場合は、サーバーから受信したHTMLページを分析して、信号線の強調表示と設定のすべての作業を手動で行う必要があります。 エンジンの変更が小さい場合、すべてがこれに制限されます。 しかし、エンジンが大幅に再設計され、HTML構造が完全に異なっていることが判明する場合があります。 その後、メインモジュール全体をやり直す必要がありますが、一般に「マルチフォーラム」を維持できるというのは事実ではありません。 プロキシサーバーの別のバージョンを保持する方が簡単である可能性があります。これは、「ファンシー」フォーラムの1つに特化したものです。
解析が正しく機能するためには、フォーラムのプロファイルを変更する必要もあります。 事実、デフォルトでは、エンジンは秒を指定せずにメッセージの日付/時刻を表示しますが、これ以上時間をかける場所がないため、マークを配置する際のエラーは1分になりますが、これはもちろん多すぎます。 したがって、プロファイル[設定]でより完全な時間形式を秒単位で選択する必要があります。 「D dmY、G:i:s」という形式に決めました。これにより、「Mon 02/14/2011、10:57:44」の形式で日付を表示できます(もちろん、プロキシサーバーは曜日を必要としませんが、愛する人にとっても便利です忘れないでください)。 別の形式を使用する場合は、タイムスタンプの解析機能を適切に修正する必要があります。 日付の代わりに「今日」または「昨日」という単語を挿入できるphpBBの変更を忘れてはなりません。 残念ながら、これにはコードの改良も必要です。
まあ、いくつかのより多くの機能を言及するのを残しました。
- おそらく主な問題は、そのようなプロキシサーバーを継続的に使用することは非常に不便であることです。 単一のフォーラムで作業しているときにブレーキング作業を生き残ることができれば、日常作業でブレーキをかけることは非常に不快になります。 私はこの問題を次のように自分で解決しました。Proxomitronを広告用カッターとして長い間使用しており、あらゆる種類のグッズを追加しています。 特に、要求されたアドレスに応じて異なるプロキシサーバーを使用する機能があります。 ルールを作成しただけで、必要なフォーラムがプロキシを介して読み込まれ(全体ではなく、処理されているページのみ)、他のすべてが直接機能するので、この欠点は私に不便さを引き起こしません。 Proxomitronを使用しないユーザーは、いくつかの代替オプションを探すか、ブラウザで自分でプロキシをすばやく手動で切り替える機能を設定できます(もちろん、ブラウザにこのような機会がある場合)。
- 本格的なHTTPサーバーを実装したり、既製の実装を探したくなかったため、自分で作成した単純な、しかしかなり限定されたバージョンに限定しました(gzip圧縮の強制切断ではHTTP / 1.0のみがサポートされます)。 個人的にはこれで十分ですが、一部の人にとっては、これらの機会は十分に思えないかもしれません。
- phpBBにはもう1つ問題があります。 同時に複数のフォーラムページを開いたり更新したりすると、エンジンはフォーラムから私を追い出します(読み取りステータスのリセットと相まって、私は単に腹を立てました)。 この動作の理由はまだ解明されていませんが、同時にプロキシサーバーによってこの問題を回避することができました。 最初はマルチスレッド化されていたため、あるページの処理で他のページの処理が遅くなることはありませんでした。 マルチスレッドのコードをコメントアウトし、ページ処理の速度は遅くなりましたが、より一貫したものになったため、ログインする内容をほとんど心配することなく、すぐにバックグラウンドタブで多数のリンクを開くことができます(もちろん、今ではそれほど致命的ではありませんが、余分です)ログイン/パスワードを入力したり、既に開いているページを更新したりする気はありません)。 もちろん、このようなソリューションには欠点もあります。何らかの理由でページの1つがフリーズした場合、残りのページは読み込まれず、タイムアウトを待つかプロキシサーバーを再起動する必要があります。 また、複数のフォーラムで作業する場合、他のフォーラムをロードするために一方を待つことは間違っています。 解決策は、各フォーラムに1つずつ、複数の独立したスレッドを起動すること、または異なるポートでプロキシサーバーの複数のインスタンスを起動することです。 念のため、マルチスレッドコードを削除せず、単にコメントアウトしたため、コメントを外して、必要に応じて通常のマルチスレッドバージョンを使用できます。
- プロキシサーバーは、データベースの行数を監視し、必要に応じて新しい行を追加する方法を知りません(正直に言うと、実装するのが面倒でした)。したがって、最初にゼロ行で満たされたファイルを作成する必要があります。 行数はフォーラム(より正確には、フォーラム内のトピックの数)に依存します。 問題を回避するには、すぐに十分なマージンを持ってファイルを作成することをお勧めします。
- プロキシサーバーでは、phpBBモード「単一メッセージの表示」( viewpost.phpスクリプト)のサポートもあります。 単一の投稿を表示する場合、データベース内のトピックにアクセスする時間は更新されません。 この場合、表示しているメッセージの前の未読メッセージを見逃すことは簡単です。 誰かがこれを間違っていると考える場合、 ifを削除することでコードを簡単に修正できます。
さて、誰かがこのトラブルをすべて怖がらなかった場合、サーバー自体は
ここからダウンロードでき
ます (アーカイブ、5 Kb)。 キットには、公式フォーラムTotal Commanderの一連のルールがあります。これは、私の実験の基礎として採用したもので、基本的にこのすべてのボディアジーが始まりました。