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
# Copyright 2016 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Multiprocess file credential storage. This module provides file-based storage that supports multiple credentials and cross-thread and process access. This module supersedes the functionality previously found in `multistore_file`. This module provides :class:`MultiprocessFileStorage` which: * Is tied to a single credential via a user-specified key. This key can be used to distinguish between multiple users, client ids, and/or scopes. * Can be safely accessed and refreshed across threads and processes. Process & thread safety guarantees the following behavior: * If one thread or process refreshes a credential, subsequent refreshes from other processes will re-fetch the credentials from the file instead of performing an http request. * If two processes or threads attempt to refresh concurrently, only one will be able to acquire the lock and refresh, with the deadlock caveat below. * The interprocess lock will not deadlock, instead, the if a process can not acquire the interprocess lock within ``INTERPROCESS_LOCK_DEADLINE`` it will allow refreshing the credential but will not write the updated credential to disk, This logic happens during every lock cycle - if the credentials are refreshed again it will retry locking and writing as normal. Usage ===== Before using the storage, you need to decide how you want to key the credentials. A few common strategies include: * If you're storing credentials for multiple users in a single file, use a unique identifier for each user as the key. * If you're storing credentials for multiple client IDs in a single file, use the client ID as the key. * If you're storing multiple credentials for one user, use the scopes as the key. * If you have a complicated setup, use a compound key. For example, you can use a combination of the client ID and scopes as the key. Create an instance of :class:`MultiprocessFileStorage` for each credential you want to store, for example:: filename = 'credentials' key = '{}-{}'.format(client_id, user_id) storage = MultiprocessFileStorage(filename, key) To store the credentials:: storage.put(credentials) If you're going to continue to use the credentials after storing them, be sure to call :func:`set_store`:: credentials.set_store(storage) To retrieve the credentials:: storage.get(credentials) """ import base64 import json import logging import os import threading import fasteners from six import iteritems from oauth2client import _helpers from oauth2client import client #: The maximum amount of time, in seconds, to wait when acquire the #: interprocess lock before falling back to read-only mode. INTERPROCESS_LOCK_DEADLINE = 1 logger = logging.getLogger(__name__) _backends = {} _backends_lock = threading.Lock() def _create_file_if_needed(filename): """Creates the an empty file if it does not already exist. Returns: True if the file was created, False otherwise. """ if os.path.exists(filename): return False else: old_umask = os.umask(0o177) try: # Equivalent to "touch". open(filename, 'a+b').close() finally: os.umask(old_umask) logger.info('Credential file {0} created'.format(filename)) return True def _load_credentials_file(credentials_file): """Load credentials from the given file handle. The file is expected to be in this format: { "file_version": 2, "credentials": { "key": "base64 encoded json representation of credentials." } } This function will warn and return empty credentials instead of raising exceptions. Args: credentials_file: An open file handle. Returns: A dictionary mapping user-defined keys to an instance of :class:`oauth2client.client.Credentials`. """ try: credentials_file.seek(0) data = json.load(credentials_file) except Exception: logger.warning( 'Credentials file could not be loaded, will ignore and ' 'overwrite.') return {} if data.get('file_version') != 2: logger.warning( 'Credentials file is not version 2, will ignore and ' 'overwrite.') return {} credentials = {} for key, encoded_credential in iteritems(data.get('credentials', {})): try: credential_json = base64.b64decode(encoded_credential) credential = client.Credentials.new_from_json(credential_json) credentials[key] = credential except: logger.warning( 'Invalid credential {0} in file, ignoring.'.format(key)) return credentials def _write_credentials_file(credentials_file, credentials): """Writes credentials to a file. Refer to :func:`_load_credentials_file` for the format. Args: credentials_file: An open file handle, must be read/write. credentials: A dictionary mapping user-defined keys to an instance of :class:`oauth2client.client.Credentials`. """ data = {'file_version': 2, 'credentials': {}} for key, credential in iteritems(credentials): credential_json = credential.to_json() encoded_credential = _helpers._from_bytes(base64.b64encode( _helpers._to_bytes(credential_json))) data['credentials'][key] = encoded_credential credentials_file.seek(0) json.dump(data, credentials_file) credentials_file.truncate() class _MultiprocessStorageBackend(object): """Thread-local backend for multiprocess storage. Each process has only one instance of this backend per file. All threads share a single instance of this backend. This ensures that all threads use the same thread lock and process lock when accessing the file. """ def __init__(self, filename): self._file = None self._filename = filename self._process_lock = fasteners.InterProcessLock( '{0}.lock'.format(filename)) self._thread_lock = threading.Lock() self._read_only = False self._credentials = {} def _load_credentials(self): """(Re-)loads the credentials from the file.""" if not self._file: return loaded_credentials = _load_credentials_file(self._file) self._credentials.update(loaded_credentials) logger.debug('Read credential file') def _write_credentials(self): if self._read_only: logger.debug('In read-only mode, not writing credentials.') return _write_credentials_file(self._file, self._credentials) logger.debug('Wrote credential file {0}.'.format(self._filename)) def acquire_lock(self): self._thread_lock.acquire() locked = self._process_lock.acquire(timeout=INTERPROCESS_LOCK_DEADLINE) if locked: _create_file_if_needed(self._filename) self._file = open(self._filename, 'r+') self._read_only = False else: logger.warn( 'Failed to obtain interprocess lock for credentials. ' 'If a credential is being refreshed, other processes may ' 'not see the updated access token and refresh as well.') if os.path.exists(self._filename): self._file = open(self._filename, 'r') else: self._file = None self._read_only = True self._load_credentials() def release_lock(self): if self._file is not None: self._file.close() self._file = None if not self._read_only: self._process_lock.release() self._thread_lock.release() def _refresh_predicate(self, credentials): if credentials is None: return True elif credentials.invalid: return True elif credentials.access_token_expired: return True else: return False def locked_get(self, key): # Check if the credential is already in memory. credentials = self._credentials.get(key, None) # Use the refresh predicate to determine if the entire store should be # reloaded. This basically checks if the credentials are invalid # or expired. This covers the situation where another process has # refreshed the credentials and this process doesn't know about it yet. # In that case, this process won't needlessly refresh the credentials. if self._refresh_predicate(credentials): self._load_credentials() credentials = self._credentials.get(key, None) return credentials def locked_put(self, key, credentials): self._load_credentials() self._credentials[key] = credentials self._write_credentials() def locked_delete(self, key): self._load_credentials() self._credentials.pop(key, None) self._write_credentials() def _get_backend(filename): """A helper method to get or create a backend with thread locking. This ensures that only one backend is used per-file per-process, so that thread and process locks are appropriately shared. Args: filename: The full path to the credential storage file. Returns: An instance of :class:`_MultiprocessStorageBackend`. """ filename = os.path.abspath(filename) with _backends_lock: if filename not in _backends: _backends[filename] = _MultiprocessStorageBackend(filename) return _backends[filename] class MultiprocessFileStorage(client.Storage): """Multiprocess file credential storage. Args: filename: The path to the file where credentials will be stored. key: An arbitrary string used to uniquely identify this set of credentials. For example, you may use the user's ID as the key or a combination of the client ID and user ID. """ def __init__(self, filename, key): self._key = key self._backend = _get_backend(filename) def acquire_lock(self): self._backend.acquire_lock() def release_lock(self): self._backend.release_lock() def locked_get(self): """Retrieves the current credentials from the store. Returns: An instance of :class:`oauth2client.client.Credentials` or `None`. """ credential = self._backend.locked_get(self._key) if credential is not None: credential.set_store(self) return credential def locked_put(self, credentials): """Writes the given credentials to the store. Args: credentials: an instance of :class:`oauth2client.client.Credentials`. """ return self._backend.locked_put(self._key, credentials) def locked_delete(self): """Deletes the current credentials from the store.""" return self._backend.locked_delete(self._key)