猫の手も借したい

暇を極めた時に更新します

「あいつまだ寝てるのかプログラム」をハゲにパクられたので風邪の中進捗出しました。

nanaesu.hatenablog.com


@7shageに「last_post スクリーンネーム」で最終Postの時間のみを返す仕様の模様。


彼もコードを公開しているので脆弱性を見つけて煽るしか無い、と頭をフル回転させました。


や っ た ぜ 。

$lastPostTime = $lastStatus[0]->created_at;
sec2str(time() - strtotime($lastPostTime), $d, $h, $m, $s);

多分引き算した数字をそのまま出力したからこういうことになってるわけで、それの60との商を上の位に足せばいいのでは。
とか書いてた下書き記事をハゲに見せたら即修正されました。

nanaesu.hatenablog.com




以降しつこく圧力をかけてきます。



とは言え、製作時間一時間ほどで同等のものを作られてしまったので年上のプライドとして距離を離しておこうとキーボードに向かいました。熱出てるのに。



絶対ゆるさねえこいつ

進捗報告

  • 未実装だった「Postされた瞬間の時間」を返すようにした→相対時間を返す仕様に変更
  • よってタイムスタンプを廃止
  • UUIDを「問い合わせ時点の分秒から生成する四桁の数字」に変更
  • 現在時間との差分のみを返すモードも作った
  • 元のPostを参照した際140文字を超えてしまう場合の対策を実装
  • 本人 or bot自体 を指定された場合参照しない仕様に

相対時間

のようにした。0日~のように数値がゼロの際その項目を省くのはそのうち実装予定。
具体的には、created_atと現在時間の差分を秒で出して、あとから日時分に繰り上げてる。
ソースコード45-52行あたり

UUID

Postの末尾についてる(nnnn)
今まではタイムスタンプをそのまま付加していたので文字数が多い上に投稿時間と見分けづらかった。
連投規制を回避するためのものなので、UUIDである必要なくない?と気付き「一時間ごとにリセットされるID」にすることに。
要は分分秒秒で四桁の数字化しているだけなので、「一時間前のリクエストから他のリクエストがなかった時」かつ「同じユーザーが前回と全く同じ分秒でリクエストした」というスナイプを決められると連投規制にかかる。

まあそんなスナイパーいないでしょwと思いこういう仕様にしています。
ソースコード60行目

差分のみを返すモード

文字通り。
「last_time スクリーンネーム」で動作。
57行目以降。

140文字超え対策。

上のPostにも書いてあるが、...(以下略)という部分。参照したPostを無条件で70文字にカットすることにした。
TwitterのIDが最大15文字らしいので、そこからもし15文字のユーザーにリクエストされた場合超えない文字数をちょっと余裕を持って設定した結果がこれ。
43行目。

本人のPost/botを指定された場合弾く


どちらもこの処理があるということはその瞬間が最終Postなので、聞かなくてもわかるでしょってことで
33-36行。



まあ色々実装して更に穴も増えたので徐々に改善していこうと思います。
風邪引いてるのにこんなことをさせるハゲきらい。

ソースコード

# coding: utf-8

require "./consumer"
require "twitter"
require 'date'

rest_client = Twitter::REST::Client.new do |config|
	config.consumer_key        = CONSUMER_KEY
	config.consumer_secret     = CONSUMER_SECRET
	config.access_token        = ACCESS_TOKEN
	config.access_token_secret = ACCESS_SECRET
end

stream_client = Twitter::Streaming::Client.new do |config|
	config.consumer_key        = CONSUMER_KEY
	config.consumer_secret     = CONSUMER_SECRET
	config.access_token        = ACCESS_TOKEN
	config.access_token_secret = ACCESS_SECRET
end

time = Time.now.strftime("%Y-%m-%d %H:%M:%S")
rest_client.update("Start. #{time}")

stream_client.user do |status|
	if status.is_a?(Twitter::Tweet)

		if status.text.match("@got_up_bot last_post")

			user = status.text.gsub(/(@got_up_bot|last_post|\s|\.)/, "")
			uuid = Time.now.strftime("%M%S")
			time = Time.now

			if user == status.user.screen_name
				rest_client.update("@#{status.user.screen_name} 問い合わせユーザー自身の最終Postは取得しません。(#{uuid})")
			elsif user == "got_up_bot"
				rest_client.update("@#{status.user.screen_name} 当bot自身の最終Postは取得しません。(#{uuid})")

			else
				puts "(@#{status.user.screen_name}) take #{user}'s post. #{time}"
				rest_client.user_timeline(user, { count: 1 } ).each do |timeline|
					tweet = rest_client.status(timeline.id)
					del_at = tweet.text.gsub(/(@)/, "(at)")
					post = del_at[0...70]

					at_post = tweet.created_at
					post_time = (time.to_time.to_i - at_post.to_time.to_i)
					d = post_time / 86400
					h = post_time % 86400 / 3600
					m =	post_time % 86400 % 3600 / 60
					s = post_time % 86400 % 3600 % 60
					before = "#{d}#{h}時間#{m}#{s}"
					rest_client.update("@#{status.user.screen_name} #{user}の最終投稿は「#{post}...(以下略)」で#{before}前です。 (#{uuid})")
				end
			end
		end

		if status.text.match("got_up_bot last_time")

			user = status.text.gsub(/(@got_up_bot|last_time|\s|\.)/, "")
			uuid = Time.now.strftime("%M%S")
			time = Time.now

			if user == status.user.screen_name
				rest_client.update("@#{status.user.screen_name} 問い合わせユーザー自身の最終投稿は取得しません。(#{uuid})")
			elsif user == "got_up_bot"
				rest_client.update("@#{status.user.screen_name} 当bot自身の最終投稿時間は取得しません。(#{uuid})")

			else
				puts "(@#{status.user.screen_name}) take #{user}'s time. #{time}"
				rest_client.user_timeline(user, { count: 1 } ).each do |timeline|
					tweet = rest_client.status(timeline.id)
					at_post = tweet.created_at
					post_time = (time.to_time.to_i - at_post.to_time.to_i)
					d = post_time / 86400
					h = post_time % 86400 / 3600
					m =	post_time % 86400 % 3600 / 60
					s = post_time % 86400 % 3600 % 60
					before = "#{d}#{h}時間#{m}#{s}"
					rest_client.update("@#{status.user.screen_name} #{user}の最終投稿時間は#{before}前です。 (#{uuid})")
				end
			end
		end

	end
end