Skip to content

adds --ignore-newer-than, fix tests #87

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 46 additions & 12 deletions classifier/classifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
"""

import argparse
import arrow
import os
import subprocess
import sys
from pytimeparse import parse as timeparse
from datetime import timedelta

import arrow

VERSION = 'Classifier 2.0'
DIRCONFFILE = '.classifier.conf'
Expand All @@ -34,7 +36,7 @@


def main():
Classifier()
Classifier(sys.argv[1:]).run()


class Classifier:
Expand All @@ -47,7 +49,7 @@ class Classifier:
Documents - https://en.wikipedia.org/wiki/List_of_Microsoft_Office_filename_extensions
"""

def __init__(self):
def __init__(self, args=None):
self.description = "Organize files in your directory instantly,by classifying them into different folders"
self.parser = argparse.ArgumentParser(description=self.description)

Expand All @@ -62,13 +64,13 @@ def __init__(self):

self.parser.add_argument("-rst", "--reset", action='store_true',
help="Reset the default Config file")

"""
self.parser.add_argument("-r", "--recursive", action='store_true',
help="Recursively search your source directory. " +
"WARNING: Ensure you use the correct path as this " +
"WILL move all files from your selected types.")
"""
"""

self.parser.add_argument("-st", "--specific-types", type=str, nargs='+',
help="Move all file extensions, given in the args list, " +
Expand All @@ -89,12 +91,17 @@ def __init__(self):
self.parser.add_argument("-df", "--dateformat", type=str,
help="set the date format using YYYY, MM or DD")

self.args = self.parser.parse_args()
self.parser.add_argument("-n", "--ignore-newer-than", type=str,
help="Ignore files created or modified in less than provided time "
"(i.e. 5m, 32m, 2h32m, 3d2h32m, 1h, 1d, 2w)")

self._ignore_newer_than = None

self.args = self.parser.parse_args(args)
self.dateformat = 'YYYY-MM-DD'
self.formats = {}
self.dirconf = None
self.checkconfig()
self.run()

def create_default_config(self):
with open(CONFIG, "w") as conffile:
Expand All @@ -109,7 +116,7 @@ def create_default_config(self):
"DEBPackages: deb\n" +
"Programs: exe, msi\n" +
"RPMPackages: rpm")
print("CONFIG file created at: "+CONFIG)
print("CONFIG file created at: " + CONFIG)

def checkconfig(self):
""" create a default config if not available """
Expand All @@ -121,14 +128,19 @@ def checkconfig(self):
with open(CONFIG, 'r') as file:
for items in file:
spl = items.replace('\n', '').split(':')
key = spl[0].replace(" ","")
val = spl[1].replace(" ","")
key = spl[0].replace(" ", "")
val = spl[1].replace(" ", "")
self.formats[key] = val
return

def moveto(self, filename, from_folder, to_folder):
from_file = os.path.join(from_folder, filename)

if self._is_file_too_recent(from_file):
return

to_file = os.path.join(to_folder, filename)

# to move only files, not folders
if not to_file == from_file:
print('moved: ' + str(to_file))
Expand Down Expand Up @@ -194,6 +206,21 @@ def _format_arg(self, arg):
arg = self._format_text_arg(arg)
return arg

def _is_file_too_recent(self, from_file):
if self._ignore_newer_than is None:
return False

file_modification_time = arrow.get(os.path.getmtime(from_file))

time_since_modification: timedelta = arrow.utcnow() - file_modification_time

return self._ignore_newer_than > time_since_modification

def _parse_ignore_newer_than(self):
if not self.args.ignore_newer_than:
return
self._ignore_newer_than = timedelta(seconds=timeparse(self.args.ignore_newer_than))

def run(self):
if self.args.version:
# Show version information and quit
Expand All @@ -203,7 +230,7 @@ def run(self):
if self.args.types:
# Show file format information then quit
for key, value in self.formats.items():
print(key + ': '+ value)
print(key + ': ' + value)
return False

if self.args.edittypes:
Expand Down Expand Up @@ -255,6 +282,14 @@ def run(self):
'Dateformat -df must be given alongwith date -dt option')
sys.exit()

if self.args.ignore_newer_than:
try:
self._parse_ignore_newer_than()
except TypeError:
print("Invalid value for ignore-newer-than: " + self.args.ignore_newer_than)
print("Example of valid values: 5m, 32m, 2h32m, 3d2h32m, 1h, 1d, 2w")
return False

if self.args.date:
if self.args.dateformat:
self.classify_by_date(self.args.dateformat, output, directory)
Expand Down Expand Up @@ -287,4 +322,3 @@ def run(self):

print("Done!\n")
return True

27 changes: 14 additions & 13 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
from setuptools import setup

setup(
name="classifier",
version="2.0",
description="Classify the files in your Downloads folder into suitable destinations.",
url="http://github.com/bhrigu123/classifier",
author="Bhrigu Srivastava",
author_email="[email protected]",
license='MIT',
packages=["classifier"],
entry_points="""
name="classifier",
version="2.0",
description="Classify the files in your Downloads folder into suitable destinations.",
url="http://github.com/bhrigu123/classifier",
author="Bhrigu Srivastava",
author_email="[email protected]",
license='MIT',
packages=["classifier"],
entry_points="""
[console_scripts]
classifier = classifier.classifier:main
""",
install_requires=[
'arrow'
],
zip_safe=False
install_requires=[
'arrow',
'pytimeparse'
],
zip_safe=False
)
45 changes: 42 additions & 3 deletions tests/test_classifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import os
import shutil
import unittest
import time
import datetime
import classifier.classifier as clf


Expand All @@ -13,7 +15,7 @@ class ClassifierTest(unittest.TestCase):
__location = os.path.realpath(
os.path.join(os.getcwd(), os.path.dirname(__file__), '.unittest'))

__tmp_files = [u'test_file', u'test_file_中文']
__tmp_files = [u'test_file.mp3', u'test_file_中文.rar']
__tmp_dirs = [u'test_dir', u'test_dir_中文']

def setUp(self):
Expand All @@ -25,6 +27,9 @@ def setUp(self):
for dir_ in self.__tmp_dirs:
if not os.path.exists(dir_):
os.mkdir(dir_)

self.classifier = clf.Classifier()

super(ClassifierTest, self).setUp()

def tearDown(self):
Expand All @@ -34,7 +39,7 @@ def tearDown(self):
def test_moveto(self):
target_dir = os.path.abspath(os.path.join(self.__location, 'moveto'))
for file_ in self.__tmp_files:
clf.self.moveto(file_, self.__location, target_dir)
self.classifier.moveto(file_, self.__location, target_dir)

for file_ in self.__tmp_files:
final_file_path = os.path.join(target_dir, file_)
Expand All @@ -47,12 +52,46 @@ def test_classify_bydate(self):
target_dir = arrow.get(os.path.getctime(file_)).format(date_format)
final_file_path = os.path.join(target_dir, file_)
target_files.append(final_file_path)
clf.self.classify_by_date(date_format, self.__location)
self.classifier.classify_by_date(date_format, self.__location, self.__location)
for file_ in target_files:
self.assertTrue(os.path.exists(file_))
for dir_ in self.__tmp_dirs:
self.assertTrue(os.path.exists(dir_))

def test_ignore_newer_than_should_ignore_new_files(self):
self.classifier = clf.Classifier([
'--ignore-newer-than=10m'
])

self.assertTrue(self.classifier.run())

for file in self.__tmp_files:
file_path = os.path.join(self.__location, file)
self.assertTrue(os.path.exists(file_path))

def test_ignore_newer_than_should_not_ignore_old_files(self):
self.classifier = clf.Classifier([
'--ignore-newer-than=10m'
])

for file_ in self.__tmp_files:
date = datetime.datetime.now() - datetime.timedelta(minutes=11)
mod_time = time.mktime(date.timetuple())
os.utime(os.path.join(self.__location, file_), (mod_time, mod_time))

self.assertTrue(self.classifier.run())

for file in self.__tmp_files:
fp = os.path.join(self.__location, file)
self.assertFalse(os.path.exists(fp))

def test_ignore_newer_than_with_wrong_input(self):
self.classifier = clf.Classifier([
'--ignore-newer-than=wrong_input'
])

self.assertFalse(self.classifier.run())


if __name__ == '__main__':
unittest.main()