patternpythonMinor
Torrent File Remover
Viewed 0 times
filetorrentremover
Problem
This script to locate torrent files in a given directory, and if they have been seeding for 2 weeks, delete the files.
I realize the comments are overboard. The reason for that is it's being shared with people who don't program.
What should I have done differently?
```
import os # for listdir(), path(), remove(), and getctime()
from time import time, ctime, sleep
import datetime as dt # datetime to compare dates
# Path to torrents
torrents_folder = r'C:\users\user\torrents\folder'
# Torrent files as a list
torrents = os.listdir(torrents_folder)
# Months will be used to swap month prefix and corresponding month number
months = {"Jan": "01", "Feb": "02", "Mar": "03", "Apr": "04", "May": "05", "Jun": "06", "Jul": "07", "Aug": "08",
"Sep": "09", "October": "10", "Nov": "11", "Dec": "12", }
# Set the number of days to elapse from creation date before file is deleted
days_to_wait = dt.timedelta(days=14)
# function to remove torrent
def torrent_remover(month):
# Format the date, casting month to string
start_date = dt.datetime.strptime(str(month), "%m %d %Y")
# Elapsed Time. See line 12
end_date = start_date + days_to_wait
# Today's date for comparison
today = dt.datetime.today()
if end_date <= today:
print("Removing: ", torrent, "\tTorrent expired on", end_date)
# Create full path from the torrent folder and torrent file
torrent_files = os.path.join(torrents_folder, torrent)
# Delete the torrents
os.remove(torrent_files)
else:
print("Nothing to remove")
exit()
# Start the loop
for torrent in torrents:
if torrent.endswith(".torrent"):
# Get date time from each file then join file and folder to create full path
date = ctime(os.path.getctime(os.path.join(torrents_folder, torrent)))
# Remove the timestamp
remove_timestamp = date.replace(date[11:19], "")
# Remove
I realize the comments are overboard. The reason for that is it's being shared with people who don't program.
What should I have done differently?
```
import os # for listdir(), path(), remove(), and getctime()
from time import time, ctime, sleep
import datetime as dt # datetime to compare dates
# Path to torrents
torrents_folder = r'C:\users\user\torrents\folder'
# Torrent files as a list
torrents = os.listdir(torrents_folder)
# Months will be used to swap month prefix and corresponding month number
months = {"Jan": "01", "Feb": "02", "Mar": "03", "Apr": "04", "May": "05", "Jun": "06", "Jul": "07", "Aug": "08",
"Sep": "09", "October": "10", "Nov": "11", "Dec": "12", }
# Set the number of days to elapse from creation date before file is deleted
days_to_wait = dt.timedelta(days=14)
# function to remove torrent
def torrent_remover(month):
# Format the date, casting month to string
start_date = dt.datetime.strptime(str(month), "%m %d %Y")
# Elapsed Time. See line 12
end_date = start_date + days_to_wait
# Today's date for comparison
today = dt.datetime.today()
if end_date <= today:
print("Removing: ", torrent, "\tTorrent expired on", end_date)
# Create full path from the torrent folder and torrent file
torrent_files = os.path.join(torrents_folder, torrent)
# Delete the torrents
os.remove(torrent_files)
else:
print("Nothing to remove")
exit()
# Start the loop
for torrent in torrents:
if torrent.endswith(".torrent"):
# Get date time from each file then join file and folder to create full path
date = ctime(os.path.getctime(os.path.join(torrents_folder, torrent)))
# Remove the timestamp
remove_timestamp = date.replace(date[11:19], "")
# Remove
Solution
You could do with learning some of the more powerful tools in Python, such as
Tracing control flow, instead of
you can do
Then to get the date you can do just
Before I leave this, though, I should warn that your
to remove a slice is error-prone if that slice ever appears elsewhere. Instead try something like
Your
looks strange - of course it will be
Anyway, this can now be avoided entirely since we have a
You run
Instead, add another parameter so you have
Your checks can then just be
Your
Is misnamed (you only remove one file), but now can be just
and your other path looks wrong:
since
I would let
Finally, your printing adds spaces between every part. One way to fix that is
but it seems better to use formatting here:
This all gives
which I hope you'll agree is simpler. To add a check for if any file has been removed, try something like
This is untested.
pathlib.Tracing control flow, instead of
torrents_folder = r'C:\users\user\torrents\folder'
torrents = os.listdir(torrents_folder)
for torrent in torrents:
if torrent.endswith(".torrent"):
...you can do
torrents_folder = Path(r'C:\users\user\torrents\folder')
for torrent_path in torrents_folder.glob("*.torrent"):
...Then to get the date you can do just
datetime.date.fromtimestamp(torrent_path.stat().st_ctime)Before I leave this, though, I should warn that your
text.replace(text[a:b], "")to remove a slice is error-prone if that slice ever appears elsewhere. Instead try something like
text = text[:a] + text[b:]Your
if aftermonth = [month for month in months if month in new_date][0]
if month in new_date:looks strange - of course it will be
True since you've just checked for it.Anyway, this can now be avoided entirely since we have a
date object.You run
torrent_remover(date) (although you call it month in the call signature!), but you also need the torrent_path. It turns out you're passing this as a global! That's bad!Instead, add another parameter so you have
def torrent_remover(path, date):Your checks can then just be
end_date = date + days_to_wait
today = dt.datetime.today()
if end_date <= today:
...
else:
...Your
print("Removing: ", torrent, "\tTorrent expired on", end_date)
torrent_files = os.path.join(torrents_folder, torrent)
os.remove(torrent_files)Is misnamed (you only remove one file), but now can be just
print("Removing: ", torrent_path, "\tTorrent expired on", end_date)
torrent_path.unlink()and your other path looks wrong:
print("Nothing to remove")
exit()since
exit quits the process entirely.days_to_wait is a global constant, so should be uppercase. However, I would put the code in a main function and just pass it to the remover.I would let
torrent_remover get the date itself, simplifying the main loop.Finally, your printing adds spaces between every part. One way to fix that is
print(a, b, c, sep="")but it seems better to use formatting here:
print("{}{}{}".format(a, b, c))This all gives
from datetime import date, timedelta
from pathlib import Path
def torrent_remover(path, shelf_life):
created_on = date.fromtimestamp(torrent_path.stat().st_ctime)
expired_on = created_on + shelf_life
if expired_on <= date.today():
print("Removing: {}\tTorrent expired on {}".format(torrent_path, expired_on))
torrent_path.unlink()
def main():
shelf_life = timedelta(days=14)
torrents_folder = Path(r"C:\users\user\torrents\folder")
for torrent_path in torrents_folder.glob("*.torrent"):
torrent_remover(torrent_path, shelf_life)
if __name__ == '__main__':
main()which I hope you'll agree is simpler. To add a check for if any file has been removed, try something like
from datetime import date, timedelta
from pathlib import Path
def torrent_remover(path, shelf_life):
created_on = date.fromtimestamp(torrent_path.stat().st_ctime)
expired_on = created_on + shelf_life
if expired_on <= date.today():
print("Removing: {}\tTorrent expired on {}".format(torrent_path, expired_on))
torrent_path.unlink()
return True
return False
def main():
shelf_life = timedelta(days=14)
torrent_paths = Path(r"C:\users\user\torrents\folder").glob("*.torrent")
removed = sum(torrent_remover(path, shelf_life) for path in torrent_paths)
if not removed:
print("Nothing to remove")
if __name__ == '__main__':
main()This is untested.
Code Snippets
torrents_folder = r'C:\users\user\torrents\folder'
torrents = os.listdir(torrents_folder)
for torrent in torrents:
if torrent.endswith(".torrent"):
...torrents_folder = Path(r'C:\users\user\torrents\folder')
for torrent_path in torrents_folder.glob("*.torrent"):
...datetime.date.fromtimestamp(torrent_path.stat().st_ctime)text.replace(text[a:b], "")text = text[:a] + text[b:]Context
StackExchange Code Review Q#84917, answer score: 4
Revisions (0)
No revisions yet.