Ë
    ÷¬‹j  ã                   ó*  — d Z ddlZddlZddlZddlZddlZddlmZmZ ddl	m
Z
mZ dZej                  j                  ed«      ej                  j                  ed«      dœZd	Zd
Z G d„ de«      Zedk(  rž eej*                  «      dkD  r eej*                  d   «      ndZej1                  «       D ]  Z ej4                  ed¬«       Œ  edefe«      Z ede› �«        eded   › ded   › �«        ede› de› �«       ej;                  «        yy)uâ  
Pak Otto Upload Server â€” biar Bos bisa upload (copy-paste) file dari lokal ke folder
pak_otto_image & pak_otto_video di server OpenClaw lewat browser.

- Port: 8124 (bind 0.0.0.0) â†’ akses dari Mac Bos via Tailscale: http://100.79.230.61:8124
- Halaman: pilih folder (Image / Video), pilih file (multipart), upload
- Simpan: /home/mantapman/.openclaw/workspace-atun/pak_otto_{image,video}/
- Proteksi: token sederhana (query ?t=... atau header) â€” ganti TOKEN sesuai keinginan
é    N)ÚBaseHTTPRequestHandlerÚThreadingHTTPServer)ÚurlparseÚparse_qsz(/home/mantapman/.openclaw/workspace-atunÚpak_otto_imageÚpak_otto_video)ÚimageÚvideoÚotto2026uz  <!DOCTYPE html>
<html lang="id"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Pak Otto Upload</title>
<style>
 body{font-family:system-ui,sans-serif;background:#1E3A8A;color:#fff;display:flex;justify-content:center;padding:40px 16px;margin:0}
 .card{background:#fff;color:#111;border-radius:16px;padding:28px;max-width:480px;width:100%;box-shadow:0 10px 30px rgba(0,0,0,.3)}
 h1{font-size:22px;margin:0 0 6px} p.sub{margin:0 0 18px;color:#555;font-size:14px}
 label{font-weight:600;font-size:14px} select,input[type=file]{width:100%;padding:10px;margin:8px 0 16px;border:1px solid #ccc;border-radius:8px;font-size:14px}
 input[type=file]{background:#f5f5f5}
 button{width:100%;padding:12px;background:#F97316;color:#fff;border:0;border-radius:8px;font-size:16px;font-weight:700;cursor:pointer}
 button:hover{background:#ea6a0b}
 .ok{background:#dcfce7;color:#166534;padding:10px;border-radius:8px;margin-top:14px;font-size:14px}
 .err{background:#fee2e2;color:#991b1b;padding:10px;border-radius:8px;margin-top:14px;font-size:14px}
 ul{font-size:13px;color:#444;padding-left:18px;line-height:1.6}
</style></head><body>
<div class="card">
 <h1>ðŸ“� Upload Aset Pak Otto</h1>
 <p class="sub">Pilih folder, pilih file, klik Upload. File langsung masuk server OpenClaw.</p>
 <form method="post" enctype="multipart/form-data" action="/upload">
  <label for="folder">Folder tujuan</label>
  <select name="folder" id="folder">
   <option value="image">ðŸ–¼ï¸� pak_otto_image</option>
   <option value="video">ðŸŽ¬ pak_otto_video</option>
  </select>
  <label for="file">File (boleh banyak sekaligus)</label>
  <input type="file" name="file" id="file" multiple required>
  <button type="submit">â¬†ï¸� Upload</button>
 </form>
 {MSG}
 <p class="sub" style="margin-top:18px">Setelah upload, file langsung bisa dipakai (URL server otomatis).</p>
</div></body></html>c                   ó,   — e Zd Zd„ Zd„ Zdd„Zd„ Zd„ Zy)ÚHandlerc                  ó   — y ©N© )ÚselfÚas     úpak_otto_upload_server.pyÚlog_messagezHandler.log_message9   s   € Øó    c                 óÚ   — t        t        | j                  «      j                  «      }|j	                  ddg«      d   }|t
        k(  ry| j                  j	                  d«      t
        k(  ryy)NÚtÚ r   TzX-TokenF)r   r   ÚpathÚqueryÚgetÚTOKENÚheaders)r   Úqr   s      r   Ú_check_tokenzHandler._check_token<   sY   € Ü”X˜dŸi™iÓ(×.Ñ.Ó/ˆØ�E‰E�#˜�tÓ˜QÑˆØ”Š:Øà�<‰<×Ñ˜IÓ&¬%Ò/ØØr   c                 óè   — | j                  |«       | j                  d|«       | j                  dt        t        |«      «      «       | j	                  «        | j
                  j                  |«       y )NúContent-TypeúContent-Length)Úsend_responseÚsend_headerÚstrÚlenÚend_headersÚwfileÚwrite)r   ÚcodeÚbodyÚctypes       r   Ú_sendzHandler._sendF   sW   € Ø×Ñ˜4Ô Ø×Ñ˜¨Ô/Ø×ÑÐ)¬3¬s°4«y«>Ô:Ø×ÑÔØ�
‰
×Ñ˜Õr   c                 óN  — | j                  «       s!| j                  ddj                  «       «       y d}t        j                  j                  d«      rt        j                  j                  d«      }| j                  dt        j                  |¬«      j                  «       «       y )Né‘  u?   <h3>401 â€” butuh token. Akses: http://IP:8124/?t=otto2026</h3>r   Ú
UPLOAD_MSGéÈ   )ÚMSG)	r   r-   ÚencodeÚosÚenvironr   ÚpopÚPAGEÚformat)r   Úmsgs     r   Údo_GETzHandler.do_GETM   sr   € Ø× Ñ Ô"Ø�J‰J�sÐ]×dÑdÓfÔgØØˆÜ�:‰:�>‰>˜,Ô'Ü—*‘*—.‘. Ó.ˆCØ�
‰
�3œŸ™¨˜Ó,×3Ñ3Ó5Õ6r   c                 óN  — | j                  «       s!| j                  ddj                  «       «       y | j                  j	                  dd«      }d|vr!| j                  ddj                  «       «       y 	 t        | j                  j	                  dd	«      «      }| j                  j                  |«      }|j                  d
«      d   j                  «       j                  d«      j                  «       }|j                  d|z   «      }d}g }g }|D �]u  }	|	r|	dv rŒ|	j                  d«      \  }
}}|j                  d«      }|
j                  dd«      }t        j                  d|«      }|sŒ\|j!                  d«      }|dk(  r)|j                  «       j                  «       }|t"        vrd}Œ›|dk(  sŒ¡t        j                  d|«      }|r|j!                  d«      nd}t$        j&                  j)                  |j+                  dd«      «      }|r|s�Œt        j,                  dd|«      }t$        j&                  j/                  t"        |   |«      }t1        |d«      5 }|j3                  |«       d d d «       |j5                  |«       �Œx |r/dt7        |«      › d|› d�d j/                  d!„ |D «       «      z   d"z   }nd#}|t$        j8                  d$<   | j;                  d%«       | j=                  d&d't>        z   «       | jA                  «        y # t        $ r d	}Y �Œ~w xY w# 1 sw Y   Œ°xY w)(Nr/   u   <h3>401 â€” token salah</h3>r!   r   zmultipart/form-datai�  u*   <h3>400 â€” butuh multipart/form-data</h3>r"   r   z	boundary=é   ú"ó   --r	   )ó   
s   --
r>   s   

