ジャンル不定の日記です。

なんか突然フォントのアンチエイリアスが効かなくなった

今メインPC再起動したらアンチエイリアスが効かなくなった。
即再起動しなかったが、今日pacman -Syuやってるんだが、怪しいのはない。
前回pacman -Syuは11月23日で、kernelのアップはなかったからそれより前から再起動してなかった可能性はある・・・

~/.config/fontconfig/ に変更された形跡はなく、
KDEのアプリはシステム設定からアンチエイリアスを設定するとKDEのアプリには適用されたように見えるんだが、Firefoxが汚いまま・・・

CS918ってのがWall Mount対応ぽい

次のサブPCをx86ではなく安いARM機にしようかと思って、ボードPC・スティックPC・TV-BOXなどARM機を調査している。

raspberry pi等のボードPCはスティックPCやTV-BOXに比べて高いし、コスパ的にx86のAMDチップに劣るんじゃないかと思う。
スティックPC・TV-BOXは3,000円程度から無線LAN搭載で箱までついてるんで、ハードスペック的には安いと思う。
スティックPC・TV-BOXの問題は、Googleのパクリで始めた製品だからなんだと思うがAndroidがプリインされてるのが大問題。
タッチパネルのないHDMIディスプレイに繋いで使うのにAndroidとかねえわw

あと、NUCに代表されるx86のPC-BOXはほとんどの製品がVESAマウント対応だが、AndroidのTV-BOXはディスプレイに繋いで使う製品なのにVESAマウント対応してない。
のだが、CS918って製品の裏にWall Mount用の穴が2個ついてることに気づいた。
VESAマウントの記載はないが、本体サイズと写真の穴位置からVESAの10cm間の様に見える。
10cm付近の幅でWall Mount穴空けるなら、VESAマウントを考慮して正しく10cmになっているんじゃないかと・・・
仮に10cmじゃないとしても、穴さえあいてれば本体加工せずにVESAマウントできると思う。


というわけで、CS918ってAndroid TV BOXに興味あり。

出品によってハードスペックの記載が違ってて怪しいんだが、
CPUはRK3188(T)かRK3128(T)ぽい
メモリ1GB,ストレージ8GB
電源は5V2AのDCジャック
USBは後ろに1個・横に1個と MicroUSB(母艦PCとの通信用?)
HDMIとLINE outとSPDIF
無線LAN(802.11n アンテナ付き)とBluetooth
RJ45(100BASE-TX)
TF(SD)スロット

で、eBayだと送料込み5,000円弱くらいから。
日本Amazonのマーケットプレイスとかでも同じの売ってるが、6,000円以上になりそう。

スティックPCと比べてちょっと値段高いかなと思うが、サブPCとしてはスペックはこんなもんでいいと思う。
ストレージは遅い可能性もあるが、CPU性能とかは全然問題ないはず。


PCとして使うのにAndroidは無理あるからLinuxに載せ替えるのが大前提だが、
この手のTV-BOXはRockChipかAmlogicのCPU搭載品が多いようなんだが、ROM焼きはRockChipの方ができそうな感じする・・・
OS載せ替えが無理だったら、メディアプレーヤーにしかならんかね・・・

スティック型よりTV BOXの方が良い気はするんだが・・・

次に買うサブPCを、x86の普通のPCじゃなくてスティック型とかHDMI出力付きのBOX型Androidでも良いと思って調べてるんだが、
スティック型はどの製品も有線LANはついてないが、HDMI出力付きのBOX型Android端末の場合は、どの製品も100MぽいがRJ45 LANコネクタついてるんだね。
ルーター化も考えてるから、スティックよりもBOXの方が良さそうな感じ。
価格はBOXの方が若干スティックより高いかなって感じだが、4,000円弱からある。

サブ機用のスペックとしては十分と思うから、割とマジで安いAndroid PCを買おうと思ってるんだが、
ルーター化するにしてもデスクトップ用途で使うにしてもLinux載せたいよね。
ってわけで、安い製品探しながら、当該端末とか搭載CPUでのLinux導入事例とか調べてるんだが、
この手の製品はスマホやタブレットと違って、タッチパネルではなくマウスやキーボードで操作するんだから、なんでLinuxじゃなくてAndroidが載ってるんだ?ってことに気づいた・・・

