Readit News logoReadit News
Posted by u/ThePhysicist 3 years ago
Ask HN: Small scripts, hacks and automations you're proud of?
I sometimes think back fondly of the small automation scripts I wrote over the years, so I wanted to ask you: Which scripts, hacks & automations did you create that your're proud of? Personally, I e.g. built a bot to automatically answer apartment ads [1], a small script to run Borg backup once per day [2], and a small automation to track the temperature in my aquarium [3].

1: https://gist.github.com/adewes/c9b2a71457c6c6f01f2f

2: https://gist.github.com/adewes/02e8a1f662d100a7ed80627801d0a...

3: https://gist.github.com/adewes/7a4c20a5a7379e19d78ba54521d3d...

jimt1234 · 3 years ago
Honestly, the script/hack/automation I'm still most proud of is from around 1983, when I was 12 years old, for my Commodore 64. Back then, all computer communications were over the phone line, and in my house, we only had one line, so I spent a lot of late nights, dialing into BBSs, often not going to sleep until the sun came up. Then, I would get in trouble at school for falling asleep in class. So I came up with a little program I called "Simon". I named it after a popular kids game called "Simon Says". It was basically a 1983 version of Selenium. I created instruction files, which would tell the main program (Simon) what to do: the time to dial a BBS, the number to dial, the login info, and then all the commands to send. It did things like download my messages so I could read them the next day. Send messages. But mostly, and kinda shamefully, it was used to pirate games. I had a list of about 10 local BBSs that I would dial every night, and a list of games I was looking for. If Simon found a game on the list, it downloaded the game for me. Then, it would hang up. I even created a hard-hang-up time of 7am, when my mom woke up, because if the computer was still on the line and she needed to use the phone, she would kill me! LOL

I'm still super proud of that because it was so much fun to create. I recall "releasing" the program to a handful of friends, and they all seemed to like it, but it never really went anywhere.

mapster · 3 years ago
Very impressive. I was a xerox of you sans coding skills and entrepreneurship. I recall falling asleep while my C64 and Hess modem were being used my a ‘war dialer’. I did make a friend on a BBS who worked for Bell telephone - so we used UPS each week to ship each other envelopes of double sided floppies stuffed with fun games and utilities. I still get goosebumps when I hear a UPS truck pull open outside my home.
mettamage · 3 years ago
I wish I could give you an award. I’m also happy that HN doesn’t have that feature. So here have this instead:

            ___________
            '._==_==_=_.'
            .-\:      /-.
           | (|:.     |) |
            '-|:.     |-'
              \::.    /
               '::. .'
                 ) (
               _.' '._
          jgs `"""""""`

jasondigitized · 3 years ago
I ran my own BBS on my Commodore 64 for about a year. I was completely hooked and lost a lot of sleep as well. My mother came to me one day and said "You really need to go outside"
forinti · 3 years ago
Do tell us more. I suppose you downloaded the games to a floppy; did you have to worry about running out of space?
actually_a_dog · 3 years ago
Xmodem includes a header that specifies the exact file size. So, all you need to do is check that number against the amount of free space on whatever device you're downloading to.

Deleted Comment

edngibson · 3 years ago
When you were 12? Wow.
moonshinefe · 3 years ago
that sounds sweet haha
vagabund · 3 years ago
So certainly not impressive, and morally ambiguous, but when chatGPT first released, I worked with it to create a python script that crawled The New Yorker sitemaps, found articles with embedded audio versions, downloaded the mp3 by reconstructing the file url using the article ID in the page source, and then renamed the file to match the page title and saved it to a well structured Google Drive directory. Now when I walk my dog, exercise, or clean, I'll put on a random article and have a much more enjoyable experience than a podcast would offer. The mp3s were publicly available so I think it's fine for personal use?

I'd never written a line of code in my life, so going through the iterative process of getting it functioning and fixing bugs was pretty invigorating. I could see where the generated code was going awry and describe it in natural language, and chatGPT would turn that into syntax and explain why it worked. Definitely a fun way to learn.

I'm sure it's ugly/inefficient, but here's the script:

https://pastebin.com/raw/DuAVAikD

johtso · 3 years ago
"going through the iterative process of getting it functioning and fixing bugs was pretty invigorating."

Damn right it is! Writing scrapers is definitely the gateway drug of programming. It's such an exciting feeling to step across the boundaries from "passive user at the mercy of the UI" to "I can do anything if I can conceptualise it (and break it up into steps)".

photoGrant · 3 years ago
You summed up what dragged me from "Sure I'll learn to program a notepad or todo app so I can learn, but I won't" to "I can do anything if I think about what I want first, then how to get it!"
UI_at_80x24 · 3 years ago
For me it was writing MIRC scripts that monitored the IRC channels I was in. So it was scrapping the content, but not nearly as elegant as what the OP mentioned.
noufalibrahim · 3 years ago
Completely agree. It's often the first "real program" I give to my students when I teach coding and all of them love the high of doing it.
prashantsengar · 3 years ago
Pretty impressive to be able to create such a script when you haven't programmed before.

I used to freelance when I learnt to code in college and I wrote many such small automation scripts for quite a few people. Looks like the AI is already taking away some jobs ;)

