Beispiel #1
0
class ServerConfig(ConfigFile):

    schema = {
        'modules': Tokens,
        'listen-address': String(default=''),
        'listen-port': Integer(default=None),
        # Mailing
        'smtp-host': String(default=''),
        'smtp-from': String(default=''),
        'smtp-login': String(default=''),
        'smtp-password': String(default=''),
        # Logging
        'log-level': String(default='warning'),
        'log-email': Email(default=''),
        # Time events
        'cron-interval': Integer(default=0),
        # Security
        'session-timeout': ExpireValue(default=timedelta(0)),
        # Tuning
        'database-size': String(default='19500:20500'),
        'database-readonly': Boolean(default=False),
        'index-text': Boolean(default=True),
        'max-width': Integer(default=None),
        'max-height': Integer(default=None),
    }
Beispiel #2
0
class Document(CatalogAware):

    fields = {
        'name': String(is_key_field=True, is_stored=True, is_indexed=True),
        'title': Unicode(is_stored=True, is_indexed=True),
        'data': Unicode(is_indexed=True),
        'size': Integer(is_indexed=True),
        'about_wolf': Boolean(is_indexed=True),
        'is_long': Boolean(is_indexed=False, is_stored=True)
    }

    def __init__(self, abspath):
        self.abspath = abspath

    def get_catalog_values(self):
        data = lfs.open(self.abspath).read()

        return {
            'name': basename(self.abspath),
            'title': data.splitlines()[0],
            'data': data,
            'size': len(data),
            'about_wolf': re.search('wolf', data, re.I) is not None,
            'is_long': len(data) > 1024,
        }
Beispiel #3
0
class PaymentWay_Configure(DBResource_Edit):

    access = 'is_admin'

    schema = {
        'title': Unicode(mandatory=True, multilingual=True),
        'logo': ImagePathDataType(mandatory=True, multilingual=True),
        'data': XHTMLBody(mandatory=True, multilingual=True),
        'only_this_groups': UserGroup_Enumerate(multiple=True),
        'enabled': Boolean(mandatory=True)
    }

    widgets = [
        TextWidget('title', title=MSG(u'Title')),
        ImageSelectorWidget('logo', title=MSG(u'Logo')),
        BooleanRadio('enabled', title=MSG(u'Enabled ?')),
        RTEWidget('data', title=MSG(u"Description")),
        SelectWidget('only_this_groups', title=MSG(u"Only for this groups"))
    ]

    submit_value = MSG(u'Edit configuration')

    def get_value(self, resource, context, name, datatype):
        language = resource.get_content_language(context)
        return resource.get_property(name, language=language)

    def action(self, resource, context, form):
        language = resource.get_content_language(context)
        for key, datatype in self.schema.items():
            if getattr(datatype, 'multilingual', False):
                resource.set_property(key, form[key], language=language)
            else:
                resource.set_property(key, form[key])
        return context.come_back(messages.MSG_CHANGES_SAVED, goto='./')
Beispiel #4
0
 def get_metadata_schema(cls):
     return merge_dicts(ShopFolder.get_metadata_schema(),
                        data=XHTMLBody(multilingual=True),
                        title=Unicode(multilingual=True),
                        enabled=Boolean(default=True),
                        only_this_groups=UserGroup_Enumerate(multiple=True),
                        logo=ImagePathDataType(multilingual=True))
Beispiel #5
0
 def get_metadata_schema(cls):
     schema = ShopFolder.get_metadata_schema()
     schema.update(WorkflowAware.get_metadata_schema())
     schema['total_price'] = Decimal(title=MSG(u'Total price'))
     schema['shipping_price'] = Decimal
     schema['total_weight'] = Decimal
     schema['creation_datetime'] = ISODateTime(title=MSG(u'Creation date'))
     schema['customer_id'] = Users_Enumerate
     schema['payment_mode'] = PaymentWaysEnumerate
     schema['shipping'] = ShippingWaysEnumerate
     schema['delivery_address'] = Integer
     schema['bill_address'] = Integer
     # States
     schema['is_payed'] = Boolean(default=False)
     schema['is_sent'] = Boolean(default=False)
     return schema
Beispiel #6
0
class Document(Resource):

    fields = {
        'abspath': String(indexed=True, stored=True),
        'name': String(indexed=True),
        'lang': String(indexed=True, stored=True),
        'title': Unicode(stored=True, indexed=True),
        'data': Unicode(indexed=True),
        'about_wolf': Boolean(indexed=True),
        'is_long': Boolean(indexed=False, stored=True),
        'count': Integer(stored=True, multiple=True),
    }

    def __init__(self, abspath):
        self.abspath = abspath

    def get_catalog_values(self):
        # Filename
        filename = basename(self.abspath)
        name, ext, lang = FileName.decode(filename)
        # Content
        with open(self.abspath) as f:
            data = f.read()
            data = unicode(data, 'utf-8')
        title = data.splitlines()[0]
        wolf = re.search('wolf', data, re.I) is not None
        count = [
            len(data.splitlines()),  # lines
            len(data.split()),  # words
            len(data)
        ]  # chars
        # Multilingual
        if lang:
            data = {lang: data}
            title = {lang: title}

        # Ok
        return {
            'abspath': filename,  # oid
            'name': name,
            'lang': lang,
            'title': title,
            'data': data,
            'count': count,
            'about_wolf': wolf,
            'is_long': count[2] > 1024
        }
Beispiel #7
0
class ITWSHOPConfig(ConfigFile):

    schema = {
        'url': String(default=''),
        'source_language': LanguageTag(default=('en', 'EN')),
        'target_languages': Tokens(default=(('en', 'EN'), )),
        'skin_path': String(default=''),
        'show_language_title': Boolean(default=False)
    }
Beispiel #8
0
class PaymentWayBaseTable(BaseTable):

    record_properties = {
        'ref': String(is_indexed=True, is_stored=True),
        'user': String(is_indexed=True),
        'state': Boolean(is_indexed=True,),
        'amount': Decimal(title=MSG(u'Payment amount')),
        'resource_validator': String,
        'description': Unicode(title=MSG(u'Payment description'))}
Beispiel #9
0
    def rest(self):
        rest = {'type': self.rest_type}
        # From the datatype
        datatype = self.get_datatype()
        for key in 'multiple', 'multilingual', 'indexed', 'stored':
            value = getattr(datatype, key)
            rest[key] = Boolean.encode(value)

        # Default value
        default = self.get_default()
        if default is not None:
            rest['default'] = datatype.encode(default)

        # Other
        for key in 'required', 'readonly':
            value = getattr(self, key)
            rest[key] = Boolean.encode(value)

        # Ok
        return rest
Beispiel #10
0
    def rest(self):
        rest = {'type': self.rest_type}
        # From the datatype
        datatype = self.get_datatype()
        for key in 'multiple', 'multilingual', 'indexed', 'stored':
            value = getattr(datatype, key)
            rest[key] = Boolean.encode(value)

        # Default value
        default = self.get_default()
        if default is not None:
            rest['default'] = datatype.encode(default)

        # Other
        for key in 'required', 'readonly':
            value = getattr(self, key)
            rest[key] = Boolean.encode(value)

        # Ok
        return rest
