「btn」を含む日記 RSS

はてなキーワード: btnとは

2025-08-22

dorawii@執筆依頼募集中

昨日一番肝心なファイルなのにURLとみなされる部分が多いことの関係投稿できなかったのでそれを小分けにして書く。

小分けというか例のスパムの影響でNGワードに引っかかっていたようなのでそこだけ書き換えた。

suuportと書いていある部分は元のコードでは当然uが一つ少ないので利用するときはそうすること。

hatena_client.py

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager # ← 追加
from selenium.webdriver.common.by import By
from selenium.webdriver.suupport.ui import WebDriverWait
from selenium.webdriver.suupport import expected_conditions as EC
import time, json
from selenium.common.exceptions import TimeoutException

class HatenaClient:
def __init__(self, username, password):
self.username = username
self.password = password
self.driver = None

def start_browser(self):
options = Options()
options.set_capability("goog:loggingPrefs", {"browser": "ALL"})
options.add_argument("--headless=new") # 開発中は消してよい
options.add_argument("--disable-gpu")

# ✅ webdriver-manager を使って ChromeDriver を自動取得・設定
service = Service(ChromeDriverManager().install())
self.driver = webdriver.Chrome(service=service, options=options)


def login(self):
self.driver.get("https://b.hatena.ne.jp/my")
print(self.driver.current_url)

self.driver.get("https://www.hatena.ne.jp/login")
time.sleep(2)
self.driver.find_element(By.NAME, "username").send_keys(self.username)
self.driver.find_element(By.NAME, "password").send_keys(self.password)
self.driver.find_element(By.XPATH, "//button[contains(text(), 'ログイン')]").click()
WebDriverWait(self.driver, 10).until(lambda d: "my" in d.current_url or "login" not in d.current_url)
if "passkeys" in self.driver.current_url:
self.driver.get("https://b.hatena.ne.jp/my")

print(self.driver.current_url)
print(self.driver.title)
return "dorawii" in self.driver.current_url

def add_bookmark(self, target_url):
self.driver.get(f"https://b.hatena.ne.jp/{self.username}/add.confirm?url={target_url}")
time.sleep(2)

try:
# コメントがあれば入力
comment_box = self.driver.find_element(By.CSS_SELECTOR, "textarea.bookmarkadd-comment-form")
comment_box.clear()
comment_box.send_keys("わしが書いた")

# 登録ボタンを押す
save_button = self.driver.find_element(By.CSS_SELECTOR, "input.bookmarkadd-submit-btn")
save_button.click()
time.sleep(2)

return True
except Exception as e:
print(f"Bookmark failed: {e}")
return False

def quit(self):
self.driver.quit()

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

https://anond.hatelabo.jp/20250822131958#
-----BEGIN PGP SIGNATURE-----

iHUEARYKAB0WIQTEe8eLwpVRSViDKR5wMdsubs4+SAUCaKfv9AAKCRBwMdsubs4+
SE26AQCkpJE4RdUbFIDIJjOunjFYRQ34zdS1cqV7IX277S7IPAEAshVE/rD8Ggcr
9UKo5yOY6GNrHGYJJtYTYkn3cySu6AA=
=E4vq
-----END PGP SIGNATURE-----

2025-06-09

dorawii

ようやく(ほぼ)すべてが自動化された。

あとはローカルサーバーの起動をスタートアップに設定する(方法AIに聞いて指示に従う)だけの消化試合

ここにほとんどAI頼りのコードを公開しておく。

事前にインストールしておくもの

autohotkey

nodejs

ユーザースクリプトを実行できる拡張機能

パスとかの注意

署名要求してくるパスワードを自動入力するahkファイルドキュメントAutoHotkey配下に置いた。

バッチファイル(make.sign.bat)はデスクトップに置いた。

以下コード

autopass.ahk
#Persistent
#SingleInstance ignore
SetTitleMatchMode, 2
WinWaitActive, pinentry
SendInput お前のパスワード
Sleep 100
SendInput {Enter}
ExitApp
run-bacth-server.js
// 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/');
});
makesign.bat
@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
tempermonkeyとかに登録するユーザースクリプト
// ==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-----

2020-05-08

