__init__.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. # -*- coding: utf-8 -*-
  2. import os
  3. import pygame
  4. import platform
  5. #import commands
  6. import glob
  7. import json
  8. import gobject
  9. import sqlite3
  10. #from beeprint import pp
  11. from libs.roundrects import aa_round_rect
  12. ## local UI import
  13. from UI.constants import Width,Height,ICON_TYPES,RESTARTUI
  14. from UI.page import Page,PageSelector
  15. from UI.label import Label
  16. from UI.util_funcs import midRect,FileExists,ArmSystem
  17. from UI.keys_def import CurKeys, IsKeyStartOrA, IsKeyMenuOrB
  18. from UI.scroller import ListScroller
  19. from UI.icon_pool import MyIconPool
  20. from UI.icon_item import IconItem
  21. from UI.multilabel import MultiLabel
  22. from UI.skin_manager import MySkinManager
  23. from UI.lang_manager import MyLangManager
  24. from UI.info_page_list_item import InfoPageListItem
  25. from UI.info_page_selector import InfoPageSelector
  26. import config
  27. class RPCStack:
  28. def __init__(self):
  29. self.stack = list()
  30. def Push(self,data):
  31. if data not in self.stack:
  32. self.stack.append(data)
  33. return True
  34. return False
  35. def Pop(self):
  36. if len(self.stack)<=0:
  37. return None,False
  38. return self.stack.pop(),True
  39. def Last(self):
  40. idx = len(self.stack) -1
  41. if idx < 0:
  42. return None
  43. else:
  44. return self.stack[ idx ]
  45. def Length(self):
  46. return len(self.stack)
  47. class GameConfirmInstallPopupUpPage(Page):
  48. pass
  49. class Aria2DownloadProcessPage(Page):
  50. _FootMsg = ["Nav.","","Pause","Back","Cancel"]
  51. _DownloaderTimer = -1
  52. _Value = 0
  53. _GID = None
  54. _PngSize = {}
  55. _FileNameLabel = None
  56. _SizeLabel = None
  57. _URLColor = MySkinManager.GiveColor('URL')
  58. _TextColor = MySkinManager.GiveColor('Text')
  59. def __init__(self):
  60. Page.__init__(self)
  61. self._Icons = {}
  62. self._CanvasHWND = None
  63. def Init(self):
  64. self._PosX = self._Index * self._Screen._Width
  65. self._Width = self._Screen._Width
  66. self._Height = self._Screen._Height
  67. self._CanvasHWND = self._Screen._CanvasHWND
  68. bgpng = IconItem()
  69. bgpng._ImgSurf = MyIconPool.GiveIconSurface("rom_download")
  70. bgpng._MyType = ICON_TYPES["STAT"]
  71. bgpng._Parent = self
  72. bgpng.Adjust(0,0,self._PngSize["bg"][0],self._PngSize["bg"][1],0)
  73. self._Icons["bg"] = bgpng
  74. self._FileNameLabel = Label()
  75. self._FileNameLabel.SetCanvasHWND(self._CanvasHWND)
  76. self._FileNameLabel.Init("", MyLangManager.TrFont("varela12"))
  77. self._SizeLabel = Label()
  78. self._SizeLabel.SetCanvasHWND(self._CanvasHWND)
  79. self._SizeLabel.Init("0/0Kb",MyLangManager.TrFont("varela12"))
  80. self._SizeLabel.SetColor( self._URLColor )
  81. def GObjectUpdateProcessInterval(self):
  82. if self._Screen.CurPage() == self and self._GID is not None:
  83. self._Value = config.RPC.tellStatus(self._GID)
  84. downloaded = 0
  85. total = 0
  86. if self._Value["status"] == "waiting":
  87. self._FileNameLabel.SetText( "waiting to download..." )
  88. if self._Value["status"] == "paused":
  89. self._FileNameLabel.SetText( "download paused..." )
  90. if self._Value["status"] == "error":
  91. self._FileNameLabel.SetText("download errors,cancel it please")
  92. if self._Value["status"] == "active":
  93. downloaded = self._Value["completedLength"]
  94. total = self._Value["totalLength"]
  95. downloaded = downloaded/1000.0/1000.0
  96. total = total/1000.0/1000.0
  97. self._SizeLabel.SetText( "%.2f" % downloaded+"/"+ "%.2f" % total +"Mb")
  98. print("Progress: %d%%" % (self._Value))
  99. self._Screen.Draw()
  100. self._Screen.SwapAndShow()
  101. return True
  102. else:
  103. return False
  104. def CheckDownload(self,aria2_gid):
  105. self._GID = aria2_gid
  106. self._DownloaderTimer = gobject.timeout_add(123, self.GObjectUpdateProcessInterval)
  107. def KeyDown(self,event):
  108. if IsKeyMenuOrB(event.key):
  109. gobject.source_remove(self._DownloaderTimer)
  110. self._DownloaderTimer = -1
  111. #if self._Downloader != None:
  112. # try:
  113. # self._Downloader.stop()
  114. # except:
  115. # print("user canceled ")
  116. self.ReturnToUpLevelPage()
  117. self._Screen.Draw()
  118. self._Screen.SwapAndShow()
  119. def Draw(self):
  120. self.ClearCanvas()
  121. self._Icons["bg"].NewCoord(self._Width/2,self._Height/2-20)
  122. self._Icons["bg"].Draw()
  123. percent = self._Value
  124. if percent < 10:
  125. percent = 10
  126. rect_ = midRect(self._Width/2,self._Height/2+33,170,17, Width,Height)
  127. aa_round_rect(self._CanvasHWND,rect_,MySkinManager.GiveColor('TitleBg'),5,0,MySkinManager.GiveColor('TitleBg'))
  128. rect2 = midRect(self._Width/2,self._Height/2+33,int(170*(percent/100.0)),17, Width,Height)
  129. rect2.left = rect_.left
  130. rect2.top = rect_.top
  131. aa_round_rect(self._CanvasHWND,rect2,MySkinManager.GiveColor('Front'),5,0,MySkinManager.GiveColor('Front'))
  132. rect3 = midRect(self._Width/2,self._Height/2+53,self._FileNameLabel._Width, self._FileNameLabel._Height,Width,Height)
  133. rect4 = midRect(self._Width/2,self._Height/2+70,self._SizeLabel._Width, self._SizeLabel._Height,Width,Height)
  134. self._FileNameLabel.NewCoord(rect3.left,rect3.top)
  135. self._SizeLabel.NewCoord(rect4.left, rect4.top)
  136. self._FileNameLabel.Draw()
  137. self._SizeLabel.Draw()
  138. def dict_factory(cursor, row):
  139. d = {}
  140. for idx, col in enumerate(cursor.description):
  141. d[col[0]] = row[idx]
  142. return d
  143. class GameStorePage(Page):
  144. _FootMsg = ["Nav","","Up","Back","Select"]
  145. _MyList = []
  146. _ListFont = MyLangManager.TrFont("notosanscjk12")
  147. _AList = {}
  148. _Scrolled = 0
  149. _BGwidth = 320
  150. _BGheight = 240-24-20
  151. _DrawOnce = False
  152. _Scroller = None
  153. _InfoPage = None
  154. _Downloading = None
  155. def __init__(self):
  156. Page.__init__(self)
  157. self._Icons = {}
  158. self._MyStack = RPCStack()
  159. #title path type
  160. repos = [
  161. {"title":"github.com/cuu/gamestore","file":"https://raw.githubusercontent.com/cuu/gamestore/master/index.json","type":"dir"}
  162. ]
  163. self._MyStack.Push(repos)
  164. def SyncSqlite(self):
  165. try:
  166. conn = sqlite3.connect("aria2tasks.db")
  167. conn.row_factory = dict_factory
  168. c = conn.cursor()
  169. ret = c.execute("SELECT * FROM tasks").fetchall()
  170. conn.close()
  171. return ret
  172. except Exception as ex:
  173. print(ex)
  174. return None
  175. return None
  176. def SyncList(self):
  177. self._MyList = []
  178. start_x = 0
  179. start_y = 0
  180. last_height = 0
  181. repos = []
  182. stk = self._MyStack.Last()
  183. repos.extend(stk)
  184. if self._MyStack.Length() == 1: # on top
  185. sqlite3_menu= self.SyncSqlite()
  186. if sqlite3_menu != None and len(sqlite3_menu) > 0:
  187. print(sqlite3_menu)
  188. repos.extend(sqlite3_menu )
  189. print(repos)
  190. for i,u in enumerate( repos ):
  191. #print(i,u)
  192. li = InfoPageListItem()
  193. li._Parent = self
  194. li._PosX = start_x
  195. li._PosY = start_y + last_height
  196. li._Width = Width
  197. li._Fonts["normal"] = self._ListFont
  198. li._Active = False
  199. li._Value = u
  200. li.Init( u["title"] )
  201. last_height += li._Height
  202. self._MyList.append(li)
  203. self._MyStack.Push(repos)
  204. def Init(self):
  205. if self._Screen != None:
  206. if self._Screen._CanvasHWND != None and self._CanvasHWND == None:
  207. self._HWND = self._Screen._CanvasHWND
  208. self._CanvasHWND = pygame.Surface( (self._Screen._Width,self._BGheight) )
  209. self._PosX = self._Index*self._Screen._Width
  210. self._Width = self._Screen._Width ## equal to screen width
  211. self._Height = self._Screen._Height
  212. done = IconItem()
  213. done._ImgSurf = MyIconPool.GiveIconSurface("done")
  214. done._MyType = ICON_TYPES["STAT"]
  215. done._Parent = self
  216. self._Icons["done"] = done
  217. ps = InfoPageSelector()
  218. ps._Parent = self
  219. self._Ps = ps
  220. self._PsIndex = 0
  221. self.SyncList()
  222. self._Scroller = ListScroller()
  223. self._Scroller._Parent = self
  224. self._Scroller._PosX = self._Width - 10
  225. self._Scroller._PosY = 2
  226. self._Scroller.Init()
  227. self._Scroller.SetCanvasHWND(self._HWND)
  228. def Click(self):
  229. if self._PsIndex > len(self._MyList) -1:
  230. return
  231. cur_li = self._MyList[self._PsIndex]
  232. if cur_li._Active == True:
  233. return
  234. print(cur_li._Value)
  235. if cur_li._Value["type"] == "dir":
  236. remote_file_url = cur_li._Value["file"]
  237. menu_file = remote_file_url.split("master")[1] #assume master branch
  238. local_menu_file = "%s/aria2download%s" % (os.path.expanduser('~'),menu_file )
  239. print(local_menu_file)
  240. if FileExists( local_menu_file ) == False:
  241. print(local_menu_file, "non-existed")
  242. gid,ret = config.RPC.urlDownloading(remote_file_url)
  243. if ret == False:
  244. gid = config.RPC.addUri( remote_file_url, options={"out": menu_file})
  245. self._Downloading = remote_file_url
  246. self._Screen._MsgBox.SetText("Loading")
  247. self._Screen._MsgBox.Draw()
  248. self._Screen.SwapAndShow()
  249. else:
  250. print(gid," url is downloading")
  251. self._Screen._MsgBox.SetText("Loading")
  252. self._Screen._MsgBox.Draw()
  253. self._Screen.SwapAndShow()
  254. else:
  255. #read the local_menu_file, push into stack,display menu
  256. self._Downloading = None
  257. with open(local_menu_file) as json_file:
  258. local_menu_json = json.load(json_file)
  259. print(local_menu_json)
  260. self._MyStack.Push(local_menu_json["list"])
  261. self.SyncList()
  262. self._Screen.Draw()
  263. self._Screen.SwapAndShow()
  264. else:
  265. #download the game probably
  266. remote_file_url = cur_li._Value["file"]
  267. menu_file = remote_file_url.split("master")[1]
  268. local_menu_file = "%s/aria2download%s" % (os.path.expanduser('~'),menu_file )
  269. if FileExists( local_menu_file ) == False:
  270. gid,ret = config.RPC.urlDownloading(remote_file_url)
  271. if ret == False:
  272. gid = config.RPC.addUri( remote_file_url, options={"out": menu_file})
  273. self._Downloading = remote_file_url
  274. try:
  275. conn = sqlite3.connect("aria2tasks.db")
  276. c = conn.cursor()
  277. c.execute("INSERT INTO tasks(gid,title,file,type,status,fav) VALUES ('"+gid+"','"+cur_li._Value["title"]+"','"+cur_li._Value["file"]+"','"+cur_li._Value["type"]+"','active','0')")
  278. conn.commit()
  279. conn.close()
  280. except Exception as ex:
  281. print("SQLITE3 ",ex)
  282. self._Screen._MsgBox.SetText("Getting the game now")
  283. self._Screen._MsgBox.Draw()
  284. self._Screen.SwapAndShow()
  285. else:
  286. print("file downloaded")# maybe check it if is installed,then execute it
  287. def OnLoadCb(self):
  288. self._Scrolled = 0
  289. self._PosY = 0
  290. self._DrawOnce = False
  291. #sync
  292. self.SyncList()
  293. def OnReturnBackCb(self):
  294. pass
  295. """
  296. self.ReturnToUpLevelPage()
  297. self._Screen.Draw()
  298. self._Screen.SwapAndShow()
  299. """
  300. def KeyDown(self,event):
  301. if IsKeyMenuOrB(event.key):
  302. self.ReturnToUpLevelPage()
  303. self._Screen.Draw()
  304. self._Screen.SwapAndShow()
  305. if IsKeyStartOrA(event.key):
  306. self.Click()
  307. if event.key == CurKeys["X"]:
  308. if self._MyStack.Length() > 1:
  309. self._MyStack.Pop()
  310. self.SyncList()
  311. self._Screen.Draw()
  312. self._Screen.SwapAndShow()
  313. if event.key == CurKeys["Up"]:
  314. self.ScrollUp()
  315. self._Screen.Draw()
  316. self._Screen.SwapAndShow()
  317. if event.key == CurKeys["Down"]:
  318. self.ScrollDown()
  319. self._Screen.Draw()
  320. self._Screen.SwapAndShow()
  321. def Draw(self):
  322. self.ClearCanvas()
  323. if len(self._MyList) == 0:
  324. return
  325. else:
  326. if len(self._MyList) * self._MyList[0]._Height > self._Height:
  327. self._Ps._Width = self._Width - 11
  328. self._Ps.Draw()
  329. for i in self._MyList:
  330. if i._PosY > self._Height + self._Height/2:
  331. break
  332. if i._PosY < 0:
  333. continue
  334. i.Draw()
  335. self._Scroller.UpdateSize( len(self._MyList)*self._MyList[0]._Height, self._PsIndex*self._MyList[0]._Height)
  336. self._Scroller.Draw()
  337. else:
  338. self._Ps._Width = self._Width
  339. self._Ps.Draw()
  340. for i in self._MyList:
  341. if i._PosY > self._Height + self._Height/2:
  342. break
  343. if i._PosY < 0:
  344. continue
  345. i.Draw()
  346. if self._HWND != None:
  347. self._HWND.fill(MySkinManager.GiveColor("White"))
  348. self._HWND.blit(self._CanvasHWND,(self._PosX,self._PosY,self._Width, self._Height ) )
  349. class APIOBJ(object):
  350. _Page = None
  351. def __init__(self):
  352. pass
  353. def Init(self,main_screen):
  354. self._Page = GameStorePage()
  355. self._Page._Screen = main_screen
  356. self._Page._Name ="Download games"
  357. self._Page.Init()
  358. def API(self,main_screen):
  359. if main_screen !=None:
  360. main_screen.PushPage(self._Page)
  361. main_screen.Draw()
  362. main_screen.SwapAndShow()
  363. OBJ = APIOBJ()
  364. def Init(main_screen):
  365. OBJ.Init(main_screen)
  366. def API(main_screen):
  367. OBJ.API(main_screen)