This commit is contained in:
yumoqing 2020-01-08 18:04:39 +08:00
parent edce30e08f
commit 0249db446b
13 changed files with 738 additions and 154 deletions

520
kivyblocks/blocks.bak.py Normal file
View File

@ -0,0 +1,520 @@
import os
import sys
import codecs
import json
from traceback import print_exc
from functools import partial
from appPublic.dictExt import dictExtend
from appPublic.jsonConfig import getConfig
from appPublic.folderUtils import ProgramPath
from appPublic.dictObject import DictObject
from appPublic.Singleton import SingletonDecorator
from kivy.config import Config
from kivy.metrics import sp,dp,mm
from kivy.core.window import WindowBase
from kivy.properties import BooleanProperty
from kivy.uix.widget import Widget
from kivy.app import App
from .baseWidget import *
from .widgetExt import Messager
from .externalwidgetmanager import ExternalWidgetManager
from .threadcall import HttpClient
from .toolbar import *
from .dg import DataGrid
from .utils import *
from .ready import WidgetReady
from .serverImageViewer import ServerImageViewer
from .vplayer import VPlayer
from .form import InputBox, Form, StrSearchForm
from .boxViewer import BoxViewer
def showError(e):
print('error',e)
class WidgetNotFoundById(Exception):
def __init__(self, id):
super().__init__()
self.idstr = id
def __str__(self):
return "Widget not found by id:" + self.idstr + ':'
def __expr__(self):
return str(self)
class ClassMethodNotFound(Exception):
def __init__(self,k,m):
super().__init__()
self.kname = k
self.mname = m
def __str__(self):
s = 'Method(%s) not found in class(%s)' % (self.mname,
str(self.kname.__classname__))
return s
def __expr__(self):
return self.__str__()
class NotExistsObject(Exception):
def __init__(self,name):
super().__init__()
self.name = name
def __str__(self):
s = 'not exists widget(%s)' % self.name
return s
def __expr__(self):
return self.__str__()
class ArgumentError(Exception):
def __init__(self,argument,desc):
super().__init__()
self.argument = argument
self.desc = desc
def __str__(self):
s = 'argument(%s) missed:%s' % (self.argument,self.desc)
return s
def __expr__(self):
return self.__str__()
class NotRegistedWidget(Exception):
def __init__(self,name):
super().__init__()
self.widget_name = name
def __str__(self):
s = 'not reigsted widget(%s)' % self.name
return s
def __expr__(self):
return self.__str__()
@SingletonDecorator
class RegistedFunction:
def __init__(self):
self.rf_list = {}
def register(self,name,func):
self.rf_list[name] = func
def get(self,name):
return self.rf_list.get(name)
def registerWidget(name,widget):
globals()[name] = widget
class Blocks:
registedWidgets = {}
def __init__(self):
self.action_id = 0
def register_widget(self,name,widget):
globals()[name] = widget
def buildAction(self,widget,desc):
self.action_id += 1
fname = 'action%d' % self.action_id
l = {
}
body="""def %s(widget,obj=None, v=None):
jsonstr='''%s'''
print(type(widget), type(obj),v,'action():desc=',jsonstr)
desc = json.loads(jsonstr)
app = App.get_running_app()
app.blocks.uniaction(widget, desc)
print('finished')
""" % (fname, json.dumps(desc))
exec(body,globals(),l)
f = l.get(fname,None)
if f is None:
raise Exception('None Function')
func =partial(f,widget)
return func
setattr(widget,fname,f)
return getattr(widget,fname)
def eval(self,s,l):
g = {}
forbidens = [
"os",
"sys",
"codecs",
"json",
]
for k,v in globals().copy().items():
if k not in forbidens:
g[k] = v
g['__builtins__'] = globals()['__builtins__'].copy()
g['__builtins__']['__import__'] = None
g['__builtins__']['__loader__'] = None
g['__builtins__']['open'] = None
return eval(s,g,l)
def getUrlData(self,kw,parenturl=None):
url = kw.get('url')
method = kw.get('method','GET')
params = kw.get('params',{})
if url is None:
print('kw=',kw)
raise ArgumentError('url','getUrlData() miss a url argument')
url = absurl(url,parenturl)
if url.startswith('file://'):
filename = url[7:]
print(filename)
with codecs.open(filename,'r','utf-8') as f:
b = f.read()
dic = json.loads(b)
else:
dic = App.get_running_app().hc(url,method=method,params=params)
return dic, url
def register(self,name : str ,base:str=None,
defaultOpts:dict={},optkeys:list=[],
properties:list=[]):
"""
"""
self.registedWidgets[name] = {
"defaultOpts":defaultOpts,
"base":base,
"properties":properties, # property: 0 name, 1 type
"optkeys":optkeys,
"infos":{}
}
def buildRegistedWidgetInfo(self, widgettype:str):
"""
setup registed widget defaultOpts and optkeys
by merge its and it's bases widgets
"""
rw = self.registedWidgets.get(widgettype)
if not rw:
raise NotRegistedWidget(widgettype)
rw['infos']['defaultOpts'] = rw['defaultOpts']
rw['infos']['optkeys'] = rw['optkeys']
for b in base:
brw = self.registedWidgets.get(b)
if not brw:
raise NotRegistedWidget(b)
opts = self.getWidgetOptions(b)
opts.update(rw['defaultOpts'])
rw['infos']['defaultOpts'].update({'defaultOpts':opts})
rw['infos']['optkeys'] = list(set(self.getWidgetOptkeys(b) + rw['infos']['optkeys']))
return rw['infos']
def getWidgetOptkeys(self,widgettype:str):
"""
"""
if widgettype not in self.registedWidgets.keys():
raise NotRegistedWidget(widgettype)
infos = self.registedWidgets.get(widgettype)['infos']
if infos == {}:
infos = self.buildRegistedWidgetInfo(widgettype)
return infos['optkeys']
def getWidgetOptions(self,widgettype:str, opts:dict={}):
"""
get widget type valid options, from it's registed info
and it given argument:opts
"""
if widgettype not in self.registedWidgets.keys():
raise NotRegistedWidget(widgettype)
infos = self.registedWidgets.get(widgettype)['infos']
if infos == {}:
infos = self.buildRegistedWidgetInfo(widgettype)
opt = infos['defaultOpts']
keys = opts.keys()
for k in infos['optkeys']:
if k in keys:
opt.update({k:opts[k]})
return opt
def getObject(self,klass:str ,bases:list=[],
properties:list=[]):
pstrs = [ "%s = %s\n" % (n,t) for n, t in properties ]
if klass not in globals().keys():
script="""
class %s(%s):
%s
def __init__(self):
super().__init__()
""" % (klass, '\t'.join(pstrs),','.join(bases))
exec(script,globals(),globals())
return globals().get(klass)()
def isBaseWidget(self,widgettype):
rw = self.registedWidgets.get(widgettype)
if not rw:
raise NotRegistedWidget(widgettype)
return rw['bases'] == []
def getBases(self, widgettype:str):
rw = self.registedWidgets.get(widgettype)
if not rw:
raise NotRegistedWidget(widgettype)
return rw['bases']
def strValueExpr(self,s:str,localnamespace:dict={}):
if not s.startswith('py::'):
return s
try:
v = self.eval(s[4:],localnamespace)
return v
except Exception as e:
if s.startswith('CSize'):
print('Exception .... ',e,s)
print_exc()
return s
def arrayValueExpr(self,arr:list,localnamespace:dict={}):
d = []
for v in arr:
if type(v) == type(''):
d.append(self.strValueExpr(v,localnamespace))
continue
if type(v) == type([]):
d.append(self.arrayValueExpr(v,localnamespace))
continue
if type(v) == type({}):
d.append(self.dictValueExpr(v,localnamespace))
continue
if type(v) == type(DictObject):
d.append(self.dictValueExpr(v,localnamespace))
continue
d.append(v)
return d
def dictValueExpr(self,dic:dict,localnamespace:dict={}):
d = {}
for k,v in dic.items():
if type(v) == type(''):
d[k] = self.strValueExpr(v,localnamespace)
continue
if type(v) == type([]):
d[k] = self.arrayValueExpr(v,localnamespace)
continue
if type(v) == type({}):
d[k] = self.dictValueExpr(v,localnamespace)
continue
if type(v) == type(DictObject):
d[k] = self.dictValueExpr(v,localnamespace)
continue
d[k] = v
return d
def valueExpr(self,obj,localnamespace={}):
if type(obj) == type(''):
return self.strValueExpr(obj,localnamespace)
if type(obj) == type([]):
return self.arrayValueExpr(obj,localnamespace)
if type(obj) in [ type({}), type(DictObject) ]:
return self.dictValueExpr(obj,localnamespace)
return obj
def __build(self,desc:dict,ancestor=None):
def checkReady(w,o):
print('checkReady():w=',w,'o=',o)
w.children_ready[o] = True
if all(w.children_ready.values()):
w.ready = True
widgetClass = desc.get('widgettype',None)
if not widgetClass:
print("__build(), desc invalid", desc)
raise Exception(desc)
widgetClass = desc['widgettype']
opts = desc.get('options',{})
klass = globals().get(widgetClass)
if not klass:
raise NotExistsObject(widgetClass)
widget = klass(**opts)
if desc.get('parenturl'):
widget.parenturl = desc.get('parenturl')
ancestor = widget
if desc.get('id'):
myid = desc.get('id')
holder = ancestor
if ancestor == widget:
app = App.get_running_app()
holder = app.root
if not hasattr(holder,'widget_ids'):
setattr(holder,'widget_ids',{})
holder.widget_ids[myid] = widget
widget.build_desc = desc
self.build_rest(widget,desc,ancestor)
# f = partial(self.build_rest,widget,desc,ancestor)
# event = Clock.schedule_once(f,0)
return widget
def build_rest(self, widget,desc,ancestor,t=None):
for sw in desc.get('subwidgets',[]):
w = self.widgetBuild(sw, ancestor=ancestor)
if w is None:
continue
w.parenturl = widget.parenturl
widget.add_widget(w)
if hasattr(widget,'addChild'):
widget.addChild(w)
for b in desc.get('binds',[]):
self.buildBind(widget,b)
if hasattr(widget, 'built'):
widget.built()
def buildBind(self,widget,desc):
wid = desc.get('wid','self')
w = self.getWidgetByIdPath(widget,wid)
event = desc.get('event')
if event is None:
return
f = self.buildAction(widget,desc)
w.bind(**{event:f})
def uniaction(self,widget,desc):
acttype = desc.get('actiontype')
if acttype=='blocks':
return self.blocksAction(widget,desc)
if acttype=='urlwidget':
return self.urlwidgetAction(widget,desc)
if acttype == 'registedfunction':
return self.registedfunctionAction(widget,desc)
if acttype == 'script':
return self.scriptAction(widget, desc)
if acttype == 'method':
return self.methodAction(widget, desc)
alert(msg="actiontype invalid",title=acttype)
def blocksAction(widget,desc):
target = self.getWidgetByIdPath(widget, desc.get('target','self'))
add_mode = desc.get('mode','replace')
opts = desc.get('options')
d = self.getActionData(widget,desc)
p = opts.get('options',{})
p.update(d)
opts['options'] = p
x = self.widgetBuild(opts,ancestor=widget)
if x is None:
alert(str(opts), title='widugetBuild error')
return
if add_mode == 'replace':
target.clear_widgets()
target.add_widget(x)
def urlwidgetAction(self,widget,desc):
target = self.getWidgetByIdPath(widget, desc.get('target','self'))
add_mode = desc.get('mode','replace')
opts = desc.get('options')
d = self.getActionData(widget,desc)
p = opts.get('params',{})
p.update(d)
opts['params'] = p
d = {
'widgettype' : 'urlwidget'
}
d['options'] = opts
x = self.widgetBuild(d,ancestor=widget)
if x is None:
return
if add_mode == 'replace':
target.clear_widgets()
target.add_widget(x)
def getActionData(self,widget,desc):
data = {}
if desc.get('datawidget',False):
dwidget = self.getWidgetByIdPath(widget,
desc.get('datawidget'))
data = dwidget.getData()
return data
def registedfunctionAction(self, widget, desc):
rf = RegistedFunction()
name = desc.get('rfname')
func = rf.get(name)
params = desc.get(params,{})
d = self.getActionData(widget,desc)
params.update(d)
func(params)
def scriptAction(self, widget, desc):
script = desc.get('script')
if script:
self.eval(script, {'self': widget})
def methodAction(self, widget, desc):
method = desc.get('method')
target = self.getWidgetByIdPath(widget, desc.get('target','self'))
if hasattr(target,method):
f = getattr(target, method)
kwargs = desc.get('options',{})
d = self.getActionData(widget,desc)
kwargs.update(d)
f(**kwargs)
else:
alert('%s method not found' % method)
def widgetBuild(self,desc,ancestor=None):
"""
desc format:
{
widgettype:<registered widget>,
id:widget id,
options:
subwidgets:[
]
binds:[
]
}
"""
name = desc['widgettype']
if name == 'urlwidget':
opts = desc.get('options')
parenturl = None
if ancestor:
parenturl = ancestor.parenturl
desc, parenturl = self.getUrlData(opts,parenturl)
if not isinstance(desc,dict):
print("getUrlData() return error data",opts,parenturl)
alert(str(dict) + 'format error')
return None
desc = self.valueExpr(desc)
desc['parenturl'] = parenturl
try:
widget = self.__build(desc,ancestor=ancestor)
return widget
except:
print('widgetBuild() Error',desc)
print_exc()
alert(str(desc))
return None
def getWidgetByIdPath(self,widget,path):
ids = path.split('/')
if ids[0] == '':
app = App.get_running_app()
widget = app.root
ids = ids[1:]
for id in ids:
if id == 'self':
return widget
widget = widget.widget_ids.get(id,None)
if widget is None:
print('widget not found,path=',path,'id=',id,'ids=',ids)
raise WidgetNotFoundById(id)
return widget

