pkgsrc/print/py-pdfを使って、PDFファイル中のハイパーリンクを抽出する

とある自治体が法令に基づいて公開しているPDFファイル一式を入手したかったのだが、そのPDFファイルへのリンク先が1つのPDFファイル中のハイパーリンクという形でしか提供されていなかった。 と言うことで、pkgsrc/textproc/py-pdfからpy314-pdf-6.7.0をインストールして抽出することにした。

と言うことで、以下のようなスクリプトを書いてみた。

$ cat extract-hyperlinks.py
#!/usr/pkg/bin/python3.14
#
# Usage:
# $ cd /usr/pkgsrc/textproc/py-pdf
# $ make install
# $ ./extract-hyperlinks.py target.pdf > links.txt
# $ wget -i links.txt

import sys
from pypdf import PdfReader

pdfpath = sys.argv[1]

reader = PdfReader(pdfpath)

for page in reader.pages:
  if '/Annots' in page:
    for annot in page['/Annots']:
      annotation = annot.get_object()
      if "/A" in annotation and "/URI" in annotation["/A"]:
        uri = annotation["/A"]["/URI"]

        print(f"{uri}")

以下のように利用すれば良い。

$ python3.14 extract-hyperlinks.py ../hyperlinks.pdf > links.txt

Metabaseでlog4jを使ってログを出力する

pkgsrc/www/metabaseを最新にアップデートするのは怠けているのだが、手元ではほぼ常に最新版を使っている。 pkgsrc/www/metabaseのインストールするrcスクリプトには、log4jによりログを出力する設定が含まれている。 また、そのrcスクリプトが利用するlog4j2.xmlという設定ファイルの雛形も含まれている。 なので、pkgsrcからMetabaseをインストールすれば、/var/log/metabase/metabase.logに、設定されたようにログが出力される。

log4jによりログを出力するのは、私の用途では重要なのだが、少なくとも私がMetabaseを使い始めた時にはあまり情報がなかったように思う。 もうずいぶんと前の話なので、今は十分に説明するウェブページが世間にはあるようだ。

Grafanaには、BASIC認証を設定できない

Grafanaを簡単にどういうものか説明できるほど良く理解していないが、私の使い方で言えば、時系列データを保存しているデータベースがあって、その内容を折れ線グラフでプロットして、その値によってアラートを出すように設定できるダッシュボードのウェブページである。 ビジネス・インテリジェンス・システムのようなものであるような気もする。

私は、少し古いがpkgsrc/www/grafanaから11.0.0をインストールし、データベースは、pkgsrc/databases/influxdbを手元でアップデートしてInfluxDB 1.8.10をインストールして使っている。 ウェブサーバーがないと使えない訳ではないと思うが、Apache httpdをリバースプロキシーとして利用している。

Grafanaには、もちろんログイン機能があって、ログインしなければダッシュボードを見ることはできない。 そもそもやりたかったのは、そもそもGrafanaのログイン画面へ行くこともできないようにすることだった。 そうだとすると、一番簡単なのは、BASIC認証を設定することであるように思えた。

しかし、BASIC認証は使えない。 と言うのは、ユーザー追加をする際に、Grafana自体が自身のAPIを利用する場合にBASIC認証を利用しているからであるようである。 Apache httpdでBASIC認証した上で、ユーザー追加をすると、追加したユーザーでしかログインできなくなるばかりか、そのユーザーからログアウトすることもできなくなってしまう。

おとなしく、Grafana備え付けのログイン画面を使っておくのが一番良さそうである。

Windows 11でwgetを使ってhttpsなウェブサイトから情報を取得する

Windows 11でhttpsなウェブサイトから情報を取得したいのだが、ウェブ上にある多くの古いwgetのWindows用のバイナリーは、TLS 1.2以降に対応しておらず私の接続先には利用できなかった。 また、このwgetを動かす環境は、ユーザー認証付きのHTTPプロキシーサーバーを経由しないとイントラネット外のウェブサイトへ接続することはできない。 このような状況でWindows 11のマシンでwgetを利用する方法を書いておく。

wgetのバイナリーを入手する

Windows binaries of GNU Wgetで公開されているwgetバイナリーは、新しいTLSのバージョンにも対応していた。 他にもおそらく使えるバイナリーを配布している所はあるかもしれないが、具体的には確認していない。

具体的には、バージョン1.21.4のバイナリーをダウンロードして利用した。

設定値をファイルに格納する

ユーザー認証付きHTTPプロキシーサーバーを利用する必要があり、これらを毎回コマンドライン引数として入力するのは煩雑になる。 また、パスワードをコマンドライン引数として与えるのも、パスワードが画面上に表示されてしまい、うれしくない。

ということで、設定値はwgetrc.txtというテキストファイルに予め記入しておくことにした。 その内容は以下のようにした。

