foltia ANIME LOCKER用 予約重複 チェックツール

2025/07/20 19:39 Perl
自動録画予約ソフトウェア foltia ANIME LOCKER を利用していますが、予約重複でチューナー不足になっているのを見逃して録画に失敗してしまい、残念な思いをすることがあります。
そこで、予約一覧から予約時刻が重複している番組を抽出するツールを作成しました。
Perl で書いてあります。cron で実行すると重複予約があるときだけメールで知らせてくれるように出来ます。

ソース
#!/usr/bin/env perl

use strict;
use warnings;

use HTTP::Tiny;


our $FOLTIA_HOST = 'http://localhost:80';

get_reservation_table('/reservation/');
exit;



sub get_reservation_table {
    my ($path) = @_;
    my $resp   = HTTP::Tiny->new->get($FOLTIA_HOST. $path);
    
    if ($resp->{success}) {
        my $body = $resp->{content};
        while ($body =~ m|<tr.+?</tr>|sg) {
            my $rec = $&;
            $rec =~ s/<br>|\n|\r//g;
            my ($id)      = $rec =~ m|id="(-\d+)"|;
            next unless $id;
            
            my ($station) = $rec =~ m|<td class="station">(.+?)</td>|;
            my ($date)    = $rec =~ m|<td class="date">(.+?)</td>|;
            my ($title)   = $rec =~ m|<td>(.+?)</td>|;
            die "放送局・日時・番組名が取得できませんでした. rec=$rec" unless $station && $date && $title;
    
            print "$id $date $station $title\n" if check_overwrap($id);;
        }
        
        get_reservation_table($1) if $body =~ m|<a rel=next href="(.+?)" >|;
        
    } else {
        die "予約一覧が取得できませんでした. get=$FOLTIA_HOST$path";
    }

}



sub check_overwrap {
    my ($id) = @_;
    
    my $api_url = "${FOLTIA_HOST}/reservation/reservation_overwrap_chk_api.php?p=$id";

    my $resp = HTTP::Tiny->new->get($api_url);
    
    if ($resp->{success}) {
        my $body = $resp->{content};
        if(  my ($overwrap) = $body =~ /"overwrap":"(.*?)"/  ) {
            return $overwrap;
            
        } else {
            die "overwrap 文字列が取得できませんでした. api_url=$api_url";
        }
        
    } else {
        die "overwrap が取得できませんでした. api_url=$api_url";
    }

}

Excel で切手組み合わせ問題を整数計画問題として解く

2025/07/17 19:44 整数計画問題
当サイトでは任意の額面を手持ちの切手を組み合わせて用意する 切手組み合わせ計算ツール を公開しています。
その内部では整数計画問題ソルバである GLPK (Gnu Linear Programming Kit) を使って切手の使用枚数が最小となる最適解を求めていますが、同様のことを Microsoft Excel を使って求めてみようと思います。

準備

  1. Excel のオプション -> アドイン -> 管理 -> Excel アドイン -> ソルバーアドイン があるのを確認 -> 設定ボタンをクリック
    excel-option.png
  2. ソルバーアドイン にチェック -> OK ボタンをクリック
    excel-add-in.png

入力フォーマットや数式の入力

  1. 例えば次のようなフォーマットを用意します。
    excel-main-formula.png

    Excel ファイルは こちら
    xlsx_icon.png
    kitte.xlsx
    です。
  2. C2 セルに 組み合わせたい金額を入力します
  3. B5 セルから B24 セルには切手の単価を入力します。とりあえず現在発売中の切手の金額を入力します。
  4. D5 セルから D24 セルに手持ちの枚数を入力します。
  5. F5 セルから F24 セルに後ほど結果が代入されます。なんでもいいのですが、とりあえず 0 で埋めておきます。
  6. C26 セルは組み合わせ試行中の合計金額を表します。数式 =SUMPRODUCT(B5:B24,F5:F24) を入力します。この数式は (単価×枚数) の総和を意味します。
  7. C27 セルは組み合わせ試行中の合計枚数を表します。数式 =SUM(F5:F24) を入力します。これがこの問題の最小化させたい目的関数となります。