View File

@ -181,93 +181,6 @@ class Blocks:
dic = App.get_running_app().hc(url,method=method,params=params)
return dic, url
def register(self,name : str ,base:str=None,
defaultOpts:dict={},optkeys:list=[],
properties:list=[]):
"""
"""
self.registedWidgets[name] = {
"defaultOpts":defaultOpts,
"base":base,
"properties":properties, # property: 0 name, 1 type
"optkeys":optkeys,
"infos":{}
}
def buildRegistedWidgetInfo(self, widgettype:str):
"""
setup registed widget defaultOpts and optkeys
by merge its and it's bases widgets
"""
rw = self.registedWidgets.get(widgettype)
if not rw:
raise NotRegistedWidget(widgettype)
rw['infos']['defaultOpts'] = rw['defaultOpts']
rw['infos']['optkeys'] = rw['optkeys']
for b in base:
brw = self.registedWidgets.get(b)
if not brw:
raise NotRegistedWidget(b)
opts = self.getWidgetOptions(b)
opts.update(rw['defaultOpts'])
rw['infos']['defaultOpts'].update({'defaultOpts':opts})
rw['infos']['optkeys'] = list(set(self.getWidgetOptkeys(b) + rw['infos']['optkeys']))
return rw['infos']
def getWidgetOptkeys(self,widgettype:str):
"""
"""
if widgettype not in self.registedWidgets.keys():
raise NotRegistedWidget(widgettype)
infos = self.registedWidgets.get(widgettype)['infos']
if infos == {}:
infos = self.buildRegistedWidgetInfo(widgettype)
return infos['optkeys']
def getWidgetOptions(self,widgettype:str, opts:dict={}):
"""
get widget type valid options, from it's registed info
and it given argument:opts
"""
if widgettype not in self.registedWidgets.keys():
raise NotRegistedWidget(widgettype)
infos = self.registedWidgets.get(widgettype)['infos']
if infos == {}:
infos = self.buildRegistedWidgetInfo(widgettype)
opt = infos['defaultOpts']
keys = opts.keys()
for k in infos['optkeys']:
if k in keys:
opt.update({k:opts[k]})
return opt
def getObject(self,klass:str ,bases:list=[],
properties:list=[]):
pstrs = [ "%s = %s\n" % (n,t) for n, t in properties ]
if klass not in globals().keys():
script="""
class %s(%s):
%s
def __init__(self):
super().__init__()
""" % (klass, '\t'.join(pstrs),','.join(bases))
exec(script,globals(),globals())
return globals().get(klass)()
def isBaseWidget(self,widgettype):
rw = self.registedWidgets.get(widgettype)
if not rw:
raise NotRegistedWidget(widgettype)
return rw['bases'] == []
def getBases(self, widgettype:str):
rw = self.registedWidgets.get(widgettype)
if not rw:
raise NotRegistedWidget(widgettype)
return rw['bases']
def strValueExpr(self,s:str,localnamespace:dict={}):
if not s.startswith('py::'):
return s
@ -376,9 +289,6 @@ class %s(%s):
widget.built()
def buildBind(self,widget,desc):
body="""
"""
wid = desc.get('wid','self')
w = self.getWidgetByIdPath(widget,wid)
event = desc.get('event')
@ -389,6 +299,8 @@ class %s(%s):
def uniaction(self,widget,desc):
acttype = desc.get('actiontype')
if acttype=='blocks':
return self.blocksAction(widget,desc)
if acttype=='urlwidget':
return self.urlwidgetAction(widget,desc)
if acttype == 'registedfunction':
@ -399,6 +311,22 @@ class %s(%s):
return self.methodAction(widget, desc)
alert(msg="actiontype invalid",title=acttype)
def blocksAction(widget,desc):
target = self.getWidgetByIdPath(widget, desc.get('target','self'))
add_mode = desc.get('mode','replace')
opts = desc.get('options')
d = self.getActionData(widget,desc)
p = opts.get('options',{})
p.update(d)
opts['options'] = p
x = self.widgetBuild(opts,ancestor=widget)
if x is None:
alert(str(opts), title='widugetBuild error')
return
if add_mode == 'replace':
target.clear_widgets()
target.add_widget(x)
def urlwidgetAction(self,widget,desc):
target = self.getWidgetByIdPath(widget, desc.get('target','self'))
add_mode = desc.get('mode','replace')
@ -437,8 +365,15 @@ class %s(%s):
def scriptAction(self, widget, desc):
script = desc.get('script')
if script:
self.eval(script, {'self': widget})
if not script:
return
target = self.getWidgetByIdPath(widget, desc.get('target','self'))
d = self.getActionData(widget,desc)
ns = {
"self":target
}
ns.update(d)
self.eval(script, ns)
def methodAction(self, widget, desc):
method = desc.get('method')

View File

@ -51,6 +51,7 @@ class BlocksApp(App):
self.hc = HttpClient()
WindowBase.softinput_mode='below_target'
Clock.schedule_once(self.build1)
print('build() called......')
return x
def setUserInfo(self,uinfo):
@ -60,6 +61,9 @@ class BlocksApp(App):
d['authcode'] = uinfo.get('authcode','')
self.userinfo = d
def on_start(self):
print('on_start() called ...')
def build1(self,t):
x = None
x = self.blocks.widgetBuild(self.config.root)

View File

@ -103,4 +103,5 @@ class BoxViewer(BoxLayout):
self.dispatch('on_selected',o.getRecord())
def getData(self):
self.selected_data['__dataloader__'] = self.dataloader
return self.selected_data

View File

@ -1,12 +1,14 @@
from kivy.uix.textinput import TextInput
from kivy.uix.boxlayout import BoxLayout
from kivy.core.window import Window
from kivycalendar import DatePicker
from .responsivelayout import VResponsiveLayout
from .widgetExt.inputext import FloatInput,IntegerInput, \
StrInput,SelectInput, BoolInput, AmountInput, Password
from .baseWidget import *
from kivycalendar import DatePicker
from .utils import *
from .i18n import getI18n
from .i18n import I18nText, I18n
from .toolbar import Toolbar
"""
form options
{
@ -43,6 +45,10 @@ uitypes = {
"orientation":"horizontal",
"wclass":StrInput,
},
"password":{
"orientation":"horizontal",
"wclass":Password,
},
"number":{
"orientation":"horizontal",
"wclass":IntegerInput,
@ -92,7 +98,7 @@ class InputBox(BoxLayout):
def __init__(self, form, **options):
self.form = form
self.options = options
self.uitype = options.get('uityoe','string')
self.uitype = options.get('uitype','string')
self.uidef = uitypes[self.uitype]
orientation = self.uidef['orientation']
width = self.form.inputwidth
@ -101,7 +107,7 @@ class InputBox(BoxLayout):
kwargs = {
"orientation":orientation,
"size_hint_y":None,
"height":CSzie(height)
"height":height
}
if width <= 1:
kwargs['size_hint_x'] = width
@ -114,8 +120,11 @@ class InputBox(BoxLayout):
pos=self.setSize)
self.register_event_type("on_datainput")
def on_datainput(self,o,v=None):
print('on_datainput fired ...',o,v)
def init(self):
i18n = getI18n()
i18n = I18n()
if self.initflag:
return
label = self.options.get('label',self.options.get('name'))
@ -123,7 +132,9 @@ class InputBox(BoxLayout):
label = label + '*'
kwargs = {
"otext":label,
"font_size":CSize(1)
"font_size":CSize(1),
"size_hint_y":None,
"height":CSize(2)
}
if self.labelwidth<=1:
kwargs['size_hint_x'] = self.labelwidth
@ -139,6 +150,7 @@ class InputBox(BoxLayout):
if self.options.get('tip'):
options['hint_text'] = i18n(self.options.get('tip'))
print('uitype=',self.options['uitype'], self.uitype, 'uidef=',self.uidef)
self.input_widget = self.uidef['wclass'](**options)
if self.options.get('readonly'):
self.input_widget.disabled = True
@ -166,13 +178,13 @@ class InputBox(BoxLayout):
self.input_widget.setValue(v)
def getValue(self):
return self.input_widget.getValue()
return {self.options.get('name'):self.input_widget.getValue()}
def defaultToolbar():
return {
img_size:1.5,
text_size:0.7,
tools:[
"img_size":1.5,
"text_size":0.7,
"tools":[
{
"name":"__submit",
"img_src":blockImage("clear.png"),
@ -197,12 +209,6 @@ class Form(BoxLayout):
self.cols = 1
self.inputwidth = Window.width / self.cols
self.inputheight = CSize(self.options.get('inputheight',3))
self.toolbar = Toolbar(options.get('toolbar',defaultToolbar()))
self.fsc = VResponsiveLayout(cols=self.cols,
box_width=self.inputwidth)
self.add_widget(self.toolbar)
self.add_widget(self.fsc)
self.register_event_type('on_submit')
self.initflag = False
self.bind(size=self.on_size,
pos=self.on_size)
@ -210,20 +216,41 @@ class Form(BoxLayout):
def init(self):
if self.initflag:
return
self.toolbar = Toolbar(ancestor=self,**self.options.get('toolbar',defaultToolbar()))
self.fsc = VResponsiveLayout(cols=self.cols,
box_width=self.inputwidth)
self.add_widget(self.toolbar)
self.add_widget(self.fsc)
self.register_event_type('on_submit')
self.fieldWidgets=[]
for f in self.options['fields']:
w = InputBox(self, self, **f)
w = InputBox(self, **f)
# print('w size=',w.size)
self.fsc.add_widget(w)
self.fieldWidgets.append(w)
blocks = App.get_running_app().blocks
wid = getWidgetById(self,'__submit')
wid = self.widget_ids['__submit']
# wid = getWidgetById(self,'__submit')
# print('ids=',self.widget_ids.keys())
wid.bind(on_press=self.on_submit_button)
wid = getWidgetById(self,'__clear')
# wid = getWidgetById(self,'__clear')
wid = self.widget_ids['__clear']
wid.bind(on_press=self.on_clear_button)
self.initflag = True
def getData(self):
d = {}
for f in self.fieldWidgets:
v = f.getValue()
d.update(v)
return d
def on_submit(self,o,v=None):
print(o,v)
def on_submit_button(self,o,v=None):
self.dispatch('on_submit')
d = self.getData()
self.dispatch('on_submit',self,d)
def on_clear_button(self,o,v=None):
for fw in self.fieldWidgets:

15
kivyblocks/gps.py Normal file
View File

@ -0,0 +1,15 @@
from pyler import gps
class GPS:
def __init__(self):
gps.configure(on_location=self.on_location, on_status=self.on_status)
gps.start()
def on_location(self, **kw):
pass
def on_status(self,**kw):
def __del__(self):
gps.stop()

View File

@ -7,9 +7,8 @@ from .baseWidget import Text
@SingletonDecorator
class I18n:
def __init__(self,url):
def __init__(self):
self.kvlang={}
self.loadUrl = url
self.lang = locale.getdefaultlocale()[0]
self.loadI18n(self.lang)
self.i18nWidgets = []
@ -18,11 +17,11 @@ class I18n:
self.i18nWidgets.append(w)
def loadI18n(self,lang):
if not self.loadUrl:
self.kvlang[lang] = {}
return
app = App.get_running_app()
d = app.hc.get('%s?lang=%s' % (self.loadUrl,lang))
config = getConfig()
url = '%s%s/%s' % (config.uihome, config.i18n_url, lang)
d = app.hc.get(url)
print('i18n() %s get data=' % url, d, type(d))
self.kvlang[lang] = d
def __call__(self,msg,lang=None):
@ -39,10 +38,6 @@ class I18n:
for w in self.i18nWidgets:
w.changeLang(lang)
def getI18n(url=None):
i18n=I18n(url)
return i18n
class I18nText(Text):
lang=StringProperty('')
otext=StringProperty('')
@ -53,7 +48,7 @@ class I18nText(Text):
if kw.get('otext'):
del kw['otext']
super().__init__(**kw)
self.i18n = getI18n()
self.i18n = I18n()
self.i18n.addI18nWidget(self)
self.otext = otext

View File

@ -0,0 +1,36 @@
import os
from appPublic.folderUtils import listFile
from kivy.utils import platform
from .paging import PageLoader
class FileLoader(PageLoader):
def __init__(self, folder='/DCIM',**options):
self.files = []
fold = os.path.abspath(folder)
self.params = options.get('params',{})
suffixes = self.parasm.get('suffixes',[])
rescursive = self.params.get('rescursive',True)
suffixs=[],rescursive=False
for f in listFile(fold, suffixs=suffixes, rescursive=resursive):
x = {
"id":f,
"name":f
}
self.files.append(x)
self.page_rows = options.get('page_rows',1)
self.loading = False
self.total_cnt = len(self.files)
self.total_page = self.total_cnt / self.page_rows
if self.total_cnt % self.page_rows != 0:
self.total_page += 1
self.curpage = 0
def loadPage(self,p):
if p < 1 or p > self.total_page:
return None
beg = self.page_rows * (p - 1)
end = beg + self.page_rows
return self.files[beg:end]

View File

@ -15,7 +15,7 @@ logformdesc = {
"name":"userid",
"label":"user name",
"datatype":"str",
"uitype":"str"
"uitype":"string"
},
{
"name":"passwd",
@ -26,12 +26,14 @@ logformdesc = {
]
},
"binds":[
"wid":"self",
"event":"on_submit",
"datawidegt":"self",
"actiontype":"registedfunction",
"rfname":"setupUserInfo"
}
{
"wid":"self",
"event":"on_submit",
"datawidegt":"self",
"actiontype":"registedfunction",
"rfname":"setupUserInfo"
}
]
}
@SingletonDecorator

View File

@ -28,6 +28,25 @@ class PagingButton(Button):
filter
}
"""
class HttpLoader:
def __init__(self, url, method, params):
self.page_rows = page_rows
self.url = url
self.method = method,
self.params = params
def setParams(self,params):
self.params = params
def load(self, callback, errback):
hc = App.get_running_app().hc
x = hc(self.url,
method=self.method,
params=self.params,
callback=callback,
errback=errback)
class PageLoader:
def __init__(self, **options):
self.loading = False
@ -36,12 +55,9 @@ class PageLoader:
self.filter = StrSearchForm(**options['filter'])
self.filter.bind(on_submit=self.do_search)
self.locater = options.get('locater')
self.params = options.get('params')
self.params = options.get('params',{})
self.method = options.get('method','GET')
self.url = options.get('dataurl')
if not self.url:
raise Exception('dataurl must be present:options=%s' % str(options))
self.total_cnt = 0
self.total_page = 0
self.page_rows = options.get('page_rows',0)
@ -83,12 +99,14 @@ class PageLoader:
self.dir = 'up'
def show_page(self,o,d):
p = self.curpage * self.page_rows + 1
p = (self.curpage - 1) * self.page_rows + 1
for r in d['rows']:
r['__posInSet__'] = p
p += 1
def loadPage(self,p):
if not self.url:
raise Exception('dataurl must be present:options=%s' % str(options))
self.curpage = p
self.loading = True
params = self.params.copy()
@ -123,6 +141,7 @@ class RelatedLoader(PageLoader):
def __init__(self, **options):
super().__init__(**options)
self.adder = options.get('adder')
self.locater = options.get('locater',None)
self.remover = options.get('remover')
self.clearer = options.get('clearer')
self.target = options.get('target')
@ -139,8 +158,6 @@ class RelatedLoader(PageLoader):
self.calculateTotalPage()
self.reload()
pass
def doBufferMaintain(self):
siz = len(self.objectPages.keys())
if siz >= self.MaxbufferPage:
@ -179,12 +196,13 @@ class RelatedLoader(PageLoader):
self.objectPages[self.curpage] = widgets
pages = len(self.objectPages.keys())
loc = 1.0 / float(pages)
if pages == 1:
self.locater(1)
elif self.dir == 'up':
self.locater(1 - loc)
else:
self.locater(loc)
if self.locater:
if pages == 1:
self.locater(1)
elif self.dir == 'up':
self.locater(1 - loc)
else:
self.locater(loc)
self.loading = False
print('buffer pages=',len(self.objectPages.keys()),'pages=',self.objectPages.keys())
@ -289,3 +307,15 @@ class Paging(PageLoader):
return
self.loadPage(self.total_page)
class OneRecordLoader(PageLoader):
def __init__(self,**options):
PageLoader.__init__(self,**options)
self.adder = options.get('adder')
self.page_rows = 1
def calculateTotalPage(self):
self.total_page = self.total_cnt
def show_page(self,o,d):
self.adder(d['rows'][0])

