def process_ugoira_local(caller, config):
    directory = config.rootDirectory
    counter = 0
    d = ""
    res = None
    counter = 0
    list_done = list()

    try:
        print('')
        for extension in ["ugoira", "zip"]:  # always ugoira then zip
            for zip in pathlib.Path(directory).rglob(f'*.{extension}'):
                zip_name = os.path.splitext(os.path.basename(zip))[0]
                zip_dir = os.path.dirname(zip)
                image_id = zip_name.partition("_")[0]
                if image_id not in list_done:
                    counter += 1
                    PixivHelper.print_and_log(None, f"# Ugoira {counter}")
                    PixivHelper.print_and_log(
                        "info",
                        "Deleting old animated files ...",
                        newline=False)
                    d = PixivHelper.create_temp_dir(prefix="reencoding")

                    # List and move all files related to the image_id
                    for file in os.listdir(zip_dir):
                        if os.path.isfile(os.path.join(
                                zip_dir, file)) and zip_name in file:
                            file_basename = os.path.basename(file)
                            file_ext = os.path.splitext(file_basename)[1]
                            if ((("gif" in file_ext) and (config.createGif)) or
                                (("png" in file_ext) and (config.createApng))
                                    or (("webm" in file_ext) and
                                        (config.createWebm)) or
                                (("webp" in file_ext) and (config.createWebp))
                                    or (("ugoira" in file_ext) and
                                        (config.createUgoira))
                                    or ("zip" in file_ext)):
                                abs_file_path = os.path.abspath(
                                    os.path.join(zip_dir, file))
                                PixivHelper.print_and_log(
                                    "debug", f"Moving {abs_file_path} to {d}")
                                if ("zip" in file_ext) or ("ugoira"
                                                           in file_ext):
                                    shutil.copy2(
                                        abs_file_path,
                                        os.path.join(d, file_basename))
                                else:
                                    shutil.move(abs_file_path,
                                                os.path.join(d, file_basename))
                    PixivHelper.print_and_log(None, " done.")

                    # Process artwork locally
                    if "ugoira" in extension and not config.overwrite:
                        try:
                            msg = Fore.YELLOW + Style.NORMAL + f'Processing Image Id: {image_id}' + Style.RESET_ALL
                            PixivHelper.print_and_log(None, msg)
                            PixivDownloadHandler.handle_ugoira(
                                None, str(zip), config, None)
                            res = PixivConstant.PIXIVUTIL_OK
                        except PixivException as ex:
                            PixivHelper.print_and_log(
                                'error',
                                f'PixivException for Image ID ({image_id}): {ex}'
                            )
                            PixivHelper.print_and_log(
                                'error', f'Stack Trace: {sys.exc_info()}')
                            res = PixivConstant.PIXIVUTIL_NOT_OK
                        except Exception as ex:
                            PixivHelper.print_and_log(
                                'error',
                                f'Exception for Image ID ({image_id}): {ex}')
                            PixivHelper.print_and_log(
                                'error', f'Stack Trace: {sys.exc_info()}')
                            exc_type, exc_value, exc_traceback = sys.exc_info()
                            traceback.print_exception(exc_type, exc_value,
                                                      exc_traceback)
                            res = PixivConstant.PIXIVUTIL_NOT_OK
                        finally:
                            if res == PixivConstant.PIXIVUTIL_NOT_OK:
                                PixivHelper.print_and_log(
                                    'warn',
                                    f'Failed to process Image ID {image_id} locally: will retry with online infos'
                                )
                                PixivHelper.print_and_log(
                                    'debug',
                                    f'Removing corrupted ugoira {zip}')
                                os.remove(zip)

                    # Process artwork with online infos
                    if "zip" in extension or res == PixivConstant.PIXIVUTIL_NOT_OK or (
                            "ugoira" in extension and config.overwrite):
                        res = process_image(caller,
                                            config,
                                            artist=None,
                                            image_id=image_id,
                                            useblacklist=False,
                                            reencoding=True)
                        if res == PixivConstant.PIXIVUTIL_NOT_OK:
                            PixivHelper.print_and_log(
                                "warn",
                                f"Cannot process Image Id: {image_id}, restoring old animated files...",
                                newline=False)
                            for file_name in os.listdir(d):
                                PixivHelper.print_and_log(
                                    "debug",
                                    f"Moving back {os.path.join(d, file_name)} to {os.path.join(zip_dir, file_name)}"
                                )
                                shutil.move(
                                    os.path.join(d, file_name),
                                    os.path.join(zip_dir, file_name)
                                )  # overwrite corrupted file generated
                            PixivHelper.print_and_log(None, " done.")
                            print('')

                    # Checking result
                    list_file_zipdir = os.listdir(zip_dir)
                    for file_name in os.listdir(d):
                        file_ext = os.path.splitext(file_name)[1]
                        if file_name not in list_file_zipdir and config.backupOldFile:
                            if ((config.createUgoira
                                 and not config.deleteUgoira
                                 and "ugoira" in file_ext)
                                    or (not config.deleteZipFile
                                        and "zip" in file_ext)
                                    or (config.createGif and "gif" in file_ext)
                                    or
                                (config.createApng and "png" in file_ext) or
                                (config.createWebm and "webm" in file_ext) or
                                (config.createWebp and "webp" in file_ext)):
                                split_name = file_name.rsplit(".", 1)
                                new_name = file_name + "." + str(
                                    int(time.time()))
                                if len(split_name) == 2:
                                    new_name = split_name[0] + "." + str(
                                        int(time.time())) + "." + split_name[1]
                                PixivHelper.print_and_log(
                                    'warn',
                                    f"Could not found the animated file re-encoded ==> {file_name}, backing up to: {new_name}"
                                )
                                PixivHelper.print_and_log(
                                    'warn',
                                    "The new encoded file may have another name or the artist may have change its name."
                                )
                                PixivHelper.print_and_log(
                                    "debug",
                                    f"Rename and move {os.path.join(d, file_name)} to {os.path.join(zip_dir, new_name)}"
                                )
                                shutil.move(os.path.join(d, file_name),
                                            os.path.join(zip_dir, new_name))
                    print('')

                    # Delete temp path
                    if os.path.exists(d) and d != "":
                        PixivHelper.print_and_log("debug",
                                                  f"Deleting path {d}")
                        shutil.rmtree(d)
                    list_done.append(image_id)
        if counter == 0:
            PixivHelper.print_and_log(
                'info',
                "No zip file or ugoira found to re-encode animated files.")

    except Exception as ex:
        if isinstance(ex, KeyboardInterrupt):
            raise
        PixivHelper.print_and_log(
            'error',
            'Error at process_ugoira_local(): %s' % str(sys.exc_info()))
        PixivHelper.print_and_log('error', 'failed')
        raise
    finally:
        if os.path.exists(d) and d != "":
            PixivHelper.print_and_log("debug", f"Deleting path {d} in finally")
            shutil.rmtree(d)
