Beispiel #1
0
def main():
    logging.info("Starting calculator...")
    logging.info(
        "Sleeping for 8 seconds. Waiting for the database to turn on...")
    time.sleep(8)

    killhandler = KillHandler()

    engine = create_engine(config.DB, pool_recycle=60, pool_pre_ping=True)
    session_maker = sessionmaker(bind=engine)

    reddit = praw.Reddit(client_id=config.CLIENT_ID,
                         client_secret=config.CLIENT_SECRET,
                         username=config.USERNAME,
                         password=config.PASSWORD,
                         user_agent=config.USER_AGENT)

    # We will test our reddit connection here
    if not utils.test_reddit_connection(reddit):
        exit()

    praw.models.Comment.edit_wrap = edit_wrap

    stopwatch = Stopwatch()

    logging.info("Monitoring active investments...")

    while not killhandler.killed:
        sess = session_maker()

        then = int(time.time()) - config.INVESTMENT_DURATION
        investment = sess.query(Investment).\
            filter(Investment.done == 0).\
            filter(Investment.time < then).\
            order_by(Investment.time.asc()).\
            first()

        if not investment:
            # Nothing matured yet; wait a bit before trying again
            time.sleep(5)
            continue

        duration = stopwatch.measure()

        investor = sess.query(Investor).filter(
            Investor.name == investment.name).one()
        net_worth = sess.\
            query(func.sum(Investment.amount)).\
            filter(and_(Investment.name == investor.name, Investment.done == 0)).\
            scalar()\
            + investor.balance

        logging.info("New mature investment: %s", investment.comment)
        logging.info(" -- by %s", investor.name)

        # Retrieve the post the user invested in (lazily, no API call)
        post = reddit.submission(investment.post)

        # Retrieve the post's current upvote count (triggers an API call)
        upvotes_now = post.ups
        investment.final_upvotes = upvotes_now

        # Updating the investor's balance
        factor = formula.calculate(upvotes_now, investment.upvotes, net_worth)
        amount = investment.amount
        balance = investor.balance

        new_balance = int(balance + (amount * factor))
        change = new_balance - balance
        profit = change - amount
        percent_str = f"{int((profit/amount)*100)}%"

        # Updating the investor's variables
        investor.completed += 1

        # Retrieve the bot's original response (lazily, no API call)
        if investment.response != "0":
            response = reddit.comment(id=investment.response)
        else:
            response = EmptyResponse()

        firm_profit = 0
        if new_balance < BALANCE_CAP:
            # If investor is in a firm and he profits,
            # 15% goes to the firm
            firm_name = ''
            if investor.firm != 0 and profit >= 0:
                firm = sess.query(Firm).\
                    filter(Firm.id == investor.firm).\
                    first()
                firm_name = firm.name

                user_profit = int(profit * ((100 - firm.tax) / 100))
                investor.balance += user_profit + amount

                firm_profit = int(profit * (firm.tax / 100))
                firm.balance += firm_profit
            else:
                investor.balance = new_balance

            # Edit the bot's response (triggers an API call)
            if profit > 0:
                logging.info(" -- profited %s", profit)
            elif profit == 0:
                logging.info(" -- broke even")
            else:
                logging.info(" -- lost %s", profit)

            edited_response = message.modify_invest_return(
                investment.amount, investment.upvotes, upvotes_now, change,
                profit, percent_str, investor.balance)
            if investor.firm != 0:
                edited_response += message.modify_firm_tax(
                    firm_profit, firm_name)

            response.edit_wrap(edited_response)
        else:
            # This investment pushed the investor's balance over the cap
            investor.balance = BALANCE_CAP

            # Edit the bot's response (triggers an API call)
            logging.info(" -- profited %s but got capped", profit)
            response.edit_wrap(
                message.modify_invest_capped(investment.amount,
                                             investment.upvotes, upvotes_now,
                                             change, profit, percent_str,
                                             investor.balance))

        investment.success = (profit > 0)
        investment.profit = profit
        investment.done = True

        sess.commit()

        # Measure how long processing took
        duration = stopwatch.measure()
        logging.info(" -- processed in %.2fs", duration)

        # Report the Reddit API call stats
        rem = int(reddit.auth.limits['remaining'])
        res = int(reddit.auth.limits['reset_timestamp'] - time.time())
        logging.info(" -- API calls remaining: %s, resetting in %.2fs", rem,
                     res)

        sess.close()
