class OAuthSignIn(Display):
    """ Initial oauth sign in page. First leg of 3 legged oauth. """
    link_info = Display.LinkInfo(lambda link: lambda: link, '/oauth/sign_in')

    def __init__(self, application, consumerToken, consumerSecret):
        Display.__init__(self,
                         application,
                         pageRoute=('/oauth/sign_in', None),
                         webSocketManagers=None)
        assert isinstance(application, WebApplicationTwitter)
        self.consumer_token = consumerToken
        self.consumer_secret = consumerSecret

    @property
    def page_html_function(self):
        def func(templateArguments):
            oauth = OAuth1(self.consumer_token,
                           client_secret=self.consumer_secret)
            response = requests.post(
                'https://api.twitter.com/oauth/request_token',
                params={'oauth_callback': OAuthCallback.link_info.page_link},
                auth=oauth)
            if not response.ok:
                return redirect_problem(
                    'Failed to retrieve oauth_token from twitter: %s' %
                    response.text)

            qs = parse_qs(response.text)
            oauth_token = qs['oauth_token'][0]

            return redirect(
                'https://api.twitter.com/oauth/authenticate?oauth_token=%s' %
                oauth_token)

        return func
Beispiel #2
0
class UserFollowerEnrichPage(Display):
    link_info = Display.LinkInfo(
        lambda link: lambda instance, user: link % (instance, user),
        '/instance/%s/user_follower_enrich/%d')

    def __init__(self, application, dataCollection,
                 followerExtractorGateThread):
        Display.__init__(
            self,
            application,
            pageRoute=('/instance/<instance>/user_follower_enrich/<user:int>',
                       None),
            webSocketManagers=None,
            onDisplayUsageFunc=onDisplayUsageFunc)
        assert isinstance(dataCollection, DataCollection)
        assert isinstance(followerExtractorGateThread,
                          FollowerExtractorGateThread)

        self.data_collection = dataCollection
        self.follower_extractor_gate_thread = followerExtractorGateThread

    @property
    def page_html_function(self):
        def func(templateArguments, instance, user):
            try:
                twitterInstance = self.application.twitter_instances.getInstanceByInstanceKey(
                    instance)
                if twitterInstance is None:
                    abort(404, "No active search stream found at this address")

                # We need name and followers count for the progress bar.
                userObject = self.data_collection.getUser(
                    instance, user,
                    twitterInstance.twitter_thread.twitter_session, False,
                    UserProjection.Geocode(
                        True, UserDataProjection(['name', 'followers_count'])))
                if not userObject:
                    abort(404, "No user found at this address")

                assert isinstance(userObject, User)
                if not self.follower_extractor_gate_thread.addUser(
                        userObject, restrictInfluenceArea=False):
                    logger.warn(
                        'Not processed user: %s/%d for enrichment - shouldProcessUser returned false'
                        % (instance, user))

            except KeyError:
                logger.warn(
                    'Follower information enrich request received for user which does not exist: %s/%d'
                    % (instance, user))

            return redirect(
                UserInformationPage.link_info.getPageLink(instance, user))

        return func
Beispiel #3
0
class ManageInstancePost(Display):
    """ Post operation on manage instance means terminate that instance. """
    link_info = Display.LinkInfo(lambda link: lambda: link, '/manage_instance')

    def __init__(self, application):
        Display.__init__(self,
                         application,
                         pageRoute=('/manage_instance', ['POST']),
                         webSocketManagers=None)
        assert isinstance(application, WebApplicationTwitter)

    @property
    def page_html_function(self):
        def func(templateArguments):
            oauth_token = request.forms.get('oauth_token')
            oauth_secret = request.forms.get('oauth_secret')

            oauth = TwitterInstance.makeAuthTuple(oauth_token, oauth_secret)
            removedInstance = self.application.twitter_instances.removeTwitterInstanceByAuth(
                oauth)

            if removedInstance is not None:
                assert isinstance(removedInstance, TwitterInstance)

                logger.info('Cleaned up twitter instance with oauth: %s' %
                            unicode(oauth))

                try:
                    keywords = ','.join(
                        removedInstance.twitter_thread.twitter_feed.keywords)
                except TypeError:
                    keywords = ''

                regions = removedInstance.geographic_setup_string
                instanceSetupCode = removedInstance.instance_setup_code
            else:
                keywords = None
                regions = None
                instanceSetupCode = None

            return redirect(
                Display.addArgumentsToLink(
                    GateInstance.link_info.getPageLink(),
                    oauth_token=oauth_token,
                    oauth_secret=oauth_secret,
                    keywords=keywords,
                    regions=regions,
                    instance_setup_code=instanceSetupCode))

        return func
Beispiel #4
0
class UserInformationPage(Display):
    link_info = Display.LinkInfo(
        lambda link: lambda instance, user: link % (instance, user),
        '/instance/%s/user/%d')

    @staticmethod
    def getPageLinkImage(instance, user, target):
        assert isinstance(user, User)
        imageHtml = Display.getImage(user.profile_image_url,
                                     user.name,
                                     None,
                                     className='twitter-profile-image')

        return Display.getLink(UserInformationPage.link_info.getPageLink(
            instance, user.id),
                               imageHtml,
                               target=target)

    def __init__(self, application, userInformationWebSocketGroup):
        Display.__init__(self,
                         application,
                         pageRoute=('/instance/<instance>/user/<user:int>',
                                    None),
                         webSocketManagers=[userInformationWebSocketGroup],
                         onDisplayUsageFunc=onDisplayUsageFunc)

    @property
    def page_html_function(self):
        def func(templateArguments, instance, user):
            twitterInstance = self.application.twitter_instances.getInstanceByInstanceKey(
                instance)
            if twitterInstance is None:
                abort(404, "No active search stream found at this address")

            instanceDescription = getInstanceDescription(twitterInstance, True)
            instanceLink = getInstanceLink(twitterInstance)
            homeLink = getHomeLink(Configuration.PROJECT_NAME)

            templateArguments.update({
                'home_link': homeLink,
                'instance': instance,
                'instance_description': instanceDescription,
                'instance_link': instanceLink,
                'user_id': user
            })
            return template('user.tpl', templateArguments)

        return func
class OAuthCallback(Display):
    """ Final stage of authorisation, twitter redirects here. """
    link_info = Display.LinkInfo(lambda link: lambda: link, '/oauth/callback')

    def __init__(self, application, consumerToken, consumerSecret,
                 callbackLink):
        Display.__init__(self,
                         application,
                         pageRoute=('/oauth/callback', None),
                         webSocketManagers=None)
        assert isinstance(application, WebApplicationTwitter)
        self.consumer_token = consumerToken
        self.consumer_secret = consumerSecret
        self.callback_link = callbackLink

    @property
    def page_html_function(self):
        def func(templateArguments):
            oauth_token = request.GET.oauth_token
            oauth_secret = request.GET.oauth_token_secret
            oauth_verifier = request.GET.oauth_verifier

            oauth = OAuth1(self.consumer_token,
                           client_secret=self.consumer_secret,
                           resource_owner_key=oauth_token,
                           resource_owner_secret=oauth_secret,
                           verifier=oauth_verifier)
            response = requests.post(
                'https://api.twitter.com/oauth/access_token', auth=oauth)
            if not response.ok:
                return redirect_problem(
                    'Failed to retrieve oauth_secret from twitter')

            response = parse_qs(response.content)
            final_token = response['oauth_token'][0]
            final_token_secret = response['oauth_token_secret'][0]

            logger.info('oauth_token: %s, oauth_secret: %s received' %
                        (final_token, final_token_secret))

            return redirect(
                Display.addArgumentsToLink(self.callback_link,
                                           oauth_token=final_token,
                                           oauth_secret=final_token_secret))

        return func