raspberry piみたいなボードPCと同じように最初からLinux前提になってれば安心なんだがな・・・
あと、BOX型はx86だとNUCとかの小型ベアボーンに近い製品と思うが、VESAマウント対応製品がないんだよね。
ディスプレイやテレビにHDMIで繋いで使う物なんだから、VESAマウント対応にしてくれればいいのに。

ルーターのLEDが赤点滅

メイン機と交換したためサブPCが無くなって購入を検討しているが、
Elecomの無線ルーター(WRC-300FEBK)が結構頻繁にダウンするんで、サブPCをルーター兼用にすることを考えてeBay見たりしてる。

自宅のネットワーク構成が、
フレッツ
|
ルーター - 無線
|
有線
てな感じで、今は有線はメインPC1台しか繋がってない。

ルーターの価格を調べると、ホテル用となっている有線がWAN用1ポートしか無い製品だと、ebayとかだと1,000円未満で結構ある。国内でも1,000円超える程度で買えるね。
有線LANポート付きのルーターだと100Mbpsので海外通販でも安いのは選択肢が少なく2,000円超えちゃう感じ。
PCはGbps対応だしプロバイダも一応100Mbps↑の回線だから、できれば有線部がGのルーターが良いが、今使ってるのも100M。
G対応だと結構値段違ってくるし、発熱で落ちやすいよね。(まあ、今のルーターの落ちやすさは100Mなのに過去最悪だがw)

次のサブPCは無線でも良いかなーとは考えてるが、セキュリティー的にメインPCはできれば有線が良いかなーと思う。
だが、有線ルーターの下に無線ルーターをつける感じの構成もありかなと気づいた。
有線専用のルーターは今は家庭向けでは需要が少ないんだろうが、無線より選択肢が少なくて、新品買うとかえって高くなりそう。
海外通販だと、eBayでは1,000円未満はほとんど出品されておらず、Aliexpressだとかろうじて1,000円未満で買えそう。
国内通販だと2,000円弱からぽい。
が、ヤフオクで中古購入だと、送料が高く付くが1,000円未満でいけそう。
無線と同じで、安いのは100Mbpsの製品が主流だね。


ルーター製品ではなく、PC製品をルーター化は、
  • Mini-ITXとか普通のPC
  • raspberry piみたいなボードPC
  • スティックPC
  • スマホやタブレットを改造
  • ルーター製品をLinux化改造
てなパターンで考えた。

有線付きのルーターを用意するにはLANが2ポート以上なければならないが、元々ルーター用の製品以外ではLANポートが複数あるものはほぼ無い。
LANポートが複数のボードを買おうとすると、たぶんかなり高い。

というわけで、安くボードを調達するには、元々ルーターとして売られている安ルーターを購入してLinux化改造だが、
その場合は、グラフィック出力機能など無いからサブPCとして用途が限られてしまう。
サブPCとしては無いね。

raspberry piとかシングルボードPCもいろいろ調べたが、
多くの製品は有線LANが1ポートで無線無しだと5,000くらいから。無線付きだと10,000円近くしちゃうね。
10,000円出せばAMD Kabiniとか普通にPCとして問題ない性能のPCが用意できるのに、雑魚ボードに10,000円近く出すのはないな。
そこら中にある5V(USB)で給電できる製品があるってのは魅力ではあるが、5V2Aとか使うなら消費電力的にはKabiniと大差ないわな。
先日発売された?raspberry pi zeroとやらは$5の破格だが、LANが1ポートもないのが残念・・・

スティックPCは、RockChipの載った安い中華製品がeBayなら3,500円程度から買えそう。国内で買うと5,000円程度からぽい。
Androidの載ったARMスティックだと、AndroidにはたぶんPPPoEが無いから、中身をLinux化しないと厳しそう。
5V2A程度の給電がないと危なそうなんで、ルーターを自作したとしても発熱で安定させられないかもしれない。
どの製品も無線LANは搭載しているが、有線はないのでUSB用のLANアダプタをつける必要がある。
USB用のLANアダプタはeBayなら600円程度で買えそう。無線より高いんだよね・・・
スティックPCにはx86のXPUが載った製品もあるが、10,000円前後はする。10,000出すならKabini買う。

スマホやタブレットを改造は、液晶割れとか起動不可とかのジャンクでもよくね?
と思ったんだが、タブレットのジャンク高いね。
x86のジャンクは、PCとしてならジャンクでも普通に使えね?って感じだが、それをやってる人もいるんだろうかね。
スマホならヤフオクで起動するやつを1,000円未満で買えそう。
電池レスで起動できるように改造する必要があると思うが、HDMI付きの端末ならスティックPCと同じように使えそうな気がする。



そんな感じで、よくまとまってないが、
普通のx86のPCボードじゃないとLinux環境で自分で作っても安定させられないのかな。とも思う。
まあ、今のルーターが完全故障してもすぐに代替ネットワークを構築できるように、サブ機をルーター化できる準備をしておくのはありかな。
臨時用途ならメインPCは一時的に無線化してもいいと思うから、無線アダプタ買っておこうかな。PCIとかPCMCIAの古い無線アダプタは持ってるんだが。

サブPCとしては、安く済むならx86にこだわる必要はないかなと思ってる。
というわけで、3,000円台のスティックAndroidに興味あり。
だが、Linux載せるのに苦労するかもしれないから、ボードPCのが確実かな。
有線1ポートと無線付きのボードPCが5,000円未満であれば良いんだが・・・
ARMにLinuxで不安なのは、Adobe Flashあるの?ってこと。まあ、無いならないで諦めるが。



とか考えてたんだが、今使ってるルーター(WRC-300FEBK)のLEDが赤点滅してることに気づいた。
点滅してたのは[INFO]で、更新ファームがあると点滅するらしい。
確認したら、v1.05のファームがきてた。
Elecomのサイトに1.04までしかなくて、何が変わったのかわからないから適用は今度にしようかとも思ったが、更新しちゃった。
ファーム更新で安定するようになってたら神だが・・・

Google Drive API のバックアップスクリプトを改良した。

先日暗号化したローカルファイルをAPI使ってGoogle DriveにUPするPerlスクリプトを作ったが、
ファイルを読み込んでLWPでうpする仕様だったから、どうにかしてファイルを読み込まずに(メモリを使わずに)直接送れないかと方法を模索してた。

LWP::UserAgentやHTTP::Requestのコード見たりもしたんだが、
HTTP::Request::Commonの説明ではContentに配列のリファレンスでファイル名を渡せばメモリ使わず送れるみたいに書いてあるんだが、
コード見てもよくわかんないし、どっちにしろmultipart/form-data形式しか無理っぽい感じで、Google Driveではmultipart/relatedで送る必要があるのでダメぽい。
LWP以外にfurlってのも見たが、コマンド名を変えてるだけで中身はLWPと同じような気配だった。


というわけで、定番で使い慣れたPerl用HTTP通信モジュールのLWPではどうもできなそうなんで、より低レベルなIO::Socket::SSLを使って実装することにした。


#!/usr/bin/perl
###
$userId='Google ID';
$client_id='クライアントID';
$client_secret='クライアント シークレット';
$refresh_token='refresh_token';

$Folder='フォルダID';

$Type{'gz'}='application/gzip';
###
###
use LWP::UserAgent;
use IO::Socket::SSL;
use JSON;
###
my $res=&HttpRequest('POST',"https://www.googleapis.com/oauth2/v3/token","client_id=$client_id&client_secret=$client_secret&refresh_token=$refresh_token&grant_type=refresh_token");
our ($access_token)=$res=~/"access_token": "([^"]+)"/;
die if(!$access_token);

foreach(@ARGV){
    my ($dir,$name)=$_=~/^(.*?)\/?([^\/]+)$/;
    my ($ext)=$name=~/\.([^\.]+)$/;
    my $type=$Type{$ext}||'application/octet-stream';
    my $old=JSON::from_json(&HttpRequest('GET',"https://www.googleapis.com/drive/v2/files/$Folder/children?q=@{[&UrlEncode('title=\''.$name.'\'')]}"));
    my $new=JSON::from_json(&FileUpload($dir,$name,$type));
    if($new->{'id'}){
        foreach(@{$old->{'items'}}){
            &HttpRequest('DELETE',"https://www.googleapis.com/drive/v2/files/$_->{'id'}");
        }
    }
    sleep(1);
}
###
sub HttpRequest{
    my $method=shift;
    my $url=shift;
    my $body=shift;
    my $ua=LWP::UserAgent->new;
    my $req;
    if($method eq 'GET' || $method eq 'DELETE'){
        $req=HTTP::Request->new($method=>$url);
    }else{
        $req=HTTP::Request->new(POST=>$url);
        $req->content_type('application/x-www-form-urlencoded');
        $req->header(Content_length=>0) if(!$body);
        $req->content($body);
    }
    $req->header(Authorization=>"Bearer $access_token") if($access_token);
    my $res=$ua->request($req);
    return($res->content);
}
###
sub FileUpload{
    my $dir=shift||'.';
    my $name=shift;
    my $type="Content-Type: ".shift."\r\n\r\n";
    my $boundary=$name.time;
    my($head,$json,$len);
    $json="Content-Type: application/json; charset=UTF-8\r\n\r\n{'title':'$name','parents':[{'id':'$Folder'}]}\r\n";
    $len=length($json)+length($type)+(-s("$dir/$name"))+((length($boundary)+4)*3)+4;
    $head.="POST /upload/drive/v2/files?uploadType=multipart HTTP/1.1\r\n";
    $head.="Host: www.googleapis.com\r\n";
    $head.="Authorization: Bearer $access_token\r\n";
    $head.="Content-Type: multipart/related; boundary=\"$boundary\"\r\n";
    $head.="Content-Length: $len\r\n\r\n";

    my $sock=IO::Socket::SSL->new('www.googleapis.com:443');
    $sock->autoflush(1);
    print $sock $head;
    print $sock "--$boundary\r\n";
    print $sock $json;
    print $sock "--$boundary\r\n";
    print $sock $type;
    open(FILE,"$dir/$name");
    while(<FILE>){
        print $sock $_;
    }
    close(FILE);
    print $sock "\r\n--$boundary--\r\n";
    my($line,$len,$res);
    $line=$sock->getline;
    return if(!$line=~/^HTTP\S*200/);
    while(($line=$sock->getline) ne "\r\n"){
        $len=$1 if($line=~/^Content-Length: (\d+)/);
    }
    $sock->read($res,$len);
    $sock->close;
    return($res);
}
###
sub UrlEncode{
    my $str=shift;
    $str=~s/([^\w\-\.\~])/'%'.uc(unpack('H2',$1))/eg;
    return($str);
}
###
こんな感じ。
FileUpload 部分をLWP::UserAgentからIO::Socket::SSLに変更した。

Socket使う場合はヘッダから直接printで出力しちゃえばいいだけだが、ファイル読み込まずにContent-Lengthを計算するのがめんどい。
あと、前はファイル中にboundaryが出現しないかチェックしていたが、読み込まないんで決め打ちで「ファイル名+UNIXタイム」にした。出現しちゃったら失敗すると思うが、出現するようなことはありえないだろう。

Googleからのレスポンスをヘッダ取り除いて抽出しないといけないが、
自動で切断はされないようなんでレスポンスのContent-Lengthを確認して適切なサイズでreadしないとダメぽい。

ついでに、前はバックアップフォルダのファイル取得に https://www.googleapis.com/drive/v2/files に検索クエリでフォルダを指定していたが、
https://www.googleapis.com/drive/v2/files/フォルダID/children にGETすればフォルダ内だけに限定できるぽい。
そっちの方がわかりやすいから変更した。
最上位のファイルを取得する方法がわからなかったのだが、フォルダIDを"root"にすればルートフォルダの取得ができるぽいようなことも書いてあった。
これなら普通のファイルシステムみたいに使えるね。


目的通りメモリを使わずにUPできているかは確認しにくいが、topで見た感じだと問題無さそう。
これで大きいファイルもUPして問題なくなったから、サーバーのバックアップファイルなんかもGoogle Driveに上げちゃおうかと思う。
サーバーからのUPは転送量がきついが、自宅でPULLする代わりにGoogleにPUSHすれば同じだよね。
自宅よりもGoogleの方がデータ消滅の危険は少ないと思うし、自宅のストレージ節約もできる。

このところeBayよく見てるのだが・・・

このところeBayよく見てるのだが、買いたいものと価格について考えて整理してみる。

メインPC用にサブ機から交換したMSI AM1IにSATAが2portしかないので、どうにかしたい。
Mini PCIeを搭載しているので、

こんな感じのMini PCIe用のSATA増設カード使えばいいんだが、eBayでも安いので3,000円って感じ。
同じものが国内でも流通してるが、安くて5,000円するんじゃないかと。
そもそも、Mini PCIeではなくmSATAならコントローラー不要だからだと思うが、この手の製品はほとんど存在しない。
似たようなので写真見てコントローラー非搭載なことがわかるSATA変換カードが300円程度で存在するが、コントローラー無いのはmSATAでないと使えないはずなのでダメ。
AMD AM1はSATAが2portだが、ASRockのAM1マザーは追加2の4portで4,000円ちょいで買えそうなので、SATAボードで3,000円は論外。



今度のはminiじゃないPCIe用のSATA増設ボード。
国内では安いので2,000円程はするんじゃないかと思うが、eBayでは送料込み900円弱でいっぱい売ってる。
これは値段的に結構検討してる。
だが、mini-ITXマザーでPCIeは1個しか無いから、使っちゃうと他に何も挿せないんだよね・・・



PCIe使っちゃうのが問題なら、

↑こんな感じの内部USBの外部USB直結コネクタと、

USB→SATA変換を使うってのもありかなと考えた。
USBでSATAにすると速度低下しちゃうが、光学ドライブ用なら問題ないかなと・・・
内部USBのが600円程度で、SATA変換のが300円くらい。
USB-SATA変換のはパラレルも対応したケーブル持ってるが、SATAだけのやつだと安いね。
これは電源コネクタはないやつだが、電源付きのもさほど変わらない値段で売ってる。
内部で使う用途だと電源不要だが、外で使うことを考えると電源付きのが良いかね。


そんな感じでSATAの検討してるんだが、
次にマザー買うときに、Raspberry Piみたいにショボいのをサブ機用に買って、メイン機は今のままって可能性も考えてるんだが、
逆にメイン機用に良いの買って、今のをサブ機に回す可能性を考えると、SATA2portで足りちゃうんだよね。
PCIeの奴かUSB変換なら金額的に許容範囲かなと思うんだが、次のPC買うまで我慢しようかなとも・・・



地デジチューナーも、以前はPCIeのやつが欲しいと思ってたんだが、最近はブラジル向けのUSBのやつ買ったほうが良いかなと思ってる。
上のやつはたぶんRealtekのチップだと思うんだが、玄人はSianoチップの買うの?それっぽい奴はeBayで見つからない。
というか、この前某掲示板で中身がSianoだとかで晒されてて、Linuxで動きそうなら欲しいと思ったんだが、全部買いつくされちゃったぽいw
1,500円未満くらいなのかな?
Linuxで見れるならワンセグでも良いんだがな。


海外通販だと国内より全然安いものがあるから、5.25インチベイ用のリムーバブルなんかも欲しいと思って調べたんだが、国内と値段変わらない感じだった。
箱物は送料高いから海外通販向きじゃないのかね?

VirtualboxでVM起動してると母艦で音がでない

メイン機を今のマザーに変えてからなんだが、
VirtualboxでVMを起動してるとホストPCの方で音が出なくなる。

先日書いたが、今のマザーがサウンドデバイスがアナログとHDMIで2つあって何も設定しないとHDMIが先。
アナログで音出してるからHDMIの優先順位下げてるんで、それとの関係だと思うんだが、どうにかならんもんだろうか・・・


eBayで詐欺の返金

先日eBayで、

Android5.1
サイズ: 10インチ
メモリ: 1GB
ストレージ: 8GB
解像度: 1024x600

って、とりあえず使えそうなスペックのタブが、送料込み€11.0、なにこれ安いって感じで出品されてるのを見つけて、
出品者が作ったばっかのアカウントだったから詐欺じゃないかと思ったが、PayPalは詐欺で返金してもらいやすいようなんで即落してみた。

[流れ]
注文→決済
翌日連絡がなかったので、さらに次の日「いつ発送するの?」的な文で連絡。
相手から返信はなく、数日後にeBayから、「出品が消えたから返金求められるよ」的なメール。
メールに従って返金請求。
相手から連絡無しで、PayPal(eBay?)が全額返金。

ってな感じになった。
カードの方はまだ反映してないが、PayPalの履歴には「カードに返金」となってた。

80人近く買ってる人いたけど、返金求めない人がいたらお金GET!の詐欺なのかな?


PayPalアカウントに返金だったら、PCIeのSATA増設かUSB接続のテレビチューナー買おうかと思ってたが、カードに返金なんだね。

日本で使えそうな南米向けのテレビチューナーが1000円ちょいで存在するらしいんで、
日本のテレビチューナーは暗号化されててLinuxで動かないから、南米チューナー欲しい。