anond:20200507235719

目が痛かった

textarea,

#text-title,

.message {

background-color: #7f8283 !important;

}

#body,

body,

.box-curve {

color: #c5c8c6 !important;

background-color: #333 !important;

}

.refererlist ul {

color: #c5c8c6 !important;

background-color: #153555 !important;

}

div.body {

border: #15497f 1px solid !important;

}

span.sanchor {

color: #15497f !important;

}

div.btn-standard,

a.tw-share-button,

a.fb-share-button {

background-color: #15497f !important;

}

#intro p {

color: #c5c8c6 !important;

background-color: #404142 !important;

}

td.gmenu {

background-color: #384d88 !important;

}

span.label {

color: #c5c8c6 !important;

}

a.keyword,

a.okeyword {

color: #c5c8c6 !important;

background-color: #333 !important;

border-bottom: none !important;

}

a {

color: #2ea6c0 !important;

}

td.username,

h2 {

background-color: #404142 !important;

}

2017-02-01

http://anond.hatelabo.jp/20170201160608

システムハンガリアンはIDEの発達や型推論で廃れた。変数ポインタを当てるだけで型がわかる。

アプリケーションハンガリアンは、自分もメンバ変数btn~にしたり~Buttonにしたり迷ってたりしてたが、プロパティとして公開するときはハンガリアンにするわけにはいかないので、結局ハンガリアンをやめた。プロパティとメンバ変数機械的対応が取れてたほうが便利。"_プロパティ名"とかにしてしまう。

型よりもその変数意味のほうが重要だという考え方がハンガリアンが廃れた大もとの原因だろう。最近IDE中間一致で補完するのが主流なので、Buttonと打てばボタン一覧が出てくる。

2012-07-08

Rails3 とTwitter Bootstrapで、オシャレなエロサイトをつくってみました。

Rails3 と jQuery で、真面目にオシャレなエロサイトをつくってみました。 - h300

http://d.hatena.ne.jp/inouetakuya/20120331/1333192327

に触発されて、オシャレエロサイトを作ってみました。

以下は製作記になります

オシャレエロサイトを作ろうと思ったのはいいのですが、デザインは苦手なので途方に暮れていました。

h300の方はペパボソフトウェアエンジニアらしいのですが、こっちはただの素人プログラマー

オシャレなサイトなんて作れるわけがありません。

そこで何か裏ワザみたいなものはないかとググっていると、Twitter Bootstrapという文字が目にとまりました。

Bootstrapの名前は知っていましたが、深い内容までは知りませんでした。

ですが、紹介記事を読んでみると自分理想に近かったので早速使ってみることにしました。

Twitter Bootstrapとは?

Twitter Bootstrapはある程度有名だと思うんですが知らない方のために説明すると、

CSSフレームワークの一つで、ウェブデザイン作成を手助けしてくれるものです。

色々なCSSフレームワークを見ましたがTwitter Bootstrapが一番完成度が高いと感じました。

ウィキを見ると最初リリース2011年8月なので比較最近のものですね。

CSSフレームワークの説明は難しいんですが、

普段、みなさんがウェブサイトを作る時、HTML + CSSで作られるかなと思うんですよね。

この時、CSSが事前に用意されているとすごく楽じゃないですか?

CSSフレームワークCSSの大部分を前もって用意してくれているんですよ。(フレームワークによりますが)

ですので基本的にCSSに合わせてHTML記述するだけでウェブサイトが出来てしまます

CSSに合わせてHTML記述するとはどういうことでしょうか?

匿名ダイアリーでも似たようなことができるのでやってみます

この文章は薄い青色ハイライトされていますよね?
Bootstrapで似たようなことをする場合
<div class="well">
ハイライトしたい文章
</div>
という感じになります

classにwellと指定しているだけですね。

なぜそうするだけで文章がハイライトされるかというと、

divのclassにwellが付いていたら、いい感じでハイライトしてねっていう指示が

Twitter BootstrapのCSSに書いてあるからです。

BootstrapのCSSには、divのclassにalert alert-errorっていうのがあったら警告文だしてねとか、

button class="btn"ってあったらボタン表示させてねとか色んなことが最初から書いてくれています

