m DMc@sdZdklZdklZlZlZlZlZl Z l Z l Z l Z l Z lZdklZlZlZlZlZdklZlZlZlZlZlZdklZdklZlZlZl Z dk!l"Z"dk#l$Z$d k%l&Z&d k'Z'd k(Z(d k)Z)e(i*d Z+e(i*d Z,d Z-dZ.de/fdYZ0de0fdYZ1de1fdYZ2de1fdYZ3de1fdYZ4de1fdYZ5de1fdYZ6de1fdYZ7de0fd YZ8d!e0fd"YZ9d#e0fd$YZ:d%e1fd&YZ;d'e:fd(YZ<d)e:fd*YZ=d+e:fd,YZ>d-e0fd.YZ?d/e0fd0YZ@d1e/fd2YZAd3efd4YZBd5efd6YZCeBiDZEd S(7sX This file is part of the web2py Web Framework Copyrighted by Massimo Di Pierro License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) Holds: - SQLFORM: provide a form for a table (with/without record) - SQLTABLE: provides a table for a set of records - form_factory: provides a SQLFORM for an non-db backed table (sHTTP( sXMLsSPANsTAGtAsDIVsULsLIsTEXTAREAsBRsIMGsSCRIPT(sFORMsINPUTsLABELsOPTIONsSELECT(sTABLEsTHEADsTBODYsTRsTDsTH(sURL(sDALsTablesRows CALLABLETYPES(sStorage(smd5_hash(s IS_EMPTY_ORNs[\w_]+\.[\w_]+s^\w*cCs,yt|SWntj o dSnXdS(Ni(tinttxt ValueError(R((t7/home/camdpams_www/Products_Activation/gluon/sqlhtml.pytsafe_int#scCs,yt|SWntj o dSnXdS(Ni(tfloatRR(R((Rt safe_float)st FormWidgetcBs,tZdZedZedZRS(sa helper for SQLFORM to generate form input fields (widget), related to the fieldtype c Ksmtdd|i|ifdtit|iid|id|i }|i ||i ||S(s helper to build a common set of attributes :param field: the field involved, some attributes are derived from this :param widget_attributes: widget related attributes :param attributes: any other supplied attributes t_ids%s_%st_classt_nametrequiresN(tdicttfieldt _tablenametnamet widget_classtmatchtstrttypetgroupR tattrtupdatetwidget_attributest attributes(RRRR((Rt _attributes5s   cKs tdS(sT generates the widget for the field. When serialized, will provide an INPUT tag: - id = tablename_fieldname - class = field.type - name = fieldname :param field: the field needing the widget :param value: value :param attributes: any other attributes to be applied N(tNotImplementedError(RtvalueR((RtwidgetHs(t__name__t __module__t__doc__t staticmethodRR(((RR/s t StringWidgetcBstZedZRS(NcKsNtddd|djo t|pd}ti|||}t |S(s[ generates an INPUT text tag. see also: :meth:`FormWidget.widget` t_typettextRtN( R RtNoneRtdefaultR"RRRRtINPUT(RRRRR'((RR\s  &(RRR!R(((RR"Zst IntegerWidgetcBstZRS(N(RR(((RR)mst DoubleWidgetcBstZRS(N(RR(((RR*rst DecimalWidgetcBstZRS(N(RR(((RR+wst TimeWidgetcBstZRS(N(RR(((RR,|st DateWidgetcBstZRS(N(RR(((RR-stDatetimeWidgetcBstZRS(N(RR(((RR.st TextWidgetcBstZedZRS(NcKs.td|}ti|||}t|S(sX generates a TEXTAREA tag. see also: :meth:`FormWidget.widget` RN( R RR'R/RRRRtTEXTAREA(RRRRR'((RRs(RRR!R(((RR/st BooleanWidgetcBstZedZRS(NcKs4tddd|}ti|||}t|S(s_ generates an INPUT checkbox tag. see also: :meth:`FormWidget.widget` R#tcheckboxRN( R RR'R1RRRRR((RRRRR'((RRs   (RRR!R(((RR1st OptionsWidgetcBs&tZedZedZRS(NcCst|idS(s checks if the field has selectable options :param field: the field needing checking :returns: True if the field has options toptionsN(thasattrRR (R((Rt has_optionssc Kstd|}ti|||}|i} t | t t fp | g} n| o9t | ddo| di } qtd|ng}| D]\}}|t|d|q~}t||S(s generates a SELECT tag, including OPTIONs (only 1 option allowed) see also: :meth:`FormWidget.widget` RiR4s%widget cannot determine options of %st_valueN(R RR'R3RRRRR t isinstancetlistttupleR5R4t SyntaxErrort_[1]tktvtOPTIONtoptstSELECT( RRRRR'R=R<R@R>R R4((RRs  3(RRR!R6R(((RR3s t ListWidgetcBstZedZRS(Nc Ksd|i|if} |i}|idjo d}nd}g}|pdgD]4}|t t d| d|d|d |d t qT~}td | }| d |dtLIR(tTruetitemstSCRIPTtscriptRtTAGtUL( RRRR RKRIR R<R>R ((RRs  R(RRR!R(((RRBstMultipleOptionsWidgetcBstZeddZRS(NicKs/|itd|dtti|||S(s generates a SELECT tag, including OPTIONs (multiple options allowed) see also: :meth:`FormWidget.widget` :param size: optional param (default=5) to indicate how many rows must be shown t_sizet _multipleN( RRR tsizeRHR3RRR(RRRQR((RRs (RRR!R(((RRNst RadioWidgetcBstZedZRS(NcKsti|h|}|i} t| ttfp | g} n| o9t | ddo| di }qt d|ng} |D]*\} } t| o| | | fqq~ }g}|idd}t|}||}||}|o|d7}nxt|D]} g}xs|| || d|!D]X\} } |ittddd|id |id dd td | d || q?W|it!|qW|ot"|d ddd RR@tgetRStlenttotalstmodstrowstrangetr_indexttdstappendtTDR(RR&RHRtTRtFalsetTABLE(RRRRSRYRWR\RXRR[R=R<R>R R4R@((RRs>  >       (RRR!R(((RRRstCheckboxesWidgetcBstZedZRS(NcKsft|ttfo+g} |D]}| t|q!~ } nt|g} ti |h|} |i }t|ttfp |g}n|o9t|ddo|di}qtd|ng} |D]*\} }| djo| | |fqq~ }g}|idd}t|}||}||}|o|d7}nxt|D]} g}x|| || d|!D]\} }t| iot| | jo | }ng}|it t!ddd |i"d | id dd t$d | d ||qW|it%|qiW|ot&|dddd RtvaluesR3RRRRR R5R4R;R=R@RURSRVRWRXRYRZR[R\tisdigitRtr_valueR]R^R(RR&RHR_R`Ra(RRRRSRYRWReR\RXRR[R=R<RcR>R R4R@((RRBsJ+  >     &   (RRR!R(((RRb@stPasswordWidgetcBs!tZddZedZRS(Nit*cKsEtddd|o tipd}ti|||}t |S(s generates a INPUT password tag. If a value is present it will be shown as a number of '*', not related to the length of the actual value. see also: :meth:`FormWidget.widget` R#tpasswordR7R%N( R RRftDEFAULT_PASSWORD_DISPLAYR'RRRRR((RRRRR'((RR{s  (RRRiR!R(((RRfws t UploadWidgetcBsStZdZdZdZdZeddZeddZ edZ RS(Nt150pxt__deletetfiletdeletec Ks9tdd}ti|||}t|}|o|o|d|} d\}}ti|o%t}td| dti}n|d} | gjpt| toSt|dttid | d tdd d |ititid || }q5t|dttid | d ||}n|S(s8 generates a INPUT file tag. Optionally provides an A link to the file, including a checkbox so the file can be deleted. All is wrapped in a DIV. see also: :meth:`FormWidget.widget` :param download_url: Optional URL to link to the file (default = None) R#Rmt/R%t_srct_widthR t[t_hreft|R2R t]N(R%R%(R R'RjRRRRR(tinpt download_urlRturltbrtimagetis_imagetBRtIMGt DEFAULT_WIDTHR R8t IS_EMPTY_ORtDIVRtGENERIC_DESCRIPTIONRtID_DELETE_SUFFIXt DELETE_FILE( RRRwRRR'RzRvRyRxR ((RRs.        cCskti}|oW|oP|d|}ti|otd|dti}nt |d|}n|S(s_ how to represent the file: - with download url and if it is an image: - otherwise with download url: file - otherwise: file :param field: the field :param value: the field value :param download_url: url for the file download (default = None) RoRpRqRsN( RjRRvRwRRxR{R}R~R(RRRwRxRv((Rt represents  cCsA|iddi}|dddddgjotSntS( s Tries to check if the filename provided references to an image Checking is based on filename extension. Currently recognized: gif, png, jp(e)g, bmp :param value: filename t.itgiftpngtjpgtjpegtbmpN(Rtsplittlowert extensionRHR`(RR((RR{s ( RRR~RRRR!R&RRR{(((RRjs+tAutocompleteWidgetcBs5tZdddddddZdZdZRS( Nii s_autocomplete_%(fieldname)sic Cs||_|td|i|_|p|i|_||_||_ ||_ |g|_ |ot |_|i i|n t|_t|do)td|d|i|_|in ||_dS(Nt fieldnamet applicationtrtargs(trequesttselftkeywordR RRtdbt_dbtorderbytlimitbyt min_lengthtfieldstid_fieldRHt is_referenceR]R`R5tUrlRRxtcallback( RRRRRRRRR((Rt__init__s       cCs|i|iijo|id}|i|i|ii|idid|i d|i |i}|o<|i o|id}tdtd|idd d t|d t|djg}t|D]9\}}|t||id ||id |djq~iqtdtd|idd d t|d t|djg}t|D],\}}|t||id |djqh~iqtddndS(Nit%RRiiR R t autocompleteRORPR7t _selectedR%(RRRtvarsRRRtliketselectRRRYRRtHTTPRARVR<t enumerateR=tsR?Rtxml(RRYRR<RRR=((RRs G  X)K)c Kstddd|djo t|pd}ti|||}|i d} d|d<|i o|i d}|i d }d |d <|d } d |jo |d =n||d <|d}|i|id|ji|idi}|o||idi|d=%(min_length)s) jQuery.get('%(url)s?%(key)s='+escape(jQuery('#%(id)s').val()),function(data){if(data=='')jQuery('#%(key3)s').val('');else{jQuery('#%(id)s').next('.error').hide();jQuery('#%(div_id)s').html(data).show().focus();jQuery('#%(div_id)s select').css('width',jQuery('#%(id)s').css('width'));jQuery('#%(key3)s').val(jQuery('#%(key)s').val());jQuery('#%(key)s').change(%(u)s);jQuery('#%(key)s').click(%(u)s);};}); else jQuery('#%(div_id)s').fadeOut('slow');RxRtkeytidR tkey2tkey3Rt_onkeyupt_onfocusthiddenR7t_stylesposition:absolute;sovar e=event.which?event.which:event.keyCode; function %(u)s(){jQuery('#%(id)s').val(jQuery('#%(key)s').val())}; if(e==39) %(u)s(); else if(e==40) {if(jQuery('#%(key)s option:selected').next().length)jQuery('#%(key)s option:selected').attr('selected',null).next().attr('selected','selected'); %(u)s();} else if(e==38) {if(jQuery('#%(key)s option:selected').prev().length)jQuery('#%(key)s option:selected').attr('selected',null).prev().attr('selected','selected'); %(u)s();} else if(jQuery('#%(id)s').val().length>=%(min_length)s) jQuery.get('%(url)s?%(key)s='+escape(jQuery('#%(id)s').val()),function(data){jQuery('#%(id)s').next('.error').hide();jQuery('#%(div_id)s').html(data).show().focus();jQuery('#%(div_id)s select').css('width',jQuery('#%(id)s').css('width'));jQuery('#%(key)s').change(%(u)s);jQuery('#%(key)s').click(%(u)s);}); else jQuery('#%(div_id)s').fadeOut('slow');(R RR&RR'R"RRRRRRRRRRRRRRtfirsttrecordRxRRLR(R R( RRRRRRR'RRRR((Rt__call__s@ &          2$$% $1(ii (RRR&RRR(((RRs tSQLFORMc&BstZdZeededededede de de de d e d ed ed ed edededededeZdZdZdZdZeeeeeehddeeegeeddgdZdZedeeeeedZ e!dZ"RS( s SQLFORM is used to map a table (and a current record) into an HTML form given a SQLTable stored in db.table generates an insert form:: SQLFORM(db.table) generates an update form:: record=db.table[some_id] SQLFORM(db.table, record) generates an update with a delete button:: SQLFORM(db.table, record, deletable=True) if record is an int:: record=db.table[record] optional arguments: :param fields: a list of fields that should be placed in the form, default is all. :param labels: a dictionary with labels for each field, keys are the field names. :param col3: a dictionary with content for an optional third column (right of each field). keys are field names. :param linkto: the URL of a controller/function to access referencedby records see controller appadmin.py for examples :param upload: the URL of a controller/function to download an uploaded file see controller appadmin.py for examples any named optional attribute is passed to the
tag for example _class, _id, _style, _action, _method, etc. RDR$RhRCtdoubletdecimalttimetdatetdatetimetuploadtbooleantblobR4tmultipleRTt checkboxesRR9tdelete_this_recordt delete_recordt__labelt__rowtSubmitsCheck to delete:t table3colstsubmitc2 Ks ||_||_td}ti|g||}"t |d}+|d,joRg},|D]:}(|p|(ip |(io|(i o|,|(iq^q^~,}n||_|id|idjo6t|to&|+ o|iid|idn||_ |ot|ttttfoht|iptddn|i|i|ji i!}|ptddqn||_||_"|+oy|o;t#g},|i$D]}*|,|*||*fq~,|_"q%t#g},|i$D]}*|,|*d,fq~,|_"nh|_&g}!||_t(|_)t(|i)_*t(|i)_+t(|i)_,t(|i)_-t(|i)_.t(|i)_/x|iD]}-|-i1ddjoqn|i |-}d,}| o|i5|-|i-}n|d,jo d}n||i)i-|-<|d,jo!|-|jo||-}d}n|i,}d}||i)i,|-s%sN(yt ignore_rwRt formstyletXMLtnbsptFORMRRRtofieldsR5ttabletkeyedR&R<tftwritabletreadabletcomputeRR8tTabletinsertRRtlongRtunicodeRdRRRRRt record_idR RR=t field_parenttxfieldstStoragetcustomtdspvaltinpvaltlabeltcommentRtlinktoRtfindRtcommentstcol3RUtlabelstcolonRtfield_idtLABELRtID_LABEL_SUFFIXt ID_ROW_SUFFIXtrow_idRtshowidR>tSPANR]treadonlyR't CALLABLETYPEStcondt formatterRRvRjRtwidgetsRRHR3R6R RR4tkeepoptsRLt componentst startswithR9R$RhRfRiRDRRt_referenced_bytrtabletrfieldtrfldturllibtquotetquerytlnametolnameRtreplacet deletableR(tFIELDKEY_DELETE_RECORDtFIELDNAME_REQUEST_DELETEt delete_labelRtbuttonsRt_xmltbegintendttagt createform(2RRRRRRRRRRRRRRRRRRRRRRRRRR RR RRRRRRRRRvRRR RR'R=RR<RR>RRR((RRsP    R 3 #$  ;7              # "        8*8$    /   , c Cs8|idjo~t}x|D]f\} }}}t |dd}|i | <|i t t |dd|t |ddd| q Wn|idjot}x|D]\} }}}t |dddd }|i | <|i t t |ddt |ddd| d dd |i t |d| d dd qWn|id jotd}x|D]f\} }}}t|dd} |i | <|i tt|dd| t|ddd| qpWnW|idjo~t}x:|D]f\} }}}t|dd} |i | <|i tt|dd| t|ddd| qWnt|itdjot}x|D]\} }}}t |dd}|i | <|i| |||}t|idjo |g}nx|D]}|i |q WqWn td|S(NRR tw2p_fwtw2p_fltw2p_fcR t table2colst_colspant2t1teventoddtdivsR%tulcCsdS(N(R&(((RtsR:sformsyle not supported(RRRaRRRtatbtcR^ttd_bRR]R_RLRtdiv_bRMRGRtnewrowsRtnewrowt RuntimeError( RRR'R)R(R,R-R*RR+R((RRs\ $ # + $ $   s%(tablename)s/%(record_id)sc $ s iidjo intid}d&_ |oOi oAt _ di diiD}t|_qni ou|oEdi diiD}tdiiD} n i iidd&}} t}nQ|o=d }tg}iiD]}||d&fq1~} n d'\}} | o$t| ttfo| d } n|o#|td ii d |}nxiD]}i|} | i#pg}"t|"ttfp |"g}"ng}|"D]7}t|d o!io||i%iqq~qWh}x"i&D]}i&|||ii:| _:nt| do| i:o|jo|i&joi&|}n,i oi |}ni|i@}di|tAiBf}!| i:| |} | giD|!_E| i0i;dpiD|!iFt |n| i7i:|sRc#s<x5|].}ti|oti|VqqWdS(N(R0R=R5RRR(R0R=(R(RR1sc#s"x|]}||fVqWdS(N(R0R=t request_vars(R0R=(R2(RR1sRtcreateit tablenameRt set_self_idRERR%slist:Rs%s_%s%ss1user is tampering with form's record_id: %s != %scCs||@S(N(Rty(RR6((RR&Hssinput, select, textareaRRRhs %s__deleteRmsfile.txts%s_newfilenameRsno datas list:stringRCRRcCs |o|S(N(RR6(RR6((RR&scCs||@S(N(RR6(RR6((RR&sN(screateN(NR%(kR2t __class__Rt post_varsR5RRRR&trecord_changedtdetect_record_changeRR`tjoinRt serializedtmd5_hasht record_hashRt formname_idR RRRURHt keepvaluesR<R=R8R9R:tformnameRRRR titemR5RRRtacceptstsessiont onvalidationREtretterrorstkeysRRjRRtrequested_deleteRLt hidden_fieldsRRtauchRRR3R6RRR'RRRRRt _traverseRR;tdbioRRtreducetqryRRntcleartelementst componentRRRfRiRtfdRmtfilenamet source_filetoriginal_filenameRt cStringIOtStringIOtstoret newfilenamet uploadfieldtreadRRRRRcRtpk($RR2RDRAR@RERMRER:RRORFRRRVRRRKRZRSRR?R]RR<RR=RRR<RBRURRRR RI((RR2RRCsR    % "# 7    M   b %  /' # ?  3 6  !   #D (  : >! 3cOsI|idd}d|jo |d=nttdi|||S(s generates a SQLFORM for the given fields. Internally will build a non-database based data model to hold the fields. t table_nametno_tableN(RRUR^RtDALR&t define_tableR(RRR^((Rtfactorys   (#RRR RR R"R/RfR)R*R+R,R-R.RjR1R&R3RNRRRbRRBRRRRRR`RHRRRCR!Rb(((RR?s8 ) ? ,tSQLTABLEcBs,tZdZeeehdeddZRS(s given a Rows object, as returned by a db().select(), generates an html table with the rows. optional arguments: :param linkto: URL (or lambda to generate a URL) to edit individual records :param upload: URL to download uploaded files :param orderby: Add an orderby link to column headers. :param headers: dictionary of headers to headers redefinions headers can also be a string to gerenare the headers from data for now only headers="fieldname:capitalize", headers="labels" and headers=None are supported :param truncate: length at which to truncate text in table cells. Defaults to 16 characters. :param columns: a list or dict contaning the names of the columns to be shown Defaults to all Optional names attributes for passed to the tag The keys of headers and columns must be of the form "tablename.fieldname" Simple linkto example:: rows = db.select(db.sometable.ALL) table = SQLTABLE(rows, linkto='someurl') This will link rows[id] to .../sometable/value_of_id More advanced linkto example:: def mylink(field, type, ref): return URL(r=request, args=[field]) rows = db.select(db.sometable.ALL) table = SQLTABLE(rows, linkto=mylink) This will link rows[id] to current_app/current_controlle/current_function/value_of_id iR%c " KsBti|| g|_| |_||_|ig}!} |p |i}n|djoeh}x|D]P}di g}|i ddi dD]}||iq~||do||i>i?jot:i;t@g}|i>i?D]]}|| | jo6t,| t-o&t,| | t-o|| | |fp|| |fq'~}t|dd|| |f}nB|i1i4do|i<|pg}n|i<o|i<|}n|i1djo|o d}n|i1djoI|o'|o tddd||f}q|o d}qd}n~|i1ddgjogt=|iD|}tE|d }|djo2tH||jo||d! iId d"}qn| it(|qW|itd#|| qW|!itJ|dS($Nsfieldname:capitalizet Rit_RRss ?orderby=iiR"R#t_extrasColumn %s not found (SQLTABLE)ssomething wrong in Rows objectRRs%s/%s/%sRi Rs%s/%s?%sslist:RtDATARRms%s/%sR%RDR$tutf8is...R (KRaRRRRtsqlrowstrowtcolumnstcolnamestheadersR)R;R<Rtwt capitalizettRRRRR&RR]tTHRRUtth_linktTHEADR_ttbodyRtrcRR tcolnamet table_fieldRRfRR^tKeyErrorR4RR8tRowR;tr_oldRRthreft TypeErrorRtrefRttreftfrefR5R t urlencodeRRt_tableRR R=RRRRturttruncateRVtencodetTBODY("RRiRRRRmRRkRrRR4R{RjRRtRRuR R}RRnRvRRRzR)RR=R~R<RRRpR((RRs      R  #    1   2 %" -#      #(RRR R&R(((RRcs ,(FR thttpRthtmlRRRLRRRMRGR0R|R}RJRR(RR?RARaRsRR_R^RqtURLRtdalR`RRyRtstorageRtutilsR=t validatorsRR treRWtcompileRwRRRtobjectRR"R)R*R+R,R-R.R/R1R3RBRNRRRbRfRjRRRcRbt form_factory(;RR3RR?RWRRRRRRR|RR/RRRARRRRJR`R_R-R RGRcRRwRLRqRaR^R)RR1R}RR.R+RR,R*RRBRNR(RsRR0R"RRjRMRfR=RRbRRy((Rt?sN I%+         +&+-7[V