Dead Comment

more_corn · 3 years ago
You might be one of the first of a new generation of programmers who start with no programming skills, bootstrap with chat gpt and reach a high level of capability. Keep hacking!
iambateman · 3 years ago
Very cool! It sounds like you could have a career in software development if you wanted one.
kmoser · 3 years ago
The comments are even more valuable than the code!
totetsu · 3 years ago
I was trying to do this same thing to download my Dalle2 history all at once. but being behind cloudflare made it a bit hard.
kkoncevicius · 3 years ago
This is more in the "hack" category, but here is a solution for bookmarking directories[1] that I am quite fond of:

  mkdir ~/.marks/
  export CDPATH=.:~/.marks/
  function mark { ln -sr "$(pwd)" ~/.marks/"$1"; }
Then:

  mark @name   # add bookmark called @name for the current directory
  cd @name     # jump to the bookmarked location
  cd @<tab>    # list all available bookmarks
It can list bookmarks, auto-complete, jump to sub-directories within bookmarks, all without introducing any new commands - just `cd`.

[1]: http://karolis.koncevicius.lt/posts/fast_navigation_in_the_c...

evgpbfhnr · 3 years ago
I've been trying this for a few days and now noticed u-boot no longer builds with an output dir ( `make O=subdir whatever` ).

It sure took me ages to figure it was CDPATH, but CDPATH it is. I won't retry without making that "cd @" thing a subfunction (that might involve making its own completion, but that's easy compared to debugging make... I still don't know WHY it broke, just that it's CDPATH that broke it -- it decided to duplicate the subdir arg when invoking a submake so make was now left with a weird unknown target, but it obviously wouldn't say that and just failed weirdly)

kkoncevicius · 3 years ago
Interesting, thanks for sharing. I would be tempted to call this a bug in the Makefile if this is the case. CDPATH is a standard bash environment variable, people use it in various ways: https://github.com/search?q=%22export+CDPATH%22&type=code

If all these causes the build to fail then the maintainers of that build should be informed.

the_fury · 3 years ago
I've just spent the last few minutes playing with the bookmarks snippet. This is both elegant and immediately useful to me. Thanks for sharing!
kkoncevicius · 3 years ago
Glad it is useful. Just a note of advice - prefix your bookmarks with a symbol that is not used to start directory names (was @ in my case).

This is useful for two things - 1) avoiding clashes with existing directories, 2) having a quick command to list all the bookmarks: cd @<tab>

p4l4g4 · 3 years ago
Awesome snippet! I organize most of my work using something similar to the Johnny decimal system[0] and use CDPATH for quicker lookups. But I love how you build a dynamic system with a simple oneliner!

[0] https://johnnydecimal.com/

gbrindisi · 3 years ago
Nice!

I gave up on bookmarking so I now use an alias to quickly find what I am looking for with fzf and fd:

  p () { cd $(fd $1 $HOME -d 4 -i -E Pictures -E Desktop | fzf) }

Deleted Comment

porcc · 3 years ago
For people interested in this def look into autojump before doing this
meain · 3 years ago
behnamoh · 3 years ago
I just use ranger and mark/bookmark directories like in Vim.
adrianh · 3 years ago
In 2004, the website All Music Guide did a horrible redesign. I was so irritated that I created a Firefox extension that did only one thing — it made All Music Guide a bit more useable.

To my knowledge, this was the first "site-specific" browser extension, so I wrote a blog post about it:

https://www.holovaty.com/writing/all-music-guide/

Aaron Boodman saw my post and decided to generalize the idea; he created Greasemonkey, which was a single browser extension that could aggregate site-specific JS customizations. In the years since, this idea of "user scripts" has further developed, and I think some browsers even support the concept natively.

netsharc · 3 years ago
Ah, that reminds me of how I modified sites using https://www.proxomitron.info/ , it's a Windows program that would start a local HTTP proxy and you can configure browsers to use this proxy, and it would block ads. This worked really well before the web became HTTPS-crazy.

The way it would block ads is to analyze the files it was fetching for the browser and modifying found keywords, for a crude example all IMG tags with SRC containing the string ad.* would be replaced by gray images.