20
kivyblocks/playlist.py Normal file
View File

@ -0,0 +1,20 @@
class PlayListBase:
def __init__(self, player, url, params, curpos):
self.dataloader = RelatedLoader
def first(self):
pass
def next(self):
pass
def previous(self):
pass
def last(self):
pass
def getSource(self):
pass

View File

@ -5,6 +5,7 @@ import requests
from kivy.event import EventDispatcher
from kivy.clock import Clock
from kivy.app import App
from .login import LoginForm
class NeedLogin(Exception):
pass
@ -30,9 +31,6 @@ class ThreadCall(Thread,EventDispatcher):
try:
self.rez = self.target(*self.args,**self.kwargs)
self.dispatch('on_result',self.rez)
except NeedLogin as e:
lf = LoginForm()
lf.needlogin(url,method,params,headers,callback,errback)
except Exception as e:
self.dispatch('on_error',e)
@ -86,13 +84,13 @@ class HttpClient:
self.s = requests.Session()
self.workers = App.get_running_app().workers
def webcall(self,url,method="GET",params={},headers={}):
def webcall(self,url,method="GET",params={},files={},headers={}):
if method in ['GET']:
req = requests.Request(method,url,
params=params,headers=headers)
else:
req = requests.Request(method,url,
data=params,headers=headers)
data=params,files=files,headers=headers)
prepped = self.s.prepare_request(req)
resp = self.s.send(prepped)
if resp.status_code == 200:
@ -114,18 +112,18 @@ class HttpClient:
print('Error', url, method, params, resp.status_code,type(resp.status_code))
raise Exception('error:%s' % url)
def __call__(self,url,method="GET",params={},headers={},callback=None,errback=None):
def __call__(self,url,method="GET",params={},headers={},files={},callback=None,errback=None):
def cb(t,resp):
return resp
if callback is None:
try:
resp = self.webcall(url, method=method,
params=params, headers=headers)
params=params, files=files, headers=headers)
return cb(None,resp)
except NeedLogin as e:
lf = LoginForm()
lf.needlogin(url,method,params,headers,callback,errback)
lf.needlogin(url,method,params,files,headers,callback,errback)
return None
except Exception as e:
if errback is not None:
@ -135,6 +133,7 @@ class HttpClient:
"url":url,
"method":method,
"params":params,
"files":files,
"headers":headers
}
self.workers.add(self.webcall,callback,errback,kwargs=kwargs)
@ -143,8 +142,8 @@ class HttpClient:
return self.__call__(url,method='GET',params=params,
headers=headers, callback=callback,
errback=errback)
def post(self, url, params={}, headers={}, callback=None, errback=None):
return self.__call__(url,method='POST',params=params,
def post(self, url, params={}, headers={}, files={}, callback=None, errback=None):
return self.__call__(url,method='POST',params=params, files=files,
headers=headers, callback=callback,
errback=errback)

View File

@ -15,7 +15,7 @@
"root":{
"widgettype":"urlwidget",
"options":{
"url":"/toolpage.ui"
"url":"/test/loginform.ui"
}
}
}