octoprint.util.files#
find_collision_free_name(filename, extension, existing_filenames, max_power = 2)
#
Tries to find a collision free translation of "existing_filenames
.
First strips all of ."/\[]:;=,
from the filename and extensions, converts them to lower case and truncates
the extension
to a maximum length of 3 characters.
If the filename is already equal or less than 8 characters in length after that procedure and "existing_files
, that concatenation will be returned as the result.
If not, the following algorithm will be applied to try to find a collision free name::
set counter := power := 1
while counter < 10^max_power:
set truncated := substr(filename, 0, 6 - power + 1) + "~" + counter
set result := "<truncated>.<extension>"
if result is collision free:
return result
counter++
if counter >= 10 ** power:
power++
raise ValueError
This will basically -- for a given original filename of some_filename
and an extension of gco
-- iterate
through names of the format some_f~1.gco
, some_f~2.gco
, ..., some_~10.gco
, some_~11.gco
, ...,
<prefix>~<n>.gco
for n
less than 10 ^ max_power
, returning as soon as one is found that is not colliding.
Parameters:
-
filename
(
string
) –The filename without the extension to convert to 8.3.
-
extension
(
string
) –The extension to convert to 8.3 -- will be truncated to 3 characters if it's longer than that.
-
existing_filenames
(
list
) –A list of existing filenames to prevent name collisions with.
-
max_power
(
int
) –Limits the possible attempts of generating a collision free name to 10 ^
max_power
variations. Defaults to 2, so the name generation will maximally reach<name>~99.<ext>
before aborting and raising an exception.
Returns:
-
string –
A 8.3 representation of the provided original filename, ensured to not collide with the provided
existing_filenames
Raises:
-
ValueError
–No collision free name could be found.
Examples:
>>> find_collision_free_name("test1234", "gco", [])
'test1234.gco'
>>> find_collision_free_name("test1234", "gcode", [])
'test1234.gco'
>>> find_collision_free_name("test12345", "gco", [])
'test12~1.gco'
>>> find_collision_free_name("test 123", "gco", [])
'test_123.gco'
>>> find_collision_free_name("test1234", "g o", [])
'test1234.g_o'
>>> find_collision_free_name("test12345", "gco", ["/test12~1.gco"])
'test12~2.gco'
>>> many_files = ["/test12~{}.gco".format(x) for x in range(10)[1:]]
>>> find_collision_free_name("test12345", "gco", many_files)
'test1~10.gco'
>>> many_more_files = many_files + ["/test1~{}.gco".format(x) for x in range(10, 99)]
>>> find_collision_free_name("test12345", "gco", many_more_files)
'test1~99.gco'
>>> many_more_files_plus_one = many_more_files + ["/test1~99.gco"]
>>> find_collision_free_name("test12345", "gco", many_more_files_plus_one)
Traceback (most recent call last):
...
ValueError: Can't create a collision free filename
>>> find_collision_free_name("test12345", "gco", many_more_files_plus_one, max_power=3)
'test~100.gco'
get_dos_filename(input, existing_filenames = None, extension = None, whitelisted_extensions = None, **kwargs)
#
Converts the provided input filename to a 8.3 DOS compatible filename. If existing_filenames
is provided, the
conversion result will be guaranteed not to collide with any of the filenames provided thus.
Uses :func:find_collision_free_name
internally.
Parameters:
-
input
(
string
) –The original filename incl. extension to convert to the 8.3 format.
-
existing_filenames
(
list
) –A list of existing filenames with which the generated 8.3 name must not collide. Optional.
-
extension
(
string
) –The .3 file extension to use for the generated filename. If not provided, the extension of the provided
filename
will simply be truncated to 3 characters. -
whitelisted_extensions
(
list
) –A list of extensions on
input
that will be left as-is instead of exchanging forextension
. -
kwargs
(
dict
) –Additional keyword arguments to provide to :func:
find_collision_free_name
.
Returns:
-
string –
A 8.3 compatible translation of the original filename, not colliding with the optionally provided
existing_filenames
and with the providedextension
or the original extension shortened to a maximum of 3 characters.
Raises:
-
ValueError
–No 8.3 compatible name could be found that doesn't collide with the provided
existing_filenames
.
Examples:
>>> get_dos_filename("test1234.gco")
'test1234.gco'
>>> get_dos_filename("test1234.gcode")
'test1234.gco'
>>> get_dos_filename("test12345.gco")
'test12~1.gco'
>>> get_dos_filename("Wölfe 🐺.gcode")
'wolfe_~1.gco'
>>> get_dos_filename("💚.gcode")
'green_~1.gco'
>>> get_dos_filename("test1234.fnord", extension="gco")
'test1234.gco'
>>> get_dos_filename("auto0.g", extension="gco")
'auto0.gco'
>>> get_dos_filename("auto0.g", extension="gco", whitelisted_extensions=["g"])
'auto0.g'
>>> get_dos_filename(None)
>>> get_dos_filename("foo")
'foo'
m20_timestamp_to_unix_timestamp(timestamp)
#
Converts "M20 T" timestamp to unix timestamp. Upper 16 bit contain date, lower 16 bit contain time.
https://reprap.org/wiki/G-code#M20:_List_SD_card
Format derived from FAT filesystem timestamps: https://wiki.osdev.org/FAT
Parameters:
-
timestamp
(
string
) –M20 T timestamp as hex string
Returns:
-
int –
Unix timestamp in seconds
sanitize_filename(name, really_universal = False)
#
Sanitizes the provided filename. Implementation differs between Python versions.
Under normal operation, pathvalidate.sanitize_filename
will be used, leaving the
name as intact as possible while still being a legal file name under all operating
systems.
Behaviour can be changed by setting really_universal
to True
. In this case,
the name will be ASCII-fied, using octoprint.util.text.sanitize
with
safe chars -_.()[]
and all spaces replaced by _
. This is the old behaviour.
In all cases, a single leading .
will be removed (as it denotes hidden files
on *nix).
Parameters:
-
name
–
The file name to sanitize. Only the name, no path elements.
-
really_universal
–
If
True
, the old method of sanitization will always be used. Defaults toFalse
.
Returns:
-
–
the sanitized file name
silent_remove(file)
#
Silently removes a file. Does not raise an error if the file doesn't exist.
Parameters:
-
file
(
string
) –The path of the file to be removed
unix_timestamp_to_m20_timestamp(unix_timestamp)
#
Converts unix timestamp to "M20 T" format which embeds date and time into 32bit int. Upper 16 bit contain date, lower 16 bit contain time.
https://reprap.org/wiki/G-code#M20:_List_SD_card
Format derived from FAT filesystem timestamps: https://wiki.osdev.org/FAT
Parameters:
-
unix_timestamp
(
int
) –Unix timestamp in seconds
Returns:
-
string –
M20 T timestamp as hex string