from decimal import Decimal from zope.interface import implementer from Products.Archetypes import atapi from Products.ATContentTypes.content.schemata import finalizeATCTSchema from Products.PloneFormGen.content.actionAdapter import FormActionAdapter from Products.PloneFormGen.content.actionAdapter import FormAdapterSchema from Products.PloneFormGen.interfaces import IPloneFormGenActionAdapter from jazkarta.shop.cart import Cart from Products.statusmessages.interfaces import IStatusMessage from .config import PROJECTNAME from .interfaces import IJazShopCheckoutAdapter JAZSHOP_FIELDS = ['JazShopSelectStringField', 'JazShopMultiSelectStringField'] JazShopCheckoutAdapterSchema = FormAdapterSchema.copy() + atapi.Schema( (atapi.StringField( 'formIdExpression', required=False, default='', description="""Expression containing one or more field names to be prepended to order data on Jazkarta Shop orders page. Field names must be enclosed in brackets. Example: {last_name}, {first_name}: """, ), )) finalizeATCTSchema(JazShopCheckoutAdapterSchema) @implementer(IPloneFormGenActionAdapter, IJazShopCheckoutAdapter) class JazShopCheckoutAdapter(FormActionAdapter): meta_type = 'JazShopCheckoutAdapter'
# -*- coding: utf-8 -*- """Definition of the PFGCorrectAnswersAdapter content type""" from AccessControl import ClassSecurityInfo from osha.quizzes.config import PROJECTNAME from osha.quizzes.interfaces import IPFGCorrectAnswersAdapter from plone import api from Products.Archetypes import atapi from Products.ATContentTypes.content import schemata from Products.CMFCore.permissions import View from Products.PloneFormGen.content.actionAdapter import FormActionAdapter from Products.PloneFormGen.content.actionAdapter import FormAdapterSchema from zope.interface import implements PFGCorrectAnswersAdapterSchema = FormAdapterSchema.copy() + atapi.Schema(( # -*- Your Archetypes field definitions here ... -*- )) # Set storage on fields copied from ATContentTypeSchema, making sure # they work well with the python bridge properties. PFGCorrectAnswersAdapterSchema['title'].storage = atapi.AnnotationStorage() PFGCorrectAnswersAdapterSchema['description'].storage = \ atapi.AnnotationStorage() schemata.finalizeATCTSchema( PFGCorrectAnswersAdapterSchema, moveDiscussion=False) class PFGCorrectAnswersAdapter(FormActionAdapter): """Calculate the percentage of correct answers."""
from Products.PloneFormGen.content.actionAdapter import FormActionAdapter, FormAdapterSchema from Products.PloneFormGen.interfaces.actionAdapter import IPloneFormGenActionAdapter from collective.pfg.mailchimp import MessageFactory as _ from chimpy import Connection from chimpy.chimpy import ChimpyException from Products.CMFCore.utils import getToolByName from config import PROJECTNAME from logging import getLogger log = getLogger("collective.pfg.mailchimp") mailchimpSubscribeAdapterSchema = FormAdapterSchema.copy() + atapi.Schema(( atapi.StringField('replyto_field', searchable=0, required=0, vocabulary='fieldsDisplayList', widget=atapi.SelectionWidget( label = _(u"Extract Subscribe Email"), description = _(u""" Choose a form field from which you wish to extract input for the Reply-To header. NOTE: You should activate e-mail address verification for the designated field. """) ), ),
class SoupAdapter(FormActionAdapter): """A form action adapter storing form input data in a soup. """ schema = FormAdapterSchema.copy() + atapi.Schema(atfields) meta_type = 'SoupAdapter' security = ClassSecurityInfo() def exclude_from_nav(self): return True @property def _soup_name(self): if IPfgSoupAdapter(self).soup_name.strip(): return 'PFGNAMEDSOUP_%s' % IPfgSoupAdapter(self).soup_name.strip() else: return 'PFGSOUP%s' % self.UID() def get_soup(self): return get_soup(self._soup_name, self) def onSuccess(self, fields, REQUEST=None, loopstop=False): """ saves data. """ now = tzawarenow() soup = self.get_soup() modified_fields = list() iid = self.REQUEST.cookies.get('PFGSOUP_POST', None) if iid: iid = int(iid) data = soup.get(iid) else: data = OOBTNode() for field in fields: if field.isLabel(): continue field_name = field.getFieldFormName() if field.isFileField(): file_value = REQUEST.form.get('%s_file' % field_name) raise NotImplementedError('FileField Not Yet Done') value = REQUEST.form.get(field_name, '') if iid: if data.attrs.get(field_name, None) == value: continue modified_fields.append(field_name) data.attrs[field_name] = value sm = getSecurityManager() if iid: if modified_fields: data.attrs['_auto_last_modified'] = now log = {} log['user'] = sm.getUser().getId() log['date'] = now log['fields'] = modified_fields if '_auto_log' not in data.attrs: data.attrs['_auto_log'] = PersistentList() data.attrs['_auto_log'].append(log) self.REQUEST.response.expireCookie('PFGSOUP_POST', path='/') # XXX redirect to table # self.REQUEST.response.redirect(...) return data.attrs['_auto_created'] = now data.attrs['_auto_last_modified'] = now data.attrs['_auto_userid'] = sm.getUser().getId() data.attrs['_auto_log'] = PersistentList() soup.add(data)
from Products.DataGridField.DataGridWidget import DataGridWidget from Products.DataGridField.Column import Column from Products.DataGridField.SelectColumn import SelectColumn from zope.annotation.interfaces import IAnnotations from msgraph.sharepoint import (Sharepoint, SharepointDateTimeColumn, SharepointChoiceColumn,) from msgraph.drives import Drive from collective.pfgsharepoint import _, PROJECTNAME from collective.pfgsharepoint.utils import getClient logger = logging.getLogger('collective.pfgsharepoint') SharePointAdapterSchema = FormAdapterSchema.copy() + atapi.Schema(( atapi.StringField('sharepoint_tenant', required=True, write_permission=ModifyPortalContent, read_permission=ModifyPortalContent, vocabulary_factory="collective.pfgsharepoint.vocabularies.SharepointTenants", widget=atapi.SelectionWidget( label=u'SharePoint Tenant', )), atapi.StringField('sharepoint_site', required=False, write_permission=ModifyPortalContent, read_permission=ModifyPortalContent, vocabulary='getSites', widget=atapi.SelectionWidget( label=u'SharePoint Site ID',
if isinstance(title, bytes): return u'<a href="{0:s}">{1:s}</a>'.format( self.absolute_url(), title.decode('utf-8', 'ignore')) else: return u'<a href="{0:s}">{1:s}</a>'.format(self.absolute_url(), title) LOG = logging.getLogger('collective.pfg.dexterity') TARGET_INTERFACES = ( 'Products.ATContentTypes.interfaces.folder.IATFolder', 'collective.pfg.dexterity.interfaces.IDexterityContentAdapter', 'plone.dexterity.interfaces.IDexterityContainer') DexterityContentAdapterSchema = FormAdapterSchema.copy() + atapi.Schema( (atapi.StringField( 'createdType', required=True, write_permission=ModifyPortalContent, read_permission=ModifyPortalContent, storage=atapi.AnnotationStorage(), searchable=False, vocabulary='listTypes', widget=SelectionWidget( label=_('created_type_label', default=u'Content type'), description=_('created_type_help', default=(u'Select the type of new content ' u'to be created.')))), (HAS_RELATED_ITEMS_WIDGET and atapi.StringField( 'targetFolder',
from email.MIMEBase import MIMEBase from email.MIMEImage import MIMEImage from email.MIMEMultipart import MIMEMultipart from email.MIMEText import MIMEText from email.utils import formataddr from types import StringTypes from Products.PloneFormGen import PloneFormGenMessageFactory as _ from Products.PloneFormGen import dollarReplace from zope.contenttype import guess_content_type import zope.i18n formMailerAdapterSchema = FormAdapterSchema.copy() + Schema(( StringField( 'recipient_name', searchable=0, required=0, default_method='getDefaultRecipientName', write_permission=EDIT_ADDRESSING_PERMISSION, read_permission=ModifyPortalContent, widget=StringWidget( label=_(u'label_formmailer_recipient_fullname', default=u"Recipient's full name"), description=_(u'help_formmailer_recipient_fullname', default=u""" The full name of the recipient of the mailed form. """), ),
from plone.directives.form import IFormFieldProvider from plone.dexterity.interfaces import IDexterityFTI from plone.dexterity.utils import createContentInContainer from collective.pfg.dexterity.interfaces import IDexterityContentAdapter from collective.pfg.dexterity.config import PROJECTNAME from zope.i18nmessageid import MessageFactory as ZopeMessageFactory _ = ZopeMessageFactory("collective.pfg.dexterity") LOG = logging.getLogger("collective.pfg.dexterity") DexterityContentAdapterSchema = FormAdapterSchema.copy() + atapi.Schema( ( atapi.StringField( "createdType", required=True, write_permission=ModifyPortalContent, read_permission=ModifyPortalContent, storage=atapi.AnnotationStorage(), searchable=False, vocabulary="listTypes", widget=SelectionWidget( label=_("created_type_label", default=u"Content type"), description=_("created_type_help", default=(u"Select the type of new content " u"to be created.")), ), ), atapi.ReferenceField(
from collective.pfg.signup import _ from collective.pfg.signup.config import PROJECTNAME from collective.pfg.signup.interfaces import ISignUpAdapter from datetime import datetime from email import message_from_string from smtplib import SMTPRecipientsRefused from smtplib import SMTPServerDisconnected from zope.component import getUtility from zope.interface import implements import logging import random import string import transaction SignUpAdapterSchema = FormAdapterSchema.copy() + atapi.Schema(( atapi.StringField( 'full_name_field', default='fullname', required=False, widget=atapi.StringWidget( label=_(u'label_full_name', default=u'Full Name Field'), # noqa H702 description=_( u'help_full_name_field', default=u"""Enter the id of the field that will be used for the user's full name."""), ), ), atapi.StringField(
class FormCustomScriptAdapter(FormActionAdapter): """ Executes a Python script for form data """ # Python script receives parameters # resultData - cleaned up input # form - the PFG object # REQUEST # External Python script (as in Plone skins) SCRIPT_TYPE_SKINS_SCRIPT="skins_script" # Script defined in ScriptData field SCRIPT_TYPE_INTERNAL_SCRIPT="internal_script" schema = FormAdapterSchema.copy() + Schema(( StringField('ProxyRole', searchable=0, required=1, default="none", read_permission=ModifyPortalContent, write_permission=EDIT_PYTHON_PERMISSION, vocabulary="getProxyRoleChoices", widget=SelectionWidget( label=_(u'label_script_proxy', default=u'Proxy role'), description = _(u'help_script_proxy', default=u""" Role under which to run the script. """), ), ), PythonField('ScriptBody', searchable=0, required=0, default=default_script, read_permission=ModifyPortalContent, write_permission=EDIT_PYTHON_PERMISSION, widget=TextAreaWidget( label=_(u'label_script_body', default=u'Script body'), rows=10, visible={'view': 'invisible','edit': 'visible'}, description = _(u'help_script_body', default=u""" Write your script here. """), ), ), )) meta_type = portal_type = 'FormCustomScriptAdapter' archetype_name = 'Custom Script Adapter' content_icon = 'scriptaction.gif' #immediate_view = 'fg_savedata_view' #default_view = 'fg_savedata_view' security = ClassSecurityInfo() def __init__(self, oid, **kwargs): """ initialize class """ FormActionAdapter.__init__(self, oid, **kwargs) # for the convenience of scripters operating # in a restricted python environment, # let's store a reference to FORM_ERROR_MARKER # on the object, so it'll be available # as an attribute of context. self.FORM_ERROR_MARKER = config.FORM_ERROR_MARKER def updateScript(self, body, role): """ Regenerate Python script object Sync set of script source code, proxy role and creation of Python Script object. """ bodyField = self.schema["ScriptBody"] proxyField = self.schema["ProxyRole"] script = PythonScript(self.title_or_id()) script = script.__of__(self) # Force proxy role if role != "none": script.manage_proxy((role,)) script.ZPythonScript_edit("fields, ploneformgen, request", body) PythonField.set(bodyField, self, script) StringField.set(proxyField, self, role) def setScriptBody(self, body): """ Make PythonScript construction to take parameters """ proxy = self.getProxyRole() self.updateScript(body, proxy) def setProxyRole(self, role): sourceCode = self.getRawScriptBody() self.updateScript(sourceCode, role) def getProxyRoleChoices(self): """ Get proxy role choices""" # XXX TODO: use real role list return DisplayList( (("none", "No proxy role"), ("Manager", "Manager"), )) def onSuccess(self, fields, REQUEST=None): """ Executes the custom script """ # use PloneFormGen object as a context form = aq_parent(self) if REQUEST != None: resultData = self.sanifyFields(REQUEST.form) else: resultData = {} return self.executeCustomScript(resultData, form, REQUEST) def checkWarningsAndErrors(self): """ Raise exception if there has been bad things with the script compiling """ field = self.schema["ScriptBody"] script = ObjectField.get(field, self) if len(script.warnings) > 0: logger.warn("Python script " + self.title_or_id() + " has warning:" + str(script.warnings)) if len(script.errors) > 0: logger.error("Python script " + self.title_or_id() + " has errors: " + str(script.errors)) raise ValueError, "Python script " + self.title_or_id() + " has errors: " + str(script.errors) def executeCustomScript(self, result, form, req): """ Execute in-place script @param result Extracted fields from REQUEST.form @param form PloneFormGen object """ field = self.schema["ScriptBody"] # Now pass through PythonField/PythonScript abstraction # to access bad things (tm) # otherwise there are silent failures script = ObjectField.get(field, self) logger.debug("Executing Custom Script Adapter " + self.title_or_id() + " fields:" + str(result)) self.checkWarningsAndErrors() response = script(result, form, req) return response def sanifyFields(self, form): """ Makes request.form fields accessible in a script Avoid Unauthorized exceptions since REQUEST.form is inaccesible """ result = {} for field in form: result[field] = form[field] return result
# -*- coding: utf-8 -*- """Definition of the PFGCorrectAnswersAdapter content type""" from AccessControl import ClassSecurityInfo from osha.quizzes.config import PROJECTNAME from osha.quizzes.interfaces import IPFGCorrectAnswersAdapter from plone import api from Products.Archetypes import atapi from Products.ATContentTypes.content import schemata from Products.CMFCore.permissions import View from Products.PloneFormGen.content.actionAdapter import FormActionAdapter from Products.PloneFormGen.content.actionAdapter import FormAdapterSchema from zope.interface import implements PFGCorrectAnswersAdapterSchema = FormAdapterSchema.copy() + atapi.Schema(( # -*- Your Archetypes field definitions here ... -*- )) # Set storage on fields copied from ATContentTypeSchema, making sure # they work well with the python bridge properties. PFGCorrectAnswersAdapterSchema['title'].storage = atapi.AnnotationStorage() PFGCorrectAnswersAdapterSchema['description'].storage = \ atapi.AnnotationStorage() schemata.finalizeATCTSchema(PFGCorrectAnswersAdapterSchema, moveDiscussion=False) class PFGCorrectAnswersAdapter(FormActionAdapter): """Calculate the percentage of correct answers."""
from Products.Archetypes import atapi from Products.ATContentTypes.content import schemata # from Products.CMFPlone.interfaces import IPloneSiteRoot from Products.CMFCore.permissions import ModifyPortalContent from Products.PloneFormGen.content.actionAdapter import FormActionAdapter from Products.PloneFormGen.content.actionAdapter import FormAdapterSchema from Products.PloneFormGen.config import EDIT_TALES_PERMISSION from Products.TemplateFields import ZPTField from abstract.pfg2pdf.interfaces import IFormToPDFAdapter from abstract.pfg2pdf.config import PROJECTNAME from abstract.pfg2pdf import _ FormToPDFAdapterSchema = FormAdapterSchema.copy() + atapi.Schema(( ZPTField( 'pdf_body_pt', # schemata='template', write_permission=EDIT_TALES_PERMISSION, default_method='getPDFBodyDefault', read_permission=ModifyPortalContent, widget=atapi.TextAreaWidget( label=_(_(u'PDF-Body Template')), description=_( _(u"This is a Zope Page Template " u"used for rendering of the PDF for this form. " u"You will find data from the form " u"in the `options` var (es: options/comments)")), rows=20, visible={
from Products.PloneFormGen.content.saveDataAdapter import FormSaveDataAdapter from Products.PloneFormGen.interfaces import \ IPloneFormGenActionAdapter, IPloneFormGenFieldset, IPloneFormGenForm from collective.webservicespfgadapter.config import * from collections import OrderedDict from plone import api from types import StringTypes import json, logging, requests, sys, traceback logger = logging.getLogger("PloneFormGen") formWebServiceAdapterSchema = FormAdapterSchema.copy() + Schema(( StringField('url', required=1, searchable=0, write_permission=EDIT_URL_PERMISSION, read_permission=ModifyPortalContent, widget=StringWidget( label=u'Web Services Address', description=u""" Specify the web address of the service that will receive the form submission information. It's highly recommended that the web address start with 'https://' to ensure the form data is transmitted securely. """, ), ),
# from Products.CMFPlone.interfaces import IPloneSiteRoot from Products.CMFCore.permissions import ModifyPortalContent from Products.PloneFormGen.content.actionAdapter import FormActionAdapter from Products.PloneFormGen.content.actionAdapter import FormAdapterSchema from Products.PloneFormGen.config import EDIT_TALES_PERMISSION from Products.TemplateFields import ZPTField from abstract.pfg2pdf.interfaces import IFormToPDFAdapter from abstract.pfg2pdf.config import PROJECTNAME from abstract.pfg2pdf import _ FormToPDFAdapterSchema = FormAdapterSchema.copy() + atapi.Schema(( ZPTField( 'pdf_body_pt', # schemata='template', write_permission=EDIT_TALES_PERMISSION, default_method='getPDFBodyDefault', read_permission=ModifyPortalContent, widget=atapi.TextAreaWidget( label=_( _(u'PDF-Body Template') ), description=_( _(u"This is a Zope Page Template " u"used for rendering of the PDF for this form. " u"You will find data from the form "
from Products.salesforcepfgadapter import SalesforcePFGAdapterMessageFactory as _ from Products.salesforcepfgadapter import HAS_PLONE25, HAS_PLONE30 from Products.salesforcepfgadapter import validators from Products.salesforcepfgadapter import interfaces from Products.salesforcepfgadapter import config from Products.salesforcepfgadapter.prepopulator import ExpressionChanged, sanitize_soql if HAS_PLONE25: import zope.i18n logger = logging.getLogger("PloneFormGen") validation.register( validators.CircularDependencyValidator('CircularDependencyValidator')) schema = FormAdapterSchema.copy() + Schema(( StringField( 'SFObjectType', searchable=0, required=1, read_permission=ModifyPortalContent, default=u'Contact', mutator='setSFObjectType', widget=SelectionWidget( label='Salesforce Object Type', i18n_domain="salesforcepfgadapter", label_msgid="label_salesforce_type_text", ), vocabulary='displaySFObjectTypes', ), DataGridField(
from Products.PloneFormGen.content.actionAdapter import \ FormActionAdapter, FormAdapterSchema from zope.app.intid.interfaces import IIntIds from Products.Archetypes import atapi from Products.ATContentTypes.content import schemata # -*- Message Factory Imported Here -*- from getpaid.pfgbuyableadapter import pfgbuyableadapterMessageFactory as _ from getpaid.pfgbuyableadapter.interfaces import IBuyableFormAdapter from getpaid.pfgbuyableadapter.config import PROJECTNAME BuyableFormAdapterSchema = FormAdapterSchema.copy() + atapi.Schema(( # -*- Your Archetypes field definitions here ... -*- atapi.FixedPointField( 'price', storage=atapi.AnnotationStorage(), widget=atapi.DecimalWidget( label=_(u"Price"), description=_(u"How much does this form cost"), dollars_and_cents=True, ), required=True, precision = 2, validators=('isDecimal'), ),
class FormSaveDataAdapter(FormActionAdapter): """A form action adapter that will save form input data and return it in csv- or tab-delimited format.""" schema = FormAdapterSchema.copy() + Schema(( LinesField('ExtraData', widget=MultiSelectionWidget( label=_(u'label_savedataextra_text', default='Extra Data'), description=_(u'help_savedataextra_text', default=u""" Pick any extra data you'd like saved with the form input. """), format='checkbox', ), vocabulary = 'vocabExtraDataDL', ), StringField('DownloadFormat', searchable=0, required=1, default='csv', vocabulary = 'vocabFormatDL', widget=SelectionWidget( label=_(u'label_downloadformat_text', default=u'Download Format'), ), ), BooleanField("UseColumnNames", required=False, searchable=False, widget=BooleanWidget( label = _(u'label_usecolumnnames_text', default=u"Include Column Names"), description = _(u'help_usecolumnnames_text', default=u"Do you wish to have column names on the first line of downloaded input?"), ), ), ExLinesField('SavedFormInput', edit_accessor='getSavedFormInputForEdit', mutator='setSavedFormInput', searchable=0, required=0, primary=1, schemata="saved data", read_permission=DOWNLOAD_SAVED_PERMISSION, widget=TextAreaWidget( label=_(u'label_savedatainput_text', default=u"Saved Form Input"), description=_(u'help_savedatainput_text'), ), ), )) schema.moveField('execCondition', pos='bottom') meta_type = 'FormSaveDataAdapter' portal_type = 'FormSaveDataAdapter' archetype_name = 'Save Data Adapter' immediate_view = 'fg_savedata_view_p3' default_view = 'fg_savedata_view_p3' suppl_views = ('fg_savedata_tabview_p3', 'fg_savedata_recview_p3',) security = ClassSecurityInfo() def _migrateStorage(self): # we're going to use an LOBTree for storage. we need to # consider the possibility that self is from an # older version that uses the native Archetypes storage # or the former IOBTree (<= 1.6.0b2 ) # in the SavedFormInput field. updated = base_hasattr(self, '_inputStorage') and \ base_hasattr(self, '_inputItems') and \ base_hasattr(self, '_length') if not updated: try: saved_input = self.getSavedFormInput() except AttributeError: saved_input = [] self._inputStorage = SavedDataBTree() i = 0 self._inputItems = 0 self._length = Length() if len(saved_input): for row in saved_input: self._inputStorage[i] = row i += 1 self.SavedFormInput = [] self._inputItems = i self._length.set(i) security.declareProtected(DOWNLOAD_SAVED_PERMISSION, 'getSavedFormInput') def getSavedFormInput(self): """ returns saved input as an iterable; each row is a sequence of fields. """ if base_hasattr(self, '_inputStorage'): return self._inputStorage.values() else: return self.SavedFormInput security.declareProtected(DOWNLOAD_SAVED_PERMISSION, 'getSavedFormInputItems') def getSavedFormInputItems(self): """ returns saved input as an iterable; each row is an (id, sequence of fields) tuple """ if base_hasattr(self, '_inputStorage'): return self._inputStorage.items() else: return enumerate(self.SavedFormInput) security.declareProtected(ModifyPortalContent, 'getSavedFormInputForEdit') def getSavedFormInputForEdit(self, **kwargs): """ returns saved as CSV text """ delimiter = self.csvDelimiter() sbuf = StringIO() writer = csv.writer(sbuf, delimiter=delimiter) for row in self.getSavedFormInput(): writer.writerow( row ) res = sbuf.getvalue() sbuf.close() return res security.declareProtected(ModifyPortalContent, 'setSavedFormInput') def setSavedFormInput(self, value, **kwargs): """ expects value as csv text string, stores as list of lists """ self._migrateStorage() self._inputStorage.clear() i = 0 self._inputItems = 0 self._length.set(0) if len(value): delimiter = self.csvDelimiter() sbuf = StringIO( value ) reader = csv.reader(sbuf, delimiter=delimiter) for row in reader: if row: self._inputStorage[i] = row i += 1 self._inputItems = i self._length.set(i) sbuf.close() # logger.debug("setSavedFormInput: %s items" % self._inputItems) security.declareProtected(ModifyPortalContent, 'clearSavedFormInput') def clearSavedFormInput(self, **kwargs): """ convenience method to clear input buffer """ REQUEST = kwargs.get('request', self.REQUEST) if REQUEST.form.has_key('clearSavedFormInput'): # we're processing a request from the web; # check for CSRF plone.protect.CheckAuthenticator(REQUEST) plone.protect.PostOnly(REQUEST) self._migrateStorage() self._inputStorage.clear() self._inputItems = 0 self._length.set(0) security.declareProtected(DOWNLOAD_SAVED_PERMISSION, 'getSavedFormInputById') def getSavedFormInputById(self, id): """ Return the data stored for record with 'id' """ lst = [field.replace('\r','').replace('\n', r'\n') for field in self._inputStorage[id]] return lst security.declareProtected(ModifyPortalContent, 'manage_saveData') def manage_saveData(self, id, data): """ Save the data for record with 'id' """ self._migrateStorage() lst = list() for i in range(0, len(self.getColumnNames())): lst.append(getattr(data, 'item-%d' % i, '').replace(r'\n', '\n')) self._inputStorage[id] = lst self.REQUEST.RESPONSE.redirect(self.absolute_url() + '/view') security.declareProtected(ModifyPortalContent, 'manage_deleteData') def manage_deleteData(self, id): """ Delete the data for record with 'id' """ self._migrateStorage() del self._inputStorage[id] self._inputItems -= 1 self._length.change(-1) self.REQUEST.RESPONSE.redirect(self.absolute_url() + '/view') def _addDataRow(self, value): self._migrateStorage() if isinstance(self._inputStorage, IOBTree): # 32-bit IOBTree; use a key which is more likely to conflict # but which won't overflow the key's bits id = self._inputItems self._inputItems += 1 else: # 64-bit LOBTree id = int(time.time() * 1000) while id in self._inputStorage: # avoid collisions during testing id += 1 self._inputStorage[id] = value self._length.change(1) security.declareProtected(ModifyPortalContent, 'addDataRow') def addDataRow(self, value): """ a wrapper for the _addDataRow method """ self._addDataRow(value) def onSuccess(self, fields, REQUEST=None, loopstop=False): """ saves data. """ if LP_SAVE_TO_CANONICAL and not loopstop: # LinguaPlone functionality: # check to see if we're in a translated # form folder, but not the canonical version. parent = self.aq_parent if safe_hasattr(parent, 'isTranslation') and \ parent.isTranslation() and not parent.isCanonical(): # look in the canonical version to see if there is # a matching (by id) save-data adapter. # If so, call its onSuccess method cf = parent.getCanonical() target = cf.get(self.getId()) if target is not None and target.meta_type == 'FormSaveDataAdapter': target.onSuccess(fields, REQUEST, loopstop=True) return from ZPublisher.HTTPRequest import FileUpload data = [] for f in fields: if f.isFileField(): file = REQUEST.form.get('%s_file' % f.fgField.getName()) if isinstance(file, FileUpload) and file.filename != '': file.seek(0) fdata = file.read() filename = file.filename mimetype, enc = guess_content_type(filename, fdata, None) if mimetype.find('text/') >= 0: # convert to native eols fdata = fdata.replace('\x0d\x0a', '\n').replace('\x0a', '\n').replace('\x0d', '\n') data.append( '%s:%s:%s:%s' % (filename, mimetype, enc, fdata) ) else: data.append( '%s:%s:%s:Binary upload discarded' % (filename, mimetype, enc) ) else: data.append( 'NO UPLOAD' ) elif not f.isLabel(): val = REQUEST.form.get(f.fgField.getName(),'') if not type(val) in StringTypes: # Zope has marshalled the field into # something other than a string val = str(val) data.append(val) if self.ExtraData: for f in self.ExtraData: if f == 'dt': data.append( str(DateTime()) ) else: data.append( getattr(REQUEST, f, '') ) self._addDataRow( data ) security.declareProtected(DOWNLOAD_SAVED_PERMISSION, 'getColumnNames') def getColumnNames(self): """Returns a list of column names""" names = [field.getName() for field in self.fgFields(displayOnly=True)] for f in self.ExtraData: names.append(f) return names security.declareProtected(DOWNLOAD_SAVED_PERMISSION, 'getColumnTitles') def getColumnTitles(self): """Returns a list of column titles""" names = [field.widget.label for field in self.fgFields(displayOnly=True)] for f in self.ExtraData: names.append(self.vocabExtraDataDL().getValue(f, '')) return names def _cleanInputForTSV(self, value): # make data safe to store in tab-delimited format return str(value).replace('\x0d\x0a', r'\n').replace('\x0a', r'\n').replace('\x0d', r'\n').replace('\t', r'\t') security.declareProtected(DOWNLOAD_SAVED_PERMISSION, 'download_tsv') def download_tsv(self, REQUEST=None, RESPONSE=None): """Download the saved data """ filename = self.id if filename.find('.') < 0: filename = '%s.tsv' % filename header_value = contentDispositionHeader('attachment', self.getCharset(), filename=filename) RESPONSE.setHeader("Content-Disposition", header_value) RESPONSE.setHeader("Content-Type", 'text/tab-separated-values;charset=%s' % self.getCharset()) if getattr(self, 'UseColumnNames', False): res = "%s\n" % '\t'.join( self.getColumnNames() ) if isinstance(res, unicode): res = res.encode(self.getCharset()) else: res = '' for row in self.getSavedFormInput(): res = '%s%s\n' % (res, '\t'.join( [self._cleanInputForTSV(col) for col in row] )) return res security.declareProtected(DOWNLOAD_SAVED_PERMISSION, 'download_csv') def download_csv(self, REQUEST=None, RESPONSE=None): """Download the saved data """ filename = self.id if filename.find('.') < 0: filename = '%s.csv' % filename header_value = contentDispositionHeader('attachment', self.getCharset(), filename=filename) RESPONSE.setHeader("Content-Disposition", header_value) RESPONSE.setHeader("Content-Type", 'text/comma-separated-values;charset=%s' % self.getCharset()) if getattr(self, 'UseColumnNames', False): delimiter = self.csvDelimiter() res = "%s\n" % delimiter.join( self.getColumnNames() ) if isinstance(res, unicode): res = res.encode(self.getCharset()) else: res = '' return '%s%s' % (res, self.getSavedFormInputForEdit()) security.declareProtected(DOWNLOAD_SAVED_PERMISSION, 'download') def download(self, REQUEST=None, RESPONSE=None): """Download the saved data """ format = getattr(self, 'DownloadFormat', 'tsv') if format == 'tsv': return self.download_tsv(REQUEST, RESPONSE) else: assert format == 'csv', 'Unknown download format' return self.download_csv(REQUEST, RESPONSE) security.declareProtected(DOWNLOAD_SAVED_PERMISSION, 'rowAsColDict') def rowAsColDict(self, row, cols): """ Where row is a data sequence and cols is a column name sequence, returns a dict of colname:column. This is a convenience method used in the record view. """ colcount = len(cols) rdict = {} for i in range(0, len(row)): if i < colcount: rdict[cols[i]] = row[i] else: rdict['column-%s' % i] = row[i] return rdict security.declareProtected(DOWNLOAD_SAVED_PERMISSION, 'inputAsDictionaries') def inputAsDictionaries(self): """returns saved data as an iterable of dictionaries """ cols = self.getColumnNames() for row in self.getSavedFormInput(): yield self.rowAsColDict(row, cols) # alias for old mis-naming security.declareProtected(DOWNLOAD_SAVED_PERMISSION, 'InputAsDictionaries') InputAsDictionaries = inputAsDictionaries security.declareProtected(DOWNLOAD_SAVED_PERMISSION, 'formatMIME') def formatMIME(self): """MIME format selected for download """ format = getattr(self, 'DownloadFormat', 'tsv') if format == 'tsv': return 'text/tab-separated-values' else: assert format == 'csv', 'Unknown download format' return 'text/comma-separated-values' security.declarePrivate('csvDelimiter') def csvDelimiter(self): """Delimiter character for CSV downloads """ fgt = getToolByName(self, 'formgen_tool') return fgt.getCSVDelimiter() security.declareProtected(DOWNLOAD_SAVED_PERMISSION, 'itemsSaved') def itemsSaved(self): """Download the saved data """ if base_hasattr(self, '_length'): return self._length() elif base_hasattr(self, '_inputItems'): return self._inputItems else: return len(self.SavedFormInput) def vocabExtraDataDL(self): """ returns vocabulary for extra data """ return DisplayList( ( ('dt', self.translate( msgid='vocabulary_postingdt_text', domain='ploneformgen', default='Posting Date/Time') ), ('HTTP_X_FORWARDED_FOR','HTTP_X_FORWARDED_FOR',), ('REMOTE_ADDR','REMOTE_ADDR',), ('HTTP_USER_AGENT','HTTP_USER_AGENT',), ) ) def vocabFormatDL(self): """ returns vocabulary for format """ return DisplayList( ( ('tsv', self.translate( msgid='vocabulary_tsv_text', domain='ploneformgen', default='Tab-Separated Values') ), ('csv', self.translate( msgid='vocabulary_csv_text', domain='ploneformgen', default='Comma-Separated Values') ), ) )
from types import StringTypes from Products.PloneFormGen import PloneFormGenMessageFactory as _ from Products.PloneFormGen import HAS_PLONE30, dollarReplace try: # 3.0+ from zope.contenttype import guess_content_type except ImportError: # 2.5.x from zope.app.content_types import guess_content_type import zope.i18n formMailerAdapterSchema = FormAdapterSchema.copy() + Schema(( StringField('recipient_name', searchable=0, required=0, default_method='getDefaultRecipientName', write_permission=EDIT_ADDRESSING_PERMISSION, read_permission=ModifyPortalContent, widget=StringWidget( label = "Recipient's full name", description = """ The full name of the recipient of the mailed form. """, description_msgid = "help_formmailer_recipient_fullname", label_msgid = "label_formmailer_recipient_fullname", i18n_domain = "ploneformgen", ),
from Products.PloneFormGen.content.actionAdapter import \ FormActionAdapter, FormAdapterSchema from Products.ATContentTypes.content import schemata # -*- Message Factory Imported Here -*- from collective.pfg.sqlformadapter import sqlformadapterMessageFactory as _ from collective.pfg.sqlformadapter.interfaces import IEncryptedSQLAdapter from collective.pfg.sqlformadapter.config import PROJECTNAME import pymssql import logging dblog = logging.getLogger('collective.pfg.sqlformadapter.dblog') EncryptedSQLAdapterSchema = FormAdapterSchema.copy() + atapi.Schema(( # -*- Your Archetypes field definitions here ... -*- atapi.StringField( 'table', storage=atapi.AnnotationStorage(), widget=atapi.StringWidget( label=_(u"Database Table"), description=_(u"Table to insert data into"), ), required=True, ), atapi.StringField(
# sqlalchemy imports from sqlalchemy import MetaData, Table, Column # sqlalchemy column types from sqlalchemy import Integer, String, Text, Boolean, DateTime, Float logger = logging.getLogger("Products.sqlpfgadapter") from Products.sqlpfgadapter.config import PROJECTNAME # Used for storing multiple values in a column DELIMITER = '\nXXX' # DB Columns (field names) must be shorter than this MAX_COLUMN_SIZE = 64 schema = FormAdapterSchema.copy() + Schema(( StringField('table_id', widget=StringWidget( label = "Database table name", description = """A database table with this name was added when the action adapter was created. The submitted forms will be stored in this table. Its name is provided here so you know where to find the saved forms. """, label_msgid = "label_table_id", description_msgid = "help_table_id", i18n_domain = "Products.sqlpfgadapter", visible = {'edit': 'hidden', 'view': 'visible'}, ), required = False, ), )) class SQLPFGAdapter(FormActionAdapter):
from Products.Archetypes import atapi from Products.ATContentTypes.content import base from Products.ATContentTypes.content import schemata from Products.CMFPlone.interfaces import IPloneSiteRoot from Products.PloneFormGen.content.actionAdapter import \ FormActionAdapter, FormAdapterSchema from abstract.downloadmarshal.interfaces import IMarshal from abstract.downloadmarshal_pfg.interfaces import IDownloadMarshalAdapter from abstract.downloadmarshal_pfg.config import PROJECTNAME from abstract.downloadmarshal_pfg import _ DownloadMarshalAdapterSchema = FormAdapterSchema.copy() + atapi.Schema(( atapi.StringField( 'resource_path', widget=atapi.StringWidget( label=_(u'path to download resource'), description=_(u'if none the container of the form folder will be used as resource'), ), searchable=0, required=0, ), )) # Set storage on fields copied from ATContentTypeSchema, making sure # they work well with the python bridge properties.