「あいつまだ寝てるのかプログラム」をハゲにパクられたので風邪の中進捗出しました。
@7shageに「last_post スクリーンネーム」で最終Postの時間のみを返す仕様の模様。
彼もコードを公開しているので脆弱性を見つけて煽るしか無い、と頭をフル回転させました。
@akkisino02 null の最終ツイートは 796日19107時間1146441分3秒前だよ!
— 7sr_ (@7shage) 2015, 9月 2
や っ た ぜ 。
$lastPostTime = $lastStatus[0]->created_at; sec2str(time() - strtotime($lastPostTime), $d, $h, $m, $s);
多分引き算した数字をそのまま出力したからこういうことになってるわけで、それの60との商を上の位に足せばいいのでは。
とか書いてた下書き記事をハゲに見せたら即修正されました。
以降しつこく圧力をかけてきます。
さっさとブログ記事上げろ @akkisino02
— 7sr_ (@7shage) 2015, 9月 3
akkisino02ブログを更新しろ~
— 7sr_ (@7shage) 2015, 9月 4
とは言え、製作時間一時間ほどで同等のものを作られてしまったので年上のプライドとして距離を離しておこうとキーボードに向かいました。熱出てるのに。
モジャにうるさくコーディングハラスしてたら作業を開始したようでご満悦
— 7sr_ (@7shage) 2015, 9月 5
絶対ゆるさねえこいつ
進捗報告
- 未実装だった「Postされた瞬間の時間」を返すようにした→相対時間を返す仕様に変更
- よってタイムスタンプを廃止
- UUIDを「問い合わせ時点の分秒から生成する四桁の数字」に変更
- 現在時間との差分のみを返すモードも作った
- 元のPostを参照した際140文字を超えてしまう場合の対策を実装
- 本人 or bot自体 を指定された場合参照しない仕様に
相対時間
@akkisino02 7shageの最終投稿は「(at)got_up_bot last_post null...(以下略)」で0日0時間31分19秒前です。 (3009)
— おるかw bot (@got_up_bot) 2015, 9月 6
のようにした。0日~のように数値がゼロの際その項目を省くのはそのうち実装予定。
具体的には、created_atと現在時間の差分を秒で出して、あとから日時分に繰り上げてる。
ソースコード45-52行あたり
UUID
Postの末尾についてる(nnnn)
今まではタイムスタンプをそのまま付加していたので文字数が多い上に投稿時間と見分けづらかった。
連投規制を回避するためのものなので、UUIDである必要なくない?と気付き「一時間ごとにリセットされるID」にすることに。
要は分分秒秒で四桁の数字化しているだけなので、「一時間前のリクエストから他のリクエストがなかった時」かつ「同じユーザーが前回と全く同じ分秒でリクエストした」というスナイプを決められると連投規制にかかる。
まあそんなスナイパーいないでしょwと思いこういう仕様にしています。
ソースコード60行目
差分のみを返すモード
@akkisino02 7shageの最終投稿時間は0日0時間2分3秒前です。 (5437)
— おるかw bot (@got_up_bot) 2015, 9月 6
文字通り。
「last_time スクリーンネーム」で動作。
57行目以降。
140文字超え対策。
上のPostにも書いてあるが、...(以下略)という部分。参照したPostを無条件で70文字にカットすることにした。
TwitterのIDが最大15文字らしいので、そこからもし15文字のユーザーにリクエストされた場合超えない文字数をちょっと余裕を持って設定した結果がこれ。
43行目。
本人のPost/botを指定された場合弾く
@akkisino02 問い合わせユーザー自身の最終Postは取得しません。(3321)
— おるかw bot (@got_up_bot) 2015, 9月 6
@akkisino02 当bot自身の最終投稿時間は取得しません。(5828)
— おるかw bot (@got_up_bot) 2015, 9月 6
どちらもこの処理があるということはその瞬間が最終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