Last active
June 1, 2023 05:27
-
-
Save panam510/c5d0fd8cd969e2809f87ced217a4f6d8 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| #!/usr/bin/perl | |
| # ニコニコ生放送 タイムシフト予約スクリプト | |
| use 5.14.2; | |
| use warnings; | |
| use utf8; | |
| use Encode; | |
| use LWP::UserAgent; | |
| use HTTP::Cookies; | |
| use HTTP::Request::Common; | |
| use Getopt::Std; | |
| $Getopt::Std::STANDARD_HELP_VERSION = 1; | |
| our $VERSION = 20230601; | |
| binmode STDOUT, ":utf8"; | |
| # 引数の処理 | |
| our($opt_d, $opt_f, $opt_u, $opt_p); | |
| getopts("dfu:p:"); | |
| #ID・パスワードは、以下シングルクォーテーション内に直書き。 | |
| #ただし、-u,-pオプションで渡されたらそちらを優先。 | |
| my $user = $opt_u // '[email protected]'; | |
| my $pass = $opt_p // 'password'; | |
| my $is_debug = $opt_d; #エラー時にサーバからの応答を出す(デバッグ用) | |
| #my $is_force = $opt_f; #タイムシフト上書きフラグ(デフォルト上書きになったため廃止) | |
| my $liveurl = shift; | |
| my $vid; | |
| #URLから動画ID取得 | |
| if ( !(defined($liveurl)) ){ | |
| #URLの指定がない | |
| die "liveurl is required.\nUsage: $0 [-d] [-f] [-u userid] [-p password] liveurl\n"; | |
| }elsif( $liveurl !~ /\A(?:https?.*\/)?((?:lv)?(\d+))\z/){ | |
| #動画IDっぽい文字列がない | |
| die "liveurl is not valid.\nUsage: $0 [-d] [-f] [-u userid] [-p password] liveurl\n"; | |
| }else{ | |
| #URLの「lv+数字」部分を取得 | |
| $vid = $1; | |
| } | |
| #ログイン部 | |
| my $url = 'https://account.nicovideo.jp/api/v1/login'; | |
| my %account = ( | |
| mail_tel => $user, | |
| password => $pass, | |
| ); | |
| my %ua_option = ( | |
| agent => "nicotsreserve.pl", | |
| timeout => 30, | |
| ); | |
| my $ua = LWP::UserAgent->new(%ua_option); | |
| my $request = POST($url, [%account]); | |
| my $cookie_jar = HTTP::Cookies->new; | |
| my $response = $ua->request($request); #ログインを試行 | |
| $cookie_jar->extract_cookies($response); #user_sessionを取得 | |
| #予約部 | |
| $url = sprintf("https://live2.nicovideo.jp/api/v2/programs/%s/timeshift/reservation",$vid); | |
| $request = POST($url); | |
| $cookie_jar->add_cookie_header( $request ); | |
| $response = $ua->request($request); | |
| my $authflag = $response->header("X-Niconico-Authflag"); | |
| unless (defined $authflag && ($authflag == 1 || $authflag == 3)){ | |
| #ログイン失敗。 | |
| #アカウントID・パスワードが違うか、ニコニコのメンテナンス中? | |
| &debugmsg; | |
| die "Can't login. Incorrect account, or under maintenance.\n"; | |
| } | |
| my $content = $response->content; | |
| if ( $content =~ /\"status\":200/){ | |
| #うまく行ったっぽい | |
| &debugmsg; | |
| say "Hoolay! Reservation succeeded. liveid: ".$vid; | |
| }elsif( $content =~ /PROGRAM_NOT_FOUND/){ | |
| #生放送が存在しない | |
| &debugmsg; | |
| die "Reservation failed. Program not found.\n"; | |
| }elsif( $content =~ /EXPIRED_(GENERAL|PREMIUM)/){ | |
| #予約期限が切れている。一般会員だと「EXPIRED_GENERAL」、プレミアム会員だと「EXPIRED_PREMIUM」が返る | |
| &debugmsg; | |
| die "Reservation failed. Reservation has expired.\n"; | |
| }elsif( $content =~ /DUPLICATED/){ | |
| #すでに予約されている | |
| &debugmsg; | |
| die "Already reserved.\n"; | |
| }else{ | |
| #未検証エラー | |
| #予約件数の上限に達しているなど? | |
| &debugmsg; | |
| die "Reservation failed. Add the -d flag and check the cause.\n"; | |
| } | |
| #デバッグ用関数 | |
| sub debugmsg { | |
| if($is_debug){ | |
| say STDERR "An error occurred. The response is shown below:"; | |
| say STDERR $response->as_string; | |
| } | |
| } | |
| sub HELP_MESSAGE { | |
| say "Usage: $0 [-d] [-f] [-u userid] [-p password] liveurl"; | |
| say ''; | |
| say 'liveurlは以下いずれかの形式で指定:'; | |
| say ' http://live.nicovideo.jp/watch/lv012345678'; | |
| say ' lv012345678'; | |
| # say ' 012345678'; | |
| say ''; | |
| say 'Option:'; | |
| say ' -d 予約できなかった際、サーバからの応答を標準エラーへ出力する(デバッグ用)'; | |
| # say ' -f 予約件数の上限に達しているとき、期限切れの予約があれば上書きする'; | |
| say ' -u \'[email protected]\' ユーザID。スクリプト内の記述より優先される'; | |
| say ' -p \'password\' パスワード。同上'; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment