Twitterで強制的にPNG32でアップロードするツールを作った。

Twitterに画像をPNGでアップロードするツール
作りました。左上1pxの透明度を1%だけ落として強制的にPNG32でアップロードします。

Lenna(元画像)

Lenna(アップロード後)

差分

RGBAだと1だけ下がってるように見えます。ソースは以下。
retrorocket/twimage: Twitterで画像を強制的にPNGでアップできるようにする
PerlMagick便利ですね。

画像の引用元は以下です。
Lenna – Wikipedia

TimeLine Copierで1000人近くリストに入れようとするとTwitter側から不審なアクティビティ扱いされる。

お問い合わせがあったのですが、たまたま今日早く帰ってくることになってたので調査しました。
事象としては、3000人近いフォロワーがいるユーザがTimeLine Copierでリストを作ると、1000人超えた当たりでアカウントがロックされるというものです。
とりあえずガチャピンのフォロワーでリストを作ったのですがなるほど1000人くらいになったところでtwitterを覗くと以下の画面に飛ばされました。

ロックされた

私としてはどうしようもないので、800人位登録したら一旦登録を打ち切って、しばらく経った後に既存リストに追加してもらう機能を使ってもらうしかないですね。アプリは修正します。

追記(2017/06/28)

一回アカウントロックされるとしばらくcreate_allエンドポイントが使用不能になるみたいですね。めちゃくちゃ不便だ…。テスト用のアカウントで試したら500人でアウトだったので大事をとって300人位にしておくことにしました。

TwitterのアイコンをAPI経由でアップロードするツールに強制PNGモードを追加した。

TwitterのアイコンをAPI経由でアップロードするツール

ImageMagickとPerlMagickを入れるのがひたすらめんどくさいという理由だけで対応してなかったのですが、アイコンも丸くなるし強制JPGにされるしでうんざりしたので対応しました。
githubには後でpushしておきます。ソースはこんな感じで、左上の1pxの透明度を1から0.99に変更して元画像に極力影響ないようにPNG32に変換しています。

	#PNG変換モード
	if($self->session("png32")){
		my $img = Image::Magick->new;
		$img->Read($image_file);
		$img->Set(alpha => 'On');
		my @pixels = $img->GetPixel(x=>0,y=>0);
		$pixels[3]=0.998; #透明度を99%にする。
		$img->SetPixel(x=>0, y=>0, color=>\@pixels);
		binmode(STDOUT);
		$img->Write("PNG32:".$image_file);
		undef $img;
	}

やっぱりImageMagick便利ですね。クライアント側で変換させてもよかったのですが、upico使用ユーザ層のITリテラシー的にクライアントで変換させると余計トラブルになりそうなのでやめました。
みんなもうちょっと自分で調べるとかしてくれるといいんですが。

入れたImageMagickは7.0.6で、PerlMagickがうまいこと入らなかったので以下の記事を参考にしました。
ImageMagickインストール済みのとこからImage::Magick(PerlMagick)をコンパイル・インストールする方法 – Qiita
make perl-sources してなくてハマりました。

追記(2017/06/29)

座標の指定方法が間違ってたので修正しました。

Bash on Ubuntu on WindowsでMojolicious::LiteとかNet::Twitter::Liteを動かす。

Windows 10 Anniversary Update(Windows 10 バージョン 1607)を適用したので、Bash on Ubuntu on Windowsを使ってみました。念には念を入れて、アップグレードツールを使わずにWindows Updateから適用できる段階でアップデートしたのですが、失敗してOSごと起動しなくなったりしました。相変わらずですね。
私の環境の場合、MacTypeとセキュリティソフトとタッチパッドのドライバが原因だったので、セーフモードで無理やり起動させて原因のアプリを停止させた後、ツールからアップデートしたらうまくいきました。
自分のマシンだとWindows Helloは予想通りサポートされなかったので、使いたかった機能がbashだけになりました。
OSビルドは14393.51です。

Tech TIPS:Windows 10のLinux/Ubuntu互換環境でbashを使う – @IT
ここを見ながらbashを使えるようにしてみました。ちなみに、私の環境だと、bashを使うときにコマンドプロンプトのオプションから「従来のコンソールを使う」のチェックボックスを外さないと動きませんでした。
Bash on ubuntu on Windowsが起動できません。 – マイクロソフト コミュニティ

sudoすると、「名前解決が出来ません」と言われてしまうので、/etc/hostsに「127.0.0.1 ホスト名」を追加しておきました。
ちなみにPerlはv5.18.2でした。メイン環境のさくらVPS/CentOS 7環境がv5.16.3なので、ubuntuのほうがバージョン上ですね。
ubuntuのバージョンは以下のとおり。

➜  ~ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.5 LTS"

ちなみにoh-my-zsh使ってみたのですが、(やっぱり)文字化けしちゃいました、

ホームディレクトリの実体は以下にありました。

C:\Users\ユーザ名\AppData\Local\lxss\home\ubuntuのユーザ名

cpanでモジュールを導入しようとした

最初はcpanでMojoliciousを入れようとしたのですが、「Warning: the following files are missing in your kit」みたいな感じで全然makeできないので、cpanは使えませんでした。cpanmならいけるかもしれないけどめんどくさいので試してません。