Example #2
0
    def WriteXMP(self, filename):
        import pyexiv2
        # import tempfile

        # need to use temp file due to bad unicode support for pyexiv2 in windows
        d = PixivHelper.create_temp_dir(prefix="xmp")
        tempname = f"{d}/{self.imageId}.xmp"

        info = codecs.open(tempname, 'wb', encoding='utf-8')

        # Create the XMP file template.
        info.write(
            '<?xpacket begin="" id=""?>\n<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 4.4.0-Exiv2">\n</x:xmpmeta>\n<?xpacket end="w"?>\n'
        )
        info.close()

        # Reopen file using pyexiv2
        # newer version e.g. pyexiv2-2.7.0
        info = pyexiv2.Image(tempname)
        info_dict = info.read_xmp()
        info_dict['Xmp.dc.creator'] = [self.artist.artistName]
        # Check array isn't empty.
        if self.imageTitle:
            info_dict['Xmp.dc.title'] = self.imageTitle
        # Check array isn't empty.
        if self.imageCaption:
            info_dict['Xmp.dc.description'] = self.imageCaption
        # Check array isn't empty.
        if self.imageTags:
            info_dict['Xmp.dc.subject'] = self.imageTags
        info_dict['Xmp.dc.date'] = [self.worksDateDateTime]
        info_dict[
            'Xmp.dc.source'] = f"http://www.pixiv.net/en/artworks/{self.imageId}"
        info_dict['Xmp.dc.identifier'] = self.imageId

        # Custom 'pixiv' namespace for non-standard details.
        pyexiv2.registerNs('http://pixiv.com/', 'pixiv')

        info_dict['Xmp.pixiv.artist_id'] = self.artist.artistId
        info_dict['Xmp.pixiv.image_mode'] = self.imageMode
        info_dict['Xmp.pixiv.pages'] = self.imageCount
        info_dict['Xmp.pixiv.resolution'] = self.worksResolution
        info_dict['Xmp.pixiv.bookmark_count'] = self.bookmark_count

        if self.seriesNavData:
            info_dict['Xmp.pixiv.series_title'] = self.seriesNavData['title']
            info_dict['Xmp.pixiv.series_order'] = self.seriesNavData['order']
            info_dict['Xmp.pixiv.series_id'] = self.seriesNavData['seriesId']
        if self.ugoira_data:
            info_dict['Xmp.pixiv.ugoira_data'] = self.ugoira_data
        if len(self.descriptionUrlList) > 0:
            info_dict['Xmp.pixiv.urls'] = ", ".join(self.descriptionUrlList)
        # Issue #1064
        if len(self.translated_work_title) > 0:
            info_dict[
                'Xmp.pixiv.translated_work_title'] = self.translated_work_title
        if len(self.translated_work_caption) > 0:
            info_dict[
                'Xmp.pixiv.translated_work_caption'] = self.translated_work_caption
        info.modify_xmp(info_dict)
        info.close()

        # rename to actual file
        try:
            # Issue #421 ensure subdir exists.
            PixivHelper.makeSubdirs(filename)
            shutil.move(tempname, filename)
        except IOError:
            shutil.move(tempname, f"{self.imageId}.xmp")
            PixivHelper.get_logger().exception(
                "Error when saving image info: %s, file is saved to: %s.xmp",
                filename, str(self.imageId))