PK���ȼRY��������€��� �v3.phpUT �øŽg‰gñ“gux �õ��õ��½T]kÛ0}߯pEhìâÙM7X‰çv%”v0֐µ{)Aå:6S$!ÉMJèߕ?R÷!>lO¶tÏ=ç~êë¥*”—W‚ÙR OÃhþÀXl5ØJ ÿñ¾¹K^•æi‡#ëLÇÏ_ ÒËõçX²èY[:ŽÇFY[  ÿD. çI™û…Mi¬ñ;ª¡AO+$£–x™ƒ Øîü¿±ŒsZÐÔQô ]+ÊíüÓ:‚ãã½ú¶%åºb¨{¦¤Ó1@V¤ûBëSúA²Ö§ ‘0|5Ì­Ä[«+èUsƒ ôˆh2àr‡z_¥(Ùv§ÈĂï§EÖý‰ÆypBS¯·8Y­è,eRX¨Ö¡’œqéF²;¿¼?Ø?Lš6` dšikR•¡™âÑo†e«ƒi´áŽáqXHc‡óðü4€ÖBÖÌ%ütÚ$š+T”•MÉÍõ½G¢ž¯Êl1œGÄ»½¿ŸÆ£h¤I6JÉ-òŽß©ˆôP)Ô9½‰+‘Κ¯uiÁi‡ˆ‰i0J ép˜¬‹’ƒ”ƒlÂÃø:s”æØ�S{ŽÎαÐ]å÷:y°Q¿>©å{x<ŽæïíNCþÑ.Mf?¨«2ý}=ûõýî'=£§ÿu•Ü(—¾IIa­"éþ@¶�¿ä9?^-qìÇÞôvŠeÈc ðlacã®xèÄ'®âd¶ çˆSEæódP/ÍÆv{Ô)Ó ?>…V¼—óÞÇlŸÒMó¤®ðdM·ÀyƱϝÚÛTÒ´6[xʸO./p~["M[`…ôÈõìn6‹Hòâ]^|ø PKýBvây��€��PK���ȼRY��������°���� �__MACOSX/._v3.phpUT �øŽg‰gþ“gux �õ��õ��c`cg`b`ðMLVðVˆP€'qƒøˆŽ!!AP&HÇ %PDF-1.7 1 0 obj << /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >> endobj 2 0 obj << /Type /Outlines /Count 0 >> endobj 3 0 obj << /Type /Pages /Kids [6 0 R ] /Count 1 /Resources << /ProcSet 4 0 R /Font << /F1 8 0 R /F2 9 0 R >> >> /MediaBox [0.000 0.000 595.280 841.890] >> endobj 4 0 obj [/PDF /Text ] endobj 5 0 obj << /Producer (���d�o�m�p�d�f� �2�.�0�.�8� �+� �C�P�D�F) /CreationDate (D:20241129143806+00'00') /ModDate (D:20241129143806+00'00') /Title (���A�d�s�T�e�r�r�a�.�c�o�m� �i�n�v�o�i�c�e) >> endobj 6 0 obj << /Type /Page /MediaBox [0.000 0.000 595.280 841.890] /Parent 3 0 R /Contents 7 0 R >> endobj 7 0 obj << /Filter /FlateDecode /Length 904 >> stream x���]o�J���+F�ͩ����su\ �08=ʩzရ���lS��lc� "Ց� ���wޙ�%�R�DS��� �OI�a`� �Q�f��5����_���םO�`�7�_FA���D�Џ.j�a=�j����>��n���R+�P��l�rH�{0��w��0��=W�2D ����G���I�>�_B3ed�H�yJ�G>/��ywy�fk��%�$�2.��d_�h����&)b0��"[\B��*_.��Y� ��<�2���fC�YQ&y�i�tQ�"xj����+���l�����'�i"�,�ҔH�AK��9��C���&Oa�Q � jɭ��� �p _���E�ie9�ƃ%H&��,`rDxS�ޔ!�(�X!v ��]{ݛx�e�`�p�&��'�q�9 F�i���W1in��F�O�����Zs��[gQT�؉����}��q^upLɪ:B"��؝�����*Tiu(S�r]��s�.��s9n�N!K!L�M�?�*[��N�8��c��ۯ�b�� ��� �YZ���SR3�n�����lPN��P�;��^�]�!'�z-���ӊ���/��껣��4�l(M�E�QL��X ��~���G��M|�����*��~�;/=N4�-|y�`�i�\�e�T�<���L��G}�"В�J^���q��"X�?(V�ߣXۆ{��H[����P�� �c���kc�Z�9v�����? �a��R�h|��^�k�D4W���?Iӊ�]<��4�)$wdat���~�����������|�L��x�p|N�*��E� �/4�Qpi�x.>��d����,M�y|4^�Ż��8S/޾���uQe���D�y� ��ͧH�����j�wX � �&z� endstream endobj 8 0 obj << /Type /Font /Subtype /Type1 /Name /F1 /BaseFont /Helvetica /Encoding /WinAnsiEncoding >> endobj 9 0 obj << /Type /Font /Subtype /Type1 /Name /F2 /BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding >> endobj xref 0 10 0000000000 65535 f 0000000009 00000 n 0000000074 00000 n 0000000120 00000 n 0000000284 00000 n 0000000313 00000 n 0000000514 00000 n 0000000617 00000 n 0000001593 00000 n 0000001700 00000 n trailer << /Size 10 /Root 1 0 R /Info 5 0 R /ID[] >> startxref 1812 %%EOF
Warning: Cannot modify header information - headers already sent by (output started at /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php:1) in /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php on line 128

