class EmbeddedListFieldNonFullTestResource(resources.MongoEngineResource):
    embeddedlist = fields.EmbeddedListField(of='test_project.test_app.api.resources.EmbeddedPersonResource', attribute='embeddedlist', full=False, null=True)

    class Meta:
        queryset = documents.EmbeddedListFieldTest.objects.all()
        allowed_methods = ('get', 'post', 'put', 'patch', 'delete')
        authorization = tastypie_authorization.Authorization()
Beispiel #2
0
class PurchaseOrderResource(InvoiceBaseResource, InvoiceMakableResourceMixin):
    state = base_fields.CharField(
        attribute='state',
        readonly=True,
        help_text=HELP_TEXT['purchase_order']['state']
    )

    current_revision = fields.EmbeddedDocumentField(
        embedded='invoicing.api.resources.PurchaseOrderRevisionResource',
        attribute='current_revision',
        help_text=HELP_TEXT['purchase_order']['current_revision']
    )
    revisions = fields.EmbeddedListField(
        of='invoicing.api.resources.PurchaseOrderRevisionResource',
        attribute='revisions',
        readonly=True,
        null=True,
        blank=True,
        help_text=HELP_TEXT['purchase_order']['revisions']
    )

    class Meta(InvoiceBaseResource.Meta):
        resource_name = 'purchase_order'
        queryset = PurchaseOrder.objects.all()
        detail_specific_methods = ('make_down_payment_invoice', 'make_invoice', 'mark_as_awaiting_approval')

    def prepend_urls(self):
        """Add urls for resources actions."""
        urls = super(PurchaseOrderResource, self).prepend_urls()
        urls.extend((
            url(r'^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/make_invoice%s$' % (self._meta.resource_name, trailing_slash()), self.wrap_view('make_invoice'), name='api_quotation_make_invoice'),
            url(r'^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/make_down_payment_invoice%s$' % (self._meta.resource_name, trailing_slash()), self.wrap_view('make_down_payment_invoice'), name='api_quotation_make_down_payment_invoice'),
        ))
        return urls
Beispiel #3
0
class SnapshotCurrencyResource(VosaeResource):
    symbol = base_fields.CharField(attribute='symbol',
                                   help_text=HELP_TEXT['currency']['symbol'])

    rates = fields.EmbeddedListField(
        of='invoicing.api.resources.ExchangeRateResource',
        attribute='rates',
        full=True,
        null=True,
        help_text=HELP_TEXT['currency']['rates'])

    class Meta(VosaeResource.Meta):
        object_class = SnapshotCurrency
        excludes = ('id', )

    def hydrate(self, bundle):
        """
        If an `id` is present in serialized data (data comes from a Currency and not a SnapshotCurrency),
        the currency is fetch and exchange rates are updated based on their current rates.
        """
        bundle = super(SnapshotCurrencyResource, self).hydrate(bundle)
        if 'id' in bundle.data:
            currency = Currency.objects.get(id=bundle.data.pop('id'))
            snapshot = currency.get_snapshot()
            bundle.data['symbol'] = snapshot.symbol
            bundle.data['rates'] = []
            for rate in snapshot.rates:
                bundle.data['rates'].append({
                    'currency_to': rate.currency_to,
                    'datetime': rate.datetime,
                    'rate': rate.rate
                })
        return bundle
class BoardResource(resources.MongoEngineResource):
    posts = fields.EmbeddedListField(of='test_project.test_app.api.resources.EmbeddedPostResource', attribute='posts', full=True, null=True)

    class Meta:
        queryset = documents.Board.objects.all()
        allowed_methods = ('get', 'post', 'put', 'patch', 'delete')
        authorization = tastypie_authorization.Authorization()
class PipeResource(resources.MongoEngineResource):
    exporters = fields.EmbeddedListField(of='test_project.test_app.api.resources.EmbeddedExporterListResource', attribute='exporters', full=True, null=True)

    class Meta:
        queryset = documents.Pipe.objects.all()
        resource_name = 'pipes'
        allowed_methods = ('get', 'post', 'put', 'delete')
        authorization = tastypie_authorization.Authorization()
Beispiel #6
0
class CalendarAclResource(VosaeResource):
    rules = fields.EmbeddedListField(
        of='organizer.api.resources.CalendarAclRuleResource',
        attribute='rules',
        full=True,
        help_text=HELP_TEXT['calendar_acl']['rules'])

    class Meta(VosaeResource.Meta):
        object_class = CalendarAcl
        excludes = ('read_list', 'write_list', 'negate_list')
class EmbeddedPostResource(resources.MongoEngineResource):
    comments = fields.EmbeddedListField(
        of='test_project.test_app.api.resources.EmbeddedCommentResource',
        attribute='comments',
        full=True,
        null=True)

    class Meta(object):
        object_class = documents.EmbeddedPost
        ordering = ('title', 'comments')
Beispiel #8
0
class FunctionResource(resources.MongoEngineResource):
    args = fields.EmbeddedListField(of='netlambda.resources.ArgResource',
                                    attribute='args',
                                    full=True,
                                    null=True)

    class Meta:
        object_class = models.Function
        allowed_methods = ('get')
        resource_name = 'func'
Beispiel #9
0
class PostResource(resources.MongoEngineResource):
    comments = fields.EmbeddedListField(
        of='HelloDjandroid.droid.resources.CommentResource',
        attribute='comments',
        full=True,
        null=True)

    class Meta:
        object_class = documents.Post
        authentication = FacebookOAUTH2Authentication()
        ordering = ('datetime', )
Beispiel #10
0
class PostResource(AuthoredResource):
    """
    Query set is ordered by updated time for following reasons:

        * those who open web page will get posts in updated time order,
        * others with already opened page will get updated posts again as they will request them based on ID of current newest post.

    This is useful if we would like to show on the client side that post has been updated (but we do not necessary have to reorder them).
    """

    updated_time = tastypie_fields.DateTimeField(attribute='updated_time',
                                                 null=False,
                                                 readonly=True)
    comments = fields.EmbeddedListField(
        of='piplmesh.api.resources.CommentResource',
        attribute='comments',
        default=lambda: [],
        null=True,
        full=False)
    attachments = fields.EmbeddedListField(
        of='piplmesh.api.resources.AttachmentResource',
        attribute='attachments',
        default=lambda: [],
        null=True,
        full=True)

    def obj_create(self, bundle, request=None, **kwargs):
        bundle = super(PostResource, self).obj_create(bundle,
                                                      request=request,
                                                      **kwargs)
        signals.post_created.send(sender=self,
                                  post=bundle.obj,
                                  request=request or bundle.request,
                                  bundle=bundle)
        return bundle

    class Meta:
        queryset = api_models.Post.objects.all().order_by('-updated_time')
        allowed_methods = ('get', 'post', 'put', 'patch', 'delete')
        authorization = authorization.PostAuthorization()
        paginator_class = paginator.Paginator
Beispiel #11
0
class ReminderSettingsResource(VosaeResource):
    use_default = base_fields.BooleanField(
        attribute='use_default',
        help_text=HELP_TEXT['reminder']['use_default'])

    overrides = fields.EmbeddedListField(
        of='organizer.api.resources.ReminderEntryResource',
        attribute='overrides',
        null=True,
        blank=True,
        full=True,
        help_text=HELP_TEXT['reminder']['overrides'])

    class Meta(VosaeResource.Meta):
        object_class = ReminderSettings
Beispiel #12
0
class CurrencyResource(VosaeResource):
    symbol = base_fields.CharField(attribute='symbol',
                                   help_text=HELP_TEXT['currency']['symbol'])

    rates = fields.EmbeddedListField(
        of='invoicing.api.resources.ExchangeRateResource',
        attribute='rates',
        readonly=True,
        full=True,
        help_text=HELP_TEXT['currency']['rates'])

    class Meta(VosaeResource.Meta):
        queryset = Currency.objects.all()
        authorization = Authorization()
        list_allowed_methods = ('get', )
        detail_allowed_methods = ('get', )
        filtering = {"symbol": ('exact', )}
Beispiel #13
0
class CreditNoteResource(InvoiceBaseResource):
    state = base_fields.CharField(
        attribute='state',
        readonly=True,
        help_text=HELP_TEXT['creditnote']['state']
    )

    current_revision = fields.EmbeddedDocumentField(
        embedded='invoicing.api.resources.CreditNoteRevisionResource',
        attribute='current_revision',
        help_text=HELP_TEXT['creditnote']['current_revision']
    )
    revisions = fields.EmbeddedListField(
        of='invoicing.api.resources.CreditNoteRevisionResource',
        attribute='revisions',
        readonly=True,
        null=True,
        blank=True,
        help_text=HELP_TEXT['creditnote']['revisions']
    )
    related_to = fields.ReferenceField(
        to='invoicing.api.resources.InvoiceResource',
        attribute='related_to',
        readonly=True,
        null=True,
        help_text=HELP_TEXT['creditnote']['related_to']
    )

    class Meta(InvoiceBaseResource.Meta):
        resource_name = 'credit_note'
        queryset = CreditNote.objects.all()
        list_allowed_methods = ('get',)
        detail_allowed_methods = ('get',)
        detail_specific_methods = ('cancel',)

    def dehydrate_related_to(self, bundle):
        from invoicing.api.resources import DownPaymentInvoiceResource, InvoiceResource
        try:
            if bundle.obj.related_to.is_down_payment_invoice():
                resource = DownPaymentInvoiceResource()
            elif bundle.obj.related_to.is_invoice():
                resource = InvoiceResource()
            resource_bundle = resource.build_bundle(obj=bundle.obj.related_to, request=bundle.request)
            return resource.get_resource_uri(resource_bundle)
        except:
            return
Beispiel #14
0
class QuotationResource(InvoiceBaseResource, InvoiceMakableResourceMixin):
    state = base_fields.CharField(attribute='state',
                                  readonly=True,
                                  help_text=HELP_TEXT['quotation']['state'])

    current_revision = fields.EmbeddedDocumentField(
        embedded='invoicing.api.resources.QuotationRevisionResource',
        attribute='current_revision',
        help_text=HELP_TEXT['quotation']['current_revision'])
    revisions = fields.EmbeddedListField(
        of='invoicing.api.resources.QuotationRevisionResource',
        attribute='revisions',
        readonly=True,
        null=True,
        blank=True,
        help_text=HELP_TEXT['quotation']['revisions'])

    class Meta(InvoiceBaseResource.Meta):
        queryset = Quotation.objects.all()
        detail_specific_methods = ('make_purchase_order',
                                   'make_down_payment_invoice', 'make_invoice',
                                   'mark_as_awaiting_approval')

    def prepend_urls(self):
        """Add urls for resources actions."""
        urls = super(QuotationResource, self).prepend_urls()
        urls.extend((
            url(r'^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/make_purchase_order%s$'
                % (self._meta.resource_name, trailing_slash()),
                self.wrap_view('make_purchase_order'),
                name='api_quotation_make_purchase_order'),
            url(r'^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/make_down_payment_invoice%s$'
                % (self._meta.resource_name, trailing_slash()),
                self.wrap_view('make_down_payment_invoice'),
                name='api_quotation_make_down_payment_invoice'),
            url(r'^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/make_invoice%s$' %
                (self._meta.resource_name, trailing_slash()),
                self.wrap_view('make_invoice'),
                name='api_quotation_make_invoice'),
        ))
        return urls

    def make_purchase_order(self, request, **kwargs):
        """Create a purchase order from a quotation"""
        from invoicing.api.resources.purchase_order import PurchaseOrderResource
        self.method_check(request, allowed=['put'])
        self.is_authenticated(request)
        self.throttle_check(request)

        try:
            bundle = self.build_bundle(request=request)
            obj = self.cached_obj_get(bundle=bundle,
                                      **self.remove_api_resource_names(kwargs))
        except ObjectDoesNotExist:
            return http.HttpNotFound()

        purchase_order = obj.make_purchase_order(request.vosae_user)
        invoicing_signals.post_make_purchase_order.send(
            obj.__class__,
            issuer=request.vosae_user,
            document=obj,
            new_document=purchase_order)
        purchase_order_resource = PurchaseOrderResource()
        purchase_order_resource_bundle = purchase_order_resource.build_bundle(
            obj=purchase_order, request=request)

        self.log_throttled_access(request)

        to_be_serialized = {
            'purchase_order_uri':
            purchase_order_resource.get_resource_uri(
                purchase_order_resource_bundle)
        }
        to_be_serialized = self.alter_list_data_to_serialize(
            request, to_be_serialized)
        return self.create_response(request, to_be_serialized)
Beispiel #15
0
class IdeaResource(BaseCorsResource, resources.MongoEngineResource):

    protective_marking = mongo_fields.EmbeddedDocumentField(
        embedded='ideasapp.api.ProtectiveMarkingResource',
        attribute='protective_marking',
        help_text=
        'protective marking of this idea, comprising classification, descriptor, codewords and national caveats.',
        null=True)
    comments = mongo_fields.EmbeddedListField(
        of='ideasapp.api.CommentResource',
        attribute='comments',
        full=True,
        null=True)
    likes = mongo_fields.EmbeddedListField(
        of='ideasapp.api.LikeResource',
        attribute='likes',
        help_text='The user likes recorded for this idea',
        full=True,
        null=True)
    dislikes = mongo_fields.EmbeddedListField(
        of='ideasapp.api.DislikeResource',
        attribute='dislikes',
        help_text='The user dislikes recorded for this idea',
        full=True,
        null=True)

    class Meta:
        queryset = documents.Idea.objects.all()
        resource_name = 'idea'
        # What is permitted at the list level and at the single instance level
        list_allowed_methods = ['get', 'post', 'delete', 'put']
        detailed_allowed_methods = ['get', 'post', 'put', 'delete', 'patch']

        # Setup to default print pretty - mainly for debuggin
        serializer = CustomSerializer()

        authentication = CustomApiKeyAuthentication()
        authorization = StatusAuthorization()

        max_limit = None

        filtering = {
            'created': ['gt', 'gte', 'lt', 'lte'],
            'modified': ['gt', 'gte', 'lt', 'lte'],
            'like_count': ['gt', 'gte', 'lt', 'lte'],
            'dislike_count': ['gt', 'gte', 'lt', 'lte'],
            'comment_count': ['gt', 'gte', 'lt', 'lte'],
            'vote_score': ['gt', 'gte', 'lt', 'lte'],
            'tag_count': ['gt', 'gte', 'lt', 'lte'],
            'verified': ['exact'],
            'verified_by': ['exact'],
            'tags': ['exact', 'in', 'contains'],
            'status': ['exact', 'in'],
            'user': ['exact'],
            'public': ['exact']
        }

        ordering = [
            'title', 'created', 'modified', 'like_count', 'dislike_count',
            'comment_count', 'verified', 'status', 'vote_score'
        ]

    def serialize(self, request, data, format, options=None):
        """
        Override of resource.serialize so that custom options
        can be built for the rss serializer
        """

        # Is it an rss feed
        if 'application/rss+xml' in format:

            options = {}

            # Has the feed been filtered?
            params = request.GET.keys()
            params.pop(params.index('format'))
            if params and len(params) > 0:
                filtered = ' (filtered)'
            else:
                filtered = ''

            # Build a title based on the end point
            path = request.path.strip('/').split('/')
            # If it's not a detail view
            if len(path[-1]) != 24:

                # If there are tags, then make them available for the title
                tags = request.GET.get('tags', None)
                if not tags:
                    tags = request.GET.get('tags__in', None)
                if tags:
                    filtered = ' (Tags:%s)' % (tags)

                # Build the title
                api_end_point = path[-1].lower()
                options['title'] = settings.END_POINT_DESCRIPTIONS[
                    api_end_point] + filtered

                current_site = get_current_site(request)
                options['link'] = current_site.domain + settings.FRONT_END_URL
                options['description'] = settings.END_POINT_DESCRIPTIONS[
                    api_end_point]

        return super(IdeaResource, self).serialize(request, data, format,
                                                   options)

# ------------------------------------------------------------------------------------------------------------

    def obj_create(self, bundle, **kwargs):
        """ Modifies the content before submission """

        # Add in the user
        bundle.data['user'] = bundle.request.user.username
        # These ensure that counts are present if ideas are created with tags/likes/dislikes and comments
        bundle = count_builder(bundle, 'comments', 'comment_count')
        bundle = count_builder(bundle, 'likes', 'like_count')
        bundle = count_builder(bundle, 'dislikes', 'dislike_count')
        bundle = count_builder(bundle, 'tags', 'tag_count')

        # Sanitize tags before they get submitted
        try:
            bundle.data['tags'] = cleanup_tags(bundle.data['tags'])
        except:
            pass

        # Finally build the score
        bundle.data['vote_score'] = vote_score(bundle.data['like_count'],
                                               bundle.data['dislike_count'])

        return super(IdeaResource, self).obj_create(bundle)

    # No obj_update here because updates to lists of embedded docs don't trigger that function.
    # See individual embedded doc lists for update calls

# ------------------------------------------------------------------------------------------------------------

    def obj_update(self, bundle, **kwargs):
        """ Updates content when resource is PUT or PATCHed """

        # These ensure that counts are present if ideas are created with tags/likes/dislikes and comments
        bundle = count_builder(bundle, 'tags', 'tag_count')

        return super(IdeaResource, self).obj_create(bundle)

    # No obj_update here because updates to lists of embedded docs don't trigger that function.
    # See individual embedded doc lists for update calls

# ------------------------------------------------------------------------------------------------------------

    def alter_detail_data_to_serialize(self, request, data):
        """ Modify the content just before serializing data for a specific item """

        # Don't apply the meta object if it's anything but GET
        if request.method == 'GET':
            # Add a meta element for the single item response
            response_data = {'meta': {}, 'objects': [data]}

            # Add max PM into a newly created meta object
            pms = get_all_pms(response_data['objects'],
                              subdocs_to_check=['comments'],
                              pm_name='protective_marking')
            response_data['meta']['max_pm'] = get_max_pm(pms)

            # Get the modified time for this 1 object
            response_data['meta']['modified'] = data.data['modified']

            # Filter out the meta and objects content based on the data_level
            response_data = filter_by_data_level(request, response_data)

        else:
            response_data = data

        return response_data

# ------------------------------------------------------------------------------------------------------------

    def alter_list_data_to_serialize(self, request, data):
        """ Modify content just before serialized to output """

        # Try to get the modified timestamp. Except catches instance where no data
        try:
            idea_mod = documents.Idea.objects.order_by(
                '-modified')[0]['modified']
        except:
            return data

        # Retrieve all comment modified timestamps (idea, comments)
        res = documents.Idea._get_collection().aggregate([{
            "$project": {
                "_id": 0,
                "comments": 1
            }
        }, {
            "$unwind":
            "$comments"
        }, {
            "$project": {
                "modified": "$comments.modified"
            }
        }, {
            "$sort": {
                "modified": -1
            }
        }, {
            "$limit": 1
        }])['result']

        # In the event that there are no comments, chuck in an old date to guarantee the idea mod date wins
        if res:
            comments_mod = res[0]['modified']
        else:
            comments_mod = datetime.datetime(1970, 1, 1)

        # Assign the meta-level modified datetime to the most recent comment/idea modified datetime
        data['meta']['modified'] = max([idea_mod, comments_mod])

        # Tag-based filtering
        if request.method == 'GET' and request.GET.get('tags__in'):
            data = tag_based_filtering(request, data)

        # Find the highest protective marking in the dataset
        pms = get_all_pms(data['objects'],
                          subdocs_to_check=['comments'],
                          pm_name='protective_marking')
        data['meta']['max_pm'] = get_max_pm(pms)

        # Filter out the meta and objects content based on the data_level
        if request.method == 'GET':
            data = filter_by_data_level(request, data)

        return data

    # ------------------------------------------------------------------------------------------------------------

    def determine_format(self, request):
        """ Override the default format, so that format=json is not required """

        content_types = {
            'json': 'application/json',
            'jsonp': 'text/javascript',
            'xml': 'application/xml',
            'yaml': 'text/yaml',
            'html': 'text/html',
            'plist': 'application/x-plist',
            'csv': 'text/csv',
            'rss': 'application/rss+xml',
        }

        format = request.GET.get('format', None)
        if format == None:
            return 'application/json'
        else:
            return content_types[format]

    # ------------------------------------------------------------------------------------------------------------
    '''    
    def hydrate(self, bundle):
        """ Need to pass through user all the way through to dehydrate,
            so enabling that here"""
        print 'in hydrate', bundle.request.user
        bundle = super(IdeaResource, self).hydrate(bundle) 
        
        return bundle
    '''

    # ------------------------------------------------------------------------------------------------------------

    def hydrate_modified(self, bundle):
        """ Updates the idea-level modified timestamp field if the idea
            is edited. It doesn't handle updates to comments because they are
            an embedded resource"""

        if bundle.request.method != 'GET':
            bundle.data['modified'] = datetime.datetime.utcnow()
        return bundle

    # ------------------------------------------------------------------------------------------------------------

    def dehydrate(self, bundle):
        """ Dehydrate - data on its way back to requester """

        # User gets passed through because CustomAuth now passes it even for GET requests
        bundle.data['user_voted'] = get_user_vote_status(bundle)

        # Class will always have a time_stamp due to default.
        bundle.data['informal_created'] = calculate_informal_time(
            bundle.data['created'])
        bundle.data['informal_modified'] = calculate_informal_time(
            bundle.data['modified'])

        # Get the useful protective marking elements
        bundle = get_top_level_pm_elements(bundle)

        # Lookup the user's info
        bundle = get_contributors_info(bundle)

        # Produce a truncated (by word), html-tag cleaned version
        if bundle.data.has_key('description'):
            bundle.data['description_snippet'] = derive_snippet(
                bundle.data['description'])

        return bundle