Google Drive API使えた

先程はGoogle Developer Consoleで認証情報が設定できなくて後日にしようと思ってたが、Googleさん治ってたんで、Google Drive APIを使ったバックアップを導入した。
APIは、怪しいプログラムをインストールするよりも自分で作っちゃおう。って考えたので、慣れたPerl使った。


導入手順は、
  1. Google Developer Consoleでプロジェクトを作成。
  2. Drive APIを有効にして他は無効に。
  3. OAuth2.0クライアントIDを作成。(種類は「その他」で作った)
  4. "code"の取得。
  5. "refresh_token"の取得。
さっきできなくてハマったが、DNS関連だと思うがタイミングが悪いと3.のクライアントIDの作成ができない。

3.でクライアントIDを作成すると"クライアントID"と"クライアント シークレット"が表示されるが、両方共プログラムで使うのでメモっとく。

4.の"code"は、5.の"refresh_token"を取得するために必要でブラウザでURLにアクセスしてプログラムを許可すると表示される。
https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/drive&response_type=code&redirect_uri=urn:ietf:wg:oauth:2.0:oob&client_id=[クライアント ID]
↑接続するURLはこんな感じ。
scopeはプログラムに与える権限で、"https://www.googleapis.com/auth/drive"はGoogle Driveの全権限。リードオンリーとかもできる。
response_typeは、"code"の場合はredirect_uriで指定したURLの末尾にクエリでつけられてリダイレクトされる。
クライアントプログラムを作るのでリダイレクト用のページなど存在しないが、その場合は"urn:ietf:wg:oauth:2.0:oob"を指定するとGoogleのページでコードを表示してくれる。
取得できたコードは5.の"refresh_token"を取得するために1回だけ必要。

5.の"refresh_token"の取得は、POSTでリクエストしないといけないので、curlコマンドを使って、
curl -d redirect_uri=urn:ietf:wg:oauth:2.0:oob -d client_id=[クライアント ID] -d client_secret=[クライアント シークレット] -d grant_type=authorization_code -d code=[ブラウザで取得したコード] https://accounts.google.com/o/oauth2/token
こんな感じでリクエストを投げるとJSON形式で返ってくる。
"refresh_token"だけが必要。


で、ファイルPATH(又はカレントディレクトリのファイル名)をパラメータで渡すとGoogle DriveにアップロードするPerlスクリプトを作った。
#!/usr/bin/perl
###
$userId='Google ID';
$client_id='クライアントID';
$client_secret='クライアント シークレット';
$refresh_token='refresh_token';

$Folder='フォルダID';

$Type{'gz'}='application/gzip';
###
###
use LWP::UserAgent;
use JSON;
###
my $res=&HttpRequest('POST',"https://www.googleapis.com/oauth2/v3/token","client_id=$client_id&client_secret=$client_secret&refresh_token=$refresh_token&grant_type=refresh_token");
our ($access_token)=$res=~/"access_token": "([^"]+)"/;
die if(!$access_token);

foreach(@ARGV){
    my ($dir,$name)=$_=~/^(.*?)\/?([^\/]+)$/;
    my ($ext)=$name=~/\.([^\.]+)$/;
    my $type=$Type{$ext}||'application/octet-stream';
    my $old=JSON::from_json(&HttpRequest('GET',"https://www.googleapis.com/drive/v2/files?q=@{[&UrlEncode('\''.$Folder.'\' in parents and title=\''.$name.'\'')]}"));
    my $new=JSON::from_json(&FileUpload($dir,$name,$type));
    if($new->{'id'}){
        foreach(@{$old->{'items'}}){
            &HttpRequest('DELETE',"https://www.googleapis.com/drive/v2/files/$_->{'id'}");
        }
    }
    sleep(1);
}
###
sub HttpRequest{
    my $method=shift;
    my $url=shift;
    my $body=shift;
    my $ua=LWP::UserAgent->new;
    my $req;
    if($method eq 'GET' || $method eq 'DELETE'){
        $req=HTTP::Request->new($method=>$url);
    }else{
        $req=HTTP::Request->new(POST=>$url);
        $req->content_type('application/x-www-form-urlencoded');
        $req->header(Content_length=>0) if(!$body);
        $req->content($body);
    }
    $req->header(Authorization=>"OAuth $access_token") if($access_token);
    my $res=$ua->request($req);
    return($res->content);
}
###
sub FileUpload{
    my $dir=shift;
    my $name=shift;
    my $type=shift;
    my($file,$count,$body);
    open(FILE,"$dir/$name");
    while(<FILE>){
        $file.=$_;
    }
    close(FILE);
    while($file=~/\-\-$name$count/){
        $count++;
    }
    $body="--$name$count\nContent-Type: application/json; charset=UTF-8\n\n{'title':'$name','parents':[{'id':'$Folder'}]}\n";
    $body.="--$name$count\nContent-Type: $type\n\n".$file."\n--$name$count--\n";
    my $ua=LWP::UserAgent->new;
    my $req=HTTP::Request->new(POST=>"https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart");
    $req->content_type("multipart/related; boundary=\"$name$count\"");
    $req->content_length(length($body));
    $req->content($body);
    $req->header(Authorization=>"OAuth $access_token");
    my $res=$ua->request($req);
    return($res->content);
}
###
sub UrlEncode{
    my $str=shift;
    $str=~s/([^\w\-\.\~])/'%'.uc(unpack('H2',$1))/eg;
    return($str);
}
###
こんな感じ。
赤字のとこは自分用に入力。

