Ejemplo n.º 1
0
def build_StructBlockValidationError():
    FieldValidationError = g.ObjectType(
        'WagtailStructBlockFieldValidationError',
        fields=lambda: g.fields({
            'name': str,
            'error': WagtailBlockValidationError
        }),
    )

    return g.ObjectType(
        'WagtailStructBlockValidationError',
        fields=lambda: g.fields({
            'error_message':
            valdiation_error_message_field,
            'errors':
            g.Field(
                g.NNList(FieldValidationError),
                resolve=lambda obj, info: [{
                    'name': k,
                    'error': v
                } for k, v in obj.data[0].params.items()],
            ),
        }),
        interfaces=[WagtailBlockValidationError],
    )
Ejemplo n.º 2
0
class checkRatioPromocode(helpers.BaseFieldWithInput):
    def resolve(self, _, info, input):
        try:
            ticket_type = models.TicketType.objects.get(
                uuid=input['ticket_type_id'])
        except models.TicketType.DoesNotExist:
            return None

        try:
            promocode = ticket_type.check_promocode(code=input['code'])
        except models.Promocode.DoesNotExist:
            return None

        if not promocode.is_valid():
            return None

        return {
            'discounted_price': promocode.check_apply(ticket_type.price),
        }

    permissions = []
    input = {
        'ticket_type_id': 'ID!',
        'code': str,
    }
    result = g.ObjectType(
        'CheckRatioPromocodeResult',
        g.fields({
            'discounted_price': int,
        }),
    )
Ejemplo n.º 3
0
def build_ValidationError():
    ValidationErrorItem = g.ObjectType(
        'ValidationErrorItem',
        fields=g.fields({
            'name': str,
            'messages': g.NNList(g.String),
        }),
    )

    def resolve_errors(obj, info):
        # note .error, obj is boxed with kocherga.django.errors.BoxedError
        return [{
            'name': k,
            'messages': [str(e) for e in v]
        } for k, v in obj.error.message_dict.items()]

    return g.ObjectType(
        'ValidationError',
        fields={
            'errors':
            g.Field(
                g.NNList(ValidationErrorItem),
                resolve=resolve_errors,
            ),
        },
    )
Ejemplo n.º 4
0
def build_WagtailStreamFieldValidationError():
    def resolve_block_errors(obj, info):
        result = []
        for k, v in obj['params'].items():
            assert isinstance(v, ErrorList)
            if k == '__all__':
                continue  # non-block error
            result.append({'block_id': k, 'error': v})
        return result

    def resolve_non_block_error(obj, info):
        error = obj['params'].get('__all__')
        if error is None:
            return None
        return str(error)

    return g.ObjectType(
        'WagtailStreamFieldValidationError',
        g.fields({
            'block_errors':
            g.Field(
                g.NNList(WagtailStreamBlockValidationError),
                resolve=resolve_block_errors,
            ),
            'non_block_error':
            g.Field(g.String, resolve=resolve_non_block_error),
        }),
    )
Ejemplo n.º 5
0
class authLogout(helpers.BaseField):
    permissions = [authenticated]
    result = g.NN(
        g.ObjectType('AuthLogoutResult', g.fields({'ok': Optional[bool]})))

    def resolve(self, _, info):
        logout(info.context)
        return {'ok': True}
Ejemplo n.º 6
0
class vk_field(helpers.BaseField):
    def resolve(self, obj, info):
        return {
            'link': obj.vk_link(),
        }

    permissions = []
    result = g.NN(
        g.ObjectType('EventsWeeklyDigestVk', g.fields({'link':
                                                       Optional[str]})))
Ejemplo n.º 7
0
def service_fields(account_type):
    return g.fields({
        'slug':
        str,
        'accounts':
        g.Field(
            g.NNList(account_type),
            resolve=lambda obj, info: obj.list_accounts(),
        ),
    })
Ejemplo n.º 8
0
def build_AnyBlockValidationError():
    return g.ObjectType(
        'WagtailAnyBlockValidationError',
        fields=lambda: g.fields({
            'error_message':
            g.Field(
                g.NN(g.String),
                resolve=lambda obj, info: getattr(obj.data[0], 'message',
                                                  str(obj.data[0])),
            ),
        }),
        interfaces=[WagtailBlockValidationError],
    )
