ware_house_page.go 23 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010
  1. package Warehouse
  2. import (
  3. "context"
  4. "fmt"
  5. "log"
  6. gotime "time"
  7. "strconv"
  8. "strings"
  9. "os"
  10. "io/ioutil"
  11. "path/filepath"
  12. "encoding/json"
  13. "reflect"
  14. "database/sql"
  15. _ "github.com/mattn/go-sqlite3"
  16. "github.com/zyxar/argo/rpc"
  17. //"github.com/veandco/go-sdl2/sdl"
  18. "github.com/veandco/go-sdl2/ttf"
  19. "github.com/cuu/gogame/surface"
  20. "github.com/cuu/gogame/time"
  21. "github.com/cuu/gogame/event"
  22. "github.com/cuu/gogame/rect"
  23. "github.com/cuu/grab"
  24. "github.com/clockworkpi/LauncherGoDev/sysgo"
  25. "github.com/clockworkpi/LauncherGoDev/sysgo/UI"
  26. )
  27. type WareHouse struct {
  28. UI.Page
  29. ListFontObj15 *ttf.Font
  30. ListFontObj12 *ttf.Font
  31. Icons map[string]UI.IconItemInterface
  32. BGwidth int
  33. BGheight int
  34. DrawOnce bool
  35. Scroller *UI.ListScroller
  36. RemovePage *UI.YesCancelConfirmPage
  37. Keyboard *UI.Keyboard
  38. PreviewPage *ImageDownloadProcessPage
  39. LoadHousePage *LoadHousePage
  40. WareHouseDB string
  41. MyStack *WareHouseStack
  42. rpcc rpc.Client
  43. rpcSecret string
  44. rpcURI string
  45. Aria2DownloadingGid string // the Downloading Gid of aria2c
  46. Downloading chan bool
  47. Downloader *grab.Client
  48. resp *grab.Response
  49. req *grab.Request
  50. ScrolledCnt int
  51. }
  52. func NewWareHouse() *WareHouse {
  53. p := &WareHouse{}
  54. p.ListFontObj12 = UI.MyLangManager.TrFont("notosanscjk12")
  55. p.ListFontObj15 = UI.MyLangManager.TrFont("varela15")
  56. p.Icons = make(map[string]UI.IconItemInterface)
  57. p.FootMsg = [5]string{"Nav","Update","Up","Back","Select"}
  58. p.WareHouseDB = sysgo.SQLDB
  59. p.BGwidth = 320
  60. p.BGheight = 240-24-20
  61. p.MyStack = NewWareHouseStack()
  62. repo := make(map[string]string)
  63. repo["title"] = "github.com/clockworkpi/warehouse"
  64. repo["file"] = "https://raw.githubusercontent.com/clockworkpi/warehouse/master/index.json"
  65. repo["type"] = "source"
  66. p.MyStack.Push(repo)
  67. p.rpcURI = sysgo.Aria2Url
  68. return p
  69. }
  70. func (self *WareHouse) GetAria2DownloadingPercent(url string) int {
  71. if resp,err := self.rpcc.TellActive();err == nil {
  72. for _,v := range resp {
  73. if uris,err := self.rpcc.GetURIs(v.Gid); err == nil {
  74. for _,x := range uris {
  75. if x.URI == url {
  76. comp_len,_ := strconv.ParseInt(v.CompletedLength,10,64)
  77. totl_len,_ := strconv.ParseInt(v.TotalLength,10,64)
  78. pct := float64(comp_len)/float64(totl_len)
  79. pct = pct * 100.0
  80. return int(pct)
  81. }
  82. }
  83. }
  84. }
  85. }
  86. return -1;///None
  87. }
  88. func (self *WareHouse) UpdateProcessInterval(ms int) {
  89. dirty := false
  90. RefreshTicker := gotime.NewTicker(gotime.Duration(ms)*gotime.Millisecond)
  91. defer RefreshTicker.Stop()
  92. L:
  93. for {
  94. select {
  95. case <- RefreshTicker.C:
  96. for _,i := range self.MyList {
  97. x := i.(*WareHouseListItem)
  98. if x.Type == "launcher" || x.Type == "pico8" || x.Type == "tic80" {
  99. percent := self.GetAria2DownloadingPercent(x.Value["file"])
  100. if percent < 0 {
  101. x.SetSmallText("")
  102. }else {
  103. x.SetSmallText(fmt.Sprintf("%d%%",percent))
  104. dirty = true
  105. }
  106. }
  107. }
  108. if self.Screen.CurPage() == self && dirty == true {
  109. self.Screen.Draw()
  110. self.Screen.SwapAndShow()
  111. }
  112. dirty = false
  113. case v:= <- self.Downloading:
  114. if v== false {
  115. break L
  116. }
  117. }
  118. }
  119. }
  120. func (self *WareHouse) SyncWareHouse() []map[string]string {
  121. db, err := sql.Open("sqlite3", self.WareHouseDB)
  122. if err != nil {
  123. log.Fatal(err)
  124. return nil
  125. }
  126. defer db.Close()
  127. //id,title,file,type
  128. rows, err := db.Query("select * from warehouse")
  129. if err != nil {
  130. log.Fatal(err)
  131. }
  132. defer rows.Close()
  133. var ret []map[string]string
  134. for rows.Next() {
  135. var id int
  136. var title string
  137. var file string
  138. var type_ string
  139. err = rows.Scan(&id, &title,&file,&type_)
  140. if err != nil {
  141. log.Fatal(err)
  142. }
  143. w_dbt := make(map[string]string)
  144. w_dbt["title"] = title
  145. w_dbt["file"] = file
  146. w_dbt["type"] = type_
  147. ret = append(ret,w_dbt)
  148. }
  149. return ret
  150. }
  151. func (self *WareHouse) SyncTasks() []map[string]string {
  152. db, err := sql.Open("sqlite3", self.WareHouseDB)
  153. if err != nil {
  154. log.Fatal(err)
  155. return nil
  156. }
  157. defer db.Close()
  158. //id,gid,title,file,type,status,totalLength,completedLength,fav
  159. rows, err := db.Query("select * from tasks")
  160. if err != nil {
  161. log.Fatal(err)
  162. }
  163. defer rows.Close()
  164. var ret []map[string]string
  165. for rows.Next() {
  166. var id int
  167. var gid string
  168. var title string
  169. var file string
  170. var type_ string
  171. var status string
  172. var totalLength string
  173. var completedLength string
  174. var fav string
  175. err = rows.Scan(&id,&gid, &title,&file,&type_,&status,&totalLength,&completedLength,&fav)
  176. if err != nil {
  177. log.Fatal(err)
  178. }
  179. w_dbt := make(map[string]string)
  180. w_dbt["gid"] = gid
  181. w_dbt["title"] = title
  182. w_dbt["file"] = file
  183. w_dbt["type"] = type_
  184. w_dbt["status"] = status
  185. w_dbt["totalLength"] = totalLength
  186. w_dbt["completedLength"] = completedLength
  187. ret = append(ret,w_dbt)
  188. }
  189. return ret
  190. }
  191. func IsSlice(v interface{}) bool {
  192. if reflect.TypeOf(v).Kind() == reflect.Slice || reflect.TypeOf(v).Kind() == reflect.Array {
  193. return true
  194. }
  195. return false
  196. }
  197. func (self *WareHouse) SyncList() {
  198. self.MyList = self.MyList[:0]
  199. start_x := 0
  200. start_y := 0
  201. last_height := 0
  202. var repos []map[string]string
  203. fmt.Printf("SyncList: %+v\n", self.MyStack)
  204. stk := self.MyStack.Last()
  205. stk_len := self.MyStack.Length()
  206. if IsSlice(stk) {
  207. repos = append(repos, stk.([]map[string]string)...)
  208. }else {
  209. repos = append(repos, stk.(map[string]string))
  210. }
  211. add_new_house := make(map[string]string)
  212. add_new_house["title"] = "Add new warehouse..."
  213. add_new_house["file"] = "master/index.json"
  214. add_new_house["type"] = "add_house"
  215. add_new_house["status"] = "complete"
  216. if stk_len == 1 {//on top
  217. ware_menu := self.SyncWareHouse()
  218. if len(ware_menu) > 0 {
  219. repos = append(repos,ware_menu...)
  220. }
  221. tasks_menu := self.SyncTasks()
  222. if len(tasks_menu) > 0 {
  223. repos = append(repos,tasks_menu...)
  224. }
  225. repos = append(repos,add_new_house)
  226. }
  227. for _, u := range repos {
  228. fmt.Printf("%+v\n",u)
  229. li := NewWareHouseListItem()
  230. li.Parent = self
  231. li.PosX = start_x
  232. li.PosY = start_y + last_height
  233. li.Width = UI.Width
  234. li.Fonts["normal"] = self.ListFontObj15
  235. li.Fonts["small"] = self.ListFontObj12
  236. li.ReadOnly = true
  237. li.Type = u["type"]
  238. li.Value = u
  239. li.Init(u["title"])
  240. if stk_len > 1 {
  241. remote_file_url := u["file"]
  242. menu_file := strings.Split(remote_file_url,"raw.githubusercontent.com")[1]
  243. home_path, err := os.UserHomeDir()
  244. if err != nil {
  245. log.Fatal( err )
  246. }
  247. local_menu_file := fmt.Sprintf(aria2dl_folder,home_path,menu_file)
  248. fmt.Println("for loop ",local_menu_file)
  249. if UI.FileExists(local_menu_file) {
  250. li.ReadOnly = false
  251. }else {
  252. li.ReadOnly = true
  253. }
  254. } else if stk_len == 1 {
  255. if _,ok := u["status"];ok {
  256. if u["status"] == "complete" {
  257. li.ReadOnly = false
  258. }
  259. }
  260. if u["type"] == "source" {
  261. li.ReadOnly = false
  262. }
  263. }
  264. last_height += li.Height
  265. if li.Type == "launcher" || li.Type == "pico8" || li.Type == "tic80" {
  266. li.SetSmallText("")
  267. }
  268. self.MyList = append(self.MyList,li)
  269. }
  270. self.RefreshPsIndex()
  271. }
  272. func (self *WareHouse) Init() {
  273. if self.Screen != nil {
  274. if self.Screen.CanvasHWND != nil && self.CanvasHWND == nil {
  275. self.HWND = self.Screen.CanvasHWND
  276. self.CanvasHWND = surface.Surface(self.Screen.Width, self.BGheight)
  277. }
  278. self.PosX = self.Index * self.Screen.Width
  279. self.Width = self.Screen.Width //equal to screen width
  280. self.Height = self.Screen.Height
  281. done := UI.NewIconItem()
  282. done.ImgSurf = UI.MyIconPool.GetImgSurf("done")
  283. done.MyType = UI.ICON_TYPES["STAT"]
  284. done.Parent = self
  285. self.Icons["done"] = done
  286. ps := UI.NewInfoPageSelector()
  287. ps.Parent = self
  288. self.Ps = ps
  289. self.PsIndex = 0
  290. self.Scroller = UI.NewListScroller()
  291. self.Scroller.Parent = self
  292. self.Scroller.PosX = self.Width - 10
  293. self.Scroller.PosY = 2
  294. self.Scroller.Init()
  295. self.Scroller.SetCanvasHWND(self.CanvasHWND)
  296. self.RemovePage = UI.NewYesCancelConfirmPage()
  297. self.RemovePage.Screen = self.Screen
  298. self.RemovePage.StartOrAEvent = self.RemoveGame
  299. self.RemovePage.Name = "Are you sure?"
  300. self.RemovePage.Init()
  301. self.Keyboard = UI.NewKeyboard()
  302. self.Keyboard.Name = "Enter warehouse addr"
  303. self.Keyboard.FootMsg = [5]string{"Nav.","Add","ABC","Backspace","Enter"}
  304. self.Keyboard.Screen = self.Screen
  305. self.Keyboard.Init()
  306. self.Keyboard.SetPassword("github.com/clockworkpi/warehouse")
  307. self.Keyboard.Caller = self
  308. self.PreviewPage = NewImageDownloadProcessPage()
  309. self.PreviewPage.Screen = self.Screen
  310. self.PreviewPage.Name ="Preview"
  311. self.PreviewPage.Init()
  312. self.LoadHousePage = NewLoadHousePage()
  313. self.LoadHousePage.Screen = self.Screen
  314. self.LoadHousePage.Name = "Warehouse"
  315. self.LoadHousePage.Parent = self
  316. self.LoadHousePage.Init()
  317. rpcc, err := rpc.New(context.Background(),
  318. self.rpcURI,
  319. self.rpcSecret,
  320. gotime.Second, AppNotifier{Parent:self})
  321. if err != nil {
  322. fmt.Fprintln(os.Stderr, err)
  323. os.Exit(2)
  324. }
  325. self.rpcc = rpcc
  326. self.Downloader = grab.NewClient()
  327. self.Downloading = make(chan bool,1)
  328. }
  329. }
  330. func (self *WareHouse) SetDownloading(v bool) {
  331. for len(self.Downloading) > 0 {
  332. <- self.Downloading
  333. }
  334. self.Downloading <- v
  335. }
  336. func (self *WareHouse) ResetHouse() {
  337. if self.PsIndex > len(self.MyList) -1 {
  338. return
  339. }
  340. cur_li := self.MyList[self.PsIndex].(*WareHouseListItem)
  341. home_path, _ := os.UserHomeDir()
  342. if cur_li.Value["type"] == "source" {
  343. remote_file_url := cur_li.Value["file"]
  344. parts := strings.Split(remote_file_url,"raw.githubusercontent.com")
  345. menu_file := parts[1]
  346. local_menu_file := fmt.Sprintf(aria2dl_folder,home_path,menu_file)
  347. local_menu_file_path := filepath.Dir(local_menu_file)
  348. fmt.Println(local_menu_file)
  349. local_jsons,err := filepath.Glob(local_menu_file_path+"/**/*.json")
  350. if err != nil {
  351. fmt.Println(err)
  352. }
  353. if UI.FileExists(local_menu_file) {
  354. os.Remove(local_menu_file)
  355. }
  356. if UI.FileExists(local_menu_file+".aria2") {
  357. os.Remove(local_menu_file+".aria2")
  358. }
  359. for _,x := range local_jsons {
  360. os.Remove(x)
  361. }
  362. self.Screen.MsgBox.SetText("Done")
  363. self.Screen.MsgBox.Draw()
  364. self.Screen.SwapAndShow()
  365. }
  366. }
  367. func (self *WareHouse) LoadHouse() {
  368. if self.PsIndex > len(self.MyList) -1 {
  369. return
  370. }
  371. cur_li := self.MyList[self.PsIndex].(*WareHouseListItem)
  372. if cur_li.Value["type"] == "source" || cur_li.Value["type"] == "dir" {
  373. self.LoadHousePage.URL = cur_li.Value["file"]
  374. self.Screen.PushPage(self.LoadHousePage)
  375. self.Screen.Draw()
  376. self.Screen.SwapAndShow()
  377. }
  378. }
  379. func (self *WareHouse) PreviewGame() {
  380. if self.PsIndex > len(self.MyList) -1 {
  381. return
  382. }
  383. cur_li := self.MyList[self.PsIndex].(*WareHouseListItem)
  384. if cur_li.Value["type"] == "launcher" ||
  385. cur_li.Value["type"] == "pico8" ||
  386. cur_li.Value["type"] == "tic80" {
  387. if _,ok := cur_li.Value["shots"];ok {
  388. fmt.Println(cur_li.Value["shots"])
  389. self.PreviewPage.URL = cur_li.Value["shots"]
  390. self.Screen.PushPage(self.PreviewPage)
  391. self.Screen.Draw()
  392. self.Screen.SwapAndShow()
  393. }
  394. }
  395. }
  396. //check if an Url is downloading in aria2c
  397. func (self *WareHouse) UrlIsDownloading(url string) (string,bool) {
  398. if resp,err := self.rpcc.TellActive();err == nil {
  399. for _,v := range resp {
  400. if uris,err := self.rpcc.GetURIs(v.Gid);err == nil {
  401. for _,x := range uris {
  402. if x.URI == url {
  403. fmt.Println(x.URI," ",url)
  404. return v.Gid,true
  405. }
  406. }
  407. }
  408. }
  409. }else {
  410. log.Println(err)
  411. }
  412. return "",false
  413. }
  414. func (self *WareHouse) RemoveGame() {
  415. if self.PsIndex > len(self.MyList) -1 {
  416. return
  417. }
  418. fmt.Println("RemoveGame")
  419. cur_li := self.MyList[self.PsIndex].(*WareHouseListItem)
  420. fmt.Println("Remove cur_li._Value",cur_li.Value)
  421. home_path, _ := os.UserHomeDir()
  422. if cur_li.Value["type"] == "source" {
  423. db, err := sql.Open("sqlite3", self.WareHouseDB)
  424. if err != nil {
  425. log.Fatal(err)
  426. }
  427. defer db.Close()
  428. _, err = db.Exec(fmt.Sprintf("DELETE FROM warehouse WHERE file = '%s'",
  429. cur_li.Value["file"]))
  430. if err != nil {
  431. log.Println(err)
  432. }
  433. } else if cur_li.Value["type"] == "launcher" ||
  434. cur_li.Value["type"] == "pico8" ||
  435. cur_li.Value["type"] == "tic80" {
  436. remote_file_url := cur_li.Value["file"]
  437. parts := strings.Split(remote_file_url,"raw.githubusercontent.com")
  438. menu_file := parts[1]
  439. local_menu_file := fmt.Sprintf(aria2dl_folder,home_path,menu_file)
  440. local_menu_file_path := filepath.Dir(local_menu_file)
  441. gid,ret := self.UrlIsDownloading(remote_file_url)
  442. if ret == true {
  443. self.rpcc.Remove(gid)
  444. }
  445. if UI.FileExists(local_menu_file) {
  446. os.Remove(local_menu_file)
  447. }
  448. if UI.FileExists(local_menu_file+".aria2") {
  449. os.Remove(local_menu_file+".aria2")
  450. }
  451. if UI.FileExists(filepath.Join(local_menu_file_path,cur_li.Value["title"])) {
  452. os.RemoveAll(filepath.Join(local_menu_file_path,cur_li.Value["title"]))
  453. }
  454. }
  455. }
  456. func (self *WareHouse) Click() {
  457. if self.PsIndex > len(self.MyList) -1 {
  458. return
  459. }
  460. cur_li := self.MyList[self.PsIndex].(*WareHouseListItem)
  461. home_path, _ := os.UserHomeDir()
  462. fmt.Println("Click cur_li._Value",cur_li.Value)
  463. if cur_li.Value["type"] == "source" || cur_li.Value["type"] == "dir" {
  464. remote_file_url := cur_li.Value["file"]
  465. parts := strings.Split(remote_file_url,"raw.githubusercontent.com")//assume master branch
  466. menu_file := parts[1]
  467. local_menu_file := fmt.Sprintf(aria2dl_folder,home_path,menu_file)
  468. fmt.Println("warehouse click: ",local_menu_file)
  469. if UI.FileExists(local_menu_file) == false {
  470. self.LoadHouse()
  471. }else {
  472. //read the local_menu_file,push into stack,display menu
  473. self.Aria2DownloadingGid = ""
  474. var result WareHouseIndex
  475. jsonFile, err := os.Open(local_menu_file)
  476. if err != nil {
  477. fmt.Println(err)
  478. self.Screen.MsgBox.SetText("Open House failed")
  479. self.Screen.MsgBox.Draw()
  480. self.Screen.SwapAndShow()
  481. }else {
  482. defer jsonFile.Close()
  483. byteValue, _ := ioutil.ReadAll(jsonFile)
  484. json.Unmarshal(byteValue, &result)
  485. self.MyStack.Push(result.List)
  486. self.SyncList()
  487. self.Screen.Draw()
  488. self.Screen.SwapAndShow()
  489. }
  490. }
  491. } else if cur_li.Value["type"] == "add_house" {
  492. fmt.Println("show keyboard to add warehouse")
  493. self.Screen.PushCurPage()
  494. self.Screen.SetCurPage(self.Keyboard)
  495. } else {
  496. //download the game probably
  497. remote_file_url := cur_li.Value["file"]
  498. parts := strings.Split(remote_file_url,"raw.githubusercontent.com")//assume master branch
  499. menu_file := parts[1]
  500. local_menu_file := fmt.Sprintf(aria2dl_folder,home_path,menu_file)
  501. fmt.Println("Click on game ", local_menu_file)
  502. if UI.FileExists(local_menu_file) == false {
  503. gid,ret := self.UrlIsDownloading(remote_file_url)
  504. if ret == false {
  505. outfile := struct {
  506. Out string `json:"out"`
  507. }{Out:menu_file}
  508. gid,err := self.rpcc.AddURI([]string{remote_file_url},outfile)
  509. if err != nil {
  510. log.Println(err)
  511. }else {
  512. fmt.Println("Warehouse Click game is downloading, ",gid)
  513. fmt.Println(remote_file_url)
  514. self.Aria2DownloadingGid = gid
  515. }
  516. } else {
  517. fmt.Println(self.rpcc.TellStatus(gid,"status","totalLength","completedLength"))
  518. self.Screen.MsgBox.SetText("Getting the game now")
  519. self.Screen.MsgBox.Draw()
  520. self.Screen.SwapAndShow()
  521. time.BlockDelay(800)
  522. self.Screen.TitleBar.Redraw()
  523. }
  524. }else {
  525. fmt.Println("file downloaded ", cur_li.Value) //maybe check it if is installed fst,then execute it
  526. if cur_li.Value["type"] == "launcher" && cur_li.ReadOnly == false {
  527. local_menu_file_path := filepath.Dir(local_menu_file)
  528. game_sh := filepath.Join(local_menu_file_path,cur_li.Value["title"],cur_li.Value["title"]+".sh")
  529. fmt.Println("run game: ",game_sh, UI.FileExists(game_sh))
  530. self.Screen.RunEXE(game_sh)
  531. }
  532. if cur_li.Value["type"] == "pico8" && cur_li.ReadOnly == false {
  533. if UI.FileExists("/home/cpi/games/PICO-8/pico-8/pico8") {
  534. game_sh := "/home/cpi/launcher/Menu/GameShell/50_PICO-8/PICO-8.sh"
  535. self.Screen.RunEXE(game_sh) //pico8 manages its games self
  536. }
  537. }
  538. if cur_li.Value["type"] == "tic80" && cur_li.ReadOnly == false {
  539. game_sh := "/home/cpi/apps/Menu/51_TIC-80/TIC-80.sh"
  540. self.Screen.RunEXE(game_sh)
  541. }
  542. }
  543. }
  544. }
  545. func (self *WareHouse) OnAria2CompleteCb(gid string) {
  546. fmt.Println("OnAria2CompleteCb", gid)
  547. self.SyncList()
  548. self.Screen.Draw()
  549. self.Screen.SwapAndShow()
  550. if gid == self.Aria2DownloadingGid {
  551. self.Aria2DownloadingGid = ""
  552. }
  553. }
  554. func (self *WareHouse) raw_github_com(url string) (bool,string) {
  555. if strings.HasPrefix(url,"github.com") == false {
  556. return false,""
  557. }
  558. parts := strings.Split(url,"/")
  559. if len(parts) != 3 {
  560. return false, ""
  561. }
  562. str := []string{"https://raw.githubusercontent.com",
  563. parts[1],
  564. parts[2],
  565. "master/index.json"}
  566. return true,strings.Join(str,"/")
  567. }
  568. func (self *WareHouse) OnKbdReturnBackCb() {
  569. inputed:= strings.Join(self.Keyboard.Textarea.MyWords,"")
  570. inputed = strings.Replace(inputed,"http://","",-1)
  571. inputed = strings.Replace(inputed,"https://","",-1)
  572. if strings.HasSuffix(inputed,".git") {
  573. inputed = inputed[:len(inputed)-4]
  574. }
  575. if strings.HasSuffix(inputed,"/") {
  576. inputed = inputed[:len(inputed)-1]
  577. }
  578. fmt.Println("last: ",inputed)
  579. db, err := sql.Open("sqlite3", self.WareHouseDB)
  580. if err != nil {
  581. log.Fatal(err)
  582. return
  583. }
  584. defer db.Close()
  585. stmt, err := db.Prepare("SELECT count(*) FROM warehouse WHERE title= ?")
  586. defer stmt.Close()
  587. if err != nil {
  588. log.Fatal(err)
  589. }
  590. var cnt_str string
  591. cnt := 0
  592. err = stmt.QueryRow(inputed).Scan(&cnt_str)
  593. if err != nil {
  594. log.Println(err)
  595. cnt_str = "0"
  596. }else {
  597. cnt,_= strconv.Atoi(cnt_str)
  598. }
  599. if cnt > 0 {
  600. self.Screen.MsgBox.SetText("Warehouse existed")
  601. self.Screen.MsgBox.Draw()
  602. self.Screen.SwapAndShow()
  603. } else {
  604. if strings.Contains(inputed,"github.com/clockworkpi/warehouse") {
  605. self.Screen.MsgBox.SetText("Warehouse existed")
  606. self.Screen.MsgBox.Draw()
  607. self.Screen.SwapAndShow()
  608. }else {
  609. valid_,_url := self.raw_github_com(inputed)
  610. if valid_ == false {
  611. self.Screen.MsgBox.SetText("Warehouse url error!")
  612. self.Screen.MsgBox.Draw()
  613. self.Screen.SwapAndShow()
  614. } else {
  615. sql_insert := fmt.Sprintf("INSERT INTO warehouse(title,file,type) VALUES('%s','%s','source');",
  616. inputed,_url)
  617. _, err = db.Exec(sql_insert)
  618. if err != nil {
  619. log.Println(err)
  620. }
  621. self.SyncList()
  622. self.Screen.Draw()
  623. self.Screen.SwapAndShow()
  624. }
  625. }
  626. }
  627. }
  628. func (self *WareHouse) OnExitCb() {
  629. self.SetDownloading(false)
  630. self.rpcc.Close()
  631. }
  632. func (self *WareHouse) OnLoadCb() {
  633. if self.MyStack.Length() == 1 {
  634. self.FootMsg[2] = "Remove"
  635. self.FootMsg[1] = "Update"
  636. }else {
  637. self.FootMsg[2] = "Remove"
  638. self.FootMsg[1] = "Preview"
  639. }
  640. self.SetDownloading(true)
  641. go self.UpdateProcessInterval(500)
  642. self.SyncList()
  643. }
  644. func (self *WareHouse) OnReturnBackCb() {
  645. if self.MyStack.Length() == 1 {
  646. self.FootMsg[2] = "Remove"
  647. self.FootMsg[1] = "Update"
  648. }else {
  649. self.FootMsg[2] = "Remove"
  650. self.FootMsg[1] = "Preview"
  651. }
  652. self.SyncList()
  653. self.RestoreScrolled()
  654. self.Screen.Draw()
  655. self.Screen.SwapAndShow()
  656. }
  657. func (self *WareHouse) ScrollDown() {
  658. if len(self.MyList) == 0 {
  659. return
  660. }
  661. self.PsIndex += 1
  662. if self.PsIndex >= len(self.MyList) {
  663. self.PsIndex = len(self.MyList) - 1
  664. }
  665. cur_li := self.MyList[self.PsIndex]
  666. x, y := cur_li.Coord()
  667. _, h := cur_li.Size()
  668. if y+h > self.Height {
  669. for i, _ := range self.MyList {
  670. x, y = self.MyList[i].Coord()
  671. _, h = self.MyList[i].Size()
  672. self.MyList[i].NewCoord(x, y-h)
  673. }
  674. self.ScrolledCnt -= h
  675. }
  676. }
  677. func (self *WareHouse) ScrollUp() {
  678. if len(self.MyList) == 0 {
  679. return
  680. }
  681. self.PsIndex -= 1
  682. if self.PsIndex < 0 {
  683. self.PsIndex = 0
  684. }
  685. cur_li := self.MyList[self.PsIndex]
  686. x, y := cur_li.Coord()
  687. _, h := cur_li.Size()
  688. if y < 0 {
  689. for i, _ := range self.MyList {
  690. x, y = self.MyList[i].Coord()
  691. _, h = self.MyList[i].Size()
  692. self.MyList[i].NewCoord(x, y+h)
  693. }
  694. self.ScrolledCnt += h
  695. }
  696. }
  697. func (self *WareHouse) RestoreScrolled() {
  698. for i,_ := range self.MyList {
  699. x,y := self.MyList[i].Coord()
  700. self.MyList[i].NewCoord(x, y+ self.ScrolledCnt)
  701. }
  702. }
  703. func (self *WareHouse) KeyDown(ev *event.Event) {
  704. if UI.IsKeyMenuOrB(ev.Data["Key"]) {
  705. if self.MyStack.Length() > 1 {
  706. self.MyStack.Pop()
  707. if self.MyStack.Length() == 1 {
  708. self.FootMsg[2] = "Remove"
  709. self.FootMsg[1] = "Update"
  710. }else {
  711. self.FootMsg[2] = "Remove"
  712. self.FootMsg[1] = "Preview"
  713. if self.MyStack.Length() == 2 {
  714. self.FootMsg[2] = ""
  715. self.FootMsg[1] = ""
  716. }
  717. }
  718. self.SyncList()
  719. self.Screen.Draw()
  720. self.Screen.SwapAndShow()
  721. }else if self.MyStack.Length() == 1 {
  722. self.ReturnToUpLevelPage()
  723. self.Screen.Draw()
  724. self.Screen.SwapAndShow()
  725. self.SetDownloading(false)//shutdown UpdateProcessInterval
  726. }
  727. }
  728. if UI.IsKeyStartOrA(ev.Data["Key"]) {
  729. self.Click()
  730. if self.MyStack.Length() == 1 {
  731. self.FootMsg[2] = "Remove"
  732. self.FootMsg[1] = "Update"
  733. }else {
  734. self.FootMsg[2] = "Remove"
  735. self.FootMsg[1] = "Preview"
  736. if self.MyStack.Length() == 2 {
  737. self.FootMsg[2] = ""
  738. self.FootMsg[1] = ""
  739. }
  740. }
  741. self.Screen.Draw()
  742. self.Screen.SwapAndShow()
  743. }
  744. if ev.Data["Key"] == UI.CurKeys["X"] {
  745. if self.PsIndex <= len(self.MyList) -1 {
  746. cur_li := self.MyList[self.PsIndex].(*WareHouseListItem)
  747. if cur_li.Type != "dir" {
  748. if self.MyStack.Length() ==1 && self.PsIndex == 0 {
  749. //pass
  750. }else {
  751. self.Screen.PushPage(self.RemovePage)
  752. self.RemovePage.StartOrAEvent = self.RemoveGame
  753. self.Screen.Draw()
  754. self.Screen.SwapAndShow()
  755. }
  756. }
  757. return
  758. }
  759. self.SyncList()
  760. self.Screen.Draw()
  761. self.Screen.SwapAndShow()
  762. }
  763. if ev.Data["Key"] == UI.CurKeys["Y"] {
  764. if self.MyStack.Length() == 1 {
  765. self.ResetHouse()
  766. }else {
  767. self.PreviewGame()
  768. }
  769. }
  770. if ev.Data["Key"] == UI.CurKeys["Up"] {
  771. self.ScrollUp()
  772. self.Screen.Draw()
  773. self.Screen.SwapAndShow()
  774. }
  775. if ev.Data["Key"] == UI.CurKeys["Down"] {
  776. self.ScrollDown()
  777. self.Screen.Draw()
  778. self.Screen.SwapAndShow()
  779. }
  780. }
  781. func (self *WareHouse) Draw() {
  782. self.ClearCanvas()
  783. if self.PsIndex > len(self.MyList) -1 {
  784. self.PsIndex = len(self.MyList) -1
  785. }
  786. if self.PsIndex < 0 {
  787. self.PsIndex = 0
  788. }
  789. if len(self.MyList) == 0 {
  790. return
  791. } else {
  792. if len(self.MyList) * UI.DefaultInfoPageListItemHeight > self.Height {
  793. _,h := self.Ps.Size()
  794. self.Ps.NewSize(self.Width - 11,h)
  795. self.Ps.Draw()
  796. for _,v := range self.MyList {
  797. _,y := v.Coord()
  798. if y > (self.Height + self.Height/2) {
  799. break
  800. }
  801. if y < 0 {
  802. continue
  803. }
  804. v.Draw()
  805. }
  806. self.Scroller.UpdateSize(len(self.MyList)*UI.DefaultInfoPageListItemHeight,self.PsIndex*UI.DefaultInfoPageListItemHeight)
  807. self.Scroller.Draw()
  808. }else {
  809. _,h := self.Ps.Size()
  810. self.Ps.NewSize(self.Width,h)
  811. self.Ps.Draw()
  812. for _,v := range self.MyList {
  813. _,y := v.Coord()
  814. if y > self.Height + self.Height/2 {
  815. break
  816. }
  817. if y < 0 {
  818. continue
  819. }
  820. v.Draw()
  821. }
  822. }
  823. }
  824. if self.HWND != nil {
  825. surface.Fill(self.HWND, UI.MySkinManager.GiveColor("White"))
  826. rect_ := rect.Rect(self.PosX, self.PosY, self.Width, self.Height)
  827. surface.Blit(self.HWND, self.CanvasHWND, &rect_, nil)
  828. }
  829. }