Construct an appropriate ZipInfo for a file on the filesystem. filename should be the path to a file or directory on the filesystem. arcname is the name which it will have within the archive (by default, this will be the same as filename, but without a drive letter and with
(cls, filename, arcname=None, *, strict_timestamps=True)
| 618 | |
| 619 | @classmethod |
| 620 | def from_file(cls, filename, arcname=None, *, strict_timestamps=True): |
| 621 | """Construct an appropriate ZipInfo for a file on the filesystem. |
| 622 | |
| 623 | filename should be the path to a file or directory on the filesystem. |
| 624 | |
| 625 | arcname is the name which it will have within the archive (by default, |
| 626 | this will be the same as filename, but without a drive letter and with |
| 627 | leading path separators removed). |
| 628 | """ |
| 629 | if isinstance(filename, os.PathLike): |
| 630 | filename = os.fspath(filename) |
| 631 | st = os.stat(filename) |
| 632 | isdir = stat.S_ISDIR(st.st_mode) |
| 633 | mtime = time.localtime(st.st_mtime) |
| 634 | date_time = mtime[0:6] |
| 635 | if not strict_timestamps and date_time[0] < 1980: |
| 636 | date_time = (1980, 1, 1, 0, 0, 0) |
| 637 | elif not strict_timestamps and date_time[0] > 2107: |
| 638 | date_time = (2107, 12, 31, 23, 59, 59) |
| 639 | # Create ZipInfo instance to store file information |
| 640 | if arcname is None: |
| 641 | arcname = filename |
| 642 | arcname = os.path.normpath(os.path.splitdrive(arcname)[1]) |
| 643 | while arcname[0] in (os.sep, os.altsep): |
| 644 | arcname = arcname[1:] |
| 645 | if isdir: |
| 646 | arcname += '/' |
| 647 | zinfo = cls(arcname, date_time) |
| 648 | zinfo.external_attr = (st.st_mode & 0xFFFF) << 16 # Unix attributes |
| 649 | if isdir: |
| 650 | zinfo.file_size = 0 |
| 651 | zinfo.external_attr |= 0x10 # MS-DOS directory flag |
| 652 | else: |
| 653 | zinfo.file_size = st.st_size |
| 654 | |
| 655 | return zinfo |
| 656 | |
| 657 | def _for_archive(self, archive): |
| 658 | """Resolve suitable defaults from the archive. |