Beispiel #16
0
class BaseRevisionResource(VosaeResource):
    revision = base_fields.CharField(
        attribute='revision',
        readonly=True,
        help_text=HELP_TEXT['base_revision']['revision'])
    issue_date = base_fields.DateTimeField(
        attribute='issue_date',
        readonly=True,
        help_text=HELP_TEXT['base_revision']['issue_date'])
    sender = base_fields.CharField(
        attribute='sender',
        null=True,
        blank=True,
        help_text=HELP_TEXT['base_revision']['sender'])
    sender_organization = base_fields.CharField(
        attribute='sender_organization',
        readonly=True,
        null=True,
        help_text=HELP_TEXT['base_revision']['sender_organization'])
    custom_payment_conditions = base_fields.CharField(
        attribute='custom_payment_conditions',
        null=True,
        blank=True,
        help_text=HELP_TEXT['base_revision']['custom_payment_conditions'])
    customer_reference = base_fields.CharField(
        attribute='customer_reference',
        null=True,
        blank=True,
        help_text=HELP_TEXT['base_revision']['customer_reference'])
    taxes_application = base_fields.CharField(
        attribute='taxes_application',
        help_text=HELP_TEXT['base_revision']['taxes_application'])

    issuer = fields.ReferenceField(
        to='core.api.resources.VosaeUserResource',
        attribute='issuer',
        readonly=True,
        null=True,
        help_text=HELP_TEXT['base_revision']['issuer'])
    sender_address = fields.EmbeddedDocumentField(
        embedded='contacts.api.resources.AddressResource',
        attribute='sender_address',
        null=True,
        help_text=HELP_TEXT['base_revision']['sender_address'])
    contact = fields.ReferenceField(
        to='contacts.api.resources.ContactResource',
        attribute='contact',
        null=True,
        help_text=HELP_TEXT['base_revision']['contact'])
    organization = fields.ReferenceField(
        to='contacts.api.resources.OrganizationResource',
        attribute='organization',
        null=True,
        help_text=HELP_TEXT['base_revision']['organization'])
    billing_address = fields.EmbeddedDocumentField(
        embedded='contacts.api.resources.AddressResource',
        attribute='billing_address',
        null=True,
        help_text=HELP_TEXT['base_revision']['billing_address'])
    delivery_address = fields.EmbeddedDocumentField(
        embedded='contacts.api.resources.AddressResource',
        attribute='delivery_address',
        null=True,
        help_text=HELP_TEXT['base_revision']['delivery_address'])
    currency = fields.EmbeddedDocumentField(
        embedded='invoicing.api.resources.SnapshotCurrencyResource',
        attribute='currency',
        help_text=HELP_TEXT['base_revision']['currency'])
    line_items = fields.EmbeddedListField(
        of='invoicing.api.resources.InvoiceItemResource',
        attribute='line_items',
        full=True,
        null=True,
        help_text=HELP_TEXT['base_revision']['line_items'])
    pdf = ReferencedDictField(of='core.api.resources.VosaeFileResource',
                              attribute='pdf',
                              readonly=True,
                              null=True,
                              help_text=HELP_TEXT['base_revision']['pdf'])

    class Meta(VosaeResource.Meta):
        object_class = InvoiceRevision

    def hydrate(self, bundle):
        """Set issue data and issuer on POST, extracted from request"""
        bundle = super(BaseRevisionResource, self).hydrate(bundle)
        bundle.obj.issuer = bundle.request.vosae_user
        bundle.obj.issue_date = datetime_now()
        return bundle
Beispiel #17
0
class PluginResource(resources.MongoEngineResource):
    description = fields.EmbeddedListField(
        of='lisa.server.web.manageplugins.api.EmbeddedDescriptionResource',
        attribute='description',
        full=True,
        null=True)

    class Meta:
        queryset = Plugin.objects.all()
        allowed_methods = ('get', 'post', 'put', 'delete')
        authorization = authorization.Authorization()
        authentication = MultiAuthentication(CustomApiKeyAuthentication())
        extra_actions = [
            {
                'name':
                'install',
                'summary':
                'Install a plugin',
                'http_method':
                'POST',
                "errorResponses": [{
                    "reason": "Plugin was installed correctly.",
                    "code": 201
                }, {
                    'reason': "There was a problem during the install.",
                    'code': 304
                }],
                'fields': {}
            },
            {
                'name': 'uninstall',
                'summary': 'Uninstall a plugin',
                'http_method': 'GET',
                'fields': {}
            },
            {
                'name': 'enable',
                'summary': 'Enable a plugin',
                'http_method': 'GET',
                'fields': {}
            },
            {
                'name': 'disable',
                'summary': 'Disable a plugin',
                'http_method': 'GET',
                'fields': {}
            },
            {
                'name': 'methodslist',
                'summary':
                'List the method of all (or the plugin name in parameter) plugins installed',
                'http_method': 'GET',
                'fields': {}
            },
        ]

    def prepend_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/(?P<plugin_name>[\w_-]+)/install%s" %
                (self._meta.resource_name, trailing_slash()),
                self.wrap_view('install'),
                name="api_plugin_install"),
            url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/enable%s" %
                (self._meta.resource_name, trailing_slash()),
                self.wrap_view('enable'),
                name="api_plugin_enable"),
            url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/disable%s" %
                (self._meta.resource_name, trailing_slash()),
                self.wrap_view('disable'),
                name="api_plugin_disable"),
            url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/uninstall%s" %
                (self._meta.resource_name, trailing_slash()),
                self.wrap_view('uninstall'),
                name="api_plugin_uninstall"),
            url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/upgrade%s" %
                (self._meta.resource_name, trailing_slash()),
                self.wrap_view('upgrade'),
                name="api_plugin_upgrade"),
            url(r"^(?P<resource_name>%s)/(?P<plugin_name>[\w_-]+)/methodslist%s"
                % (self._meta.resource_name, trailing_slash()),
                self.wrap_view('methodslist'),
                name="api_plugin_methodslist"),
            url(r"^(?P<resource_name>%s)/methodslist%s" %
                (self._meta.resource_name, trailing_slash()),
                self.wrap_view('methodslist'),
                name="api_plugin_methodslist"),
        ]

    def install(self, request, **kwargs):
        self.method_check(request, allowed=['post', 'get'])
        self.is_authenticated(request)
        self.throttle_check(request)
        plugin_name = kwargs['plugin_name']
        status = PluginManagerSingleton.get().installPlugin(
            plugin_name=plugin_name)

        self.log_throttled_access(request)
        LisaFactorySingleton.get().SchedReload()
        LisaFactorySingleton.get().LisaReload()
        return self.create_response(request, status, HttpCreated)

    def enable(self, request, **kwargs):
        self.method_check(request, allowed=['get'])
        self.is_authenticated(request)
        self.throttle_check(request)

        status = PluginManagerSingleton.get().enablePlugin(
            plugin_pk=kwargs['pk'])
        self.log_throttled_access(request)
        LisaFactorySingleton.get().SchedReload()
        LisaFactorySingleton.get().LisaReload()
        return self.create_response(request, status, HttpAccepted)

    def disable(self, request, **kwargs):
        self.method_check(request, allowed=['get'])
        self.is_authenticated(request)
        self.throttle_check(request)

        status = PluginManagerSingleton.get().disablePlugin(
            plugin_pk=kwargs['pk'])
        self.log_throttled_access(request)
        LisaFactorySingleton.get().SchedReload()
        LisaFactorySingleton.get().LisaReload()
        return self.create_response(request, status, HttpAccepted)

    def uninstall(self, request, **kwargs):
        self.method_check(request, allowed=['get'])
        self.is_authenticated(request)
        self.throttle_check(request)

        status = PluginManagerSingleton.get().uninstallPlugin(
            plugin_pk=kwargs['pk'])
        self.log_throttled_access(request)
        LisaFactorySingleton.get().SchedReload()
        LisaFactorySingleton.get().LisaReload()
        return self.create_response(request, status, HttpAccepted)

    def methodslist(self, request, **kwargs):
        self.method_check(request, allowed=['get'])
        self.is_authenticated(request)
        self.throttle_check(request)

        if 'plugin_name' in kwargs:
            methods = PluginManagerSingleton.get().methodListPlugin(
                plugin_name=kwargs['plugin_name'])
        else:
            methods = PluginManagerSingleton.get().methodListPlugin()
        self.log_throttled_access(request)
        return self.create_response(request, methods, HttpAccepted)