Beispiel #6
0
class GeocodeCachePage(Display):
    link_info = Display.LinkInfo(lambda link: lambda: link, '/geocode_search')

    def __init__(self, application, providerId):
        Display.__init__(self,
                         application,
                         pageRoute=('/geocode_search', None),
                         webSocketManagers=None)

        self.provider_id = providerId

    @property
    def page_html_function(self):
        def func(templateArguments):
            placeName = parseString(request.GET.place_name)

            data = list()

            if placeName is None:
                return {'json': data}

            locations = list()
            maxLocations = 10

            locations += GeocodeResultAbstract.searchGnsByName(placeName, 3)
            maxLocations -= len(locations)

            if maxLocations > 0:
                newLocations = geocodeSearch(self.provider_id, placeName,
                                             maxLocations)
                maxLocations -= len(newLocations)
                locations += newLocations

            for location in locations:
                assert isinstance(location, GeocodeResultAbstract)
                data.append((location.cache_id, location.bounding_box,
                             location.coordinate, location.display_name))

            return {'json': data}

        return func
Beispiel #7
0
class BulkDownloadDataProvider(AsyncTunnelProviderFile):
    link_info = Display.LinkInfo(
        lambda link: lambda instanceId, socketId, tunnelId: link %
        (instanceId, socketId, tunnelId),
        '/instance/%s/bulk_download_provider/%d/%s')

    def __init__(self, application):
        super(BulkDownloadDataProvider, self).__init__(
            application,
            pageRoute=
            ('/instance/<instance>/bulk_download_provider/<socket_id:int>/<tunnel_id>',
             None),
            onDisplayUsageFunc=onDisplayUsageFunc)

    def getFileName(self, tunnelId):
        if tunnelId == 'tweet_tunnel':
            return 'Tweets_' + getDateTime()
        else:
            return 'Users_' + getDateTime()

    def getFileExtension(self, tunnelId):
        return 'csv'
Beispiel #8
0
class LocationsPage(Display):
    link_info = Display.LinkInfo(
        lambda link: lambda instance, location, providerId: link %
        (instance, location, providerId), '/instance/%s/location/%d/%d/page')

    def __init__(self, application, tweetByLocationWebSocketGroup,
                 dataDownloadWebSocketManager, realtimePerformance):
        Display.__init__(
            self,
            application,
            pageRoute=
            ('/instance/<instance>/location/<location:int>/<provider:int>/page',
             None),
            webSocketManagers=[
                tweetByLocationWebSocketGroup,
                (dataDownloadWebSocketManager, False),
                (realtimePerformance, False)
            ],
            onDisplayUsageFunc=onDisplayUsageFunc)

    @property
    def page_html_function(self):
        def func(templateArguments, instance, location, provider):
            twitterInstance = self.application.twitter_instances.getInstanceByInstanceKey(
                instance)
            if twitterInstance is None:
                abort(404, "No active search stream found at this address")

            geocode = geocodeFromCacheById(
                GeocodeResultAbstract.buildCacheId(provider, location))
            assert geocode is not None

            instanceDescription = getInstanceDescription(twitterInstance)
            instanceLink = getInstanceLink(twitterInstance)

            homeLink = getHomeLink(Configuration.PROJECT_NAME)

            templateArguments.update(
                {
                    'home_link': homeLink,
                    'instance': instance,
                    'location': location,
                    'provider': provider,
                    'instance_link': instanceLink,
                    'instance_description': instanceDescription,
                    'place': geocode.display_name_short,
                    'place_coord': geocode.coordinate,
                    'startEpoch': twitterInstance.constructed_at,
                    'server_current_epoch': getEpochMs(),
                    'max_tweets': Configuration.MAX_CLIENT_LIVE_TWEETS
                }
            )  # Client needs to offset to this epoch in case its clock is wrong.

            if geocode.has_bounding_box:
                templateArguments.update(
                    {'place_bounding_box': geocode.bounding_box})

            if geocode.has_country:
                templateArguments.update({
                    'place_country_link':
                    LocationsPage.link_info.getPageLink(
                        instance, geocode.country.place_id,
                        geocode.country.provider_id)
                })
                templateArguments.update(
                    {'place_country': geocode.country.display_name_short})

            if geocode.has_continent:
                templateArguments.update({
                    'place_continent_link':
                    LocationsPage.link_info.getPageLink(
                        instance, geocode.continent.place_id,
                        geocode.continent.provider_id)
                })
                templateArguments.update(
                    {'place_continent': geocode.continent.display_name_short})

            return template('location.tpl', templateArguments)

        return func
Beispiel #9
0
class LocationsMapPage(Display):
    link_info = Display.LinkInfo(lambda link: lambda instance: link % instance,
                                 '/instance/%s')

    def __init__(self, application, mapWebSocketGroup,
                 dataDownloadWebSocketManager,
                 realTimePerformanceWebSocketGroup):
        assert isinstance(application, WebApplicationTwitter)

        Display.__init__(self,
                         application,
                         pageRoute=('/instance/<instance>', None),
                         webSocketManagers=[
                             mapWebSocketGroup, dataDownloadWebSocketManager,
                             realTimePerformanceWebSocketGroup
                         ],
                         onDisplayUsageFunc=onDisplayUsageFunc)
        self.locations = set()

    @property
    def page_html_function(self):
        def func(templateArguments, instance):
            instance = self.application.twitter_instances.getInstanceByInstanceKey(
                instance)
            if instance is None:
                abort(404, "No active search stream found at this address")

            assert isinstance(instance, TwitterInstance)

            keywords = instance.twitter_thread.twitter_feed.keywords
            geographicalSetupString = instance.geographic_setup_string

            if keywords is None:
                keywords = ''
                keywordsDisplay = '[None]'
            else:
                keywords = ','.join(keywords)
                keywordsDisplay = keywords

            instanceDescription = getInstanceDescription(instance, False)
            instanceDescriptionWithPrefix = getInstanceDescription(
                instance, True)

            homeLink = getHomeLink(Configuration.PROJECT_NAME)

            templateArguments.update({
                'instance_description':
                instanceDescription,
                'instance_description_with_prefix':
                instanceDescriptionWithPrefix,
                'home_link':
                homeLink,
                'instance_name':
                instance.instance_key,
                'keywords':
                keywords,
                'keywords_display':
                keywordsDisplay,
                'instance_map_data':
                geographicalSetupString,
                'post_address':
                WEBSITE_ROOT_HTTP +
                '/manage_instance',  # for terminate instance button.
                'login_address':
                OAuthSignIn.link_info.getPageLink(),
                'start_epoch':
                instance.constructed_at,
                'server_current_epoch':
                getEpochMs()
            })

            return template('locations-map.tpl', templateArguments)

        return func