apt-getで導入する

ubuntuだとapt-getでperlのモジュールを導入できるので、sudo apt-getで導入してしまいました。

➜  ~ sudo apt-get install libmojolicious-perl
➜  ~ sudo apt-get install libnet-twitter-lite-perl

無事導入できました。

Mojolicious:Liteを動かしてみる

以下のスクリプトをhypnotoadで実行して、http://localhost:8181にアクセスしてみました。

#!/usr/bin/perl

use strict;
use warnings;
use utf8;

use Mojolicious::Lite;
app->config(
  hypnotoad => {
    listen => ['http://*:8181'],
    },
);

get '/' => sub {
  my $self = shift;
  return $self->render(json =>{test => "hello world"});
} => 'index';
app->start;

bashから動かすMojoLite

bashから動かすMojoLite


わーい動いた。

Net::Twitter::Liteを動かしてみる

以下のスクリプトを動かしてみました。

#!/usr/bin/perl

use strict;
use warnings;
use utf8;

use Net::Twitter::Lite::WithAPIv1_1;
use Encode;

my $nt = Net::Twitter::Lite::WithAPIv1_1->new(
consumer_key => $consumer_key,
consumer_secret => $consumer_key_secret,
access_token => $access_token,
access_token_secret => $access_token_secret,
ssl => 1
);

my $tl = $nt->user_timeline();

for my $status(@$tl){
    print encode_utf8($status->{text} ."\n");
}

コンソールから実行してみる

コンソールから実行してみる


わーい動いた。

試したけどできなかったこと

mongodb3は導入できませんでした。以下のStackOverflowの記事と同じ症状です。
Windows 10 Linux Subsystem. How to install MongoDB – Stack Overflow

感想

VirtualBoxでやれ。
ちなみにrm -rfしたらどうなるのかなーと思ったら、やっぱり試してる人がいて「あっ…」てなりました。
`rm -rf /` on Bash on Ubuntu on Windows – Qiita

TwistOAuthでイカのレギュラーマッチの現在のステージをツイートする。

API初心者ですhttp://splapi.retrorocket.biz/こちらのサイトにあるデータを使… – Yahoo!知恵袋
APIってなんだろう…。Win32APIのことでしたらこちらの動画がチュートリアルとして最適です。
【プログラミング】テトリスを1時間強で作ってみた【実況解説】 – ニコニコ動画:GINZA

splapiが返却するのはただのJSONなので、Web APIどうこうはもはや関係ない気がしましたがどうなんでしょうか。
まずググりながら素のJSON操作→ほしい箇所だけechoするところから始めて、次にTwitterにテスト文字列をツイートして、そこまでできたら下のサンプル読んでみてほしいなぁ、と思いました。

PHPからツイートするのには以下のライブラリがとても便利でした。pharを1ファイルDLで済むのと、それと例外処理でかゆいところに手が届くのが素晴らしいです。(Twitter API自体例外発生時のエラーレスポンスめちゃくちゃなので)
mpyw/TwistOAuth: Advanced PHP Twitter library. (Launched branch v3.x and released stable 3.5.2)
普段Perl使ってるし、PHPはWordPress専用言語だと思ってるので、PHPからTwitter API使うことはもうなさそうですが、機会があればまた使ってみようと思います。(PHP自体使わなすぎてブログカテゴリすら存在しない)

実行マシンはRaspberry Pi2 Model B(OSはraspbian wheezy)を使いました。phpのバージョンは以下。

 xxx@raspberrypi ⮀ ~ ⮀ php -v
PHP 5.4.45-0+deb7u2 (cli) (built: Oct 27 2015 23:22:07)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2014 Zend Technologies

注意点として、実行時にPHP Fatal error: Call to undefined function curl_init() が出てしまう場合は、php5-curlをインストールする必要があることくらいでしょうか。
私の環境では上記エラー解消後すぐ動きました。

<?php
 
require_once 'TwistOAuth.phar';
 
define('CONSUMER_KEY', 'xxx');
define('CONSUMER_SECRET', 'xxx');
define('ACCESS_TOKEN', 'xxx');
define('ACCESS_TOKEN_SECRET', 'xxx');
 
// ツイート用オブジェクト作成
try {
    $to = new TwistOAuth(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET);
}
catch (TwistException $e) { 
    echo $e->getMessage() . "\n";
}
 
// JSON取得
$url = 'http://splapi.retrorocket.biz/regular/now';
$json = file_get_contents($url);
 
// 配列化
$array = json_decode($json,true);
$map_array = $array['result'][0]['maps'];
 
// ツイート用文字列作成
$tweet_string = '【現在のレギュラーマッチステージ】';
foreach( $map_array as $value ){
    $tweet_string = $tweet_string ."\n". $value;
}
echo $tweet_string; 
 
// ツイート
try {
    $to->post('statuses/update', ['status' => $tweet_string]);
} catch (TwistException $e) { 
    echo $e->getMessage() . "\n";
}
 
?>

知恵袋に回答してるカテゴリマスターさんが色んな意味で香ばしくてすごかったです。ある程度香ばしくないと起業とか経営ってできないのかもしれないですね。