Beispiel #18
0
class InvoiceResource(InvoiceBaseResource):
    state = base_fields.CharField(attribute='state',
                                  readonly=True,
                                  help_text=HELP_TEXT['invoice']['state'])
    paid = base_fields.DecimalField(attribute='paid',
                                    readonly=True,
                                    help_text=HELP_TEXT['invoice']['paid'])
    balance = base_fields.DecimalField(
        attribute='balance',
        readonly=True,
        help_text=HELP_TEXT['invoice']['balance'])
    has_temporary_reference = base_fields.BooleanField(
        attribute='has_temporary_reference',
        readonly=True,
        help_text=HELP_TEXT['invoice']['has_temporary_reference'])

    current_revision = fields.EmbeddedDocumentField(
        embedded='invoicing.api.resources.InvoiceRevisionResource',
        attribute='current_revision',
        help_text=HELP_TEXT['invoice']['current_revision'])
    revisions = fields.EmbeddedListField(
        of='invoicing.api.resources.InvoiceRevisionResource',
        attribute='revisions',
        readonly=True,
        null=True,
        blank=True,
        help_text=HELP_TEXT['invoice']['revisions'])
    related_to = fields.ReferenceField(
        to='invoicing.api.resources.QuotationResource',
        attribute='related_to',
        readonly=True,
        null=True,
        help_text=HELP_TEXT['invoice']['related_to'])
    payments = fields.ReferencedListField(
        of='invoicing.api.resources.PaymentResource',
        attribute='payments',
        readonly=True,
        null=True,
        blank=True,
        help_text=HELP_TEXT['invoice']['payments'])

    class Meta(InvoiceBaseResource.Meta):
        queryset = Invoice.objects.all()
        detail_specific_methods = ('cancel', 'mark_as_registered')

    def prepend_urls(self):
        """Add urls for resources actions."""
        urls = super(InvoiceResource, self).prepend_urls()
        urls.extend(
            (url(r'^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/cancel%s$' %
                 (self._meta.resource_name, trailing_slash()),
                 self.wrap_view('invoice_cancel'),
                 name='api_invoice_cancel'), ))
        return urls

    def invoice_cancel(self, request, **kwargs):
        """Cancel the invoice and returns the associated credit note."""
        from invoicing.api.resources.credit_note import CreditNoteResource
        self.method_check(request, allowed=['put'])
        self.is_authenticated(request)
        self.throttle_check(request)

        try:
            bundle = self.build_bundle(request=request)
            obj = self.cached_obj_get(bundle=bundle,
                                      **self.remove_api_resource_names(kwargs))
        except ObjectDoesNotExist:
            return http.HttpNotFound()

        try:
            credit_note = obj.cancel(request.vosae_user)
            invoicing_signals.post_cancel_invoice.send(
                obj.__class__,
                issuer=request.vosae_user,
                document=obj,
                credit_note=credit_note)
            credit_note_resource = CreditNoteResource()
            credit_note_resource_bundle = credit_note_resource.build_bundle(
                obj=credit_note, request=request)
        except NotCancelableInvoice as e:
            raise BadRequest(e)

        self.log_throttled_access(request)

        to_be_serialized = {
            'credit_note_uri':
            credit_note_resource.get_resource_uri(credit_note_resource_bundle)
        }
        to_be_serialized = self.alter_list_data_to_serialize(
            request, to_be_serialized)
        return self.create_response(request, to_be_serialized)

    def dehydrate_related_to(self, bundle):
        from invoicing.api.resources import QuotationResource, PurchaseOrderResource
        try:
            if bundle.obj.related_to.is_quotation():
                resource = QuotationResource()
            elif bundle.obj.related_to.is_purchase_order():
                resource = PurchaseOrderResource()
            resource_bundle = resource.build_bundle(obj=bundle.obj.related_to,
                                                    request=bundle.request)
            return resource.get_resource_uri(resource_bundle)
        except:
            return