Beispiel #11
0
class DBResource_GetImage(DBResource_GetFile):

    query_schema = {
        'name': String,
        'width': Integer,
        'height': Integer,
        'fit': Boolean(default=False),
        'lossy': Boolean(default=False)
    }

    def GET(self, resource, context):
        field_name = self.get_field_name(context)
        handler = self.get_handler(resource, field_name)

        image_width, image_height = handler.get_size()
        fit = context.query['fit']
        lossy = context.query['lossy']
        width = context.query['width'] or image_width
        height = context.query['height'] or image_height

        format = 'jpeg'
        if lossy is False:
            format = handler.get_mimetype().split('/')[1]
        data, format = handler.get_thumbnail(width, height, format, fit)
        if data is None:
            default = context.get_template('/ui/icons/48x48/image.png')
            data = default.to_str()
            format = 'png'

        # Headers
        context.set_content_type('image/%s' % format)
        #       filename = resource.get_value('filename')
        #       if filename:
        #           context.set_content_disposition('inline', filename)

        # Ok
        return data
Beispiel #12
0
    def get_table_head(self, resource, context, items):
        actions = self.actions_namespace

        # Get from the query
        query = context.query
        sort_by = query['sort_by']
        reverse = query['reverse']

        columns = self._get_table_columns(resource, context)
        columns_ns = []
        for name, title, sortable, css in columns:
            if name == 'checkbox':
                # Type: checkbox
                if actions:
                    columns_ns.append({'is_checkbox': True})
            elif title is None:
                # Type: nothing
                continue
            elif not sortable:
                # Type: nothing or not sortable
                columns_ns.append({
                    'is_checkbox': False,
                    'title': title,
                    'href': None
                })
            else:
                # Type: normal
                kw = {'sort_by': name}
                if name == sort_by:
                    col_reverse = (not reverse)
                    order = 'up' if reverse else 'down'
                else:
                    col_reverse = False
                    order = 'none'
                kw['reverse'] = Boolean.encode(col_reverse)
                columns_ns.append({
                    'is_checkbox': False,
                    'title': title,
                    'order': order,
                    'href': context.uri.replace(**kw),
                })
Beispiel #13
0
    def get_table_head(self, resource, context, items):
        actions = self.actions_namespace

        # Get from the query
        query = context.query
        sort_by = query['sort_by']
        reverse = query['reverse']

        columns = self._get_table_columns(resource, context)
        columns_ns = []
        for name, title, sortable, css in columns:
            if name == 'checkbox':
                # Type: checkbox
                if  actions:
                    columns_ns.append({'is_checkbox': True})
            elif title is None:
                # Type: nothing
                continue
            elif not sortable:
                # Type: nothing or not sortable
                columns_ns.append({
                    'is_checkbox': False,
                    'title': title,
                    'href': None})
            else:
                # Type: normal
                kw = {'sort_by': name}
                if name == sort_by:
                    col_reverse = (not reverse)
                    order = 'up' if reverse else 'down'
                else:
                    col_reverse = False
                    order = 'none'
                kw['reverse'] = Boolean.encode(col_reverse)
                columns_ns.append({
                    'is_checkbox': False,
                    'title': title,
                    'order': order,
                    'href': context.uri.replace(**kw),
                    })
Beispiel #14
0
    def get_quantity_in_stock(self):
        return self.get_property('stock-quantity')

    def get_reference(self):
        return self.get_property('reference')

    def get_price_impact(self, prefix):
        if prefix is None:
            prefix = self.parent.get_price_prefix()
        return self.get_property('%simpact_on_price' % prefix)

    def get_weight(self):
        base_weight = self.parent.get_property('weight')
        weight_impact = self.get_property('impact-on-weight')
        weight_value = self.get_property('weight-impact-value')
        if weight_impact == 'none':
            return base_weight
        elif weight_impact == 'increase':
            return base_weight + weight_value
        elif weight_impact == 'decrease':
            return base_weight - weight_value

    def get_document_types(self):
        return []


