コーディング中の過集中を防止する簡易アプリをPythonで作ってみた【Windows・VSCode用】

## 目次
[1. こんな感じのアプリ](#こんな感じのアプリ)
[2. 主な機能](#主な機能)
[3. なぜ作ろうと思ったか](#なぜ作ろうと思ったか)
[4. アプリのセットアップ](#アプリのセットアップ)
  - [4.1 コードのインストール](#コードのインストール)
  - [4.2 アイコンの設定](#アイコンの設定)
  - [4.3 ライブラリのインストール](#ライブラリのインストール)
  - [4.4 exeファイルの作成](#exeファイルの作成)

[5 使用方法](#使用方法)
  - [5.1 アプリケーションの起動](#アプリケーションの起動)
  - [5.2 時間帯の設定](#時間帯の設定)
  - [5.3 終了](#終了)
  - [5.4 注意点](#注意点)

[6. 処理の内容](#処理の内容)
[7. 使ってみてどうだったか](#使ってみてどうだったか)


## こんな感じのアプリ
毎時指定された時間内のとき、自動的にVSCodeを保存して終了するアプリです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296599/ea817939-6b36-b5a5-4db9-d70185ae05b1.png)

## 主な機能
- 毎時アプリで設定した時間内（デフォルトだと30分から59分の間）になると、VSCodeのプロセスを終了する
- VSCodeのウィンドウが最小化されていない場合、自動でファイル保存のショートカットキーを実行してからプロセスを終了する
- VSCodeのウィンドウが最小化されている場合、単にプロセスを終了する（保存されていないファイルがあっても、再度VSCodeでファイルを開けば変更内容は引き継がれます）

## なぜ作ろうと思ったか
コーディングをしていると、ついつい集中しすぎてしまって体は休みたいと思っているのに、数時間辞め時がわからないまま続けてしまうことが度々ありました。
その結果「**作業は終わったけど、疲れすぎてもう何もしたくない、、**」みたいな状況になることが多く、長期的な生産性を考えたときに良くないなとずっと思っていました。
そこで、過集中を防止するために、毎時指定の時間になったらVSCodeを強制終了してくれるようなアプリがあったらなと思い作ってみました。
会社のPCで使いたかったので、余計な外部ソフトウェアに頼りたくなかったことも自作した理由の一つです。

## アプリのセットアップ
### コードのインストール
コードを[Github](https://github.com/Asiaticum/vscode_blocker)に挙げているので、適当なディレクトリにダウンロードしてください。

### アイコンの設定
vscode_blocker.pyの20行目の
```python
icon_path = "/path/to/your/icon.jpg"
```
をご自分の環境に合わせて、変更してください。
icon.jpgをGithubにも上げていますが、好きな画像をアイコンにすることもできます。

### ライブラリのインストール
ライブラリインストール:
アプリケーションを実行するために必要なライブラリを以下でインストールします。
```bash
pip install pyautogui psutil PyQt5
```

### exeファイルの作成
スクリプトファイル（vscode_blocker.py）があるディレクトリで以下のコマンドを実行してください。

```bash
pip install pyinstaller
pyinstaller --onefile --noconsole .\vscode_blocker.py
```
これにより、distディレクトリが作成され、その中にvscode_blocker.exeが生成されます。

## 使用方法
### アプリケーションの起動:
distディレクトリ内のvscode_blocker.exeをダブルクリックしてアプリケーションを起動します。アイコンがシステムトレイに表示され、アプリケーションがバックグラウンドで実行を開始します。
プログラムが開始すると、以下のようなアイコンがタスクバーに表示されます（以下の画像はGithubに上げたアイコンの画像を使った場合）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296599/95cedec8-b0c6-959f-289a-e1673c5eeb4e.png)


### 時間帯の設定:
システムトレイのアイコンを右クリックし、「Set Time Limits」を選択して、VS Codeを終了させたい時間帯を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296599/682870f3-fcda-e4a6-07d1-fa79b2678b6c.png)

デフォルトでは毎時30分から59分までになっていますが、この30-59の範囲を変更できます。
以下のように一つ目のボックスで開始時間を設定してOKを押すと、二つ目のボックスが表示され、そこで終了時間を設定するようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296599/fa096d43-63d8-55c7-edad-89b73d50c394.png)


### 終了:
システムトレイのアイコンを右クリックし、「Exit」を選択することでアプリケーションを終了させることができます。

### 注意点
デバッグをきちんとしていないので、予期せぬ動作によってクラッシュしてしまう可能性があることは使用の際ご了承ください。

## 処理の内容
全体のソースコードはGithubをご覧ください。
複雑な処理はしていないですが、
```python
def is_vscode_running():
    for process in psutil.process_iter(["pid", "name"]):
        if process.info["name"] == "Code.exe":
            return True
    return False
```
によって、VSCodeが起動しているかの確認を行い、VSCodeが起動している場合は、以下のコードによってファイルの自動保存を行います。
```python
def save_all_in_vscode():
    windows = pyautogui.getWindowsWithTitle("Visual Studio Code")
    if windows:
        try:
            print("VS Code is running.")
            windows[0].activate()

            # 「全て保存」のショートカットを実行
            pyautogui.hotkey("ctrl", "k")
            time.sleep(0.2)  # キー入力の間に短い遅延を設ける
            pyautogui.press("s")
        except:
            pass
```
そして、 
```python
def kill_vscode():
    try:
        subprocess.run(
            ["taskkill", "/f", "/im", "Code.exe"],
            check=True,
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL,
        )
    except subprocess.CalledProcessError:
        pass  # Visual Studio Code is not running or already closed.
```
によって、VSCodeのプロセスを終了させています。

## 使ってみてどうだったか
集中していても、設定時間になってVSCodeが強制終了されると「あぁ、休憩しなきゃ」という気持ちになるので、今のところ良い感じです。
過集中は自分の意志では対策が難しいと感じているので、集中を邪魔する仕組み化が大事だなと思いました。