Coverage for pyquickhelper/filehelper/file_info.py: 100%
60 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-03 02:21 +0200
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-03 02:21 +0200
1# -*- coding: utf-8 -*-
2"""
3@file
4@brief Defines class @see cl FileInfo
5"""
6import datetime
7import hashlib
8import re
9import urllib.parse as urlparse
12def convert_st_date_to_datetime(t):
13 """
14 Converts a string into a datetime.
16 @param t str
17 @return datetime
18 """
19 if isinstance(t, str):
20 if "." in t:
21 return datetime.datetime.strptime(t, "%Y-%m-%d %H:%M:%S.%f")
22 return datetime.datetime.strptime( # pragma: no cover
23 t, "%Y-%m-%d %H:%M:%S")
24 return datetime.datetime.fromtimestamp(t)
27def checksum_md5(filename):
28 """
29 Computes MD5 for a file.
31 @param filename filename
32 @return string
33 """
34 fname = filename
35 block_size = 0x10000
36 zero = hashlib.md5()
37 with open(fname, "rb") as fd:
38 block = [fd.read(block_size)]
39 while len(block[-1]) > 0:
40 block.append(fd.read(block_size))
41 for el in block:
42 zero.update(el)
43 return zero.hexdigest()
46_allowed = re.compile("^([a-zA-Z]:)?[^:*?\"<>|]+$")
49def is_file_string(s):
50 """
51 Tells if the string *s* could be a filename.
53 @param s string
54 @return boolean
55 """
56 if len(s) >= 5000:
57 return False # pragma: no cover
58 global _allowed
59 if not _allowed.search(s):
60 return False
61 for c in s:
62 if ord(c) < 32:
63 return False
64 return True
67def is_url_string(s):
68 """
69 Tells if the string s could be a url.
71 @param s string
72 @return boolean
73 """
74 if "\n" in s:
75 return False
76 sch = urlparse.urlparse(s)
77 if len(sch.scheme) > 10:
78 return False # pragma: no cover
79 return sch.scheme.lower() not in ("", None, "warning")
82class FileInfo:
84 """
85 Intermediate class: it represents the data it collects about a file
86 to determine whether or not it was modified.
87 """
89 def __init__(self, filename, size, date, mdate, checksum):
90 """
91 @param filename filename
92 @param size size
93 @param date date (str or datetime)
94 @param mdate modification date (str or datetime)
95 @param checksum to check the file was modified
97 Dates will be converted into datetime.
98 """
99 self.filename = filename
100 self.size = size
101 self.date = date
102 self.mdate = mdate # modification date
103 self.checksum = checksum
104 if date is not None and not isinstance(self.date, datetime.datetime):
105 raise ValueError( # pragma: no cover
106 f"mismatch for date ({str(type(date))}) and file {filename}")
107 if mdate is not None and not isinstance(self.mdate, datetime.datetime):
108 raise ValueError( # pragma: no cover
109 f"mismatch for mdate ({str(type(mdate))}) and file {filename}")
110 if not isinstance(size, int):
111 raise ValueError( # pragma: no cover
112 f"mismatch for size ({str(type(size))}) and file {filename}")
113 if checksum is not None and not isinstance(checksum, str):
114 raise ValueError( # pragma: no cover
115 f"mismatch for checksum ({str(type(checksum))}) and file {filename}")
116 if date is not None and mdate is not None:
117 if mdate > date:
118 raise ValueError( # pragma: no cover
119 "expecting mdate <= date for file " + filename)
121 def __str__(self):
122 """
123 usual
124 """
125 return "File[name=%s, size=%d (%s), mdate=%s (%s), date=%s (%s), md5=%s (%s)]" % \
126 (self.filename,
127 self.size, str(type(self.size)),
128 str(self.mdate), str(type(self.mdate)),
129 str(self.date), str(type(self.date)),
130 self.checksum, str(type(self.checksum)))
132 def set_date(self, date):
133 """
134 set date
136 @param date date (a str or datetime)
137 """
138 self.date = date
139 if not isinstance(self.date, datetime.datetime):
140 raise ValueError( # pragma: no cover
141 f"mismatch for date ({str(type(date))}) and file {self.filename}")
143 def set_mdate(self, mdate):
144 """
145 set mdate
147 @param mdate mdate (a str or datetime)
148 """
149 self.mdate = mdate
150 if not isinstance(self.mdate, datetime.datetime):
151 raise ValueError( # pragma: no cover
152 f"mismatch for date ({str(type(mdate))}) and file {self.filename}")
154 def set_md5(self, checksum):
155 """
156 set md5
158 @param checksum checksum
159 """
160 self.checksum = checksum
161 if not isinstance(checksum, str):
162 raise ValueError( # pragma: no cover
163 "mismatch for checksum (%s) and file %s" % (
164 str(type(checksum)), self.filename))