adbird(広告鳥) 備忘録

記事一覧・このブログの主要カテゴリー

記事一覧

ブログ(無料版)の仕様で、デフォルトのトップページだと投稿記事の1つ1つが全部表示されてしまい、ブログ全体を把握しづらい。下記のリンクから入ったほうが記事を探しやすいかも。このブログをブックマークする際も下記リンクをブックマークすることをオススメする。

最近よく更新するカテゴリーなど。

python と pdftk で、複数のPDFを結合し、ページ番号をつけ、しおりをつけるスクリプト【改良版】

以前、以下のような記事を書いたが、この方法だと別途「ページ番号.pdf」と「bookmarks.txt」が必要だった。

python と pdftk でPDFを結合し、ページ番号をつけ、しおりをつけるスクリプト - adbird(広告鳥) 備忘録

今回は、「ページ番号.pdf」と「bookmarks.txt」を用意しなくても良い方法。

えぇ、今回もChat GPTさんに聞きまくりました(これやるにはどんなスクリプト書けばいい?→こうです→こんなエラーが出たよ→こうでした→こんなエラーが…の繰り返し)。

環境はUbuntu

ディレクトリ構造

├── 001_test.pdf
├── 002_テスト.pdf
├── 003_てすと.pdf
├── addbookmarks.py
├── getpagenum.py
└── mergepdf.py

pdfファイル名は「001_」というように、3ケタの連番+半角アンダーバーを必ずつける。

getpagenum.py、mergepdf.py、addbookmarks.pyの順番にスクリプトを実行していく。

getpagenum.py

pdfファイルを結合した際の、各pdfがどのページに位置づけられるかを取得。また、ファイル名を取得してbookmarks.csvに出力するスクリプト

import csv
import glob
from PyPDF4 import PdfFileReader

# PDFファイルのリストを取得する
pdf_files = sorted(glob.glob("*.pdf"))

# 結合後の各PDFファイルの開始ページを取得する
start_pages = []
current_page = 1
for pdf_file in pdf_files:
    with open(pdf_file, "rb") as f:
        reader = PdfFileReader(f)
        start_pages.append(current_page)
        current_page += reader.numPages

# bookmarks.csvファイルに出力する
csv_file = "bookmarks.csv"
with open(csv_file, mode='w', newline='') as f:
    writer = csv.writer(f)
    for idx, start_page in enumerate(start_pages):
        writer.writerow([f"1",pdf_files[idx], start_page])

print(f"CSVファイル '{csv_file}' に出力しました。")

端末で

python3 getpagenum.py

とすると、「bookmarks.csv」が生成される。

mergepdf.py

PDFの結合とページ番号の追加。

import os
import io
from PyPDF4 import PdfFileMerger, PdfFileReader, PdfFileWriter
from reportlab.pdfgen import canvas

# カレントディレクトリを取得
current_directory = os.getcwd()

# 結合後のPDFファイル名
output_pdf = os.path.join(current_directory, "input.pdf")

# ワイルドカードを使用してPDFファイルをリストアップし、ファイル名のソートを行う
pdf_files = sorted([os.path.join(current_directory, file) for file in os.listdir(current_directory) if file.endswith('.pdf')])

# PdfFileMergerオブジェクトを作成
pdf_merger = PdfFileMerger()

# PDFファイルを結合
for pdf_file in pdf_files:
    with open(pdf_file, 'rb') as file:
        pdf_merger.append(file)

# 結合したPDFを一時的なファイルに保存
temp_merged_pdf = os.path.join(current_directory, "temp_merged_file.pdf")
with open(temp_merged_pdf, 'wb') as file:
    pdf_merger.write(file)

# ページ番号を追加する関数
def add_page_numbers(input_pdf, output_pdf):
    with open(input_pdf, 'rb') as file:
        pdf_reader = PdfFileReader(file)
        pdf_writer = PdfFileWriter()

        # 全ページの数を取得
        num_pages = pdf_reader.numPages

        # ページ番号を追加して新しいPDFを作成
        for page_number in range(num_pages):
            page = pdf_reader.getPage(page_number)

            packet = io.BytesIO()
            can = canvas.Canvas(packet)
            text = str(page_number + 1)
            can.drawString(565, 810, text)  #ページ番号の位置(左下からの位置。単位はpt。)
            can.save()

            packet.seek(0)
            new_page = PdfFileReader(packet)
            page.mergePage(new_page.getPage(0))

            pdf_writer.addPage(page)

        # 新しいPDFを保存
        with open(output_pdf, 'wb') as output_file:
            pdf_writer.write(output_file)

# ページ番号を追加
add_page_numbers(temp_merged_pdf, output_pdf)

# 一時的な結合ファイルを削除
os.remove(temp_merged_pdf)

print("PDFの結合とページ番号の追加が完了しました。")

端末で

python3 mergepdf.py

とすると、「input.pdf」が生成される。Windowsは python3 ではなく、python かも(以下、同じ)。

addbookmarks.py

bookmarks.csv 中の、ファイル名=ブックマーク名の「001_」から「050_」までの連番を削除。

bookmarks.csvをpdftkのブックマーク書式に変換して、上記のinput.pdfにブックマークをつけて、output.pdfに出力。

import csv
import re
import subprocess

# ファイル名
input_file = 'bookmarks.csv'
output_file_txt = 'output.txt'
output_file_pdf = 'output.pdf'

# ブックマーク書式のテンプレート
bookmark_template = "BookmarkBegin\nBookmarkTitle: {title}\nBookmarkLevel: 1\nBookmarkPageNumber: {page}\n"

# 連番のパターン
number_pattern = r'\d{3}_'

# 連番の最大値
max_number = 50

# CSVファイルの読み込み
with open(input_file, 'r', newline='', encoding='utf-8') as csv_in:
    reader = csv.reader(csv_in)

    # ブックマーク書き出し用のテキストファイルを作成
    with open(output_file_txt, 'w', encoding='utf-8') as txt_out:
        for row in reader:
            # ファイル名から連番を削除
            file_name = row[1]

            # 連番を削除
            file_name = re.sub(number_pattern, '', file_name)

            # ページ番号
            page_number = row[2]

            # ページ番号が連番の最大値を超えている場合は調整
            page_number = min(int(page_number), max_number)

            # ブックマーク書式にフォーマットして書き出し
            bookmark_data = bookmark_template.format(title=file_name, page=page_number)
            txt_out.write(bookmark_data)

# pdftkを使ってPDFにブックマークを追加
subprocess.run(["pdftk", "input.pdf", "update_info_utf8", output_file_txt, "output", output_file_pdf, "verbose"])

print("処理が完了しました。")

端末で

python3 addbookmarks.py

とすると、「output.pdf」が生成される。完成。

複数のPDFファイルを結合して、通しページ番号をつけるpythonスクリプト

ディレクトリ内にある複数のPDFファイル(001.pdf 002.pdf …などの連番のPDF)を結合して、通しページ番号をつけるpythonスクリプト

Chat GPTさんに何度も聞きながら、できた。

何はともあれ、python をインストール。Ubuntu 22.04.3 LTS の場合、端末で

sudo apt install python3

PyPDF4をインストール。

 pip install PyPDF4

結合させたい複数のpdfファイルの入っているディレクトリに、下記の内容の mergepdf.py を保存。

import os
import io
from PyPDF4 import PdfFileMerger, PdfFileReader, PdfFileWriter
from reportlab.pdfgen import canvas

# カレントディレクトリを取得
current_directory = os.getcwd()

# 結合後のPDFファイル名
output_pdf = os.path.join(current_directory, "output.pdf")

# ワイルドカードを使用してPDFファイルをリストアップし、ファイル名のソートを行う
pdf_files = sorted([os.path.join(current_directory, file) for file in os.listdir(current_directory) if file.endswith('.pdf')])

# PdfFileMergerオブジェクトを作成
pdf_merger = PdfFileMerger()

# PDFファイルを結合
for pdf_file in pdf_files:
    with open(pdf_file, 'rb') as file:
        pdf_merger.append(file)

# 結合したPDFを一時的なファイルに保存
temp_merged_pdf = os.path.join(current_directory, "temp_merged_file.pdf")
with open(temp_merged_pdf, 'wb') as file:
    pdf_merger.write(file)

# ページ番号を追加する関数
def add_page_numbers(input_pdf, output_pdf):
    with open(input_pdf, 'rb') as file:
        pdf_reader = PdfFileReader(file)
        pdf_writer = PdfFileWriter()

        # 全ページの数を取得
        num_pages = pdf_reader.numPages

        # ページ番号を追加して新しいPDFを作成
        for page_number in range(num_pages):
            page = pdf_reader.getPage(page_number)

            packet = io.BytesIO()
            can = canvas.Canvas(packet)
            text = str(page_number + 1)
            # フォントを設定
           # can.setFont('Helvetica', 12)  # フォント名とフォントサイズ
            can.setFont('Times-Roman', 12)  # フォント名とフォントサイズ
           # can.drawString(565, 810, text)  #ページ番号が右上(左下からの位置。単位はpt。)
            can.drawString(293, 25, text)  #ページ番号中央下(左下からの位置。単位はpt。)
            can.save()

            packet.seek(0)
            new_page = PdfFileReader(packet)
            page.mergePage(new_page.getPage(0))

            pdf_writer.addPage(page)

        # 新しいPDFを保存
        with open(output_pdf, 'wb') as output_file:
            pdf_writer.write(output_file)