もちろん見栄えがよくなるように記述されていますので、classを指定するだけでモダンデザインになるわけですよ。

CSSに合わせてHTML記述するだけでウェブサイトが出来るというのはこういうことです。

でも、最近ウェブサイトHTML + CSS + JQueryという場合も多いですよね。

安心してください。Twitter Bootstrapの場合JQueryの基本的な部分も用意してくれています

ですのでドロップダウンメニューやタブ、スライドショーなどの実装も簡単にできます

それに加えてBootstrapはよく使うアイコン数百種類まで用意してくれています

至れり尽くせりですよ。

神様ですね。

CSSフレームワークを使うメリットはまだまだあります

CSS固定化されていると、HTML自動的に固定化されます

CSSに合わせて記述するので当たり前といえば当たり前ですね。

CSS記述一定HTMLもある程度一定なので、メンテナンスが格段にやりやすくなります

個人プログラマーの方だと、サイトごとにHTMLCSSもグチャグチャという方も多いのではないでしょうか?

フレームワークを使えばそういうこともなくなるということです。

Twitter Bootstrapの凄さはそれだけではありません。

現在ユーザーがどんなデバイスウェブサイトアクセスしてくるか分かりません。

PCスマートフォンiPadTV3dsなど全てのデバイスに合わせてデザインを作るのは時間がかかりすぎます

でもTwitter Bootstrapならbootstrap-responsive.cssというCSSを選ぶだけで、

デバイスの横幅に合わせてデザインが変わるレスポンシブなウェブサイトができます

iPhoneiPad対応もすぐですよ。

もちろんデメリットもありまして、サイトデザインが似てしまうというのが難点です。

ですが基本はBootstrapを使って、ちょっと自分カスタマイズしてオリジナルっぽくすることもできますので、

一度Twitter Bootstrapを使ってみる価値はあると思います

http://twitter.github.com/bootstrap/

Bootstrapの説明が長くなってしまいましたね…。

ここからアダルトサイト作成の説明です。

クローラ作り

1.エロいサイトを巡って、XVIDEOSやFC2動画などのリンク、embedされたものがあれば取得。

2.リンクから動画サイトアクセスしてサムネイルを取得。

3.データベースに登録。

一連の作業をクローラーやらせプログラムRubyで書く。

RailsでBootstrapを使う。

RailsでBootstrapを使うにはtwitter bootstrap railsというgemを使うらしいです。

しかし、使おうと思ったのですが、windowsでは上手くインストールできませんでした。

windowsRubyを使うとバグが多いです。

仕方なく、代わりにsass-rails-bootstrapというものを使いました。

違いはcssにLESSをつかっているかsass(scss)を使用しているかだと思います

http://d.hatena.ne.jp/tkawa/20120219/p1

の記事が参考になりました。

ちなみにLESSとかSassってのはcss効率的に書けるすぐれたものです。

最近webクリエイターボックスさんでも紹介されていました。

http://www.webcreatorbox.com/tech/css-sass/

LESSとかSass(Scss)もお勧めですよ。

railsでは3.1からcoffee scriptと共にsassがデフォルトで使えます

このあたりがRailsの素晴らしさですね。

Bootstrapは画像を綺麗に並べて表示することにも向いているので、

アダルトサイトと相性がいいなと感じました。

タグリスト実装

AV女優名とか女子校生人妻などのジャンルタグがあれば便利ですよね。

Railsではacts-as-taggable-onというgemを使い実装しました。

動画タイトルが事前に用意したAV女優リストジャンルリスト合致すればタグ付けするという感じです。

AV女優リストDMMからジャンルリストは大手アダルトサイトから作成しました。

AV女優タグ名前順でソートしたいと思ったのですが、

漢字ソートできないのでしばらく悩んだ結果、

タグ付けするときに あおいそら-蒼井そら みたいな感じでタグ付けするようにしました。

もっとスマート方法があるはずですが思いつかなかったので仕方ないです。

ア行、カ行…のように行別にわけて、なおかつアイウエオ順で表記してますので

お気に入りAV女優名を探しやすいはずです。

簡易ブックマーク実装

