app.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. # @Author: Bachir Soussi Chiadmi <bach>
  4. # @Date: 23-05-2017
  5. # @Email: bachir@figureslibres.io
  6. # @Last modified by: bach
  7. # @Last modified time: 21-04-2017
  8. # @License: GPL-V3
  9. import sys, os
  10. from socket import socket
  11. import socketserver
  12. import http.server
  13. import threading
  14. from PyQt5 import QtCore
  15. from PyQt5.QtCore import QCoreApplication, QUrl, QFileSystemWatcher, pyqtSlot
  16. from PyQt5.QtGui import QKeySequence
  17. from PyQt5.QtWidgets import QMainWindow, QWidget, QApplication, QShortcut, QGridLayout, QLabel, QTabWidget, QHBoxLayout, QVBoxLayout, QSplitter, QSplitterHandle
  18. # from PyQt5.QtNetwork import QNetworkProxyFactory, QNetworkRequest
  19. from PyQt5.QtWebKit import QWebSettings
  20. from PyQt5.QtWebKitWidgets import QWebPage, QWebView, QWebInspector
  21. import sass
  22. class Core():
  23. def __init__(self, parent=None):
  24. self.server = Server()
  25. self.compiler = Compiler()
  26. class Server():
  27. def __init__(self, parent=None):
  28. # find free port
  29. sock = socket()
  30. sock.bind(('', 0))
  31. self._port = sock.getsockname()[1]
  32. sock.close()
  33. self.httpd = http.server.HTTPServer(('', self.port), http.server.SimpleHTTPRequestHandler)
  34. self.thread = threading.Thread(target=self.httpd.serve_forever)
  35. self.thread.start()
  36. print("serving at port", self._port)
  37. @property
  38. def port(self):
  39. return self._port
  40. class Compiler():
  41. def __init__(self,parent=None):
  42. paths = [
  43. 'assets',
  44. 'assets/scss',
  45. 'assets/scss/styles.scss'
  46. ]
  47. self.fs_watcher = QFileSystemWatcher(paths)
  48. # self.fs_watcher.directoryChanged.connect(self.directory_changed)
  49. self.fs_watcher.fileChanged.connect(self.compile_scss)
  50. self.compile_scss()
  51. # def directory_changed(path):
  52. # print("Directory changed : %s" % path)
  53. def compile_scss(path = ""):
  54. print("compiling sass : %s" % path)
  55. scss = sass.compile_file(b'assets/scss/main.scss')
  56. with open('assets/scss/main.css', 'w') as fp:
  57. fp.write(scss.decode('utf8'))
  58. class WebkitView(QWebView):
  59. def __init__(self, port):
  60. self.port = port
  61. self.view = QWebView.__init__(self)
  62. self.load(QUrl('http://localhost:'+str(self.port)))
  63. self.settings().setAttribute(QWebSettings.DeveloperExtrasEnabled, True)
  64. # self.settings().setAttribute(QWebSettings.PluginsEnabled, True)
  65. class WebkitInspector(QWebInspector):
  66. def __init__(self, webkitview):
  67. super().__init__()
  68. self.webkitview = webkitview
  69. self.setPage(self.webkitview.page())
  70. # TODO: webkitinspector is disappearing when chaging tabs
  71. class ViewTab(QWidget):
  72. def __init__(self, core):
  73. super(ViewTab, self).__init__()
  74. # self.grid = QGridLayout()
  75. hbox = QHBoxLayout()
  76. self.setLayout(hbox)
  77. # webviewbox = QVBoxLayout()
  78. vsplitter = QSplitter(QtCore.Qt.Vertical)
  79. self.webkitview = WebkitView(core.server.port)
  80. vsplitter.addWidget(self.webkitview)
  81. self.webkitinspector = WebkitInspector(self.webkitview)
  82. vsplitter.addWidget(self.webkitinspector)
  83. hsplitter = QSplitter(QtCore.Qt.Horizontal)
  84. hsplitter.addWidget(vsplitter)
  85. self.codeeditor = QLabel("Code Editor (SCSS & JS)")
  86. hsplitter.addWidget(self.codeeditor)
  87. hbox.addWidget(hsplitter)
  88. def onChanged(self, text):
  89. print("ViewTba Layout Changed")
  90. self.lbl.setText(text)
  91. self.lbl.adjustSize()
  92. class MainWindow(QMainWindow):
  93. def __init__(self, core):
  94. super(MainWindow, self).__init__()
  95. self.setWindowFlags(QtCore.Qt.WindowTitleHint)
  96. # QtCore.Qt.CustomizeWindowHint
  97. # | QtCore.Qt.Tool
  98. # | QtCore.Qt.FramelessWindowHint
  99. # | QtCore.Qt.WindowTitleHint
  100. # | QtCore.Qt.WindowStaysOnTopHint
  101. self.tabwidget = QTabWidget()
  102. # self.tabwidget.setStyleSheet("""
  103. # .QWidget {
  104. # border: 1px solid black;
  105. # margin:0;
  106. # padding:0;
  107. # }
  108. # """)
  109. self.viewtab = ViewTab(core)
  110. self.contenttab = QLabel("Content (markdown editor).")
  111. self.versiontab = QLabel("Version (git).")
  112. self.tabwidget.addTab(self.viewtab, "View")
  113. self.tabwidget.addTab(self.contenttab, "Content")
  114. self.tabwidget.addTab(self.versiontab, "Version")
  115. self.setCentralWidget(self.tabwidget)
  116. self.shortcut = QShortcut(QKeySequence("Ctrl+Q"), self)
  117. self.shortcut.activated.connect(self.on_quit)
  118. self.show()
  119. @pyqtSlot()
  120. def on_quit(self):
  121. print("Quit!")
  122. QCoreApplication.instance().quit()
  123. def main():
  124. # app = QtCore.QCoreApplication(sys.argv)
  125. app = QApplication(sys.argv)
  126. core = Core()
  127. mainappwindow = MainWindow(core)
  128. sys.exit(app.exec_())
  129. if __name__ == "__main__":
  130. main()