예제 #1
0
def _get_config(archive: tarfile.TarFile) -> Tuple[Dict, Dict, File]:
    """
    Extracts Docker image archive manifest and configuration.
    Returns a tuple with:
    - the deserialized manifest,
    - the deserialized configuration,
    - the configuration File object to scan.
    """
    manifest_file = archive.extractfile("manifest.json")
    if manifest_file is None:
        raise InvalidDockerArchiveException("No manifest file found.")

    manifest = json.load(manifest_file)[0]

    config_file_path = manifest.get("Config")

    config_file_info = archive.getmember(config_file_path)
    if config_file_info is None:
        raise InvalidDockerArchiveException("No config file found.")

    config_file = archive.extractfile(config_file_info)
    if config_file is None:
        raise InvalidDockerArchiveException(
            "Config file could not be extracted.")

    config_file_content = config_file.read().decode()

    return (
        manifest,
        json.loads(config_file_content),
        File(config_file_content, filename="Dockerfile or build-args"),
    )
예제 #2
0
def _extract_files_by_provided_names_tar(t_file: tarfile.TarFile,
                                         names: List[str],
                                         output_path: str) -> None:
    # TODO: write description
    for name in names:
        member = t_file.getmember(name)
        extracting_path = output_path
        t_file.extract(member, path=extracting_path)
예제 #3
0
def song_info(tar: tarfile.TarFile, path: str):
    content = tar.extractfile(path)
    parsed = parse(content.read())
    if parsed is None:
        return None
    artist = parsed.get('ARTIST')
    transcriber = parsed.get('CREATOR')
    genre = parsed.get('GENRE', 'Pony')
    language = parsed.get('LANGUAGE', 'English')
    title = parsed.get('TITLE')
    cover = parsed['COVER']
    song_year = int(parsed.get('YEAR', '0')) or None
    try:
        updated = dateutil.parser.parse(
            parsed['UPDATED'],
            MLKDateParserInfo()) if 'UPDATED' in parsed else None
    except ValueError:
        print(f"Couldn't parse date: {parsed['UPDATED']}")
        updated = None
    mp3_path = os.path.join(os.path.dirname(path), parsed['MP3'])
    try:
        tar.getmember(mp3_path)
    except KeyError:
        return None
    if 'END' in parsed:
        duration = int(parsed['END']) / 1000
    else:
        duration = mutagen.mp3.MP3(tar.extractfile(mp3_path)).info.length
    if 'START' in parsed:
        duration -= float(parsed['START'].replace(',', '.'))
    is_mlk = 'mylittlekaraoke' in parsed.get('COMMENT', '')
    mp3 = parsed['MP3']
    background = parsed.get('BACKGROUND')
    video = parsed.get('VIDEO')
    if 'P1' and 'P2' in parsed:
        parts = [parsed['P1'], parsed['P2']]
    else:
        parts = None

    preview_start = float(parsed['PREVIEWSTART'].replace(
        ',', '.')) if 'PREVIEWSTART' in parsed else None
    return SongInfo(title, artist, genre, song_year, duration, language,
                    transcriber, is_mlk, updated, path, mp3, background, video,
                    preview_start, parts, cover)
예제 #4
0
    def member_is_package(tar: tarfile.TarFile,
                          member: tarfile.TarInfo) -> bool:
        """Checks if the given member of the provided tar object contains a
        __init__.py file.

        Parameters
        ----------
        tar: tarfile.TarFile
            A tar object containing member.
        member: tarfile.TarInfo
            The member of the tar object to verify.

        Returns
        -------
        bool
            Wheter the given member is a package or not.
        """

        try:
            tar.getmember(f"{member.name}/__init__.py")
            return True
        except KeyError:
            return False
예제 #5
0
class ArchiveManager:
    def __init__(self):
        """Summary
        """
        self.archive = None
        self.archive_type = None
        self.listfile = None
        self.listfile_index = 0
        self.archive_path = None
        self.archive_length = 0

        self.hit_next = 0

    def open_zip(self, archive_path):

        if self.archive:
            self.archive.close()

        self.archive_path = archive_path

        filename, file_extension = os.path.splitext(archive_path)

        if file_extension == ".zip" or file_extension == ".cbz":
            self.archive = ZipFile(archive_path, 'r')
            self.archive_type = "zip"
            namelist = self.archive.namelist()
        elif file_extension == ".tar" or file_extension == ".cbt":
            self.archive = TarFile(archive_path, 'r')
            self.archive_type = "tar"
            namelist = self.archive.getnames()
        else:
            raise ("archive not supported")

        # we sort the files by decimal found, excluding directories /
        self.listfile = sorted([x for x in namelist if not x.endswith('/')],
                               key=lambda name: alphanum_key(name))

        self.archive_length = len(self.listfile)
        self.listfile_index = 0

    def delete_current_archive(self):

        if not self.archive or not self.archive_path:
            return

        self.archive.close()

        try:
            os.remove(self.archive_path)
            return True
        except Exception as e:
            print(e)
            return False

    def first_page(self):

        return self.get_file(self.listfile[0])

    def last_page(self):

        self.listfile_index = len(self.listfile) - 1
        return self.get_file(self.listfile[self.listfile_index])

    def get_file(self, name):
        image = BytesIO()
        if self.archive_type == "zip":
            image.write(self.archive.read(name))
        elif self.archive_type == "tar":
            tarinfo = self.archive.getmember(name)
            image_file = self.archive.extractfile(tarinfo)
            image.write(image_file.read())
        else:
            return None

        return image

    def next(self):
        if not self.archive:
            return None

        self.listfile_index = self.listfile_index + 1

        if self.listfile_index >= self.archive_length:
            self.listfile_index = self.archive_length - 1
            return None

        filename = self.listfile[self.listfile_index]
        return self.get_file(filename)

    def previous(self):
        if not self.archive:
            return None

        self.listfile_index = self.listfile_index - 1
        if self.listfile_index < 0:
            self.listfile_index = 0
            return None

        filename = self.listfile[self.listfile_index]
        return self.get_file(filename)

    def get_current_archive_name(self):
        return os.path.basename(self.archive_path)

    def get_display_counter(self):
        return "%i/%i" % (self.listfile_index + 1, self.archive_length)