Beispiel #10
0
class LandingPage(Display):
    link_info = Display.LinkInfo(lambda link: lambda: link, '/')

    def __init__(self, application):
        Display.__init__(self,
                         application,
                         pageRoute=('/', None),
                         webSocketManagers=None)

    @staticmethod
    def getLandingPageLink(pageNum):
        return Display.addArgumentsToLink(LandingPage.link_info.getPageLink(),
                                          page=pageNum)

    def getHumanTime(self, milliseconds):
        seconds = milliseconds / 1000
        if seconds < 60:
            if seconds == 1:
                return "1 second"

            return "%d seconds" % seconds

        minutes = seconds / 60
        if minutes < 60:
            if minutes == 1:
                return "1 minute"

            return "%d minutes" % minutes

        hours = minutes / 60
        if hours < 24:
            if hours == 1:
                return "1 hour"

            return "%d hours" % hours

        days = hours / 24
        if days == 1:
            return "1 day"

        return "%d days" % days

    @property
    def page_html_function(self):
        def func(templateArguments):
            argList = list()
            instanceList = self.application.twitter_instances.getInstanceList()

            # todo remove this, this generates more instances for debugging.
            # if len(instanceList) > 0:
            #    count = 0
            #    while count < 7:
            #        instanceList.append(instanceList[0])
            #        count += 1
            # todo end of remove this.

            numInstances = len(instanceList)

            numInstancesPerPage = Configuration.NUM_LANDING_PAGE_INSTANCES_PER_PAGE

            if numInstances > 3 or numInstances < 1:
                numInstancesPerRow = Configuration.NUM_LANDING_PAGE_INSTANCES_PER_ROW
            else:
                numInstancesPerRow = numInstances

            thumbnailSpan = 12 / numInstancesPerRow
            pageNum = parseInteger(request.GET.page, 0, numInstances, 0)
            startIndex = numInstancesPerPage * pageNum
            endIndex = startIndex + numInstancesPerPage
            numPages = int(
                ceil(float(numInstances) / float(numInstancesPerPage)))

            for instance in instanceList[startIndex:endIndex]:
                assert isinstance(instance, TwitterInstance)
                argList.append((LocationsMapPage.link_info.getPageLink(
                    instance.instance_key), instance.getShortDescription(True),
                                instance.geographic_setup_string))

            # Split into rows.
            argList = splitList(argList, numInstancesPerRow)
            templateArguments.update({'instances': argList})

            # Pagination
            startSmallPageIndex = pageNum - 5
            endSmallPageIndex = 0
            if startSmallPageIndex < 0:
                endSmallPageIndex -= startSmallPageIndex
                startSmallPageIndex = 0

            endSmallPageIndex += (pageNum + 5)
            offEndBy = endSmallPageIndex - numPages
            if offEndBy > 0:
                startSmallPageIndex -= offEndBy
                if startSmallPageIndex < 0:
                    startSmallPageIndex = 0

                endSmallPageIndex = numPages

            pagination = list()
            for n in range(startSmallPageIndex, endSmallPageIndex):
                isCurrentPage = pageNum == n
                pagination.append(
                    (n + 1, LandingPage.getLandingPageLink(n), isCurrentPage))

            step = (numPages - endSmallPageIndex) / 5
            if step > 0:
                for n in range(endSmallPageIndex, numPages, step):
                    pagination.append(
                        (n + 1, LandingPage.getLandingPageLink(n), False))

            if pageNum < numPages - 1:
                templateArguments.update({
                    'pagination_next':
                    LandingPage.getLandingPageLink(pageNum + 1)
                })

            if pageNum > 0:
                templateArguments.update({
                    'pagination_previous':
                    LandingPage.getLandingPageLink(pageNum - 1)
                })

            maxInactiveTime = Configuration.MAX_INSTANCE_INACTIVE_TIME_MS
            maxTotalTime = Configuration.MAX_INSTANCE_TOTAL_AGE_MS

            templateArguments.update({
                'pagination':
                pagination,
                'thumbnail_span':
                thumbnailSpan,
                'build_instance_link':
                OAuthSignIn.link_info.getPageLink(),
                'maxInactiveTime':
                self.getHumanTime(maxInactiveTime),
                'maxTotalTime':
                self.getHumanTime(maxTotalTime)
            })

            return template('landing-page.tpl', templateArguments)

        return func