I also remember using it to "fix" a redesign of a site.

mdaniel · 3 years ago
In that case, thank you to you both for dramatically improving my web experience -- I don't know that I could stand browsing without uBlockOrigin and ViolentMonkey

I'm not aware of any browsers that support it natively, although TBH there are so many random Firefox forks that any one of them could have just bundled the extension and called it native

gertlex · 3 years ago
Hah, well here's a thread to latch on to.

I'm pretty sure AllMusic was my source of track lengths for albums. Back in the middle of high school (so just before that redesign maybe?), I had some java utility that (I'm sure I'm imperfectly recalling) I pasted track information into. It then generated the Wikipedia markup equivalent, and I went around editing album pages on Wikipedia adding track lengths (and total album length).

And that's why I have something over 1000 wikipedia edits made a long time ago.

cpach · 3 years ago
I remember that AMG redesign. Horrible it was. And dog-slow IIRC. Had no idea about your extension and how it inspired Greasemonkey. Cool!
carpdiem · 3 years ago
Most useful script I've ever written, and legitimately how I keep track of everything important in my life:

  #! /bin/bash

  function todo {
   if [ $# -eq 0 ]
    then
     vim ~/Dropbox/todo/todo_list.txt
    else
     vim "$HOME/Dropbox/todo/todo_list_$1.txt"
   fi
  }
Sourcing this in my shell means I just have to type...

  todo
To automatically get into my default todo list which is synced to dropbox (and thus accessible everywhere on mobile as well).

While, whenever I have a new project/etc come up, I can just

  todo new_project_name
And get a new, nice clean file, with the same backups and multi-device accessibility.

gglitch · 3 years ago
Similar. I've ended up at these functions in .bashrc:

   # Append a timestamped entry to the journal
   log() {
       printf "$(date +%Y-%m-%d--%H:%M)   %s\n" "$*" >> $journal
   }
   
   # Query the journal
   lquery() {
       grep -ni $1 $journal
   }
   
   # Show all journal entries from today
   ltoday() {
       clear
       grep -n $(date +%Y-%m-%d) $journal
   }
   
   # On a line identified by line number, switch @todo to @done
   ldo() {
       sed -i "$1 s/@todo/@done/" $journal
       sed -i "$1 s/$/ \[COMPLETED $(date +%Y-%m-%d--%H:%M)\]/" $journal
   }
Nice things about this system: there's only one file; I'm only ever looking at the data I want to see; and there are no applications running or files open (except my terminal, I guess).

EFreethought · 3 years ago
I use Org mode in Emacs, so I have a follow up:

Do you have a format in your text files to track when things are done, like a checklist?

In Org, you can give things states like "TODO", "INPROGRESS", "DONE", "CANCELLED", add checkboxes (like "[ ]" and "[x]"), have sub-tasks/lists, etc.

I have really gotten into Org, and I have found there are a few other checklist formats/programs in plain text. Just wondering how you do it.

EVa5I7bHFq9mnYK · 3 years ago
I just have a Dropbox/todo.txt file opened permanently in Notepad++, no scripts and no need to type anything.
inconceivable · 3 years ago
here's my pull request

$ cat << EOF > ~/.bash_profile

> alias lstd='ls ~/Dropbox/todo'

> EOF

Deleted Comment

throwaway019254 · 3 years ago
And maybe some autocompletion if using zsh?

    #compdef todo
    
    _todo() {
      _files -W $HOME/Dropbox/todo/
    }
    
    _todo "$@"

jameskraus · 3 years ago
Easily my highest utility script so far was to get an edge while picking classes. At my university there were some classes which were very competitive and there was also system where tranches of students would get access to those classes earlier (e.g. groups of honors students -> groups of seniors -> juniors, etc). I was a lowly sophomore at the time, so I basically got what was left over.

Before I could register I could see most classes I wanted to take had plenty of availability except for one which was almost full. That class would make my schedule perfect (no classes before 10am, everything ending before 4PM, good teachers), so I was ready the moment my group got access. I logged into the janky Java applet and saw that my desired class was full. Dismayed, but not giving up, I refreshed the class list to see if someone might drop during the drop-add week. Nope, still full, but there was still time for someone to change their mind and for me to slip in. I was going to need an edge.

Another peculiarity of this system was that it was definitely a weird Java app based on some type of main frame. It must have been around for a decade at least. One of the signs of its age was that you had a limited amount of time per day during which you could be logged into the system, something like 90 minutes a day.

So I did what any good hacker would: I made _really_ good use of that limited time. I wrote an AutoHotkey script which would automatically log in, traverse all the menus and attempt to sign me up for that class. It was much faster than a human, so each run barely put a dent in my logged-in time allotment. As a cherry on top, I wired it up to a python script to push notify me if it succeeded.

After letting it run for two days, some false alarms, and tweaking, I got a delightful "You're registered!" notification on my phone and found that it had successfully gotten me the class I wanted. I'm still chasing that high to this day.

throwaway78678 · 3 years ago
It reminds me of my time as an undergrad in a quantum chemistry lab. I had something like 150 calculations to run (about 4h each) and therefore could only submit them to the "small" calculation queue (for jobs less than a day).

The problem was that it was essentially always used at the maximum because most people had such small jobs to run + other queues were not as efficient. Because of the inner "fighting", the HPC admin essentially blocked the possibility to have jobs pending. So first come first serve.

So basically I've set up a cron job to look prepare my jobs and look for empty slots during the night. I remember looking at results in the morning while sipping on coffee and the head of the lab congratulating me for my "dedication" as she saw I submitted jobs at 3AM!! :)

At the end of the internship, I basically had a script "assistant" that I would use to prepare the calculation jobs, unite them so I could use them on "bigger" queues, do most of the post-calculation analysis (essentially producing CSVs and graph for me).

And I am too, chasing that high to this day.

hattmall · 3 years ago
I wrote something similar, I called it "Class Catcher" it was a VB program with the Web browser Control. I paired it with Pick-a-prof to get the best classes. I even sold a few copies via Facebook Ads.
mo_42 · 3 years ago
I use the following tiny script to make PDFs look like they have been scanned. There are still entities that require you to physically sign a document and scan it. So far, everyone accepted PDFs like these:

  #!/bin/sh
  ROTATION=$(shuf -n 1 -e '-' '')$(shuf -n 1 -e $(seq 0.05 .5))
  convert -density 150 $1 \
    -linear-stretch '1.5%x2%' \
    -rotate ${ROTATION} \
    -attenuate '0.01' \
    +noise  Multiplicative \
    -colorspace 'gray' $2

spaboleo · 3 years ago
This is awesome! It would be perfect if there an occasional artefact line crossing the entire page vertically could be added. You know, those lines caused by an old crusty ink jet print head. Also a visibly cast shadow by the allegedly scanned edge of the paper due to misalignment on the flat bed would add to the illusion.
lloydatkinson · 3 years ago
Do you have a before and after of a sample pdf? Sounds great.

How do you use it? I don't see any PDF file paths?

mo_42 · 3 years ago
The first argument is the input file and the second one the output:

  ./script.sh original.pdf scanned.pdf

kilroy123 · 3 years ago
So awesome! Just tried and it worked great.
melagonster · 3 years ago
this surprise me, I don't know pdf can work on this way haha.
zamadatix · 3 years ago
I don't have the script anymore but when I was an intern at a regional hospital system ~10 years ago they were running into problems with an old wireless system where after a certain global client count and AP uptime APs would stop registering clients or roams. At the start of the day everything was fine, by night some random wireless tickets were coming in, and by next morning everything was on fire and thousands of APs worth of Wi-Fi was useless. The wireless lead was sweating bullets trying to get the vendor to figure out what was wrong but the product was nearing the end of its life plus having transitioned between companies in its lifespan so support wasn't great. As a stopgap he'd stay late and reboot all of the APs from the controller at night. It'd take about 30 minutes for everything to process and the doctors/nurses would still raise hell but a scheduled blip at night was better than everything being broken in the morning.

We had great AP density so by the 2nd night I started working on an Expect script that would log in and boot 1 AP at a time per floor-building combo (multiple areas simultaneously), wait for them to come back, wait about 30 seconds, and move to the next AP on each floor. At first I did a dry run where the reboot was commented out and the "is it back yet" was delayed by a short timer to simulate a reboot delay + make sure the script would really run without a login timeout or something stupid. This would take a couple hours but it was better than taking everything down as clients under the specific AP being cycled would just roam and have a weaker signal for a minute (assuming the system had been booted the night before). We ran it the 3rd night in place of the mass reboot and watched it carefully. It went great so we left it to run every night. We had the nightly notice from an outage to a potential outage and stopped getting complaints because, except for a particularly unlucky laptop in a corner for 1 minute, nothing was really out of the ordinary. At this point we knew we were buying a brand new wireless system that fiscal year (already in the budget) so we ended up just riding the year out with this script.

In all it was a lame reboot script shorter than the table containing the lists of APs to boot 1 by 1 but it probably had more real impact than any fancier scripts/tools I made while I was there.

noisy_boy · 3 years ago
I love stories like this that directly result in quality of life improvment.