ソルバーの設定

  1. メニューの データ タブ -> 分析 -> ソルバー をクリック
    excel-menu-solver.png

    excel-solver-setting.png
  2. 目的セルを C27 に設定します。このセルは合計枚数を示すものです。
  3. 目標値は 最小値 を選択します。合計枚数を最小にする解を得たいからです。
  4. 変数セルは F5:F24 にします。ソルバーによってこの範囲に各切手の枚数が代入されていきます。
  5. 制約条件の対象 に3つ条件を追加します。
    • (1) C26 = C2
      これによって合計金額が指定の金額と等しくなるように制約します。
      excel-subject-to-total.png
    • (2) F5:F24 <= D5:D24
      これによって各切手の使用枚数が各々の在庫数以下であることを制約します。
      excel-subject-to-stock.png
    • (3) F5:F24 = 整数
      これによって切手の使用枚数が整数しか取り得ないことを制約します。
      整数に制約したいときには真ん中のセレクトボックスで int を選択します。
      excel-subject-to-integer.png
  6. 制約のない変数を非負数にする にチェックします。切手の使用枚数はマイナスにはならないからです。
  7. 解決方法の選択 では シンプレックスLP を選択します。ここで解決したい問題が線形を示す問題だからです。
  8. 最後に 解決 ボタンをクリックします。

結果を読む

  1. 「整数解が見つかりました」と出たら成功です。
    excel-solver-found.png
    • ソルバーの解の保持 を選択して OK ボタンをクリックします。
    • F5:F24 セル範囲に代入されている枚数が答えです。
  2. 「実行可能解が見つかりませんでした」と出たら、手持ちの切手では合計金額ちょうどの組み合わせが作れなかったということです。
    excel-solver-not-found.png
    • 計算前の値に戻す を選択して OK ボタンをクリックして戻り、在庫枚数などの条件を見直しましょう。

参考

  1. Wikipedia日本語版「整数計画問題」: https://ja.wikipedia.org/wiki/%E6%95%B4%E6%95%B0%E8%A8%88%E7%94%BB%E5%95%8F%E9%A1%8C
  2. Wikipedia日本語版「切手問題」:https://ja.wikipedia.org/wiki/%E5%88%87%E6%89%8B%E5%95%8F%E9%A1%8C

Linux desktop (MATE) でランチャから起動された端末(Terminal)のタイトルを変更する方法

2025/02/07 22:23 Linux
Linux Desktop (MATE) において ワンクリックでアプリケーションを起動させたいとき、カスタム・アプリケーションのランチャをパネルに追加します。
そのソフトが CUI のソフトのときは キーの型を[端末内で機能する]とするのですが、それを起動するときタスクバーに表示されるタイトルが単に[端末]となってしまい、何が実行されているのか分かりづらいです。
Windows の bat ファイルでは title コマンドを使って 実行されているウインドウのタイトルを簡単に変更できるのですが、同様のことを Linux で実現する方法を探しました。

アイコン右クリック > [プロパティ] > [コマンド] に次のように指定します。
bash -c "echo -ne '\033]0;'\"TITLEタイトル\"'\a'; sleep 10 ; exit"

TITLEタイトル がタイトルになります。sleep コマンド以降は適宜実行したいコマンドに置き換えてください。

set_terminal_title.png
実行されている様子

radiko 録音予約ツール

2024/10/09 15:34 LinuxPerl
radiko でインターネット配信されるラジオ番組を、指定した時刻に予約録音するツールを制作しました。