Ejemplo n.º 9
0
class wagtailPagePermissions(helpers.BaseField):
    # TODO - enum? PAGE_PERMISSION_TYPES is a constant in wagtail
    _permission_type = g.NN(g.String)

    WagtailSpecificPagePermission = g.ObjectType(
        'WagtailSpecificPagePermission',
        fields=g.fields({
            'id': 'ID!',
            'permission_type': _permission_type,
            'page': g.NN(wagtail_types.WagtailPage),
        }),
    )

    WagtailRootPagePermission = g.ObjectType(
        'WagtailRootPagePermission',
        fields=g.fields({
            'id': 'ID!',
            'permission_type': _permission_type,
        }),
    )

    # TODO - interface instead of union? would be better for querying
    WagtailPagePermission = g.UnionType(
        'WagtailPagePermission',
        types=[WagtailRootPagePermission, WagtailSpecificPagePermission],
        resolve_type=lambda obj, info, *_:
        ('WagtailRootPagePermission'
         if obj.page.is_root() else 'WagtailSpecificPagePermission'),
    )

    # AuthGroup is very private so we don't need additional checks here
    permissions = []

    def resolve(self, group, info):
        return group.page_permissions.all()

    result = g.NNList(WagtailPagePermission)
Ejemplo n.º 10
0
class mailchimp_field(helpers.BaseField):
    def resolve(self, obj, info):
        return {
            'link': obj.mailchimp_campaign_link(),
            'is_sent': obj.mailchimp_sent,
        }

    permissions = []
    result = g.NN(
        g.ObjectType(
            'EventsWeeklyDigestMailchimp',
            g.fields({
                'link': Optional[str],
                'is_sent': bool,
            }),
        ))
Ejemplo n.º 11
0
def create_EventsListBlock():
    def resolve_value(obj, info):
        qs = kocherga.events.models.Event.objects.public_only(
        ).filter_by_period(from_date=datetime.today())
        return qs[:20]

    return g.ObjectType(
        'EventsListBlock',
        interfaces=[WagtailBlock],
        fields=g.fields({
            'id':
            'ID!',
            'events':
            g.Field(g.NNList(event_types.Event), resolve=resolve_value),
        }),
    )
Ejemplo n.º 12
0
class wagtailCollectionPermissions(helpers.BaseField):
    WagtailCollectionPermission = g.ObjectType(
        'WagtailCollectionPermission',
        fields=g.fields({
            'id': 'ID!',
            'permission': g.NN(AuthPermission),
            'collection': g.NN(wagtail_types.WagtailCollection),
        }),
    )

    permissions = []

    def resolve(self, group, info):
        return group.collection_permissions.all()

    result = g.NNList(WagtailCollectionPermission)
Ejemplo n.º 13
0
def build_ListBlockValidationError():
    def resolve_errors(obj, info):
        return obj.data[0].params

    return g.ObjectType(
        'WagtailListBlockValidationError',
        fields=lambda: g.fields({
            'error_message':
            valdiation_error_message_field,
            'errors':
            g.Field(
                g.NN(g.List(WagtailBlockValidationError)),
                resolve=resolve_errors,
            ),
        }),
        interfaces=[WagtailBlockValidationError],
    )
Ejemplo n.º 14
0
def create_account_and_service_types(service_class, account_fields):
    Account = g.ObjectType(
        service_to_account_type(service_class),
        fields=lambda: g.fields({
            'service': g.NN(Service),
            **account_fields
        }),
        interfaces=[ExternalServiceAccount],
    )

    Service = g.ObjectType(
        service_to_type(service_class),
        fields=service_fields(Account),
        interfaces=[ExternalService],
    )

    return [Account, Service]
Ejemplo n.º 15
0
def create_PhotoRibbonBlock():
    def resolve_value(obj, info, spec):
        return [image.get_rendition(spec) for image in obj.value]

    return g.ObjectType(
        'PhotoRibbonBlock',
        interfaces=[WagtailBlock],
        fields=g.fields({
            'id':
            'ID!',
            'value':
            g.Field(
                g.NNList(WagtailImageRendition),
                args=g.arguments({'spec': str}),
                resolve=resolve_value,
            ),
        }),
    )
Ejemplo n.º 16
0
class ratioConfirmOrder(helpers.BaseFieldWithInput):
    def resolve(self, _, info, input):
        order_id = input['order_id']
        try:
            order = models.Order.objects.get(uuid=order_id)
        except models.Order.DoesNotExist:
            return {'outcome': self.OutcomeEnum.NOT_FOUND.value}

        try:
            order.confirm()
        except models.Order.NotPaidError:
            return {'outcome': self.OutcomeEnum.NOT_PAID.value}
        except models.Order.AlreadyFulfilledError:
            return {'outcome': self.OutcomeEnum.ALREADY_FULFILLED.value}
        except models.Order.TicketAlreadyExistsError:
            return {'outcome': self.OutcomeEnum.TICKET_ALREADY_EXISTS.value}

        return {'outcome': self.OutcomeEnum.OK.value}

    permissions = []
    input = {
        'order_id': 'ID!',  # this is uuid, order's pk is hidden
    }

    class OutcomeEnum(enum.Enum):
        NOT_FOUND = 0
        NOT_PAID = 1
        OK = 2
        ALREADY_FULFILLED = 3
        TICKET_ALREADY_EXISTS = 4

    Outcome = g.EnumType('RatioConfirmOrderOutcome', OutcomeEnum)

    # Returning a ticket here is a bad idea: this mutation is public, so we shouldn' expose private objects.
    # Ratio ticket is currently a private type for usage by internal APIs only.
    result = g.NN(
        g.ObjectType(
            'RatioConfirmOrderResult',
            g.fields({
                'outcome': g.NN(Outcome),
            }),
        ))
Ejemplo n.º 17
0
class kkmRegisterCheck(helpers.UnionFieldMixin, helpers.BaseFieldWithInput):
    def resolve(self, _, info, input):
        controller: models.Controller = models.Controller.load()
        result = controller.register_check(
            email=input['email'],
            title=input['title'],
            sum=input['sum'],
            sign_method_calculation=kkmserver.SignMethodCalculation[
                input['sign_method_calculation']],
        )

        # status values:
        # Ok = 0, Run(Запущено на выполнение) = 1, Error = 2, NotFound(устройство не найдено) = 3, NotRun = 4

        if result['Status'] == 0:
            return RegisterCheckOkResult(url=result['URL'])

        error = result.get('Error', 'Неизвестная ошибка')
        return kocherga.django.errors.GenericError(
            f"{error} (status: {result['Status']})")

    permissions = [user_perm('kkm.kkmserver')]
    input = {
        'email': str,
        'title': str,
        'sum': int,
        'sign_method_calculation': g.NN(types.KkmSignMethodCalculation),
    }

    OkResultType = g.ObjectType(
        'KkmRegisterCheckOkResult',
        g.fields({
            'url': str,
        }),
    )

    result_types = {
        RegisterCheckOkResult:
        OkResultType,
        kocherga.django.errors.GenericError:
        kocherga.django.schema.types.GenericError,
    }
Ejemplo n.º 18
0
def build_WagtailImage():
    def resolve_rendition(obj, info, spec):
        return obj.get_rendition(spec)

    return g.ObjectType(
        'WagtailImage',
        lambda: g.fields({
            'id':
            'ID!',
            'url':
            str,
            'width':
            int,
            'height':
            int,
            'rendition':
            g.Field(
                g.NN(WagtailImageRendition),
                args=g.arguments({'spec': str}),
                resolve=resolve_rendition,
            ),
        }),
    )
Ejemplo n.º 19
0
def settings_fields():
    # TODO - do we actually need such strict permissions? Maybe these settings should simply be public.
    # TODO - manage_events permission for telegram_images & other fields seems wrong and arbitrary.
    from kocherga.events.permissions import manage_events
    from kocherga.telegram.permissions import view_all_telegram_chats
    from kocherga.telegram.schema import types as telegram_types
    from kocherga.wagtail.schema import types as wagtail_types

    return g.fields({
        **{
            f: field_with_permissions(g.NN(wagtail_types.WagtailCollection),
                                      permissions=[manage_events])
            for f in [
                'default_events_images_collection',
                'default_events_vk_images_collection',
                'weekly_digest_images_collection',
                'telegram_images_collection',
            ]
        },
        'community_org_team_telegram_chat':
        field_with_permissions(telegram_types.TelegramChat,
                               permissions=[view_all_telegram_chats]),
    })
Ejemplo n.º 20
0
def block_to_types(
    t: Tuple[str, wagtail.core.blocks.Block],
    types_for_page_chooser: Dict[str, g.ObjectType] = {},
    rewrite_name=True,
):
    """Converts wagtail block tuple to the list of graphql types.

    Tuple should look like `('foo_block', blocks.CharBlock())`.
    This function returns a list of types because complex wagtail blocks can include StreamBlocks which can
    define new graphql types implementing WagtailBlock interface.
    """

    (name, block_type) = t

    # false `rewrite_name` is useful in recursion from block_to_gfield
    if rewrite_name:
        name = wagtail_to_graphql_block_name(name)

    extra_types = []

    def registrator(t: g.ObjectType):
        extra_types.append(t)

    value_field = block_to_gfield(name, block_type, registrator,
                                  types_for_page_chooser)

    return [
        g.ObjectType(
            name,
            interfaces=[types.WagtailBlock],
            fields=g.fields({
                'id': 'ID!',
                'value': value_field
            }),
        ),
        *extra_types,
    ]
Ejemplo n.º 21
0
import graphql
import kocherga.projects.models
import kocherga.wagtail.models
from kocherga.error import PublicError
from kocherga.graphql import django_utils, g, helpers
from kocherga.graphql.basic_types import BasicResult
from kocherga.graphql.permissions import authenticated

from ... import models, permissions
from ..types import Event

c = helpers.Collection()

EventUpdateResult = g.ObjectType(
    'EventUpdateResult', g.fields({
        'ok': Optional[bool],
        'event': g.NN(Event)
    }))


@c.class_field
class eventCreate(helpers.BaseFieldWithInput):
    def resolve(self, _, info, input):
        title = input['title']
        start = input['start']
        end = input['end']

        start = dateutil.parser.isoparse(start)
        end = dateutil.parser.isoparse(end)

        params = {
            'title': title,
Ejemplo n.º 22
0
from typing import Optional

from kocherga.graphql import g, helpers

from .event import Event

MyEventsTicket = g.ObjectType(
    'MyEventsTicket',
    g.fields({
        'id':
        g.Field(g.NN(g.ID), resolve=lambda obj, info: obj.event.uuid),
        'event':
        g.NN(Event),
        'status':
        str,
        'created':
        Optional[str],
        'zoom_link':
        Optional[str],
    }),
)

MyEventsTicketConnection = helpers.ConnectionType(MyEventsTicket)
Ejemplo n.º 23
0
    models.TildaPage,
    db_fields=[
        'id',
        'page_id',
        'path',
        'body',
        'title',
        'description',
        'show_header_and_footer',
    ],
    extra_fields=lambda: g.fields(
        {
            'og_image': wagtail_utils.image_rendition_field(
                models.TildaPage, 'og_image'
            ),
            'assets': g.Field(g.NNList(TildaAsset), resolve=resolve_assets),
            'css': g.Field(g.NNList(TildaAsset), resolve=resolve_css),
            'js': g.Field(g.NNList(TildaAsset), resolve=resolve_js),
            'imported_dt': imported_dt().as_field(),
        },
    ),
)


class imported_dt(helpers.BaseField):
    def resolve(self, obj, info):
        return obj.imported_dt

    permissions = [permissions.staffonly]
    result = str
Ejemplo n.º 24
0
from kocherga.graphql import g

from kocherga.auth.schema.types import AuthUser

EventsTicket = g.ObjectType(
    'EventsTicket',
    g.fields({
        'id': 'ID!',
        'status': str,
        'user': g.NN(AuthUser)
    }))
Ejemplo n.º 25
0
def build_event_fields():
    def description_field():
        def resolve(obj, info, format=None):
            # PLAIN is default for now, for backward-compatibility
            if format == 'PLAIN' or format is None:
                return markup.Markup(obj.description).as_plain()
            elif format == 'SOURCE' or format is None:
                return obj.description
            else:
                raise Exception(f"Unknown markup format {format}")

        args = g.arguments({'format': EventsMarkupFormat})
        return g.Field(g.NN(g.String), args=args, resolve=resolve)

    def resolve_public_tags(obj, info):
        return obj.public_tag_names()

    def tags_field():
        @check_permissions([permissions.manage_events])
        def resolve(obj, info):
            return obj.tag_names()

        return g.Field(g.NNList(g.String), resolve=resolve)

    def room_field():
        @check_permissions([permissions.manage_events])
        def resolve(obj, info):
            return obj.get_room()

        return g.Field(g.NN(g.String), resolve=resolve)

    def my_ticket_field():
        # note that there's no @auth decorator - we don't want any errors if user is not authenticated
        def resolve(obj, info):
            if not info.context.user.is_authenticated:
                return None  # not authorized, no ticket, but that's ok

            ticket = obj.tickets.filter(user=info.context.user).first()
            return ticket

        # lazy import - avoiding circular dependency
        from .my_ticket import MyEventsTicket

        return g.Field(MyEventsTicket, resolve=resolve)

    def announcements_field():
        from .announcements import EventsAnnouncements

        def resolve(obj, info):
            return {
                'timepad': getattr(obj, 'timepad_announcement', None),
                'vk': getattr(obj, 'vk_announcement', None),
                'fb': getattr(obj, 'fb_announcement', None),
            }

        return g.Field(g.NN(EventsAnnouncements), resolve=resolve)

    from .google_event import EventsGoogleEvent

    class public_google_event_field(helpers.BaseField):
        def resolve(self, obj, info):
            return obj.public_google_event()

        permissions = []
        result = EventsGoogleEvent

    from .feedback import EventsFeedback
    from .prototype import EventsPrototype
    from .ticket import EventsTicket
    from .youtube_video import EventsYoutubeVideo

    return g.fields({
        **django_utils.model_fields(
            models.Event,
            [
                'start',
                'end',
                'title',
                'summary',
                'registration_type',
                'pricing_type',
                'realm',
                'published',
                'event_type',
            ],
        ),
        'id':
        g.Field(g.NN(g.ID), resolve=lambda obj, info: obj.uuid),
        'event_id':
        g.Field(g.NN(g.ID), resolve=lambda obj, info: obj.uuid
                ),  # deprecated, use `id` instead
        'description':
        description_field(),
        'stream_body':
        g.NNList(WagtailBlock),
        'image':
        wagtail_utils.image_rendition_field(models.Event, 'image'),
        'project':
        ProjectPage,
        'public_tags':
        g.Field(g.NNList(g.String), resolve=resolve_public_tags),
        'announcements':
        announcements_field(),
        # signed-in fields
        'my_ticket':
        my_ticket_field(),
        # private fields
        'tags':
        tags_field(),
        'public_google_event':
        public_google_event_field().as_field(),
        'zoom_meeting':
        helpers.field_with_permissions(zoom_types.ZoomMeeting,
                                       [permissions.manage_events]),
        'prototype':
        helpers.field_with_permissions(EventsPrototype,
                                       [permissions.manage_events]),
        'visitors':
        helpers.field_with_permissions(g.String, [permissions.manage_events]),
        'creator':
        helpers.field_with_permissions(g.String, [permissions.manage_events]),
        'created':
        helpers.field_with_permissions(g.NN(g.String),
                                       [permissions.manage_events]),
        'updated':
        helpers.field_with_permissions(g.NN(g.String),
                                       [permissions.manage_events]),
        'location':
        helpers.field_with_permissions(g.NN(g.String),
                                       [permissions.manage_events]),
        'room':
        room_field(),
        'zoom_link':
        helpers.field_with_permissions(g.NN(g.String),
                                       [permissions.manage_events]),
        'timing_description_override':
        helpers.field_with_permissions(g.NN(g.String),
                                       [permissions.manage_events]),
        'tickets':
        django_utils.related_field(
            models.Event,
            'tickets',
            item_type=EventsTicket,
            permissions=[permissions.manage_events],
        ),
        'feedbacks':
        django_utils.related_field(
            models.Event,
            'feedbacks',
            item_type=EventsFeedback,
            permissions=[permissions.manage_events],
        ),
        'youtube_videos':
        django_utils.related_field(
            models.Event,
            'youtube_videos',
            item_type=EventsYoutubeVideo,
        ),
    })
Ejemplo n.º 26
0
 lambda: g.fields({
     'id':
     g.Field(g.NN(g.ID), resolve=lambda obj, info: obj.prototype_id),
     **django_utils.model_fields(
         models.EventPrototype,
         [
             'title',
             'summary',
             'description',
             'location',
             'timing_description_override',
             'active',
             'weekday',
             'hour',
             'minute',
             'length',
         ],
     ),
     'project':
     g.Field(ProjectPage),
     'tags':
     tags_field(),
     'image':
     wagtail_utils.image_rendition_field(models.EventPrototype, 'image'),
     'suggested_dates':
     suggested_dates_field(),
     'instances':
     instances_field(),
     'vk_group':
     vk_group_field(),
     'timepad_category':
     timepad_category_field(),
 }),
Ejemplo n.º 27
0
        fields={
            'errors':
            g.Field(
                g.NNList(ValidationErrorItem),
                resolve=resolve_errors,
            ),
        },
    )


ValidationError = build_ValidationError()

GenericError = g.ObjectType(
    'GenericError',
    fields=g.fields({
        'message': str,
    }),
)


def settings_fields():
    # TODO - do we actually need such strict permissions? Maybe these settings should simply be public.
    # TODO - manage_events permission for telegram_images & other fields seems wrong and arbitrary.
    from kocherga.events.permissions import manage_events
    from kocherga.telegram.permissions import view_all_telegram_chats
    from kocherga.telegram.schema import types as telegram_types
    from kocherga.wagtail.schema import types as wagtail_types

    return g.fields({
        **{
            f: field_with_permissions(g.NN(wagtail_types.WagtailCollection),
Ejemplo n.º 28
0
from typing import Optional
from kocherga.graphql import g, helpers
from kocherga.graphql.permissions import authenticated

from .. import models

c = helpers.Collection()

MyEmailSubscriptionInterest = g.ObjectType(
    'MyEmailSubscriptionInterest',
    g.fields({
        'id': 'ID!',
        'name': str,
        'subscribed': Optional[bool]
    }),
)

MyEmailSubscription = g.ObjectType(
    'MyEmailSubscription',
    g.fields({
        'status': str,
        'interests': g.List(g.NN(MyEmailSubscriptionInterest))
    }),
)


@c.class_field
class email_subscription(helpers.BaseField):
    def resolve(self, _, info):
        subscription = models.MailchimpMember.get_from_mailchimp(
            info.context.user.email)
Ejemplo n.º 29
0
from kocherga.graphql import g, django_utils
from kocherga.wagtail import graphql_utils as wagtail_utils

from kocherga.wagtail.schema.types import WagtailPage

from .. import models

FaqEntry = g.ObjectType(
    'FaqEntry',
    g.fields({
        **django_utils.model_fields(models.Entry, ['id', 'question']),
        'answer':
        wagtail_utils.richtext_field(models.Entry, 'answer'),
    }),
)

FaqPage = g.ObjectType(
    'FaqPage',
    interfaces=[WagtailPage],
    fields=lambda: g.fields({
        **wagtail_utils.basic_fields(),
        **django_utils.model_fields(models.FAQPage, ['title', 'summary']),
        'prev_page':
        FaqPage,
        'next_page':
        FaqPage,
        'entries':
        django_utils.related_field(
            models.FAQPage, 'entries', item_type=FaqEntry),
        'subpages':
        g.NNList(FaqPage),
Ejemplo n.º 30
0
import logging

from asgiref.sync import sync_to_async

logger = logging.getLogger(__name__)

from kocherga.graphql import g, helpers
from kocherga.graphql.permissions import check_permissions

from .. import permissions, channels

c = helpers.Collection()

WatchmenScheduleUpdateNotification = g.ObjectType(
    'WatchmenScheduleUpdateNotification', g.fields({'updated': bool}))


@c.field
def watchmenScheduleUpdates(_):
    async def subscribe(obj, info):
        # check permissions
        await sync_to_async(permissions.manage_watchmen,
                            thread_sensitive=True)(obj, info)

        async for msg in channels.watchmen_updates_group.subscribe():
            logger.info('yielding True')
            yield True

    @check_permissions([permissions.manage_watchmen])
    def resolve(msg, info):
        logger.info('returning updated')