Response to https://gist.github.com/Thomas-0001111111/e40b05c3ed0da41a3d7308b90ef8383f
Test any script that affects a system file using a local copy until it's complete. cd
to your project folder, then in the terminal:
cp /etc/hosts ./
cp /etc/hosts ./hosts_orig
After testing the script, return the local copy to its original state for further testing with:
cp hosts_orig hosts
The default hosts file contains necessary entries. If these have been removed from yours, get them from here: How to Reset Hosts File to Default on Mac and Windows PC
To invoke the script directly, add a crunchbang to the top of the .py file:
#!/usr/bin/env python3
Make the file executable in the terminal:
chmod +x webblocker.py
Now you can run it directly without invoking it through Python:
./webblocker.py
And with sudo
when ready to point it at the real system file.
sudo ./webblocker.py
The hosts file expects domains, not URLs, so "www.bbc.co.uk" instead of "https://www.bbc.co.uk/news".
websitelist = [
'www.bbc.co.uk',
'www.dailymail.co.uk',
'www.facebook.com',
'www.youtube.com',
]
Following DRY (Don't Repeat Yourself) and not re-opening the file in append mode when it's already open in read+, here's how I might organize this:
#!/usr/bin/env python3
import datetime as dt
# hostpath = '/private/etc/hosts' # macOS 11+
# hostpath = '/etc/hosts' # Linux, macOS X
hostpath = 'hosts' # Local testing
domains = [
'www.bbc.co.uk',
'www.dailymail.co.uk',
'www.facebook.com',
'www.youtube.com',
]
def is_blocktime():
start = dt.time(6, 0)
end = dt.time(18, 0)
now = dt.datetime.now().time()
return start <= now < end
with open(hostpath, 'r+') as file:
content = file.read()
if is_blocktime():
# Block
print('Time to focus now, Thomas!')
for domain in domains:
if not domain in content:
content += f'\n127.0.0.1 {domain}'
else:
# Unblock
print('Enjoy your free time, Thomas!')
new_lines = []
for line in content.splitlines():
if not any(domain in line for domain in domains):
new_lines += [line]
content = '\n'.join(new_lines)
# Write
if not content.endswith('\n'):
content += '\n'
file.seek(0)
file.write(content)
file.truncate()
Note that I've changed the import statement so we can access datetime.time. While testing, you can add return True
or return False
as the first line of is_blocktime() to override it, and in the terminal, cat hosts
to see what's going on. Once you're satisfied, comment-out:
hostpath = 'hosts'
and un-comment:
hostpath = '/private/etc/hosts'
Use crontab to make the script automatically run every hour.
sudo crontab -e
Add this line:
0 * * * * /absolute/path/to/webblocker.py
Format:
* * * * * command to execute
│ │ │ │ │
│ │ │ │ └─── day of week (0 - 6) (0 to 6 are Sunday to Saturday, or use names; 7 is Sunday, the same as 0)
│ │ │ └──────── month (1 - 12)
│ │ └───────────── day of month (1 - 31)
│ └────────────────── hour (0 - 23)
└─────────────────────── min (0 - 59)
You can get the absolute path to your working directory by running pwd
(print working directory) in the terminal within your project folder.
Thanks a lot for this and taking the time out to help a stranger. I feel I've learnt more reading this for 10 mins than watching a Youtube video. I'll try this out to see if it works!