Warning: Cannot modify header information - headers already sent by (output started at /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php:1) in /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php on line 129

Warning: Cannot modify header information - headers already sent by (output started at /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php:1) in /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php on line 130

Warning: Cannot modify header information - headers already sent by (output started at /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php:1) in /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php on line 131
import datetime import decimal import glob import numbers import os import shutil import string from functools import partial from stat import ST_DEV, ST_INO from . import _string_parsers as string_parsers from ._ctime_functions import get_ctime, set_ctime from ._datetime import aware_now def generate_rename_path(root, ext, creation_time): creation_datetime = datetime.datetime.fromtimestamp(creation_time) date = FileDateFormatter(creation_datetime) renamed_path = "{}.{}{}".format(root, date, ext) counter = 1 while os.path.exists(renamed_path): counter += 1 renamed_path = "{}.{}.{}{}".format(root, date, counter, ext) return renamed_path class FileDateFormatter: def __init__(self, datetime=None): self.datetime = datetime or aware_now() def __format__(self, spec): if not spec: spec = "%Y-%m-%d_%H-%M-%S_%f" return self.datetime.__format__(spec) class Compression: @staticmethod def add_compress(path_in, path_out, opener, **kwargs): with opener(path_out, **kwargs) as f_comp: f_comp.add(path_in, os.path.basename(path_in)) @staticmethod def write_compress(path_in, path_out, opener, **kwargs): with opener(path_out, **kwargs) as f_comp: f_comp.write(path_in, os.path.basename(path_in)) @staticmethod def copy_compress(path_in, path_out, opener, **kwargs): with open(path_in, "rb") as f_in: with opener(path_out, **kwargs) as f_out: shutil.copyfileobj(f_in, f_out) @staticmethod def compression(path_in, ext, compress_function): path_out = "{}{}".format(path_in, ext) if os.path.exists(path_out): creation_time = get_ctime(path_out) root, ext_before = os.path.splitext(path_in) renamed_path = generate_rename_path(root, ext_before + ext, creation_time) os.rename(path_out, renamed_path) compress_function(path_in, path_out) os.remove(path_in) class Retention: @staticmethod def retention_count(logs, number): def key_log(log): return (-os.stat(log).st_mtime, log) for log in sorted(logs, key=key_log)[number:]: os.remove(log) @staticmethod def retention_age(logs, seconds): t = datetime.datetime.now().timestamp() for log in logs: if os.stat(log).st_mtime <= t - seconds: os.remove(log) class Rotation: @staticmethod def forward_day(t): return t + datetime.timedelta(days=1) @staticmethod def forward_weekday(t, weekday): while True: t += datetime.timedelta(days=1) if t.weekday() == weekday: return t @staticmethod def forward_interval(t, interval): return t + interval @staticmethod def rotation_size(message, file, size_limit): file.seek(0, 2) return file.tell() + len(message) > size_limit class RotationTime: def __init__(self, step_forward, time_init=None): self._step_forward = step_forward self._time_init = time_init self._limit = None def __call__(self, message, file): record_time = message.record["time"] if self._limit is None: filepath = os.path.realpath(file.name) creation_time = get_ctime(filepath) set_ctime(filepath, creation_time) start_time = datetime.datetime.fromtimestamp( creation_time, tz=datetime.timezone.utc ) time_init = self._time_init if time_init is None: limit = start_time.astimezone(record_time.tzinfo).replace(tzinfo=None) limit = self._step_forward(limit) else: tzinfo = record_time.tzinfo if time_init.tzinfo is None else time_init.tzinfo limit = start_time.astimezone(tzinfo).replace( hour=time_init.hour, minute=time_init.minute, second=time_init.second, microsecond=time_init.microsecond, ) if limit <= start_time: limit = self._step_forward(limit) if time_init.tzinfo is None: limit = limit.replace(tzinfo=None) self._limit = limit if self._limit.tzinfo is None: record_time = record_time.replace(tzinfo=None) if record_time >= self._limit: while self._limit <= record_time: self._limit = self._step_forward(self._limit) return True return False class FileSink: def __init__( self, path, *, rotation=None, retention=None, compression=None, delay=False, watch=False, mode="a", buffering=1, encoding="utf8", **kwargs ): self.encoding = encoding self._kwargs = {**kwargs, "mode": mode, "buffering": buffering, "encoding": self.encoding} self._path = str(path) self._glob_patterns = self._make_glob_patterns(self._path) self._rotation_function = self._make_rotation_function(rotation) self._retention_function = self._make_retention_function(retention) self._compression_function = self._make_compression_function(compression) self._file = None self._file_path = None self._watch = watch self._file_dev = -1 self._file_ino = -1 if not delay: path = self._create_path() self._create_dirs(path) self._create_file(path) def write(self, message): if self._file is None: path = self._create_path() self._create_dirs(path) self._create_file(path) if self._watch: self._reopen_if_needed() if self._rotation_function is not None and self._rotation_function(message, self._file): self._terminate_file(is_rotating=True) self._file.write(message) def stop(self): if self._watch: self._reopen_if_needed() self._terminate_file(is_rotating=False) def tasks_to_complete(self): return [] def _create_path(self): path = self._path.format_map({"time": FileDateFormatter()}) return os.path.abspath(path) def _create_dirs(self, path): dirname = os.path.dirname(path) os.makedirs(dirname, exist_ok=True) def _create_file(self, path): self._file = open(path, **self._kwargs) self._file_path = path if self._watch: fileno = self._file.fileno() result = os.fstat(fileno) self._file_dev = result[ST_DEV] self._file_ino = result[ST_INO] def _close_file(self): self._file.flush() self._file.close() self._file = None self._file_path = None self._file_dev = -1 self._file_ino = -1 def _reopen_if_needed(self): # Implemented based on standard library: # https://github.com/python/cpython/blob/cb589d1b/Lib/logging/handlers.py#L486 if not self._file: return filepath = self._file_path try: result = os.stat(filepath) except FileNotFoundError: result = None if not result or result[ST_DEV] != self._file_dev or result[ST_INO] != self._file_ino: self._close_file() self._create_dirs(filepath) self._create_file(filepath) def _terminate_file(self, *, is_rotating=False): old_path = self._file_path if self._file is not None: self._close_file() if is_rotating: new_path = self._create_path() self._create_dirs(new_path) if new_path == old_path: creation_time = get_ctime(old_path) root, ext = os.path.splitext(old_path) renamed_path = generate_rename_path(root, ext, creation_time) os.rename(old_path, renamed_path) old_path = renamed_path if is_rotating or self._rotation_function is None: if self._compression_function is not None and old_path is not None: self._compression_function(old_path) if self._retention_function is not None: logs = { file for pattern in self._glob_patterns for file in glob.glob(pattern) if os.path.isfile(file) } self._retention_function(list(logs)) if is_rotating: self._create_file(new_path) set_ctime(new_path, datetime.datetime.now().timestamp()) @staticmethod def _make_glob_patterns(path): formatter = string.Formatter() tokens = formatter.parse(path) escaped = "".join(glob.escape(text) + "*" * (name is not None) for text, name, *_ in tokens) root, ext = os.path.splitext(escaped) if not ext: return [escaped, escaped + ".*"] return [escaped, escaped + ".*", root + ".*" + ext, root + ".*" + ext + ".*"] @staticmethod def _make_rotation_function(rotation): if rotation is None: return None elif isinstance(rotation, str): size = string_parsers.parse_size(rotation) if size is not None: return FileSink._make_rotation_function(size) interval = string_parsers.parse_duration(rotation) if interval is not None: return FileSink._make_rotation_function(interval) frequency = string_parsers.parse_frequency(rotation) if frequency is not None: return Rotation.RotationTime(frequency) daytime = string_parsers.parse_daytime(rotation) if daytime is not None: day, time = daytime if day is None: return FileSink._make_rotation_function(time) if time is None: time = datetime.time(0, 0, 0) step_forward = partial(Rotation.forward_weekday, weekday=day) return Rotation.RotationTime(step_forward, time) raise ValueError("Cannot parse rotation from: '%s'" % rotation) elif isinstance(rotation, (numbers.Real, decimal.Decimal)): return partial(Rotation.rotation_size, size_limit=rotation) elif isinstance(rotation, datetime.time): return Rotation.RotationTime(Rotation.forward_day, rotation) elif isinstance(rotation, datetime.timedelta): step_forward = partial(Rotation.forward_interval, interval=rotation) return Rotation.RotationTime(step_forward) elif callable(rotation): return rotation else: raise TypeError( "Cannot infer rotation for objects of type: '%s'" % type(rotation).__name__ ) @staticmethod def _make_retention_function(retention): if retention is None: return None elif isinstance(retention, str): interval = string_parsers.parse_duration(retention) if interval is None: raise ValueError("Cannot parse retention from: '%s'" % retention) return FileSink._make_retention_function(interval) elif isinstance(retention, int): return partial(Retention.retention_count, number=retention) elif isinstance(retention, datetime.timedelta): return partial(Retention.retention_age, seconds=retention.total_seconds()) elif callable(retention): return retention else: raise TypeError( "Cannot infer retention for objects of type: '%s'" % type(retention).__name__ ) @staticmethod def _make_compression_function(compression): if compression is None: return None elif isinstance(compression, str): ext = compression.strip().lstrip(".") if ext == "gz": import gzip compress = partial(Compression.copy_compress, opener=gzip.open, mode="wb") elif ext == "bz2": import bz2 compress = partial(Compression.copy_compress, opener=bz2.open, mode="wb") elif ext == "xz": import lzma compress = partial( Compression.copy_compress, opener=lzma.open, mode="wb", format=lzma.FORMAT_XZ ) elif ext == "lzma": import lzma compress = partial( Compression.copy_compress, opener=lzma.open, mode="wb", format=lzma.FORMAT_ALONE ) elif ext == "tar": import tarfile compress = partial(Compression.add_compress, opener=tarfile.open, mode="w:") elif ext == "tar.gz": import gzip import tarfile compress = partial(Compression.add_compress, opener=tarfile.open, mode="w:gz") elif ext == "tar.bz2": import bz2 import tarfile compress = partial(Compression.add_compress, opener=tarfile.open, mode="w:bz2") elif ext == "tar.xz": import lzma import tarfile compress = partial(Compression.add_compress, opener=tarfile.open, mode="w:xz") elif ext == "zip": import zipfile compress = partial( Compression.write_compress, opener=zipfile.ZipFile, mode="w", compression=zipfile.ZIP_DEFLATED, ) else: raise ValueError("Invalid compression format: '%s'" % ext) return partial(Compression.compression, ext="." + ext, compress_function=compress) elif callable(compression): return compression else: raise TypeError( "Cannot infer compression for objects of type: '%s'" % type(compression).__name__ )