예제 #1
0
    def tweet(self, access_token):
        if not access_token:
            raise ValueError("No access token")
        
        token = oauth.OAuthToken.from_string(access_token)

        sanitized_content = self.word.content.replace('#', '%23')
        sanitized_content = sanitized_content.replace('@', '%40')
        url = 'http://pretweeting.com/w/%s' % sanitized_content

        message = '@pretweeting %s -> see price at %s' % (self.description, url)
        try:
            response = post_tweet(CONSUMER, CONNECTION, token, message)
        except TwitterError, e:
            raise IOError("Couldn't post to twitter %s" % str(e))
예제 #2
0
def chat(request):
    
    if request.method == 'POST':
        
        message = request.POST['message']
        if not message:
            return HttpResponse(dumps({
                'success': False,
                'error': 'You need a message to send!'
            }))
        
        if len(message) > 140 - len(' #pretweeting'):
            return HttpResponse(dumps({
                'success': False,
                'error': 'Message too long'
            }))
        
        access_token = request.session.get('access_token', None)
        if access_token is None:
            access_token = request.user.get_profile().access_token
        if access_token is None:
             return HttpResponse(dumps({
                 'success': False,
                 'error': 'Invalid authentication'
             }))
        
        token = oauth.OAuthToken.from_string(access_token)

        if not settings.POST_TWEETS or not access_token:
            return HttpResponse(dumps({
                'success': False,
                'error': "Can't post to twitter."
            }))
        
        full_msg = '%s #pretweeting' % message
        try:
            response = post_tweet(CONSUMER, CONNECTION, token, full_msg)
        except TwitterError, e:
            return HttpResponse(dumps({
                'success': False,
                'error': 'Error posting to twitter.'
            }))
        else:
            return HttpResponse(dumps({
                'success': True,
                'message': 'Sent! Wait few seconds for it to show up.'
            }))
예제 #3
0
def process_batch(file_name):
    "Lock the file and process it."

    timestamp = int(file_name.split(".")[0])

    log_msg("--- processing %s at %s ---" % (file_name, datetime.datetime.now().replace(microsecond=0)))
    pexpect.run("%s %s %s" % ("mv" if REMOVE_FROM_BATCH_QUEUE else "cp", os.path.join(BATCH_DIR, file_name), LOCK_DIR))

    batch = open(os.path.join(LOCK_DIR, file_name))

    frequencies = {}

    total_lines = 0
    num_lines = 0
    num_words = 0

    t0 = time.time()
    while True:

        line = batch.readline()
        if not line:
            break
        try:
            data_object = loads(line)
        except ValueError:
            # if it's invalid json, just pass it
            continue

        total_lines += 1

        if RESTRICT_TIMEZONES:
            try:
                if data_object["user"]["time_zone"] not in ALLOWED_TIMEZONES:
                    continue
            except KeyError:
                continue

        try:
            text = data_object["text"]
        except KeyError:
            # not a status object
            continue

        num_lines += 1

        words = process_text(text)
        num_words += len(words)
        update_frequencies(frequencies, words)

    batch.close()

    # kill the file. no need to keep them
    os.remove(os.path.join(LOCK_DIR, file_name))

    total_words = len(frequencies.keys())
    total_count = sum(frequencies.values())
    t1 = time.time()
    log_msg(
        "%d lines (of %d), %d words, %d usages counted: %.01fs."
        % (num_lines, total_lines, total_words, total_count, (t1 - t0))
    )

    if total_words == 0:
        log_msg("skipping new batch...no content.")
        return

    # create new counts and measures
    new_batch = Batch.objects.create(total_messages=num_lines, created_on=datetime.datetime.fromtimestamp(timestamp))

    num_words = Word.objects.all().count()
    num_counts = Count.objects.all().count()

    # Bulk insert all words, ignoring errors
    for content, number in frequencies.iteritems():
        Word.objects.bulk_insert(content=content, send_pre_save=False)

    Word.objects.bulk_insert_commit(send_post_save=False, recover_pks=False)

    # Fetch the ids for new words so we can match them to counts
    words = Word.objects.filter(content__in=frequencies.keys())
    word_ids = dict([(word.content, word.id) for word in words])

    t2 = time.time()
    new_num_words = Word.objects.all().count()
    log_msg("%d new words created: %.01fs." % ((new_num_words - num_words), (t2 - t1)))

    # And bulk insert the new counts
    for content, number in frequencies.iteritems():
        if content not in word_ids:
            # for some reason, the word wasn't successfully created by the
            # bulk insert
            new_word = Word.objects.create(content=content)
            word_ids[content] = new_word.id
            log_msg("*** failsafe create for '%s'." % content)

        Count.objects.bulk_insert(word=word_ids[content], batch=new_batch, number=number, send_pre_save=False)

    Count.objects.bulk_insert_commit(send_post_save=False, recover_pks=False)

    new_num_counts = Count.objects.all().count()

    t3 = time.time()

    log_msg("%d new counts created: %.01fs." % ((new_num_counts - num_counts), (t3 - t2)))

    # update round
    if Round.objects.count() > 0:
        t0 = time.time()

        maturations = []

        latest_round = Round.objects.latest()
        holdings = Holding.objects.filter(user_round__is_active=True).exclude(quantity=0).select_related("word")
        for holding in holdings:
            try:
                number = frequencies[holding.word.content]
            except KeyError:
                number = 0
            price = compute_price(number, new_batch.total_messages)
            holding.current_value = price * holding.quantity
            holding.save()

        user_rounds = UserRound.objects.filter(is_active=True)
        # aggregate into current value
        for user_round in user_rounds:
            user_round.update_current_value()

        t1 = time.time()

        log_msg(
            "%d holdings and %d user rounds updated: %.01fs." % (Holding.objects.count(), len(user_rounds), (t1 - t0))
        )

    # activate new measure
    new_batch.active = True
    new_batch.save()

    # update rounds.
    try:
        last_round = Round.objects.latest()
        last_number = last_round.number
        last_ends = last_round.ends_on
    except Round.DoesNotExist:
        last_round = None
        last_number = 0
        last_ends = datetime.datetime.now()

    if datetime.datetime.now() >= last_ends:

        if last_round:
            # tweet win
            if settings.TWEET_WIN:
                try:
                    winning_userround = (last_round.userround_set.order_by("-current_value"))[0]
                except IndexError:
                    # no winner
                    pass
                else:
                    message = "Congrats to @%s for winning %s with $%s! #pretweeting" % (
                        winning_userround.user.username,
                        last_round.name,
                        priceformat.currency(winning_userround.current_value),
                    )

                    access_token = settings.TWITTER_OAUTH_TOKEN
                    token = oauth.OAuthToken.from_string(access_token)
                    try:
                        post_tweet(CONSUMER, CONNECTION, token, message)
                    except TwitterError, e:
                        log_msg(e)

            # create frozen copies of all user rounds
            for user_round in last_round.userround_set.filter(is_active=True, is_frozen=False):
                user_round.copy_frozen()

        # create next round
        new_number = last_number + 1
        new_name = "Round %d" % new_number
        new_round = Round(number=new_number, name=new_name)
        new_round.started_on = datetime.datetime.now()
        new_round.ends_on = datetime.datetime.now() + settings.ROUND_LENGTH
        new_round.save()