Jump to content

Cold turkey blocker


Recommended Posts

  • 2 years later...
Posted (edited)

In case anybody else has trouble with this, the version I downloaded at the link actually requires the number of hours before the block name, so something like "block 5 news" would start and lock the 'news' blocker for 5 hours.  

You can change the script to work as indicated by @sinalalgedonico by changing the argument ('$') references as follows:

 

for i in ${*:1}
do
	/Applications/Cold\ Turkey\ Blocker.app/Contents/MacOS/Cold\ Turkey\ Blocker -start $i -lock $(($2 * 60))
done


It just swaps '$1' in place of '$2' and vice versa.  I modified this code all by myself without AI or Googling and I'm just chuffed at that.  It's still case sensitive for block names so be aware of that.

Edited by attaboyBrad
Posted (edited)

If you substitute the following for /bin/zsh under 'block', you can define a list of blocks to fuzzy search (so it's no longer case sensitive, must have fzf installed), and it will parse 'm' and 'h' units like '5m' for 'five minutes' or '2h' for 'two hours'.

EDIT: 
Updated this to default to 'hours' if the unit is not specified and the number entered is 12 or below, and minutes if the units is not specified and the number is greater than 12.
 

#!/bin/zsh

# Function to parse duration input (e.g., '5m', '2h', or '30')
parse_duration() {
    local input="$1"
    local value unit

    # Extract numeric value and unit using parameter expansion
    value="${input//[^0-9]/}"
    unit="${input//[0-9]/}"
    unit="${unit,,}"   # Convert to lowercase

    # Validate numeric value
    if [[ -z "$value" ]]; then
        echo "Invalid duration format '$input'. No numeric value found." >&2
        exit 1
    fi

    # Determine default unit if none provided
    if [[ -z "$unit" ]]; then
        if (( value <= 12 )); then
            unit="h"
        else
            unit="m"
        fi
    fi

    # Convert duration to minutes
    case "$unit" in
        h)
            echo $((value * 60))
            ;;
        m)
            echo "$value"
            ;;
        *)
            echo "Invalid unit '$unit'. Use 'h' for hours or 'm' for minutes." >&2
            exit 1
            ;;
    esac
}

# Ensure at least two arguments are provided
if [[ $# -lt 2 ]]; then
    echo "Usage: script_name <block_name1> [block_name2 ...] <duration>" >&2
    exit 1
fi

# Get the duration input (last argument)
duration_input="${@: -1}"

# Parse the lock duration
lock_duration_minutes=$(parse_duration "$duration_input")

# Get the block names (all arguments except the last one)
block_names=("${@:1:$(($#-1))}")

# Ensure 'fzf' is installed
if ! command -v fzf >/dev/null 2>&1; then
    echo "'fzf' is required for fuzzy matching. Install it with 'brew install fzf'." >&2
    exit 1
fi

# Define your block names here (update with your actual block names)
blocks=("Test" "Social Media" "News Sites" "Work Focus" "Gaming" "Video Streaming" "Chad")

# Function to perform fuzzy matching
fuzzy_match() {
    local query="$1"
    local match_result

    # Use fzf for fuzzy matching
    match_result=$(printf "%s\n" "${blocks[@]}" | fzf --filter="$query" --select-1 --exit-0)

    # Return the matched block
    echo "$match_result"
}

# Process each block name argument
for i in "${block_names[@]}"
do
    matched_block=$(fuzzy_match "$i")
    if [[ -n "$matched_block" ]]; then
        # Start the Cold Turkey block with the matched block name and parsed duration
        /Applications/Cold\ Turkey\ Blocker.app/Contents/MacOS/Cold\ Turkey\ Blocker -start "$matched_block" -lock "$lock_duration_minutes"
    else
        echo "No match found for '$i'" >&2
    fi
done



 

Edited by attaboyBrad
  • 1 month later...
Posted

@attaboyBrad thank you for the updated code!

It somehow didn't work for me at first. After a little bit of digging, I realised that the tolower conversion in the unit line seems to be shell-dependent (no idea why).

Anyway, in case you need to fix this, you can do so by replacing:

unit="${unit,,}"

with: 

unit=$(echo "$unit" | tr '[:upper:]' '[:lower:]')

 

Also, for anyone who would like to try this out themselves, do remember to replace the blocks variable values with your own as @attaboyBrad points out in the comments.

# Define your block names here (update with your actual block names)
blocks=("Test" "Social Media" "News Sites" "Work Focus" "Gaming" "Video Streaming" "Chad")

 

  • 4 weeks later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...