http_client.py 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876
  1. # (c) J.Y.Amihud 2023
  2. # GPL-3 or any later version
  3. import os
  4. import json
  5. import zlib
  6. import time
  7. import fnmatch
  8. import threading
  9. import hashlib
  10. import urllib.request
  11. import urllib.parse
  12. import subprocess
  13. # GTK module ( Graphical interface
  14. import gi
  15. gi.require_version('Gtk', '3.0')
  16. from gi.repository import Gtk
  17. from gi.repository import GLib
  18. from gi.repository import Gdk
  19. import cairo
  20. # Own modules
  21. from settings import settings
  22. from settings import fileformats
  23. from settings import talk
  24. from project_manager import pm_project
  25. #UI modules
  26. from UI import UI_elements
  27. from UI import UI_color
  28. from UI import UI_math
  29. from studio import story
  30. from studio import analytics
  31. # This is a http client. To work on projects remotely.
  32. def csize(x):
  33. x = float(x)
  34. l = ["B","KB", "MB", "GB", "TB"]
  35. for i in range(5):
  36. if x > 1024:
  37. x = x / 1024
  38. else:
  39. return str(round(x, 2))+" "+l[i]
  40. return str(round(x, 2))+" "+l[i]
  41. def go(win, website, path):
  42. url = website+path
  43. print("url", url)
  44. response = urllib.request.urlopen(url)
  45. data = response.read()
  46. text = data.decode("utf-8")
  47. data = json.loads(text)
  48. return data
  49. def down(win, website, filename, fsize=100000):
  50. # If it is a blend file, we are in trouble.
  51. # if filename.endswith(".blend"):
  52. # dp = go(win, website, "/blend"+filename)
  53. # dplen = len(dp.get("files", {}))
  54. # for f in dp.get("files", {}):
  55. # try:
  56. # hashis = hashlib.md5(open(win.project+f,'rb').read()).hexdigest()
  57. # except:
  58. # hashis = ""
  59. # if hashis != dp.get("files", {}).get(f, {}).get("md5"):
  60. # win.current["http-server"]["message"] = f[f.rfind("/")+1:]
  61. # filesize = dp.get("files", {}).get(f, {}).get("filesize")
  62. # print("trying to get:", f)
  63. # pp = down(win, website, f, filesize)
  64. # Making folder for the files
  65. try:
  66. os.makedirs(win.project+filename[:filename.rfind("/")+1])
  67. except:
  68. pass
  69. # downloading the file
  70. url = website+"/download_z"+filename
  71. response = urllib.request.urlopen(url)
  72. for line in str(response.info()).split("\n"):
  73. if line.startswith("Content-length: "):
  74. try:
  75. fsize = int(line[line.find(" ")+1:])
  76. except:
  77. pass
  78. savef = open(win.project+filename, "wb")
  79. zd = b""
  80. sofar = 0
  81. chunk = response.read(8192)
  82. while chunk:
  83. zd = zd + chunk
  84. chunk = response.read(8192)
  85. sofar = sofar + 8192
  86. win.current["http-server"]["message"] = filename[filename.rfind("/")+1:]
  87. win.current["http-server"]["fileprog"] = sofar / fsize
  88. unz = zlib.decompress(zd)
  89. savef.write(unz)
  90. savef.close()
  91. def download_missing_changed(win, cur, call):
  92. # This function downloads files from remote server using the
  93. # remote-folder-data data.
  94. website = win.analytics["remote-server-url"]
  95. for t in ["missing", "changed"]:
  96. while win.current["remote-folder-data"][cur][t]: # IDK WHAT I'M DOING!!!
  97. try:
  98. for f in win.current["remote-folder-data"][cur][t]:
  99. fdata = win.current["remote-folder-data"][cur][t][f]
  100. if fdata.get("to_download", True):
  101. print("Downloading", f)
  102. try:
  103. down(win, website, f, fdata.get("filesize", 10000))
  104. except Exception as e:
  105. print(e)
  106. del win.current["remote-folder-data"][cur][t][f]
  107. except:
  108. pass
  109. win.current["remote-folder-data"][cur]["downloading"] = False
  110. win.current["calls"][call]["var"] = False
  111. def get_folder_info(win, folders, cur):
  112. # This function gets an information of what files should be changed. And outputs
  113. # the found data into the the global win thing, so it could accessed later.
  114. # Making sure we have the infrastructure.
  115. print("Getting Update Info About Folders")
  116. website = win.analytics["remote-server-url"]
  117. if "remote-folder-data" not in win.current:
  118. win.current["remote-folder-data"] = {}
  119. if cur not in win.current["remote-folder-data"]:
  120. win.current["remote-folder-data"][cur] = {"missing":{},
  121. "changed":{}}
  122. win.current["remote-folder-data"][cur]["loaded"] = False
  123. def sort_file(filename, files, f, filedata=None):
  124. if not filedata:
  125. filedata = files.get(f, {})
  126. filedata["finished"] = False
  127. try:
  128. hashis = hashlib.md5(open(win.project+filename,'rb').read()).hexdigest()
  129. except:
  130. hashis = ""
  131. if not os.path.exists(win.project+filename):
  132. win.current["remote-folder-data"][cur]["missing"][filename] = filedata
  133. elif hashis != filedata.get("md5"):
  134. filedata["to_download"] = True
  135. win.current["remote-folder-data"][cur]["changed"][filename] = filedata
  136. # Part one: Getting all the data about the files.
  137. for foldername in folders:
  138. try:
  139. answer = go(win, website, "/list"+foldername)
  140. files = list(answer.get("files", {}).keys())
  141. for f in fnmatch.filter(files, folders.get(foldername, "*")):
  142. # Now we need to figure out whether we have the file
  143. # , whether we don't even have it ,
  144. # or whether we have a different version.
  145. fullfilename = foldername+"/"+f
  146. sort_file(fullfilename, answer.get("files", {}), f)
  147. except Exception as e:
  148. error = "Error: "+ str(e)
  149. print(error)
  150. # Part two: Unwrapping all the blend dependancies data.
  151. # Here we are going to store blend file that were checked already.
  152. win.current["remote-folder-data"][cur]["blend_checked"] = []
  153. # A function checking if we still have some unchecked .blends
  154. def not_checked():
  155. for t in ["missing", "changed"]:
  156. for i in win.current["remote-folder-data"][cur][t]:
  157. if i not in win.current["remote-folder-data"][cur]["blend_checked"] and i.endswith(".blend"):
  158. return i
  159. return False
  160. nc = not_checked()
  161. while nc:
  162. try:
  163. dp = go(win, website, "/blend"+nc)
  164. for f in dp.get("files", {}):
  165. try:
  166. sort_file(f,
  167. dp.get("files", {}),
  168. f[f.rfind("/")+1:],
  169. filedata=dp.get("files", {})[f])
  170. except Exception as e:
  171. print(e)
  172. except Exception as e:
  173. print(e)
  174. win.current["remote-folder-data"][cur]["blend_checked"].append(nc)
  175. nc = not_checked()
  176. for t in ["missing", "changed"]:
  177. print(t+":")
  178. for i in win.current["remote-folder-data"][cur][t]:
  179. print(" "+i)
  180. win.current["remote-folder-data"][cur]["loaded"] = True
  181. def get_folders(win):
  182. # This function will get specified subfolders
  183. win.current["http-server"]["message"] = "Getting Remote Folders"
  184. folder = win.current["http-server"]["args"]
  185. website = win.analytics["remote-server-url"]
  186. call = win.current["http-server"]["call"]
  187. try:
  188. answer = go(win, website, "/list"+folder)
  189. for n, i in enumerate(answer.get("folders", [])):
  190. win.current["http-server"]["progress"] = n/len(answer.get("folders", []))
  191. win.current["http-server"]["message"] = i
  192. try:
  193. os.makedirs(win.project+folder+"/"+i)
  194. except:
  195. pass
  196. except Exception as e:
  197. error = "Error: "+ str(e)
  198. print(error)
  199. win.current["http-server"]["message"] = error
  200. time.sleep(1)
  201. # Ending the process
  202. win.current["calls"][call]["var"] = False
  203. def get_asset_files(win):
  204. # This function will get specified subfolders
  205. win.current["http-server"]["message"] = "Getting / Updating Files"
  206. folder = win.current["http-server"]["args"]
  207. website = win.analytics["remote-server-url"]
  208. call = win.current["http-server"]["call"]
  209. folder = folder.replace("//", "/")
  210. if folder.endswith("/"):
  211. folder = folder[:-1]
  212. try:
  213. answer = go(win, website, "/list"+folder)
  214. for n, i in enumerate(answer.get("files", [])):
  215. win.current["http-server"]["progress"] = n/len(answer.get("files", []))
  216. win.current["http-server"]["message"] = i
  217. filename = folder+"/"+i
  218. try:
  219. hashis = hashlib.md5(open(win.project+filename,'rb').read()).hexdigest()
  220. except:
  221. hashis = ""
  222. if hashis != answer.get("files", {}).get(i, {}).get("md5"):
  223. filesize = answer.get("files", {}).get(i, {}).get("filesize")
  224. down(win, website, filename, filesize)
  225. win.current["http-server"]["message"] = "Getting Thumbnail"
  226. other_folder = folder+"/renders"
  227. print("otherfolder 1", other_folder)
  228. answer = go(win, website, "/list"+other_folder)
  229. for n, i in enumerate(answer.get("files", [])):
  230. win.current["http-server"]["progress"] = n/len(answer.get("files", []))
  231. win.current["http-server"]["message"] = i
  232. if i.startswith("Preview"):
  233. print("getting", i)
  234. filename = other_folder+"/"+i
  235. try:
  236. hashis = hashlib.md5(open(win.project+filename,'rb').read()).hexdigest()
  237. except:
  238. hashis = ""
  239. if hashis != answer.get("files", {}).get(i, {}).get("md5"):
  240. filesize = answer.get("files", {}).get(i, {}).get("filesize")
  241. down(win, website, filename, filesize)
  242. win.current["http-server"]["message"] = "Getting Asset Blend"
  243. other_folder = folder[:folder.rfind("/")+1].replace("/dev/", "/ast/")
  244. print("otherfolder 2", other_folder, folder)
  245. answer = go(win, website, "/list"+other_folder)
  246. for n, i in enumerate(answer.get("files", [])):
  247. win.current["http-server"]["progress"] = n/len(answer.get("files", []))
  248. win.current["http-server"]["message"] = i
  249. if i.startswith(folder[folder.rfind("/")+1:]):
  250. print("getting", i)
  251. filename = other_folder+"/"+i
  252. try:
  253. hashis = hashlib.md5(open(win.project+filename,'rb').read()).hexdigest()
  254. except:
  255. hashis = ""
  256. if hashis != answer.get("files", {}).get(i, {}).get("md5"):
  257. filesize = answer.get("files", {}).get(i, {}).get("filesize")
  258. down(win, website, filename, filesize)
  259. except Exception as e:
  260. error = "Error: "+ str(e)
  261. print(error)
  262. win.current["http-server"]["message"] = error
  263. time.sleep(1)
  264. # Ending the process
  265. win.current["calls"][call]["var"] = False
  266. def get_files(win):
  267. # This function will get specified subfolders
  268. win.current["http-server"]["message"] = "Getting / Updating Files"
  269. folder = win.current["http-server"]["args"]
  270. website = win.analytics["remote-server-url"]
  271. call = win.current["http-server"]["call"]
  272. try:
  273. answer = go(win, website, "/list"+folder)
  274. for n, i in enumerate(answer.get("files", [])):
  275. win.current["http-server"]["progress"] = n/len(answer.get("files", []))
  276. win.current["http-server"]["message"] = i
  277. filename = folder+"/"+i
  278. try:
  279. hashis = hashlib.md5(open(win.project+filename,'rb').read()).hexdigest()
  280. except:
  281. print("missing", filename)
  282. hashis = ""
  283. if hashis != answer.get("files", {}).get(i, {}).get("md5"):
  284. filesize = answer.get("files", {}).get(i, {}).get("filesize")
  285. down(win, website, filename, filesize)
  286. except Exception as e:
  287. error = "Error: "+ str(e)
  288. print(error)
  289. win.current["http-server"]["message"] = error
  290. time.sleep(1)
  291. # Ending the process
  292. win.current["calls"][call]["var"] = False
  293. def get_essentials(win):
  294. # This function will get essential parts of the project.
  295. # Essentials are: Story, Analitycs, Project.progress and Banner Image.
  296. essentials = [
  297. "/pln/story.vcss",
  298. "/set/analytics.json",
  299. "/set/project.progress",
  300. "/set/banner.png"]
  301. website = win.analytics["remote-server-url"]
  302. call = win.current["http-server"]["call"]
  303. for n, i in enumerate(essentials):
  304. win.current["http-server"]["progress"] = n/len(essentials)
  305. win.current["http-server"]["message"] = i
  306. try:
  307. down(win, website, i)
  308. except Exception as e:
  309. error = "Error: "+ str(e)
  310. print(error)
  311. win.current["http-server"]["message"] = error
  312. time.sleep(1)
  313. win.story = story.load(win.project)
  314. win.analytics = analytics.load(win.project)
  315. win.analytics["remote-server-url"] = website
  316. win.analytics["from-remote-server"] = True
  317. analytics.save(win.project, win.analytics)
  318. # Ending the process
  319. win.current["calls"][call]["var"] = False
  320. def layer(win, call):
  321. # Making the layer
  322. surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, win.current['w'],
  323. win.current['h'])
  324. layer = cairo.Context(surface)
  325. #text setting
  326. layer.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
  327. UI_color.set(layer, win, "dark_overdrop")
  328. layer.rectangle(
  329. 0,
  330. 0,
  331. win.current["w"],
  332. win.current["h"],
  333. )
  334. layer.fill()
  335. # So it's going to be like a little window in the center of the VCStudio
  336. # with a simple UI. Probably like 2 things. Folder and a projectname.
  337. UI_color.set(layer, win, "node_background")
  338. UI_elements.roundrect(layer, win,
  339. win.current["w"]/2-250,
  340. win.current["h"]/2-60,
  341. 500,
  342. 150,
  343. 10)
  344. # Title of the operation. Incase the user forgot.
  345. UI_elements.text(layer, win, "scan_project_title",
  346. win.current["w"]/2-250,
  347. win.current["h"]/2-35,
  348. 500,
  349. 30,
  350. 10,
  351. fill=False,
  352. centered=True,
  353. editable=False)
  354. win.text["scan_project_title"]["text"] = win.current["http-server"]["message"]
  355. # File Progressbar
  356. UI_color.set(layer, win, "progress_background")
  357. UI_elements.roundrect(layer, win,
  358. win.current["w"]/2-200,
  359. win.current["h"]/2+10,
  360. 400,
  361. 20,
  362. 10,
  363. tip="Hello")
  364. UI_color.set(layer, win, "progress_active")
  365. UI_elements.roundrect(layer, win,
  366. win.current["w"]/2-200,
  367. win.current["h"]/2+10,
  368. 400*max(0, min(1, win.current["http-server"]["fileprog"])),
  369. 20,
  370. 10,)
  371. # Progressbar
  372. UI_color.set(layer, win, "progress_background")
  373. UI_elements.roundrect(layer, win,
  374. win.current["w"]/2-200,
  375. win.current["h"]/2+40,
  376. 400,
  377. 20,
  378. 10,
  379. tip="Hello")
  380. UI_color.set(layer, win, "progress_active")
  381. UI_elements.roundrect(layer, win,
  382. win.current["w"]/2-200,
  383. win.current["h"]/2+40,
  384. 400*max(0, min(1, win.current["http-server"]["progress"])),
  385. 20,
  386. 10,)
  387. return surface
  388. def prompt_layer(win, call):
  389. # Making the layer
  390. surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, win.current['w'],
  391. win.current['h'])
  392. layer = cairo.Context(surface)
  393. #text setting
  394. layer.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
  395. UI_color.set(layer, win, "dark_overdrop")
  396. layer.rectangle(
  397. 0,
  398. 0,
  399. win.current["w"],
  400. win.current["h"],
  401. )
  402. layer.fill()
  403. # So it's going to be like a little window in the center of the VCStudio
  404. # with a simple UI. Probably like 2 things. Folder and a projectname.
  405. UI_color.set(layer, win, "node_background")
  406. UI_elements.roundrect(layer, win,
  407. win.current["w"]/2-350,
  408. 100,
  409. 700,
  410. win.current["h"]-200,
  411. 10)
  412. cur = win.current["remote-folder-data"]["prompt"]
  413. if "downloading" not in win.current["remote-folder-data"][cur]:
  414. win.current["remote-folder-data"][cur]["downloading"] = False
  415. if not win.current["remote-folder-data"][cur]["downloading"]:
  416. # Exit button
  417. def do():
  418. win.current["calls"][call]["var"] = False
  419. UI_elements.roundrect(layer, win,
  420. win.current["w"]/2+310,
  421. win.current["h"]-140,
  422. 40,
  423. 40,
  424. 10,
  425. button=do,
  426. icon="cancel",
  427. tip=talk.text("cancel"))
  428. # Download button
  429. if win.current["remote-folder-data"][cur]["loaded"]:
  430. def do():
  431. win.current["remote-folder-data"][cur]["downloading"] = True
  432. start_downaloding = threading.Thread(target=download_missing_changed,
  433. args=(win, cur, call, ))
  434. start_downaloding.setDaemon(True)
  435. start_downaloding.start()
  436. UI_elements.roundrect(layer, win,
  437. win.current["w"]/2+270,
  438. win.current["h"]-140,
  439. 40,
  440. 40,
  441. 10,
  442. button=do,
  443. icon="download",
  444. tip=talk.text("DownloadRemoteServer"))
  445. else:
  446. UI_color.set(layer, win, "text_normal")
  447. layer.set_font_size(15)
  448. layer.move_to(win.current["w"]/2,
  449. win.current["h"]-120,)
  450. layer.show_text(talk.text("StillLoadingRemoteData"))
  451. else:
  452. # Progress bar
  453. UI_color.set(layer, win, "progress_background")
  454. UI_elements.roundrect(layer, win,
  455. win.current["w"]/2-200,
  456. win.current["h"]-140,
  457. 400,
  458. 20,
  459. 10,
  460. tip="Hello")
  461. UI_color.set(layer, win, "progress_active")
  462. UI_elements.roundrect(layer, win,
  463. win.current["w"]/2-200,
  464. win.current["h"]-140,
  465. 400*max(0, min(1, win.current["http-server"]["fileprog"])),
  466. 20,
  467. 10,)
  468. UI_color.set(layer, win, "text_normal")
  469. layer.set_font_size(15)
  470. layer.move_to(win.current["w"]/2-180,
  471. win.current["h"]-145)
  472. layer.show_text(win.current["http-server"]["message"])
  473. # Top Tabs
  474. if "active_tab" not in win.current["remote-folder-data"][cur]:
  475. win.current["remote-folder-data"][cur]["active_tab"] = "changed"
  476. # Missing
  477. def do():
  478. win.current["remote-folder-data"][cur]["active_tab"] = "missing"
  479. if win.current["remote-folder-data"][cur]["active_tab"] == "missing":
  480. UI_color.set(layer, win, "progress_time")
  481. UI_elements.roundrect(layer, win,
  482. win.current["w"]/2-340,
  483. 110,
  484. 330,
  485. 40,
  486. 10)
  487. UI_elements.roundrect(layer, win,
  488. win.current["w"]/2-340,
  489. 110,
  490. 330,
  491. 40,
  492. 10,
  493. button=do,
  494. icon="new_file",
  495. tip=talk.text("MissingFiles"))
  496. UI_color.set(layer, win, "text_normal")
  497. layer.set_font_size(20)
  498. layer.move_to(win.current["w"]/2-290,
  499. 135)
  500. layer.show_text(str(len(win.current["remote-folder-data"][cur]["missing"]))+" "+talk.text("MissingFiles"))
  501. # Changed
  502. def do():
  503. win.current["remote-folder-data"][cur]["active_tab"] = "changed"
  504. if win.current["remote-folder-data"][cur]["active_tab"] == "changed":
  505. UI_color.set(layer, win, "progress_time")
  506. UI_elements.roundrect(layer, win,
  507. win.current["w"]/2+10,
  508. 110,
  509. 330,
  510. 40,
  511. 10)
  512. UI_elements.roundrect(layer, win,
  513. win.current["w"]/2+10,
  514. 110,
  515. 330,
  516. 40,
  517. 10,
  518. button=do,
  519. icon="configure_file",
  520. tip=talk.text("ChangedFiles"))
  521. UI_color.set(layer, win, "text_normal")
  522. layer.set_font_size(20)
  523. layer.move_to(win.current["w"]/2+60,
  524. 135)
  525. layer.show_text(str(len(win.current["remote-folder-data"][cur]["changed"]))+" "+talk.text("ChangedFiles"))
  526. # Search
  527. UI_elements.image(layer, win, "settings/themes/"\
  528. +win.settings["Theme"]+"/icons/search.png",
  529. win.current["w"]/2,
  530. 160,
  531. 40,
  532. 40)
  533. UI_elements.text(layer, win, "http_client_search",
  534. win.current["w"]/2+50,
  535. 160,
  536. 250,
  537. 40)
  538. # Toggle Visible
  539. if "toggle_visible" not in win.current["remote-folder-data"][cur]:
  540. win.current["remote-folder-data"][cur]["toggle_visible"] = True
  541. toggle = {"do":None}
  542. def do():
  543. win.current["remote-folder-data"][cur]["toggle_visible"] = not win.current["remote-folder-data"][cur]["toggle_visible"]
  544. toggle["do"] = win.current["remote-folder-data"][cur]["toggle_visible"]
  545. icon = "unchecked"
  546. if win.current["remote-folder-data"][cur]["toggle_visible"]:
  547. icon = "checked"
  548. UI_elements.roundrect(layer, win,
  549. win.current["w"]/2-340,
  550. 160,
  551. 330,
  552. 40,
  553. 10,
  554. button=do,
  555. icon=icon,
  556. tip=talk.text("ToggleVisible"))
  557. UI_color.set(layer, win, "text_normal")
  558. layer.set_font_size(20)
  559. layer.move_to(win.current["w"]/2-290,
  560. 185)
  561. layer.show_text(talk.text("ToggleVisible"))
  562. # Clipping everything
  563. UI_elements.roundrect(layer, win,
  564. win.current["w"]/2-350,
  565. 200,
  566. 700,
  567. win.current["h"]-360,
  568. 10,
  569. fill=False)
  570. layer.clip()
  571. clip = [
  572. win.current["w"]/2-350,
  573. 200,
  574. 700,
  575. win.current["h"]-360]
  576. # Setting up the scroll
  577. if "http-prompt" not in win.scroll:
  578. win.scroll["http-prompt"] = 0
  579. current_Y = 100
  580. # Display list
  581. DisplayList = {}
  582. ActiveTab = win.current["remote-folder-data"][cur]["active_tab"]
  583. DisplayList = win.current["remote-folder-data"][cur][ActiveTab]
  584. try:
  585. for f in DisplayList:
  586. fdata = DisplayList[f]
  587. if fdata.get("finished"):
  588. continue
  589. if win.text["http_client_search"]["text"] and not UI_math.found(f, win.text["http_client_search"]["text"]):
  590. continue
  591. ticon = "unchecked"
  592. if fdata.get("to_download", True):
  593. ticon = "checked"
  594. if toggle["do"] != None:
  595. fdata["to_download"] = toggle["do"]
  596. def do():
  597. fdata["to_download"] = not fdata.get("to_download", True)
  598. # Filetype icon
  599. ext = f[f.rfind(".")+1:]
  600. if ext in fileformats.images:
  601. icon = "image"
  602. elif ext in fileformats.videos:
  603. icon = "video"
  604. elif ext in fileformats.sounds:
  605. icon = "mus"
  606. elif ext == "blend":
  607. icon = "blender"
  608. elif ext == "progress":
  609. icon = "checklist"
  610. else:
  611. icon = "file"
  612. UI_elements.roundrect(layer, win,
  613. win.current["w"]/2-315,
  614. 110 + current_Y + win.scroll["http-prompt"],
  615. 660,
  616. 40,
  617. 10,
  618. button=do,
  619. icon=ticon,
  620. tip=f)
  621. UI_elements.image(layer, win, "settings/themes/"+win.settings["Theme"]+"/icons/"+icon+".png",
  622. win.current["w"]/2-275,
  623. 110 + current_Y + win.scroll["http-prompt"],
  624. 40,
  625. 40)
  626. UI_color.set(layer, win, "text_normal")
  627. layer.set_font_size(20)
  628. layer.move_to(win.current["w"]/2-220,
  629. current_Y + win.scroll["http-prompt"] + 135)
  630. layer.show_text(f[f.rfind("/")+1:])
  631. current_Y += 50
  632. except Exception as e:
  633. print(e)
  634. pass
  635. UI_elements.scroll_area(layer, win, "http-prompt",
  636. int(win.current["w"]/2-350),
  637. 200,
  638. 700,
  639. win.current["h"]-360,
  640. current_Y,
  641. bar=True,
  642. mmb=True,
  643. url="http-server-prompt"
  644. )
  645. return surface