From 589e4352b35e96ea3b0cf56e0281533bb024241a Mon Sep 17 00:00:00 2001 From: satomichan Date: Wed, 27 Aug 2025 00:01:41 +0900 Subject: [PATCH] 1st ver. --- foltia-dl.pl | 250 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100755 foltia-dl.pl diff --git a/foltia-dl.pl b/foltia-dl.pl new file mode 100755 index 0000000..45be956 --- /dev/null +++ b/foltia-dl.pl @@ -0,0 +1,250 @@ +#!/usr/bin/env -S perl -w + +# foltia-dl.pl ---- foltia ANIME LOCKER 録画データ ダウンローダ +# (https://satomichan.jp/foltia-dl) +# +# foltia ANIME LOCKER (https://foltia.com/ANILOC/) が動作している +# Webサイトから録画・録音ファイルをダウンロードし, +# メタデータ(番組名・放送局名・放送時間)を付加して保存するツールです. +# +# 使い方: +# foltia-dl.pl [--tsv] [--grep ] +# +# --tsv または -t を指定すると, タブ区切りテキスト出力モードになります. +# 指定しないときが通常モードで, シェルで実行可能な文字列を出力します. +# --grep <正規表現文字列> を設定すると, 番組名が<正規表現文字列>に +# 合致した場合のみ出力します. +# +# 実行例: +# foltia-dl.pl --grep 'きょうの(料理|健康)' | bash +# +# $FOLTIA_HOST を指定している箇所は, 環境に合わせて foltia ANIME LOCKER が +# 動作しているホスト名またはIPアドレスに書き換えてください. +# +# +# Copyright 2025 FUKUDA Satomi (https://satomichan.jp/) +# +# Licensed under the Apache License, Version 2.0 (the “License”); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an “AS IS” BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# +# See the License for the specific language governing permissions and +# limitations under the License. + +use strict; +use warnings; + +use utf8; +binmode STDOUT, ":utf8"; +binmode STDERR, ":utf8"; + +use HTTP::Tiny; +use Encode; +use HTML::Entities; # apt install libhtml-parser-perl +use Getopt::Long qw(:config posix_default no_ignore_case gnu_compat); + +#要変更箇所 お使いの環境に合わせて書き換えてください. +# (foltia ANIME LOCKER が動作しているホスト名またはIPアドレス) +our $FOLTIA_HOST = 'http://FOLTIA-ANIME-LOCKER.test'; + +#保存ファイル名(拡張子を除いた部分)の最大長さ(bytes) +our $LIMIT_LENGTH_OF_FILE_BASE_NAME = 80; + + + +#オプション解析 +my %opts; +GetOptions( \%opts, ('tsv|t', 'grep=s') ); +our ($is_tsv_mode, $is_cmdline_mode, $opts_grep); + +#TSVモード or コマンドラインモード(通常) +if ($opts{'tsv'}) { + $is_tsv_mode = 1; +}else{ + $is_cmdline_mode = 1; +} + +#番組名grep +$opts_grep = Encode::decode('UTF-8', $opts{'grep'}); + + + +my $cnt_programs = 0; +my %used_filename; + +get_rec_table('/recorded/recfiles_all.php'); + +print STDERR "ダウンロード対象 番組数:$cnt_programs ファイル数:@{[ 0+ keys %used_filename ]}\n"; + +exit; + + + +sub get_rec_table { + my ($a_path) = @_; + my $resp = HTTP::Tiny->new->get($FOLTIA_HOST. $a_path); + + if ($resp->{success}) { + my $body = Encode::decode('UTF-8', $resp->{content}); + + #レコード(番組)ごとのループ + while ($body =~ m||sg) { + my $rec = $&; + $rec =~ s/(
)|\n|\r//g; + + my ($chapter) = $rec =~ m|(.+?)|; #話数 + + next unless $chapter; #話数がなければ番組ではない + next if $rec =~ /watchnow/; #録画中 + + my ($pid) = $rec =~ m|pid=(-\d+)|; + + my $date; + if ( $rec =~ m|(\d{4})/(\d{2})/(\d{2})\(.+\) (\d{2}):(\d{2})| ) { + $date = "$1-$2-$3T$4:$5"; + } + + my ($title) = $rec =~ m|(.+?)|; + $title = HTML::Entities::decode_entities($title); #HTML文字実体参照(&xxxx;) デコード + + my (@paths) = $rec =~ m||g; + + die "日時・番組名が取得できませんでした. rec=$rec" unless $date && $title; + + #番組名grep + if ($opts_grep) { + next unless $title =~ /$opts_grep/; + } + + #ここまできたら, DL対象の番組である + $cnt_programs++; + + #放送局・放送長さ取得 + my($station, $min) = ('', ''); + if ($pid) { #テレビ番組のとき + ($station, $min) = get_detail($pid); + + }else{ #ラジオ番組のとき + ($station) = $paths[0] =~ m|-(\w+)\.\w+$|; + } + + #print "($chapter,@{[ $pid ? $pid : '' ]}) $date, $title, $station, $min, {@paths}\n"; + + #ファイル名 基本部 + my $basename = make_basename($date, $title); + + + #DL対象ファイルごとのループ + foreach my $a_path (@paths) { + + #拡張子 + my ($ext) = $a_path =~ /\.(\w+)$/; + $ext = lc $ext; + + #ファイル名 重複あるとき + $basename .= "_c$chapter" if $used_filename{"$basename.$ext"}; + + $used_filename{"$basename.$ext"} = 1; + + if ($is_tsv_mode) { + #TSV出力モード + my @outputs = ("$basename.$ext", $a_path, $title, $station, "$date (${min}min)"); + print join("\t", @outputs). "\n"; + + } elsif ($is_cmdline_mode) { + #コマンドライン出力モード + print "wget --continue -O '$basename.$ext' '$FOLTIA_HOST$a_path'"; + + #.mp4のとき -> メタ情報を付加するコマンドも出力 + if ($ext eq 'mp4') { + $title =~ s/'/'\\''/g; + print " && ffmpeg -nostdin -i '$basename.$ext' -metadata title='$title' -metadata artist='$station' ". + "-metadata date='$date' -metadata comment='$date (${min}min)' -codec copy $chapter.$ext"; + print " && mv $chapter.$ext '$basename.$ext'"; + } + + print "\n"; + } + + + } #DL対象ファイルごとのループ + + + } #レコード(番組)ごとのループ + + #次の HTML ページ + get_rec_table($1) if $body =~ m|