Beispiel #11
0
class InfluenceCachePage(Display):
    link_info = Display.LinkInfo(lambda link: lambda instance: link % instance,
                                 '/instance/%s/influence')

    def __init__(self, application):
        Display.__init__(self,
                         application,
                         pageRoute=('/instance/<instance>/influence', None),
                         webSocketManagers=None,
                         onDisplayUsageFunc=onDisplayUsageFunc)

    @property
    def page_html_function(self):
        def func(templateArguments, instance):
            twitterInstance = self.application.twitter_instances.getInstanceByInstanceKey(
                instance)
            if twitterInstance is None:
                return dict()

            baseEpoch = twitterInstance.constructed_at

            start_epoch = parseInteger(request.GET.start_epoch, default=None)
            end_epoch = parseInteger(request.GET.end_epoch, default=None)
            source_place_id = parseInteger(request.GET.source_place_id)
            source_provider_id = parseInteger(request.GET.source_provider_id)

            if source_place_id is None:
                logger.error(
                    'Invalid place ID specified while providing influence data: %s'
                    % unicode(source_place_id))
                return dict()

            source_cache_id = GeocodeResultAbstract.buildCacheId(
                source_provider_id, source_place_id)

            temporalCollection = getTemporalInfluenceCollection(instance)

            if start_epoch is not None:
                start_time_id = getTimeIdFromTimestamp(
                    baseEpoch, Configuration.TEMPORAL_STEP, start_epoch)
            else:
                start_time_id = None

            if end_epoch is not None:
                end_time_id = getTimeIdFromTimestamp(
                    baseEpoch, Configuration.TEMPORAL_STEP, end_epoch)
            else:
                end_time_id = None

            timerMs = getEpochMs()
            cacheData = getTemporalRange(temporalCollection,
                                         start_time_id,
                                         end_time_id,
                                         source_cache_id,
                                         preciseFromBack=True,
                                         preciseFromFront=True)
            logger.info('Took %dms to read temporal range data' %
                        (getEpochMs() - timerMs))

            timerMs = getEpochMs()

            geocodeByPlaceType = dict()
            totalsByPlaceType = dict()

            if cacheData is not None:
                for providerId, providerIdData in cacheData.iteritems():
                    providerId = int(providerId)

                    for destination, count in providerIdData.iteritems():
                        split = destination.split('_')
                        placeType = int(split[0])
                        placeId = int(split[1])

                        record = [placeId, providerId, None, None, count, None]

                        geocodeByPlaceType.setdefault(placeType,
                                                      list()).append(record)

                # Process only the records we are going to display.
                for placeType, records in geocodeByPlaceType.iteritems():
                    aux = sorted(records, key=lambda x: x[4], reverse=True)
                    aux = aux[:Configuration.
                              DISPLAY_MAX_NUM_INFLUENCE_RECORDS_PER_PLACE_TYPE]
                    geocodeByPlaceType[placeType] = aux

                    for record in aux:
                        cacheId = GeocodeResultAbstract.buildCacheId(
                            record[1], record[0])
                        geocode = geocodeFromCacheById(cacheId)

                        record[2] = geocode.display_name
                        record[3] = geocode.coordinate
                        count = record[4]
                        record[5] = geocode.bounding_box

                        totalsByPlaceType[placeType] = totalsByPlaceType.get(
                            placeType, 0) + count

            def getResultPart(placeType):
                return {
                    'geocode_list': geocodeByPlaceType.get(placeType, list()),
                    'total': totalsByPlaceType.get(placeType, 0)
                }

            resultData = dict()
            resultData['city'] = getResultPart(
                GeocodeResultAbstract.PlaceTypes.CITY)
            resultData['country'] = getResultPart(
                GeocodeResultAbstract.PlaceTypes.COUNTRY)
            resultData['continent'] = getResultPart(
                GeocodeResultAbstract.PlaceTypes.CONTINENT)

            logger.info('Took %dms to build temporal range result data' %
                        (getEpochMs() - timerMs))

            return {'json': resultData}

        return func