# ページ番号を追加
add_page_numbers(temp_merged_pdf, output_pdf)

# 一時的な結合ファイルを削除
os.remove(temp_merged_pdf)

print("PDFの結合とページ番号の追加が完了しました。")

※「can.drawString(293, 25, text) #ページ番号の位置(左下からの位置。単位はpt。)」の箇所は適宜、変更する。

pdfの入っているディレクトリで右クリック>端末で開く

python3 mergepdf.py

Windowsでは以下かも。

python mergepdf.py

LinuxでYahoo!ニュースやTVerの動画を再生する

Yahoo!ニュースのニュース動画やTVerの動画を、LinuxUbuntu)のVivaldiで見ようとすると、推奨環境じゃないということで再生できない。

そんなときは、アドオンの拡張機能 User-Agent Switcher and Manager を使って、ブラウザをWindowsChromeなどに偽装して視聴する。

上記アドオンのオプションで Custom Mode にして何も入力せず、そのままであればどのサイトでも設定したブラウザに偽装できる。

しかし、僕は積極的に「Linuxを使ってるんだぞ」とアピールしたいし、そういう人が多いほど、サイト構築者もLinuxユーザーを意識してくれるはず…?

ということで、 White-List Mode で、エラーで見られない動画等のサイトを入力して、 Save。

news.yahoo.co.jp, tver.jp

アドオンを入れたくない、という人はこちら。

タイマーで音楽再生(目覚まし音楽)

環境はUbuntu 22.04.3 LTS。

下準備

  • SMplayer をインストールしておく。
  • 音楽データ。
  • SMplayer でプレイリスト(例:目覚ましプレイリスト.m3u)を作っておく。

cron(crontab) で音楽を鳴らす時間を設定

端末で

$ crontab -e

最初はエディタ選択を求められるので、nanoを選択。

次のような行を入力。hogehogeの部分は適宜変更のこと。

土日も含めて毎日の場合。

#毎日6時
0 6 * * * DISPLAY=:0 smplayer "/home/hogehoge/ミュージック/目覚ましプレイリスト.m3u"

月曜日から金曜日の場合。

#月〜金の6時
0 6 * * 1-5 DISPLAY=:0 smplayer "/home/hogehoge/ミュージック/目覚ましプレイリスト.m3u"

月曜日から土曜日の場合。

#月〜土の6時
0 6 * * 1-6 DISPLAY=:0 smplayer "/home/hogehoge/ミュージック/目覚ましプレイリスト.m3u"

crontabの書式は、

分 時 日 月 曜日 コマンド(やスクリプト)

crontabでググればもっと詳細な情報が出てくるので、それらを参考に。

諸注意

  • 上記の方法(cronだけ)だと、ずっとPCの電源を入れておかないといけないが(消費電力の少ないラズパイとかなら気にしなくもいいだろうけど)、rtcwakeコマンドと組み合わせたら、PCの自動起動&音楽再生もできるかもしれない。
  • nanoの場合、上書き保存はCtrl + o、終了はCtrl + x。nanoをちゃんと終了させておかないとcronが動いてくれない。

Vivaldiパネル上の Vivaldi Social(ビバ丼) の画像を小さくする

ビバ丼(というか、X〔twitter〕もかな)、vivaldiのパネルで表示させていると、スマホで撮影した縦長の画像が大きすぎて、パネルの表示画面がほぼその1枚の画像だけになるのが嫌。

twicli使ってたときは、CSSで画像の高さを制限して小さくさせていたので、なおさら。

とりあえず、Vivaldiパネル上の Vivaldi Social(ビバ丼) のアイコン周りの余白を狭くする - adbird(広告鳥) 備忘録と同じ方法で、

右クリック > 開発者ツール > 検証

開発者ツール「DevTools」が新しいウィンドウで立ち上がるので、

 ソース > custom.css

をクリックして、custom.cssに以下の内容を追加して、その場しのぎ。

.media-gallery {
  height: 50%;  
  width: 50%;
}

メールソフト Claws Mail


Claws Mail という選択肢

基本、アンチMSなのでw、MS関連のソフト・アプリは極力、使いたくない。 そもそもUbuntuが常用OSなので、Outlookなどのメールソフトは使えないし、Windows環境でも使いたくない。

なので、メールソフトに何を使うかというと、定番の

Thunderbird

は、私のある環境ではいろいろ不具合(メール送信がソフト上では送信中の状態で止まってしまい、メールが「送信済み」に送られず、しかし、実際には送信されている(で、何度も送信し直してしまい、何度も相手先に同じメールが届く)という事態が何度も発生)があったり、使わないカレンダーなどの機能があるので、