普通にファイルシステムを使う感じとはだいぶ違ってて、把握するのが結構難しかった。
普通のファイルシステムと一番違うのが、PATH的な概念がなくPATH指定で対象を選択できない。
ローテートするのが面倒かと思ったんだが、PATHが無いので同じ場所に同名ファイルを置けるんで、同じ場所にアップロードして成功したら古いの削除しちゃうだけで良いことに気づいたんで、そうした。
アップロードするファイルを置くフォルダは、PATHが無いので毎回検索クエリを投げなきゃダメかとも思ったが、
フォルダのIDはブラウザでフォルダにアクセスした時のURL末尾の文字列と同じだったんで、プログラムに直接設定する仕様にした。

%Typeで拡張子を設定しておけばアップロード時にファイルタイプを指定して送るが、未設定のファイル場合は"application/octet-stream"で送る。

ファイルPATHをパラメータとして渡すとアップロードするけど、パラメータのPATHはスペース区切りで複数可。
アップロードに1秒以上かかるだろうが、秒間10リクエストまでの制限があるようなので、1ファイル毎に1秒寝る。

アップロード成功したら対象フォルダ内の古い同名ファイルは削除するが、
失敗した場合(idが取得できなかった場合)は、古いのそのままにしとく。



てな感じで、Google DriveのAPIが使えたんで、
先日のファイル暗号化をバックアップスクリプトに導入して、今回のGoogle Driveのアップロードスクリプトを使ってクラウドでバックアップするようにした。
これで万が一自宅PCのデータがバックアップストレージからの復元すらできないような状況に陥っても、致命的な状況に陥るのは回避できそう。

Google Driveでのバックアップを導入しようとしたが・・・

昨日バックアップファイルの暗号化をシェルスクリプトでやるようにして、暗号化したファイルをGoogle Driveに保存するようにしようとした。

Google DriveはArch Linux + KDEの標準では使えず、AURで「google drive」で検索すると、それっぽいのが複数出てきて迷う。
google-drive-ocamlfuse ってのが、マウントできるツール。
grive ってのが、同期ツール。
その他複数あるのは、Google Drive のAPIコマンドをCUIから使うためのコマンド。
って感じぽい。


AURのプログラムはどれもきちんとメンテされるのか怪しいし、APIコマンドを使うなら、Perlで自分で作っちゃえばよくね?
ってことに気づいた。
手元のマインOSが変わることや、Google以外のストレージに移行する場合なんかも、自前で作っちゃったほうが流用効くし。

以前PerlでGmailのAPI使うプログラムを作ったんで、それ参考にGoogle Drive のAPIを・・・
とやったんだが、なんかGoogle Developer Consoleで認証情報のところに行くと、
「サービス アカウントを読み込めませんでした。」
とエラーが出る。
無視してOAuthのキーを作成しようとすると、
「読み込めませんでした」
と表示されて無理・・・

FirefoxではなくChromeで試したりしてもダメ。
わからなくて、表示を英語にしてみてググったが、DNSの不整合でつながってないぽい?
日を改めてやることにするかな。


先日Windows10入れたらoneDriveとかってのがあったから、
GoogleじゃなくてMicrosoftのストレージも試してみようかな。APIあるよね?