My Codeforces Journal は、 Codeforces ユーザーが解決した問題を追跡するのに役立つ Chrome 拡張機能です。クリックするだけで、拡張機能は現在の問題の詳細を、ユーザーが接続している Google スプレッドシートに保存します。これにより、時間の経過とともに解決された問題の個人的なログを維持することが容易になります。
このクロム拡張に貢献したいですか?このリポジトリに移動します:My Codeforces Journal Development
ワンクリックストレージ: 解決した現在の Codeforces 問題をワンクリックで保存します。
スプレッドシートの統合: 独自の Google スプレッドシートをリンクして、問題を適切な形式で保存および整理します。
キャプチャされた問題の詳細: 拡張機能には、問題の URL、問題の名前、問題の評価などの重要な情報が保存されます。
この YouTube ビデオをご覧ください: My Codeforces Journal の使用を開始する方法
拡張機能を使用する前に、次のものが揃っていることを確認してください。
問題が保存される Google スプレッドシート。
Codeforces Journal Chrome 拡張機能がインストールされ、スプレッドシートへのアクセスが許可されています。
この最後にある「一般的なエラー」セクションを必ずお読みください。
次のリンクからdist
フォルダーをダウンロードします: My Codeforces Journal
Chrome を開き、 chrome://extensions/
に移動します。
右上隅で開発者モードを有効にします。
「Load unpacked」をクリックし、 dist
フォルダーが保存されているフォルダーを選択します。
拡張機能が拡張機能ページに表示されるようになります。
簡単に使用できるように、拡張機能をツールバーにピン留めします。
新しい Google スプレッドシートを作成します。
スプレッドシートに任意の名前を付けます。
「拡張機能」メニューをクリックし、「App Script」をクリックします。
「無題」をクリックし、この App Script ファイルの名前をスプレッドシートの名前と一致するように変更します。
以下のコードをコピーして App Script エディターに貼り付け、 cmd + S
/ ctrl + S
キーを押して保存します。
右上の「デプロイ」ボタンをクリックし、「新規デプロイ」を選択します。
選択した説明を追加します (スプレッドシートの名前と同じでも構いません)。
「アクセスできる人」を「誰でも」に設定します。
「デプロイ」をクリックし、App Scriptを承認します。
[承認] をクリックして、スプレッドシートの作成に使用した Google アカウントを選択すると、「Google はこのアプリを検証していません」というメッセージが表示されます。
下部にある「詳細設定」をクリックし、
表示されている AppScript プロジェクトの名前をクリックし、[許可] をクリックします。
プロジェクトが適切に承認されていることを確認するために、AppScript プロジェクトを再デプロイします。
スクリプト URL (これは AppScript URL です) をコピーし、後で拡張機能で使用できるように保存します。
もう一度「デプロイ」ボタンをクリックします
「デプロイメントの管理」を選択すると、モーダルが表示されます
「編集」ボタン (ペンのアイコン) をクリックすると、下部の「デプロイ」ボタンがアクティブになります。
「デプロイ」をクリックします
認証に何らかのエラーが存在する場合は、再度認証ボタンが表示されるか、スクリプトの URL をコピーするように表示されます。
function doPost(e) { try { varsheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0]; // 受信リクエストデータ var data を解析します。 { data = JSON.parse(e.postData.contents); を試してください。 catch (parseError) { return ContentService.createTextOutput('{"ステータス":"エラー","メッセージ":"無効な JSON 形式です。"}').setMimeType(ContentService.MimeType.TEXT); } // リクエストが既存の問題をチェックするものであるかどうかを確認します if (data.action === "checkProblem") { const questionNameColumn =sheet .getRange("B2:B" + Sheet.getLastRow()) .getValues() 。フラット(); const 問題存在 = 問題名列.includes(データ.問題名); return ContentService.createTextOutput(JSON.stringify({ ステータス: "成功", 存在:問題存在 })).setMimeType(ContentService.MimeType.JSON); } // (既存の 'initialize' および 'add問題' ロジックはここにあります) if (data.action === "initialize") { var headers = ["評価", "問題", "ステータス", "備考", "日付」、「テイクアウト」、「トピックス」]; if (sheet.getLastRow() === 0 ||sheet.getRange("A1").getValue() === "") { // 初期化ロジックは同じsheet.getRange("A1:G1")のままです。マージ(); Sheet.getRange("A1").setValue("Codeforces シート"); sheet.getRange("A1").setFontSize(13).sethorizontalAlignment("center").setBackground("#ffd966"); sheet.getRange("A2:G2").setValues([ヘッダー]); Sheet.getRange("A2:G2").setFontSize(12).sethorizontalAlignment("center").setBackground("#93c47d"); sheet.setColumnWidth(1, 75); sheet.setColumnWidth(2, 185); sheet.setColumnWidth(3, 155); sheet.setColumnWidth(4, 290); sheet.setColumnWidth(5, 80); sheet.setColumnWidth(6, 530); sheet.setColumnWidth(7, 190); Sheet.getRange("A2:G1000").setVerticalAlignment("middle"); sheet.getRange("C2:C1000").setWrap(true); sheet.getRange("D2:D1000").setWrap(true); sheet.getRange("F2:F1000").setWrap(true); sheet.getRange("G2:G1000").setWrap(true); Sheet.getRange("A2:A1000").sethorizontalAlignment("center"); sheet.getRange("B2:B1000").sethorizontalAlignment("center"); sheet.getRange("E2:E1000").sethorizontalAlignment("center"); sheet.getRange("G2:G1000").sethorizontalAlignment("center"); var newDate = 新しい日付(); sheet.getRange("E3:E1000").setNumberFormat("dd-mmm-yyyy"); シート.insertRowBefore(3); Sheet .getRange("A3:G3") .setValues([ [9999, "問題9999Z", "解決済み", "直感を実装できませんでした", newDate, "再帰がどのように機能するかを理解しました", "再帰、DP、グラフ" ]、]); return ContentService.createTextOutput( '{"status":"success","message":"書式設定、カスタム列幅、行の追加でヘッダーが初期化されました。"}' ).setMimeType(ContentService.MimeType.TEXT); } else { return ContentService.createTextOutput('{"ステータス":"成功","メッセージ":"ヘッダーはすでに存在します。"}').setMimeType(ContentService.MimeType.TEXT); } } else if (data.action === "add問題") { try { const newRow = [data.problemRating, data.problemName, data.problemStatus, data.remarks, data.dateSolved, data.takeaways, data.problemTopics] ; const lastRow = シート.getLastRow() + 1; シート.appendRow(newRow); const 問題名セル =sheet.getRange(lastRow, 2); if (data.problemUrl) { questionNameCell.setValue(data.problemName).setFormula(`=HYPERLINK("${data.problemUrl}", "${data.problemName}")`); return ContentService.createTextOutput('{"ステータス":"成功","メッセージ":"問題のデータがハイパーリンクとともに追加されました。"}').setMimeType( ContentService.MimeType.JSON ); catch (addError) { return ContentService.createTextOutput('{"ステータス":"エラー","メッセージ":"問題データの追加に失敗しました。"}').setMimeType( ContentService.MimeType.TEXT ); catch (エラー) { return ContentService.createTextOutput('{"ステータス":"エラー","メッセージ":"' + error.message + '"}').setMimeType(ContentService.MimeType.TEXT); }}
Codeforces の問題ページを開きます。
問題を解決したら、My Codeforces Journal 拡張機能アイコンをクリックし、[問題の追加] をクリックします。
フォームに記入し、「送信」を押してください。
問題の詳細は、接続されたスプレッドシートに自動的に保存されます。
この拡張機能には次の権限が必要です。
アクティブなタブ: 問題を保存するときに現在のタブの URL にアクセスします。
ストレージ: 接続されたスプレッドシートの詳細を保存します。
スクリプト: JavaScript を実行するため
原因: これは通常、存在しない Codeforces ID が送信された場合に発生します。
解決策: ID を再確認し、それが正しいことを確認します。
原因: このエラーは通常、指定された AppScript URL が正しくないことを意味します。
解決策: URL を確認し、正しい AppScript URL を使用します。
追加のヒント: このエラーは、AppScript プロジェクトが適切に承認されていない場合にも表示されることがあります。適切な認証を確保するには:
スプレッドシートのセットアップ中に、AppScript プロジェクトを 2 回デプロイします。 2 番目のデプロイメントは、AppScript プロジェクトが完全に承認されていることを確認するのに役立ちます。
原因: これは、追加しようとしている問題が、Codeforces での過去 40 件の送信以内に解決されていない場合に発生します。
解決策: 最近問題を解決したことを確認してください。そうでない場合は、スプレッドシートに追加する前に Codeforces で試してください。