[Python] mod_python ed il giusto handler
Andrea Giammarchi
andrea a 3site.it
Ven 18 Ago 2006 23:06:44 CEST
Lawrence Oluyede ha scritto:
> Mi scrivi 5 righe della parte Python di gestione della roba JS con la
> tua libreria?
ti posto in fondo tutta la libreria .. che è ancora alpha e non è
completa, ha diversi buchi, ma tutto sommato comincia a funzionare
> Non trovo un motivo valido per avere questa caratteristica
> sinceramente, magari mi sbaglio
esporti classi che hanno metodi utili per il JS
da JS usi queste classi, le istanzi, sfrutti gli oggetti già definiti
dalla lib e per ogni oggetto hai già i metodi e per ogni metodo i tre
metodi call, result, progress, puoi usarli tutti o nessuno
Questa è la parte che interessa il primo invio poi questi oggetti, visto
che hai esportato delle classi presenti con il methodTable, puoi usarli
sul client o sul server perchè sono già presenti, il caso di oggetti
non presenti e creati runtime è molto particolare e sono un pò stanco
per spiegarlo bene.
> E' troppo perchè sono varie funzioni.
appunto, io vorrei avere tutto disponibile subito
> Quindi scrivi una lib in Python per risolvere un problema che ha solo
> quella schifezza di PHP?
ho già risposto a questa domanda, scrivo una lib che non è per l'uno o
per l'altro, ma che per avere senso a livello di portabilità del client
deve basarsi o su JSON o su PHP_Serializer, io ho scelto la seconda per
rispetto del predominante nel web, PHP
> Interazione avanzate in AJAX?
si, se AHAH è l' abc , con altre lib puoi fare interazioni più
complesse, quindi più avanzate
>
>> > callRemote("sayHello").addCallback(function(str) {alert(str)})
>> la callback semplifica ? callRemote è una sola funzione ?
>> devo farne una per ogni tipo di callRemote ??? .... e quando ti passa
>> a te ?
>
> Che vuol dire tipo di callRemote? La callRemot chiama una funzione e
> piglia il valore di ritorno. Che c'è da riscrivere?
niente, avevo capito male ... però questo non è un approccio procedurale ?
io preferirei
myClassVar.sayHello.call();
e nel frattempo hai anche un'istanza di classe da gestire come vuoi
> Tutto su che?
u ... unicode
> L'hai detto tu che non usi JSON perchè non c'è una libreria in PHP
> decente preinstallata. Tra l'altro non avrai lo stesso problema di
> deployment con la tua libreria rispetto a quelle più performanti per
> PHP ma non preinstallate?
molto meno, per il semplice fatto che non ci sono caratteri da
modificare, solo length da sfruttare.
La serializzazione / unserializzazione di PHP è molto più semplice di
quella json, sia in conversione che in riconversione, Python e C# se la
cavano bene anche senza moduli dedicati.
Il problema della length per UTF-8, come ho detto, è pià per portabilità
della classe PHP_Serializer che altro, perchè trattando stringhe come
text (numero dei caratteri), non è necessario usare
UTF-8 con altri linguaggi diversi dal PHP, quindi è molto rapida.
Anzi ... a dirla tutta, in PyRex le uniche reali ottimizzazioni sono
proprio per la __slen, che se "inusata", potrebbe avere poco senso di
esistere.
> Non è un partito preso, è un non reinventare la ruota
infatti non l'ho reinventata, l'ho solo aggiustata (male, datemi tempo)
> La tua lib in pyrex sarà ancora meno portabile sui server che non
> preinstallano le librerie JSON in PHP performanti, vero?
come sopra
ACE.py
import types, re, PHP_Serializer
HAND_RULES = {
"DEBUG" :False,
"UTF8" :False,
"GZ" :False
}
def in_list(value, values):
result = False
for i in range(0, len(values)):
if value == values[i]:
result = True
break
return result
class ACE:
php = None # PHP_Serializer
utf8 = False # is UTF8 enabled or not
next = True # has any error
gz = False # uses gz compression
dodebug = False # creates a debug file
debug = [] # debug informations
types = { # valid variable types
"s":"string", "N":"null", "O":"Class", "b":"boolean",
"i":"integer", "d":"float", "a":"array", "u":"undefined"
}
def __init__(self, settings):
self.utf8 = settings["UTF8"]
self.dodebug = settings["DEBUG"]
self.gz = not self.dodebug and settings["GZ"]
self.php = PHP_Serializer.PHP_Serializer(self.utf8)
def getMethods(self, classDict):
tmp = None
result = []
if classDict.has_key("methodTable") and
type(classDict["methodTable"]) is types.DictType:
for key in classDict["methodTable"]:
tmp = classDict["methodTable"][key]
if type(tmp) is types.DictType and (not
tmp.has_key("access") or tmp["access"] == "remote"):
result.append(key)
return result
def getMethodInformations(self, tmpclass, method):
i = 0
result = {}
vars = tmpclass.__class__.__dict__["methodTable"][method]
if vars.has_key("arguments") and type(vars["arguments"]):
result = {"info":[], "required":0}
if type(vars["arguments"]) is types.ListType:
for key in range(0, len(vars["arguments"])):
result["info"].append({"type":self.parseType(vars["arguments"][key]),"required":self.isRequired(vars["arguments"][key])})
elif type(vars["arguments"]) is types.DictType:
for key in vars["arguments"]:
result["info"].append({"type":self.parseType(vars["arguments"][key]),"required":self.isRequired(vars["arguments"][key])})
if result["info"][i]["required"]:
result["required"] = result["required"] + 1
i = i + 1
return result
def parseType(self, value):
result = "u"
if value.has_key("type"):
result = value["type"].lower()
if result == "string":
result = "s"
elif result == "int" or result == "integer":
result = "i"
elif result == "null" or result == "none":
result = "N"
elif result == "class" or result == "object":
result = "O"
elif result == "bool" or result == "boolean":
result = "b"
elif result == "array" or result == "list" or result ==
"dict" or result == "tuple":
result = "a"
elif result == "float" or result == "double" or result ==
"long":
result = "d"
return result
def isRequired(self, value):
result = False
if value.has_key("required"):
result = value["required"]
return result
def goodRequestVariable(self, settings, i, post, hasinfo):
if self.next:
self.next = len(post) > 0
if self.next and hasinfo and settings["info"].has_key(i):
if post[0] != settings["info"][i]["type"] and
settings["info"][i]["type"] != "u":
if self.dodebug:
self.debug.append("Variable #" + str(i + 1) + ' of
type ' + self.types[settings["info"][i]["type"]] + " is not defined or
is not correct: " + post)
self.next = False
return self.next
def callClassMethod(self, className, method, _POST):
i = 0
istring = "_0"
hasinfo = False
args = settings = methodInfo = []
vars = {}
tmpclass = self.getClass(className)
if(tmpclass != None):
if in_list(method,
self.getMethods(tmpclass.__class__.__dict__)):
vars = self.getMethodInformations(tmpclass, method)
if vars["required"] == 0 or _POST.has_key("_" +
str((vars["required"] - 1))):
while _POST.has_key(istring) and
self.goodRequestVariable(vars, i, _POST, hasinfo):
if self.dodebug:
methodInfo.append("args[" + str(i) + "] = "
+ _POST[istring])
args.append(self.unserialize(_POST[istring]))
i = i + 1
istring = "_" + str(i)
if self.next:
settings = []
i = len(args)
for i in range(0, len(args)):
settings.append("args[" + str(i) + "]")
method = method + "(" + ",".join(settings) + ")"
exec "istring=self.php.serialize(tmpclass." +
method + ")"
if self.dodebug:
method = method + "<br />" + "<br
/>".join(methodInfo)
elif self.dodebug:
self.debug.append("ACE has killed itsself, bye
bye.")
elif self.dodebug:
while _POST.get("_" + i, None) != None:
i = i + 1
self.debug.append(method + " method requires at
least " + vars["required"] + " params and not " + i)
elif self.dodebug:
self.debug.append("Choosed method is not availbale: " +
method)
elif self.dodebug:
self.debug.append("Choosed Class or method is not valid: " +
className + "." + method)
if not self.next:
istring = ""
return istring
def exportClass(self, className):
result = settings = []
tmpclass = self.getClass(className)
if tmpclass != None:
settings = self.getMethods(tmpclass.__class__.__dict__)
for i in range(0, len(settings)):
result.append(settings[i])
elif self.dodebug:
self.debug.append("Class " + className + " is not valid")
return result
def getClass(self, className):
classExists = None
try:
exec "import " + className
classExists = eval(className + "." + className + "()")
except:
classExists = None
return classExists
def unserialize(self, post):
result = None
try:
result = self.php.unserialize(post)
except:
if self.dodebug:
self.debug.append("Unserialize Exception [utf8: " +
str(self.utf8) + "] with this var: " + pos)
self.next = False
return result;
ace = ACE(HAND_RULES)
_POST = {"_0":"s:4:\"ace!\";"}
print ace.exportClass("MyClass")
ace.callClassMethod("MyClass", "hello", _POST)
MyClass.py
class MyClass:
methodTable = {
"hello":{"access":"remote",
"arguments":[{
"type":"string",
"required":True
}]}
}
def hello(self, str):
print str
Devo ancora lavorarci sopra ... anche e soprattutto per l'import
dinamico (ogni consiglio è bene accetto)
Maggiori informazioni sulla lista
Python