> type wgetrc.txt
use_proxy=on
http_proxy=http://10.1.1.1:8080/
https_proxy=http://10.1.1.1:8080/
proxy_user=(YOUR USERID)
proxy_password=(YOUR PASSWORD)
check_certificate=off

ここで、check_certificate=offはTLS証明書のチェックを省略している。 これは良い習慣ではない。

実行例

このwgetrc.txtファイルを使いつつ、ウェブサイトから情報を取得するには、以下のようにすれば良い。

> wget.exe --config=wgetrc.txt -nc -r https://www.ryoon.net/

MetabaseをOracle databaseへクエリーするAPIサーバーとして利用する

Oracle databaseに各クライアントPC上のMicrosoft Excel VBAからアクセスしようとすると、Oracle Instant Clientのインストールが必要になる。 ODBC経由だとデータソースの設定が必要になり、皿に初期設定は手間がかかるが、Excel VBAからアクセスする程度であれば、ADO DB経由でも問題ない。 この場合には、tnsnames.oraに接続先を設定する必要はなく、接続文字列に直接接続先を記載すれば良いので、とりあえずOracle Instant Clientをインストールさえして置けば良い。 ただ、Oracle社の用意しているOracle Instant Clientのインストーラーは冗長かつ何をしているか分かりにく、インストールに失敗するとインストーラーはまた別のディレクトリーにインストールしてしまうので、同じ緩急を作るのも面倒だ。 これについては、必要なファイルと処理のみを解析して抜き出したWindowsバッチファイルを用意しているので、個人的には解決はしているが…。

とは言っても、あくまでWindowsバッチファイルであり、環境変数の設定は手作業でするようになってもいるので、インストールには手間がかかる。 そもそもOracle Instant Clientをインストールしない方法を探していた。

過去にはJRubyからJDBCを使ってOracle databaseにアクセスし、結果を返すサーバーを書いてもいたのだが、利用者の認証や権限設定も欠けており、起動させておくのも面倒なので、実用できてはいなかった。

metabaseのドキュメントを読んでいたら、アクセストークンを発行して、それによりREST APIでMetabaseに登録されたデータベースにクエリーを投げて、その結果をJSONやCSV形式で返してくれる仕組みがあった。 今回は本来は使うべきであるセッションIDは使わないのだが、curlコマンドで試した内容を書いておく。

アクセスする例

最初に、前提となる情報を書いておく。

今回使うユーザーグループ権限のAPIキー
mb_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=
MetabaseサーバーのURI (都合上HTTPでしかアクセスできない)
http://mbserv.example.com/
アクセスするデータベースの番号 (JDBC経由で接続できるようにウェブUIで設定されている)
2

このMetabaseサーバーが設置され、クライアントのWindows PCが接続されているイントラネットは、イントラネット外の80版ポートに接続するにはHTTPプロキシサーバーを経由する必要がある。 だが、イントラネット内にあるMetabaseサーバーにはHTTPプロキシサーバー経由ではアクセスできないので、HTTPプロキシサーバーを掴ない設定も重要である。

グループの一覧を取得する。 これはOracle databaseには無関係なMetabaseの機能に対する問い合わせである。

$ curl --noproxy mbserv.example.com -H 'x-api-key: mb_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=' -X GET 'http://mbserv.example.com/api/permissions/group'

MBQL JSON形式でSQLのクエリーの結果を取得する。 結果はMBQLのJSON形式であり、前半にデータが、後半にコラム情報が収録されており、Excel VBAであればVBA-FastDictionaryVBA-FastJSONを使えば解析しデータを利用するのが幹太になる。

$ curl --noproxy mbserv.example.com -H 'x-api-key: mb_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=' -H 'Content-Type: application/json' -X POST 'http://mbserv.example.com/api/dataset' -d '{ "database": 2, "native": { "query": "select * from myschema.MYTABLE1" }, "type": "native"}'

CSV形式でSQLのクエリーの結果を取得する。

$ curl --noproxy mbserv.example.com -H 'x-api-key: mb_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=' -H 'Content-Type: application/x-www-form-urlencoded' -X POST 'http://mbserv.example.com/api/dataset/csv' -d 'query={ "database": 2, "native": { "query": "select * from myschema.MYTABLE1" }, "type": "native"}'

これで、Oracle Instant Clientをインストールせずに、クライアントWindows PCからOracle databseの内容を参照できるようになった。

MetabaseでActive Directory認証する際に、ユーザーIDでも電子メールアドレスでも、ログインユーザーIDとして使えるようにする

