TrayiconPlugin.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. import os
  2. import sys
  3. import atexit
  4. from Plugin import PluginManager
  5. from Config import config
  6. from Translate import Translate
  7. allow_reload = False # No source reload supported in this plugin
  8. if "_" not in locals():
  9. _ = Translate("plugins/Trayicon/languages/")
  10. @PluginManager.registerTo("Actions")
  11. class ActionsPlugin(object):
  12. def main(self):
  13. global notificationicon, winfolders
  14. from lib import notificationicon, winfolders
  15. import gevent.threadpool
  16. self.main = sys.modules["main"]
  17. fs_encoding = sys.getfilesystemencoding()
  18. icon = notificationicon.NotificationIcon(
  19. os.path.join(os.path.dirname(os.path.abspath(__file__).decode(fs_encoding)), 'trayicon.ico'),
  20. "ZeroNet %s" % config.version
  21. )
  22. self.icon = icon
  23. if not config.debug: # Hide console if not in debug mode
  24. notificationicon.hideConsole()
  25. self.console = False
  26. else:
  27. self.console = True
  28. @atexit.register
  29. def hideIcon():
  30. icon.die()
  31. ui_ip = config.ui_ip if config.ui_ip != "*" else "127.0.0.1"
  32. icon.items = [
  33. (self.titleIp, False),
  34. (self.titleConnections, False),
  35. (self.titleTransfer, False),
  36. (self.titleConsole, self.toggleConsole),
  37. (self.titleAutorun, self.toggleAutorun),
  38. "--",
  39. (_["ZeroNet Twitter"], lambda: self.opensite("https://twitter.com/HelloZeroNet")),
  40. (_["ZeroNet Reddit"], lambda: self.opensite("http://www.reddit.com/r/zeronet/")),
  41. (_["ZeroNet Github"], lambda: self.opensite("https://github.com/HelloZeroNet/ZeroNet")),
  42. (_["Report bug/request feature"], lambda: self.opensite("https://github.com/HelloZeroNet/ZeroNet/issues")),
  43. "--",
  44. (_["!Open ZeroNet"], lambda: self.opensite("http://%s:%s/%s" % (ui_ip, config.ui_port, config.homepage))),
  45. "--",
  46. (_["Quit"], self.quit),
  47. ]
  48. if not notificationicon.hasConsole():
  49. del icon.items[3]
  50. icon.clicked = lambda: self.opensite("http://%s:%s/%s" % (ui_ip, config.ui_port, config.homepage))
  51. self.quit_servers_event = gevent.threadpool.ThreadResult(
  52. lambda res: gevent.spawn_later(0.1, self.quitServers), gevent.threadpool.get_hub(), lambda: True
  53. ) # Fix gevent thread switch error
  54. gevent.threadpool.start_new_thread(icon._run, ()) # Start in real thread (not gevent compatible)
  55. super(ActionsPlugin, self).main()
  56. icon._die = True
  57. def quit(self):
  58. self.icon.die()
  59. self.quit_servers_event.set(True)
  60. def quitServers(self):
  61. self.main.ui_server.stop()
  62. self.main.file_server.stop()
  63. def opensite(self, url):
  64. import webbrowser
  65. webbrowser.open(url, new=0)
  66. def titleIp(self):
  67. title = "!IP: %s " % ", ".join(self.main.file_server.ip_external_list)
  68. if any(self.main.file_server.port_opened):
  69. title += _["(active)"]
  70. else:
  71. title += _["(passive)"]
  72. return title
  73. def titleConnections(self):
  74. title = _["Connections: %s"] % len(self.main.file_server.connections)
  75. return title
  76. def titleTransfer(self):
  77. title = _["Received: %.2f MB | Sent: %.2f MB"] % (
  78. float(self.main.file_server.bytes_recv) / 1024 / 1024,
  79. float(self.main.file_server.bytes_sent) / 1024 / 1024
  80. )
  81. return title
  82. def titleConsole(self):
  83. translate = _["Show console window"]
  84. if self.console:
  85. return "+" + translate
  86. else:
  87. return translate
  88. def toggleConsole(self):
  89. if self.console:
  90. notificationicon.hideConsole()
  91. self.console = False
  92. else:
  93. notificationicon.showConsole()
  94. self.console = True
  95. def getAutorunPath(self):
  96. return "%s\\zeronet.cmd" % winfolders.get(winfolders.STARTUP)
  97. def formatAutorun(self):
  98. args = sys.argv[:]
  99. if not getattr(sys, 'frozen', False): # Not frozen
  100. args.insert(0, sys.executable)
  101. cwd = os.getcwd().decode(sys.getfilesystemencoding())
  102. else:
  103. cwd = os.path.dirname(sys.executable).decode(sys.getfilesystemencoding())
  104. if sys.platform == 'win32':
  105. args = ['"%s"' % arg for arg in args if arg]
  106. cmd = " ".join(args)
  107. # Dont open browser on autorun
  108. cmd = cmd.replace("start.py", "zeronet.py").replace('"--open_browser"', "").replace('"default_browser"', "").strip()
  109. cmd += ' --open_browser ""'
  110. cmd = cmd.decode(sys.getfilesystemencoding())
  111. return u"""
  112. @echo off
  113. chcp 65001 > nul
  114. set PYTHONIOENCODING=utf-8
  115. cd /D \"%s\"
  116. start "" %s
  117. """ % (cwd, cmd)
  118. def isAutorunEnabled(self):
  119. path = self.getAutorunPath()
  120. return os.path.isfile(path) and open(path).read().decode("utf8") == self.formatAutorun()
  121. def titleAutorun(self):
  122. translate = _["Start ZeroNet when Windows starts"]
  123. if self.isAutorunEnabled():
  124. return "+" + translate
  125. else:
  126. return translate
  127. def toggleAutorun(self):
  128. if self.isAutorunEnabled():
  129. os.unlink(self.getAutorunPath())
  130. else:
  131. open(self.getAutorunPath(), "w").write(self.formatAutorun().encode("utf8"))