Skip to content

Commit

Permalink
refactors to use nicegui and nicegui_widgets
Browse files Browse the repository at this point in the history
  • Loading branch information
WolfgangFahl committed Sep 22, 2023
1 parent 12c0df8 commit db85bbe
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 250 deletions.
2 changes: 1 addition & 1 deletion .project
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<name>pysotsog</name>
<comment></comment>
<projects>
<project>justpy</project>
<project>nicegui_widgets</project>
<project>pyJustpyWidgets</project>
<project>pyOnlineSpreadSheetEditing</project>
</projects>
Expand Down
6 changes: 2 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,12 @@ readme = "README.md"
# flit_core.config.ConfigError: license field should be <class 'dict'>, not <class 'str'>
license= "Apache-2.0"
dependencies = [
# https://github.com/justpy-org/justpy
'justpy>=0.12.1',
"nicegui",
"ngwidgets>=0.0.23",
# https://pypi.org/project/pylodstorage/
'pyLodStorage>=0.4.7',
# https://pypi.org/project/habanero/
'habanero~=1.2.2',
# https://pypi.org/project/pyJustpyWidgets/
'pyJustpyWidgets>=0.1.13',
# https://pypi.org/project/search-engine-parser/
'search-engine-parser>=0.6.8',
# https://github.com/fake-useragent/fake-useragent
Expand Down
224 changes: 70 additions & 154 deletions skg/skgbrowser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,77 +3,58 @@
@author: wf
'''
import html
import os
from jpcore.compat import Compatibility;Compatibility(0,11,1)
from jpcore.justpy_config import JpConfig
script_dir = os.path.dirname(os.path.abspath(__file__))
static_dir = script_dir+"/resources/static"
JpConfig.set("STATIC_DIRECTORY",static_dir)
# shut up justpy
JpConfig.set("VERBOSE","False")
JpConfig.setup()
from jpwidgets.bt5widgets import App,Link,About
from nicegui import ui, Client
from ngwidgets.input_webserver import InputWebserver
from ngwidgets.webserver import WebserverConfig
from ngwidgets.widgets import Link, Lang
from urllib import parse
from skg.search import SearchOptions
from skg.orcid import ORCID
from skg.scholargrid import ScholarGrid
from wikibot3rd.wikiuser import WikiUser
from skg.wikidata import Wikidata
from starlette.responses import JSONResponse
from skg.version import Version

class SkgBrowser(App):
class SkgBrowser(InputWebserver):
"""
scholary knowledge graph browser
"""

def __init__(self,version,sotsog,options:SearchOptions):
'''
Constructor

@classmethod
def get_config(cls)->WebserverConfig:
copy_right="(c)2022 Wolfgang Fahl"
if not hasattr(cls, "config"):
cls.config=WebserverConfig(copy_right=copy_right,version=Version(),default_port=8765)
return cls.config

def __init__(self):
"""Constructs all the necessary attributes for the WebServer object."""
config=SkgBrowser.get_config()
self.sotsog=config.sotsog
self.options=config.options
InputWebserver.__init__(self,config=config)
self.language="en"
self.wikiId="or"

Args:
version(Version): the version info for the app
'''
self.sotsog=sotsog
import justpy as jp
self.jp=jp
App.__init__(self, version)
self.addMenuLink(text='Home',icon='home', href="/")
self.addMenuLink(text='Scholars',icon='account-school',href='/scholars')
self.addMenuLink(text='github',icon='github', href=version.cm_url)
self.addMenuLink(text='Chat',icon='chat',href=version.chat_url)
self.addMenuLink(text='Documentation',icon='file-document',href=version.doc_url)
self.addMenuLink(text='Settings',icon='cog',href="/settings")
self.addMenuLink(text='About',icon='information',href="/about")
self.options=options
def configure_run(self):
self.markup_names=["-","bibtex","scite","smw"]
self.markup_name=self.markup_names[1]
# wiki users
self.wikiUsers=WikiUser.getWikiUsers()
self.wikiId=sotsog.args.wikiId
jp.Route('/scholars',self.scholars)
jp.Route('/settings',self.settings)
jp.Route('/about',self.about)
jp.Route('/hello2',self.hello)
self.wikiId=self.args.wikiId
wikidata=Wikidata()
self.sparql=wikidata.sparql

@self.jp.app.route("/hello/{name}", methods=['GET'])
async def say_hello_handler(request):
name = request.path_params['name']
if name=="jp":
return self.wp
msg=self.get_hello(name)
r=JSONResponse({'message': msg})
return r

def hello(self):
return self.wp
@ui.page('/scholars')
async def scholars(client: Client):
return await self.scholars(client)

def configure_menu(self):
"""
configure additional non-standard menu entries
"""
#self.link_button(name='Scholars',icon_name='account-school',target='/scholars')
pass

def get_hello(self,name:str):
msg='Hello,' + name
return msg

def createItemLink(self,item,term:str,index:int)->str:
"""
create a link for the given item
Expand Down Expand Up @@ -151,127 +132,62 @@ async def onChangeMarkup(self,msg):
self.markup_name=msg.value
except Exception as ex:
self.handleException(ex)

def setupRowsAndCols(self):
"""
setup the general layout
"""
head_html="""<link rel="stylesheet" href="/static/css/md_style_indigo.css">"""
self.wp=self.getWp(head_html)
self.button_classes = """btn btn-primary"""
# rows
self.rowA=self.jp.Div(classes="row",a=self.contentbox)
self.rowB=self.jp.Div(classes="row",a=self.contentbox)
self.rowC=self.jp.Div(classes="row",a=self.contentbox)
# columns
self.colA1=self.jp.Div(classes="col-12",a=self.rowA)
self.colB1=self.jp.Div(classes="col-6",a=self.rowB)
self.rowB1r1=self.jp.Div(classes="row",a=self.colB1)
self.colB11=self.jp.Div(classes="col-3",a=self.rowB1r1)
self.rowB1r2=self.jp.Div(classes="row",a=self.colB1)
self.colB12=self.jp.Div(classes="col-6",a=self.rowB1r2)
self.colB2=self.jp.Div(classes="col-6",a=self.rowB)
self.colC1=self.jp.Div(classes="col-12",a=self.rowC,style='color:black')
# standard elements
self.errors=self.jp.Div(a=self.colA1,style='color:red')
self.messages=self.jp.Div(a=self.colC1,style='color:black')

async def onChangeLanguage(self,msg):
"""
react on language being changed via Select control
"""
self.language=msg.value

async def onChangeWikiUser(self,msg):
"""
react on a the wikiuser being changed via a Select control
"""
self.wikiId=msg.value

def addLanguageSelect(self):
"""
add a language selector
"""
self.languageSelect=self.createSelect("Language","en",a=self.colB11,change=self.onChangeLanguage)
for language in self.getLanguages():
lang=language[0]
desc=language[1]
desc=html.unescape(desc)
self.languageSelect.add(self.jp.Option(value=lang,text=desc))

lang_dict=Lang.get_language_dict()
self.add_select("language:",lang_dict).bind_value(self, "language")

def addWikiUserSelect(self):
"""
add a wiki user selector
"""
if len(self.wikiUsers)>0:
self.wikiuser_select=self.createSelect("wikiId", value=self.wikiId, change=self.onChangeWikiUser, a=self.colB11)
wu_dict={}
for wikiUser in sorted(self.wikiUsers):
self.wikiuser_select.add(self.jp.Option(value=wikiUser,text=wikiUser))
wu_dict[wikiUser]=wikiUser
self.add_select("wiki:",wu_dict).bind_value(self,"wikiId")

async def scholars(self)->"jp.WebPage":
async def scholars(self,client:Client):
'''
scholar display
Returns:
jp.Webpage: a justpy webpage rendered with a grid of scholars
'''
self.setupRowsAndCols()
self.scholarsGrid=ScholarGrid(self,self.wikiUsers,self.wikiId,sparql=self.sparql)
# @TODO refactor the two setup calls to one to hide wdgrid details
self.scholarsGrid.setup(a=self.rowB, header=self.rowA)
self.scholarsGrid.wdgrid.setup(a=self.rowC)
return self.wp

async def settings(self)->"jp.WebPage":
'''
settings
Returns:
jp.WebPage: a justpy webpage renderer
'''
self.setupRowsAndCols()
self.setup_menu()
with ui.element("div").classes("w-full h-full"):
try:
self.scholarsGrid=ScholarGrid(self,self.wikiUsers,self.wikiId,sparql=self.sparql)
# @TODO refactor the two setup calls to one to hide wdgrid details
#self.scholarsGrid.setup(a=self.rowB, header=self.rowA)
#self.scholarsGrid.wdgrid.setup(a=self.rowC)
except BaseException as ex:
self.handle_exception(ex)
await self.setup_footer()

def configure_settings(self):
"""
configure settings
"""
self.addLanguageSelect()
self.addWikiUserSelect()
return self.wp

async def about(self)->"jp.WebPage":
'''
show about dialog
Returns:
jp.WebPage: a justpy webpage renderer
'''
self.setupRowsAndCols()
self.aboutDiv=About(a=self.colB1,version=self.version)
# @TODO Refactor to pyJustpyWidgets
return self.wp

async def content(self)->"jp.WebPage":
async def home(self,_client:Client):
'''
provide the main content page
Returns:
jp.WebPage: a justpy webpage renderer
'''
self.setupRowsAndCols()
self.results=self.jp.Div(a=self.colC1)
self.markup=self.colB2
# sotsog search
self.markup_select = self.createSelect("markup",
value=self.markup_name,
change=self.onChangeMarkup,
a=self.colB11)
for markup_name in self.markup_names:
self.markup_select.add(self.jp.Option(value=markup_name,text=markup_name))
#self.conceptSelection=
self.searchTerms=self.jp.Textarea(placeholder="enter search terms", a=self.colB12, rows=5,cols=120)
self.searchButton=self.jp.Button(text="search",click=self.onSearchButton,a=self.colB12,classes=self.button_classes)
return self.wp

def start(self,host,port,debug):
"""
start the server
"""
self.debug=debug
import justpy as jp
jp.justpy(self.content,host=host,port=port)
self.setup_menu()
with ui.element("div").classes("w-full h-full"):
self.results=ui.element("div")
#self.markup=self.colB2
# sotsog search
self.markup_select = ui.select(options=self.markup_names)
#value=self.markup_name,
#change=self.onChangeMarkup,
#a=self.colB11)
#self.conceptSelection=
self.searchTerms=ui.textarea(placeholder="enter search terms")
self.searchButton=ui.button("search",on_click=self.onSearchButton)
await self.setup_footer()
Loading

0 comments on commit db85bbe

Please sign in to comment.