Beispiel #19
0
class VosaeEventResource(TenantResource):
    status = base_fields.CharField(
        attribute='status',
        null=True,
        blank=True,
        help_text=HELP_TEXT['vosae_event']['status'])
    created_at = base_fields.DateTimeField(
        attribute='created_at',
        readonly=True,
        help_text=HELP_TEXT['vosae_event']['created_at'])
    updated_at = base_fields.DateTimeField(
        attribute='updated_at',
        readonly=True,
        help_text=HELP_TEXT['vosae_event']['updated_at'])
    summary = base_fields.CharField(
        attribute='summary', help_text=HELP_TEXT['vosae_event']['summary'])
    description = base_fields.CharField(
        attribute='description',
        null=True,
        blank=True,
        help_text=HELP_TEXT['vosae_event']['description'])
    location = base_fields.CharField(
        attribute='location',
        null=True,
        blank=True,
        help_text=HELP_TEXT['vosae_event']['location'])
    color = base_fields.CharField(attribute='color',
                                  null=True,
                                  blank=True,
                                  help_text=HELP_TEXT['vosae_event']['color'])
    start = fields.EmbeddedDocumentField(
        embedded='organizer.api.resources.EventDateTimeResource',
        attribute='start',
        help_text=HELP_TEXT['vosae_event']['start'])
    end = fields.EmbeddedDocumentField(
        embedded='organizer.api.resources.EventDateTimeResource',
        attribute='end',
        help_text=HELP_TEXT['vosae_event']['end'])
    recurrence = base_fields.CharField(
        attribute='recurrence',
        null=True,
        blank=True,
        help_text=HELP_TEXT['vosae_event']['recurrence'])
    original_start = fields.EmbeddedDocumentField(
        embedded='organizer.api.resources.EventDateTimeResource',
        attribute='original_start',
        readonly=True,
        help_text=HELP_TEXT['vosae_event']['original_start'])
    instance_id = base_fields.CharField(
        attribute='instance_id',
        readonly=True,
        null=True,
        blank=True,
        help_text=HELP_TEXT['vosae_event']['instance_id'])
    transparency = base_fields.CharField(
        attribute='transparency',
        null=True,
        blank=True,
        help_text=HELP_TEXT['vosae_event']['transparency'])

    calendar = fields.ReferenceField(
        to='organizer.api.resources.VosaeCalendarResource',
        attribute='calendar',
        help_text=HELP_TEXT['vosae_event']['calendar'])
    creator = fields.ReferenceField(
        to='core.api.resources.VosaeUserResource',
        attribute='creator',
        readonly=True,
        help_text=HELP_TEXT['vosae_event']['creator'])
    organizer = fields.ReferenceField(
        to='core.api.resources.VosaeUserResource',
        attribute='organizer',
        readonly=True,
        help_text=HELP_TEXT['vosae_event']['organizer'])
    attendees = fields.EmbeddedListField(
        of='organizer.api.resources.AttendeeResource',
        attribute='attendees',
        null=True,
        blank=True,
        full=True,
        help_text=HELP_TEXT['vosae_event']['attendees'])
    reminders = fields.EmbeddedDocumentField(
        embedded='organizer.api.resources.ReminderSettingsResource',
        attribute='reminders',
        blank=True,
        help_text=HELP_TEXT['vosae_event']['reminders'])

    class Meta(TenantResource.Meta):
        resource_name = 'vosae_event'
        queryset = VosaeEvent.objects.all()
        excludes = ('tenant', 'occurrences', 'next_reminder', 'ical_uid',
                    'ical_data')
        filtering = {
            'start': ('exact', 'gt', 'gte'),
            'end': ('exact', 'lt', 'lte'),
            'calendar': ('exact')
        }
        validation = EventValidation()

    def prepend_urls(self):
        """Add urls for resources actions."""
        urls = super(VosaeEventResource, self).prepend_urls()
        urls.extend(
            (url(r'^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/instances%s$' %
                 (self._meta.resource_name, trailing_slash()),
                 self.wrap_view('event_instances'),
                 name='api_vosae_event_instances'), ))
        return urls

    def build_filters(self, filters=None):
        qs_filters = super(VosaeEventResource, self).build_filters(filters)
        for filter_name, filter_value in qs_filters.iteritems():
            if filter_name.endswith('__exact'):
                new_name = filter_name[:filter_name.index('__exact')]
                qs_filters[new_name] = filter_value
                del qs_filters[filter_name]
                filter_name = new_name
            if filter_name in DATERANGE_FILTERS:
                if isinstance(filter_value, basestring):
                    qs_filters[filter_name] = parse(filter_value)
        return qs_filters

    def get_object_list(self, request):
        """Filters events based on calendar accesses (extracted from request user)"""
        from organizer.models import VosaeCalendar
        object_list = super(VosaeEventResource, self).get_object_list(request)
        principals = [request.vosae_user] + request.vosae_user.groups
        calendars = VosaeCalendar.objects.filter(
            acl__read_list__in=principals, acl__negate_list__nin=principals)
        return object_list.filter(calendar__in=list(calendars))

    def apply_filters(self, request, applicable_filters):
        object_list = super(VosaeEventResource,
                            self).apply_filters(request, applicable_filters)
        filters = request.GET
        if 'single_events' in filters and filters['single_events'] in [
                'true', 'True', True
        ]:
            start = None
            end = None
            for filter_name, filter_value in filters.iteritems():
                try:
                    if filter_name.startswith('start'):
                        start = parse(filter_value)
                    elif filter_name.startswith('end'):
                        end = parse(filter_value)
                except:
                    pass
            return object_list.with_instances(start, end)
        return object_list

    def event_instances(self, request, **kwargs):
        """List all instances of the event"""
        self.method_check(request, allowed=['get'])
        self.is_authenticated(request)
        self.throttle_check(request)

        try:
            bundle = self.build_bundle(request=request)
            objects = self.obj_get_list(
                bundle,
                **self.remove_api_resource_names(kwargs)).with_instances()
        except ObjectDoesNotExist:
            return http.HttpNotFound()

        if objects.count() < 2:
            return http.HttpNotFound()

        sorted_objects = self.apply_sorting(objects, options=request.GET)

        first_objects_bundle = self.build_bundle(obj=objects[0],
                                                 request=request)
        instances_resource_uri = '%sinstances/' % self.get_resource_uri(
            first_objects_bundle)
        paginator = self._meta.paginator_class(
            request.GET,
            sorted_objects,
            resource_uri=instances_resource_uri,
            limit=self._meta.limit)
        to_be_serialized = paginator.page()

        # Dehydrate the bundles in preparation for serialization.
        bundles = [
            self.build_bundle(obj=obj, request=request)
            for obj in to_be_serialized['objects']
        ]
        to_be_serialized['objects'] = [self.full_dehydrate(b) for b in bundles]
        to_be_serialized = self.alter_list_data_to_serialize(
            request, to_be_serialized)
        return self.create_response(request, to_be_serialized)

    def full_hydrate(self, bundle):
        """Set event's creator and organizer"""
        bundle = super(VosaeEventResource, self).full_hydrate(bundle)
        bundle.obj.creator = bundle.request.vosae_user
        # Organizer should be the user owner of the calendar
        try:
            organizer = bundle.obj.calendar.acl.get_owner()
        except:
            organizer = bundle.request.vosae_user
        bundle.obj.organizer = organizer
        return bundle

    def full_dehydrate(self, bundle, for_list=False):
        bundle = super(VosaeEventResource,
                       self).full_dehydrate(bundle, for_list=for_list)
        if not bundle.data['instance_id']:
            del bundle.data['instance_id']
        return bundle

    def dehydrate(self, bundle):
        """Dehydrates the appropriate CalendarList which differs according to user (extracted from request)"""
        from organizer.models import CalendarList
        from organizer.api.resources import CalendarListResource
        bundle = super(VosaeEventResource, self).dehydrate(bundle)
        calendar_list = CalendarList.objects.get(
            calendar=bundle.obj.calendar, vosae_user=bundle.request.vosae_user)
        calendar_list_resource = CalendarListResource()
        calendar_list_resource_bundle = calendar_list_resource.build_bundle(
            obj=calendar_list, request=bundle.request)
        bundle.data['calendar_list'] = calendar_list_resource.get_resource_uri(
            calendar_list_resource_bundle)
        return bundle
