Skip to content

Latest commit

 

History

History
139 lines (87 loc) · 9.09 KB

shuffleLines.md

File metadata and controls

139 lines (87 loc) · 9.09 KB

ツイッターbotの投稿順序を並び替える

ツイッターbotから投稿するツイートの順序を、ランダムに入れ替えます。

目的

ツイッターbotには、登録したツイートをランダムに投稿できるものがあります。しかしツイートがランダムに選ばれると、以下のような状況が発生します。

  • あるツイートは短期間に繰り返し投稿される
  • あるツイートいつまで経っても投稿されない
  • 最近思いついたネタをすぐに投稿する方法がない

そこでこのようなスクリプトを作って、上記の問題を解決することにしました。

  • それぞれのツイートは、全ツイートが一周するまでに、一回ずつ投稿される。全ツイートが一周しそうになったら、全ツイートを一括ダウンロードしてから、本スクリプトでツイート順序を並べ替えてアップロードする。
  • 最近思いついたネタをすぐ投稿できる。Botサービスで、まもなく投稿されるネタを最近思いついたネタで上書きし、上書きされたネタを最後に追加する。

入出力形式と実行方法

入力形式

一行一ツイートです。改行などはbotサービスごとに指定される形式でエスケープされているものとします。文字エンコーディングは、UTF-8.jpのみ受け付けます。

出力形式

入力の行をランダムに入れ替えたものを出力します。それぞれの行の内容は変更しません。

実行方法

まずお試しとして、以下の通り実行すると、 cppFriendsBot.txt の各行を入れ替えたものが標準出力に出力されます。

ruby -Ku shuffleLines.rb -i cppFriendsBot.txt

オプションは下表の通りです。オプションの値は、オプションに続けて-i input.txtまたは--input=input.txtのように書きます。オプションの値の、先頭および末尾にある空白は取り除きます。

オプション 意味 省略値
-i, --input 入力ファイル名 標準入力
-o, --output 出力ファイル名 標準出力
-p, --phrase 最後のツイートに含まれる文字列 指定しない
-c, --[no-]check ツイートを検査する 検査しない

以下を実行すると、input.txtの内容を変換して、output.txtに出力します。

ruby -Ku shuffleLines.rb -i input.txt -o output.txt

--phrase=stringオプションをつけると、string が最後に含まれる行とそれより前の行を、string が最後に含まれる行より後ろにある行よりも、後に出力します。後述のように、ツイートが一周する前に順番を入れ替えるために用います。空白を含むオプションの値をシェルから渡すときは、""で囲ってください。

ruby -Ku shuffleLines.rb -i input.txt -o output.txt -p "わ-い たーのしー"

--checkオプションをつけると、ツイートを検査して、指摘事項を標準エラー出力に書き出します。--checkオプションが無い場合および--no-checkオプションを指定した場合は指摘しません。指摘事項は後述します。

WindowsコマンドプロンプトからActiveScriptRubyを使って実行するときは、あらかじめコードページをUTF-8に変更する必要があります。

chcp 65001

行の入れ替え方法

本スクリプトは入力した行をランダムに入れ替えますが、以下の規則に従います。ツイートを並べ替える目的で作りましたのでツイートと記しますが、ツイート以外の任意のUTF-8.jp文字列にも適用可能です。

未投稿のツイートを先頭に置く

既に述べた通り、ツイートの順序を入れ替えるのは、全ツイートが一周する直前です。そこであるツイートより後にあるツイートは未投稿とみなして前に出力し、それ以外の(投稿済みの)ツイートをその後に出力します。

例として、本レポジトリにあるshuffleLinesSample.txtを用います。このファイルには{1,2,3,4,5,a,b,c,d,e}と、各行に先頭から順に記述しています。ここで最後のツイートが5だとします。このとき、はじめに未投稿のツイート=a..eをランダムに選んで出力し、その後に投稿済のツイート=1..5をランダムに選んで出力するには、以下の通り実行します。

ruby -Ku shuffleLines.rb -i shuffleLinesSample.txt -p 5

結果は毎回変わりますが、必ず英字が前に続き、その後に数字が続きます。

この機能を有効にするためには、-pオプションを用います。-pオプションで与える文字列を最初に含む行を、最後の投稿とみなします。最後の投稿以外のツイートに一致しないよう、-pオプションで与える文字列は、改行を除いたツイート全文にするなど十分長くしてください。例えばwcコマンドで調べるとよいでしょう。

# int3を指定したつもりが、int32が混じっている
$ grep int3 cppFriendsBot.txt
わざとint3を踏んで...
uint32_t = 1を一度に35回シフトして...
uint32_tとかuint64_tとか...

$ grep int3 cppFriendsBot.txt | wc
      3      15     736

-pオプションを指定しない場合は、全ツイートをランダムに入れ替えます。

分類の異なるものをほどよく混ぜる

具体的には、「やめるのだフェネック」で始まるツイート、「けものフレンズ」を含むツイート、それ以外のツイートが、できるだけ交互に出現するようにします。現在は「やめるのだフェネック」で始まるツイートが過半数を占めていますので、「やめるのだフェネック」で始まるツイートが連続することがありますが、それ以外のツイートが連続することは少なくなるようにします。

上記以外の分類を用いる場合は、本スクリプトの LINE_PATTERN_SET 変数に、順に適用する正規表現を設定してください。

ツイートの検査

-cまたは--checkオプションをつけると、ツイートを検査して、指摘事項を標準エラー出力に書き出します。このオプションの有無によって、出力されるツイートが変わることはありません。指摘内容が的外れであれば、単に無視してかまいません。指摘内容は以下の通りです。

メンションがある

おそらく他のツイッターユーザに、何かを1回だけ伝えてたくてbotにツイートを登録したのでしょう。もう一度伝えたいのでなければ、そのツイートは削除したいのだと思います。

メンションとして扱う文字列は、@の後に英数字またはアンダーバー(_)が並び、前後が空白、行頭または行末の文字列です。

未登録のハッシュタグがある

あるハッシュタグが流行ったのでツイートしたが、次回botで投稿する頃には旬を過ぎていることがあります。そのようなツイートを見つけるために、未登録のハッシュタグを列挙します。今後も使い続けそうなハッシュタグは、スクリプトの変数 HASHTAG_SET に追加してください。C++プリプロセッサ指令(#include)はハッシュタグと誤認されるので、適宜追加してください。

入力ストリームに含まれるハッシュタグ一覧は、以下のシェルコマンドから作ることができます。

$ cat cppFriendsBot.txt | tr "\\r " "\\n" | egrep -o "#\\S+" | sort | uniq

終了コード

正常終了時は、終了ステータス0で終了します。それ以外の場合は、0以外の終了ステータスで終了します。例えば以下のような場合に終了します。異常系は作り込んでいませんので、明示的に例外を投げる場合以外にも、Ruby処理系が例外を投げて終了することがあります。

  • 指定したファイルを開けなかった
  • 入力ファイルと出力ファイルが同じだった
  • 入力に解釈できない文字があった。入力がShift_JISだった場合もエラーになります。
  • -pオプションで与えた文字列を含むツイートが見つからなかった

ユニットテスト

以下を実行すると、結果を報告します。実行には本レポジトリにある、先の例で用いたcppFriendsBot.txtとshuffleLinesSample.txtが必要です。cppFriendsBot.txtは、私が自動投稿しているTwitterアカウントの原稿です。

ruby -Ku shuffleLinesTest.rb

ライセンス

本レポジトリのREADME.mdに記載の通りです。