37 "sep": 9, |
39 "sep": 9, |
38 "oct": 10, |
40 "oct": 10, |
39 "nov": 11, |
41 "nov": 11, |
40 "dec": 12, |
42 "dec": 12, |
41 } |
43 } |
42 |
44 |
43 def __init__(self, parent=None): |
45 def __init__(self, parent=None): |
44 """ |
46 """ |
45 Constructor |
47 Constructor |
46 |
48 |
47 @param parent reference to the parent object (QObject) |
49 @param parent reference to the parent object (QObject) |
48 """ |
50 """ |
49 super().__init__(parent) |
51 super().__init__(parent) |
50 |
52 |
51 self.__parseLine = self.__parseUnixLine |
53 self.__parseLine = self.__parseUnixLine |
52 self.__modeSwitchAllowed = True |
54 self.__modeSwitchAllowed = True |
53 |
55 |
54 def __ignoreLine(self, line): |
56 def __ignoreLine(self, line): |
55 """ |
57 """ |
56 Private method to check, if the line should be ignored. |
58 Private method to check, if the line should be ignored. |
57 |
59 |
58 @param line to check (string) |
60 @param line to check (string) |
59 @return flag indicating to ignore the line (boolean) |
61 @return flag indicating to ignore the line (boolean) |
60 """ |
62 """ |
61 return ( |
63 return line.strip() == "" or line.strip().lower().startswith("total ") |
62 line.strip() == "" or |
64 |
63 line.strip().lower().startswith("total ") |
|
64 ) |
|
65 |
|
66 def __parseUnixMode(self, modeString, urlInfo): |
65 def __parseUnixMode(self, modeString, urlInfo): |
67 """ |
66 """ |
68 Private method to parse a Unix mode string modifying the |
67 Private method to parse a Unix mode string modifying the |
69 given URL info object. |
68 given URL info object. |
70 |
69 |
71 @param modeString mode string to be parsed (string) |
70 @param modeString mode string to be parsed (string) |
72 @param urlInfo reference to the URL info object (EricUrlInfo) |
71 @param urlInfo reference to the URL info object (EricUrlInfo) |
73 @exception FtpDirLineParserError Raised if the mode cannot be parsed. |
72 @exception FtpDirLineParserError Raised if the mode cannot be parsed. |
74 """ |
73 """ |
75 if len(modeString) != 10: |
74 if len(modeString) != 10: |
76 raise FtpDirLineParserError( |
75 raise FtpDirLineParserError("invalid mode string '{0}'".format(modeString)) |
77 "invalid mode string '{0}'".format(modeString)) |
76 |
78 |
|
79 modeString = modeString.lower() |
77 modeString = modeString.lower() |
80 |
78 |
81 permission = 0 |
79 permission = 0 |
82 if modeString[1] != '-': |
80 if modeString[1] != "-": |
83 permission |= EricUrlPermission.READ_OWNER |
81 permission |= EricUrlPermission.READ_OWNER |
84 if modeString[2] != '-': |
82 if modeString[2] != "-": |
85 permission |= EricUrlPermission.WRITE_OWNER |
83 permission |= EricUrlPermission.WRITE_OWNER |
86 if modeString[3] != '-': |
84 if modeString[3] != "-": |
87 permission |= EricUrlPermission.EXE_OWNER |
85 permission |= EricUrlPermission.EXE_OWNER |
88 if modeString[4] != '-': |
86 if modeString[4] != "-": |
89 permission |= EricUrlPermission.READ_GROUP |
87 permission |= EricUrlPermission.READ_GROUP |
90 if modeString[5] != '-': |
88 if modeString[5] != "-": |
91 permission |= EricUrlPermission.WRITE_GROUP |
89 permission |= EricUrlPermission.WRITE_GROUP |
92 if modeString[6] != '-': |
90 if modeString[6] != "-": |
93 permission |= EricUrlPermission.EXE_GROUP |
91 permission |= EricUrlPermission.EXE_GROUP |
94 if modeString[7] != '-': |
92 if modeString[7] != "-": |
95 permission |= EricUrlPermission.READ_OTHER |
93 permission |= EricUrlPermission.READ_OTHER |
96 if modeString[8] != '-': |
94 if modeString[8] != "-": |
97 permission |= EricUrlPermission.WRITE_OTHER |
95 permission |= EricUrlPermission.WRITE_OTHER |
98 if modeString[9] != '-': |
96 if modeString[9] != "-": |
99 permission |= EricUrlPermission.EXE_OTHER |
97 permission |= EricUrlPermission.EXE_OTHER |
100 urlInfo.setPermissions(permission) |
98 urlInfo.setPermissions(permission) |
101 |
99 |
102 if modeString[0] == "d": |
100 if modeString[0] == "d": |
103 urlInfo.setDir(True) |
101 urlInfo.setDir(True) |
104 urlInfo.setFile(False) |
102 urlInfo.setFile(False) |
105 urlInfo.setSymLink(False) |
103 urlInfo.setSymLink(False) |
106 elif modeString[0] == "l": |
104 elif modeString[0] == "l": |
109 urlInfo.setSymLink(True) |
107 urlInfo.setSymLink(True) |
110 elif modeString[0] == "-": |
108 elif modeString[0] == "-": |
111 urlInfo.setDir(False) |
109 urlInfo.setDir(False) |
112 urlInfo.setFile(True) |
110 urlInfo.setFile(True) |
113 urlInfo.setSymLink(False) |
111 urlInfo.setSymLink(False) |
114 |
112 |
115 def __parseUnixTime(self, monthAbbreviation, day, yearOrTime, urlInfo): |
113 def __parseUnixTime(self, monthAbbreviation, day, yearOrTime, urlInfo): |
116 """ |
114 """ |
117 Private method to parse a Unix date and time indication modifying |
115 Private method to parse a Unix date and time indication modifying |
118 the given URL info object. |
116 the given URL info object. |
119 |
117 |
120 |
118 |
121 Date time strings in Unix-style directory listings typically |
119 Date time strings in Unix-style directory listings typically |
122 have one of these formats: |
120 have one of these formats: |
123 <ul> |
121 <ul> |
124 <li>"Nov 23 02:33" (month name, day of month, time)</li> |
122 <li>"Nov 23 02:33" (month name, day of month, time)</li> |
125 <li>"May 26 2005" (month name, day of month, year)</li> |
123 <li>"May 26 2005" (month name, day of month, year)</li> |
126 </ul> |
124 </ul> |
127 |
125 |
128 @param monthAbbreviation abbreviation of the month name (string) |
126 @param monthAbbreviation abbreviation of the month name (string) |
129 @param day day of the month (string) |
127 @param day day of the month (string) |
130 @param yearOrTime string giving the year or a time (string) |
128 @param yearOrTime string giving the year or a time (string) |
131 @param urlInfo reference to the URL info object (EricUrlInfo) |
129 @param urlInfo reference to the URL info object (EricUrlInfo) |
132 @exception FtpDirLineParserError Raised if the month abbreviation is |
130 @exception FtpDirLineParserError Raised if the month abbreviation is |
133 not recognized. |
131 not recognized. |
134 """ |
132 """ |
135 try: |
133 try: |
136 month = FtpDirLineParser.MonthnamesNumbers[ |
134 month = FtpDirLineParser.MonthnamesNumbers[monthAbbreviation.lower()] |
137 monthAbbreviation.lower()] |
|
138 except KeyError: |
135 except KeyError: |
139 raise FtpDirLineParserError( |
136 raise FtpDirLineParserError( |
140 "illegal month abbreviation '{0}'".format( |
137 "illegal month abbreviation '{0}'".format(monthAbbreviation) |
141 monthAbbreviation)) |
138 ) |
142 day = int(day) |
139 day = int(day) |
143 if ':' in yearOrTime: |
140 if ":" in yearOrTime: |
144 year = QDate.currentDate().year() |
141 year = QDate.currentDate().year() |
145 hour, minute = yearOrTime.split(':') |
142 hour, minute = yearOrTime.split(":") |
146 hour = int(hour) |
143 hour = int(hour) |
147 minute = int(minute) |
144 minute = int(minute) |
148 else: |
145 else: |
149 year = int(yearOrTime) |
146 year = int(yearOrTime) |
150 hour = 0 |
147 hour = 0 |
151 minute = 0 |
148 minute = 0 |
152 |
149 |
153 lastModified = QDateTime(QDate(year, month, day), QTime(hour, minute)) |
150 lastModified = QDateTime(QDate(year, month, day), QTime(hour, minute)) |
154 urlInfo.setLastModified(lastModified) |
151 urlInfo.setLastModified(lastModified) |
155 |
152 |
156 def __splitUnixLine(self, line): |
153 def __splitUnixLine(self, line): |
157 """ |
154 """ |
158 Private method to split a line of a Unix like directory listing. |
155 Private method to split a line of a Unix like directory listing. |
159 |
156 |
160 It splits the line into meta data, number of links, user, group, size, |
157 It splits the line into meta data, number of links, user, group, size, |
161 month, day, year or time and name. |
158 month, day, year or time and name. |
162 |
159 |
163 @param line directory line to split (string) |
160 @param line directory line to split (string) |
164 @return tuple of nine strings giving the meta data, |
161 @return tuple of nine strings giving the meta data, |
165 number of links, user, group, size, month, day, year or time |
162 number of links, user, group, size, month, day, year or time |
166 and name |
163 and name |
167 @exception FtpDirLineParserError Raised if the line is not of a |
164 @exception FtpDirLineParserError Raised if the line is not of a |
186 else: |
182 else: |
187 # Day |
183 # Day |
188 lineParts = line.split(None, fieldCountWithoutUserID - 1) |
184 lineParts = line.split(None, fieldCountWithoutUserID - 1) |
189 userFieldIndex = 2 |
185 userFieldIndex = 2 |
190 lineParts.insert(userFieldIndex, "") |
186 lineParts.insert(userFieldIndex, "") |
191 |
187 |
192 return lineParts |
188 return lineParts |
193 |
189 |
194 def __parseUnixLine(self, line): |
190 def __parseUnixLine(self, line): |
195 """ |
191 """ |
196 Private method to parse a Unix style directory listing line. |
192 Private method to parse a Unix style directory listing line. |
197 |
193 |
198 @param line directory line to be parsed (string) |
194 @param line directory line to be parsed (string) |
199 @return URL info object containing the valid data (EricUrlInfo) |
195 @return URL info object containing the valid data (EricUrlInfo) |
200 """ |
196 """ |
201 modeString, nlink, user, group, size, month, day, yearOrTime, name = ( |
197 ( |
202 self.__splitUnixLine(line) |
198 modeString, |
203 ) |
199 nlink, |
204 |
200 user, |
|
201 group, |
|
202 size, |
|
203 month, |
|
204 day, |
|
205 yearOrTime, |
|
206 name, |
|
207 ) = self.__splitUnixLine(line) |
|
208 |
205 if name in [".", ".."]: |
209 if name in [".", ".."]: |
206 return None |
210 return None |
207 |
211 |
208 urlInfo = EricUrlInfo() |
212 urlInfo = EricUrlInfo() |
209 self.__parseUnixMode(modeString, urlInfo) |
213 self.__parseUnixMode(modeString, urlInfo) |
210 self.__parseUnixTime(month, day, yearOrTime, urlInfo) |
214 self.__parseUnixTime(month, day, yearOrTime, urlInfo) |
211 urlInfo.setOwner(user) |
215 urlInfo.setOwner(user) |
212 urlInfo.setGroup(group) |
216 urlInfo.setGroup(group) |
214 name = name.strip() |
218 name = name.strip() |
215 i = name.find(" -> ") |
219 i = name.find(" -> ") |
216 if i >= 0: |
220 if i >= 0: |
217 name = name[:i] |
221 name = name[:i] |
218 urlInfo.setName(name) |
222 urlInfo.setName(name) |
219 |
223 |
220 return urlInfo |
224 return urlInfo |
221 |
225 |
222 def __parseWindowsTime(self, date, time, urlInfo): |
226 def __parseWindowsTime(self, date, time, urlInfo): |
223 """ |
227 """ |
224 Private method to parse a Windows date and time indication modifying |
228 Private method to parse a Windows date and time indication modifying |
225 the given URL info object. |
229 the given URL info object. |
226 |
230 |
227 Date time strings in Windows-style directory listings typically |
231 Date time strings in Windows-style directory listings typically |
228 have the format "10-23-12 03:25PM" (month-day_of_month-two_digit_year, |
232 have the format "10-23-12 03:25PM" (month-day_of_month-two_digit_year, |
229 hour:minute, am/pm). |
233 hour:minute, am/pm). |
230 |
234 |
231 @param date date string (string) |
235 @param date date string (string) |
232 @param time time string (string) |
236 @param time time string (string) |
233 @param urlInfo reference to the URL info object (EricUrlInfo) |
237 @param urlInfo reference to the URL info object (EricUrlInfo) |
234 @exception FtpDirLineParserError Raised if either of the strings is not |
238 @exception FtpDirLineParserError Raised if either of the strings is not |
235 recognized. |
239 recognized. |
236 """ |
240 """ |
237 try: |
241 try: |
238 month, day, year = [int(part) for part in date.split('-')] |
242 month, day, year = [int(part) for part in date.split("-")] |
239 year = 1900 + year if year >= 70 else 2000 + year |
243 year = 1900 + year if year >= 70 else 2000 + year |
240 except (ValueError, IndexError): |
244 except (ValueError, IndexError): |
241 raise FtpDirLineParserError( |
245 raise FtpDirLineParserError("illegal date string '{0}'".format(month)) |
242 "illegal date string '{0}'".format(month)) |
|
243 try: |
246 try: |
244 hour, minute, am_pm = time[0:2], time[3:5], time[5] |
247 hour, minute, am_pm = time[0:2], time[3:5], time[5] |
245 hour = int(hour) |
248 hour = int(hour) |
246 minute = int(minute) |
249 minute = int(minute) |
247 except (ValueError, IndexError): |
250 except (ValueError, IndexError): |
248 raise FtpDirLineParserError( |
251 raise FtpDirLineParserError("illegal time string '{0}'".format(month)) |
249 "illegal time string '{0}'".format(month)) |
252 if hour == 12 and am_pm == "A": |
250 if hour == 12 and am_pm == 'A': |
|
251 hour = 0 |
253 hour = 0 |
252 if hour != 12 and am_pm == 'P': |
254 if hour != 12 and am_pm == "P": |
253 hour += 12 |
255 hour += 12 |
254 |
256 |
255 lastModified = QDateTime(QDate(year, month, day), QTime(hour, minute)) |
257 lastModified = QDateTime(QDate(year, month, day), QTime(hour, minute)) |
256 urlInfo.setLastModified(lastModified) |
258 urlInfo.setLastModified(lastModified) |
257 |
259 |
258 def __parseWindowsLine(self, line): |
260 def __parseWindowsLine(self, line): |
259 """ |
261 """ |
260 Private method to parse a Windows style directory listing line. |
262 Private method to parse a Windows style directory listing line. |
261 |
263 |
262 @param line directory line to be parsed (string) |
264 @param line directory line to be parsed (string) |
263 @return URL info object containing the valid data (EricUrlInfo) |
265 @return URL info object containing the valid data (EricUrlInfo) |
264 @exception FtpDirLineParserError Raised if the line is not of a |
266 @exception FtpDirLineParserError Raised if the line is not of a |
265 recognized Windows format. |
267 recognized Windows format. |
266 """ |
268 """ |
267 try: |
269 try: |
268 date, time, dirOrSize, name = line.split(None, 3) |
270 date, time, dirOrSize, name = line.split(None, 3) |
269 except ValueError: |
271 except ValueError: |
270 # "unpack list of wrong size" |
272 # "unpack list of wrong size" |
271 raise FtpDirLineParserError( |
273 raise FtpDirLineParserError("line '{0}' cannot be parsed".format(line)) |
272 "line '{0}' cannot be parsed".format(line)) |
274 |
273 |
|
274 if name in [".", ".."]: |
275 if name in [".", ".."]: |
275 return None |
276 return None |
276 |
277 |
277 urlInfo = EricUrlInfo() |
278 urlInfo = EricUrlInfo() |
278 self.__parseWindowsTime(date, time, urlInfo) |
279 self.__parseWindowsTime(date, time, urlInfo) |
279 if dirOrSize.lower() == "<dir>": |
280 if dirOrSize.lower() == "<dir>": |
280 urlInfo.setDir(True) |
281 urlInfo.setDir(True) |
281 urlInfo.setFile(False) |
282 urlInfo.setFile(False) |
283 urlInfo.setDir(False) |
284 urlInfo.setDir(False) |
284 urlInfo.setFile(True) |
285 urlInfo.setFile(True) |
285 try: |
286 try: |
286 urlInfo.setSize(int(dirOrSize)) |
287 urlInfo.setSize(int(dirOrSize)) |
287 except ValueError: |
288 except ValueError: |
288 raise FtpDirLineParserError( |
289 raise FtpDirLineParserError("illegal size '{0}'".format(dirOrSize)) |
289 "illegal size '{0}'".format(dirOrSize)) |
|
290 urlInfo.setName(name) |
290 urlInfo.setName(name) |
291 |
291 |
292 ext = os.path.splitext(name.lower())[1] |
292 ext = os.path.splitext(name.lower())[1] |
293 urlInfo.setSymLink(ext == ".lnk") |
293 urlInfo.setSymLink(ext == ".lnk") |
294 |
294 |
295 permissions = ( |
295 permissions = ( |
296 EricUrlPermission.READ_OWNER | EricUrlPermission.WRITE_OWNER | |
296 EricUrlPermission.READ_OWNER |
297 EricUrlPermission.READ_GROUP | EricUrlPermission.WRITE_GROUP | |
297 | EricUrlPermission.WRITE_OWNER |
298 EricUrlPermission.READ_OTHER | EricUrlPermission.WRITE_OTHER |
298 | EricUrlPermission.READ_GROUP |
|
299 | EricUrlPermission.WRITE_GROUP |
|
300 | EricUrlPermission.READ_OTHER |
|
301 | EricUrlPermission.WRITE_OTHER |
299 ) |
302 ) |
300 if ext in [".exe", ".com", ".bat", ".cmd"]: |
303 if ext in [".exe", ".com", ".bat", ".cmd"]: |
301 permissions |= ( |
304 permissions |= ( |
302 EricUrlPermission.EXE_OWNER | |
305 EricUrlPermission.EXE_OWNER |
303 EricUrlPermission.EXE_GROUP | |
306 | EricUrlPermission.EXE_GROUP |
304 EricUrlPermission.EXE_OTHER |
307 | EricUrlPermission.EXE_OTHER |
305 ) |
308 ) |
306 urlInfo.setPermissions(permissions) |
309 urlInfo.setPermissions(permissions) |
307 |
310 |
308 return urlInfo |
311 return urlInfo |
309 |
312 |
310 def parseLine(self, line): |
313 def parseLine(self, line): |
311 """ |
314 """ |
312 Public method to parse a directory listing line. |
315 Public method to parse a directory listing line. |
313 |
316 |
314 This implementation support Unix and Windows style directory |
317 This implementation support Unix and Windows style directory |
315 listings. It tries Unix style first and if that fails switches |
318 listings. It tries Unix style first and if that fails switches |
316 to Windows style. If that fails as well, an exception is raised. |
319 to Windows style. If that fails as well, an exception is raised. |
317 |
320 |
318 @param line directory line to be parsed (string) |
321 @param line directory line to be parsed (string) |
319 @return URL info object containing the valid data (EricUrlInfo) |
322 @return URL info object containing the valid data (EricUrlInfo) |
320 """ |
323 """ |
321 if self.__ignoreLine(line): |
324 if self.__ignoreLine(line): |
322 return None |
325 return None |
323 |
326 |
324 try: |
327 try: |
325 return self.__parseLine(line) |
328 return self.__parseLine(line) |
326 except FtpDirLineParserError: |
329 except FtpDirLineParserError: |
327 if not self.__modeSwitchAllowed: |
330 if not self.__modeSwitchAllowed: |
328 raise |
331 raise |
329 |
332 |
330 self.__parseLine = self.__parseWindowsLine |
333 self.__parseLine = self.__parseWindowsLine |
331 self.__modeSwitchAllowed = False |
334 self.__modeSwitchAllowed = False |
332 return self.__parseLine(line) |
335 return self.__parseLine(line) |