VSCode PS1ファイルを開きながら統合ターミナルを開いたとき、PowerShell Extensionsが自動起動しないようにする

VSCodeのターミナルパネルでランダムにPowerShell Extensionsが自動的に起動してしまうことに悩まされていたので、その対処法をメモしておきます。 Windows 11 25H2 PowerShell 7.5 VSCode 1.106 VSCode拡張 PowerShell 2025.4.0 VSCodeの統合ターミナルには普段はGit Bashを使っていて、PowerShellスクリプトは他のシェルからpwshコマンドで実行しています。 ところが、Ctrl + Shift + @などでターミナルパネルにGit Bashを開こうとすると、PowerShell Extensionsが勝手に起動することがあり、 デフォルトターミナルのように振る舞うので、その度に終了して、Git Bashに戻す手間が発生していました。 どうやら、これはVSCodeのPowerShell拡張の機能で、 PS1ファイルを開いているときにVSCodeの統合ターミナルを開くと、 PowerShell Extensionsが自動的に起動するようです。 これを回避するために、拡張機能の設定でPowerShell Extensionsが自動起動しないようにします。 WSL側には影響しないため、Windows側のVSCodeウインドウを開きます。 Ctrl + , を押して設定画面を開き、検索ボックスにpowershell startと入力します。 PowerShell > Start Automaticallyという設定項目が表示されるので、チェックを外します。 これで、PS1ファイルを開いているときにターミナルを開いても、PowerShell Extensionsが自動起動しなくなりました。

2025年11月29日 · aoirint

Dockerfileでイメージ内の既存ディレクトリ宛にADD/COPYした場合の挙動を調べた

Docker Engine 24.0 Dockerイメージのビルド時に、イメージ内のディレクトリ構造に、同じディレクトリ構造をもつホスト側ディレクトリを追加した場合の挙動を確認したい。 cp -rやrsync -aのような挙動を期待するが、動作を検証してみた。 結果として、cp -rやrsync -aのように、既存のディレクトリ内容を維持して、新しいファイルを追加し、重複するファイルがあれば上書きする挙動をした。 ADD - Dockerfile reference | Docker Docs ADDでファイルが重複しない場合 イメージ内に以下のようなディレクトリ構造を構築する。 /hoge fuga piyo/ hogera RUN <<EOF set -eu mkdir /hoge touch /hoge/fuga mkdir /hoge/piyo touch /hoge/piyo/hogera EOF ビルドコンテキストディレクトリに以下のようなディレクトリ構造を構築する。 このディレクトリを先ほどのイメージ内の/hogeにADDする。 hoge/ fugera piyo/ hogerara ADD ./hoge /hoge/ 結果表示用のtreeコマンドをインストールするコマンドを加えて合わせると、以下のようなDockerfileになる。 # syntax=docker/dockerfile:1.6 FROM ubuntu:22.04 RUN <<EOF apt-get update apt-get install -y \ tree apt-get clean rm -rf /var/lib/apt/lists/* EOF RUN <<EOF set -eu mkdir /hoge touch /hoge/fuga mkdir /hoge/piyo touch /hoge/piyo/hogera EOF ADD ./hoge /hoge/ docker build -t doco . docker run --rm -it doco # tree /hoge /hoge |-- fuga |-- fugara `-- piyo |-- hogera `-- hogerara 1 directory, 4 files 既存のディレクトリの内容を維持したまま、新しいファイルが追加される。 ...

2023年10月13日 · aoirint

SNS・Fediverseの投稿インテントURL

Twitter (X)、Misskey、Mastodonには、URLのGETパラメータに投稿本文などを付けて、ミニブログの入力を補助する機能(投稿インテントURL機能)があります。 この記事では、各サービス・ソフトウェアの投稿インテントURLの仕様について記載します。 Twitter Web Intent (2023-07-19時点) ドキュメント: Web Intent | Docs | Twitter Developer Platform https://twitter.com/intent/tweet GETパラメータ 備考 text url hashtags via related in_reply_to Misskey 共有フォーム (v13.13.2時点, 2023-07-13) ドキュメント: 共有フォーム | Misskey Hub Misskey.ioを例とします。 https://misskey.io/share?text=hello GETパラメータ 備考 title text url replyId replyUri renoteId renoteUri visibility localOnly visibleUserIds visibleAccts fileIds Mastodon (v4.1.4時点, 2023-07-08) ドキュメント: 見つけられなかった 実装はここ: https://github.com/mastodon/mastodon/blob/3f5af768c8f1401f77d14ad5b6aeccdb7e02a9f0/app/helpers/application_helper.rb#L196-L204 mstdn.aoirint.comを例とします。 ...

2023年8月7日 · aoirint

Pythonプロジェクトの作成(pyenv + Poetry)

バージョン情報 pyenv 2.4.0 Poetry 1.8.2 Python 3.11.9 定義・ディレクトリ構成 説明のため、プロジェクトディレクトリ名my_project、パッケージ名my-project、主要なモジュール名my_projectとします。 以下のようなディレクトリ構成にすることを想定しています。 - my_project/ - pyproject.toml - Dockerfile - my_project/ - __init__.py - __main__.py - cli.py - tests/ - __init__.py - test_my_project.py Python/Poetryのインストール pyenvでPythonをインストールします。 記事作成時点で最新のリビジョン(0.0.x)を記載していますが、適宜新しいバージョンが出ているか確認し、 更新してください。 マイナーバージョン(0.x.0)を変更する場合、依存する予定のライブラリが動作するかなど、プロジェクトの要件と相談してください。 env PYTHON_CONFIGURE_OPTS="--enable-shared" pyenv install 3.11.9 PYTHON_CONFIGURE_OPTS="--enable-shared"は、PyInstallerが動作するようにするために設定しています。 pyenv and PyInstaller — PyInstaller 6.5.0 documentation Poetryをインストールします。 Poetry Installation # Linux, macOS, WSL curl -sSL https://install.python-poetry.org | python3 - # Windows (PowerShell) (Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | python - Poetryプロジェクトの作成 Poetryのグローバル設定を変更し、Python仮想環境がプロジェクトのディレクトリ/.venvに作成されるようにします。 これは、VSCode拡張機能のPylanceがPython仮想環境を認識できるようにする、または手動で設定しやすくするための変更です。 ...

2023年8月7日 · aoirint

GitLab CI, DockerイメージをビルドしてContainer Registryにpushする(2023年版)

前回の記事(2021年版)から、以下の内容でアップデートしました。 Docker Engine 24.0 BuildKit レイヤーキャッシュ(Registry cache) タグによるバージョン付け 注意:Self Hosted GitLab RunnerでのDockerデーモンを使ったイメージビルドは推奨しません DinDでのビルドのため、ホストOSのroot権限が取得可能な、コンテナの特権実行(--privileged)、またはDockerソケットのマウント(DooD)が要求されます。 GitLab.comのShared Runnerは使い捨てのGCPインスタンスで提供されるため、コンテナブレイクアウト等によりホストのroot権限が取得されても、 Dockerエンジンのホストである仮想マシンごと破棄されますが、そのような工夫をしていないRunner(VPSやベアメタル)では、 CIジョブの実行により、ホストのroot権限で悪意ある操作が実行され、また、その影響が持続する危険性があります。 Dockerデーモンを必要としない、代替ソフトウェアによるDockerイメージビルドを検討してください。 リポジトリ構造 .gitlab-ci.yml Dockerfile .gitlab-ci.yml # License: CC0-1.0 stages: - build build: stage: build image: docker:24.0 services: - docker:dind rules: # Release - if: $CI_COMMIT_TAG variables: DOCKER_IMAGE_NAME_AND_TAG: "${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG}" DOCKER_CACHE_FROM: "type=registry,ref=${CI_REGISTRY_IMAGE}:latest-buildcache" DOCKER_CACHE_TO: "" # Default branch - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH variables: DOCKER_IMAGE_NAME_AND_TAG: "${CI_REGISTRY_IMAGE}:latest" DOCKER_CACHE_FROM: "type=registry,ref=${CI_REGISTRY_IMAGE}:latest-buildcache" DOCKER_CACHE_TO: "type=registry,ref=${CI_REGISTRY_IMAGE}:latest-buildcache,mode=max" script: - apk add --no-cache git - docker buildx create --use - docker login -u "${CI_REGISTRY_USER}" -p "${CI_REGISTRY_PASSWORD}" "${CI_REGISTRY}" - > docker buildx build . -t "${DOCKER_IMAGE_NAME_AND_TAG}" --cache-from "${DOCKER_CACHE_FROM}" --cache-to "${DOCKER_CACHE_TO}" --push ※ docker buildx buildのコマンドは複数行になっていますが、2行目以降を1行目と異なるインデント数にしないでください。2行目以降が別のコマンド扱いになり、動作しなくなります。 docker buildx create --use docker buildx build実行時に、以下のようなエラーが出るため追加しています。 ...

2023年5月18日 · aoirint

Selenium HTTPリクエストのURLを記録する(Chrome, Python)

Selenium 4.9.0 Chrome 112 ChromeDriver 112.0.5615.49 Python 3.11 import time import json from selenium.webdriver import ( Chrome, DesiredCapabilities, ) desired_capabilities = DesiredCapabilities.CHROME desired_capabilities["goog:loggingPrefs"] = { "performance": "ALL", } driver = Chrome( desired_capabilities=desired_capabilities, ) driver.implicitly_wait(5) driver.get("https://www.google.com/") known_url_set = set() while True: performance_log_entries = driver.get_log("performance") for log_entry in performance_log_entries: log_message = json.loads(log_entry.get("message", "{}")).get("message", {}) method = log_message.get("method") params = log_message.get("params", {}) if method == "Network.responseReceived": response = params.get("response", {}) url = response.get("url") if url in known_url_set: continue known_url_set.add(url) print(url) time.sleep(1) Python+SeleniumでChromeデベロッパーツールのNetworkタブ相当の情報を取得する - Qiita java - Using Selenium how to get network request - Stack Overflow

2023年4月24日 · aoirint

Selenium デフォルトダウンロードディレクトリを変更する(Chrome, Python)

Selenium 4.9.0 Chrome 112 ChromeDriver 112.0.5615.49 Python 3.11 from selenium.webdriver import ( Chrome, ChromeOptions, ) download_dir = "./downloads" os.makedirs(download_dir, exist_ok=True) options = ChromeOptions() options.add_experimental_option("prefs", { "profile.default_content_settings.popups": 0, "download.default_directory": os.path.realpath(download_dir), "download.prompt_for_download": False, "download.directory_upgrade": True, }) driver = Chrome( options=options, ) python - How to change download directory location path in Selenium using Chrome? - Stack Overflow

2023年4月24日 · aoirint

FFmpegで動画を逆再生化するPythonスクリプト

MATVToolに組み込むかもしれませんが、いまのところ詳細な動作検証をするほど需要がないので、簡易的にここに置いておきます。 動画ファイルによっては、フレームの欠け、重複が発生したり、変換に失敗するかもしれません。 Python 3.11.3 FFmpeg 4.2.7-0ubuntu0.1 Ubuntu 20.04 (WSL2) python3 main.py input.mp4 output.mp4 # License: CC0-1.0 import os import subprocess import tempfile import re import math def get_duration_seconds(input_file: str) -> float: proc = subprocess.run( [ 'ffmpeg', '-hide_banner', '-i', input_file, ], stderr=subprocess.PIPE, ) lines = proc.stderr.decode(encoding='utf-8').splitlines() # hh:mm:ss.ff duration_string = None for line in lines: m = re.match(r'^\s*Duration:\s(.+?),.*$', line) if m: duration_string = m.group(1) break assert duration_string is not None hours = int(duration_string[0:2]) minutes = int(duration_string[3:5]) seconds = int(duration_string[6:8]) milliseconds = float('0.' + duration_string[9:11]) return hours * 3600 + minutes * 60 + seconds + milliseconds def parse_time(string: str) -> float: """ string: HH:MM:SS.FF """ hours = int(string[0:2]) minutes = int(string[3:5]) seconds = int(string[6:8]) milliseconds = float('0.' + string[9:11]) return hours * 3600 + minutes * 60 + seconds + milliseconds def format_time(seconds: int) -> str: hours_minutes = seconds // 60 hours = hours_minutes // 60 minutes = hours_minutes - hours * 60 local_seconds = seconds - hours_minutes * 60 return f'{hours:02d}:{minutes:02d}:{local_seconds:02d}' def main(): import argparse parser = argparse.ArgumentParser() parser.add_argument('input_file', type=str) parser.add_argument('output_file', type=str) parser.add_argument('--split_duration', type=int, default=10) args = parser.parse_args() input_file = args.input_file output_file = args.output_file split_duration = args.split_duration duration_seconds = math.ceil(get_duration_seconds(input_file=input_file)) count = math.ceil(duration_seconds / split_duration) work_dir_obj = tempfile.TemporaryDirectory() work_dir = work_dir_obj.name part_output_file_list = [] for index in range(count): start = index * split_duration end = start + split_duration start_string = format_time(start) end_string = format_time(end) print(index, start_string, end_string) part_output_file = os.path.join(work_dir, f'output{count-index}.mp4') subprocess.run([ 'ffmpeg', '-hide_banner', '-ss', start_string, '-to', end_string, '-i', 'input.mp4', '-vf', 'reverse', '-af', 'areverse', part_output_file, ]) part_output_file_list.append(part_output_file) list_file = os.path.join(work_dir, 'list.txt') with open(list_file, 'w', encoding='utf-8') as fp: for part_output_file in part_output_file_list: fp.write(f"file '{part_output_file}'\n") subprocess.run([ 'ffmpeg', '-hide_banner', '-f', 'concat', '-safe', '0', '-i', list_file, '-c', 'copy', output_file, ]) if __name__ == '__main__': main() 参考 How to Reverse a Video using FFmpeg - OTTVerse 映像と音声を逆再生にエンコードする | ニコラボ FFMPEGで動画を逆再生して保存する方法 | 技術的特異点 Concatenate – FFmpeg

2023年4月18日 · aoirint

markdownlint-cli2

Node.js 18.16.0 markdownlint-cli2 0.6.0 https://www.npmjs.com/package/markdownlint-cli2 npm install -g markdownlint-cli2 # lint markdownlint-cli2 # format markdownlint-cli2-fix Config .markdownlint-cli2.yaml Example: https://github.com/DavidAnson/markdownlint/blob/fcb8190781c80b292ac44f6df984326e0e6c69cd/schema/.markdownlint.yaml # https://github.com/DavidAnson/markdownlint # https://github.com/DavidAnson/markdownlint-cli2 globs: - "**/*.md" ignores: - ".git/**" - ".github/**" config: # h1 MD025: false # inline HTML MD033: false

2023年4月17日 · aoirint

GatsbyのsiteMetadataにカスタムデータを追加する

Node.js 18.16.0 Gatsby 5.8.1 gatsby-config.ts const config: GatsbyConfig = { siteMetadata: { siteUrl: "https://example.com", title: "Example Blog", myCustomData: myCustomData, }, graphqlTypegen: true, // ... } gatsby-node.ts export const createSchemaCustomization: GatsbyNode['createSchemaCustomization'] = ({ actions }) => { const { createTypes } = actions createTypes(` type MyCustomData { text: String flag: Boolean } type SiteSiteMetadata { myCustomData: MyCustomData } `) } mypage.tsx import * as React from "react" import { graphql, PageProps, } from 'gatsby' import { GetMyPageQuery } from '../gatsby-types' const MyPage: React.FC<PageProps<GetMyPageQuery>> = (props) => { const data = props.data const site = data?.site const myCustomData = site?.siteMetadata?.myCustomData // ... } export const pageQuery = graphql` query GetMyPage { site { siteMetadata { myCustomData { text flag } } } } ` export default MyPage 参考 https://github.com/gatsbyjs/gatsby/issues/1781 https://stackoverflow.com/questions/61530280/unable-to-filter-custom-data-in-sitemetadata-in-gatsby-using-graphql-in-graphiql https://tomiko0404.hatenablog.com/entry/2022/02/20/gatasby-graphql-datalayer https://stackoverflow.com/questions/62984585/gatsby-how-to-handle-undefined-fields-in-sitemetadata

2023年4月17日 · aoirint