gaggitのブログ

コーディング、ガジェット、TIPS関連、FX

Perl Undefined subroutineが出たら、やってみたいこと

Perlのモジュールの中のサブルーチンを使用していますが、Perlを実行すると、「Undefined subroutine &main::サブルーチン名」と表示され、エラーとなる場合があります。

その時には、以下のようにソースを修正するとうまくいきます。

修正前:

use モジュール名;

修正後:

use モジュール名 qw(サブルーチン名);

または、

use モジュール名 qw(:ALL);

 

PerlでFusionTablesへのquery接続に成功

Google API ExplorerのRequestを参照して、query後にkey(api_key)を使用して、FusionTablesへweb接続すると、「401 Login Required」(Webでのリプライ)、「401 Unauthorized」(Perlでのリプライ)で失敗します。

webで接続する場合には、key(api_key)ではなくaccess_tokenを使用してください。

 

失敗

ttps://www.googleapis.com/fusiontables/v2/query?sql=select+*+from+FusiontableのId&key={YOUR_API_KEY}

 

成功

ttps://www.googleapis.com/fusiontables/v2/query?sql=select+*+from+FusiontableのId&access_token={access_token}

 

 

参照サイト:

Google APIs Explorer

Using OAuth 2.0 for Authorization to Fusion Tables in Web Applications  |  Fusion Tables REST API  |  Google Developers

 

 

Excelで図形を使用する時には

Excelで図形を使用する時には、「図形」と「図形の選択」を頻繁にクリックすることになるのですが、Excel画面の広さによっては、3,4クリックする羽目になり、大変非効率です。

例えば、ディスプレイ画面の半分の広さでExcel画面を表示させた状態で、「図形の選択」をクリックするには、「ホーム」「編集」「検索と選択」「図形の選択」と4クリック必要になります。

同様に、図形を選択する時にも「挿入」「図」「図形」「(図形)」と4クリックです。

そんな時には、「図形の選択」と「図形」コマンドを「クイック アクセス ツール バー」に設定すると、1クリックで済みます。

 

設定方法

1.「メニュー」で右クリックして、1行目の「クイック アクセス ツール バーのユーザー設定」をクリックします。

2.Excelオプション画面で、「図形」コマンドを選択し、「追加」をクリックします。

3.「コマンドの選択」で、「すべてのコマンド」を選択する。

4.下のリストから「図形の選択」コマンドを選択し、「追加」をクリックします。

5.「OK」ボタンをクリックします。

f:id:gaggit:20170918225415p:plain

設定後のExcel画面

f:id:gaggit:20170918230546p:plain

 

 

 

Perl Net::Google::DataAPI::Auth::OAuth2のインストール

前回、XML::LibXMLモジュールのインストールに成功したので、Net::Google::DataAPI::Auth::OAuth2のインストールを行ってみました。

cpanm Net::Google::DataAPI::Auth::OAuth2であっけなく、インストールできました。(一応、perldoc Net::Google::DataAPI::Auth::OAuth2でインストール確認)

Net::Google::DataAPI::Auth::OAuth2のSYNOPSISを再度、読み返すと、プロンプトから入力をたくしているので、どうやら認証コード(code)を自動で取得し、アクセストークンにできるわけではないようです。

 

 

参照サイト:

gaggit.hatenablog.com

Net::Google::DataAPI::Auth::OAuth2 - search.cpan.org

 

libxml2とXML::LibXMLのインストール

PerlのNet::Google::DataAPI::Auth::Auth2モジュールのインストールの前提条件として、XML::LibXMLモジュールが前提となってます。さらに、このモジュールの前提条件として、libxml2とXML::NamespaceSupport、XML::SAXモジュールのインストールが前提となっています。64bitで開発環境を整えているので、ここでは、libxml2の64bit版のインストールを紹介します。

XML::NamespaceSupport、XML::SAXモジュールのインストール

1.XML::NamespaceSupportとXML::SAXをインストールします。

cpanm XML::NamespaceSupport

cpanm XML::SAX

 

詳細は忘れてしまいましたが、--forceオプションで成功した気がします。

libxml2のインストール

1.下記の本家のサイトをクリックし、左側のRelated linksから「WIndows binaries」をクリックします。

http://www.xmlsoft.org/downloads.html

 

2.「Getting the Binaries」の章の1行目にある「download area」をクリックし、ftpサイトの「64bit」をクリックします。

 

3.拡張子が7zであるlivconv,libtool,libxml2,libxslt,mingwrt,openssl,xmlsec,zlibをダウンロードし、ファイルを解凍します。

 

4.64bit shared zipのファイルをダウンロードし、拡張子が7zであるlivconv,libtool,libxml2,libxslt,mingwrt,openssl,xmlsec,zlibを解凍します。

 (解凍には7-Zipを使用)

 

5.解凍して作成されたフォルダであるbin,include,lib,shareをD:\usrにコピーします。

 

6.D:\usr\include\libxml2\libxml配下にあるヘッダファイルを一段上のlibxml2フォルダにコピーします。

 

7.gettext-toolsの64bitのshared版をダウンロードします。

 下記のURLから「Downloading gettext」の最下行にある「precompiled binaries for Windows」をクリックします。

https://www.gnu.org/software/gettext/

 

8.解凍して作成されたbin,lib,shareをD:\usrフォルダにコピーします。

 

9.システム変数のPATHにD:\usr\binを追加します。

 

 

XML::LibXML2のインストール

1.下記のリンクをクリックし、XML-LibXMLのモジュールをダウンロードします。

http://search.cpan.org/CPAN/authors/id/S/SH/SHLOMIF/XML-LibXML-2.0129.tar.gz

2.ダウンロードしたファイルを解凍します。

3.コマンドプロンプトを開き、解凍したフォルダに移動します。

4.以下を実行します。

perl Makefile.PL INC="-ID:\usr\include\libxml2 -ID:\usr\include" LIBS="-LD:\usr\lib" DEBUG=1 2>D:\temp\make.log

DEBUG以降の行は記述しなくても大丈夫ですが、デバッグがやりやすくなります。

5.dmakeを実行します。(1回目、エラーが出力されて終了)

6.D:/usr/lib配下のlibxml2.aを_libxml2.aにリネームします。

7.項番4.を再度、実行します。

8.dmakeを実行します。

9.dmake testを実行します。

 All tests successful.

Result: PASSと表示されます。

 

10.dmake installを実行します。

11.perldoc XML::LibXMLを実行し、インストールが成功しているか、確認します。

 

 

参照サイト:

www.opswat.com

http://www.xmlsoft.org/downloads.html

 

 

Perl でFusiontablesに自動アクセス

Perlを使用して、ようやくFusiontablesへの自動接続に成功しました。下記が、サンプルコードです。前提条件としては、なんらかのWebサーバのアプリをインストールする必要があります。

サンプルコード

use utf8;
use Encode;
use JSON;
use Time::Local;
use IO::Handle;
#Oauth2
use Google::API::Client;
use Google::API::OAuth2::Client;
use WWW::Scripter;

open(FD,"> D:\\temp\\log.txt");
# OAuth generate uri
my $auth = Google::API::OAuth2::Client->new({
auth_uri => "https://accounts.google.com/o/oauth2/auth",
token_uri => "https://accounts.google.com/o/oauth2/token",
client_id => "Google APIのクライアントID",
client_secret => "Google APIのクライアント シークレット",
redirect_uri => "http://127.0.0.1:8080",
auth_doc => {
oauth2 => {
scopes => {
"https://www.googleapis.com/auth/fusiontables"
}
}
}
});
# Oauth2 execute
my $mech = WWW::Scripter->new(
autocheck=>1,
show_progress=>1 # prints to stderr
);
$mech->get($auth->authorize_uri);
print(FD "mech->content1=".$mech->content."\r\n");
$mech->submit_form(
fields=>{
Email=> 'Emailアドレス'
}
);
print(FD "mech->content2=".$mech->content."\r\n");
$mech->submit_form(
fields=>{
Passwd=> 'Emailアドレスのパスワード'
}
);
$mech->follow_link(
n=>1
);

# browser
$uri=$mech->uri;
$option=" -new-tab \"$uri\"";
system('"C:\\Program Files\\Mozilla Firefox\\firefox.exe "', $option);

sleep 30;
open(FDL,"< "webサーバのログファイル名を指定");
my ($sentence, $temp, $code);
while($sentence = <FDL>){
($temp,$code) = ($sentence =~ /^(.*code=)(.*)/);
}
if (substr($code,-1,1) ne "#"){
$code = $code."#";
}
$auth->exchange($code);
# Service
my $client = Google::API::Client->new;
my $service = $client->build('fusiontables', 'v2');
my $body = {
'tableId' => 'fusiontablesのId'
};
my $res = $service->column->list(body=>$body)->execute({
"auth_driver" => $auth});
my @column_list;
for $item (@{$res->{items}}){
push @column_list, $item;
}
for my $column (@column_list){
$column_name=$column->{name};
print(FD "column_name=$column_name\r\n");
}

 

簡単にコードの説明をすると、Google::API::OAuth2::Clientで認証URLを作成しています。

次にWWW::Scripterで認証URLを実行し、Emailアドレス認証画面(submit_form)でEmailアドレスを自動入力、follow_linkでhtmlのhrefが記述されているURLを取得しています。

3番目に先ほどのURLを引数に指定してブラウザ(Firefox)を起動します。

4番目にWebサーバーのログを取得し、アクセストークン用のcodeを取得しています。

最後にGoogle::API::Clientを使用して、Fusiontablesをアクセスし、カラム名を表示しています。

 

p.s.

Webを操作するのに当初、WWW::Mechanizeのモジュールを使用していましたが、JavaScriptが記述されているhtmlでは動作しないことが判明し、次にWWW::Mechanize::Firefoxで試行しました。このモジュールはMechanizeから派生したモジュールですが、単体では動作せず、FirefoxにMozReplプラグインをインストールし、さらにメニュー「ツール」「MozRepl」「start」を実行しないと動作しないので、プログラミングを途中で断念しました。

次にWWW::Scripterモジュールで試行し、とりあえずFusiontablesにアクセスするのに成功しました。このモジュールもMechanizeから派生したモジュールです。

最後に2,3日前に見つけたモジュールNet::Google::DataAPI::Auth::OAuth2を使用すると、認証URLの作成からアクセストークンの取得まで簡単にやってくれそうです。時間があったら、こちらも試したいと思います。

 

参照サイト

Net::Google::DataAPI::Auth::OAuth2 - search.cpan.org

 

 

 

 

Perl Google::API::Client 使い方

8/4(金)にGoogle::API::Clientがインストールできた。が、どのようなメソッドがあるかはよく分からないので、まずは、cpansearch.perl.orgのサイトからGoogle::API::Clientのソースを見てみる。23行目あたりに

...'https://www.googleapis.com/discovery/v1/apis/{api}/{apiVersion}/rest'

とあるので、ブラウザで
https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest
と入力してみると、Calendar APIの仕様がJSONで返ってきた。
methodsで検索してみると、中段あたりに以下の様に表示されている。

f:id:gaggit:20170805001909p:plain

ということは、
うえちぇこさんのブログで$service->calendarList->list->exectuteの
部分は、このmethodsの上下の部分に該当。これでなんとか、メソッドが分かったので、他のAPIでも応用がききそうです。
次回は、FusionTablesでこの方法でメソッドを利用できるか、やってみます。





 

 

参照サイト:

http://cpansearch.perl.org/src/SHIGETA/Google-API-Client-0.14/lib/Google/API/Client.pm

[perl]Google::API::Clientを使ってみた | うえちょこ@ぼろぐ