Example #1
0
    def __init__(self, host='0.0.0.0', port=8251, debug=False):
        '''
        constructor
        
        Args:
            wikiId(str): id of the wiki to use as a CMS backend
            host(str): flask host
            port(int): the port to use for http connections
            debug(bool): True if debugging should be switched on
        '''
        scriptdir = os.path.dirname(os.path.abspath(__file__))
        template_folder=scriptdir + '/../templates'
        super().__init__(host=host,port=port,debug=debug,template_folder=template_folder)
        self.app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
        db.init_app(self.app)
        self.db=db
        self.loginBluePrint=LoginBluePrint(self.app,'login')
        self.server = Server()
        self.server.load()
        self.enabledSites = ['admin']
        
        #
        # setup global handlers
        #
        @self.app.before_first_request
        def before_first_request_func():
            self.initDB()
            loginMenuList=self.adminMenuList("Login")
            self.loginBluePrint.setLoginArgs(menuList=loginMenuList)
            
        @self.app.route('/')
        def index():
            return self.family()

        @self.app.route('/family')
        def family():
            return wcw.family()    
            
        @login_required
        @self.app.route('/wikis')
        def wikis():
            return self.wikis()
        
        @login_required
        @self.app.route('/frontends')
        def frontends():
            return wcw.frontends()

        @login_required
        @self.app.route('/generate/<string:siteName>', methods=['GET', 'POST'])
        def generate(siteName: str):
            '''
            Handle wiki generator page request
            Args:
                siteName(str): wikiId of the wiki the generator should be returned for
            '''
            return self.generate(siteName)
Example #2
0
    def testServer(self):
        '''
        test server functions
        '''
        server = Server()
        server.platform = 'linux'
        logo = server.getPlatformLogo()
        if self.debug:
            print("platform logo is %s " % logo)
            print(server.uname)
            print("%s(%s)" % (server.hostname, server.ip))

        self.assertTrue("Tux" in logo)
        pass
Example #3
0
 def initServer():
     '''
     initialize the server
     '''
     warnings.simplefilter("ignore", ResourceWarning)
     Server.homePath="/tmp"
     server=Server()
     server.logo="https://upload.wikimedia.org/wikipedia/commons/thumb/6/65/Desmond_Llewelyn_01.jpg/330px-Desmond_Llewelyn_01.jpg"
     server.frontendConfigs=[
         {
          'site':'or',
          'wikiId':'or', 
          'template':'bootstrap.html',
          'defaultPage':'Frontend'
         },
         {
          'site': 'cr',
          'wikiId':'cr', 
          'template':'bootstrap.html',
          'defaultPage':'Main Page'
         },
         {
          'site': 'sharks',
          'wikiId':'wiki', 
          'template':'bootstrap.html',
          'defaultPage':'Sharks'
         },
         {
          'site': 'www',
          'wikiId':'wiki', 
          'template':'design.html',
          'defaultPage':'Welcome',
          'packageFolder': '%s/www.wikicms' % tempfile.gettempdir(),
          'packageName': 'bitplan_webfrontend',
          'templateFolder': 'templates'
         }
     ]
     for frontendConfigs in server.frontendConfigs:
         # make sure ini file is available
         wikiId=frontendConfigs["wikiId"]
         TestWikiCMS.getSMW_WikiUser(wikiId)
     server.store()
     server.load()
     return server
Example #4
0
 def initServer():
     '''
     initialize the server
     '''
     Server.homePath = "/tmp"
     server = Server()
     server.logo = "https://upload.wikimedia.org/wikipedia/commons/thumb/6/65/Desmond_Llewelyn_01.jpg/330px-Desmond_Llewelyn_01.jpg"
     server.frontendConfigs = [{
         'site': 'orth',
         'wikiId': 'orth',
         'template': 'bootstrap.html',
         'defaultPage': 'Frontend'
     }]
     for frontendConfigs in server.frontendConfigs:
         # make sure ini file is available
         wikiId = frontendConfigs["wikiId"]
         TestWikiCMS.getSMW_WikiUser(wikiId)
     server.store()
     server.load()
     return server
Example #5
0
    def testSQL(self):
        '''
        try out SQL access with SQL Alchemy
        '''
        server = Server()
        server.load()
        app = Flask(__name__)
        app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

        if "credentials" in server.__dict__:
            server.hostname = "capri.bitplan.com"
            cred = server.credentials[0]
            user = cred["user"]
            password = cred["password"]
            dbname = cred["dbname"]
            dburl = server.sqlGetDatabaseUrl(dbname, user, password)

            dbExists = server.sqlDatabaseExist(dburl)
            self.assertTrue(dbExists)
            app.config["SQLALCHEMY_DATABASE_URI"] = dburl
            sqldb = SQLAlchemy(app)
        pass