Beispiel #2
0
def main():
    logging.info("Starting calculator...")

    killhandler = KillHandler()

    engine = create_engine()
    session_maker = sessionmaker(bind=engine)

    reddit = praw.Reddit(
        client_id=config.CLIENT_ID,
        client_secret=config.CLIENT_SECRET,
        username=config.USERNAME,
        password=config.PASSWORD,
        user_agent=config.USER_AGENT,
    )

    # We will test our reddit connection here
    if not utils.test_reddit_connection(reddit):
        return ()

    praw.models.Comment.edit_wrap = edit_wrap
    stopwatch = Stopwatch()

    logging.info("Retrieving top ...")

    # query
    sess = session_maker()
    try:
        top_networth = (sess.query(
            Investor.name,
            func.coalesce(Investor.balance + func.sum(Investment.amount),
                          Investor.balance).label("networth"),
        ).outerjoin(
            Investment,
            and_(Investor.name == Investment.name,
                 Investment.done == 0)).group_by(Investor.name).order_by(
                     desc("networth")).limit(1).one())[1]
    except NoResultFound:
        top_networth = 0
    top_networth = max(top_networth,
                       config.STARTING_BALANCE * 10)  # al last starting * 10
    sess.close()
    logging.info("Top networth: %d", top_networth)

    logging.info("Monitoring active investments...")

    while not killhandler.killed:
        sess = session_maker()

        then = int(time.time()) - config.INVESTMENT_DURATION
        investment = (sess.query(Investment).filter(
            Investment.done == 0).filter(Investment.time < then).order_by(
                Investment.time.asc()).first())

        if not investment:
            # Nothing matured yet; wait a bit before trying again
            time.sleep(50)
            continue

        duration = stopwatch.measure()

        investor = sess.query(Investor).filter(
            Investor.name == investment.name).one()
        net_worth = investor.networth(sess)

        logging.info("New mature investment: %s", investment.comment)
        logging.info(" -- by %s", investor.name)

        # Retrieve the post the user invested in (lazily, no API call)
        post = reddit.submission(investment.post)

        # Retrieve the post's current upvote count (triggers an API call)
        upvotes_now = post.ups
        investment.final_upvotes = upvotes_now
        investment.op = (post.author and investor.name == post.author.name)
        investment.net_worth = net_worth
        investment.top_networth = top_networth

        # Updating the investor's balance
        factor = formula.calculate(upvotes_now, investment.upvotes, net_worth,
                                   top_networth)

        if factor > 1 and post.author and investor.name == post.author.name:
            # bonus per OP
            factor *= formula.OP_BONUS

        amount = investment.amount
        balance = investor.balance

        new_balance = int(balance + (amount * factor))
        change = new_balance - balance
        profit = change - amount

        # Updating the investor's variables
        investor.completed += 1

        # Retrieve the bot's original response (lazily, no API call)
        if investment.response != "0":
            response = reddit.comment(id=investment.response)
        else:
            response = EmptyResponse()

        if new_balance < BALANCE_CAP:
            # If investor is in a firm and he profits,
            # 15% goes to the firm
            investor.balance = new_balance

            # Edit the bot's response (triggers an API call)
            if profit > 0:
                logging.info(" -- profited %s", profit)
            elif profit == 0:
                logging.info(" -- broke even")
            else:
                logging.info(" -- lost %s", profit)

            edited_response = message.modify_invest_return(
                investment.amount,
                investment.upvotes,
                upvotes_now,
                change,
                profit,
                investor.balance,
            )

            response.edit_wrap(edited_response)
        else:
            # This investment pushed the investor's balance over the cap
            investor.balance = BALANCE_CAP

            # Edit the bot's response (triggers an API call)
            logging.info(" -- profited %s but got capped", profit)
            response.edit_wrap(
                message.modify_invest_capped(
                    investment.amount,
                    investment.upvotes,
                    upvotes_now,
                    change,
                    profit,
                    investor.balance,
                ))

        investment.success = profit > 0
        investment.profit = profit
        investment.done = True

        sess.commit()

        if top_networth < investor.balance:
            top_networth = investor.balance
            logging.info("New Top networth: %d", top_networth)

        # Measure how long processing took
        duration = stopwatch.measure()
        logging.info(" -- processed in %.2fs", duration)

        # Report the Reddit API call stats
        rem = int(reddit.auth.limits["remaining"])
        res = int(reddit.auth.limits["reset_timestamp"] - time.time())
        logging.info(" -- API calls remaining: %s, resetting in %.2fs", rem,
                     res)

        sess.close()