Beispiel #12
0
class TwitterCachePage(Display):
    link_info = Display.LinkInfo(lambda link: lambda instance: link % instance,
                                 '/instance/%s/cached_tweets')

    PAGE_SIZE_ID_NAME_DATA = 80
    PAGE_SIZE_FULL_DATA = 10

    def __init__(self, application):
        Display.__init__(self,
                         application,
                         pageRoute=('/instance/<instance>/cached_tweets',
                                    None),
                         webSocketManagers=None,
                         onDisplayUsageFunc=onDisplayUsageFunc)

    @property
    def page_html_function(self):
        def func(templateArguments, instance):
            dataType = parseString(request.GET.type, ['tweet', 'user'])
            start_epoch = parseInteger(request.GET.start_epoch)
            end_epoch = parseInteger(request.GET.end_epoch)
            page_num = parseInteger(request.GET.page)
            place_id = parseInteger(request.GET.place_id)
            provider_id = parseInteger(request.GET.provider_id)
            projection_type = parseString(request.GET.projection_type)
            followee = parseInteger(request.GET.followee)

            cache_id = GeocodeResultAbstract.buildCacheId(
                provider_id, place_id)

            if dataType is None:
                return redirect_problem('type is a required argument')

            if page_num is None:
                page_num = 0

            data = []
            if dataType == 'tweet':
                tweets = readTweetsFromCache(
                    None, instance, cache_id, start_epoch, end_epoch, page_num,
                    TwitterCachePage.PAGE_SIZE_FULL_DATA)
                if tweets is not None:
                    for tweet in tweets:
                        assert isinstance(tweet, Tweet)
                        userHtml = UserInformationPage.getPageLinkImage(
                            instance, tweet.user, target='_self')

                        data.append([
                            tweet.created_at, userHtml,
                            tweet.user.location_text, tweet.text
                        ])

            elif dataType == 'user':
                if len(projection_type) == 0:
                    projection = None
                    pageSize = TwitterCachePage.PAGE_SIZE_FULL_DATA
                elif projection_type == 'name-only':
                    projection = UserProjection.IdNameImage()
                    pageSize = TwitterCachePage.PAGE_SIZE_ID_NAME_DATA
                else:
                    return redirect_problem('Unsupported projection type: %s' %
                                            projection_type)

                if followee is None:
                    return redirect_problem('Followee is required')

                users = readUsersFromCache(None,
                                           instance,
                                           cache_id,
                                           start_epoch,
                                           end_epoch,
                                           page_num,
                                           pageSize,
                                           followee,
                                           userProjection=projection)
                if users is not None:
                    for user in users:
                        assert isinstance(user, User)
                        data.append([
                            user.id, user.name, user.profile_image_url,
                            UserInformationPage.link_info.getPageLink(
                                instance, user.id)
                        ])

            return {'json': data}

        return func
Beispiel #13
0
class StartInstancePost(Display):
    """ Post operation to start a new instance. """
    link_info = Display.LinkInfo(lambda link: lambda: link, '/start_instance')

    def __init__(self,
                 application,
                 consumerToken,
                 consumerSecret,
                 initialData=None):
        Display.__init__(self,
                         application,
                         pageRoute=('/start_instance', ['POST']),
                         webSocketManagers=None)
        assert isinstance(application, WebApplicationTwitter)

        self.consumer_token = consumerToken
        self.consumer_secret = consumerSecret
        self.initial_data = initialData

    @property
    def page_html_function(self):
        def func(templateArguments):
            form = request.forms.decode('UTF-8')

            oauth_token = form.get('oauth_token')
            oauth_secret = form.get('oauth_secret')
            keywords = form.get('keywords')
            geographical_setup_string = unicode(
                form.get('regions')
            )  # includes all geographical information including influence and twitter feed areas.
            instance_setup_code = form.get('instance_setup_code')

            keywordsList = None
            if keywords is not None:
                if len(keywords) > 0:
                    assert isinstance(keywords, basestring)
                    keywordsList = keywords.split(',')

            def redirectError(errorMessage):
                return redirect(
                    Display.addArgumentsToLink(
                        GateInstance.link_info.getPageLink(),
                        oauth_token=oauth_token,
                        oauth_secret=oauth_secret,
                        keywords=keywords,
                        regions=geographical_setup_string,
                        instance_setup_code=instance_setup_code,
                        error=errorMessage))

            if not oauth_token or not oauth_secret:
                return redirectError('Twitter login credentials are missing')

            oauth = TwitterInstance.makeAuthTuple(oauth_token, oauth_secret)
            if self.application.twitter_instances.isAuthInUse(oauth):
                # Do nothing, we will be redirected to the gate instance which will hopefully
                # correct this mistake.
                pass
            else:
                try:
                    twitterInstance = self.application.twitter_instances.createInstance(
                        TwitterAuthentication(Configuration.CONSUMER_TOKEN,
                                              Configuration.CONSUMER_SECRET,
                                              oauth_token, oauth_secret),
                        geographical_setup_string, keywordsList,
                        instance_setup_code)
                except ValueError as e:
                    return redirectError(
                        'Failed to setup instance, reason: %s' % e.message)

                error = twitterInstance.setup_error
                if error is not None:
                    return redirectError(error)

            return redirect(
                Display.addArgumentsToLink(
                    GateInstance.link_info.getPageLink(),
                    oauth_token=oauth_token,
                    oauth_secret=oauth_secret))

        return func