Beispiel #20
0
class InvoiceBaseResource(NotificationAwareResourceMixin, TenantResource,
                          VosaeIMEXMixinResource):
    reference = base_fields.CharField(
        attribute='reference',
        readonly=True,
        help_text=HELP_TEXT['invoicebase']['reference'])
    total = base_fields.DecimalField(
        attribute='total',
        readonly=True,
        help_text=HELP_TEXT['invoicebase']['total'])
    amount = base_fields.DecimalField(
        attribute='amount',
        readonly=True,
        help_text=HELP_TEXT['invoicebase']['amount'])
    account_type = base_fields.CharField(
        attribute='account_type',
        help_text=HELP_TEXT['invoicebase']['account_type'])

    issuer = fields.ReferenceField(
        to='core.api.resources.VosaeUserResource',
        attribute='issuer',
        readonly=True,
        help_text=HELP_TEXT['invoicebase']['issuer'])
    organization = fields.ReferenceField(
        to='contacts.api.resources.OrganizationResource',
        attribute='organization',
        readonly=True,
        null=True,
        help_text=HELP_TEXT['invoicebase']['organization'])
    contact = fields.ReferenceField(
        to='contacts.api.resources.ContactResource',
        attribute='contact',
        readonly=True,
        null=True,
        help_text=HELP_TEXT['invoicebase']['contact'])
    history = fields.EmbeddedListField(
        of='invoicing.api.resources.InvoiceHistoryEntryResource',
        attribute='history',
        readonly=True,
        full=True,
        null=True,
        blank=True,
        help_text=HELP_TEXT['invoicebase']['history'])
    notes = fields.EmbeddedListField(
        of='invoicing.api.resources.InvoiceNoteResource',
        attribute='notes',
        full=True,
        null=True,
        blank=True,
        help_text=HELP_TEXT['invoicebase']['notes'])
    group = fields.ReferenceField(
        to='invoicing.api.resources.InvoiceBaseGroupResource',
        attribute='group',
        readonly=True,
        help_text=HELP_TEXT['invoicebase']['group'])
    attachments = fields.ReferencedListField(
        of='core.api.resources.VosaeFileResource',
        attribute='attachments',
        null=True,
        blank=True,
        help_text=HELP_TEXT['invoicebase']['attachments'])

    class Meta(TenantResource.Meta):
        excludes = ('tenant', 'base_type', 'subscribers')
        filtering = {
            'state': ('exact', 'in'),
            'contact': ('exact', ),
            'organization': ('exact', ),
            'account_type': ('exact', ),
            'reference': ('contains', )
        }

        available_imex_serializers = (invoicing_imex.PDFSerializer, )

    def prepend_urls(self):
        """Add urls for resources actions."""
        urls = super(InvoiceBaseResource, self).prepend_urls()
        urls.extend(VosaeIMEXMixinResource.prepend_urls(self))
        urls.extend((
            url(r'^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/send/mail%s$' %
                (self._meta.resource_name, trailing_slash()),
                self.wrap_view('send_by_mail'),
                name='api_invoicebase_send_by_mail'),
            url(r'^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/mark_as_(?P<invoicebase_state>(%s))%s$'
                % (self._meta.resource_name, '|'.join(
                    [k.lower() for k in MARK_AS_STATES]), trailing_slash()),
                self.wrap_view('mark_as_state'),
                name='api_invoicebase_mark_as_state'),
            url(r'^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/generate_pdf%s$' %
                (self._meta.resource_name, trailing_slash()),
                self.wrap_view('generate_pdf'),
                name='api_invoicebase_generate_pdf'),
        ))
        return urls

    @classmethod
    def post_save(self, sender, resource, bundle, created, **kwargs):
        """
        Post save API hook handler

        - Add timeline and notification entries
        """
        # Add timeline and notification entries
        invoicebase_saved_task.delay(bundle.request.vosae_user, bundle.obj,
                                     created)

    def obj_delete(self, bundle, **kwargs):
        """Raises a BadRequest if the :class:`~invoicing.models.InvoiceBase` is not in a deletable state"""
        try:
            super(InvoiceBaseResource, self).obj_delete(bundle, **kwargs)
        except NotDeletableInvoice as e:
            raise BadRequest(e)

    def do_export(self, request, serializer, export_objects):
        """Export"""
        if len(export_objects) is not 1:
            raise BadRequest('PDF export can only be done on a single item.')
        return serializer.serialize(export_objects[0]), None

    def send_by_mail(self, request, **kwargs):
        """Send an InvoiceBase by mail."""
        self.method_check(request, allowed=['post'])
        self.is_authenticated(request)
        self.throttle_check(request)

        try:
            bundle = self.build_bundle(request=request)
            obj = self.cached_obj_get(bundle=bundle,
                                      **self.remove_api_resource_names(kwargs))
        except ObjectDoesNotExist:
            return http.HttpNotFound()

        try:
            email_data = self.deserialize(request,
                                          request.body,
                                          format=request.META.get(
                                              'CONTENT_TYPE',
                                              'application/json'))
            subject = email_data.get('subject')
            message = email_data.get('message')
            to = email_data.get('to')
            cc = email_data.get('cc', [])
            bcc = email_data.get('bcc', [])
            assert isinstance(to, list) and isinstance(
                cc, list) and isinstance(bcc, list)
        except:
            raise BadRequest('Invalid email parameters.')

        try:
            obj.send_by_mail(subject, message, to, cc, bcc, request.vosae_user)
        except:
            raise BadRequest('Can\'t send email. Verify parameters.')

        self.log_throttled_access(request)

        to_be_serialized = {}
        to_be_serialized = self.alter_list_data_to_serialize(
            request, to_be_serialized)
        return self.create_response(request, to_be_serialized)

    def mark_as_state(self, request, invoicebase_state, **kwargs):
        """Set state for an InvoiceBase."""
        self.method_check(request, allowed=['put'])
        self.is_authenticated(request)
        self.throttle_check(request)

        try:
            bundle = self.build_bundle(request=request)
            obj = self.cached_obj_get(bundle=bundle,
                                      **self.remove_api_resource_names(kwargs))
        except ObjectDoesNotExist:
            return http.HttpNotFound()

        try:
            previous_state, new_state = obj.set_state(
                invoicebase_state.upper(), issuer=request.vosae_user)
            invoicing_signals.post_client_changed_invoice_state.send(
                obj.__class__,
                issuer=request.vosae_user,
                document=obj,
                previous_state=previous_state)
        except (obj.InvalidState, InvalidInvoiceBaseState) as e:
            raise BadRequest(e)

        self.log_throttled_access(request)

        return http.HttpNoContent()
        # May need to use this with ember (check if always_return_data)
        # to_be_serialized = ''
        # to_be_serialized = self.alter_list_data_to_serialize(request, to_be_serialized)
        # return self.create_response(request, to_be_serialized)

    def generate_pdf(self, request, **kwargs):
        """Generate a PDF"""
        self.method_check(request, allowed=['get'])
        self.is_authenticated(request)
        self.throttle_check(request)

        try:
            bundle = self.build_bundle(request=request)
            obj = self.cached_obj_get(bundle=bundle,
                                      **self.remove_api_resource_names(kwargs))
        except ObjectDoesNotExist:
            return http.HttpNotFound()

        try:
            language = request.META.get('HTTP_X_REPORT_LANGUAGE', None)
            if language is not None:
                assert language in [k[0] for k in settings.LANGUAGES]
        except:
            raise BadRequest('Invalid language parameters.')

        try:
            pdf = obj.get_pdf(issuer=request.vosae_user, language=language)
            pdf_resource = VosaeFileResource()
            pdf_resource_bundle = pdf_resource.build_bundle(obj=pdf,
                                                            request=request)
        except Exception, e:
            print e
            raise BadRequest('Can\'t generate PDF. Verify parameters.')

        self.log_throttled_access(request)

        pdf_resource_bundle = pdf_resource.full_dehydrate(pdf_resource_bundle)
        pdf_resource_bundle = pdf_resource.alter_detail_data_to_serialize(
            request, pdf_resource_bundle)
        return pdf_resource.create_response(request, pdf_resource_bundle)
Beispiel #21
0
class CalendarListResource(TenantResource):
    summary = base_fields.CharField(
        attribute='calendar__summary',
        readonly=True,
        help_text=HELP_TEXT['vosae_calendar']['summary']
    )
    description = base_fields.CharField(
        attribute='calendar__description',
        null=True,
        readonly=True,
        help_text=HELP_TEXT['vosae_calendar']['description']
    )
    location = base_fields.CharField(
        attribute='calendar__location',
        null=True,
        readonly=True,
        help_text=HELP_TEXT['vosae_calendar']['location']
    )
    timezone = base_fields.CharField(
        attribute='calendar__timezone',
        readonly=True,
        help_text=HELP_TEXT['vosae_calendar']['timezone']
    )
    summary_override = base_fields.CharField(
        attribute='summary_override',
        null=True,
        blank=True,
        help_text=HELP_TEXT['calendar_list']['summary_override']
    )
    color = base_fields.CharField(
        attribute='color',
        blank=True,
        help_text=HELP_TEXT['calendar_list']['color']
    )
    selected = base_fields.BooleanField(
        attribute='selected',
        blank=True,
        help_text=HELP_TEXT['calendar_list']['selected']
    )
    is_own = base_fields.BooleanField(
        readonly=True,
        help_text=HELP_TEXT['calendar_list']['is_own']
    )

    calendar = fields.ReferenceField(
        to='organizer.api.resources.VosaeCalendarResource',
        attribute='calendar',
        help_text=HELP_TEXT['calendar_list']['calendar']
    )

    reminders = fields.EmbeddedListField(
        of='organizer.api.resources.ReminderEntryResource',
        attribute='reminders',
        null=True,
        blank=True,
        full=True,
        help_text=HELP_TEXT['calendar_list']['reminders']
    )

    class Meta(TenantResource.Meta):
        resource_name = 'calendar_list'
        queryset = CalendarList.objects.all()
        excludes = ('tenant', 'vosae_user')
        filtering = {
            'calendar': ('exact',)
        }

    def get_object_list(self, request):
        """Filters objects on current user (extracted from request)"""
        object_list = super(CalendarListResource, self).get_object_list(request)
        return object_list.filter(vosae_user=request.vosae_user)

    def hydrate(self, bundle):
        """Automatically set the user (extracted from request)"""
        bundle = super(CalendarListResource, self).hydrate(bundle)
        bundle.obj.vosae_user = bundle.request.vosae_user
        return bundle

    def dehydrate_is_own(self, bundle):
        """`is_own` is processed here, based on the request's user"""
        try:
            if bundle.obj.calendar.acl.get_owner() == bundle.request.vosae_user:
                return True
        except:
            pass
        return False
