ó
    R½Íjû  ã                   óÔ   • S SK r S SKrS SKrS SKJr  S SKJr  S SKJr  \" 5         \ R                  " \
5      rSrS1rSrSr1 S	krS
 rSS jrS rS rSrSS jrSS jr " S S5      rg)é    N)ÚFernet)Úload_dotenv)ÚURL)Ú
SECRET_KEYÚAPI_KEYÚTIKTOK_CLIENT_SECRETzdev-secret-change-me)ÚsqliteÚpostgresz/app/data/tiktok_manager.db>   Ú ÚsecretÚchangemeÚpasswordr
   ú	change-meúyour-passwordc                 óÂ   • U =(       d    SR                  5       R                  5       nU[        ;   =(       d)    UR                  S5      =(       d    UR                  S5      $ )zZReturn True when a secret value is empty, a well-known default or a change-me placeholder.r   r   zyour-)ÚstripÚlowerÚPLACEHOLDER_PASSWORDSÚ
startswith©ÚvalueÚvs     Ú<F:\Solutions\Thinkera\Publishers\TikTokManager\app\config.pyÚis_placeholder_secretr      sF   € à	��"×ÑÓ×#Ñ#Ó%€AØÔ%Ñ%×[¨¯©°kÓ)B×[ÀaÇlÁlÐSZÓF[Ð[ó    c                 óÎ  • U c  [         R                  OU n U R                  S5      =(       d    SR                  5       nU(       a  U$ U R                  S5      =(       d    SR                  5       R	                  5       nUS:X  a!  SU R                  S5      =(       d    [
         3$ US:X  a§  [        R                  " S	U R                  S
5      =(       d    SU R                  S5      =(       d    SU R                  S5      =(       d    S[        U R                  S5      =(       d    S5      U R                  S5      =(       d    SS9R                  SS9$ [        S[         SU< 35      e)z€Build the SQLAlchemy URL from DATABASE_URL, else DB_ENGINE + DATABASE_PATH / POSTGRES_*; raises ValueError on an unknown engine.NÚDATABASE_URLr   Ú	DB_ENGINEr	   z
sqlite:///ÚDATABASE_PATHr
   zpostgresql+psycopgÚPOSTGRES_USERÚtiktok_managerÚPOSTGRES_PASSWORDÚPOSTGRES_HOSTÚdbÚPOSTGRES_PORTi8  ÚPOSTGRES_DB)Úusernamer   ÚhostÚportÚdatabaseF)Úhide_passwordúDB_ENGINE must be one of ú, got )ÚosÚenvironÚgetr   r   ÚDEFAULT_DATABASE_PATHr   ÚcreateÚintÚrender_as_stringÚ
ValueErrorÚSUPPORTED_DB_ENGINES)ÚenvÚoverrideÚengines      r   Údatabase_urir:      s%  € à™Œ"�*Š*¨€CØ—‘˜Ó'×-¨2×4Ñ4Ó6€HÞØˆØ�g‰g�kÓ"×. h×5Ñ5Ó7×=Ñ=Ó?€FØ�ÓØ˜CŸG™G OÓ4×MÔ8MÐNÐOÐOØ�ÓÜ�zŠzØ Ø—W‘W˜_Ó-×AÐ1AØ—W‘WÐ0Ó1×9°TØ—‘˜Ó)×1¨TÜ�S—W‘W˜_Ó-×5°Ó6Ø—W‘W˜]Ó+×?Ð/?ñ
÷ Ñ
¨Ð
Ð
/ð	0ô Ð0Ô1EÐ0FÀfÈVÉJÐWÓ
XÐXr   c                 óž   • U =(       d    SR                  5       R                  5       n[        U5      =(       d    U[        ;   =(       d    SU;   $ )z^Return True when an application secret is empty, a shipped default or a change-me placeholder.r   r   )r   r   r   ÚKNOWN_SECRET_PLACEHOLDERSr   s     r   Úis_placeholder_app_secretr=   0   s>   € à	��"×ÑÓ×#Ñ#Ó%€AÜ  Ó#×Y qÔ,EÑ'E×YÈÐXYÑIYÐYr   c                 ó:  • U =(       d    SR                  S5       Vs/ s H)  oR                  5       (       d  M  UR                  5       PM+     nnU(       d  [        S5      eU H  n [        U5        M     U$ s  snf ! [        [        4 a    [        S5      Sef = f)z‘Split TOKEN_ENCRYPTION_KEY (comma-separated Fernet keys; the first encrypts, all decrypt) into a list; raises ValueError when empty or malformed.r   Ú,z
is not setz)contains a value that is not a Fernet keyN)Úsplitr   r5   r   Ú	TypeError)r   ÚkÚkeyss      r   Útoken_encryption_keysrD   6   s�   € à %§¨×2Ñ2°3Ô7ÓEÒ7˜!¿7¹7¿9‹IˆA�G‰GŽIÑ7€DÐEÞÜ˜Ó&Ð&Ûˆð	TÜ�1ŽIñ ð
 €Kùò Føô œIÐ&ó 	TÜÐHÓIÈtÐSð	Tús   �A8¹A8Á'A=Á=Bzlgenerate one with: python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"c                 óà  • Uc  [         R                  OUnU R                  SS5      S:H  n [        U R                  S5      5        SnU(       aŽ  [         Vs/ s H&  n[        U R                  U5      5      (       d  M$  UPM(     nnU(       d  U(       aH  [        SSR                  Xc(       a  S/O/ -   5      -   S-   U(       a  SU S[         3-   5      eS	-   5      egU(       a  [        S
U S[         35      e[        U R                  S5      5      (       a/  [        R                  " S5      U S'   [        R                  S5        gg! [         a  n[        U5      n SnAGNSnAff = fs  snf )zâFail closed at startup: in production every application secret must be set and real;
outside production, mint a random SECRET_KEY when none is set. Raises RuntimeError that names
the offending variables and never their values.NÚ	FLASK_ENVÚ
productionÚTOKEN_ENCRYPTION_KEYz-Refusing to start with FLASK_ENV=production: z, z1 missing or still a placeholder from .env.examplez; TOKEN_ENCRYPTION_KEY r   z(Refusing to start: TOKEN_ENCRYPTION_KEY z; r   é    zVSECRET_KEY not set: generated a random key for this process; sessions reset on restart)r.   r/   r0   rD   r5   ÚstrÚSECRET_SETTINGSr=   ÚRuntimeErrorÚjoinÚKEY_HINTÚsecretsÚ	token_hexÚlogÚwarning)Úconfigr7   rG   Ú	key_errorÚeÚnameÚmissings          r   Úcheck_secrets_configrX   G   sc  € ð ™Œ"�*Š*¨€CØ—‘˜K¨Ó6¸,ÑF€JðÜ˜fŸj™jÐ)?Ó@ÔAØˆ	ö Ý$3Óc¢O˜DÔ7PÐQW×Q[ÑQ[Ð\`ÓQa×7b—4¡OˆÐcÞ–iÜØ?Ø—)‘)˜GÅ9Ð(>Ñ'?ÐRTÑUÓVñWàEñFö IRÐ,¨Y¨K°r¼(¸ÐDñ[óð ð XZñ[óð ð 	æÜÐEÀiÀ[ÐPRÔS[ÐR\Ð]Ó^Ð^Ü  §¡¨LÓ!9×:Ñ:Ü&×0Ò0°Ó4ˆˆ|ÑÜ�‰ÐlÕmð ;øô! ó Ü˜“FŽ	ûðüò ds#   ¬E Á#E+Á>E+Å
E(ÅE#Å#E(c                 óÎ  • Uc  [         R                  OUnU R                  SS5      S:H  nU R                  S5      =(       d    SR                  5       R	                  5       nU[
        ;  a  [        S[
         SU< 35      eU(       a3  US:w  d-  UR                  S	5      =(       d    S
R                  5       (       a  g[        UR                  S5      5      (       a  [        S5      eg)zzRefuse to start in production with DB_ENGINE=postgres and a missing or placeholder POSTGRES_PASSWORD; raises RuntimeError.NrF   rG   r   r	   r,   r-   r
   r   r   r"   zbDB_ENGINE=postgres requires a real POSTGRES_PASSWORD in production; it is missing or a placeholder)	r.   r/   r0   r   r   r6   r5   r   rL   )rS   r7   rG   r9   s       r   Úcheck_database_configrZ   e   sÆ   € à™Œ"�*Š*¨€CØ—‘˜K¨Ó6¸,ÑF€JØ�j‰j˜Ó%×1¨×8Ñ8Ó:×@Ñ@ÓB€FØÔ)Ó)ÜÐ4Ô5IÐ4JÈ&ÐQWÑPZÐ[Ó\Ð\Þ˜ :Ó-°#·'±'¸.Ó2I×2OÈR×1VÑ1V×1XÑ1XØÜ˜SŸW™WÐ%8Ó9×:Ñ:Üð-ó
ð 	
ð ;r   c                   ó4  • \ rS rSr\R
                  R                  SS5      r\R
                  R                  SS5      r\R
                  R                  SS5      r	\R
                  R                  SS5      r
\R
                  R                  SS	5      r\R
                  R                  S
S5      R                  S5      r\R
                  R                  SS5      R                  5       R                  5       r\R
                  R                  S\5      r\" 5       rSr\" \R
                  R                  SS5      5      r\" \R
                  R                  SS5      5      r\S-  S-  r\R
                  R                  SS5      r\" \R
                  R                  SS5      5      r\R
                  R                  SS5      r\R
                  R                  SS5      r\R
                  R                  SS5      r\R
                  R                  SS5      rS r S!r!g")#ÚConfigéu   r   r   rF   rG   ÚTIKTOK_CLIENT_KEYr   ÚTIKTOK_REDIRECT_URIz$https://localhost:5002/auth/callbackÚTIKTOK_SCOPESz8user.info.basic,user.info.stats,video.list,video.publishr?   r   r	   r   FÚDB_CONNECT_TIMEOUT_SECONDSÚ60ÚMAX_UPLOAD_SIZE_MBÚ4096i   ÚMEDIA_FOLDERz
/app/mediaÚSCHEDULER_INTERVAL_SECONDSÚ30ÚAPP_NAMEzTikTok ManagerÚUPLOAD_FOLDERz/app/uploadsr   rH   iÀ¨  © N)"Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__r.   r/   r0   r   rF   r^   r   r_   r@   r`   r   r   r   r1   r   r:   ÚSQLALCHEMY_DATABASE_URIÚSQLALCHEMY_TRACK_MODIFICATIONSr3   ra   rc   ÚMAX_CONTENT_LENGTHre   rf   rh   ri   r   rH   ÚWTF_CSRF_TIME_LIMITÚ__static_attributes__rj   r   r   r\   r\   u   s²  † Ø—‘—‘ ¨bÓ1€JØ—
‘
—‘˜{¨LÓ9€IàŸ
™
Ÿ™Ð':¸BÓ?ÐØŸ:™:Ÿ>™>Ð*@À"ÓEÐØŸ*™*Ÿ.™.ØÐEóÐð —J‘J—N‘NØØBó÷ �eˆCƒjð ð
 —
‘
—‘˜{¨HÓ5×;Ñ;Ó=×CÑCÓE€IØ—J‘J—N‘N ?Ð4IÓJ€MÙ*›nÐØ%*Ð"Ù!$ R§Z¡Z§^¡^Ð4PÐRVÓ%WÓ!XÐá˜RŸZ™ZŸ^™^Ð,@À&ÓIÓJÐØ+¨dÑ2°TÑ9Ðà—:‘:—>‘> .°,Ó?€LÙ!$ R§Z¡Z§^¡^Ð4PÐRVÓ%WÓ!XÐà�z‰z�~‰~˜jÐ*:Ó;€HØ—J‘J—N‘N ?°NÓC€Mà�j‰j�n‰n˜Y¨Ó+€GØŸ:™:Ÿ>™>Ð*@À"ÓEÐà&Ór   r\   )N)Úloggingr.   rO   Úcryptography.fernetr   Údotenvr   Úsqlalchemy.enginer   Ú	getLoggerrk   rQ   rK   r<   r6   r1   r   r   r:   r=   rD   rN   rX   rZ   r\   rj   r   r   Ú<module>ry      s   ðÛ Û 	Û å &Ý Ý !á „à×Ò˜Ó!€àC€Ø3Ð4Ð à-Ð Ø5Ð ÚhÐ ò\ôYò*Zò
ð5€ônô<
÷  'ò  'r   