Beispiel #14
0
class GateInstance(Display):
    """ Overall instance management page.

        If no instance is running on this users account then display page to setup a new one.
        If one is already running then display page to manage that instance. """
    link_info = Display.LinkInfo(lambda link: lambda: link, '/gate_instance')

    def __init__(self, application):
        Display.__init__(self,
                         application,
                         pageRoute=('/gate_instance', None),
                         webSocketManagers=None)
        assert isinstance(application, WebApplicationTwitter)

    @property
    def page_html_function(self):
        def func(templateArguments):
            oauth_token = request.GET.oauth_token
            oauth_secret = request.GET.oauth_secret
            templateArguments.update({
                'oauth_token': oauth_token,
                'oauth_secret': oauth_secret
            })

            oauth = TwitterInstance.makeAuthTuple(oauth_token, oauth_secret)
            if not self.application.twitter_instances.isAuthInUse(oauth):
                return self.start_instance_get(templateArguments)
            else:
                return self.manage_instance_get(templateArguments, oauth)

        return func

    def start_instance_get(self, template_arguments):
        template_arguments.update(
            {'post_address': StartInstancePost.link_info.getPageLink()})

        keywords = request.GET.keywords
        regions = parseString(request.GET.regions, default='{}')
        instanceSetupCode = parseString(request.GET.instance_setup_code,
                                        default='')

        template_arguments.update({
            'home_link':
            getHomeLink(Configuration.PROJECT_NAME),
            'keywords':
            keywords,
            'regions':
            regions,
            'instance_setup_code':
            instanceSetupCode,
            'max_geographical_filters':
            Configuration.TWITTER_MAX_GEO_FILTERS
        })

        error = request.GET.error
        if len(error) > 0:
            template_arguments.update({'error': error})

        return template('instance-start.tpl', template_arguments)

    def manage_instance_get(self, template_arguments, oauth):
        # Cannot have tuple as key in json.
        oauthStr = unicode(oauth)

        instance = self.application.twitter_instances.getInstanceByAuth(oauth)
        if instance is None:
            return self.start_instance_get(template_arguments)

        try:
            instancesByName = json.loads(
                request.get_cookie('_instancesByName', '{}'))
            instancesByAuth = json.loads(
                request.get_cookie('_instancesByAuth', '{}'))
        except CookieError as e:
            # There seems to be a bug in Python cookie module (which bottle uses) causing it to fail when certain cookie keys
            # are present (even if we don't directly look them up). In repo see file documents/cookie-bug.png,
            # this try/catch prevents the bug from causing a serious issue.
            logger.warn(
                'Cookie error while decoding _instancesByName or _instancesByAuth from user, deleting pre-existing cookies: %s'
                % e.message)
            instancesByName = dict()
            instancesByAuth = dict()

        # Delete old data in case auth used with different instance name previously.
        oldInstanceName = instancesByAuth.get(oauthStr, None)
        if oldInstanceName is not None:
            logger.info(
                'Cleaning up old cookie data, association between account and instance'
            )
            try:
                del instancesByAuth[oauthStr]
            except KeyError:
                pass

            try:
                del instancesByName[oldInstanceName]
            except KeyError:
                pass

        instancesByName[instance.instance_key] = oauth
        instancesByAuth[oauthStr] = instance.instance_key
        response.set_cookie('_instancesByName',
                            json.dumps(instancesByName),
                            path='/')
        response.set_cookie('_instancesByAuth',
                            json.dumps(instancesByAuth),
                            path='/')

        return redirect(
            LocationsMapPage.link_info.getPageLink(instance.instance_key))