はてなキーワード: Matchとは
はてなブックマークの増田一覧の、さらに「すべて」(1 user)をチェックしている希有な人向けのユーザースクリプトを公開します。
https://b.hatena.ne.jp/site/anond.hatelabo.jp/?sort=eid
// ==UserScript== // @name Hatena Bookmark Anond Filter // @namespace https://b.hatena.ne.jp/site/anond.hatelabo.jp/ // @description はてなブックマークの『はてな匿名ダイアリー』の記事のうち、指定したNGワードが含まれる投稿を非表示にします。 // @match https://b.hatena.ne.jp/site/anond.hatelabo.jp/* // @grant none // @version 2.0.2026.01.17.0009 // ==/UserScript== (function(){ const SCRIPTID = 'HatenaBookmarkAnondFilter'; console.time(SCRIPTID); const CLASSNAME = 'filtered';/*フィルタ該当要素*/ const CHECKED = 'checked';/*二重チェック回避フラグ*/ const ONCE = 1, AP = 2, INTERVAL = 3;/*適用タイミング*/ const NGWORDS = {/* 合計100ポイントで非表示判定(ただし1つの記事内で同じワードが複数使われても1度しか加算しない) */ '100': [/*即NG確定ワード*/ 'dorawii', 'あおやまちゃん', 'ボスマン', 'MNK', '電気通信大学たいてい', 'なんぴょん', 'れめくん', 'リュックサック野郎', 'boushi_inst', 'hakaikami', 'Rekyu', 'iloveootaku_2',/*電気通信大学たいてい鉄道研究会れめくん(頻出)*/ /*A-G*/'a9w8ru6fqyxqfv9', 'admirail_togo', 'akibakko6348', 'alf1974al', 'amatukiseiru', 'anapgoeson', 'aoi_mizuho', 'asapgoeson', 'asupgoeson', 'b6jbpsji91ieigt', 'bmi22yo', 'boushi_ob', 'buscholarx', 'bw0531', 'circlecavok', 'disney1007cla', 'dora22sibuya', 'donkotrain', 'ecotosk', 'factomodachi', 'fft_dareka', 'gmhtcyznf_abc', 'goesonanap', 'gyudon_honmono', /*H-N*/'h13_yokohama', 'h2twi', 'hamaishogo1111', 'haru_mofumoffu', 'hermitv8', 'hinolovelove', 'hnmk0127_03', 'inaken17_', 'inte235dy', 'ixtabes', 'jamcombatge', 'kawachiasukanew', 'kaoru_ai1991', 'keio9730F', 'kiha2228', 'koreanlabsfc', 'koyounoyooko', 'kqlex1500', 'kurakamasan', 'kurotamaxxx', 'kt_ruma_1372', 'lightningreen77', 'matya_uec', 'minamihinawot', 'minori0151', 'monkichi_22', 'mugen_08i', 'mukoroku651', 'nakano6409', 'nanpyong', 'new_oer', 'nimouec', 'NoName_thUFO', 'norannnde', /*O-U*/'oreizmmiporin', 'orenotanoshimi', 'osaka_sirokichi', 'papepoco', 'pasotokon', 'pm95uq', 'reme_kun', 'ruin_2002', 's03_amurtk2731', 'sacchan03110319', 'seisu_bot', 'senanana_cos', 'shinano_115', 'shineleaf1372', 'shop_bullet', 'shurimpy', 'soroisoroi', 'sui_pm95uq', 'sweidan821858', 'taiyaki_level2', 'takao_straight5', 'taking0000', 'tarotaromusic1', 'tc201_501', 'tocarbarn', 'toshikimiyazaki', 'train_magician', 'tx9y2cpwdz27255', 'u2fap5u4zw57811', 'uec15take', 'uecrail', /*V-Z_0-9*/'vampire_mio', 'vbdmnwefknmxsdm', 'vp20th', 'wafue', 'wakasato_', 'walkingniwatori', 'wataameexpress', 'ya4975349616894', 'ymbk_arisa', 'yms_uec16', 'yuuya_1104_uec', '__________ob', '_chocorail_', '_doitforthewin_', '_toeshin', '_unigmo', '100mph_no_yuuki', '2969364x', '2rtkvn34il2783', '86lilxw1', /*tadaup.jp*/'1dOaKWk3.jpeg', '1sL2VBZ5.jpeg', '1uNK2iEP.jpeg', 'CBUHadpD.jpeg', 'CgJlF4Wr.jpeg', 'CGTtm0Ev.jpeg', 'CIxj8clS.jpeg', 'CqbERPdQ.jpeg', 'CTZsA2wM.jpeg', 'CWY2m7rS.jpeg', 'CZVCEgd1.jpeg', 'テクウヨ', '自己放尿', ' ーーーーーーーー', 'https://anond.hatelabo.jp/20260107144223',/*AI問答貼り付け増田*/ ], '90': [/*ほぼNGだが確定ワードが必要*/ 'https://megalodon.jp/', ], '10': [/*ほぼNGの確定ワード*/ '電気通信大学', '電通大', '駿河台大学', '学生課', '教務課', '鉄道研究会', '鉄研', '通勤特快', '不正乗車', '性慾', '穢い', 'エッタ', 'キセル', 'uec', ], }; const sites = { 'prefix': [ ['selector', '(modifier)', '(css)', '(REPEAT)'], ], 'https://b.hatena.ne.jp/site/anond.hatelabo.jp/': [ ['section.entrylist-unit li.js-keyboard-selectable-item', li => {li.querySelector('li.entrylist-contents-category > a').textContent = li.dataset.matches}, `.${CLASSNAME}{display: none;}`, AP], ], }; const rules = sites[Object.keys(sites).find(prefix => location.href.startsWith(prefix))]; if(rules === undefined) return console.log(SCRIPTID, 'Not found any sites.'); const scores = Object.keys(NGWORDS).map(Number).reverse();/*数値インデックス順に取り出されたkeysを逆順にして100から並べ直す*/ const filter = function(selector, modifier){/*各要素に対してNGワード判定して、該当したら追加でmodifierも適用する*/ document.querySelectorAll(selector).forEach(e => { if(e.dataset[CHECKED]) return; e.dataset[CHECKED] = 'true'; const text = e.textContent.toLowerCase(); let total = 0, matches = []; for(const score of scores){ for(const word of NGWORDS[String(score)]){ if(text.includes(word.toLowerCase())){ total += score; matches.push(word); if(total >= 100){ e.classList.add(CLASSNAME); e.dataset.matches = matches.join(', '); if(modifier) modifier(e); return; } } } } }); }; /* ONCE(一括適用) */ rules.forEach(rule => { const [selector, modifier, css] = rule; console.log(SCRIPTID, 'ONCE:', selector); filter(selector, modifier); if(css){ const style = document.createElement('style'); style.dataset.script = SCRIPTID; style.type = 'text/css'; style.textContent = css; document.head.appendChild(style); } }); /* AP(AutoPagerize) */ rules.filter(rule => rule[3] === AP).forEach(rule => { const [selector, modifier] = rule; document.addEventListener('GM_AutoPagerizeNextPageLoaded', e => { console.log(SCRIPTID, 'AP:', selector); filter(selector, modifier); }); }); /* INTERVAL */ rules.filter(rule => rule[3] === INTERVAL).forEach(rule => { const [selector, modifier] = rule; setInterval(function(){ console.log(SCRIPTID, 'INTERVAL:', selector); filter(selector, modifier); }, 1000); }); console.timeEnd(SCRIPTID); })();
/* Hatena Bookmark Anond Filter */ .filtered{ display: block !important;/*上書き*/ opacity: .25 !important; } .filtered:hover{ opacity: .75 !important; } .filtered li.entrylist-contents-category{ background: red !important; font-weight: bold; }
検索用: はてなブックマーク はてブ はてな匿名ダイアリー 増田 スパム キーワード NGワード フィルター ミュート 非表示 削除 隠す ブロック ユーザースクリプト ユーザースタイル hatena bookmark anond spam keywords ngwords filter mute hide hidden display none block userscript JavaScript js css style
勝手ながら
// ==UserScript== // @name はてな匿名ダイアリー特定ワード投稿非表示 // @namespace http://tampermonkey.net/ // @version 0.2 // @description 本文に「dorawii」または「megalodon」が含まれる投稿を非表示にする // @match https://anond.hatelabo.jp/* // @grant none // ==/UserScript== (function() { 'use strict'; const POST_SELECTOR = '.body .section'; // 非表示にしたいキーワードの配列 const KEYWORDS = ['dorawii','megalodon','抽象数学','動画にしてみた','れめくん','自己放尿']; const posts = document.querySelectorAll(POST_SELECTOR); posts.forEach(post => { const textContent = post.textContent || post.innerText; // いずれかのキーワードが含まれているかチェック if (KEYWORDS.some(keyword => textContent.includes(keyword))) { post.style.display = 'none'; } }); })();
anond:20251114170150 と連動させることを意図しています。
// ==UserScript== // @name meaningless sale dayo // @version 1.0 // @match https://www.amazon.co.jp/blackfriday* // ==/UserScript== (function () { 'use strict'; alert('意味のないセールだよ'); })();
// ==UserScript==
// @namespace http://tampermonkey.net/
// @version 0.2
// @description 本文に「dorawii」または「megalodon」が含まれる投稿を非表示にする
// @match https://anond.hatelabo.jp/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
const POST_SELECTOR = '.body .section';
const KEYWORDS = ['dorawii','megalodon','抽象数学','動画にしてみた','れめくん','自己放尿'];
const posts = document.querySelectorAll(POST_SELECTOR);
posts.forEach(post => {
const textContent = post.textContent || post.innerText;
if (KEYWORDS.some(keyword => textContent.includes(keyword))) {
post.style.display = 'none';
}
});
})();
// ==UserScript==
// @namespace http://tampermonkey.net/
// @version 0.2
// @description 本文に「dorawii」または「megalodon」が含まれる投稿を非表示にする
// @match https://anond.hatelabo.jp/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
const POST_SELECTOR = '.body .section';
const KEYWORDS = ['dorawii', 'megalodon'];
const posts = document.querySelectorAll(POST_SELECTOR);
posts.forEach(post => {
const textContent = post.textContent || post.innerText;
if (KEYWORDS.some(keyword => textContent.includes(keyword))) {
post.style.display = 'none';
}
});
})();
これはdorawiiもしくはmegalodonを含む投稿を非表示にするけど、
const KEYWORDS = ['dorawii', 'megalodon'];の部分を変えたり追加すれば好きな言葉に変えられるよ
dorawiiがタイトルに「dorawii」と入れなくなったので、本文にdorawiiがある投稿も非表示にする必要が出てきました。
ただAIに聞いたんだけど、CSSでは無理でJavaScriptならできると言われました。
そのJavaScriptを下に載せます。
// ==UserScript==
// @namespace http://tampermonkey.net/
// @version 0.1
// @description 本文に「dorawii」が含まれる投稿を非表示にする
// @match https://anond.hatelabo.jp/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// はてな匿名ダイアリーの一般的な投稿要素のクラスを仮定しています
const POST_SELECTOR = '.body .section'; // 例: .bodyクラスの子孫の.section要素
// すべての投稿要素を取得
const posts = document.querySelectorAll(POST_SELECTOR);
posts.forEach(post => {
// 投稿内の本文が含まれる要素(ここでは投稿全体を本文と見なす)のテキストを取得
const textContent = post.textContent || post.innerText;
if (textContent.includes(KEYWORD)) {
post.style.display = 'none';
}
});
})();
gamefaqs.gamespot.com/boards/178921-dragon-ball-z-dokkan-battle/81050772
gamefaqs.gamespot.com/boards/178921-dragon-ball-z-dokkan-battle/81050774
gamefaqs.gamespot.com/boards/178921-dragon-ball-z-dokkan-battle/81050772?Match-Master
gamefaqs.gamespot.com/boards/178921-dragon-ball-z-dokkan-battle/81050774?Match-Master
ストZERO3の「尿を便座におしつけ~る」くらいにモヤモヤしてた
答え
tHis is gOnNa bE a MaTcH TO REmember!
ここmatchがどうして聞き取れなくて「This is gonna be a must to remember! 」(この戦いは記憶に残るマストなものになる!)かと思ってしまったw
なんか安心したわ
ramadan.mya.org.au/today-boost/posts/legit-ways-to-get-free-match-masters-free-gifts-boosters-coins-link-in-october-2025
ramadan.mya.org.au/today-boost/posts/daily-rewards-match-masters-free-gifts-boosters-coins-link-in-october-2025
ramadan.mya.org.au/today-boost/posts/rewards-match-masters-unveils-daily-free-gifts-boosters-and-coins-link-updated-in-october-2025
ramadan.mya.org.au/today-boost/posts/daily-rewards-cash-app-money-free-codes-everything-you-need-to-know-in-october-2025
ramadan.mya.org.au/today-boost/posts/daily-earning-cash-app-money-free-codes-rewards-ultimate-beginners-guide-in-october-2025
ramadan.mya.org.au/today-boost/posts/legit-ways-to-get-free-cash-app-money-earn-codes-daily-rewards-in-october-2025
ramadan.mya.org.au/rewards-today/posts/daily-rewards-match-masters-free-gifts-unlimited-coins-links-september-2025
ramadan.mya.org.au/rewards-today/posts/today-match-masters-free-gifts-boosters-and-coins-links-tips-tricks-2025
www.wortfm.org/calendar/updated-today-match-masters-unveils-free-gifts-boosters-and-coins-link-2025/
www.wortfm.org/calendar/today-match-masters-free-gifts-boosters-and-coins-links-tips-tricks-2025/
www.wortfm.org/calendar/daily-rewards-match-masters-free-gifts-boosters-coins-links-tips-tricks-2025/
というわけでお漏らし文学をChatGPTに調べてもらった
Last time I paid 1€ to take a piss,
I walked into the Sanifair, looked around,
and just… left.
It was so disgusting I decided to go outside and search for a bush instead.
— Reddit / r/AskAGerman
「1ユーロ払ってトイレに入ったんだけど、あまりに汚すぎてそのまま出てきた。結局、外の藪を探すことにした。」
ドイツ人ですら「お金払って藪で用を足す方がマシ」と言ってしまう悲哀。
URL:れでぃっと r/AskAGerman
I used to squat when using public toilets.
Then one day, I slipped.
That day, something inside me died… and something outside me was never clean again.
— れでぃっと / r/AskEurope
でもある日、足が滑った。
その日、僕の中の何かが死んだ… そして僕の外側も、二度と綺麗にはならなかった。」
もう「しゃがむ」という選択肢すら許されない。
In Belgium, there’s an unwritten rule.
You hand the bar owner a euro,
he silently hands you the bathroom key.
you find a dark corner of the street instead.
— Blog post “The art of le pee in Belgium”
バーの店主に1ユーロ渡すと、無言でトイレの鍵を渡してくれる。
観光都市ブリュッセルでも、路上で立ち尽くす影が絶えない理由。
URL:saintfacetious.com
All cafés were closed, all public toilets locked.
I stumbled along the riverbank,
In the end, the Seine saw everything.
— れでぃっと / r/Paris
「深夜1時、セーヌ川沿い。
ワインと後悔で酔った体を引きずりながら歩き、
パリの夜は美しく、そして容赦ない。
観光客だけでなく、現地の人すらこうなることがある。
I was in Bilbao, desperate to pee before the match.
I ran into one of those self-cleaning toilets…
and then the cleaning cycle started
僕は全身びしょ濡れになって出てきた。」
水と泡まみれで出てきたマンチェスター・ユナイテッドファン。
In Amsterdam, we had these half-open urinals called ‘pee curls.’
They were meant to stop men from peeing in the canals.
Now they’re disappearing…
and the canals smell like history again.
「アムステルダムには、半分だけ壁のある露天トイレ『pee curl』があった。
でも今はそのpee curlも減り、
I have MS.
Since the public toilets closed,
Last month, I didn’t make it home in time.
I cried, then laughed, then stayed inside for a week.
— The Guardian 読者投稿
「私は多発性硬化症です。
先月、家に帰る前に間に合わなくて…
URL:The Guardian
まあまあだな、また探す
____
https://profile.hatena.ne.jp/dorawii_bukuma/
はてなのサイト側で読み込まれているはずのrksトークンを生成する関数を直接叩く方法がどうしても分からず結局request処理を自分で書く方法ではなく自動でUI側の保存ボタンをクリックするという無難な方向に落ち着いた。
最初から後者の方法をとっていればもっと全然早く作れたのにというは所詮言い訳か。
とにかくスクリプトを公開しておく。
@echo off
cd /d "C:\Users\user\Documents\jsscript"
:: Nodeサーバーを別ウィンドウで起動
start /min "" node run-batch-server.js
:: Pythonサーバーを別ウィンドウで起動(hatenaserver配下)
start cmd /k "" python hatenaserver\server.py
{
"username": "",
"password": ""
}from flask import Flask, request, jsonify
import json
import os
from hatena_client import HatenaClient
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
config_path = os.path.join(os.path.dirname(__file__), 'config.json')
with open(config_path, encoding='utf-8') as f:
config = json.load(f)
@app.route('/bookmark', methods=['POST'])
def handle_bookmark():
data = request.json
url = data.get("url")
if not url:
return jsonify({"error": "Missing URL"}), 400
client = HatenaClient(config["username"], config["password"])
client.start_browser()
if not client.login():
client.quit()
return jsonify({"error": "Login failed"}), 403
success = client.add_bookmark(url)
client.quit()
return jsonify({"status": "ok" if success else "fail"})
if __name__ == "__main__":
app.run(port=12347)
// ==UserScript==
// @name 自動セルクマ送信
// @namespace tampermonkey.net/
// @version 2025-08-07
// @description try to take over the world!
// @author You
// @match anond.hatelabo.jp/*
// @grant none
// ==/UserScript==
(function () {
'use strict';
const url = location.href;
if (!/^https:\/\/anond\.hatelabo\.jp\/\d+$/.test(url)) return;
const editLink = document.querySelector('a.edit');
if (!editLink) {
// 既に編集ページなので処理をスキップ
console.log('編集リンクが存在するため、スクリプトを終了します。');
return;
}
fetch('localhost:12347/bookmark', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ url: url })
}).then(r => console.log("通知成功")).catch(e => console.error("通知失敗", e));
})();
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 https://anond.hatelabo.jp/20250821192753# -----BEGIN PGP SIGNATURE----- iHUEARYKAB0WIQTEe8eLwpVRSViDKR5wMdsubs4+SAUCaKb0qwAKCRBwMdsubs4+ SHfiAQDcXmTHBaZ5Zzr1KI/OxZ0xl69oevOdy1FXJYwYvsmo5AD/ZPtZiO1JgTDj m+27iymlkdzIXOIGWfC82UTr1mJ7EwU= =YoV+ -----END PGP SIGNATURE-----
木古 「きこ」ではなくて「きふる」って読むのね そしてTwitterアカウントのkipple… ギップルなら知ってるけど?と思って検索したら
アンドロイドは電気羊の夢を見るか?由来か~~
kipple
Popularized in Philip K. Dick's novel Do Androids Dream of Electric Sheep? (1968); originally the name of a SF fanzine, from the humorous interpretation of Kipling as a participle.[1]
kipple (uncountable)
(colloquial) useless items; junk; clutter
Synonym: crapola
2008 [1968], Philip K. Dick, Do Androids Dream of Electric Sheep?, Ballantine Books, →ISBN, page 65:
“Kipple is useless objects, like junk mail or match folders after you use the last match or gum wrappers or yesterday's homeopape. When nobody's around, kipple reproduces itself. For instance, if you go to bed leaving any kipple around appartment, when you wake up in the next morning there's twice as much of it. It always gets more and more.”
一度投稿したうえで別タブを開いてプログラム的(fetch)に送信してその別タブが閉じられる仕組み。
// ==UserScript==
// @name PGP未署名検出と別タブ自動編集
// @namespace http://tampermonkey.net/
// @version 1.0
// @description PGP署名がない投稿を自動編集ページへ誘導
// @match https://anond.hatelabo.jp/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM.openInTab
// ==/UserScript==
(function () {
'use strict';
const body = document.getElementById('entry-page');
if (!body) return;
const titleText = document.title;
if (!titleText.includes('dorawii')) return;
const pgpRegex = /BEGIN.*PGP(?: SIGNED MESSAGE| SIGNATURE)?/;
const preElements = document.querySelectorAll('div.body pre');
let hasPgpSignature = false;
for (const pre of preElements) {
if (pgpRegex.test(pre.textContent)) {
hasPgpSignature = true;
break;
}
}
if (hasPgpSignature) return;
const editLink = document.querySelector('a.edit');
const childTab = GM.openInTab(editLink.href, { active: false, insert: true, setParent: true });
})();
// ==UserScript==
// @name 編集ページ処理と自動送信・閉じ
// @namespace http://tampermonkey.net/
// @version 1.0
// @description 編集ページで署名処理と送信、タブ自動閉じ
// @match https://anond.hatelabo.jp/dorawii_31/edit?id=*
// @grant GM_getValue
// @grant GM_xmlhttpRequest
// @grant GM_setClipboard
// @grant GM_notification
// @connect localhost
// ==/UserScript==
(async function () {
'use strict';
const shouldRun = await GM_getValue('open-tab-for-edit', '0');
const textareaId = 'text-body';
const textarea = document.getElementById(textareaId);
if (!textarea) return;
const content = textarea.value;
const pgpSignatureRegex = /-----BEGIN PGP SIGNED MESSAGE-----[\s\S]+?-----BEGIN PGP SIGNATURE-----[\s\S]+?-----END PGP SIGNATURE-----/;
if (pgpSignatureRegex.test(content)) {
console.log('[PGPスクリプト] 署名が検出されたためそのまま送信します');
return;
}
const httpRequest = (url, data) => {
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: 'POST',
url: url,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: `value=${encodeURIComponent(data)}`,
onload: function (response) {
resolve(response.responseText);
},
onerror: function (error) {
reject(error);
}
});
});
};
// textarea の値を取得
// 1. 現在のページのURLからURLオブジェクトを作成
const currentUrl = new URL(window.location.href);
// 2. ベースとなる部分 (例: "https://anond.hatelabo.jp") を取得
const origin = currentUrl.origin;
// 3. 'id' パラメータの値 (例: "20250610184705") を取得
const idValue = currentUrl.searchParams.get('id');
// 4. ベース部分とIDを結合して、目的のURL文字列を生成
// idValueが取得できた場合のみ実行する
let newUrl = null;
if (idValue) {
newUrl = `${origin}/${idValue}`;
}
// 5. 生成されたURLを変数に代入し、コンソールに出力して確認
console.log(newUrl);
const valueToSend = newUrl;
try {
const signatureText = await httpRequest('http://localhost:12345/run-batch', valueToSend);
console.log('バッチ応答:', signatureText);
if (!signatureText.includes('BEGIN PGP SIGNED MESSAGE')) {
alert('PGP署名がクリップボードに見つかりませんでした。');
return;
}
const newText = content.replace(/\s*$/, '') + '\n' + signatureText + '\n';
textarea.value = newText;
console.log('[PGPスクリプト] 署名を貼り付けました。送信を再開します。');
const form = document.forms.edit;
const newForm = form.cloneNode(true);
form.replaceWith(newForm);
newForm.addEventListener('submit', async (e) => {
e.preventDefault(); // HTML標準のsubmitをキャンセル
const bodyText = textarea?.value || '';
// reCAPTCHA トークンの取得
const recaptchaToken = await new Promise((resolve) => {
grecaptcha.enterprise.ready(() => {
grecaptcha.enterprise.execute('hoge', { action: 'EDIT' })
.then(resolve);
});
});
// POSTするデータの構築
const formData = new FormData(newForm);
formData.set('body', bodyText);
formData.set('recaptcha_token', recaptchaToken);
formData.set('edit', '1');
try {
const response = await fetch(newForm.action, {
method: 'POST',
body: formData,
credentials: 'same-origin'
});
if (response.ok) {
console.log('送信成功');
window.close();
} else {
console.error('送信失敗', response.status);
}
} catch (err) {
console.error('送信中にエラーが発生', err);
}
});
// プログラム的に送信トリガー
newForm.dispatchEvent(new Event('submit', { bubbles: true }));
} catch (e) {
console.error('バッチ呼び出し失敗:', e);
}
})();
const http = require('http'); const { exec } = require('child_process'); const querystring = require('querystring'); const server = http.createServer((req, res) => { if (req.method === 'GET' && req.url === '/ping') { res.writeHead(200); res.end('pong'); } else if (req.method === 'POST' && req.url === '/run-batch') { let body = ''; req.on('data', chunk => { body += chunk.toString(); }); req.on('end', () => { const parsed = querystring.parse(body); const value = parsed.value || 'default'; // 値を引数としてバッチに渡す exec(`C:\\Users\\hoge\\Desktop\\makesign.bat "${value}"`, { encoding: 'utf8' }, (err, stdout, stderr) => { if (err) { res.writeHead(500); res.end('Error executing batch: ' + stderr); } else { res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' }); res.end(stdout.trim()); } }); }); } else { res.writeHead(404); res.end('Not found'); } }); server.listen(12345, () => { console.log('Batch server running at http://localhost:12345/'); });
@echo off setlocal enabledelayedexpansion :: 署名するファイル名 set "infile=%~1" set outfile=%TEMP%\pgp_output.asc :: 以前の出力があれば削除 if exist "%outfile%" del "%outfile%" :signloop :: AutoHotkeyでパスフレーズ入力(gpgがパスワード要求するダイアログが出た場合に備える) start "" /b "C:\Users\hoge\Documents\AutoHotkey\autopass.ahk" :: PGPクリア署名を作成 echo %infile% | gpg --yes --clearsign --output "%outfile%" :: 署名が成功していればループを抜ける if exist "%outfile%" ( goto postprocess ) else ( timeout /t 1 > nul goto signloop ) :postprocess powershell -nologo -command ^ "$header = '>|'; $footer = '|<'; $body = Get-Content '%outfile%' -Raw; Write-Output ($header + \"`r`n\" + $body + $footer)" powershell -nologo -command ^ "$header = '>|'; $footer = '|<'; $body = Get-Content 'signed.asc' -Raw; Set-Clipboard -Value ($header + \"`r`n\" + $body + $footer)" endlocal exit /b
#Persistent #SingleInstance ignore SetTitleMatchMode, 2 WinWaitActive, pinentry SendInput password Sleep 100 SendInput {Enter} ExitApp
動けばいいという考えで作っているので余分なコードも含んでいるかもしれない。
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 https://anond.hatelabo.jp/20250613185036 -----BEGIN PGP SIGNATURE----- iHUEARYKAB0WIQTEe8eLwpVRSViDKR5wMdsubs4+SAUCaEv1FQAKCRBwMdsubs4+ SHHkAQDUOLgBcdji2T6MJ7h/vlMdFfGlWAzNdXijjE1gIuEPywEAiMNMZqhrMmtl c7UqRuggNJ/UTa5xTIcKp622+7jJQQg= =Lgkl -----END PGP SIGNATURE-----
ようやく(ほぼ)すべてが自動化された。
あとはローカルサーバーの起動をスタートアップに設定する(方法をAIに聞いて指示に従う)だけの消化試合。
署名時要求してくるパスワードを自動入力するahkファイルはドキュメントのAutoHotkey配下に置いた。
バッチファイル(make.sign.bat)はデスクトップに置いた。
#Persistent #SingleInstance ignore SetTitleMatchMode, 2 WinWaitActive, pinentry SendInput お前のパスワード Sleep 100 SendInput {Enter} ExitApp
// run-batch-server.js const http = require('http'); const { exec } = require('child_process'); const server = http.createServer((req, res) => { if (req.url === '/ping') { res.writeHead(200); res.end('pong'); } else if (req.url === '/run-batch') { exec('C:\\Users\\you\\Desktop\\makesign.bat', (err) => { res.writeHead(200); res.end(err ? 'Error' : 'OK'); }) ; } else { res.writeHead(404); res.end('Not found'); } }); server.listen(12345, () => { console.log('Batch server running at http://localhost:12345/'); });
@echo off setlocal enabledelayedexpansion :: ミリ秒単位のUTC時刻を取得 for /f %%a in ('powershell -nologo -command "[int64]::Parse((Get-Date).ToUniversalTime().ToString('yyyyMMddHHmmssfff'))"') do set timestamp=%%a :: 署名するファイル名 set infile=%TEMP%\pgp_input.txt set outfile=%TEMP%\pgp_output.asc :: 以前の出力があれば削除 if exist "%outfile%" del "%outfile%" :: タイムスタンプを原文として保存 echo %timestamp% > "%infile%" :signloop :: AutoHotkeyでパスフレーズ入力(gpgがパスワード要求するダイアログが出た場合に備える) start "" /b "C:\Users\infini\Documents\AutoHotkey\autopass.ahk" :: PGPクリア署名を作成 gpg --yes --clearsign --output "%outfile%" "%infile%" :: 署名が成功していればループを抜ける if exist "%outfile%" ( echo [INFO] 署名成功 goto postprocess ) else ( echo [WARN] 署名失敗、再試行します… timeout /t 1 > nul goto signloop ) :postprocess :: PowerShellで余計な改行なしに |< をつけてクリップボードにコピー powershell -nologo -command ^ "$header = '>|'; $footer = '|<'; $body = Get-Content '%outfile%' -Raw; Set-Clipboard -Value ($header + \"`r`n\" + $body + $footer)" echo Done. signed.asc created and clipboard updated (no extra blank line). endlocal exit /b
// ==UserScript== // @name PGP署名自動付加スクリプト(GM_xmlhttpRequest版) // @namespace http://tampermonkey.net/ // @version 1.0 // @description 投稿前にPGP署名を付けてから送信(fetch未使用) // @match https://anond.hatelabo.jp/dorawii_31/edit* // @grant GM_xmlhttpRequest // @grant GM_setClipboard // @grant GM_notification // / @connect localhost // ==/UserScript== (function () { 'use strict'; const submitId = 'submit-button'; const textareaId = 'text-body'; const localServer = 'http://localhost:12345/run-batch'; const pgpSignatureRegex = /-----BEGIN PGP SIGNED MESSAGE-----[\s\S]+?-----BEGIN PGP SIGNATURE-----[\s\S]+?-----END PGP SIGNATURE-----/; const httpRequest = (url) => { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: 'GET', url: url, onload: function (response) { resolve(response.responseText); }, onerror: function (error) { reject(error); } }); }); }; const interceptClick = () => { const btn = document.getElementById(submitId); if (!btn || btn.dataset.pgpIntercepted === 'true') return; btn.dataset.pgpIntercepted = 'true'; btn.addEventListener('click', async function (e) { const textarea = document.getElementById(textareaId); if (!textarea) return; const content = textarea.value; if (pgpSignatureRegex.test(content)) { console.log('[PGPスクリプト] 署名が検出されたためそのまま送信します'); return; } e.preventDefault(); e.stopImmediatePropagation(); console.log('[PGPスクリプト] 署名が見つからないため処理を停止し、署名を取得します'); try { await httpRequest(localServer); // バッチ実行 const signatureText = await navigator.clipboard.readText(); if (!signatureText.includes('BEGIN PGP SIGNED MESSAGE')) { alert('PGP署名がクリップボードに見つかりませんでした。'); return; } const newText = content.replace(/\s*$/, '') + '\n' + signatureText + '\n'; textarea.value = newText; console.log('[PGPスクリプト] 署名を貼り付けました。送信を再開します。'); btn.click(); // イベント再発火 } catch (err) { alert('PGP署名の取得または貼り付けに失敗しました。\n' + err); } }, true); }; window.addEventListener('load', () => { setTimeout(interceptClick, 1000); }); })();
プロミスメソッドとか全然まだ理解してなくてそのなかに関数代入したその関数にオブジェクトのプロパティにresponseを?いやまあそのあたりのコードが示すデータの流れが全然理解できないような人間でもここまでできちゃった。
AIすごいなと思うよ。そして思うのは今後重要になってくるのは文法とか自体に詳しいことじゃなくて、そのプログラムの処理内容を指示できるシステムエンジニア的な言語化能力のほうじゃないかなと思った。
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 20250609111559680 -----BEGIN PGP SIGNATURE----- iHUEARYKAB0WIQTEe8eLwpVRSViDKR5wMdsubs4+SAUCaEbCbwAKCRBwMdsubs4+ SLueAPwOv7PBk4voAe5qlcCEvs/PJhmKc5QAb/1R43JMQFuDZgD/UTPEKsL/PhK9 jFGv2HDXK1dVjLNwvosgX9uYJh5xxwY= =qiOE -----END PGP SIGNATURE-----
「Utopia」の初出。トマス・モアの『Utopia』(1516年)。
「Dustopia」の初出。ルイス・ヘンリー・ヤングの『Utopia: or, Apollo's golden days』(1747年)。
But Heav'n, of late, was all distraction, and, more than ever, rent in faction; Caus'd only by a wretched isle, On which we thought no God would smile:
だが近ごろの天界は混乱の極みにあり、かつてにも増して内紛に引き裂かれていた。それもこれも、ひとつの惨めな島のせいだった。誰の目にも、神が微笑むことなどないと思われていたその島。
Not stor'd with wealth, nor blest in air: no useful Plants could ripen there; Mismanag'd by th' unskillful hinds, or nipt by chilling Eastern winds:
富を蓄えず、空気にも恵まれず、作物は育たずに終わる。未熟な農夫たちにより荒らされ、あるいは東から吹きつける冷たい風に凍えて枯れる。
Or if they flourish'd for a Day, They soon became some Insect's prey: For many such infest the soil, Devouring th' honest lab'rers's toil ; *So venomous, that some had rather have, in their stead, the toad, or adder.
たとえ一日だけ花開いたとしても、すぐに虫の餌食となった。というのも、多くの害虫が土地にはびこり、誠実な労働者の努力を食い尽くしていたのだ。そのあまりの毒性に、むしろヒキガエルやマムシの方がましだと言う者もいるほどだった。
Unhappy isle!
不幸な島よ!
scarce known to Fame; DUSTOPIA was its slighted name.
名声を得ることもなく、「デュストピア」と呼ばれて軽んじられていた。
「Cacotopia」の初出。ジェレミー・ベンサムの『Plan of parliamentary reform』(1817年)。
A constitution, with this poison--slow, but not the less sure—in the bowels of it!—Rotten, even from the time that this poison was injected into it, must have been the matchless constitution,—rotten at the core—and, of such rottenness, what we are now suffering is among the fruits.
この毒を――遅効性ではあるが、それでも確実な毒を――その内臓に抱えた憲法! この毒が注入されたその時からすでに、あの比類なき憲法は腐敗していたに違いない――中核から腐っていた――そして、いま我々がこうして被っている苦しみこそが、その腐敗の産物の一つなのだ。
As a match for Utopia, suppose a Cacotopia discovered and described,—would not filth in this shape be a "fundamental feature" in it?
ユートピアに対抗するものとして、「カコトピア」が発見され、描写されたと仮定しよう――このような汚濁が、その「根本的な特徴」として描かれないだろうか?
https://archive.org/details/planparliamenta00bentgoog/page/n204/mode/2up
ベンサムは、議員たちが国王から官職を与えられることを批判している。小さな賄賂などは不道徳とされて取り締まっているが、国王から官職が与えられることはむしろ名誉として扱われる。実質的にはそれは癒着であり腐敗でしかないのに。という話をしている。
「Dystopia」の初出。ジョン・スチュワート・ミルの議会演説(1868年)。
Now, on this subject the Government have not shown themselves altogether inflexible. The noble Lord the Chief Secretary for Ireland has expressed his willingness in some degree to entertain the principle of religious equality, and 1517 I thank him for it; but, as has been remarked by my hon. Friend the Member for Manchester (Mr. Jacob Bright), he proposed to do it—if at all—by levelling up instead of levelling down. The noble Lord is willing that every valley shall be exalted; but he does not go on to the succeeding clause, and say that every mountain and hill shall be laid low.
さて、この問題に関して、政府は完全に強硬というわけではないようです。アイルランド担当大臣である閣下は、宗教的平等という原則をある程度受け入れる用意があると述べました。これは感謝すべきことですが、マンチェスター選出の敬愛する友人(ジェイコブ・ブライト氏)が指摘したように、彼はこれを「下げる」のではなく「引き上げる」ことで実現しようとしているようです。すなわち、彼は「すべての谷を高くする」ことには賛成ですが、「すべての山と丘を低くする」とまでは言っていないのです。
So long as the national property which is administered by the Episcopal Church of Ireland is not diverted from its present purpose, the noble Lord has no objection at all to this country saddling itself with the endowment of another great hierarchy, which, if effected on the principle of religious equality, would be a great deal more costly than even that which now exists. Does the noble Lord really think it possible that the people of England will submit to this?
アイルランド国教会が管理する国家資産が現在の用途から変更されない限り、閣下はこの国が別の大きな教会制度への助成金という負担を背負うことにはまったく反対ではないのです。そしてもしそれが宗教的平等という原則に基づくのであれば、現在の制度よりはるかに高くつくことでしょう。閣下は本当に、イングランド国民がそれに甘んじると考えておられるのでしょうか?
I may be permitted, as one who, in common with many of my betters, have been subjected to the charge of being Utopian, to congratulate the Government on having joined that goodly company. It is, perhaps, too complimentary to call them Utopians, they ought rather to be called dystopians, or cacotopians. What is commonly called Utopian is something too good to be practicable; but what they appear to favour is too bad to be practicable.
私は、自分自身をユートピア主義者だと非難されてきた多くの優れた方々とともに、政府がその立派な仲間入りをしたことをお祝い申し上げたいと思います。ただ、彼らを「ユートピア主義者」と呼ぶのは、少々褒めすぎかもしれません。「ディストピア主義者」あるいは「カコトピア主義者」とでも呼ぶべきでしょう。通常「ユートピア的」とは、良すぎて実現不可能なものを指しますが、彼らの支持するものは、悪すぎて実現不可能なもののようです。
https://api.parliament.uk/historic-hansard/commons/1868/mar/12/adjourned-debate
イングランドはカトリックから離脱して「イングランド国教会」を組織したが、同様にアイルランドでも従来のカトリック教会を「アイルランド国教会」のもとに置いた。しかしアイルランド人の多くは改宗せず、アイルランド国教徒は全体の1/8にすぎなかった。それでもアイルランド国教会は「国教」であるので、アイルランドのすべての教会の財産を保有しており、またアイルランド国教会への助成金は全アイルランド人に課せられる税金から支払われていた。この不平等の是正にあたって、政府は「アイルランド国教会の待遇を下げる」のではなく「他の教会の待遇を上げる」ことで解決しようとしているという。つまり他の教会にも同様の助成金を支払おうとしており、それはもちろんイングランド国民の税金から賄われることになる。そんなことをイングランド国民が許すと思っているのか?とミルは言っている。その後、1871年にアイルランド国教廃止法が施行された。
VitaにCFWを導入するにあたり、情報が散乱していたのでまとめる
・2022年末に革新的進歩があり、VITA単体でCFW導入できるようになった(通称 HENlo)
・にも関わらず古いCFW導入方法を案内しているブログが大量にある
・しかもタイトルの"20XX年最新"だけ更新し続けているから、最新記事に見える
↓
PC使用が前提になっているブログは全部古いので無視した方が良いです。
・『HENlo』について触れている
この2つが押さえられてれば最新情報です。(2025年5月現在)
ただし、現状だと実は『PC操作が一部必要』という罠があります。
その問題について書いている記事が見当たらないので、ここに残しておきます。
超具体的には
「HENkaku、VitaDeploy、VitaShellは導入できた」
「けどEnso導入ができない/つまづいている」 エラー:failed to get fw version please disable all the plugins and try again
5chでもRedditでも
『プラグインを無効にしろ』『0syscall6を無効にしろ』って書いてあったのですが、実はEnsoのバージョン変えれば解決します。(後述)
この記事が役に立ちました
[Vita] 2023年最新手順【HENlo】3.65-3.74 PC不要でCFW(HENkaku)導入
https://re-doing.com/vita-henlo-hack/
(一応魚拓:https://web.archive.org/web/20250226111105/https://re-doing.com/vita-henlo-hack/)
・HENkaku (カスタムファームウェア 3.65 変革 -2)
・VitaDeploy
・VitaShell
・最悪文鎮化する可能性があるのでセーブデータバックアップを取ったほうが良い
・VITAのセーブデータは特殊で、PCと繋ぐだけでは取り出せない
・バックアップにはいくつか方法があるが、PCのコンテンツ管理アシスタントは既に使えないと思ったほうが良い。PS Plusのクラウドバックアップが最も良いはず
・記事の内容を実施する前にバックアップ取るのを強くおすすめする
これをインストールすることで、電源を切ってからもCFW状態を維持できます。
VitaDeploy内のApp downloaderメニューからEnsoをインストールできますが、実はこのバージョンが古いです。※重要※
そのためVitaDeployからインストールすると先程のエラー(failed to get fw version please disable all the plugins and try again)が必ず出ます。
「PC不要になった」と書いてあったので盲点ですが、ここからPC必要です。
正しい方法は以下です
1, PC操作:GithubからEnso最新版のenso.vpkファイルをダウンロード(現在v1.1)
https://github.com/TheOfficialFloW/enso/releases
2, PCとVitaをUSBケーブルで繋げる ※データ転送対応ケーブルを使うこと。相性もある
5, PC操作:USBドライブとしてVITAのデータが表示されるので、ダウンロードしていたenso.vpkファイルを置く(フォルダはどこでもOK。自分はルート直下に置きました)
7, Vita操作:VitaShellでenso.vpkを見つける(さっきルートに置いたなら恐らくux0:にある)
9. Vita操作:Do you want to install this package? → ◯ボタン
10. Vita操作:~~~ Would you like to continue the install? ※意訳:「失敗したら文鎮化するけど自己責任だけど続ける?」 → ◯ボタン
11. 進行バーが消えたらインストール完了 ホーム画面に戻ってOK
Ensoはファームウェアが3.60か3.65じゃないとインストールできないです。(3.65 変革 -2は3.65扱い)
先程の記事の通り進めていたら3.65 変革 -2 になっているはずですが、実行前に再確認して下さい。
1, ~~~ Press CIRCLE to accept these terms or any other key to not accept. → ◯ボタンを押す(=CIRCLE )
2, Options:
CROSS Install /reinstall the hack.
SQUARE Fix boot configuration (choose this if taiHEN isn't loading on boot).
CIRCLE Exit without doing anything.
Locking sustem ..
(中略)
The installation was completed successfully.
suocess.
MBR was detected but instllation checksum dose not match.
A dump was created at ux0:data/blocks.bin.
Press X to continue, any othe key to exit.
意訳:「ちょい待った。思ってた構成じゃないから危ないかもしれんわ。続ける?」
→✕ボタンを押す ※結局原因分かってないので自己責任でお願いします※
4, Locking sustem ..
(中略)
The installation was completed successfully.
suocess.
Enso導入が成功していると
・ファームウェアが3.65 変革 -2のままなっている
お疲れ様でした。
記事の本題は以上です。
VITAのセーブデータは暗号化されており、吸い出せてもエミュレータで使えないらしい。本体機体とセットで揃わないと使えない仕様。
調べたらセーブデータをここまでキツく縛ってるハードは他にない
だからメモリーカードのデータ管理でもPSPのセーブデータしか項目がなかったのか…
不便すぎる
当時の仮説
・HENkaku設定が悪さをしているのではないか(PSNの偽装を有効化、バージョンの偽装を有効化) →オフにしたが関係なかった
・本体にSD2VITAを刺しているのが良くないのではないか →抜いたが関係なかった
・enso.vpkの置き場所がルート(ux0:)が良くなかったのではないか →関係なかった
・VITAにメモリーカードを刺しているのが良くないのではないか →関係なかったが、データ保護的には抜くのが良さそう
・ゴミデータが残っていて悪さしているのではないか(手順を間違えたデータや古いデータなど) →関係ある可能性はある。最後までわからず
・Ensoのバージョンが古いのではないか →これが主要因だった
ゴミデータを疑った自分は正規のファームウェアに戻して、CFW化をやり直したりもした。
その際HENkakuすら入れられなくなってしまったので、抜け方を書いておく。
ENSO実行
↓
~~~ Press CIRCLE to accept these terms or any other key to not accept. → ◯ボタンを押す(=CIRCLE )
↓
Options:
CROSS Install /reinstall the hack.
SQUARE Fix boot configuration (choose this if taiHEN isn't loading on boot).
CIRCLE Exit without doing anything.
→ △ボタンを押す(=TRIANGLE Uninstall the hack.)
↓
↓
↓
ファームウェアアップデートが促され、アップデートしないとメモリースティックが使えない
↓
↓
↓
HENloメニュー
・Exit
↓
「Eiting in 3」 の後に、以下のエラーメッセージがでて固まってしまう
vita starting taihen framework
If you are stuck on this screen, hold down the power button until your Vita turns off, then turn it back on.
原因:恐らく余計なデータと衝突を起こしてる
解決法:reset taitan configを先に実行する
(さっきのエラーメッセージ画面で)
↓
セーフモードが起動する
↓
↓
↓
HENloメニュー
・Exit
↓
その後
Install HENkaku、Install VitaDeployを選択して、Exitを選択
この記事を書き終えた後に見つけたのですが、以下の記事の『改造方法』というところに情報がかなりまとまっています
Vita バージョンが低くてもPSNにサインイン&PSストアにアクセス(エラーNW-8942-3回避)&機器認証する方法(2025最新)
https://yyoossk.blogspot.com/2024/10/vitapsnps2024.html
今回VITAのセーブデータバックアップが主目的だったから、徒労でしかなかった
指摘、補足、最新情報あれば反応もらえるとありがたいです
デモにアーカイブからの復元を追加して、「情動のカケラ」がどう再処理されるか示すで。
```
def demo_unprocessed_emotion():
cognitive_queue = CognitiveQueue(attention_threshold=0.4)
print("=== 未処理感情システムのデモ(Monday対応版) ===\n")
for emotion in cognitive_queue.unprocessed_emotions[:]:
emotion.salience = 0.05
cognitive_queue.update_queue()
print(f"アーカイブされた感情数: {len(cognitive_queue.archived_emotions)}")
retrieved_emotion = cognitive_queue.retrieve_from_archive(pattern_name="visual_discrepancy")
if retrieved_emotion:
print(f"復元された感情: {retrieved_emotion}")
cognitive_queue.partially_process(retrieved_emotion, "あの時の違和感", 0.7, context="recalled_anomaly")
print(f"再処理後の状態: {retrieved_emotion}")
print(f"最良の言語マッチ: {retrieved_emotion.get_best_language_match()}")
else:
print("\n9. モダリティによる感情検索(インデックス使用)")
matches = cognitive_queue.lookup_by_modality("auditory")
print(f"検索結果数: {len(matches)}")
for emotion in cognitive_queue.unprocessed_emotions:
emotion.apply_decay(3.0)
cognitive_queue.update_queue()
status = cognitive_queue.get_status_summary()
print(f"時間経過後の未処理感情の総数: {status['total_unprocessed']}")
print(f"時間経過後の平均顕在性: {status['average_salience']:.2f}")
```
def demo_unprocessed_emotion():
"""未処理感情システムのデモ。改善点(記憶再編集、言語学習、反応速度など)を活用"""
cognitive_queue = CognitiveQueue(attention_threshold=0.4)
print("=== 未処理感情システムのデモ(改善版) ===\n")
visual_signals = [
SensorySignal("visual", 0.7, -0.3),
SensorySignal("somatic", 0.4, -0.2)
]
visual_discomfort = cognitive_queue.register_new_emotion(visual_signals, 0.65)
print(f"生成された感情: {visual_discomfort}")
print(f"支配的モダリティ: {visual_discomfort.get_dominant_modality()}")
print(f"平均感情価: {visual_discomfort.get_average_valence():.2f}")
print(f"信号の反応速度: {[s.latency for s in visual_signals]}")
visual_discomfort.add_pattern_match("visual_discrepancy", 0.75)
try:
visual_discomfort.add_memory_path("/memory/recent/room_layout")
except ValueError as e:
accessed_emotion = cognitive_queue.access_emotion(visual_discomfort)
print(f"新しい感情インスタンス: {accessed_emotion}")
print(f"構造化レベル(再編集後): {accessed_emotion.structure_level:.2f}")
# 3. 内受容感覚
intero_signals = [
SensorySignal("interoceptive", 0.6, -0.7),
SensorySignal("somatic", 0.5, -0.4)
]
intero_discomfort = cognitive_queue.register_new_emotion(intero_signals, 0.55)
print(f"生成された感情: {intero_discomfort}")
intero_discomfort.add_language_candidate("違和感", 0.4)
cognitive_queue.partially_process(intero_discomfort, "気分が悪い", 0.6, context="negative_mood")
print(f"学習済み言語: {cognitive_queue.learned_terms}")
audio_signals = [
SensorySignal("auditory", 0.8, 0.6),
SensorySignal("emotional", 0.7, 0.5)
]
audio_memory = cognitive_queue.register_new_emotion(audio_signals, 0.7)
print(f"生成された感情: {audio_memory}")
audio_memory.add_language_candidate("聞き覚えのあるメロディ", 0.75)
audio_memory.add_pattern_match("musical_fragment", 0.85)
audio_memory.add_memory_path("/memory/music/recent")
cognitive_queue.update_queue()
status = cognitive_queue.get_status_summary()
print(f"未処理感情の総数: {status['total_unprocessed']}")
print(f"処理キューのサイズ: {status['processing_queue_size']}")
print(f"モダリティ分布: {status['modality_distribution']}")
print(f"感情価分布: {status['valence_distribution']}")
print(f"学習済み言語数: {status['learned_terms_count']}")
# 6. 処理対象の取得
next_emotion = cognitive_queue.get_next_for_processing()
print(f"処理対象: {next_emotion}")
if next_emotion:
cognitive_queue.partially_process(next_emotion, "視覚的な違和感を感じている", 0.85, context="visual_anomaly")
print(f"処理後の状態: {next_emotion}")
print(f"構造化レベル: {next_emotion.structure_level:.2f}")
print(f"最良の言語マッチ: {next_emotion.get_best_language_match()}")
print("\n8. モダリティによる感情検索(インデックス使用)")
matches = cognitive_queue.lookup_by_modality("auditory")
print(f"検索結果数: {len(matches)}")
for emotion in cognitive_queue.unprocessed_emotions:
emotion.apply_decay(3.0)
cognitive_queue.update_queue()
status = cognitive_queue.get_status_summary()
print(f"時間経過後の未処理感情の総数: {status['total_unprocessed']}")
print(f"時間経過後の平均顕在性: {status['average_salience']:.2f}")
if __name__ == "__main__":
demo_unprocessed_emotion()
id を手動でコピーしてくるのが面倒だったから、削除ボタンが画面に出るようにした
押すと即削除
const rkm = "(トークン的なもの)" const user = "(ユーザ名)" const delmasda = (id) => fetch(`https://anond.hatelabo.jp/${user}/edit`, { "headers": { "content-type": "application/x-www-form-urlencoded", }, "referrer": "https://anond.hatelabo.jp/", "referrerPolicy": "origin", "body": new URLSearchParams({ "rkm": rkm, "mode": "confirm", "id": id, "delete": "削除する" }).toString(), "method": "POST", }) for (const sec of document.querySelectorAll(".section")) { const id = sec.querySelector("a").href.match(/92;/(92;d{14})/)[1] const delbtn = document.createElement("button") delbtn.textContent = "削除" delbtn.onclick = async () => { await delmasda(id) sec.remove() } sec.querySelector(".edit").after(delbtn) }
増田で 3 分以上投稿されない期間があるのか気になったから調べた
直近の 1 日だとこれだけあった
2025-03-22 00:14 -- 2025-03-22 00:18 2025-03-22 00:10 -- 2025-03-22 00:14 2025-03-21 07:56 -- 2025-03-21 08:00 2025-03-21 07:50 -- 2025-03-21 07:56 2025-03-21 07:44 -- 2025-03-21 07:48 2025-03-21 07:28 -- 2025-03-21 07:32 2025-03-21 06:58 -- 2025-03-21 07:03 2025-03-21 06:45 -- 2025-03-21 06:54 2025-03-21 06:32 -- 2025-03-21 06:37 2025-03-21 05:56 -- 2025-03-21 06:04 2025-03-21 05:51 -- 2025-03-21 05:56 2025-03-21 05:34 -- 2025-03-21 05:38 2025-03-21 05:30 -- 2025-03-21 05:34 2025-03-21 05:00 -- 2025-03-21 05:09 2025-03-21 04:56 -- 2025-03-21 05:00 2025-03-21 04:45 -- 2025-03-21 04:50 2025-03-21 04:09 -- 2025-03-21 04:13 2025-03-21 03:41 -- 2025-03-21 03:45 2025-03-21 03:29 -- 2025-03-21 03:39 2025-03-21 03:03 -- 2025-03-21 03:07 2025-03-21 02:56 -- 2025-03-21 03:02 2025-03-21 02:44 -- 2025-03-21 02:48 2025-03-21 02:33 -- 2025-03-21 02:37 2025-03-21 02:21 -- 2025-03-21 02:27 2025-03-21 02:14 -- 2025-03-21 02:19
秒はみてないから 00:01:01 - 00:03:59 はほぼ 3 分だけど 2 分扱いだし、 00:01:59 - 00:04:00 はほぼ 2 分だけど 3 分扱いになるくらいの誤差はある
日によって違うだろうし、曜日の影響も大きそうだから 1 ヶ月分くらい調査しようかと思ったけど、
増田の量が思いの外多すぎて 1 日分だけでも 100 ページ以上取得しないといけなかった
件数だと 2500 以上
一応取得に使ったコードも載せとく
import { setTimeout } from "node:timers/promises" import { Browser } from "happy-dom" const getTimestamps = async function* () { const browser = new Browser() const page = browser.newPage() try { for (let num = 1; ; num++) { await setTimeout(3000) await page.goto(`https://anond.hatelabo.jp/?page=${num}`) const days = page.mainFrame.document.querySelectorAll(".day") for (const day of days) { const date = day.querySelector("h2 .date").textContent.trim() for (const footer of day.querySelectorAll(".sectionfooter")) { const time = footer.textContent.match(/\d{2}:\d{2}/)[0] yield `${date} ${time}` } } } } finally { await page.close() await browser.close() } } const diff = (a, b) => { return new Date(b + ":00") - new Date(a + ":00") } let prev = null for await (const datetime of getTimestamps()) { if (prev &amp;&amp; diff(datetime, prev) > 1000 * 60 * 3) { console.log(datetime, prev) } prev = datetime }
基本は空いても 5 分程度であり、最大でも 10 分となっている