Example #1
0
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.
            """)
            ),
        ),
Example #4
0
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)
Example #5
0
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',
Example #7
0
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(
Example #9
0
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 "
Example #15
0
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'),
    ),
Example #17
0
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')
                    ),
            ) )
Example #18
0
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.