Example #6
0
class WikiCMSWeb(AppWrap):
    ''' 
    Wrapper for Flask Web Application 
    '''
    
    def __init__(self, host='0.0.0.0', port=8251, debug=False):
        '''
        constructor
        
        Args:
            wikiId(str): id of the wiki to use as a CMS backend
            host(str): flask host
            port(int): the port to use for http connections
            debug(bool): True if debugging should be switched on
        '''
        scriptdir = os.path.dirname(os.path.abspath(__file__))
        template_folder=scriptdir + '/../templates'
        super().__init__(host=host,port=port,debug=debug,template_folder=template_folder)
        self.app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
        db.init_app(self.app)
        self.db=db
        self.loginBluePrint=LoginBluePrint(self.app,'login')
        self.server = Server()
        self.server.load()
        self.enabledSites = ['admin']
        
        #
        # setup global handlers
        #
        @self.app.before_first_request
        def before_first_request_func():
            self.initDB()
            loginMenuList=self.adminMenuList("Login")
            self.loginBluePrint.setLoginArgs(menuList=loginMenuList)
            
        @self.app.route('/')
        def index():
            return self.family()

        @self.app.route('/family')
        def family():
            return wcw.family()    
            
        @login_required
        @self.app.route('/wikis')
        def wikis():
            return self.wikis()
        
        @login_required
        @self.app.route('/frontends')
        def frontends():
            return wcw.frontends()

        @login_required
        @self.app.route('/generate/<string:siteName>', methods=['GET', 'POST'])
        def generate(siteName: str):
            '''
            Handle wiki generator page request
            Args:
                siteName(str): wikiId of the wiki the generator should be returned for
            '''
            return self.generate(siteName)

    def initDB(self):
        '''
        initialize the database
        '''
        self.db.drop_all()
        self.db.create_all()
        self.initUsers()
    
    def initUsers(self):
        if hasattr(self.server,"adminUser"):
            self.loginBluePrint.addUser(self.db,self.server.adminUser,self.server.adminPassword)
        else:
            self.loginBluePrint.hint="There is no adminUser configured yet"
        
    @staticmethod
    def splitPath(path):
        '''
        split the given path
        Args:
            path(str): the path to split
        Returns:
            str,str: the site of the path an the actual path
        '''
        # https://stackoverflow.com/questions/2136556/in-python-how-do-i-split-a-string-and-keep-the-separators
        parts = path.split(r"/")
        site = ""
        if len(parts) > 0:
            site = parts[0]
        path = ""
        if len(parts) > 1:
            for part in parts[1:]:
                path = path + "/%s" % (part)
        return site, path    
    
    def enableSites(self, siteNames):
        '''
        enable the sites given in the sites list
        Args:
            siteNames(list): a list of strings with wikiIds to be enabled
        '''
        if siteNames is None:
            return
        for siteName in siteNames:
            self.server.enableFrontend(siteName,self)
            self.enabledSites.append(siteName)
            
    def adminMenuList(self,activeItem:str=None):
        '''
        get the list of menu items for the admin menu
        Args:
            activeItem(str): the active  menu item
        Return:
            list: the list of menu items
        '''
        menuList=[
            MenuItem('/','Home'),
            MenuItem('https://github.com/BITPlan/pyWikiCMS','github'),
            MenuItem('/generate/orth', 'Generator') # ToDo: Test Values
            ]
        if current_user.is_anonymous:
            menuList.append(MenuItem('/login','login'))
        else:
            menuList.append(MenuItem('/wikis','Wikis')),
            menuList.append(MenuItem('/frontends','Frontends')),
            menuList.append(MenuItem('/logout','logout'))
        
        if activeItem is not None:
            for menuItem in menuList:
                if menuItem.title==activeItem:
                    menuItem.active=True
                if menuItem.url.startswith("/"):
                    menuItem.url="%s%s" % (self.baseUrl,menuItem.url)
        return menuList
            
    def frontends(self) -> str:
        '''
        render the frontends view
        
        Returns:
            str: the html for the admin view
        '''
        menuList=self.adminMenuList("Frontends")
        html = render_template("tableview.html", title="Frontends", menuList=menuList,dictList=self.server.frontendConfigs)
        return html
    
    def wikis(self) -> str:
        '''
        render the wikis table
        
        Returns:
            str: the html code for the table of wikis
        '''
        wikiUsers = WikiUser.getWikiUsers()
        dictList = []
        for wikiUser in wikiUsers.values():
            url="%s%s/" % (wikiUser.url,wikiUser.scriptPath)
            wikiBackup=WikiBackup(wikiUser)
            dictList.append({
                'wikiId': Link(url,wikiUser.wikiId),
                'url': Link(wikiUser.url,wikiUser.url),
                'scriptPath':wikiUser.scriptPath,
                'version':wikiUser.version,
                'backup': "✅" if wikiBackup.exists() else "❌",
                'git': Icon("github",32) if wikiBackup.hasGit() else ""
            })
        menuList=self.adminMenuList("Wikis")      
        html = render_template("tableview.html", menuList=menuList,title="Wikis", dictList=dictList)
        return html    
    
    def logo(self, siteName:str) -> str:
        '''
        render the Logo for the given siteName
        
        Args:
            siteName(str): the name of the site e.g. wiki.bitplan.com
        Returns:
            the rendered Logo for the given Site
        '''
        wikiFamily = WikiFamily()
        if not siteName in wikiFamily.family:
            return self.error("Logo Error","invalid siteName %s" % siteName)
        wiki=wikiFamily.family[siteName]
        logoFile=wiki.getLogo()
        if logoFile is None:
            return "no logo for %s" %siteName
        else:
            return send_file(logoFile)
    
    def family(self) -> str:
        '''
        show a html representation of the family of wikis on this server (if any)
        
        Returns:
            str: a html table of all wikis in the family
        '''
        dictList = []
        wikiFamily = WikiFamily()
        for siteName in wikiFamily.family:
            localWiki = wikiFamily.family[siteName]
            logoAccess="%s/family/%s/logo" % (self.baseUrl,siteName)
            apacheAvailable=self.server.checkApacheConfiguration(localWiki.siteId,'available')
            apacheEnabled=self.server.checkApacheConfiguration(localWiki.siteId,'enabled')
            dbName=localWiki.database
            dburl=self.server.sqlGetDatabaseUrl(localWiki.database, localWiki.dbUser, localWiki.dbPassword,hostname='localhost')
            dbState=self.server.sqlDatabaseExist(dburl)
            dbStateSymbol=self.server.stateSymbol(dbState)
            backupState=self.server.sqlBackupStateAsHtml(dbName)
            hereState=self.server.stateSymbol(localWiki.ip==self.server.ip)
            statusSymbol="❌" 
            if localWiki.statusCode==200:
                statusSymbol="✅"
            elif localWiki.statusCode==404:
                statusSymbol="⚠️"
            siteDict={
                'site': "%s %s" % (Link(localWiki.url,localWiki.siteName),statusSymbol),
                'logo': Image(logoAccess,height=70),
            }
            if not current_user.is_anonymous:
                adminDict={
                   'database': "%s %s" % (localWiki.database,dbStateSymbol),
                   'SQL backup': backupState,
                    'ip': "%s%s" % (hereState,localWiki.ip),
                    'apache': "%s/%s" % (apacheAvailable,apacheEnabled)
                }  
                siteDict={**siteDict,**adminDict}
            dictList.append(siteDict)
        menuList=self.adminMenuList("Family")    
        html = render_template("welcome.html", server=self.server,menuList=menuList,title="Wiki Family", dictList=dictList)
        return html
        
    def wrap(self, siteName, path):
        '''
        wrap the given path for the given site
        Args:
            siteName(str): the name of the site to wrap
            path(path): the path to wrap
        '''
        if not siteName in self.enabledSites:
            error = "access to site '%s' is not enabled you might want to add it via the --sites command line option" % siteName
            content = None
            template = "index.html"
            title = "Error"
            return render_template(template, title=title, content=content, error=error)
        else:
            frontend = self.server.getFrontend(siteName) 
            return frontend.render(path)

    def generate(self, siteName):
        '''
        show generate page for given siteName (wikiId of wiki family member)
        Args:
            siteName(str): the name of the wiki
        Returns:
            the rendered generate page
        '''
        actuator = GenerateTopicForm.getActuatorTopic(request.form.lists())
        generator = Generator(siteName)
        menuList = self.adminMenuList("Generator")
        if actuator is not None:
            # Generate button was clicked
            generatedPages = generator.generatePages(actuator, dict(request.form.lists()))
            flash(f"Generated the following pages: {','.join(generatedPages)}", 'success')
        return generator.render(menuList)