Last active
April 8, 2019 11:21
-
-
Save naoh16/25c8e79996578f948936 to your computer and use it in GitHub Desktop.
サイボウズLiveの添付ファイルをダウンロードするスクリプト
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!env perl | |
=encoding UTF-8 | |
=head1 NAME | |
cb_download_attachment.pl - サイボウズLiveの添付ファイルを取得する | |
=head1 SYNOPSIS | |
# 1. Prepare download directory | |
$ mkdir download | |
# 2. Create/edit config file | |
$ vi cb_config.pl | |
{ | |
# Authentication | |
'username' => '', # サイボウズLiveのアカウント、空白にすると端末から入力できる | |
'password' => '', # サイボウズLiveのパスワード、空白にすると端末から入力できる | |
'oauth' => { | |
'consumer_key' => '', # 開発者サイトで登録してから入力する | |
'consumer_secret' => '' | |
}, | |
'terminal_encoding' => 'utf8', | |
'group_id' => '', # グループのID。アクセスしたときのURLの数字から読み取る(1_0123456など) | |
} | |
# 3-1. Run the script (... download attachment file from 0 to 99) | |
$ perl cb_download_attachment.pl 0 | |
# 3-2. Run the script (... download attachment file from 100 to 199) | |
$ perl cb_download_attachment.pl 100 | |
=cut | |
use utf8; | |
use strict; | |
use warnings; | |
use feature ':5.10'; | |
use Encode; | |
use Data::Dumper; | |
use Term::ReadKey; | |
use WWW::Mechanize; | |
use HTML::TreeBuilder::XPath; | |
use OAuth::Lite; | |
use OAuth::Lite::Consumer; | |
use XML::FeedPP; | |
my $cb_config = require 'cb_config.pl'; | |
my $g_terminal_encoding = $cb_config->{'terminal_encoding'} || "cp932"; | |
my $oauth_token_url = 'https://api.cybozulive.com/oauth/token'; | |
my $login_url = 'https://cybozulive.com/login'; | |
my $g_download_url = 'https://cybozulive.com/_GROUP_ID_/gwCabinet/downloadFileDirect?cid='; | |
my $g_file_detail_url = 'https://cybozulive.com/_GROUP_ID_/gwCabinet/view?cid='; | |
my $username = $cb_config->{username} || get_tty_username(); | |
my $password = $cb_config->{password} || get_tty_password(); | |
my $start_id = shift || 0; | |
## | |
## Authentication for Web-browser | |
## | |
my $mech = WWW::Mechanize->new(); | |
# LOGIN | |
$mech->get( $login_url ); | |
$mech->submit_form( | |
fields => { | |
loginMailAddress => $username, | |
password => $password, | |
} | |
); | |
## | |
## Authentication for API | |
## | |
my $consumer = OAuth::Lite::Consumer->new( | |
consumer_key => $cb_config->{oauth}->{'consumer_key'}, | |
consumer_secret => $cb_config->{oauth}->{'consumer_secret'}, | |
); | |
my $res = $consumer->obtain_access_token( | |
url => $oauth_token_url, | |
params => { | |
x_auth_username => $username, | |
x_auth_password => $password, | |
x_auth_mode => "client_auth", | |
}, | |
); | |
unless($res) { | |
say "Failed to get access token"; | |
die dump($consumer->oauth_response); | |
} | |
say "ACCESS_TOKEN:"; | |
say " TOKEN: " . $res->token->token; | |
say " SECRET: ". $res->token->secret; | |
my $group_id_colon = $cb_config->{group_id}; | |
my $group_id_url = $cb_config->{group_id}; | |
$group_id_colon =~ s/_/:/; | |
$group_id_url =~ s/:/_/; | |
$g_download_url =~ s/_GROUP_ID_/$group_id_url/; | |
$g_file_detail_url =~ s/_GROUP_ID_/$group_id_url/; | |
## | |
## Find attachment files | |
## | |
my $res2 = $consumer->request( | |
method => "GET", | |
url => "https://api.cybozulive.com/api/gwCabinet/V2", | |
token => $res->token, | |
params => { | |
group => $group_id_colon, | |
'cabinet-folder' => 'ATTACH', | |
'start-index' => $start_id, # TODO: MAKE AS LOOP!! | |
'max-results' => '100' # max should be "< 100" | |
}, | |
); | |
die "Error!!" unless($res2->is_success); | |
## | |
## Download attachment files | |
## | |
my $feed = XML::FeedPP->new($res2->decoded_content||$res2->content); | |
foreach my $item ( $feed->get_item() ) { | |
my $id = encode($g_terminal_encoding, $item->guid() ); | |
my $title = encode($g_terminal_encoding, $item->title() ); | |
my $filename = encode($g_terminal_encoding, $item->get('cblCbnt:fileName') ); | |
print "ID: " . $id . "\n"; | |
print " Title: " . $title . "\n"; | |
print " Filename: " . $filename . "\n"; | |
my %id_hash = split(/,/, $id); | |
print " CID: " . $id_hash{CABINET} . "\n"; | |
my $file_cid = $id_hash{CABINET}; | |
$file_cid =~ s/^1\://; | |
my $new_dir = prepare_download_directory($mech, $file_cid, $group_id_url); | |
$mech->get( | |
$g_download_url . $file_cid, | |
':content_file' => $new_dir . '/' . $filename | |
); | |
# last; # for debug | |
} | |
exit 0; | |
########################################################### | |
sub prepare_download_directory { | |
my $mech = shift; | |
my $cid = shift; | |
my $gid = shift; | |
# my $file_detail_url = 'https://cybozulive.com/'.$gid.'/gwCabinet/view?cid=' . $cid; | |
my $file_detail_url = $g_file_detail_url . $cid; | |
$mech->get($file_detail_url); | |
my $tree= HTML::TreeBuilder::XPath->new; | |
$tree->parse($mech->content()) or die "parsing failed"; | |
my $node = $tree->findnodes( '//div[@class="attachmentLinkSource"]/a' )->[0]; | |
my $text = encode($g_terminal_encoding, $node->as_text() ); | |
my $href = encode($g_terminal_encoding, $node->attr('href') ); | |
print "FILE_DETAIL: " . $text . "\t" . $href . "\n"; | |
$mech->get($href); | |
my $new_dir_name = encode($g_terminal_encoding, $mech->title() ); | |
## trim 1 hyphens from its tail... | |
$new_dir_name =~ s/ \-[^\-]*$//; | |
$new_dir_name =~ tr|/:|__|; | |
$new_dir_name = 'download/' . $new_dir_name; | |
print $new_dir_name; | |
mkdir $new_dir_name; | |
open my $fh, '>', $new_dir_name . '/index.html'; | |
binmode $fh; | |
print $fh encode('utf8', $mech->content()); | |
close $fh; | |
return $new_dir_name; | |
} | |
sub get_tty_password { | |
print "Password: "; | |
ReadMode "noecho"; | |
chomp( my $line = ReadLine 0 ); | |
ReadMode "restore"; | |
print "\n"; | |
#print STDERR "input: $line\n"; | |
return $line; | |
} | |
sub get_tty_username { | |
print "Username(E-mail): "; | |
ReadMode "normal"; | |
chomp( my $line = ReadLine 0 ); | |
print "\n"; | |
print STDERR "input: $line\n"; | |
return $line; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment