Pythonで書いて、サービスにしておいたので、
ラズパイが起動したら表示されます
1円起業した人付き合いの苦手な普通のプログラマの日々
政党 | 2026 | 2024 | 2021 | 2017 |
|---|---|---|---|---|
| 自民党 | 20.66% | 約17.8% | 約19.7% | 約17.9% |
| 立憲+公明(→中道改革連合) | 約10.25% | 約18.3% | 約18.4% | 約16.7% |
| 国民民主 | 5.47% | 約6.8% | 約2.6% | 約1.4% |
| 維新 | 4.85% | 約8.7% | 約8.0% | 約3.4% |
| 共産 | 2.48% | 約3.5% | 約4.1% | 約4.0% |
| れいわ | 1.64% | 約2.9% | 約2.2% | ― |
最近MacbookNeoをつかいまくってて、
SDカードとか書き込んでて気がついた
そうだった。.ds_storeとか_ファイル名とか、Macを使ってると隠しファイルができてしまうのだ。
しかし!
それらを消すコマンドがある!
ターミナルを開いて、以下のコマンドを入れる
dot_clean -m /Volumes/NO\ NAME
マウントされている名前はNO NAMEなんだけど、スペースが入ってるからバックスラッシュ・スペースでつながっている
これを毎回やるのは嫌なので、
取り出しをするときにフックして、dot_cleanを実行するアプリを作ってみた。
名前はdcleanにした
xcodeを立ち上げて、アカウント入れたりなんだりしてから、contentViewやItemを消して、dcleanAppだけ残して以下のように書き換え
import SwiftUI
import AppKit
import Combine // 🌟 これを追加!
// MARK: - 1. ログのデータ構造と管理クラス
// 重複したログでも区別できるように Identifiable にする
struct LogItem: Identifiable {
let id = UUID()
let text: String
}
// ログを管理し、UI(メニューバー)を更新する専用のクラス
class LogStore: ObservableObject {
static let shared = LogStore()
@Published var logs: [LogItem] = []
// UIの更新は必ずメインスレッドで行う
func addLog(_ message: String) {
DispatchQueue.main.async {
let formatter = DateFormatter()
formatter.dateFormat = "HH:mm:ss" // 実行時間も表示
let timeString = formatter.string(from: Date())
let newLog = LogItem(text: "[\(timeString)] \(message)")
// 最新のログが一番上に来るように追加
self.logs.insert(newLog, at: 0)
// メニューが長くなりすぎないよう最新10件に制限
if self.logs.count > 10 {
self.logs.removeLast()
}
}
}
func clear() {
DispatchQueue.main.async {
self.logs.removeAll()
}
}
}
// MARK: - 2. メインのApp定義
@main
struct dcleanApp: App {
// LogStoreの変更を監視する
@StateObject private var logStore = LogStore.shared
init() {
// アプリ起動時にディスク監視を開始
DiskObserver.shared.start()
}
var body: some Scene {
MenuBarExtra("dclean", systemImage: "wand.and.stars") {
Text("外付けドライブの取り外しを監視中...")
.font(.caption)
.disabled(true)
// ログが存在する場合のみ履歴メニューを表示
if !logStore.logs.isEmpty {
Divider()
Text("最近の動作履歴")
.font(.caption)
.disabled(true)
ForEach(logStore.logs) { log in
Text(log.text)
.font(.system(size: 11)) // ログは少し小さめの文字で表示
}
Divider()
Button("履歴をクリア") {
logStore.clear()
}
}
Divider()
Button("アプリを終了") {
NSApplication.shared.terminate(nil)
}
}
.menuBarExtraStyle(.menu)
}
}
// MARK: - 3. ディスク監視クラス
class DiskObserver: NSObject {
static let shared = DiskObserver()
private override init() {
super.init()
}
func start() {
NSWorkspace.shared.notificationCenter.addObserver(
self,
selector: #selector(handleVolumeWillUnmount(_:)),
name: NSWorkspace.willUnmountNotification,
object: nil
)
}
@objc func handleVolumeWillUnmount(_ notification: Notification) {
guard let volumeURL = notification.userInfo?[NSWorkspace.volumeURLUserInfoKey] as? URL else { return }
let path = volumeURL.path
guard path.hasPrefix("/Volumes/") else { return }
// "/Volumes/USB_Drive" から "USB_Drive" の部分だけを抽出して見やすくする
let driveName = volumeURL.lastPathComponent
print("取り外しを検知: \(path) - dot_cleanを開始します。")
LogStore.shared.addLog("⏳ \(driveName) をクリーン中...")
runDotClean(for: path, driveName: driveName)
}
func runDotClean(for path: String, driveName: String) {
let task = Process()
task.launchPath = "/usr/sbin/dot_clean"
task.arguments = ["-m", path]
do {
try task.run()
task.waitUntilExit()
print("dot_clean完了: \(path) - 安全に取り外します。")
LogStore.shared.addLog("✅ \(driveName) のクリーン完了")
} catch {
print("dot_clean実行エラー: \(error.localizedDescription)")
LogStore.shared.addLog("❌ \(driveName) でエラー発生。\(error.localizedDescription)")
}
}
}
三角を押して動作確認したら、ビルド対象をAny Mac(arm64, x86_64)にして、メニューのプロダクトからアーカイブを選んでディストリビュートし、CopyAppを選んで適当なところに配置、XCODEでを終わらせて、できたAppをダブルクリックしたら動くはず
これで、いちいち、dot_cleanする必要はなくなった。
欲しい方はこちらからどうぞ
2026年06月30日バージョンから、上記説明の他にあれこれ追加して、右クリックメニューのクイックアクションにフォルダをクリーンアップするCleanupと、.DS_Storeや._ファイル名を除外しながらZIPを作るmakeCleanZipを登録する事ができるように修正しました。
2026年07月04日ネットワークドライブなども対象になっていたので、それらを除外する処理を追加しました。
2026年07月07日アプリ用アイコン作成、上部常駐部アイコン作成、下部のバーにアイコンが出てしまったのを修正
起動すると上部にアプリが常駐します。
クイックアクション設定から「Finder右クリックに追加する」で、クイックアクションが登録されます。
「Finder右クリックから削除する」でクイックアクションは消せます。
終了させるときは「アプリを終了」です。実はこれを作る前にはKekaというアプリを使っていたのですが、
ZIPしか使わないし、拙作アプリだけで良くなりました。
農業や漁業も若者に魅力のない職業らしいが、高齢化という点では、建設業もやばい、そして実はソフトウェアもやばい
というか本気でソフトウェアはマヂやばい
建設業に似てると思う
どちらの業種もノウハウが山のようにある
それなのに大工の研修数年やった程度の人に家を建ててもらうことになるのはマヂ勘弁してほしい
プログラマもそうだろ?
半年プログラミング講義して、現場に投入よ?
今はAI使ってそれらしい答えが得られるんだけど、、、
それ、正しいわけがないので、ちゃんと読んで治せる人がいないと全然ダメ
そのうちAIが変わるかもしれないけど、今時点ではどれもこれもまだダメ
いやー本当に、プログラムなんて組まないでいい時代になってほしいよ
そうしたらスッキリやめるのになー
まぁ、多分仕事は無くならない気がする
建てた家が十年後大丈夫か見極められる人、書いたプログラムがなんでそういう設計なのかメンテコストなど見越して設計できる人、そういう立場の連中は残るだろう
そこが居なくなったら大変よ
開くときにはトルクがあるのだけど、閉まるときに全然トルクがない
多分Hブリッジイカれた
仕方ないので自前回路で置き換える
まずは部品選定(単一電池2本で動くようにしないといけない)
PIC16F1825
モータードライバはDRV8835
赤外線距離センサーはGP2Y0E03
んで次がプログラム
https://www.onlyspoolz.com/portfolio/
こちらを見ると1kgサイズのスプールは厚みが65mm程度
だからわたしが以前採用したこちらのケースでは4つのスプールが収まります。
3100円なんですけど、業務用というものもあって、
サイズもほぼ一緒でこちらは2209円
わたしは底面から15cmの中心に、
Φ20のパイプを33cm長に切って、
3Dプリンタで作った部品で固定しています。
それを作ったのが2018年の年末で、
そこからずっと使ってますが、
一度もジャムったことがありません
よくある底面で支えるタイプも試したことはあるんですが、どうもゴロゴロして安定しません
フィラメントスプールは中心に穴が空いてるんだから、そこにΦ20のパイプを通して保持する方が断然安定しますし、この容器の中にシリカゲルを仕込んだ方が扱いも簡単です。
ですが、残念なのが一点
パイプ一本なので、真ん中のスプールだけ変えたい時に全スプールをら持ち上げなくてはなりません。
まぁ、4キロくらいどうってことはないんですけど、フィラメントがPTFEパイプに通っているとちょっとやりづらさはあります。
できれば、パイプを4本に切って、スプールホルダを四つ中に仕込みたい。
2ミリ幅くらいで仕込めたらいいんだけど、パイプ保持には両側から2cmくらいは欲しい
まぁそんな感じでホルダーのデザインをしてますがなかなかうまくいかないですね
薄さと強度の両立ってなかなか大変です。
多分これなら行けるかも?
幅70mm以下のスプールに対応ホルダーの幅自体は74mmになり、4つ分を横に並べると、74 x 4 = 296mm
先程の容器の下部は小さくすぼんでいるため、
容器の最小サイズは下部となり、30 x 20 x 23くらい
30cm なら296mmでぎり入ります。
百均の園芸支柱11mmを70mm長に切って4箇所取り付け、最上部はφ20mmのパイプを同じく70mmに切って上からはめる
はめるときは真ん中を少し広げないといけないので、
都度ホルダーごと上に抜き取る必要はありますが、
フィラメント4つを引き抜くよりは楽です。
ケースもこれ以上幅広のものを用意したくは無いので、これで決まりですかね・・・
あ、いやだめだ
スプールの真ん中がφ20くらいのパイプならOKなんだけど、
それの支え部分がφ40
全然だめだ・・・
もうちょい単純に考えてこれでいい気がしてきました
スプール中心にφ20のパイプを使うのもやめます。
支柱部品も3Dプリントで作ってしまいます。