録音には うる。 氏による radish (https://github.com/uru2/radish) を利用しました。
通常では radiko そのままの m4a ファイルで保存されますが、当ツールでは録音後に m4a -> mp3 変換を掛けます。この変換を無効化することもできます。

なお当ツールは radiko 限定としましたが、radish は radiko 以外にも NHK らじる★らじる・リスラジ他多数のネットラジオに対応したソフトです。すばらしい成果を公表してくださいましたことに感謝いたします。

ソースファイル

動作要件

  • Linux など
  • radish が単独で正常に動作していること(パスの通っている場所に配置してください)
  • at (ジョブの遅延実行とバッチ処理) がインストールされていること。

実行方法の例

当ツール rec-radiko.pl を実行権をつけて、パスの通っている場所 (/usr/local/bin/ など) に配置して、
$ rec-radiko.pl [-c|--check] [-n|--no-conversion-to-mp3] <放送局ID> <録音開始日> <録音開始時刻> <録音長(分)> <タイトル>
のように実行してください。
-c または --check任意atコマンドを発行せずに、コマンドの内容を表示します。
-n または --no-conversion-to-mp3任意録音後の mp3 形式への変換をしません。
<放送局ID>必須放送局ID
<録音開始日>必須録音開始する日付を YYYY-MM-DD 形式で指定します。 例: 2024-09-02
<録音開始時刻>必須録音開始する時刻を24時間制で hhmm または hh:mm 形式で指定します。 例: 305, 0305, 3:05, 03:05
<録音長(分)>必須録音の長さを分単位で指定します。 例: 61
<タイトル>必須タイトルを指定します。

環境変数 RADIKO_SAVE_TO に保存先のディレクトリを指定します。
~/.bashrc などに
export RADIKO_SAVE_TO=/var/radiko/save/to
のように追記すればよいでしょう。

放送局ID の確認方法

 $ radi.sh -l | perl -ne 'print if /radiko/../^$/'
を実行すると確認できます。

補足

録音時に f-radiko.smartstream.ne.jp (203.211.199.181) からこちら向きの通信 (TCP/40000台Port宛て) が来るときがあるので、拒絶しないようにします。
拒絶すると録音ができませんでした。ただし必ず来るわけではないです。(しくみがよくわかっていない)

2024-09-11対策済み: at の落とし穴 (?) セット時のカレントディレクトリがなくなってしまったときの問題

このツールでタイマー録音をセットしたのに、録音に失敗するケースがありました。
rec-radiko.pl を実行した時点のカレントディレクトリを削除して(あるいは名前変更して)しまうとダメなようでした。
at -c <job番号> で確認してみると
cd /home/*****/aaaaa/bbbbb || {
         echo 'Execution directory inaccessible' >&2
         exit 1
}
のような記述があって、at を読んだときのディレクトリが存在しなくなると失敗させるようになっていました。

Windows 起動後, ネットワーク接続が安定するまで動作を待つためのプログラム

2025/07/20 0:32

Windows 起動時のスタートアップ処理として、ネットワークドライブにドライブレターを割り付けるバッチファイル (中身は net use コマンドなど) を呼び出しているのですが、思いのほかネットワーク接続の確立に時間がかかり、動作に失敗してしまうことがあります。バッチファイルから呼び出す形で、ネットワーク接続が安定するまで次のコマンドの実行を遅延させるプログラムを書きました。

ソースコード waitnet.vb

' Copyright 2023 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.

Public Module WaitNet
    Public Function Main(args As String()) As Integer
        'コマンドライン引数
        If args.Length <> 4 Then
            Console.WriteLine("USAGE:  waitnet <host> <port> <timeout(sec)> <retry(num of times)>")
            Console.WriteLine()
            Console.WriteLine("ex)  waitnet.exe www.nhk.or.jp 80 2 3")
            Return 255
        End If

        Dim host    As String  = args(0)
        Dim port    As Integer = Integer.parse(args(1))
        Dim timeout As Integer = Integer.parse(args(2))
        Dim retry   As Integer = Integer.parse(args(3))

        Dim tcp As New System.Net.Sockets.TcpClient



        ' 接続
        Dim IsConnectSuccess As Boolean
        Do
            IsConnectSuccess = true
            Try
                Dim task = tcp.ConnectAsync(host, port)
                If Not task.wait(timeout * 1000) Then
                    IsConnectSuccess = false
                End If
            Catch ex As System.Exception
                IsConnectSuccess = false
            End Try

            If IsConnectSuccess Then Exit Do
            If retry = 0 Then Exit Do

            Console.WriteLine("ReTry: More " & retry & " times To Go.")
            retry = retry - 1
            System.Threading.Thread.Sleep(5000)
        Loop While retry >= 0



        ' 結果
        Console.WriteLine("IsConnectSuccess: " & IsConnectSuccess)
        If IsConnectSuccess Then
            Return 0
        Else
            Return 1
        End If

    End Function
End Module

VB.NET で書かれていて、Windows 附属のコンパイラ (vbc.exe) でコンパイル出来ます。

コンパイルのしかた (例)

>C:\Windows\Microsoft.NET\Framework64\v4.0.30319\vbc.exe waitnet.vb
Microsoft (R) Visual Basic Compiler version 14.8.9037
for Visual Basic 2012
Copyright (c) Microsoft Corporation.  All rights reserved.

This compiler is provided as part of the Microsoft (R) .NET Framework, but only supports language versions up to Visual Basic 2012, which is no longer the latest version. For compilers that support newer versions of the Visual Basic programming language, see http://go.microsoft.com/fwlink/?LinkID=533241


>

ネットワーク接続が安定するまで遅延実行させたい処理の書き方 (バッチファイルの例)

@echo off
C:\waitnet.exe 192.168.1.1 445 5 10
if ERRORLEVEL 1 goto ERR

net use N: \\192.168.1.1\nas passwwww /user:user2

:ERR
exit

数式参照先シフト Excel など表計算ソフト用 数式参照先セルの座標を必要な分だけ上下左右にずらした式を得るためのツール

2023/12/26 12:42

Excel などの表計算ソフト利用時に、数式内で参照しているセルの座標を必要な分だけ上下左右にずらしたいときがあります。一つや二つならばマウスでドラッグすることで容易にずらせますが、対象の数が多いと大変です。そこで、この作業を簡単に行えるツールをつくりました。

Excel などから数式をコピーして次のテキストボックスに貼り付けて、移動する数を指定し「実行」ボタンを押します。そうするとその下のテキストボックスに移動後の数式が現れるので、それを全て選択してコピー、Excel などに戻り先ほどコピーしたのと同じ場所で貼り付けをします。絶対参照のときにもシフトするかどうかはチェックボックスで選択できます。

JavaScript で実装しています。入力された数式などのデータはどこにも送信せず、いまこのページをご覧のコンピュータ内のみで処理しています。

ソース (ここに Excel から数式を貼り付ける)



行 増分 下へセル (上へ移動させる場合はマイナス値を入力)  
列 増分 右へセル (左へ移動させる場合はマイナス値を入力)  

結果 (ここから数式を Excel にコピーする)


数式のコピーのしかた

Excel での 数式のコピーのしかた

例えば Excel だと、①「数式」メニュー、②「数式の表示」を順にクリックするとセル内に数式が表示されるので、必要な範囲をドラッグで選択して、右クリック・メニューから「コピー」をします。

サブルーチンの名前付きパラメータでデフォルト値を用意する方法

2023/03/15 21:17 Perl
Joseph N. Hall ほか著『Effective Perl 第2版』(2015, 翔泳社)(https://www.shoeisha.co.jp/book/detail/9784798139814) の p.161 「項目47 名前付きパラメータを渡すにはハッシュを使おう」で、パラメータとデフォルト値を組み合わせるのに
@param { keys %input } = values %input;
を使っていたが、別の方法もあったと記憶していたので、簡単に確認した。


ソース
use strict;
use warnings;
use Data::Dumper;

my %default = (
    a => 100,
    b => 101,
    c => 102,
    d => 103,
);
print Dumper \%default;

my %param = (
    a => 200,
    c => 201,
);
print Dumper \%param;

%param = (%default, %param);
print Dumper \%param;

実行結果
$VAR1 = {
          'c' => 102,
          'd' => 103,
          'a' => 100,
          'b' => 101
        };
$VAR1 = {
          'a' => 200,
          'c' => 201
        };
$VAR1 = {
          'b' => 101,
          'a' => 200,
          'c' => 201,
          'd' => 103
        };

この書籍のコードのような、ハッシュB の内容でハッシュA を上書きするような使い方では、
my %param = (...);
...
@param { keys %input } = values %input;

my %param = (...);
...
%param = (%param, %input);
は等価であることが確認できた。

オーダーメイド栄養価計算シート生成サービス Nucalgen について

2022/03/08 3:45
オーダーメイド栄養価計算シート生成サービス Nucalgen を公開しました。
この CGI のバックで動かしている Excel ファイル生成プログラムは、 Java で書きました。
ソースコードは GitWeb で公開しています。

ライセンス

Copyright 2020-2022 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.

実行方法の例

java -jar nucalgen.jar -std-food-comp-table 20201225-mxt_kagsei-mext_01110_012.xlsx [-use-processed-table] -columns columns.xml  -output output.xlsx  -lines 20 -bright-colored-vegetables-list bright-colored-vegetables.xml [-sheets 朝食 昼食 夕食 集計] [-addition addition.xml] [-set-protect]
-std-food-comp-table <filename>必須日本食品標準成分表 Excel ファイル
-use-processed-table任意日本食品標準成分表 Excel ファイルの加工をしない
-columns <filename>必須列定義ファイル
-output <filename>必須出力ファイル
-lines <n>必須行数
-bright-colored-vegetables-list <filename>必須緑黄色野菜定義ファイル
-sheets <sheet_name_1> <sheet_name_2> ... <sheet_name_n> <sheet_name_sum>任意(複数可)複数シート(食事区分+集計)を生成する
-addition <filename>任意(複数可)付加行構成ファイル
-set-protect任意入力可能セル(「食品番号」「摂取量」)以外のセルをロックする


続きを読む