register_resource_class(Declination)
register_field('declination_title', Unicode(is_indexed=True, is_stored=True))
register_field('is_default', Boolean(is_indexed=True))
Beispiel #15
0
class BrowseForm(STLView):

    template = '/ui/ikaaro/generic/browse.xml'

    query_schema = {
        'batch_start': Integer(default=0),
        'batch_size': Integer(default=20),
        'sort_by': String,
        'reverse': Boolean(default=False)}

    # Batch
    batch = Batch

    # Search configuration
    search_form_id = 'form-search'
    search_form_css = ''
    search_template = '/ui/ikaaro/auto_form.xml'
    search_template_field = '/ui/ikaaro/auto_form_field.xml'
    search_schema = {}
    search_widgets = []

    # Content
    table_template = '/ui/ikaaro/generic/browse_table.xml'
    table_form_id = 'form-table'
    table_css = None
    table_columns = []
    table_actions = []
    # Actions are external to current form
    external_form = False

    # Keep the batch in the canonical URL
    canonical_query_parameters = (STLView.canonical_query_parameters
                                  + ['batch_start'])


    def get_query_schema(self):
        proxy = super(BrowseForm, self)
        return merge_dicts(proxy.get_query_schema(), self.search_schema)


    def get_namespace(self, resource, context):
        batch = None
        table = None
        # Batch
        items = self.get_items(resource, context)
        if self.batch is not None:
            total = len(items)
            batch = self.batch(context=context, total=total).render()

        # Content
        items = self.sort_and_batch(resource, context, items)
        if self.table_template is not None:
            template = context.get_template(self.table_template)
            namespace = self.get_table_namespace(resource, context, items)
            table = stl(template, namespace)

        # The Search Form
        search = None
        if self.search_widgets:
            search = self.get_search_namespace(resource, context)

        return {'batch': batch, 'table': table, 'search': search}


    ##################################################
    # Search
    ##################################################
    def get_search_actions(self, resource, context):
        search_button = Button(access=True,
            resource=resource, context=context,
            css='button-search', title=MSG(u'Search'))
        return [search_button]


    def get_search_namespace(self, resource, context):
        form = AutoForm(
            form_id=self.search_form_id,
            form_css=self.search_form_css,
            template=self.search_template,
            template_field=self.search_template_field,
            title=MSG(u'Search'),
            method='get',
            schema=self.search_schema,
            widgets=self.search_widgets,
            actions=self.get_search_actions(resource, context))
        return form.GET(resource, context)


    #######################################################################
    # Private API (to override)
    def get_table_columns(self, resource, context):
        return self.table_columns


    def _get_table_columns(self, resource, context):
        """ Always return a tuple of 4 elements. """
        table_columns = []
        for column in self.get_table_columns(resource, context):
            if len(column) == 2:
                name, title = column
                column = (name, title, True, None)
            elif len(column) == 3:
                name, title, sortable = column
                column = (name, title, sortable, None)
            table_columns.append(column)
        return table_columns


    def get_items(self, resource, context):
        name = 'get_items'
        raise NotImplementedError, "the '%s' method is not defined" % name


    def sort_and_batch(self, resource, context, items):
        name = 'sort_and_batch'
        raise NotImplementedError, "the '%s' method is not defined" % name


    def get_item_value(self, resource, context, item, column):
        if column == 'row_css':
            return None

        # Default
        raise ValueError, 'unexpected "%s"' % column


    def get_table_actions(self, resource, context):
        return self.table_actions


    #######################################################################
    # Table
    def get_table_head(self, resource, context, items):
        actions = self.actions_namespace

        # Get from the query
        query = context.query
        sort_by = query['sort_by']
        reverse = query['reverse']

        columns = self._get_table_columns(resource, context)
        columns_ns = []
        for name, title, sortable, css in columns:
            if name == 'checkbox':
                # Type: checkbox
                if self.external_form or actions:
                    columns_ns.append({'is_checkbox': True})
            elif title is None or not sortable:
                # Type: nothing or not sortable
                columns_ns.append({
                    'is_checkbox': False,
                    'title': title,
                    'css': 'thead-%s' % name.replace('_', '-'),
                    'href': None,
                    'sortable': False})
            else:
                # Type: normal
                base_href = context.uri.replace(sort_by=name, batch_start=None)
                if name == sort_by:
                    sort_up_active = reverse is False
                    sort_down_active = reverse is True
                else:
                    sort_up_active = sort_down_active = False
                columns_ns.append({
                    'is_checkbox': False,
                    'title': title,
                    'css': 'thead-%s' % name.replace('_', '-'),
                    'sortable': True,
                    'href': context.uri.path,
                    'href_up': base_href.replace(reverse=0),
                    'href_down': base_href.replace(reverse=1),
                    'sort_up_active': sort_up_active,
                    'sort_down_active': sort_down_active
                    })
        return columns_ns


    @proto_lazy_property
    def actions_namespace(self):
        resource = self.resource
        context = self.context
        items = self._items

        actions = []
        for button in self.get_table_actions(resource, context):
            button = button(resource=resource, context=context, items=items)
            if button.show:
                actions.append(button)

        return actions


    def get_column_css(self, resource, context, column):
        return None


    def get_table_namespace(self, resource, context, items):
        # (1) Actions (submit buttons)
        self._items = items
        actions = self.actions_namespace
        # (2) Table Head: columns
        table_head = self.get_table_head(resource, context, items)

        # (3) Table Body: rows
        columns = self.get_table_columns(resource, context)
        rows = []
        for item in items:
            row_columns = []
            for column in columns:
                column = column[0]
                # Skip the checkbox column if there are not any actions
                if column == 'checkbox':
                    if not self.external_form and not actions:
                        continue

                value = self.get_item_value(resource, context, item, column)
                column_ns = {
                    'is_checkbox': False,
                    'is_icon': False,
                    'is_link': False,
                    'css': self.get_column_css(resource, context, column),
                }
                # Type: empty
                if value is None:
                    pass
                # Type: checkbox
                elif column == 'checkbox':
                    value, checked = value
                    column_ns['is_checkbox'] = True
                    column_ns['value'] = value
                    column_ns['checked'] = checked
                # Type: icon
                elif column == 'icon':
                    column_ns['is_icon'] = True
                    column_ns['src'] = value
                # Type: normal
                else:
                    column_ns['is_link'] = True
                    if type(value) is tuple:
                        value, href = value
                    else:
                        href = None
                    column_ns['value'] = value
                    column_ns['href'] = href
                row_columns.append(column_ns)
            # Row css
            row_css = self.get_item_value(resource, context, item, 'row_css')

            # Append
            rows.append({'css': row_css, 'columns': row_columns})

        # Ok
        return {
            'css': self.table_css,
            'form_id': self.table_form_id,
            'columns': table_head,
            'rows': rows,
            'actions': actions,
            'external_form': self.external_form or not actions}
Beispiel #16
0
class LoginView(STLView):

    access = True
    title = MSG(u'Login')
    template = '/ui/ikaaro/base/login.xml'
    meta = [('robots', 'noindex, follow', None)]

    query_schema = {'loginname': String(), 'no_password': Boolean()}
    schema = {
        'loginname': String(mandatory=True),
        'password': String(),
        'no_password': Boolean()
    }

    def GET(self, resource, context):
        if context.user:
            msg = MSG(u'You are already connected')
            goto = str(context.user.abspath)
            return context.come_back(msg, goto)
        return super(LoginView, self).GET(resource, context)

    def POST(self, resource, context):
        if context.status == 401:
            # Don't submit login with data from another form
            return self.GET
        return super(LoginView, self).POST(resource, context)

    def get_value(self, resource, context, name, datatype):
        if name == 'loginname':
            return context.query['loginname']
        proxy = super(LoginView, self)
        return proxy.get_value(resource, context, name, datatype)

    def get_namespace(self, resource, context):
        namespace = super(LoginView, self).get_namespace(resource, context)
        namespace['no_password'] = context.query['no_password']
        # Register
        user = context.user
        register = context.root.is_allowed_to_register(user, resource)
        namespace['register'] = register
        # Login name
        cls = context.database.get_resource_class('user')
        field = cls.get_field(cls.login_name_property)
        namespace['login_name_title'] = field.title
        # Ok
        return namespace

    def action(self, resource, context, form):
        # Get the user
        loginname = form['loginname'].strip()
        user = context.root.get_user_from_login(loginname)

        # Case 1: Forgotten password
        if form['no_password']:
            # 1.1 Send email
            if user:
                email = user.get_value('email')
                if user.get_value('user_state') == 'inactive':
                    email_id = None  # TODO
                else:
                    user.update_pending_key()
                    email_id = 'forgotten-password-ask-for-confirmation'
            else:
                email_id = None  # TODO Which is the email address?

            if email_id:
                send_email(email_id, context, email, user=user)

            # 1.2 Show message (we show the same message even if the user
            # does not exist, because privacy wins over usability)
            path = '/ui/ikaaro/website/forgotten_password.xml'
            handler = context.get_template(path)
            return stl(handler)

        # Case 2: Login
        if user is None:
            context.message = MSG_LOGIN_WRONG_NAME_OR_PASSWORD
            return

        error = user._login(form['password'], context)
        if error:
            context.message = error
            return

        return self.get_goto(user)

    def get_goto(self, user):
        context = self.context

        # Check if user account is completed
        for name, field in user.get_fields():
            if field.required and user.get_value(name) is None:
                msg = MSG(u'You must complete your account informations')
                goto = '/users/%s/;edit_account' % user.name
                return context.come_back(msg, goto)

        # Come back
        referrer = context.get_referrer()
        if referrer is None:
            goto = get_reference('./')
        else:
            path = get_uri_path(referrer)
            if path.endswith(';login') or path.endswith(';register'):
                goto = get_reference('./')
            else:
                goto = referrer

        return context.come_back(INFO(u"Welcome!"), goto)
