def __init__(self, win, site): UndoableEditor.__init__(self) self.win = win self.site = site self.title = QLineEdit() self.titleLabel.setText(QCoreApplication.translate("SiteSettingsEditor", "Site Settings")) self.filename = site.source_path + "/" + site.filename self.description = QLineEdit() self.copyright = QLineEdit() self.keywords = QLineEdit() self.author = QLineEdit() self.output = QLineEdit() self.logo = QLineEdit() seekButton = QPushButton("...") self.image = ImageSelector() self.image.setImage(QImage(":/images/image_placeholder.png")) self.copyright.setPlaceholderText("© 2019 your name") self.publisher = QComboBox() for key in Plugins.publishPluginNames(): pi = Plugins.getPublishPlugin(key) if pi: self.publisher.addItem(pi.display_name, key) vbox = QVBoxLayout() vbox.addStretch() self.layout.addWidget(QLabel(QCoreApplication.translate("SiteSettingsEditor", "Title")), 1, 0) self.layout.addWidget(self.title, 2, 0) self.layout.addWidget(QLabel(QCoreApplication.translate("SiteSettingsEditor", "Description")), 3, 0) self.layout.addWidget(self.description, 4, 0, 1, 3) self.layout.addWidget(QLabel(QCoreApplication.translate("SiteSettingsEditor", "Copyright")), 5, 0) self.layout.addWidget(self.copyright, 6, 0, 1, 3) self.layout.addWidget(QLabel(QCoreApplication.translate("SiteSettingsEditor", "Keywords")), 7, 0) self.layout.addWidget(self.keywords, 8, 0, 1, 3) self.layout.addWidget(QLabel(QCoreApplication.translate("SiteSettingsEditor", "Author")), 9, 0) self.layout.addWidget(self.author, 10, 0) self.layout.addWidget(QLabel(QCoreApplication.translate("SiteSettingsEditor", "Output directory (relative to to source dir)")), 11, 0) self.layout.addWidget(self.output, 12, 0) self.layout.addWidget(QLabel(QCoreApplication.translate("SiteSettingsEditor", "Logo")), 13, 0) self.layout.addWidget(self.logo, 14, 0) self.layout.addWidget(seekButton, 14, 1) self.layout.addWidget(self.image, 15, 0, 1, 2) self.layout.setRowStretch(15, 1) self.layout.addWidget(QLabel(QCoreApplication.translate("SiteSettingsEditor", "Plugin to be used for publishing")), 16, 0) self.layout.addWidget(self.publisher, 17, 0) self.layout.addLayout(vbox, 18, 0) self.load() self.title.editingFinished.connect(self.titleChanged) self.description.editingFinished.connect(self.descriptionChanged) self.copyright.editingFinished.connect(self.copyrightChanged) self.keywords.editingFinished.connect(self.keywordsChanged) self.author.editingFinished.connect(self.authorChanged) self.output.editingFinished.connect(self.outputChanged) self.logo.editingFinished.connect(self.logoChanged) self.publisher.currentIndexChanged.connect(self.publisherChanged) seekButton.clicked.connect(self.seek)
def actualThemeChanged(self, themename): self.theme_settings_button.setVisible(False) for name in Plugins.themePluginNames(): tei = Plugins.getThemePlugin(name) if tei: if tei.theme_name == themename: self.theme_settings_button.setVisible(True) break
def publishSite(self): pluginName = Plugins.actualPublishPlugin() pi = Plugins.getPublishPlugin(pluginName) if pi: self.setCentralWidget(pi) pi.setSitePath(self.install_directory, self.site.source_path) else: QMessageBox.warning( self, "FlatSiteBuilder", QCoreApplication.translate( "MainWindow", "Website has no publish plugin configured."))
def reloadProject(self, filename): engine = QQmlEngine() component = QQmlComponent(engine) component.loadUrl(QUrl(filename)) self.site = component.create() if self.site is not None: self.site.setFilename(filename) self.site.setWindow(self) else: for error in component.errors(): print(error.toString()) return False self.site.loadMenus() self.site.loadPages() self.site.loadPosts() self.theme_settings_button.setVisible(False) Plugins.setActualThemeEditorPlugin("") for key in Plugins.themePluginNames(): tei = Plugins.getThemePlugin(key) if tei: if tei.theme_name == self.site.theme: Plugins.setActualThemeEditorPlugin(tei.class_name) self.theme_settings_button.setVisible(True) break #if not self.site.publisher: # if len(Plugins.publishPluginNames()) > 0: # self.site.publisher = Plugins.publishPluginNames[0] Plugins.setActualPublishPlugin(self.site.publisher) self.siteLoaded.emit(self.site) return True
def showThemesSettings(self): tei = Plugins.getThemePlugin(Plugins.actualThemeEditorPlugin()) if tei: if self.editor: self.method_after_animation = "showThemesSettings" self.editor.closeEditor() return path = self.site.source_path tei.setWindow(self) tei.setSourcePath(path) self.setCentralWidget(tei) else: self.statusBar().showMessage("Unable to load plugin " + Plugins.actualThemeEditorPlugin())
def save(self, filename): with open(filename, "w") as f: f.write("import FlatSiteBuilder 2.0\n") taglist = [] self.collectTagNames(taglist) for tag in taglist: plugin_name = Plugins.getElementPluginByTagname(tag) plugin = Plugins.element_plugins[plugin_name] plugin.writeImportString(f) f.write("\n") f.write("Content {\n") self.writeAttribute(f, 4, "title", self.title) self.writeAttribute(f, 4, "menu", self.menu) self.writeAttribute(f, 4, "author", self.author) self.writeAttribute(f, 4, "keywords", self.keywords) self.writeAttribute(f, 4, "script", self.script) self.writeAttribute(f, 4, "layout", self.layout) self.writeAttribute(f, 4, "date", self.date) self.writeAttribute(f, 4, "logo", self.logo) self.writeAttribute(f, 4, "excerpt", self.excerpt) for att, value in self.attributes: f.writeAttribute(f, 4, att, value) for item in self._items: item.save(f, 4) f.write("}\n")
def save(self, filename): qml = "import FlatSiteBuilder 2.0\n" taglist = [] self.collectTagNames(taglist) for tag in taglist: plugin_name = Plugins.getElementPluginByTagname(tag) plugin = Plugins.element_plugins[plugin_name] qml += plugin.getImportString() qml += "\n" qml += "Content {\n" qml += self.getAttributeQml(4, "title", self.title) qml += self.getAttributeQml(4, "menu", self.menu) qml += self.getAttributeQml(4, "author", self.author) qml += self.getAttributeQml(4, "keywords", self.keywords) qml += self.getAttributeQml(4, "script", self.script) qml += self.getAttributeQml(4, "layout", self.layout) qml += self.getAttributeQml(4, "date", self.date) qml += self.getAttributeQml(4, "logo", self.logo) qml += self.getAttributeQml(4, "excerpt", self.excerpt) for att, value in self.attributes: qml += self.getAttributeQml(4, att, value) for item in self._items: qml += item.getQml(4) qml += "}\n" with open(filename, "w", encoding="utf-8") as f: f.write(qml)
def __init__(self): QDialog.__init__(self) self.result = "" self.setWindowTitle("Insert Module") self.grid = QGridLayout() cancelButton = QPushButton("Cancel") buttonsLayout = QHBoxLayout() buttonsLayout.addStretch(1) buttonsLayout.addWidget(cancelButton) mainLayout = QVBoxLayout() mainLayout.addLayout(self.grid) mainLayout.addStretch(1) mainLayout.addSpacing(12) mainLayout.addLayout(buttonsLayout) self.setLayout(mainLayout) row = 0 col = 0 for name in Plugins.elementPluginNames(): plugin = Plugins.element_plugins[name] btn = self.createButton(plugin.icon, plugin.display_name) btn.returncode = name self.grid.addWidget(btn, row, col) col = col + 1 btn.clickedWithReturn.connect(self.close2) if col == 4: row = row + 1 col = 0 cancelButton.clicked.connect(self.close)
def save(self): if self.site.title != self.title.text(): oldTitle = self.site.title self.site.title = self.title.text() self.site.save() #os.rename(Generator.sitesPath() + "/" + oldTitle, Generator.sitesPath() + "/" + self.site.title) self.win.statusBar().showMessage(QCoreApplication.translate("SiteSettingsEditor", "Site settings have been saved. Site should be rebuilded on the dashboard.") + " " + QCoreApplication.translate("SiteSettingsEditor", "Output path has been renamed to") + " " + self.title.text()) else: self.site.author = self.author.text() self.site.output = self.output.text() self.site.copyright = self.copyright.text() self.site.description = self.description.text() self.site.keywords = self.keywords.text() self.site.publisher = self.publisher.currentData() if not self.site.publisher: self.site.publisher = "" Plugins.setActualPublishPlugin(self.site.publisher) self.site.logo = self.logo.text() self.site.save() self.win.statusBar().showMessage(QCoreApplication.translate("SiteSettingsEditor", "Site settings have been saved. Site should be rebuilded on the dashboard."))
def elementEdit(self, ee): self.element_editor = ee plugin_name = "" if ee.type: plugin_name = Plugins.getElementPluginByTagname(ee.type) if plugin_name: self.editor = Plugins.element_plugins[plugin_name] else: self.editor = Plugins.element_plugins["TextEditor"] self.editor.setCaption("Text Module") self.editor.site = self.site self.editor.setContent(ee.getContent()) self.editor.close.connect(self.editorClose) self.animate(ee)
def loadPlugins(self): # check if we are running in a frozen environment (pyinstaller --onefile) if getattr(sys, "frozen", False): bundle_dir = sys._MEIPASS # if we are running in a onefile environment, then copy all plugin to /tmp/... if bundle_dir != os.getcwd(): os.mkdir(os.path.join(bundle_dir, "plugins")) for root, dirs, files in os.walk( os.path.join(os.getcwd(), "plugins")): for file in files: shutil.copy(os.path.join(root, file), os.path.join(bundle_dir, "plugins")) print("copy", file) break # do not copy __pycache__ else: bundle_dir = os.getcwd() plugins_dir = os.path.join(bundle_dir, "plugins") for root, dirs, files in os.walk(plugins_dir): for file in files: modulename, ext = os.path.splitext(file) if ext == ".py": module = import_module("plugins." + modulename) for name, klass in inspect.getmembers( module, inspect.isclass): if klass.__module__ == "plugins." + modulename: instance = klass() if isinstance(instance, ElementEditorInterface): Plugins.addElementPlugin(name, instance) instance.registerContenType() elif isinstance(instance, ThemeEditorInterface): Plugins.addThemePlugin(name, instance) elif isinstance(instance, PublisherInterface): Plugins.addPublishPlugin(name, instance) elif isinstance(instance, GeneratorInterface): Plugins.addGeneratorPlugin(name, instance) break # not to list __pycache__
def save(self): self.site.theme = self.themename self.site.save() Plugins.setActualThemeEditorPlugin("") for key in Plugins.themePluginNames(): tei = Plugins.getThemePlugin(key) if tei: if tei.theme_name == self.site.theme: Plugins.setActualThemeEditorPlugin(tei.class_name) #self.theme_settings_button.setVisible(True) break self.win.actualThemeChanged(self.themename) self.win.statusBar().showMessage(QCoreApplication.translate("ThemeChooser", "Theme has been changed. The site should be rebuildet on the dashboard.")) self.load()
def generateSite(self, win, site, content_to_build=None): self.site = site site_dir = os.path.join(Generator.install_directory, "sites", site.title) if not content_to_build: # clear directory for r, dirs, files in os.walk(site_dir): for f in files: os.remove(os.path.join(site_dir, f)) for d in dirs: if d != ".git": shutil.rmtree(os.path.join(site_dir, d)) pages = [] posts = [] menus = {} for content in site.pages: cm = {} cm["author"] = content.author cm["date"] = content.date cm["layout"] = content.layout cm["menu"] = content.menu cm["source"] = content.source cm["title"] = content.title cm["url"] = content.url cm["logo"] = content.logo cm["keywords"] = content.keywords cm["script"] = content.script for att, value in content.attributes.items(): cm[att] = value pages.append(cm) for content in site.posts: cm = {} cm["author"] = content.author cm["date"] = content.date cm["excerpt"] = content.excerpt cm["layout"] = content.layout cm["menu"] = content.menu cm["source"] = content.source cm["title"] = content.title cm["url"] = content.url cm["logo"] = content.logo cm["keywords"] = content.keywords cm["script"] = content.script for att, value in content.attributes.items(): cm[att] = value posts.append(cm) for menu in site.menus.menus: items = [] for item in menu.items: menuitem = {} menuitem["title"] = item.title menuitem["url"] = item.url menuitem["icon"] = item.icon attributes = "" for att, value in item.attributes.items(): if attributes: attributes += " " attributes += att + "=\"" + value + "\"" menuitem["attributes"] = attributes subitems = [] for subitem in item.items: submenuitem = {} submenuitem["title"] = subitem.title submenuitem["url"] = subitem.url submenuitem["icon"] = subitem.icon attributes = "" for att, value in subitem.attributes.items(): if attributes: attributes += " " attributes += att + "=\"" + subitem.attributes().value( att) + "\"" submenuitem["attributes"] = attributes subitems.append(submenuitem) menuitem["items"] = subitems menuitem["hasItems"] = len(subitems) > 0 items.append(menuitem) menus[menu.name] = items #qStableSort(posts.begin(), posts.end(), postLaterThan) sitevars = {} sitevars["title"] = site.title sitevars["description"] = site.description sitevars["theme"] = site.theme sitevars["copyright"] = site.copyright sitevars["source"] = site.source_path sitevars["keywords"] = site.keywords sitevars["author"] = site.author sitevars["logo"] = site.logo sitevars["pages"] = pages sitevars["posts"] = posts for att, value in site.attributes.items(): sitevars[att] = value act = Plugins.actualThemeEditorPlugin() if act: tei = Plugins.getThemePlugin(Plugins.actualThemeEditorPlugin()) if tei: tei.setWindow(win) tei.setSourcePath(site.source_path) themevars = tei.themeVars() else: themevars = {} context = Context() context["site"] = sitevars context["theme"] = themevars copy_assets = False if not os.path.exists(site_dir): os.mkdir(site_dir) copy_assets = True if not content_to_build or copy_assets: self.copytree( os.path.join(Generator.install_directory, "themes", site.theme, "assets"), os.path.join(Generator.install_directory, "sites", site.title, "assets")) self.copytree( os.path.join(site.source_path, "assets"), os.path.join(Generator.install_directory, "sites", site.title, "assets")) self.copytree( os.path.join(site.source_path, "content"), os.path.join(Generator.install_directory, "sites", site.title)) for page in site.pages: self.generateContent(page, context, menus) for post in site.posts: self.generateContent(post, context, menus) else: self.generateContent(content_to_build, context, menus)
def generateContent(self, content, context, menus): dirs = [ os.path.join(self.site.source_path, "includes"), os.path.join(self.site.source_path, "layouts"), os.path.join(Generator.install_directory, "themes", self.site.theme, "layouts"), os.path.join(Generator.install_directory, "themes", self.site.theme, "includes") ] eng = Engine(dirs=dirs, debug=True) cm = {} if content.content_type == ContentType.POST: cm["excerpt"] = content.excerpt cm["author"] = content.author cm["date"] = content.date cm["layout"] = content.layout cm["menu"] = content.menu cm["source"] = content.source cm["title"] = content.title cm["url"] = content.url cm["logo"] = content.logo cm["keywords"] = content.keywords cm["script"] = html.unescape(content.script) cm["menuitems"] = menus[content.menu] used_tag_list = [] self.content = "" for item in content.items: self.content += item.getHtml() item.collectTagNames(used_tag_list) pluginvars = {} pluginvars["styles"] = "" pluginvars["scripts"] = "" for name in Plugins.elementPluginNames(): plugin = Plugins.element_plugins[name] if plugin.tag_name in used_tag_list: plugin = Plugins.element_plugins[name] pluginvars[ "styles"] = pluginvars["styles"] + plugin.pluginStyles() pluginvars["scripts"] = pluginvars[ "scripts"] + plugin.pluginScripts() plugin.installAssets( os.path.join(Generator.install_directory, "sites", self.site.title, "assets")) pluginvars["styles"] = mark_safe(pluginvars["styles"]) pluginvars["scripts"] = mark_safe(pluginvars["scripts"]) context["plugin"] = pluginvars layout = content.layout if not layout: layout = "default" context["page"] = cm ctx = {} ctx["page"] = content ctx["site"] = self.site tmp = Template(self.content) xhtml = tmp.render(ctx) context["content"] = mark_safe(xhtml) outputfile = os.path.join(Generator.install_directory, "sites", self.site.title, content.url()) try: with open(outputfile, 'w') as f: f.write(eng.render_to_string(layout + ".html", context=context)) except: type, value, traceback = sys.exc_info() msg = "Generate content failed: Unable to create file " + outputfile print(msg, type, value, traceback)
def publishSite(self): pluginName = Plugins.actualPublishPlugin() pi = Plugins.getPublishPlugin(pluginName) if pi: self.setCentralWidget(pi) pi.setSitePath(self.site.deploy_path)
def __init__(self, site, default_path): QWidget.__init__(self) self.site = site if default_path: self.default_path = default_path else: self.default_path = os.path.join(Generator.install_directory, "sources") vbox = QVBoxLayout() layout = QGridLayout() title = QLabel() title.setText(QCoreApplication.translate("Dashboard", "Dashboard")) fnt = title.font() fnt.setPointSize(20) fnt.setBold(True) title.setFont(fnt) self.browser = QTextBrowser() self.browser.setOpenLinks(False) self.load_button = FlatButton(":/images/load_normal.png", ":/images/load_hover.png", ":/images/load_pressed.png") self.load_button.setToolTip(QCoreApplication.translate("Dashboard", "Load an existing website project")) self.create_button = FlatButton(":/images/create_normal.png", ":/images/create_hover.png", ":/images/create_pressed.png") self.create_button.setToolTip(QCoreApplication.translate("Dashboard", "Create a website project")) self.publish_button = FlatButton(":/images/publish_normal.png", ":/images/publish_hover.png", ":/images/publish_pressed.png") self.publish_button.setToolTip(QCoreApplication.translate("Dashboard", "Upload the website to your web space provider")) self.preview_button = FlatButton(":/images/preview_normal.png", ":/images/preview_hover.png", ":/images/preview_pressed.png") self.preview_button.setToolTip(QCoreApplication.translate("Dashboard", "Load the website in your browser locally")) self.build_button = FlatButton(":/images/build_normal.png", ":/images/build_hover.png", ":/images/build_pressed.png") self.build_button.setToolTip(QCoreApplication.translate("Dashboard", "Build the website")) self.info = QLabel() if self.site and self.site.title: self.info.setText(self.site.title + " " + QCoreApplication.translate("Dashboard", "loaded...")) else: self.info.setText(QCoreApplication.translate("Dashboard", "No site loaded yet...")) space = QWidget() space2 = QWidget() space3 = QWidget() space.setMinimumHeight(30) space2.setMinimumHeight(30) space3.setMinimumHeight(30) layout.addWidget(title, 0, 0, 1, 3) layout.addWidget(self.info, 1, 0, 1, 3) layout.addWidget(space, 2, 0) layout.addWidget(self.load_button, 3, 0, 1, 1, Qt.AlignCenter) layout.addWidget(self.create_button, 3, 1, 1, 1, Qt.AlignCenter) layout.addWidget(self.publish_button, 3, 2, 1, 1, Qt.AlignCenter) layout.addWidget(space2, 4, 0) layout.addWidget(self.preview_button, 5, 0, 1, 1, Qt.AlignCenter) layout.addWidget(self.build_button, 5, 1, 1, 1, Qt.AlignCenter) #load generator plugins here for plugin_name in Plugins.generatorPluginNames(): p = Plugins.getGeneratorPlugin(plugin_name) button = FlatButton(os.path.join(Plugins.getBundleDir(), "plugins",p.normal_image), os.path.join(Plugins.getBundleDir(), "plugins",p.hover_image), os.path.join(Plugins.getBundleDir(), "plugins",p.pressed_image)) button.setToolTip(QCoreApplication.translate("Dashboard", "Execute Plugin")) button.clicked.connect(p.clicked) layout.addWidget(button, 5, 2, 1, 1, Qt.AlignCenter) vbox.addLayout(layout) vbox.addSpacing(40) vbox.addWidget(self.browser) self.setLayout(vbox) self.load_button.clicked.connect(self.loadClicked) self.create_button.clicked.connect(self.createClicked) self.publish_button.clicked.connect(self.publishClicked) self.preview_button.clicked.connect(self.previewClicked) self.build_button.clicked.connect(self.buildClicked) manager = QNetworkAccessManager(self) manager.finished.connect(self.fileIsReady) manager.get(QNetworkRequest(QUrl("https://artanidos.github.io/FlatSiteBuilder/news.html")))