__init__.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. # -*- coding: utf-8 -*-
  2. """
  3. Package /home/cpi/games/xxx/yyy.zip ,only support in zip
  4. com_pkg_info /home/cpi/launcher/Menu/GameShell/xxxx/compkginfo.json
  5. use https://jsonlint.com/ to validate first in case syntax err
  6. ```
  7. {
  8. "NotFoundMsg":["Please Go to \n|None|varela14|True",
  9. "https://www.lexaloffle.com/pico-8.php|URL|None|True|True",
  10. "buy a pico-8 raspi and put zip into \n/home/cpi/games/PICO-8"]
  11. "MD5":{"pico-8_0.1.11g_raspi.zip":"a3f2995cf117499f880bd964d6a0e1f2","pico-8_0.1.11g_amd64.zip":"6726141c784afd4a41be6b7414c1b932"}
  12. }
  13. ```
  14. """
  15. import pygame
  16. #import validators
  17. import os
  18. import commands
  19. from UI.constants import Width,Height,ICON_TYPES,RUNEVT,RESTARTUI
  20. #from UI.simple_name_space import SimpleNamespace
  21. from UI.page import Page
  22. from UI.label import Label
  23. from UI.fonts import fonts
  24. from UI.icon_item import IconItem
  25. from UI.icon_pool import MyIconPool
  26. from UI.keys_def import CurKeys
  27. from UI.skin_manager import MySkinManager
  28. from UI.lang_manager import MyLangManager
  29. from UI.text_bulletinboard import Textbulletinboard,Text
  30. from UI.util_funcs import FileExists
  31. class NotFoundPage(Page):
  32. _FootMsg = ["Nav","","","Back",""]
  33. _BG = "pico8_notfound"
  34. _Leader = None
  35. _Padding = pygame.Rect(0,20,0,0)
  36. def Init(self):
  37. self._PosX = self._Index*self._Screen._Width
  38. self._Width = self._Screen._Width
  39. self._Height = self._Screen._Height
  40. self._CanvasHWND = self._Screen._CanvasHWND
  41. self._BGpng = IconItem()
  42. self._BGpng._ImgSurf = MyIconPool._Icons[self._BG]
  43. self._BGpng._MyType = ICON_TYPES["STAT"]
  44. self._BGpng._Parent = self
  45. #print( MyIconPool.Width(self._BG),MyIconPool.Height(self._BG) )
  46. self._BGpng.Adjust(0,0,MyIconPool.Width(self._BG),MyIconPool.Height(self._BG),0)
  47. self._Board = Textbulletinboard()
  48. self._Board._PosX = 4
  49. self._Board._PosY = 100
  50. self._Board._Width= self._Width - 4*2
  51. self._Board._Height = 100
  52. self._Board._CanvasHWND = self._CanvasHWND
  53. self._Board._Align = "Center"
  54. self._Board._RowPitch =30
  55. self._Board.Init()
  56. if self._Leader!= None and self._Leader._ComPkgInfo != None:
  57. if "NotFoundMsg" in self._Leader._ComPkgInfo:
  58. d = []
  59. for i, v in enumerate(self._Leader._ComPkgInfo["NotFoundMsg"]):
  60. Color = None
  61. Font = None
  62. Bold = False
  63. Und = False
  64. Txt = ""
  65. parts = v.split("|")
  66. if len(parts) > 0:
  67. Txt = parts[0]
  68. if len(parts) == 2:
  69. if parts[1] != "None":
  70. Color = MySkinManager.GiveColor(parts[1])
  71. elif len(parts) == 3:
  72. if parts[1] != "None":
  73. Color = MySkinManager.GiveColor(parts[1])
  74. if parts[2] != "None":
  75. Font = MyLangManager.TrFont(parts[2])
  76. elif len(parts) == 4:
  77. if parts[1] != "None":
  78. Color = MySkinManager.GiveColor(parts[1])
  79. if parts[2] != "None":
  80. Font = MyLangManager.TrFont(parts[2])
  81. if parts[3] == "True":
  82. Bold = True
  83. elif len(parts) == 5:
  84. if parts[1] != "None":
  85. Color = MySkinManager.GiveColor(parts[1])
  86. if parts[2] != "None":
  87. Font = MyLangManager.TrFont(parts[2])
  88. if parts[3] == "True":
  89. Bold = True
  90. if parts[4] == "True":
  91. Und = True
  92. a = Text(Txt,Color,Font,Bold,Und)
  93. d = d + a.Words()
  94. self._Board.SetAndBlitText(d)
  95. def KeyDown(self,event):
  96. if event.key == CurKeys["A"] or event.key == CurKeys["Menu"]:
  97. self.ReturnToUpLevelPage()
  98. self._Screen.Draw()
  99. self._Screen.SwapAndShow()
  100. return
  101. def Draw(self):
  102. self.ClearCanvas()
  103. if self._BGpng != None:
  104. self._BGpng.NewCoord((self._Width-self._BGpng._Width)/2,self._Padding.y )
  105. self._BGpng.DrawTopLeft()
  106. self._Board._PosY = self._BGpng._Height+self._Padding.y
  107. else:
  108. self._Board._PosY = self._Padding.y
  109. self._Board.Draw()
  110. class HashErrPage(Page):
  111. _FootMsg = ["Nav","","","Cancel","Continue"]
  112. _BG ="pico8_md5_err"
  113. _Leader = None
  114. _Padding = pygame.Rect(0,20,0,0)
  115. def Init(self):
  116. self._PosX = self._Index*self._Screen._Width
  117. self._Width = self._Screen._Width
  118. self._Height = self._Screen._Height
  119. self._CanvasHWND = self._Screen._CanvasHWND
  120. self._BGpng = IconItem()
  121. self._BGpng._ImgSurf = MyIconPool._Icons[self._BG]
  122. self._BGpng._MyType = ICON_TYPES["STAT"]
  123. self._BGpng._Parent = self
  124. self._BGpng.Adjust(0,0,MyIconPool.Width(self._BG),MyIconPool.Height(self._BG),0)
  125. self._Board = Textbulletinboard()
  126. self._Board._PosX = 4
  127. self._Board._PosY = self._Height/2 - 35
  128. self._Board._Width= self._Width - 4*2
  129. self._Board._Height = 100
  130. self._Board._CanvasHWND = self._CanvasHWND
  131. self._Board._RowPitch =30
  132. self._Board._Align = "Center"
  133. self._Board.Init()
  134. if self._Leader!= None and self._Leader._ComPkgInfo != None:
  135. if "HashErrMsg" in self._Leader._ComPkgInfo:
  136. d = []
  137. for i, v in enumerate(self._Leader._ComPkgInfo["HashErrMsg"]):
  138. Color = None
  139. Font = None
  140. Bold = False
  141. Und = False
  142. Txt = ""
  143. parts = v.split("|")
  144. if len(parts) > 0:
  145. Txt = parts[0]
  146. if len(parts) == 2:
  147. if parts[1] != "None":
  148. Color = MySkinManager.GiveColor(parts[1])
  149. elif len(parts) == 3:
  150. if parts[1] != "None":
  151. Color = MySkinManager.GiveColor(parts[1])
  152. if parts[2] != "None":
  153. Font = MyLangManager.TrFont(parts[2])
  154. elif len(parts) == 4:
  155. if parts[1] != "None":
  156. Color = MySkinManager.GiveColor(parts[1])
  157. if parts[2] != "None":
  158. Font = MyLangManager.TrFont(parts[2])
  159. if parts[3] == "True":
  160. Bold = True
  161. elif len(parts) == 5:
  162. if parts[1] != "None":
  163. Color = MySkinManager.GiveColor(parts[1])
  164. if parts[2] != "None":
  165. Font = MyLangManager.TrFont(parts[2])
  166. if parts[3] == "True":
  167. Bold = True
  168. if parts[4] == "True":
  169. Und = True
  170. a = Text(Txt,Color,Font,Bold,Und)
  171. d = d + a.Words()
  172. self._Board.SetAndBlitText(d)
  173. else:
  174. a = Text("MD5 check Failed!\n",None,MyLangManager.TrFont("varela16"))
  175. b = Text("Do you want to continue?",None,MyLangManager.TrFont("varela16"))
  176. self._Board.SetAndBlitText(a.Words()+b.Words())
  177. def KeyDown(self,event):
  178. if event.key == CurKeys["A"] or event.key == CurKeys["Menu"]:
  179. self.ReturnToUpLevelPage()
  180. self._Screen.Draw()
  181. self._Screen.SwapAndShow()
  182. return
  183. if event.key == CurKeys["B"]:
  184. self._Leader.InstallPackage(self._Screen)
  185. return
  186. def OnLoadCb(self):
  187. pass
  188. def Draw(self):
  189. self.ClearCanvas()
  190. if self._BGpng != None:
  191. self._BGpng.NewCoord((self._Width-self._BGpng._Width)/2,self._Padding.y)
  192. self._BGpng.DrawTopLeft()
  193. self._Board._PosY = self._BGpng._Height+self._Padding.y
  194. else:
  195. self._Board._PosY = self._Padding.y
  196. self._Board.Draw()
  197. class MyCommercialSoftwarePackage(object):
  198. _ComPkgInfo = None
  199. _Done = ""
  200. _InvokeDir = ""
  201. def __init__(self):
  202. pass
  203. def InstallPackage(self,main_screen):
  204. main_screen._MsgBox.SetText("Installing the package")
  205. main_screen._MsgBox.Draw()
  206. main_screen.SwapAndShow()
  207. json_config = self._ComPkgInfo
  208. cur_dir = os.getcwd()
  209. os.chdir(json_config["GameDir"])
  210. for i,v in enumerate(json_config["MD5"]):
  211. os.system("unzip -o %s" %v) ## auto overwrite
  212. if "Post-Up" in json_config:
  213. if FileExists(self._InvokeDir):
  214. os.chdir(self._InvokeDir)
  215. os.system(json_config["Post-Up"])
  216. os.chdir(cur_dir)
  217. pygame.time.delay(1000)
  218. main_screen._MsgBox.SetText("Package Installed")
  219. main_screen._MsgBox.Draw()
  220. main_screen.SwapAndShow()
  221. pygame.time.delay(500)
  222. pygame.event.post( pygame.event.Event(RESTARTUI, message=""))
  223. def VerifyPackage(self,main_screen):
  224. ## do unzip and check md5sum once
  225. main_screen._MsgBox.SetText("Verify the package")
  226. main_screen._MsgBox.Draw()
  227. main_screen.SwapAndShow()
  228. pygame.time.delay(400)
  229. Checked = False
  230. json_config = self._ComPkgInfo
  231. if json_config == None:
  232. return
  233. if "MD5" in json_config:
  234. for i,v in enumerate(json_config["MD5"]):
  235. print(i,v)
  236. if FileExists( os.path.join(json_config["GameDir"], v )):
  237. print( os.path.join(json_config["GameDir"],v ))
  238. out = commands.getstatusoutput("md5sum %s" % os.path.join(json_config["GameDir"],v))
  239. ret = out[1]
  240. ret = ret.split(" ")
  241. print(ret)
  242. if ret[0] == json_config["MD5"][v]:
  243. print("md5 is ok")
  244. Checked = True
  245. return Checked
  246. return Checked
  247. def Init(self,main_screen):
  248. self._Page1 = NotFoundPage()
  249. self._Page1._Name = "Not Found"
  250. self._Page1._Screen = main_screen
  251. self._Page1._Leader = self
  252. self._Page1.Init()
  253. self._Page2 = HashErrPage()
  254. self._Page2._Name = "Md5sum check failed"
  255. self._Page2._Screen = main_screen
  256. self._Page2._Leader = self
  257. self._Page2.Init()
  258. def API(self,main_screen):
  259. if main_screen !=None:
  260. if self._Done != "":
  261. main_screen._MsgBox.SetText("Starting")
  262. main_screen._MsgBox.Draw()
  263. main_screen.SwapAndShow()
  264. pygame.time.delay(300)
  265. ####
  266. pygame.event.post( pygame.event.Event(RUNEVT, message=self._Done))
  267. ####
  268. else:
  269. print(self._ComPkgInfo)
  270. if FileExists( os.path.join(self._ComPkgInfo["GameDir"],self._ComPkgInfo["InstallDir"] )) == False:
  271. main_screen.PushPage(self._Page1)
  272. main_screen.Draw()
  273. main_screen.SwapAndShow()
  274. else:
  275. if self.VerifyPackage(main_screen) == False:
  276. main_screen.PushPage(self._Page2)
  277. main_screen.Draw()
  278. main_screen.SwapAndShow()
  279. else:
  280. self.InstallPackage(main_screen)