Beispiel #17
0
        context.message = INFO(u'Transition done.')

    action_cancel_order_schema = {}

    def action_cancel_order(self, resource, context, form):
        try:
            resource.make_transition('open_to_cancel', None)
        except WorkflowError, excp:
            log_error(excp.message, domain='ikaaro')
            context.message = ERROR(unicode(excp.message, 'utf-8'))
            return
        context.message = INFO(u'Order has been canceled')

    action_add_message_schema = {
        'message': Unicode(mandatory=True),
        'private': Boolean(mandatory=True)
    }

    def action_add_message(self, resource, context, form):
        messages = resource.get_resource('messages')
        messages.add_new_record({
            'author': context.user.name,
            'private': form['private'],
            'message': form['message'],
            'seen': True
        })
        if form['private'] is False:
            resource.notify_new_message(form['message'], context)
        context.message = INFO(u'Your message has been sent')

    action_change_message_state_schema = {
Beispiel #18
0
class ShopModule_AReview_NewInstance(NewInstance):

    title = MSG(u'Add a review')

    query_schema = {'abspath': String}

    schema = freeze({
        'name': String,
        'abspath': String,
        'title': Unicode(mandatory=True),
        'note': NoteEnumerate,
        'description': Unicode(mandatory=True),
        'advantages': Unicode,
        'disadvantages': Unicode,
        'images': FileDataType(multiple=False),
        'recommended': RecommandationEnumerate,
        'cgu': Boolean(mandatory=True)
    })

    styles = ['/ui/modules/review/style.css']

    @property
    def access(self):
        context = get_context()
        module = get_module(context.resource, ShopModule_Review.class_id)
        if module.get_property('must_be_authenticated_to_post'):
            return 'is_authenticated'
        return True

    def get_widgets(self, resource, context):
        cgu_description = MSG(u"I'm agree with the conditions general of use")
        if context.query['abspath']:
            # on review module
            review_module = resource
        else:
            # on product review
            review_module = get_module(resource, ShopModule_Review.class_id)

        cgu = review_module.get_resource('cgu')
        cgu_link = context.get_link(cgu)
        return [
            HiddenWidget('abspath', title=None),
            TextWidget('title', title=MSG(u'Review title')),
            NoteWidget('note', title=MSG(u'Note'), has_empty_option=False),
            MultilineWidget('description', title=MSG(u'Your review')),
            TextWidget('advantages', title=MSG(u'Advantages')),
            TextWidget('disadvantages', title=MSG(u'Disadvantages')),
            FileWidget('images', title=MSG(u'Images')),
            SelectRadio('recommended',
                        title=MSG(u'Recommendation'),
                        has_empty_option=False,
                        is_inline=True),
            BooleanCheckBox_CGU('cgu',
                                title=MSG(u'Conditions of use'),
                                link=cgu_link,
                                description=cgu_description)
        ]

    def _get_current_reviews_query(self, context, form):
        if form['abspath']:
            product = context.root.get_resource(form['abspath'])
            abspath = product.get_canonical_path().resolve2('reviews')
        else:
            abspath = context.resource.get_canonical_path()
        query = AndQuery(PhraseQuery('parent_path', str(abspath)),
                         PhraseQuery('format', 'shop_module_a_review'))
        return query

    def get_new_resource_name(self, form):
        context = get_context()
        query = self._get_current_reviews_query(context, form)
        search = context.root.search(query)
        if len(search):
            doc = search.get_documents(sort_by='name', reverse=True)[0]
            id_review = int(doc.name) + 1
        else:
            id_review = 1
        return str(id_review)

    def get_value(self, resource, context, name, datatype):
        if name == 'abspath':
            return context.query['abspath']
        return NewInstance.get_value(self, resource, context, name, datatype)

    def _get_form(self, resource, context):
        form = NewInstance._get_form(self, resource, context)

        # Check if the user has already fill a review
        query = self._get_current_reviews_query(context, form)
        author_query = PhraseQuery('shop_module_review_author',
                                   context.user.name)
        query = AndQuery(query, author_query)
        if len(context.root.search(query)):
            raise FormError, ERROR(u'You already have filled a review.')

    #    form = NewInstance._get_form(self, resource, context)
    # Check images
        image = form['images']  # XXX not yet multiple
        if image:
            filename, mimetype, body = image
            if mimetype.startswith('image/') is False:
                raise FormError, MSG_UNEXPECTED_MIMETYPE(mimetype=mimetype)

        return form

    def action(self, resource, context, form):
        name = self.get_new_resource_name(form)
        # Get product in which we have to add review
        if form['abspath']:
            product = context.root.get_resource(form['abspath'])
            # Does product has a container for reviews ?
            reviews = product.get_resource('reviews', soft=True)
            if reviews is None:
                cls = ShopModule_Reviews
                reviews = product.make_resource(cls, product, 'reviews')
        else:
            reviews = resource
            product = reviews.parent
        # Create the reviews
        cls = ShopModule_AReview
        child = cls.make_resource(cls, reviews, name)
        # The metadata
        metadata = child.metadata
        language = resource.get_content_language(context)

        # Anonymous, if user is not authenticated, the review is set
        # as anonymous.
        if context.user:
            metadata.set_property('author', context.user.name)
        # Workflow
        review_module = get_module(resource, ShopModule_Review.class_id)
        state = review_module.get_property('areview_default_state')

        metadata.set_property('title', form['title'])
        metadata.set_property('ctime', datetime.now())
        metadata.set_property('state', state)
        metadata.set_property('remote_ip', context.get_remote_ip())
        metadata.set_property('description', form['description'], language)
        metadata.set_property('note', int(form['note']))
        metadata.set_property('recommended', form['recommended'])
        for key in ['advantages', 'disadvantages']:
            metadata.set_property(key, form[key])

        # Add images
        image = form['images']  # XXX not yet multiple
        if image:
            image = review_module.create_new_image(context, image)
            metadata.set_property('images', str(child.get_pathto(image)))

        # XXX Alert webmaster
        if state == 'private':
            # XXX Add pending message.
            goto = context.get_link(product)
            message = MSG(u'Your review has been added.')
        else:
            goto = context.get_link(reviews)
            message = MSG(u'Review has been added')
        return context.come_back(message, goto=goto)
Beispiel #19
0
class OrdersView(SearchTableFolder_View):

    access = 'is_admin'
    title = MSG(u'Orders')

    # Configuration
    table_actions = [MergeOrderButton, MergeBillButton, RegeneratePDFButton]
    context_menus = []

    table_columns = [
        ('checkbox', None),
        ('name', None),
        ('nb_msg', img_mail),
        ('customer_id', MSG(u'Customer')),
        ('state', MSG(u'State')),
        ('total_price', MSG(u'Total price')),
        ('creation_datetime', MSG(u'Date and Time')),
        ('order_pdf', None),
        ('bill', None),
    ]

    query_schema = merge_dicts(Folder_BrowseContent.query_schema,
                               batch_size=Integer(default=50),
                               sort_by=String(default='creation_datetime'),
                               reverse=Boolean(default=True),
                               reference=Integer)

    batch_msg1 = MSG(u"There's one order.")
    batch_msg2 = MSG(u"There are {n} orders.")

    search_schema = {
        'name':
        String,
        'workflow_state':
        OrderStates_Enumerate(default=['payment_ok'], multiple=True)
    }
    search_widgets = [
        TextWidget('name', title=MSG(u'Référence')),
        OrdersWidget('workflow_state', title=MSG(u'State'))
    ]

    def get_item_value(self, resource, context, item, column):
        item_brain, item_resource = item
        if column == 'name':
            state = item_brain.workflow_state
            href = context.resource.get_pathto(item_resource)
            name = item_resource.get_reference()
            return XMLParser(numero_template %
                             (states_color[state], href, name))
        elif column == 'state':
            state = item_brain.workflow_state
            state_title = states[state].gettext().encode('utf-8')
            href = context.resource.get_pathto(item_resource)
            return XMLParser(numero_template %
                             (states_color[state], href, state_title))
        elif column == 'total_price':
            price = item_resource.get_property(column)
            return format_price(price)
        elif column == 'order_pdf':
            if item_resource.get_resource('order', soft=True) is None:
                return
            img = """
                  <a href="./%s/order/;download">
                    <img src="/ui/icons/16x16/select_none.png"/>
                  </a>
                  """ % item_brain.name
            return XMLParser(img)
        elif column == 'bill':
            if item_resource.get_resource('bill', soft=True) is None:
                return
            img = """
                  <a href="./%s/bill/;download">
                    <img src="/ui/icons/16x16/pdf.png"/>
                  </a>
                  """ % item_brain.name
            return XMLParser(img)
        proxy = super(OrdersView, self)
        return proxy.get_item_value(resource, context, item, column)

    def get_items(self, resource, context, *args):
        abspath = str(resource.get_canonical_path())
        query = [
            PhraseQuery('parent_path', abspath),
            PhraseQuery('format', 'order')
        ]
        return SearchTableFolder_View.get_items(self,
                                                resource,
                                                context,
                                                query=query)

    def action_merge_pdfs(self, resource, context, form, pdf_name):
        context.set_content_type('application/pdf')
        context.set_content_disposition('attachment; filename="Document.pdf"')
        list_pdf = []
        for id in form['ids']:
            pdf = resource.get_resource('%s/%s' % (id, pdf_name), soft=True)
            if pdf is None:
                continue
            path = context.database.fs.get_absolute_path(pdf.handler.key)
            list_pdf.append(path)
        # Join pdf
        pdf = join_pdfs(list_pdf)
        return pdf

    def action_merge_bill(self, resource, context, form):
        return self.action_merge_pdfs(resource, context, form, 'bill')

    def action_merge_orders(self, resource, context, form):
        return self.action_merge_pdfs(resource, context, form, 'order')

    def action_regenerate_pdf(self, resource, context, form):
        for order_id in form['ids']:
            order = resource.get_resource(order_id)
            order.generate_pdf_bill(context)
            order.generate_pdf_order(context)
        return context.come_back(MSG(u'PDF has been regenerated'))
Beispiel #20
0
class Folder_BrowseContent(BrowseForm):

    access = 'is_allowed_to_view'
    title = MSG(u'Browse Content')
    context_menus = []
    query_schema = merge_dicts(BrowseForm.query_schema,
                               sort_by=String(default='mtime'),
                               reverse=Boolean(default=True))
    schema = {'ids': String(multiple=True, mandatory=True)}

    # Search Form
    search_widgets = [
        TextWidget('text', title=MSG(u'Text')),
        SelectWidget('format', title=MSG(u'Type'))
    ]
    search_schema = {'text': Unicode, 'format': SearchTypes_Enumerate}

    # Table
    table_columns = [('checkbox', None), ('icon', None),
                     ('abspath', MSG(u'Path')), ('title', MSG(u'Title')),
                     ('format', MSG(u'Type')),
                     ('mtime', MSG(u'Last Modified')),
                     ('last_author', MSG(u'Last Author'))]
    table_actions = [
        Remove_BrowseButton, RenameButton, CopyButton, CutButton, PasteButton,
        ZipButton
    ]

    def search_content_only(self, resource, context):
        return resource.is_content

    def get_scripts(self, context):
        scripts = []
        if self.search_widgets:
            for widget in self.search_widgets:
                for script in widget.scripts:
                    if script not in scripts:
                        scripts.append(script)

        return scripts

    def get_styles(self, context):
        styles = []
        if self.search_widgets:
            for widget in self.search_widgets:
                for style in widget.styles:
                    if style not in styles:
                        styles.append(style)
        return styles

    depth = None
    base_classes = None

    def get_items_query(self, resource, context):
        # Search in subtree
        query = get_base_path_query(resource.abspath, max_depth=self.depth)

        # Base classes
        base_classes = self.base_classes
        if base_classes is not None:
            base_classes_query = OrQuery(
                *[PhraseQuery('base_classes', x) for x in base_classes])
            query = AndQuery(query, base_classes_query)

        # Exclude non-content
        if self.search_content_only(resource, context) is True:
            query = AndQuery(query, PhraseQuery('is_content', True))

        return query

    def get_search_query(self, resource, context):
        query = AndQuery()
        form = context.query
        for key, datatype in self.search_schema.items():
            value = form[key]
            if value is None or value == '':
                continue
            # Special case: search on text, title and name AS AndQuery
            if key == 'text':
                text_query = []
                value = value.split(' ')
                for v in value:
                    t_query = OrQuery(TextQuery('title', v),
                                      TextQuery('text', v),
                                      PhraseQuery('name', v))
                    text_query.append(t_query)
                if len(text_query) == 1:
                    text_query = text_query[0]
                else:
                    text_query = AndQuery(*text_query)
                query.append(text_query)
            # Special case: type
            elif key == 'format':
                squery = [PhraseQuery('format', x) for x in value.split(',')]
                squery = squery[0] if len(squery) == 1 else OrQuery(*squery)
                query.append(squery)
            # Multiple
            elif datatype.multiple is True:
                query.append(OrQuery(*[PhraseQuery(key, x) for x in value]))
            # Singleton
            else:
                if value is False:
                    # FIXME No value means False in xapian
                    query.append(NotQuery(PhraseQuery(key, True)))
                else:
                    query.append(PhraseQuery(key, value))
        return query

    def get_items(self, resource, context):
        # Base query
        query = self.get_items_query(resource, context)

        # Search form
        search_query = self.get_search_query(resource, context)
        if search_query:
            query = AndQuery(query, search_query)

        # Search
        return context.search(query)

    def _get_key_sorted_by_unicode(self, field):
        def key(item):
            return getattr(item, field).lower().translate(transmap)

        return key

    def _get_key_sorted_by_user(self, field):
        get_user_title = self.context.root.get_user_title

        def key(item, cache={}):
            user = getattr(item, field)
            if user in cache:
                return cache[user]
            if user:
                title = get_user_title(user)
                value = title.lower().translate(transmap)
            else:
                value = None
            cache[user] = value
            return value

        return key

    def get_key_sorted_by_title(self):
        return self._get_key_sorted_by_unicode('title')

    def get_key_sorted_by_format(self):
        database = self.context.database

        def key(item, cache={}):
            format = item.format
            if format in cache:
                return cache[format]
            cls = database.get_resource_class(format)
            value = cls.class_title.gettext().lower().translate(transmap)
            cache[format] = value
            return value

        return key

    def get_key_sorted_by_last_author(self):
        return self._get_key_sorted_by_user('last_author')

    def sort_and_batch(self, resource, context, results):
        start = context.query['batch_start']
        size = context.query['batch_size']
        sort_by = context.query['sort_by']
        reverse = context.query['reverse']

        if sort_by is None:
            get_key = None
        else:
            get_key = getattr(self, 'get_key_sorted_by_' + sort_by, None)

        # Case 1: Custom but slower sort algorithm
        if get_key:
            items = results.get_documents()
            items.sort(key=get_key(), reverse=reverse)
            if size:
                items = items[start:start + size]
            elif start:
                items = items[start:]
            database = resource.database
            return [database.get_resource(x.abspath) for x in items]

        # Case 2: Faster Xapian sort algorithm
        items = results.get_resources(sort_by, reverse, start, size)
        return list(items)

    def get_item_value(self, resource, context, item, column):
        if column == 'checkbox':
            # checkbox
            parent = item.parent
            if parent is None:
                return None
            if item.name in parent.__fixed_handlers__:
                return None
            resource_id = str(item.abspath)
            return resource_id, False
        elif column == 'icon':
            # icon
            path_to_icon = item.get_resource_icon(16)
            if not path_to_icon:
                return None
            if path_to_icon.startswith(';'):
                path_to_icon = Path('%s/' % item.name).resolve(path_to_icon)
            return path_to_icon
        elif column == 'abspath':
            # Name
            resource_id = str(item.abspath)
            view = item.get_view(None)
            if view is None:
                return resource_id
            return resource_id, context.get_link(item)
        elif column == 'format':
            # Type
            return item.class_title.gettext()
        elif column == 'mtime':
            # Last Modified
            mtime = item.get_value('mtime')
            if mtime:
                return context.format_datetime(mtime)
            return None
        elif column == 'last_author':
            # Last author
            author = item.get_value('last_author')
            return context.root.get_user_title(author) if author else None
        elif column == 'row_css':
            return None

        # Default
        return item.get_value_title(column)

    #######################################################################
    # Form Actions
    #######################################################################
    def action_remove(self, resource, context, form):
        ids = form['ids']

        # Remove resources
        removed = []
        referenced = []
        not_removed = []
        user = context.user
        root = context.root

        # We sort and reverse ids in order to
        # remove the childs then their parents
        ids.sort()
        ids.reverse()
        for name in ids:
            child = resource.get_resource(name, soft=True)
            if child and root.is_allowed_to_remove(user, child):
                # Remove resource
                try:
                    resource.del_resource(name)
                except ConsistencyError:
                    referenced.append(name)
                    continue
                removed.append(name)
            else:
                not_removed.append(name)

        message = []
        if removed:
            resources = ', '.join(removed)
            msg = messages.MSG_RESOURCES_REMOVED(resources=resources)
            message.append(msg)
        if referenced:
            items = []
            for name in referenced:
                item = resource.get_resource(name)
                view = item.get_view('backlinks')
                if context.is_access_allowed(item, view):
                    items.append({
                        'title': item.get_title(),
                        'href': '%s/;backlinks' % item.abspath
                    })
            msg = messages.MSG_RESOURCES_REFERENCED_HTML(resources=items)
            message.append(msg)
        if not_removed:
            resources = ', '.join(not_removed)
            msg = messages.MSG_RESOURCES_NOT_REMOVED(resources=resources)
            message.append(msg)
        if not removed and not referenced and not not_removed:
            message.append(messages.MSG_NONE_REMOVED)
        context.message = message

    def action_rename(self, resource, context, form):
        ids = form['ids']
        # Filter names which the authenticated user is not allowed to move
        root = context.root
        user = context.user
        # Check if file to rename exists & user is allowed to move
        paths = []
        for x in ids:
            r_to_rename = resource.get_resource(x, soft=True)
            if r_to_rename and root.is_allowed_to_move(user, r_to_rename):
                paths.append(x)

        # Check input data
        if not paths:
            context.message = messages.MSG_NONE_SELECTED
            return

        # FIXME Hack to get rename working. The current user interface forces
        # the rename_form to be called as a form action, hence with the POST
        # method, but it should be a GET method. Maybe it will be solved after
        # the needed folder browse overhaul.
        ids_list = '&'.join(['ids=%s' % x for x in paths])
        uri = '%s/;rename?%s' % (context.get_link(resource), ids_list)
        return get_reference(uri)

    def action_copy(self, resource, context, form):
        ids = form['ids']
        # Filter names which the authenticated user is not allowed to copy
        root = context.root
        user = context.user
        names = [
            x for x in ids
            if root.is_allowed_to_copy(user, resource.get_resource(x))
        ]

        # Check input data
        if not names:
            context.message = messages.MSG_NONE_SELECTED
            return

        abspath = resource.abspath
        cp = (False, [str(abspath.resolve2(x)) for x in names])
        cp = CopyCookie.encode(cp)
        context.set_cookie('ikaaro_cp', cp, path='/')
        # Ok
        context.message = messages.MSG_COPIED

    def action_cut(self, resource, context, form):
        ids = form['ids']
        # Filter names which the authenticated user is not allowed to move
        root = context.root
        user = context.user
        # Check if file to cut exists & user is allowed to move
        names = []
        for x in ids:
            r_to_move = resource.get_resource(x, soft=True)
            if r_to_move and root.is_allowed_to_move(user, r_to_move):
                names.append(x)
        # Check input data
        if not names:
            context.message = messages.MSG_NONE_SELECTED
            return

        abspath = resource.abspath
        cp = (True, [str(abspath.resolve2(x)) for x in names])
        cp = CopyCookie.encode(cp)
        context.set_cookie('ikaaro_cp', cp, path='/')

        context.message = messages.MSG_CUT

    action_paste_schema = {}

    def action_paste(self, resource, context, form):
        # Check there is something to paste
        cut, paths = context.get_cookie('ikaaro_cp', datatype=CopyCookie)
        if len(paths) == 0:
            context.message = messages.MSG_NO_PASTE
            return

        # Paste
        target = resource
        pasted = []
        not_allowed = []
        for path in paths:
            # Check the source resource still exists
            source = target.get_resource(path, soft=True)
            if source is None:
                continue

            # If cut&paste in the same place, do nothing
            if cut is True:
                if target == source.parent:
                    pasted.append(source.name)
                    continue

            name = generate_name(source.name, target.get_names(), '_copy_')
            if cut is True:
                # Cut&Paste
                try:
                    target.move_resource(path, name)
                except ConsistencyError:
                    not_allowed.append(source.name)
                    continue
                else:
                    pasted.append(name)
            else:
                # Copy&Paste
                try:
                    target.copy_resource(path, name)
                except ConsistencyError:
                    not_allowed.append(source.name)
                    continue
                else:
                    pasted.append(name)

        # Cut, clean cookie
        if cut is True:
            context.del_cookie('ikaaro_cp')

        message = []
        if pasted:
            resources = ', '.join(pasted)
            message.append(messages.MSG_RESOURCES_PASTED(resources=resources))
        if not_allowed:
            resources = ', '.join(not_allowed)
            msg = messages.MSG_RESOURCES_NOT_PASTED(resources=resources)
            message.append(msg)

        context.message = message

    def action_zip(self, resource, context, form):
        names = sorted(form['ids'], reverse=True)
        data = resource.export_zip(names)
        # Content-Type & Content-Disposition
        context.set_content_type('application/zip')
        filename = 'archive.zip'
        context.set_content_disposition('inline', filename)
        # Ok
        return data
Beispiel #21
0
 def get_query_schema(self):
     return {
         'sort_by': String(default='title'),
         'reverse': Boolean(default=False),
         'reference': Integer
     }
Beispiel #22
0
    rest_query = Rest_Query
    rest_create = Rest_Create
    rest_read = Rest_Read
    rest_update = Rest_Update
    rest_delete = Rest_Delete
    rest_schema = Rest_Schema


###########################################################################
# Register read-only fields
###########################################################################

# Path related fields
register_field('abspath', String(indexed=True, stored=True))
register_field('abspath_depth', Integer(indexed=True, stored=True))
register_field('parent_paths', String(multiple=True, indexed=True))
register_field('name', String(stored=True, indexed=True))
# Class related fields
register_field('format', String(indexed=True, stored=True))
register_field('base_classes', String(multiple=True, indexed=True))
# Referential integrity
register_field('links', String(multiple=True, indexed=True))
register_field('onchange_reindex', String(multiple=True, indexed=True))
# Full text search
register_field('text', Unicode(indexed=True))
# Various classifications
register_field('is_content', Boolean(indexed=True))
# Time events
register_field('next_time_event', DateTime(stored=True))
register_field('next_time_event_payload', String(stored=True))
Beispiel #23
0
class SystemPay(PaymentWay):

    class_id = 'systempay'
    class_title = MSG(u'Paybox payment Module')
    class_description = MSG(u'Secured payment paybox')

    # Views
    class_views = ['configure', 'payments']

    logo = '/ui/backoffice/payments/paybox/images/logo.png'
    #    payment_table = PayboxTable

    # Views
    configure = PaymentWay_Configure()
    #    confirm_payment = Paybox_ConfirmPayment()
    #    end = Paybox_End()
    #
    #    # Admin order views
    #    order_view = Paybox_RecordView
    #    order_edit_view = Paybox_Record_Edit

    # Schema
    base_schema = {
        'PBX_SITE': StringFixSize(size=7),
        'PBX_RANG': StringFixSize(size=2),
        'PBX_IDENTIFIANT': String,
        'PBX_DIFF': StringFixSize(size=2),
        'real_mode': Boolean(default=False)
    }

    @classmethod
    def get_metadata_schema(cls):
        schema = PaymentWay.get_metadata_schema()
        # Paybox account configuration
        schema.update(cls.base_schema)
        return schema

    test_configuration = {
        'PBX_SITE': 1999888,
        'PBX_RANG': 99,
        'PBX_IDENTIFIANT': 2
    }

    uri = 'https://systempay.cyberpluspaiement.com/vads-payment/'

    def get_signature(self, kw):
        # Build signature
        signature = ''
        for key in [
                'version', 'site_id', 'ctx_mode', 'trans_id', 'trans_date',
                'validation_mode', 'capture_delay'
        ]:
            signature += '%s+' % kw[key]
        # Add key
        signature += '1122334455667788'
        # SHA1
        sign = sha1(signature)
        print 'SIGNATURE ', signature
        print 'SIGNATURE ', sign.hexdigest()
        return sign.hexdigest()

    def _show_payment_form(self, context, payment):
        kw = {
            'amout': '25',
            'currency': '978',  # Euros,
            'capture_delay': '3',
            'ctx_mode': 'TEST',
            'payment_cards': 'AMEX;CB;MASTERCARD;VISA',
            'payment_config': 'SINGLE',
            'site_id': '12345678',
            'trans_date': '20100303105332',
            'url_return': 'http://shop:8080',
            'trans_id': '1',
            'validation_mode': '0',  #Validation automatique
            'version': 'V1'
        }
        # Get signature
        kw['signature'] = self.get_signature(kw)
        # Return URI
        uri = get_reference(self.uri)
        uri.query = kw
        print '======>', uri
        return context.uri.resolve(uri)
Beispiel #24
0
 def get_query_schema(self):
     return merge_dicts(SearchTable_View.get_query_schema(self),
                        batch_size=Integer(default=500),
                        reverse=Boolean(default=False),
                        sort_by=String(default='title'))
Beispiel #25
0
# Import from standard library
from decimal import Decimal as decimal

# Import from itools
from itools.core import merge_dicts
from itools.datatypes import Decimal, Boolean
from itools.gettext import MSG
# Import from ikaaro
from ikaaro.forms import BooleanRadio, TextWidget

# Import from shop
from shop.payments.payment_way_views import PaymentWay_Configure

deposit_schema = {
    'percent': Decimal(default=decimal('100.0'), mandatory=True),
    'pay_tax': Boolean(mandatory=True)
}

deposit_widgets = [
    TextWidget('percent', title=MSG(u'Deposit amount (in %)')),
    BooleanRadio('pay_tax', title=MSG(u'Pay deposite with tax ?'))
]


class Deposit_Configure(PaymentWay_Configure):

    title = MSG(u'Configure deposite module')

    schema = merge_dicts(PaymentWay_Configure.schema, deposit_schema)

    widgets = PaymentWay_Configure.widgets + deposit_widgets
Beispiel #26
0
 def test_Boolean(self):
     for x in [True, False]:
         data = Boolean.encode(x)
         self.assertEqual(x, Boolean.decode(data))
Beispiel #27
0
class ConfigAccess_Browse(Folder_BrowseContent):

    query_schema = merge_dicts(Folder_BrowseContent.query_schema,
                               sort_by=String(default='abspath'),
                               reverse=Boolean(default=False))

    # Search form
    _columns = ['group', 'permission', 'search_path', 'search_format']

    @proto_property
    def _search_fields(self):
        cls = AccessRule
        for name in self._columns:
            yield name, cls.get_field(name)

    @proto_property
    def search_widgets(self):
        widgets = []
        for name, field in self._search_fields:
            if is_prototype(field, Select_Field):
                widget = field.widget
                widgets.append(
                    widget(name, has_empty_option=True, title=field.title))
        return widgets

    @proto_property
    def search_schema(self):
        schema = {}
        for name, field in self._search_fields:
            if is_prototype(field, Select_Field):
                schema[name] = field.datatype(default=None)
        return schema

    @proto_property
    def table_columns(self):
        columns = [('checkbox', None), ('abspath', MSG(u'Num.'))]
        for name, field in self._search_fields:
            columns.append((name, field.title))

        return columns

    table_actions = [Remove_BrowseButton]

    def get_key_sorted_by_abspath(self):
        def key(item):
            return int(item.name)

        return key

    def get_key_sorted_by_group(self):
        def key(item, cache={}):
            title = Groups_Datatype.get_value(item.group)
            if isinstance(title, MSG):
                title = title.gettext()
            return title.lower()

        return key

    def get_item_value(self, resource, context, item, column):
        if column == 'search_path':
            path = item.get_value('search_path')
            if not path or not resource.get_resource(path, soft=True):
                return None

            depth = item.get_value('search_path_depth')
            if depth == '0':
                title = path
            else:
                title = '%s (%s)' % (path, depth)

            return title, path

        proxy = super(ConfigAccess_Browse, self)
        value = proxy.get_item_value(resource, context, item, column)

        if column == 'group':
            group = item.get_value('group')
            if group[0] == '/':
                return value, group

        return value
Beispiel #28
0
class ShopModule_AReport_NewInstance(NewInstance):

    title = MSG(u'Do a report')
    access = 'is_authenticated'

    schema = freeze({
        'name': String,
        'title': Unicode,
        'description': Unicode(mandatory=True),
        'cgu': Boolean(mandatory=True)
    })

    def get_widgets(self, resource, context):
        cgu_description = MSG(u"I'm agree with the conditions general of use")
        review_module = get_module(resource, ShopModule_Review.class_id)
        cgu = review_module.get_resource('cgu')
        cgu_link = context.get_link(cgu)

        return [
            MultilineWidget('description', title=MSG(u'Your report')),
            BooleanCheckBox_CGU('cgu',
                                title=MSG(u'Conditions of use'),
                                link=cgu_link,
                                description=cgu_description)
        ]

    def get_new_resource_name(self, form):
        context = get_context()
        root = context.root
        abspath = context.resource.get_canonical_path()
        query = AndQuery(PhraseQuery('parent_path', str(abspath)),
                         PhraseQuery('format', 'shop_module_a_report'))
        search = root.search(query)
        id_report = len(search.get_documents()) + 1
        return str('report_%s' % id_report)

    def action(self, resource, context, form):
        name = self.get_new_resource_name(form)
        cls = ShopModule_AReport
        child = cls.make_resource(cls, resource, name)
        # The metadata
        metadata = child.metadata
        language = resource.get_content_language(context)

        # Anonymous ? Accepted XXX
        if context.user:
            metadata.set_property('author', context.user.name)
        # Workflow
        metadata.set_property('ctime', datetime.now())
        metadata.set_property('description', form['description'], language)
        metadata.set_property('remote_ip', context.get_remote_ip())

        # Notification
        shop = get_shop(resource)
        subject = MSG(u'A report on a review has been made').gettext()
        body = MSG(u'Go on your backoffice to see it.').gettext()
        for to_addr in shop.get_property('order_notification_mails'):
            context.root.send_email(to_addr, subject, text=body)

        goto = context.get_link(resource.parent)
        message = MSG(u'Your report has been added')
        return context.come_back(message, goto=goto)
Beispiel #29
0
class Shop_Configure(DBResource_Edit):

    access = 'is_admin'
    title = MSG(u'Configure shop')

    schema = {
        'shop_uri': String(mandatory=True),
        'shop_backoffice_uri': String(mandatory=True),
        'order_notification_mails': MultiLinesTokens(mandatory=True),
        'shop_default_zone': CountriesZonesEnumerate(mandatory=True),
        'shop_sort_by': SortBy_Enumerate(mandatory=True),
        'shop_sort_reverse': Boolean(mandatory=True),
        'devise': Devises(mandatory=True),
        'hide_not_buyable_products': Boolean(mandatory=True),
        'categories_batch_size': Integer(mandatory=True),
        'show_sub_categories': Boolean,
        'product_cover_is_mandatory': Boolean,
        'log_authentification': Boolean,
        'registration_need_email_validation': Boolean,
        'bill_logo': ImagePathDataType,
        'pdf_signature': Unicode,
        'barcode_format': BarcodesFormat
    }

    widgets = [
        TextWidget('shop_uri', title=MSG(u'Website uri')),
        TextWidget('shop_backoffice_uri',
                   title=MSG(u'Website backoffice uri')),
        MultilineWidget(
            'order_notification_mails',
            title=MSG(u'New order notification emails (1 per line)'),
            rows=8,
            cols=50),
        MultilineWidget('pdf_signature',
                        title=MSG(u'PDF signature'),
                        rows=8,
                        cols=50),
        SelectWidget('shop_default_zone', title=MSG(u'Shop default zone')),
        SelectWidget('devise', title=MSG(u'Devises'), has_empty_option=False),
        TextWidget('categories_batch_size',
                   title=MSG(u'Batch size for categories ?')),
        SelectWidget('shop_sort_by',
                     title=MSG(u'Sort products by ...'),
                     has_empty_option=False),
        BooleanRadio('shop_sort_reverse', title=MSG(u'Reverse sort ?')),
        BooleanRadio('show_sub_categories',
                     title=MSG(u'Show sub categories ?')),
        BooleanRadio('product_cover_is_mandatory',
                     title=MSG(u'Product cover is mandatory ?')),
        BooleanRadio('hide_not_buyable_products',
                     title=MSG(u'Hide not buyable products ?')),
        BooleanRadio('log_authentification',
                     title=MSG(u'Log users authentification ?')),
        BooleanRadio('registration_need_email_validation',
                     title=MSG(u'Ask for mail validation on registration ?')),
        ImageSelectorWidget('bill_logo', title=MSG(u'Bill logo')),
        SelectWidget('barcode_format',
                     title=MSG(u'Barcode format'),
                     has_empty_option=False),
    ]

    submit_value = MSG(u'Edit configuration')

    def action(self, resource, context, form):
        for key in self.schema.keys():
            if key == 'order_notification_mails':
                continue
            resource.set_property(key, form[key])
        values = [x.strip() for x in form['order_notification_mails']]
        resource.set_property('order_notification_mails', values)
        context.message = MSG_CHANGES_SAVED
        return
Beispiel #30
0
    class_id = 'orders'
    class_title = MSG(u'Orders')
    class_views = ['view']  # 'export']
    class_version = '20091127'

    # Views
    view = OrdersView()

    def get_document_types(self):
        return [Order]

    #############################
    # Export
    #############################
    export = Export(
        export_resource=Order,
        access='is_allowed_to_edit',
        file_columns=['name', 'state', 'total_price', 'creation_datetime'])


# Register catalog fields
register_field('customer_id', String(is_indexed=True))
register_field('is_payed', Boolean(is_stored=True))
register_field('creation_datetime', DateTime(is_stored=True, is_indexed=True))

# Register resources
register_resource_class(Order)
register_resource_class(Orders)
register_resource_class(OrdersProducts)
Beispiel #31
0
 def get_query_schema(self):
     return merge_dicts(SearchTableFolder_View.get_query_schema(self),
                        reverse=Boolean(default=True),
                        sort_by=String(default='ctime'))
Beispiel #32
0
 def get_query_schema(self):
     return merge_dicts(Table_View.get_query_schema(self),
                        reverse=Boolean(default=True),
                        sort_by=String(default='ts'))