クッキーを使ってログイン不要ブックマーク機能作りました

jquery.cookie.jsを使って、cookie配列に直してごにょごにょしてという感じで実装しました。

削除ボタンを押すと非同期で通信して…などいろいろ面倒でした。

でも、動画の数はかなり増やしていこうと思っていましたので頑張って実装しました。

動画の下のブックマークするボタンを押していただければブックマークできます

ブックマークするボタンの表示などにBootstrapの便利さを感じました。

アダルト動画を大画面で見れるようにする。

実はこれが一番やりたいことでした。

多くのアダルトサイト広告だらけで、肝心の動画がポツンと小さくあるだけというのが多いです。

世の男達は疲弊しています。それは本当に疲弊しています

戦場で疲れた兵士たちに、そんなせせこましい画面でアダルト動画見ろって?

そんな野暮なこと言いませんよ。

PCスクリーンの画面いっぱいに、大画面で、ドカーンエロ動画を楽しんで下さいよ。

動画はできるだけ大きく表示しています。もちろんレスポンシブです。

全画面表示にすりゃいいじゃん…っていうのは違うんですよ。

全画面表示だと逃げれないじゃないですか

不意に誰かが部屋に入ってきたらどうするんですか? 

1クリックと2クリックは大違いですよ。

コンマ一秒で守れる尊厳がある。

そう考えております

スマホ対応

Bootstrapでデザイン面はスマホ対応にはなっているのですが、

加えてjpmobileというh300で紹介されていたgemを使って、

スマホアクセスされたら表示する動画の数を減らしてとか、

広告の種類を変えるなどの微調整をしました。

サーバー選び

osukiniサーバーのGT2プランしました。

初期費用1900円、月940円で

CPU 2.66GHz、メモリ 2.2GB HDD200GBです。

チューニングは正しいかからないですね。

まぁ、アクセス捌けなくなってから考えます

Nginx + Unicornを使おうとして結局やめる。

Railsは遅いので少しでも速くするためにApacheの代わりにNginx使おうと思ったのですが、

PC用のキャッシュスマホ用のキャッシュを別々に保存して使う

ということがどうしてもできませんでした。

PC用のキャッシュがある場合スマホ用のキャッシュがなくてもキャッシュがあると認識されるなど、

もともとNginxrailsのページキャッシュは相性が悪いようです。

Nginx側でキャッシュする、もしくはスマホ用のアドレス別にすればできるかもしれないですが、

http://m.サイト名 みたいにするのが嫌だったので最終的にNginxを使うことをやめました。

Nginxに関するネット上の記述も少ないので運用するのは危険かな、ということもあります

Nginxを少しだけ使ってみた感触はかなり速いというものだったので残念でした。

バージョンが変われば、また挑戦したいですね。

Apache + passengerは遅いんですよ…。

【追記】

キャッシュの問題はRails側の問題だったので

やっぱNginxでもいけるかもしれないですね。

暇なときに試してみます

出来上がったサイト紹介

オシャレのハードルを上げすぎて紹介しづらくなったのですが、

紹介しないと終わらないということで紹介します。

http://nukisen.com  (エロ注意)

サイト名はオシャレに横文字でNukisenにしました。読み方はヌキセンです。

http://bootswatch.com でダウンロードできるBootstrapのテーマそのままですが、

オシャレというかクールデザインです。

Bootstrapを使うと自動的に細部まで凝ったデザインになるので最高ですね。

下にスクロールしていくと背景のグラデーションが変化したりとか、とても一人ではできないですよね。

長々と説明してきましたが、

ぜひNukisenで大画面のアダルト動画体感してほしいです。

動画の数をいきなり大量に増やすグーグル様に怒られるので、

しばらくは一日30本ぐらいの更新でいく予定です。

アダルトサイト同士の相互リンクアクセス増やしてなどはしない方向です。

最後

新しいことに挑戦すると得られるものが多いなと感じました。

ウェブサイトを作る際、無意識のうちに自分のできる範囲の技術で構築しがちだと思うんですが、

そうすると成長はないですね。

新しい技術に柔軟に対応していきたいです。

長文失礼しました。

 
ログイン ユーザー登録
ようこそ ゲスト さん