Sylpheed

をしばらく使ってみたのだが、いかんせん更新が全然されていなくて、見た目もモダンじゃない…。

そこで

Claws Mail

というSylpheedからフォークされたメールソフトを見つけた。

見た目もモダンで良さげ。

Sylpheedからフォークされたということもあり、Claws Mail を立ち上げた初回にSylpheedから設定を引き継ぐかどうかのポップアップが出て、OKを押したら、ほぼそのまま使えるようになった。

Ubuntuのレポジトリに入っていて sudo apt install claws-mail でインストールできる。

しばらくこれを使ってみる。

プラグイン

Claws Mail - Plugins

htmlメール表示

htmlメールの表示のためのプラグインはいくつかあるが、私の環境では以下のプラグインだけが正常に動いた。ただし、 lite とあるようにhtmlタグの全部が表示されるようではなさそう(たとえば下線は表示されなかった)。

sudo apt install claws-mail-litehtml-viewer

正しくhtmlメールを表示するには「アプリケーションで開く」をして

vivaldi-stable %s

などのコマンド(上記はVivaldiブラウザで開くコマンド)で、ブラウザで開くのが確実。

PDFビューアー

sudo apt install claws-mail-pdf-viewer

通知

sudo apt install claws-mail-multi-notifier

テーマ

Claws Mail - Themes

sudo apt install claws-mail-themes

今のところ、Tango 1.2.1 がお気に入り。

htmlメールの返信に余計な空行を削除

Sylpheed も Claws Mail もOutlookから送られてきたhtmlメールを開くと、1行毎に余計な空行が入る。

メールを閲覧する分には構わないが、それを返信すると、余計な空行が入ったままになるので、返信の際に「外部エディタで編集」をして、Geanyが立ち上がるようにして、Geanyに以下のビルドコマンドを設定して、改行を削除するようにしている。

sed -i -z "s/> \n> \n/【改行】\n/g" "%f" && sed -i -z "s/> \n//g" "%f" && sed -i -e "s/^【改行】/> /g" "%f"

もっと良さげな方法があるかもしれないが…。

署名(返信時の署名)

設定で「署名を自動的に挿入する」にチェックを入れると、返信時には、

  • 自分の返信内容
  • 相手方の文面を引用
  • 自分の署名

となるのだが、返信時には、

  • 自分の返信内容
  • 自分の署名
  • 相手方の文面を引用

となるようにしたい。

そのための設定が以下の通り。

1) 設定>アカウントを編集>アカウントを選択して、Edit。>作成の項目

  • 「署名を自動的に挿入する」にチェックを【入れない】。
  • 「ファイル」にチェックを入れる。
  • 「署名」のURLが /home/username/.signature (userneme部分は環境による)となっていることを確認して(テキストファイルであれば、.signatureでなくてもいいはず)、Edit をクリックして、署名を作成。

2) 設定>全般の設定>作成>テンプレート>作成タブで、

「新しいメッセージを作成するときはテンプレートを使用する」にチェックを入れ、テンプレートを以下のようにする。

%as

3) 設定>全般の設定>作成>テンプレート>返信タブのテンプレートを以下のようにする。

%as

On %d
%f wrote:

%Q

その他個人的設定

全体の見栄え

表示>表示/非表示

  • 「ステータスバー」のチェックを外す。

メッセージビュー

見た目がごちゃごちゃしているので(相手がどのメーラーを使っているかなんていう情報は普段はみえなくていいし)、調整。

設定>全般の設定>テキストオプション

  • 「メッセージビューの上部にヘッダペインを表示する」のチェックを外す
  • 「メッセージビューに(X-)Faceを表示する」のチェックを外す
  • 「メッセージビューにヘッダを表示する」の「Edit」をクリック。
    • 「Subject」を「Up」を押して、一番上に。
    • 「X-Mailer」を「Remove」。
      • 元に戻したい(X-Mailerを表示させたい)場合は、ヘッダ名に「X-Mailer」と入力して、「Add」をクリック。

フォント

フォントはお好みで。

設定>全般の設定>フォント

  • フォルダとメッセージリスト「UmePlus P Regular」
  • メッセージ「UmePlus P Gothic Regular」
  • スモール「UmePlus Gothic Regular」
  • 太字「UmePlus P Gothic Bold」

ツールバー

なぜ「ツールバー|作成」となっているのか謎。普通に「メール作成」に変更。

設定>全般の設定>ツールバー>メインウィンドウ

バイクのオイル交換

記録するのを忘れてた。

9月18日にバイク屋でエレメントを含めたオイル交換をしてもらった。

約20,400km。

前回のオイル交換から距離的には走っていなかったけど、約2年近く交換していなかったので。