Python-File-Tools 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- python_file_tools/__init__.py +3 -0
- python_file_tools/file_tools.py +456 -0
- python_file_tools/sort.py +180 -0
- python_file_tools/test/__init__.py +9 -0
- python_file_tools/test/test_file_tools.py +517 -0
- python_file_tools/test/test_sort.py +172 -0
- python_file_tools-0.1.0.dist-info/METADATA +100 -0
- python_file_tools-0.1.0.dist-info/RECORD +11 -0
- python_file_tools-0.1.0.dist-info/WHEEL +5 -0
- python_file_tools-0.1.0.dist-info/licenses/LICENSE +674 -0
- python_file_tools-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
import python_file_tools.sort as pft_sort
|
|
4
|
+
from os.path import abspath
|
|
5
|
+
|
|
6
|
+
def test_get_first_section():
|
|
7
|
+
"""
|
|
8
|
+
Tests the get_first_section function.
|
|
9
|
+
"""
|
|
10
|
+
# Test getting number sections
|
|
11
|
+
assert pft_sort.get_first_section("12") == "12"
|
|
12
|
+
assert pft_sort.get_first_section("123 Thing!") == "123"
|
|
13
|
+
assert pft_sort.get_first_section("1.25Words") == "1.25"
|
|
14
|
+
assert pft_sort.get_first_section("1,000 Next") == "1,000"
|
|
15
|
+
assert pft_sort.get_first_section("1,523.26!Numbers") == "1,523.26"
|
|
16
|
+
# Test getting non-number sections
|
|
17
|
+
assert pft_sort.get_first_section("Just text.") == "Just text."
|
|
18
|
+
assert pft_sort.get_first_section("Text, then Numbers.137") == "Text, then Numbers."
|
|
19
|
+
# Test getting section from string that has none
|
|
20
|
+
assert pft_sort.get_first_section("") == ""
|
|
21
|
+
|
|
22
|
+
def test_compare_sections():
|
|
23
|
+
"""
|
|
24
|
+
Tests the compare_sections function.
|
|
25
|
+
"""
|
|
26
|
+
# Test comparing just numbers
|
|
27
|
+
assert pft_sort.compare_sections("25", "0025") == 0
|
|
28
|
+
assert pft_sort.compare_sections("1,000", "1000") == 0
|
|
29
|
+
assert pft_sort.compare_sections("2", "2.000") == 0
|
|
30
|
+
assert pft_sort.compare_sections("2", "3") == -1
|
|
31
|
+
assert pft_sort.compare_sections("54", "023") == 1
|
|
32
|
+
assert pft_sort.compare_sections("1,200", "1250") == -1
|
|
33
|
+
assert pft_sort.compare_sections("3,500", "3,000") == 1
|
|
34
|
+
assert pft_sort.compare_sections("0105.3", "105.38") == -1
|
|
35
|
+
assert pft_sort.compare_sections("1.5", "1.25") == 1
|
|
36
|
+
assert pft_sort.compare_sections("1", "1.5") == -1
|
|
37
|
+
# Test comparing just text
|
|
38
|
+
assert pft_sort.compare_sections("text", "text") == 0
|
|
39
|
+
assert pft_sort.compare_sections("abc", "def") == -1
|
|
40
|
+
assert pft_sort.compare_sections("test", "blah") == 1
|
|
41
|
+
assert pft_sort.compare_sections("un", "unfinished") == -1
|
|
42
|
+
assert pft_sort.compare_sections("ending", "end") == 1
|
|
43
|
+
# Test comparing text and numbers
|
|
44
|
+
assert pft_sort.compare_sections("43", "text") == -1
|
|
45
|
+
assert pft_sort.compare_sections("other", "5.8") == 1
|
|
46
|
+
# Test with missing sections
|
|
47
|
+
assert pft_sort.compare_sections("", "540") == -1
|
|
48
|
+
assert pft_sort.compare_sections("0", "") == 1
|
|
49
|
+
assert pft_sort.compare_sections("", "word") == -1
|
|
50
|
+
assert pft_sort.compare_sections("other", "")
|
|
51
|
+
|
|
52
|
+
def test_compare_alphanum():
|
|
53
|
+
"""
|
|
54
|
+
Tests the compare_alphanum function.
|
|
55
|
+
"""
|
|
56
|
+
# Test identical strings
|
|
57
|
+
assert pft_sort.compare_alphanum("", "") == 0
|
|
58
|
+
assert pft_sort.compare_alphanum("23 test", "23 test") == 0
|
|
59
|
+
# Test comparing by number
|
|
60
|
+
assert pft_sort.compare_alphanum("Test 4", " test 10") == -1
|
|
61
|
+
assert pft_sort.compare_alphanum(" Thing 34.5 more", "Thing 5") == 1
|
|
62
|
+
assert pft_sort.compare_alphanum("14 Name 1", "14 name 3") == -1
|
|
63
|
+
assert pft_sort.compare_alphanum("024 thing next 5", "24 thing next 2") == 1
|
|
64
|
+
# Test comparing by text
|
|
65
|
+
assert pft_sort.compare_alphanum("45 abc", "45 Test") == -1
|
|
66
|
+
assert pft_sort.compare_alphanum("987 banana", "0987 AAA") == 1
|
|
67
|
+
assert pft_sort.compare_alphanum("5 Thing 65 next", "5 thing 65.0 other") == -1
|
|
68
|
+
assert pft_sort.compare_alphanum("5.8 next 4 zzz", " 5.80 next 4 aaa") == 1
|
|
69
|
+
assert pft_sort.compare_alphanum("12 thing", "12 thing next") == -1
|
|
70
|
+
assert pft_sort.compare_alphanum("50 other next", "050 Other") == 1
|
|
71
|
+
# Test comparing that with identical sections
|
|
72
|
+
assert pft_sort.compare_alphanum("AAA", "aaa") == -1
|
|
73
|
+
assert pft_sort.compare_alphanum("1.0", "1") == 1
|
|
74
|
+
|
|
75
|
+
def test_sort_alphanum():
|
|
76
|
+
"""
|
|
77
|
+
Tests the sort_alphanum function.
|
|
78
|
+
"""
|
|
79
|
+
lst = ["test 10", "test 1", "test 003", "3.5", "06 Next", "middle"]
|
|
80
|
+
sort = pft_sort.sort_alphanum(lst)
|
|
81
|
+
assert sort == ["3.5", "06 Next", "middle", "test 1", "test 003", "test 10"]
|
|
82
|
+
|
|
83
|
+
def test_get_value_from_dictionary():
|
|
84
|
+
"""
|
|
85
|
+
Tests the get_value_from_dictionary function.
|
|
86
|
+
"""
|
|
87
|
+
# Test getting a basic value
|
|
88
|
+
dictionary = {"name":"thing", "other":"name"}
|
|
89
|
+
assert pft_sort.get_value_from_dictionary(dictionary, ["name"]) == "thing"
|
|
90
|
+
assert pft_sort.get_value_from_dictionary(dictionary, ["other"]) == "name"
|
|
91
|
+
# Test getting a deeply nested value
|
|
92
|
+
dictionary = {"thing":{"a":123, "b":456}, "even":{"deeper":{"a":"abc"}}}
|
|
93
|
+
assert pft_sort.get_value_from_dictionary(dictionary, ["thing","a"]) == 123
|
|
94
|
+
assert pft_sort.get_value_from_dictionary(dictionary, ["thing","b"]) == 456
|
|
95
|
+
assert pft_sort.get_value_from_dictionary(dictionary, ["even","deeper","a"]) == "abc"
|
|
96
|
+
# Test getting an array value
|
|
97
|
+
dictionary = {"thing":["a","b","c","d"], "other":{"list":[10,20,30]}}
|
|
98
|
+
assert pft_sort.get_value_from_dictionary(dictionary, ["thing",1]) == "b"
|
|
99
|
+
assert pft_sort.get_value_from_dictionary(dictionary, ["other","list",1]) == 20
|
|
100
|
+
# Test getting a mix of array and key values
|
|
101
|
+
dictionary = {"a":[{"name":"title"}, {"name":"other"}]}
|
|
102
|
+
assert pft_sort.get_value_from_dictionary(dictionary, ["a",0,"name"]) == "title"
|
|
103
|
+
assert pft_sort.get_value_from_dictionary(dictionary, ["a",1,"name"]) == "other"
|
|
104
|
+
# Test getting an invalid key
|
|
105
|
+
assert pft_sort.get_value_from_dictionary(dictionary, [1]) is None
|
|
106
|
+
assert pft_sort.get_value_from_dictionary(dictionary, ["item"]) is None
|
|
107
|
+
assert pft_sort.get_value_from_dictionary(["thing"], [2]) is None
|
|
108
|
+
assert pft_sort.get_value_from_dictionary(["thing"], ["item"]) is None
|
|
109
|
+
assert pft_sort.get_value_from_dictionary(dictionary, ["a",5]) is None
|
|
110
|
+
assert pft_sort.get_value_from_dictionary(dictionary, ["a","thing"]) is None
|
|
111
|
+
|
|
112
|
+
def test_compare_dictionaries_alphanum():
|
|
113
|
+
"""
|
|
114
|
+
Tests the compare_dictionaries_alphanum function.
|
|
115
|
+
"""
|
|
116
|
+
# Test comparing dictionaries one key deep
|
|
117
|
+
dict1 = {"dvk_alpha_sort_key":"name", "name":"", "other":"blah"}
|
|
118
|
+
dict2 = {"dvk_alpha_sort_key":"name", "name":"", "other":"thing"}
|
|
119
|
+
assert pft_sort.compare_dictionaries_alphanum(dict1, dict2) == 0
|
|
120
|
+
dict1 = {"dvk_alpha_sort_key":"name", "name":"001", "other":"blah"}
|
|
121
|
+
dict2 = {"dvk_alpha_sort_key":"name", "name":"2", "other":"thing"}
|
|
122
|
+
assert pft_sort.compare_dictionaries_alphanum(dict1, dict2) == -1
|
|
123
|
+
dict1 = {"dvk_alpha_sort_key":"other", "name":"001", "other":"Part 23.5"}
|
|
124
|
+
dict2 = {"dvk_alpha_sort_key":"other", "name":"2", "other":"Part 23"}
|
|
125
|
+
assert pft_sort.compare_dictionaries_alphanum(dict1, dict2) == 1
|
|
126
|
+
# Test comparing dictionaries multiple keys deep
|
|
127
|
+
dict1 = {"dvk_alpha_sort_key":["name","thing"], "name":{"thing":"0"}, "other":"blah"}
|
|
128
|
+
dict2 = {"dvk_alpha_sort_key":["name","thing"], "name":{"thing":"0"}, "other":"new"}
|
|
129
|
+
assert pft_sort.compare_dictionaries_alphanum(dict1, dict2) == 0
|
|
130
|
+
dict1 = {"dvk_alpha_sort_key":["name","thing"], "name":{"thing":"A"}, "other":"blah"}
|
|
131
|
+
dict2 = {"dvk_alpha_sort_key":["name","thing"], "name":{"thing":"B"}, "other":"new"}
|
|
132
|
+
assert pft_sort.compare_dictionaries_alphanum(dict1, dict2) == -1
|
|
133
|
+
dict1 = {"dvk_alpha_sort_key":["name","thing","a"], "name":{"thing":{"a":"thing"}}, "other":"blah"}
|
|
134
|
+
dict2 = {"dvk_alpha_sort_key":["name","thing","a"], "name":{"thing":{"a":"other"}}, "other":"new"}
|
|
135
|
+
assert pft_sort.compare_dictionaries_alphanum(dict1, dict2) == 1
|
|
136
|
+
# Test comparing dictionaries with keys referencing a given array value
|
|
137
|
+
dict1 = {"dvk_alpha_sort_key":["list",2], "list":["1","2","c","3"]}
|
|
138
|
+
dict2 = {"dvk_alpha_sort_key":["list",2], "list":["a","b","c","d"]}
|
|
139
|
+
assert pft_sort.compare_dictionaries_alphanum(dict1, dict2) == 0
|
|
140
|
+
dict1 = {"dvk_alpha_sort_key":["list",0], "list":["1","2","c","3"]}
|
|
141
|
+
dict2 = {"dvk_alpha_sort_key":["list",0], "list":["a","b","c","d"]}
|
|
142
|
+
assert pft_sort.compare_dictionaries_alphanum(dict1, dict2) == -1
|
|
143
|
+
dict1 = {"dvk_alpha_sort_key":["list",3], "list":["1","2","c","Other"]}
|
|
144
|
+
dict2 = {"dvk_alpha_sort_key":["list",3], "list":["a","b","c","25"]}
|
|
145
|
+
assert pft_sort.compare_dictionaries_alphanum(dict1, dict2) == 1
|
|
146
|
+
|
|
147
|
+
def test_sort_dictionaries_alphanum():
|
|
148
|
+
"""
|
|
149
|
+
Tests the sort_dictionaries_alphanum function.
|
|
150
|
+
"""
|
|
151
|
+
dictionaries = []
|
|
152
|
+
dictionaries.append({"name":"Title 1", "other":{"a":"123", "b":"245"}})
|
|
153
|
+
dictionaries.append({"name":"Title 10", "other":{"a":"523", "b":"Thing"}})
|
|
154
|
+
dictionaries.append({"name":"Name", "other":{"a":"a", "b":"b"}})
|
|
155
|
+
dictionaries.append({"name":"ZZZ", "other":{"a":"name", "b":"title"}})
|
|
156
|
+
dictionaries.append({"name":"AAA", "other":{"a":"123.5", "b":"Blah"}})
|
|
157
|
+
# Test sorting by a standard value
|
|
158
|
+
dictionaries = pft_sort.sort_dictionaries_alphanum(dictionaries, "name")
|
|
159
|
+
assert len(dictionaries) == 5
|
|
160
|
+
assert dictionaries[0] == {"name":"AAA", "other":{"a":"123.5", "b":"Blah"}}
|
|
161
|
+
assert dictionaries[1] == {"name":"Name", "other":{"a":"a", "b":"b"}}
|
|
162
|
+
assert dictionaries[2] == {"name":"Title 1", "other":{"a":"123", "b":"245"}}
|
|
163
|
+
assert dictionaries[3] == {"name":"Title 10", "other":{"a":"523", "b":"Thing"}}
|
|
164
|
+
assert dictionaries[4] == {"name":"ZZZ", "other":{"a":"name", "b":"title"}}
|
|
165
|
+
# Test sorting by a deeper value
|
|
166
|
+
dictionaries = pft_sort.sort_dictionaries_alphanum(dictionaries, ["other","a"])
|
|
167
|
+
assert len(dictionaries) == 5
|
|
168
|
+
assert dictionaries[0] == {"name":"Title 1", "other":{"a":"123", "b":"245"}}
|
|
169
|
+
assert dictionaries[1] == {"name":"AAA", "other":{"a":"123.5", "b":"Blah"}}
|
|
170
|
+
assert dictionaries[2] == {"name":"Title 10", "other":{"a":"523", "b":"Thing"}}
|
|
171
|
+
assert dictionaries[3] == {"name":"Name", "other":{"a":"a", "b":"b"}}
|
|
172
|
+
assert dictionaries[4] == {"name":"ZZZ", "other":{"a":"name", "b":"title"}}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: Python-File-Tools
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Some basic tools that makes some basic file operations easier in Python.
|
|
5
|
+
Home-page: https://github.com/Drakovek/Python-File-Tools
|
|
6
|
+
Author: Drakovek
|
|
7
|
+
Author-email: DrakovekMail@gmail.com
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.0
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Dynamic: author
|
|
15
|
+
Dynamic: author-email
|
|
16
|
+
Dynamic: classifier
|
|
17
|
+
Dynamic: description
|
|
18
|
+
Dynamic: description-content-type
|
|
19
|
+
Dynamic: home-page
|
|
20
|
+
Dynamic: license-file
|
|
21
|
+
Dynamic: requires-python
|
|
22
|
+
Dynamic: summary
|
|
23
|
+
|
|
24
|
+
# Python-File-Tools
|
|
25
|
+
|
|
26
|
+
Python-File-Tools is a collection of simple functions for creating and manipulating files. This was all originally written form my [MetadataMagic](https://github.com/Drakovek/MetadataMagic/blob/master/README.md) project to make working with certain file archiving and creation easier, but decided to spin it off into its own thing, since I wound up finding the tools useful in other projects
|
|
27
|
+
|
|
28
|
+
These are all for using as library functions for other python projects. There are no command line utilities. I'll list the functions here, but for further details you can check the code itself. I've documented the functions and their parameters pretty well in the comments there, so I feel that should do for the time being.
|
|
29
|
+
|
|
30
|
+
# MAIN FUNCTIONS
|
|
31
|
+
|
|
32
|
+
Main file tool functions within the file_tools.py file.
|
|
33
|
+
|
|
34
|
+
## write_text_file
|
|
35
|
+
|
|
36
|
+
Writes a given piece of text to a text file in UTF-8 encoding.
|
|
37
|
+
|
|
38
|
+
## read_text_file
|
|
39
|
+
|
|
40
|
+
Returns the contents of a given text file as a string, with wide support for different text file encoding schemes.
|
|
41
|
+
|
|
42
|
+
## write_json_file
|
|
43
|
+
|
|
44
|
+
Writes a given dictionary as a .json file using UTF-8 encoding.
|
|
45
|
+
|
|
46
|
+
## read_json_file
|
|
47
|
+
|
|
48
|
+
Returns the contents of a given .json file as a python dictionary, with support for different text encoding schemes.
|
|
49
|
+
|
|
50
|
+
## find_all_files
|
|
51
|
+
|
|
52
|
+
Returns a list of absolute file paths for all the files in a directory, with or without subdirectories
|
|
53
|
+
|
|
54
|
+
## find_files_of_type
|
|
55
|
+
|
|
56
|
+
Returns a list of absolute file paths for all files in a directory that use a specific file extension or extensions.
|
|
57
|
+
|
|
58
|
+
## directory_contains
|
|
59
|
+
|
|
60
|
+
Returns whether a directory contains any files with a given file extension or extensions
|
|
61
|
+
|
|
62
|
+
## create_zip
|
|
63
|
+
|
|
64
|
+
Archives the contents of a directory into a zip file, adding a mimetype if desired.
|
|
65
|
+
|
|
66
|
+
## extract_zip
|
|
67
|
+
|
|
68
|
+
Extracts the contents of a .zip file into a directory, with many options for how to structure the extracted files and what files to not include.
|
|
69
|
+
|
|
70
|
+
## extract_file_from_zip
|
|
71
|
+
|
|
72
|
+
Extracts a single specific file from a .zip file
|
|
73
|
+
|
|
74
|
+
## get_file_friendly_text
|
|
75
|
+
|
|
76
|
+
Takes a given string and returns a text string that is allowed to be used as a filename across all major OSes and file systems, with option for pure ASCII text
|
|
77
|
+
|
|
78
|
+
## get_available_filename
|
|
79
|
+
|
|
80
|
+
Returns a valid filename for a directory given a desired filename, altering the name if a file with that name already exists
|
|
81
|
+
|
|
82
|
+
## rename_file
|
|
83
|
+
|
|
84
|
+
Renames a file to a given filename, taking care that the filename is valid and doesn't already exist.
|
|
85
|
+
|
|
86
|
+
# SORT FUNCTIONS
|
|
87
|
+
|
|
88
|
+
Sorting functions within the sort.py file. Mostly to do with "smart alphanumeric sorting" which is my quick way of saying sorting alphanumerically the way a human might, without getting confused by extra whitespace, capitalization, leading zeros, or other basic formatting. So "File 10" always comes after "File 2" and "b" comes after "A" unlike with basic alphabetic sorting.
|
|
89
|
+
|
|
90
|
+
## compare_alphanum
|
|
91
|
+
|
|
92
|
+
Compares two strings using smart alphanumeric comparison.
|
|
93
|
+
|
|
94
|
+
## sort_alphanum
|
|
95
|
+
|
|
96
|
+
Sorts a list of strings using smart alphanumeric sorting.
|
|
97
|
+
|
|
98
|
+
## sort_dictionaries_alphanum
|
|
99
|
+
|
|
100
|
+
Sorts a list of python dictionaries based on the contents of a given key using smart alphanumeric sorting.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
python_file_tools/__init__.py,sha256=465UF2d7w-z_W3_H95Lj5ZjpMYzo-w3g7BSCFaC_C80,67
|
|
2
|
+
python_file_tools/file_tools.py,sha256=J0LDyM0vPRTcca7A31MsA6GhkUm7Sbv8765PeOVq6bw,19748
|
|
3
|
+
python_file_tools/sort.py,sha256=DkNiGKHO1WfrSo1pB-gzhs1wboISPbXVL5SbehDt_0A,6354
|
|
4
|
+
python_file_tools/test/__init__.py,sha256=v3HSLt-xqpmjSSp59mki82hVbOHQa1Cdc7PgwSkzm_Y,365
|
|
5
|
+
python_file_tools/test/test_file_tools.py,sha256=MOllJPQR6D9rx9Ye7b21MRmoeyQG15qtI0W1C-obH_g,29455
|
|
6
|
+
python_file_tools/test/test_sort.py,sha256=WQ2sUya9zSefP5LzR5P9ZZDPsgg721HrCai5VDP2UBA,9400
|
|
7
|
+
python_file_tools-0.1.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
8
|
+
python_file_tools-0.1.0.dist-info/METADATA,sha256=Zw7f0KKQNYTeGz8RCn7jGgvKiv2N3SED0jc1MC-a5_0,3831
|
|
9
|
+
python_file_tools-0.1.0.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
|
|
10
|
+
python_file_tools-0.1.0.dist-info/top_level.txt,sha256=oVf8cuyNnQMvURzTbdg1kzYTyXdt4f7jVv93YsBkkI0,18
|
|
11
|
+
python_file_tools-0.1.0.dist-info/RECORD,,
|