Tuesday, January 6, 2026

Debian 13: bash to clean up unused gradle in folder $HOME/.gradle

stop any gradle daemon (better run this after you start your Debian)

copy paste this bash and change permission to execute

#!/bin/bash

# Set the cutoff date yyyy-mm-dd
CUTOFF_DATE="2025-08-01"

# Gradle folder
GRADLE_DIR="$HOME/.gradle"

# List of folders to clean
FOLDERS=("android" "build-scan-data" "caches" "daemon" "kotilin-profile" "native" "notifications" "undefined-build" "wrapper" ".tmp")

# 1. Stop Gradle Daemons first so files aren't locked
if [ -f "$GRADLE_DIR/daemon" ]; then
    echo "Stopping Gradle daemons..."
    gradle --stop 2>/dev/null || ./gradlew --stop 2>/dev/null
fi

echo "Cleaning Gradle folders in $GRADLE_DIR modified before $CUTOFF_DATE..."

for folder in "${FOLDERS[@]}"; do
    TARGET="$GRADLE_DIR/$folder"
    if [ -d "$TARGET" ]; then
        echo "Processing $TARGET..."
        # Find and delete files modified before the cutoff date
        find "$TARGET" -type f ! -newermt "$CUTOFF_DATE" -print -delete
        # Remove empty directories
        find "$TARGET" -type d -empty -print -delete
    else
        echo "Folder $TARGET does not exist, skipping."
    fi
done

echo "Cleanup complete."

Note:

  • change CUTOFF_DATE for any desire date
  • add or remove FOLDERS depends on your folder structure 

termux android: ffmpeg split video, rotate, convert h26h video, merge video

Requirement

Install termux from 

  • play store 
  • github.com/termux/termux-app latest but require allow install from unknown source

open termux and update

$ pkg upgrade

install ffmpeg

$ pkg install ffmpeg nano termux-api

Allow termux to manage files

$ termux-setup-storage

Finding the correct path 

Find location of your file, and open termux

You can get file info from file manager provided by your phone. This is information from Google File -> File info

/emulated/0/DCIM/Camera/Thumbnail/ebd64812dbf4ded1ce79xa 

Open your termux

 ~ $ cd ~/storage
~/storage $ pwd
/data/data/com.termux/files/home/storage
~/storage $ ls
audiobooks  downloads   movies    podcasts
dcim        external-0  music     shared
documents   media-0     pictures

In android it is DCIM but in termux it is become dcim 

Note these:

  • From file manager: /emulated/0/DCIM/Camera/Thumbnail/ebd64812dbf4ded1ce79xa -> to broadcast the files
  • From termux: /data/data/com.termux/files/home/storage/dcim/Camera/Thumbnail/ebd64812dbf4ded1ce79xa -> to browse in termux terminal

Split a video by time

Target:

  • every piece has 1 minutes 58 seconds
  • resolution low 480
  • output h264
  • sound mono

command to convert '172967815750944 (1).mp4'

$ ffmpeg -i 172967815750944\ \(1\).mp4 -vf scale=-2:480 -r 25 -c:v libx264 -preset veryfast -crf 28 -ac 1 -c:a aac -b:a 96k -f segment -segment_time 118 -reset_timestamps 1 out_%03d.mp4

this command will create files with name starting with name out_[number].mp4

This is fastest way to split video into smaller size, but you need to write the long command. This is bash sh to split file to avoid write long command. Open nano and copy paste it, name it with mysplitvid.sh. Make it execute $ chmod u+x mysplitvid.sh.

#!/data/data/com.termux/files/usr/bin/bash

# Check input
if [ -z "$1" ]; then
  echo "Usage: $0 inputvideo.mp4"
  exit 1
fi

INPUT="$1"
BASENAME=$(basename "$INPUT" .mp4)

# Output directory (public, visible to other apps)
OUTDIR="/sdcard/Download/${BASENAME}_split"
mkdir -p "$OUTDIR"

# FFmpeg split + encode
ffmpeg -i "$INPUT" \
  -vf scale=-2:480 \
  -r 25 \
  -c:v libx264 \
  -preset veryfast \
  -crf 28 \
  -ac 1 \
  -c:a aac \
  -b:a 96k \
  -f segment \
  -segment_time 118 \
  -reset_timestamps 1 \
  "$OUTDIR/${BASENAME}_out%02d.mp4"

# Notify Android media scanner for all outputs
for file in "$OUTDIR"/*.mp4; do
  am broadcast \
    -a android.intent.action.MEDIA_SCANNER_SCAN_FILE \
    -d "file://$file" >/dev/null
done

echo "✅ Done!"
echo "📂 Output folder: $OUTDIR”

Convert video h256 to social media

Target:

  • Video Codec: H.264 (libx264)
  • Audio Codec: AAC
  • Pixel Format: yuv420p (Required for maximum compatibility)
  • Audio Sample Rate: 48kHz or 44.1kHz
  • Container: MP4  

To convert an H.265 MP4 to a Twitter-compatible, highly compressed, lower-resolution MP4 using FFmpeg, you need to re-encode the video to H.264 video codec, AAC audio codec, a maximum resolution of 1280x720, and a lower bitrate/higher CRF value.

Assume your file is inputfile.mp4 and located at Download folder in your Android.  Here are command to convert your video to make compatible for social media. Currently social media do not support high compression like h265.

~/ $ cd ~/storage
~/storage $ ls
audiobooks downloads movies podcasts
dcim external-0 music shared
documents media-0 pictures
~/storage $ cd downloads
~/storage/downloads $ ls *.mp4
inputfile.mp4
~/storage/downloads $ ffmpeg -i inputfile.mp4 -c:v libx264 -crf 28 -preset medium -vf "scale=1280:720,format=yuv420p" -c:a aac -b:a 128k -movflags faststart output.mp4
...

This is bash sh to split file to avoid write long command. Open nano and copy paste it, name it with myconverth265.sh. Make it execute $ chmod u+x myconverth265.sh.

#!/data/data/com.termux/files/usr/bin/bash
set -e
if [ $# -ne 2 ]; then
    echo "Usage: $0 input.mp4 output.mp4"
    exit 1
fi

INPUT="$1"
OUTPUT="$2"

ffmpeg -i "$INPUT" \
  -c:v libx264 -crf 28 -preset medium \
  -vf "scale=1280:720,format=yuv420p" \
  -c:a aac -b:a 128k \
  -movflags faststart \
  "$OUTPUT"

MEDIA_PATH="$(realpath "$OUTPUT")"

am broadcast \
  -a android.intent.action.MEDIA_SCANNER_SCAN_FILE \
  -d "file://$MEDIA_PATH"

echo "Scanned:"
echo "$MEDIA_PATH"

Rotate

ffmpeg -i inputvid.mp4 -vf "transpose=1" outputvid.mp4
Parameters:
-i inputvid.mp4: Specifies the input video file.
-vf "transpose=1": This filter rotates the video 90 degrees clockwise.
0 = 90° counterclockwise and vertical flip (default) 
1 = 90° clockwise 
2 = 90° counterclockwise 
3 = 90° clockwise and vertical flip

Example use

$ cd storage/dcim/Camera
ffmpeg -i input.mp4 -vf "transpose=2" out.mp4
$ ls ~/storage/dcim/Camera/out.mp4 
/data/data/com.termux/files/home/storage/dcim/Camera/out.mp4
am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file:///storage/emulated/0/DCIM/Camera/out.mp4

Merge file with the same video properties

list file to merge

~/.../Thumbnail/ebd64812dbf4ded1ce79xa $ ls
out_001.mp4  out_004.mp4  out_007.mp4
out_002.mp4  out_005.mp4
out_003.mp4  out_006.mp4 

Create file list.txt

~/.../Thumbnail/ebd64812dbf4ded1ce79xa $ nano list.txt
E.g
# comment list of files
file 'out_001.mp4'
file 'out_002.mp4'
file 'out_003.mp4'
file 'out_004.mp4'
file 'out_005.mp4'
file 'out_006.mp4'
file 'out_007.mp4’ 

Merge

~/.../Thumbnail/ebd64812dbf4ded1ce79xa $ ffmpeg -f concat -safe 0 -i list.txt -c copy merged.mp4 

broadcast the new video

~/.../Thumbnail/ebd64812dbf4ded1ce79xa $ am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file:///sdcard/DCIM/Camera/Thumbnail/ebd64812dbf4ded1ce79xa

Make your output video accessible by other application 

Your output file owner is Termux. To make it accessible by other applications e.g. photos, files, etc, you can try these option

• Force android system to scan your output

$ am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file:///sdcard/[real_location]

From file location above

Note these:

  • From file manager: /emulated/0/DCIM/Camera/Thumbnail/ebd64812dbf4ded1ce79xa
  • From termux: /data/data/com.termux/files/home/storage/dcim/Camera/Thumbnail/ebd64812dbf4ded1ce79xa 

Replace [real_location] becomes file:///sdcard/DCIM/Camera/Thumbnail/ebd64812dbf4ded1ce79xa

It will scan all files in drive, or you can specify for specific file only.

Using termux-api (termux-media-scan) is an alternative way for am.  On newer Android versions (Android 10+), this may not work due to scoped storage restrictions. termux-media-scan is the recommended way. 

$ termux-media-scan /sdcard/[real_location] 

I test am and termux-media-scan on android 13 infinix Note 12, they work properly without issue. except for multimedia store in Thumbnail folder, only show in file manager, e.g google files.

Using bash script

To use bash script, at ~/ create bash script e.g. convert.sh and you can paste the bash code above under nano editor

~/ $ nano convert.sh
~/ $ chmod +x convert.sh

Goto directory e.g Download and run the script using ~/[filename].sh e.g 

~/.../Thumbnail/ebd64812dbf4ded1ce79xa $ ~/convert.sh vidIn.mp4 vinOut.mp3

 

 




Monday, December 22, 2025

python3: my personal package mini function

 

~/
├── .gitignore
├── dedetoklib/
│     ├── mydate
│     │     ├── __init__.py
│     │     ├── check_holiday.py
│     │     └── requirements.txt
│     ├── 
│     ├── 
│     └── 

├── test
│     ├── main.py

└── requirements.txt

 

check_holiday.py

import holidays
from datetime import datetime

# Create holiday object for Indonesia
ID_HOLIDAYS = holidays.country_holidays("ID")

def is_holiday(date_str):
    """
    Check if a date (YYYY-MM-DD) is a holiday.
    
    Returns:
        (bool, str | None): 
        - True and holiday name if holiday
        - False and None if not
    """
    date_obj = datetime.strptime(date_str, "%Y-%m-%d").date()
    
    if date_obj in ID_HOLIDAYS:
        return True, ID_HOLIDAYS[date_obj]
    else:
        return False, None

def is_working_day(date_str):
    """
    Check if a date (YYYY-MM-DD) is a working day (Monday to Friday).
    Returns:
        bool: True if Monday–Friday, False if Saturday or Sunday
    """
    date_obj = datetime.strptime(date_str, "%Y-%m-%d").date()
    # weekday(): Monday = 0, Sunday = 6    if date_obj.weekday() < 5:
        return True, "Weekday"
    else:
        return False, "Weekend"

Test main.py

from dedetoklib import check_holiday

dates = ["2025-01-01", "2025-01-02", "2025-08-17"]

for d in dates:
    # Check holiday
    holiday_flag, holiday_name = check_holiday.is_holiday(d)
    
    # Check working day
    working_flag, working_str = check_holiday.is_working_day(d)
    
    print(f"{d}: {working_str}, Holiday? {holiday_flag}", end="")
    if holiday_flag:
        print(f" ({holiday_name})")
    else:
        print()

 from dedetoklib import check_holiday as ch



 


 

python3: writing package

 
create folder to put your pyhton files e.g. dedetoklib, 

the structure of directory  

~/
├── .gitignore 

├── dedetoklib/
│   ├── __init__.py
│   └── hello.py

── main.py
└── requirements.txt

hello.py

def say_hello():
    return "Hello, World"

__init__.py

(leave it empty)

main.py 

import dedetoklib.hello

dedetoklib.hello.say_hello()

import as library

import dedetoklib.hello as h

print(h.say_hello())

 requirements.txt contains dependency.

.gitignore contains  files and folders to ignore.

Wednesday, December 10, 2025

Debian 13: rebuilding nvidia driver after kernel upgrade from linux-image-6.12.31-amd64 to linux-image-6.12.57+deb13-amd64

After you upgrade kernel, in my case linux-image-6.12.31-amd64 to linux-image-6.12.57+deb13-amd64, you need to rebuild nvidia driver. During boot, Debian will show some error loading nvidia module

To check which module fail during boot 

# journalctl -b -u systemd-modules-load.service 
Dec 10 09:48:02 mylocalpc systemd-modules-load[781]: modprobe: ERROR: Error running install command 'modprobe n> 
Dec 10 09:48:02 mylocalpc systemd-modules-load[781]: modprobe: ERROR: could not insert 'nvidia_modeset': Invali> 
Dec 10 09:48:02 mylocalpc systemd-modules-load[789]: modprobe: FATAL: Module nvidia-current-drm not found in di> 
Dec 10 09:48:02 mylocalpc systemd-modules-load[767]: Error running install command 'modprobe nvidia-modeset ; m> 
Dec 10 09:48:02 mylocalpc systemd-modules-load[767]: Failed to insert module 'nvidia_drm': Invalid argument 
Dec 10 09:48:02 mylocalpc systemd[1]: systemd-modules-load.service: Main process exited, code=exited, status=1/> 
Dec 10 09:48:02 mylocalpc systemd[1]: systemd-modules-load.service: Failed with result 'exit-code'. 
Dec 10 09:48:02 mylocalpc systemd[1]: Failed to start systemd-modules-load.service - Load 

To install dkms

root@mylocalpc:~# apt install dkms
dkms is already the newest version (3.2.2-1~deb13u1).
dkms set to manually installed.
Summary:
  Upgrading: 0, Installing: 0, Removing: 0, Not Upgrading: 1

To show dkms status

root@mylocalpc:~# dkms status
nvidia-current/550.163.01, 6.12.31-amd64, x86_64: installed 

To rebuild nvidia driver, it will build any kernel installed.

root@mylocalpc:~# dkms install nvidia-current/550.163.01
Sign command: /lib/modules/6.12.57+deb13-amd64/build/scripts/sign-file
Signing key: /var/lib/dkms/mok.key
Public certificate (MOK): /var/lib/dkms/mok.pub

Building module(s)................ done.
Signing module /var/lib/dkms/nvidia-current/550.163.01/build/nvidia.ko
Signing module /var/lib/dkms/nvidia-current/550.163.01/build/nvidia-modeset.ko
Signing module /var/lib/dkms/nvidia-current/550.163.01/build/nvidia-drm.ko
Signing module /var/lib/dkms/nvidia-current/550.163.01/build/nvidia-uvm.ko
Signing module /var/lib/dkms/nvidia-current/550.163.01/build/nvidia-peermem.ko
Installing /lib/modules/6.12.57+deb13-amd64/updates/dkms/nvidia-current.ko.xz
Installing /lib/modules/6.12.57+deb13-amd64/updates/dkms/nvidia-current-modeset.ko.xz
Installing /lib/modules/6.12.57+deb13-amd64/updates/dkms/nvidia-current-drm.ko.xz
Installing /lib/modules/6.12.57+deb13-amd64/updates/dkms/nvidia-current-uvm.ko.xz
Installing /lib/modules/6.12.57+deb13-amd64/updates/dkms/nvidia-current-peermem.ko.xz
Running depmod.... done.

to check status of nvidia modul

root@mylocalpc:~# dkms status
nvidia-current/550.163.01, 6.12.31-amd64, x86_64: installed
nvidia-current/550.163.01, 6.12.57+deb13-amd64, x86_64: installed

restart your debian.