Skip to content

Instantly share code, notes, and snippets.

@5nizza
Last active March 24, 2018 16:49
Show Gist options
  • Save 5nizza/5a35cec7e305baab5eb658ece85aaea1 to your computer and use it in GitHub Desktop.
Save 5nizza/5a35cec7e305baab5eb658ece85aaea1 to your computer and use it in GitHub Desktop.
Sort directories by last modified date of its files
#!/usr/bin/env python3
import argparse
import os
from os.path import join
from datetime import datetime
# https://stackoverflow.com/a/287944/801203
class Colors:
"""
Use it like:
print(Colors.WARNING + "Warning: No active frommets remain. Continue?" + Colors.ENDC)
"""
MAGENTA = '\033[95m'
BLUE = '\033[94m'
GREEN = '\033[92m'
YELLOW = '\033[93m'
RED = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
# https://stackoverflow.com/a/1551394/801203
def _pretty_date(time=False):
"""
Get a datetime object or a int() Epoch timestamp and return a
pretty string like 'an hour ago', 'Yesterday', '3 months ago',
'just now', etc
"""
now = datetime.now()
if type(time) is float:
diff = now - datetime.fromtimestamp(time)
elif isinstance(time,datetime):
diff = now - time
elif not time:
diff = now - now
second_diff = diff.seconds
day_diff = diff.days
if day_diff < 0:
return ''
if day_diff == 0:
if second_diff < 10:
return "just now"
if second_diff < 60:
return str(second_diff) + " seconds ago"
if second_diff < 120:
return "a minute ago"
if second_diff < 3600:
return str(int(second_diff / 60)) + " minutes ago"
if second_diff < 7200:
return "an hour ago"
if second_diff < 86400:
return str(int(second_diff / 3600)) + " hours ago"
if day_diff == 1:
return "Yesterday"
if day_diff < 7:
return str(day_diff) + " days ago"
if day_diff < 31:
return str(int(day_diff / 7)) + " weeks ago"
if day_diff < 365:
return str(int(day_diff / 30)) + " months ago"
return str(int(day_diff / 365)) + " years ago"
def _get_last_time(top_dir:str):
last_date = 0
for root, dirs, files in os.walk(top_dir, followlinks=True):
for file_name in files:
try:
last_date = max(last_date, os.path.getmtime(join(root, file_name)))
except FileNotFoundError:
pass # ignore errors (e.g., dead symbolic links)
return last_date
def do(top_dir:str):
dir_mtime_pairs = None
for root, dirs, files in os.walk(top_dir, followlinks=True, topdown=True):
dir_mtime_pairs = [(d, _get_last_time(join(root, d))) for d in dirs]
break # here only one level recursion
if not dir_mtime_pairs:
exit("No folders found")
dir_mtime_sorted = sorted(dir_mtime_pairs,
key=lambda d_t:d_t[1],
reverse=True)
for d, mtime in dir_mtime_sorted:
print('{:>50} {:>15} {:>14}'.format(Colors.BOLD + Colors.BLUE + d + Colors.ENDC,
_pretty_date(mtime),
datetime.fromtimestamp(mtime).strftime("%b %d, %H:%M")))
exit()
def main():
parser = argparse.ArgumentParser(description='Sort directories by last modified date of its content',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('top', metavar='top', type=str,
help='top directory')
# parser.add_argument('--flag', action='store_true', required=False, default=False,
# help='flag description')
args = parser.parse_args()
do(args.top)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment