def getSessionsBySpeaker(self, request):
        """Given a speaker, return all sessions given by this particular speaker, across all conferences"""

        # get speaker (to check if it exists
        speaker = ndb.Key(ConfSpeaker, request.speakerDisplayName).get()

        if not speaker:
            raise endpoints.NotFoundException(
                'No speaker found with speakerDisplayName: %s' % request.speakerDisplayName)

        # create ancestor query for all key matches for this conference
        sessions = ConfSession.query()

        # filter by type of session
        sessions = sessions.filter(ConfSession.speakerId==speaker.key.id())

        # get speakers
        speakers = [ndb.Key(ConfSpeaker, sess.speakerId) for sess in sessions]
        profiles = ndb.get_multi(speakers)

        # put display names in a dict for easier fetching
        names = {}
        for profile in profiles:
            names[profile.key.id()] = profile.displayName

        # return set of SessionForm objects
        return ConfSessionForms(
            items=[self._copySessionToForm(sess, names[sess.speakerId]) for sess in sessions]
        )
    def getProblemQuerySolution2(self, request):
        """Return all non-workshop sessions before 7 pm. (splitting the query with IN operator)"""

        sessionTypes = [str(e) for e in ConfSessionType]
        sessionTypes.remove(str(ConfSessionType.WORKSHOP))

        sessions = ConfSession.query().filter(ConfSession.typeOfSession.IN(sessionTypes))

        t = time(19, 0, 0)

        sessions = sessions.filter(ConfSession.start_time < t)

        # get speakers
        speakers = [ndb.Key(ConfSpeaker, sess.speakerId) for sess in sessions]
        profiles = ndb.get_multi(speakers)

        # put display names in a dict for easier fetching
        names = {}
        for profile in profiles:
            names[profile.key.id()] = profile.displayName

        # return set of SessionForm objects
        return ConfSessionForms(
            items=[self._copySessionToForm(sess, names[sess.speakerId]) for sess in sessions]
        )
    def getConferenceSessionsByType(self, request):
        """Given a conference, return all sessions of a specified type"""

        conf = ndb.Key(urlsafe=request.websafeConferenceKey).get()
        if not conf:
            raise endpoints.NotFoundException(
                'No conference found with key: %s' % request.websafeConferenceKey)

        # create ancestor query for all key matches for this conference
        sessions = ConfSession.query(ancestor=conf.key)

        # filter by type of session
        sessions = sessions.filter(ConfSession.typeOfSession==str(request.typeOfSession))

        # get speakers
        speakers = [ndb.Key(ConfSpeaker, sess.speakerId) for sess in sessions]
        profiles = ndb.get_multi(speakers)

        # put display names in a dict for easier fetching
        names = {}
        for profile in profiles:
            names[profile.key.id()] = profile.displayName

        # return set of SessionForm objects
        return ConfSessionForms(
            items=[self._copySessionToForm(sess, names[sess.speakerId]) for sess in sessions]
        )
    def _cacheFeatured(speakerKey, conferenceKey):
        """Create Featured speaker & assign to memcache.
        """

        conf = ndb.Key(urlsafe=conferenceKey).get()
        speaker = ndb.Key(urlsafe=speakerKey).get()

        updateCache = False

        if conf and speaker:
            sessions = ConfSession.query(ancestor=conf.key)
            sessions = sessions.filter(ConfSession.speakerId==speaker.key.id())
            updateCache = True

        if updateCache and sessions:
            # If there is a featured speaker
            # format announcement and set it in memcache
            announcement = FEATURED_SPEAKER_TPL % (speaker.displayName,
                ', '.join(sess.name for sess in sessions), conf.name)
            memcache.set(MEMCACHE_FEATUREDMSG_KEY, announcement)
        else:
            # If there is no a featured speaker
            # delete the memcache announcements entry
            announcement = ""
            memcache.delete(MEMCACHE_FEATUREDMSG_KEY)

        return announcement
    def additionalQuery2(self, request):
        """List of Users attended a conference, but didn't wishlisted a session of that conference"""
        conf = ndb.Key(urlsafe=request.websafeConferenceKey).get()

        if not conf:
            raise endpoints.NotFoundException(
                'No conference found with key: %s' % request.websafeConferenceKey)

        profiles = Profile.query(Profile.conferenceKeysToAttend.IN([request.websafeConferenceKey]))

        # get sessions for the conference
        sessions = ConfSession.query(ancestor=conf.key)

        # add the session filters
        for sess in sessions:
            profiles = profiles.filter(Profile.sessionWishlist!=sess.key.urlsafe())

        return ProfileListForm(
            items=[self._copyProfileMiniToForm(prof) for prof in profiles]
        )
    def getProblemQuerySolution1(self, request):
        """Return all non-workshop sessions before 7 pm. (using filter function of python)"""

        sessions = ConfSession.query().filter(ConfSession.typeOfSession != str(ConfSessionType.WORKSHOP))

        t = time(19, 0, 0)

        sessions = list(filter((lambda sess: sess.start_time < t), sessions))

        # get speakers
        speakers = [ndb.Key(ConfSpeaker, sess.speakerId) for sess in sessions]
        profiles = ndb.get_multi(speakers)

        # put display names in a dict for easier fetching
        names = {}
        for profile in profiles:
            names[profile.key.id()] = profile.displayName

        # return set of SessionForm objects
        return ConfSessionForms(
            items=[self._copySessionToForm(sess, names[sess.speakerId]) for sess in sessions]
        )
    def _createSessionObject(self, request):
        """Create Session object, returning SessionForm/request."""
        # preload necessary data items

        user = endpoints.get_current_user()
        if not user:
            raise endpoints.UnauthorizedException('Authorization required')

        conf = ndb.Key(urlsafe=request.websafeConferenceKey).get()
        if not conf:
            raise endpoints.NotFoundException(
                'No conference found with key: %s' % request.websafeConferenceKey)

        user_id = getUserId(user)

        if conf.organizerUserId != user_id:
            raise endpoints.UnauthorizedException('You can only create sessions for your conferences')

        if not request.name:
            raise endpoints.BadRequestException("Session 'name' field required")

        # copy SessionForm/ProtoRPC Message into dict
        data = {field.name: getattr(request, field.name) for field in request.all_fields()}

        # add default values for those missing (both data model & outbound Message)
        for df in SESS_DEFAULTS:
            if data[df] in (None, []):
                data[df] = SESS_DEFAULTS[df]
                setattr(request, df, SESS_DEFAULTS[df])

        # convert dates from strings to Date/Time objects
        if data['duration']:
            data['duration'] = datetime.strptime(data['duration'][:5], "%H:%M").time()

        if data['start_time']:
            data['start_time'] = datetime.strptime(data['start_time'][:5], "%H:%M").time()

        if data['date']:
            data['date'] = datetime.strptime(data['date'][:10], "%Y-%m-%d").date()

        speaker = self._getSpeakerFromName(data['speakerDisplayName'])

        # generate Session Key based on conference ID
        p_key = conf.key
        c_id = ConfSession.allocate_ids(size=1, parent=p_key)[0]
        c_key = ndb.Key(ConfSession, c_id, parent=p_key)
        data['key'] = c_key
        data['speakerId'] = request.speakerId = speaker.key.id()

        if not data['typeOfSession']:
            data['typeOfSession'] = str(ConfSessionType.NOT_SPECIFIED)

        data['typeOfSession'] = str(data['typeOfSession'])
        del data['websafeKey']
        del data['speakerDisplayName']
        del data['websafeConferenceKey']

        # create Session
        ConfSession(**data).put()

        # append to speaker sessions
        speaker.confSessionKeysToAttend.append(c_key)

        # sessions of this speaker and this conference (using filter .ancestor)
        sessionsInThisConf = ConfSession.query(ancestor=conf.key)
        sessionsInThisConf = sessionsInThisConf.filter(ConfSession.speakerId==speaker.key.id())

        if sessionsInThisConf.count(2)>1:
            taskqueue.add(params={'speakerKey': speaker.key.urlsafe(),
                'conferenceKey': request.websafeConferenceKey},
                url='/tasks/set_featured_speaker'
            )

        return self._copySessionToForm(c_key.get(), speaker.displayName)