r?   zutf-8Úignorezname="([^"]+)"ÚfolderÚfilezfilename="([^"]*)"ú\ú/z[^A-Za-z0-9._-]Ú_Úwbu   <div class="ok">âœ… z file terupload ke pak_otto_z/:<br>z<br>c              3   óF   K  — | ]  }t        j                  |«      –— Œ y ­wr   )ÚhtmlÚescape)Ú.0Úss     r   ú	<genexpr>z"Handler.do_POST.<locals>.<genexpr>ƒ   s*   è ø€ ò  nMð  BCÔnr×nyÑnyÐz{×n|ñ  nMùs   ‚!z</div>uB   <div class="err">âš ï¸� Tidak ada file tersimpan. Coba lagi.</div>r0   i/  ÚLocationú/?t=)!r   r-   r3   r   r   ÚintÚ
ValueErrorÚrfileÚreadÚsplitÚstripÚ	partitionÚrstripÚdecodeÚreÚsearchÚgroupÚDIRSr4   r   ÚbasenameÚreplaceÚsubÚjoinÚopenr)   Úappendr&   r5   r#   r$   r   r'   )r   r,   Úlengthr+   ÚboundaryÚpartsrA   ÚsavedÚerrorsÚpartÚheadrE   ÚdataÚhead_txtÚmÚnameÚfmÚfnameÚsafeÚdestÚfr9   s                         r   Údo_POSTzHandler.do_POSTV   sì  € Ø× Ñ Ô"Ø�J‰J�sÐ:×AÑAÓCÔDØØ—‘× Ñ  °Ó4ˆØ ¨Ñ-Ø�J‰J�sÐH×OÑOÓQÔRØð	Ü˜Ÿ™×)Ñ)Ð*:¸AÓ>Ó?ˆFð �z‰z�‰˜vÓ&ˆØ—;‘;˜{Ó+¨AÑ.×4Ñ4Ó6×<Ñ<¸SÓA×HÑHÓJˆØ—
‘
˜5 8Ñ+Ó,ˆØˆØˆØˆØó 	#ˆDÙ˜4Ð#>Ñ>ØØ ŸN™N¨;Ó7‰MˆD�!�TØ—;‘;˜wÓ'ˆDØ—{‘{ 7¨HÓ5ˆHÜ—	‘	Ð+¨XÓ6ˆAÙØØ—7‘7˜1“:ˆDØ�xÒØŸ™›×,Ñ,Ó.�Ø¤Ñ%Ø$�FØØ�v‹~Ü—Y‘YÐ4°hÓ?�Ù')˜Ÿ™ œ¨r�ÜŸ™×(Ñ(¨¯©°t¸SÓ)AÓB�Ù¡DÙÜ—v‘vÐ0°#°uÓ=�Ü—w‘w—|‘|¤D¨¡L°$Ó7�Ü˜$ Ó%ð "¨Ø—G‘G˜D”M÷"à—‘˜TÖ"ð3	#ñ4 Ø(¬¨U«¨Ð4PÐQWÐPXÐX^Ð_Ðbh×bmÑbmñ  nMð  GLô  nMó  cMñ  Mð  PXñ  X‰CàVˆCØ#&Œ�
‰
�<Ñ Ø×Ñ˜3ÔØ×Ñ˜ V¬e¡^Ô4Ø×ÑÕøôS ò 	Ø‹Fð	ú÷>"ð "ús   Á4%L	 ÉLÌ	LÌLÌL$	N)ztext/html; charset=utf-8)Ú__name__Ú
__module__Ú__qualname__r   r   r-   r:   rr   r   r   r   r   r   8   s   „ òòóò7ó3r   r   Ú__main__r<   i¼  T)Úexist_okz0.0.0.0z%Pak Otto Upload Server jalan di port zFolder: r	   z & r
   zAkses: http://100.79.230.61:rN   )Ú__doc__r4   rX   ÚsysrH   ÚuuidÚhttp.serverr   r   Úurllib.parser   r   ÚROOTr   r_   r[   r   r7   r   rs   r&   ÚargvrO   ÚportÚvaluesÚdÚmakedirsÚsrvÚprintÚserve_foreverr   r   r   ú<module>r†      s#  ðñ÷ × Ó ß Cß +à1€à�W‰W�\‰\˜$Ð 0Ó1Ø�W‰W�\‰\˜$Ð 0Ó1ñ€ð 	€ð€ôBQÐ$ô Qðf ˆzÒÙ" 3§8¡8›}¨qÒ0‰3ˆs�x‰x˜‰{Ô°d€DØ�[‰[‹]ò &ˆØˆ�‰�A Ö%ð&á
˜y¨$Ð/°Ó
9€CÙ	Ð1°$°Ð
8Ô9Ù	ˆH�T˜'‘]�O 3 t¨G¡} oÐ
6Ô7Ù	Ð(¨¨¨d°5°'Ð
:Ô;Ø×ÑÕð r   