MetabaseでActive Directory認証するで書いておいたような設定でMetabaseを運用して来たのだが、Metabaseのログイン画面にはログインユーザーID欄に「ユーザーネームまたはメールアドレス」と書かれているためか、電子メールアドレスを入力してログインできないという苦情を言う人が多いという問題があった。 駄目だったらユーザーIDでログインできるか試せば良いと私などは思うが、そんな発想にならない人ばかりに囲まれている。 そもそもなぜそういう発想をすることができるかということも説明しても理解してもらえないので、ユーザーIDでも電子メールアドレスでもログインするしかないだろう。

と言うことで、Active Directoryの項目を調べてみると、以下のような項目が使えそうであった。

  • ユーザーIDはsAMAccountNameという項目であり、既に利用している。
  • ユーザー認証に利用できる電子メールアドレスは、userPrincipalNameという項目になっているらしい。
  • 電子メールアドレスはmailという項目にも格納されているらしい。

と言うことで、これら3つのいずれかをloginに使えば良さそうだ。

以下のように設定していたので、変更しよう。

(&(sAMAccountName={login}))

変更後は以下のようにした。

(&(|(sAMAccountName={login})(mail={login})(userPrincipalName={login}))(objectClass=user))

これで、電子メールアドレスでもユーザーIDでもいずれでもログインIDとして与えてもログインできるようになった。

NetBSDでFPAG開発を始めてみる(NVCとVHDL)

この記事は、NetBSD Advent Calendar 2025の25日目の記事です。

はじめに

本当は、PyRTLで書いたロジックをTnag Nano 9Kで動かしてみたいのですが、これから勉強しないといけないので、しばらく先に進めそうにありません。 と言うことで、22日目23日目でVHDLを使ってみていましたが、その際に試していたNVCというVHDLのシミュレーターについて、試したことを書いておきたいと思います。

NVCできること

NVCは、GHDLとは違い、合成をすることはできません。 あくまで、IEEE 1076-2008のほとんどをシミュレーションできるだけのようです。 VHDLについては、普通の利用者は、GOWIN FPGA Designerを使うでしょうから、良いシミュレーターであるだけでも大きな意味があるのだと思います。 NVCはJ-Core Open Processorでも使われているようです。

NVCをインストールする

pkgsrc/cad/nvcとして、nvc-1.18.2を用意しました。 この後にインポートしておきたいと思います。

と言うことで、以下のようにインストールすれば良いでしょう。

# cd /usr/pkgsrc/cad/nvc
# make install

これによって、/usr/pkg/bin/nvcがインストールされます。 これを使って、22日目のGHDLによるシミュレーション用のMakefileに、NVCを使ったパターンも追加してみます。 analysisをするにはanalysisnvcターゲット、elaborateにはelaboratenvcターゲット、シミュレーションを実行してvcdウェーブフォームファイルを得るにはrunnvcターゲットを用意しました。

$ cat Makefile
TARG=   counter

GHDL_FLAGS+=    -fsynopsys

.PHONY: analysis elaborate run clean analysisnvc elaboratenvc runnvc

analysis: ${TARG}.vhdl
        ghdl -a ${GHDL_FLAGS} ${TARG}.vhdl
        ghdl -a ${GHDL_FLAGS} ${TARG}_tb.vhdl

analysisnvc: ${TARG}.vhdl ${TARG}_tb.vhdl
        nvc -a ${TARG}.vhdl ${TARG}_tb.vhdl

elaborate: work-obj93.cf
        ghdl -e ${GHDL_FLAGS} ${TARG}
        ghdl -e ${GHDL_FLAGS} ${TARG}_tb

elaboratenvc: analysisnvc
        nvc -e counter_tb

run: elaborate
        ghdl -r ${GHDL_FLAGS} --time-resolution=ns ${TARG}_tb --vcd=counter.vcd --stop-time=1ms

runnvc: elaboratenvc
        nvc -r --format=vcd --wave=counter-nvc.vcd --stop-time=1ms counter_tb

clean:
        rm -f counter.vcd
        rm -f work-obj93.cf
        rm -f counter-nvc.vcd
        rm -fr work

ただし、nvcの生成したcounter-nvc.vcdファイルのタイムスケールはfs単位になっていて、変更ができないようです。

結果のvcdファイルをGtkWaveで表示してみる

Zoom-outしていくと、下図のように表示できました。 既定の表示は非常にZoom-inされた状態ですが…。

これで、GHDLだけでなくシミュレーションを実行できるようになりました。 検証も確実さを上げることができそうです。

pkgsrc/print/py-pdfを使って、PDFファイル中のハイパーリンクを抽出する

とある自治体が法令に基づいて公開しているPDFファイル一式を入手したかったのだが、そのPDFファイルへのリンク先が1つのPDFファイル中のハイパーリンクという形でしか提供されていなかった。 と言うことで、pkgsrc/textproc/py-pdfからpy314-pdf...