Beispiel #3
0
def main():
    logging.info("Starting calculator")

    killhandler = KillHandler()

    engine = create_engine(config.db, pool_recycle=60)
    sm = sessionmaker(bind=engine)
    
    reddit = praw.Reddit(client_id=config.client_id,
                         client_secret=config.client_secret,
                         username=config.username,
                         password=config.password,
                         user_agent=config.user_agent)

    praw.models.Comment.edit_wrap = edit_wrap

    stopwatch = Stopwatch()

    logging.info("Monitoring active investments...")

    while not killhandler.killed:
        try:
            sess = sm()

            then = int(time.time()) - config.investment_duration
            investment = sess.query(Investment).\
                filter(Investment.done == 0).\
                filter(Investment.time < then).\
                order_by(Investment.time.asc()).\
                first()
            
            if not investment:
                # Nothing matured yet; wait a bit before trying again
                time.sleep(5)
                continue

            duration = stopwatch.measure()

            investor = sess.query(Investor).filter(Investor.name == investment.name).one()

            logging.info(f"New mature investment: {investment.comment}")
            logging.info(f" -- by {investor.name}")

            # Retrieve the post the user invested in (lazily, no API call)
            post = reddit.submission(investment.post)

            # Retrieve the post's current upvote count (triggers an API call)
            upvotes_now = post.ups
            investment.final_upvotes = upvotes_now

            # Updating the investor's balance
            factor = formula.calculate(upvotes_now, investment.upvotes)
            amount = investment.amount
            balance = investor.balance

            new_balance = int(balance + (amount * factor))
            change = new_balance - balance
            profit = change - amount
            percent_str = f"{int((profit/amount)*100)}%"

            # Updating the investor's variables
            investor.completed += 1

            # Retrieve the bot's original response (lazily, no API call)
            if investment.response != "0":
                response = reddit.comment(id=investment.response)
            else:
                response = EmptyResponse()

            if new_balance < BalanceCap:
                investor.balance = new_balance

                # Edit the bot's response (triggers an API call)
                if profit > 0:
                    logging.info(f" -- profited {profit}")
                elif profit == 0:
                    logging.info(f" -- broke even")
                else:
                    logging.info(f" -- lost {profit}")
                response.edit_wrap(message.modify_invest_return(investment.amount, investment.upvotes, upvotes_now, change, profit, percent_str, investor.balance))
            else:
                # This investment pushed the investor's balance over the cap
                investor.balance = BalanceCap

                # Edit the bot's response (triggers an API call)
                logging.info(f" -- profited {profit} but got capped")
                response.edit_wrap(message.modify_invest_capped(investment.amount, investment.upvotes, upvotes_now, change, profit, percent_str, investor.balance))

            investment.success = (profit > 0)
            investment.profit = profit
            investment.done = True

            sess.commit()

            # Measure how long processing took
            duration = stopwatch.measure()
            logging.info(f" -- processed in {duration:5.2f}s")

            # Report the Reddit API call stats
            rem = int(reddit.auth.limits['remaining'])
            res = int(reddit.auth.limits['reset_timestamp'] - time.time())
            logging.info(f" -- API calls remaining: {rem:3d}, resetting in {res:3d}s")

        except prawcore.exceptions.OAuthException as e_creds:
            traceback.print_exc()
            logging.error(e_creds)
            logging.critical("Invalid login credentials. Check your .env!")
            logging.critical("Fatal error. Cannot continue or fix the problem. Bailing out...")
            exit()
    
        except Exception as e:
            logging.error(e)
            traceback.print_exc()
            time.sleep(10)
        finally:
            sess.close()