Beispiel #22
0
class FeedbackResource(BaseCorsResource, resources.MongoEngineResource):
    
    protective_marking = mongo_fields.EmbeddedDocumentField(embedded='contentapp.api.ProtectiveMarkingResource', attribute='protective_marking', help_text='protective marking of this content', null=True)
    comments           = mongo_fields.EmbeddedListField(of='contentapp.api.FeedbackCommentResource', attribute='comments', full=True, null=True)
    
    class Meta:
        resource_name = 'feedback'
        queryset = documents.Feedback.objects.all()
        serializer = CustomSerializer()
        allowed_methods = ('get', 'post', 'put', 'delete')
        
        authentication = CustomApiKeyAuthentication()
        authorization = PrivilegedAndSubmitterOnly()
        
        filtering = {'created'  : ['gt', 'gte', 'lt', 'lte'],
                     'modified' : ['gt', 'gte', 'lt', 'lte'],
                     'status'   : ['exact'],
                     'type'     : ['exact'],
                     'user'     : ['exact']}

        ordering = ['title', 'created', 'modified', 'status', 'user', 'summary', 'body']

    # ------------------------------------------------------------------------------------------------------------        

    def determine_format(self, request):
        """ Override the default format, so that format=json is not required """
    
        content_types = {
                        'json': 'application/json',
                        'jsonp': 'text/javascript',
                        'xml': 'application/xml',
                        'yaml': 'text/yaml',
                        'html': 'text/html',
                        'plist': 'application/x-plist',
                        'csv': 'text/csv',
                        'rss': 'application/rss+xml',
                    }
    
        format = request.GET.get('format', None)
        if format == None:
            return 'application/json'    
        else:
            return content_types[format]

    # ------------------------------------------------------------------------------------------------------------        

    def obj_create(self, bundle, **kwargs):
        """ How to create a feedback object  """
        
        # Add the user to the data payload
        bundle.data['user'] = bundle.request.user.username
        bundle = count_builder(bundle, 'comments',  'comment_count')
        
        return super(FeedbackResource, self).obj_create(bundle)
    
    # ------------------------------------------------------------------------------------------------------------        

    def obj_update(self, bundle, **kwargs):
        """ Apply the authorization limits when putting"""
        
        # We must get the primary key because the mongoengine obj_update function is
        # expecting one to access the object we want to modify.
        regExp = re.compile('.*/(?P<doc_id>[a-zA-Z0-9]{24})/')
        m = re.match(regExp, bundle.request.path).groupdict()
        if not getattr(bundle.obj, 'pk', None):
            bundle.obj.pk = m['doc_id']
        
        return super(FeedbackResource, self).obj_update(bundle)
    
    # ------------------------------------------------------------------------------------------------------------        

    def hydrate_modified(self, bundle):
        """ Updates the idea-level modified timestamp field if the idea
            is edited. It doesn't handle updates to comments because they are
            an embedded resource"""
        
        if bundle.request.method != 'GET':
            bundle.data['modified'] = datetime.datetime.utcnow()
        return bundle
    
    # ------------------------------------------------------------------------------------------------------------        

    def dehydrate(self, bundle):
        """ Dehydrate - data on its way back to requester """
        
        # Class will always have a time_stamp due to default.
        bundle.data['informal_created'] = calculate_informal_time(bundle.data['created'])
        bundle.data['informal_modified'] = calculate_informal_time(bundle.data['modified'])
        
        # Get the useful protective marking elements
        bundle = get_top_level_pm_elements(bundle)
               
        # Lookup the user's info
        bundle = get_contributors_info(bundle)
        
        return bundle

# ------------------------------------------------------------------------------------------------------------        

    def alter_detail_data_to_serialize(self, request, data):
        """ Modify the content just before serializing data for a specific item """
        
        # Don't apply the meta object if it's anything but GET
        if request.method == 'GET':
            # Add a meta element for the single item response
            response_data = {'meta':{},'objects':[data]}
    
            # Add max PM into a newly created meta object
            pms = get_all_pms(response_data['objects'], subdocs_to_check=['comments'], pm_name='protective_marking')
            response_data['meta']['max_pm'] = get_max_pm(pms)    
    
            # Get the modified time for this 1 object
            response_data['meta']['modified'] = data.data['modified'] 

        else:
            response_data = data

        return response_data

# ------------------------------------------------------------------------------------------------------------        
    
    def alter_list_data_to_serialize(self, request, data):
        """ Modify content just before serialized to output """             

        # Try to get the modified timestamp. Except catches instance where no data
        try:
            idea_mod = documents.Feedback.objects.order_by('-modified')[0]['modified']
            data['meta']['modified'] = idea_mod
        except:
            return data
            
        # Find the highest protective marking in the dataset
        if request.method == 'GET':
            pms = get_all_pms(data['objects'], subdocs_to_check=['comments'], pm_name='protective_marking')
            data['meta']['max_pm'] = get_max_pm(pms)    
        
        return data
    
    #-----------------------------------------------------------------------------
    
    def serialize(self, request, data, format, options=None):
        """
        Override of resource.serialize so that custom options
        can be built for the rss serializer
        """
        
        # Is it an rss feed
        if 'application/rss+xml' in format:
            
            options = {}
            
            # Has the feed been filtered?
            params = request.GET.keys()
            params.pop(params.index('format'))
            if params and len(params) > 0:
                filtered = ' (filtered)'
            else:
                filtered = ''
            
            # Build a title based on the end point
            path = request.path.strip('/').split('/')
            # If it's not a detail view
            if len(path[-1]) != 24:

                # If there are tags, then make them available for the title
                tags = request.GET.get('tags', None)
                if not tags:
                    tags = request.GET.get('tags__in', None)
                if tags:
                    filtered = ' (Tags:%s)'%(tags)

                # Build the title                
                api_end_point = path[-1].lower()
                options['title'] = settings.END_POINT_DESCRIPTIONS[api_end_point]
                
                current_site = get_current_site(request)
                options['link'] = current_site.domain + settings.FRONT_END_URL
                options['description'] = settings.END_POINT_DESCRIPTIONS[api_end_point]
            
        return super(FeedbackResource, self).serialize(request, data, format, options)