Example #1
0
    def test_region_autocapital(self):
        """A region that's a capital is automatically owned by the same team"""
        cap = Region.capital_for(0, self.sess)
        self.assertEqual(cap.capital, cap.owner)

        cap = Region.capital_for(1, self.sess)
        self.assertEqual(cap.capital, cap.owner)
Example #2
0
 def create_user(self, name, team):
     newbie = User(name=name, team=team, loyalists=100, leader=True)
     self.sess.add(newbie)
     cap = Region.capital_for(team, self.sess)
     newbie.region = cap
     self.sess.commit()
     return newbie
Example #3
0
    def test_extract_cancels_movement(self):
        """Emergency movement shouldn't rubberband"""
        sess = self.sess
        cap = Region.capital_for(0, sess)
        # Move Alice somewhere else
        londo = self.get_region("Orange Londo")
        self.alice.move(100, londo, 0)

        # Should be in londo
        self.assertEqual(self.alice.region, londo)

        # Bloodless coup of Sapphire
        sapp = self.get_region("Sapphire")
        sapp.owner = self.alice.team
        sess.commit()

        # Start wandering that way
        order = self.alice.move(100, sapp, 60 * 60 * 24)
        self.assert_(order)

        orders = self.sess.query(MarchingOrder).count()
        self.assertEqual(orders, 1)

        self.alice.extract()
        self.assertEqual(self.alice.region, cap)

        orders = self.sess.query(MarchingOrder).count()
        self.assertEqual(orders, 0)
Example #4
0
    def recruit_from_comment(self, comment):
        session = self.session
        if not comment.author:  # Deleted comments don't have an author
            return
        name = comment.author.name.lower()
        if name == self.config.username.lower():
            return

        # Is this author already one of us?
        found = session.query(User).filter_by(name=name).first()
        if not found:
            # Getting the author ID triggers a lookup on the userpage.  In the
            # case of banned users, this will 404.  @failable would normally
            # catch that just fine, but I want to check it here so that in the
            # future, I can do things like e.g. add to an 'ignored' list and
            # save myself the lookup
            try:
                author_id = comment.author.id
            except NotFound:
                logging.warn("Ignored banned user %s" % name)
                return

            team = 0
            assignment = self.config['game']['assignment']
            if assignment == 'uid':
                base10_id = base36decode(author_id)
                team = base10_id % 2
            elif assignment == "random":
                team = random.randint(0, 1)
            is_leader = name in self.config["game"]["leaders"]
            loyalists = self.config["game"].get("starting_troops", 100)
            newbie = User(name=name,
                          team=team,
                          loyalists=loyalists,
                          leader=is_leader)
            session.add(newbie)

            cap = Region.capital_for(newbie.team, session)
            if not cap:
                logging.fatal("Could not find capital for %d" % newbie.team)
            newbie.region = cap

            session.commit()
            logging.info("Created combatant %s", newbie)

            reply = ("Welcome to Chroma!  You are now a %s "
                     "in the %s army, commanding a force of loyalists "
                     "%d people strong. You are currently encamped at %s") % (
                         newbie.rank, num_to_team(newbie.team, self.config),
                         newbie.loyalists, cap.markdown())

            team = session.query(TeamInfo).filter_by(id=newbie.team).first()
            if team:
                reply = "%s\n\n%s" % (reply, team.greeting)

            comment.reply(reply)
        else:
            #logging.info("Already registered %s", comment.author.name)
            pass
Example #5
0
    def expand_path(cls, regions, context):
        if "*" not in regions:
            return [Region.get_region(where, context) for where in regions]
        if regions[-1] == '*':
            context.reply("You can't end a movement command with a "
                          "pathfinding instruction; I have no idea where you "
                          "want to end up!")
            return
        result = []
        curr = context.player.region
        for index, region_name in enumerate(regions):
            if region_name == '*':
                if not curr:
                    continue  # Don't bother if we don't know prev location
                if regions[index + 1] == '*':
                    continue  # Ignore consecutive pathfinding instructions
                dest = Region.get_region(regions[index + 1], context)
                if not dest:
                    return None

                # See if we allow neutral traversal
                conf = context.config
                traverse_neutrals = False
                if conf:
                    traverse_neutrals = conf["game"].get("traversable_neutrals",
                                                         False)
                path = find_path(curr, dest, context.player.team,
                                 traverse_neutrals=traverse_neutrals)
                if path:
                    path = path[1:-1]  # We already have the first and the last
                    if not path:
                        continue  # They were already adjacent!
                    result.extend(path)
                else:
                    context.reply("I couldn't find a friendly-territory path "
                                  "between %s and %s "
                                  % (curr.name, dest.name))
                    return None
                curr = dest
            else:
                dest = Region.get_region(region_name, context)
                if not dest:
                    return None
                result.append(dest)
                curr = dest
        return result
Example #6
0
    def recruit_from_comment(self, comment):
        session = self.session
        if not comment.author:  # Deleted comments don't have an author
            return
        name = comment.author.name.lower()
        if name == self.config.username.lower():
            return

        # Is this author already one of us?
        found = session.query(User).filter_by(
            name=name).first()
        if not found:
            # Getting the author ID triggers a lookup on the userpage.  In the
            # case of banned users, this will 404.  @failable would normally
            # catch that just fine, but I want to check it here so that in the
            # future, I can do things like e.g. add to an 'ignored' list and
            # save myself the lookup
            try:
                author_id = comment.author.id
            except NotFound:
                logging.warn("Ignored banned user %s" % name)
                return

            team = 0
            assignment = self.config['game']['assignment']
            if assignment == 'uid':
                base10_id = base36decode(author_id)
                team = base10_id % 2
            elif assignment == "random":
                team = random.randint(0, 1)
            is_leader = name in self.config["game"]["leaders"]
            newbie = User(name=name,
                          team=team,
                          loyalists=100,
                          leader=is_leader)
            session.add(newbie)

            cap = Region.capital_for(newbie.team, session)
            if not cap:
                logging.fatal("Could not find capital for %d" %
                              newbie.team)
            newbie.region = cap

            session.commit()
            logging.info("Created combatant %s", newbie)

            reply = ("Welcome to Chroma!  You are now a %s "
                     "in the %s army, commanding a force of loyalists "
                     "%d people strong. You are currently encamped at %s"
            ) % (newbie.rank,
                 num_to_team(newbie.team, self.config),
                 newbie.loyalists,
                 cap.markdown())
            comment.reply(reply)
        else:
            #logging.info("Already registered %s", comment.author.name)
            pass
Example #7
0
 def add_region(session, id, continent_id, name_rus):
     cont = session.query(Continent).get(continent_id)
     new_region = session.query(Region).get(id)
     if new_region:
         new_region.continent_id = cont.id
         new_region.name_rus = name_rus
     else:
         new_region = Region(name_rus=name_rus, continent_id=cont.id)
         session.add(new_region)
Example #8
0
def map(region):
    try:
        r = Region.get(Region.tag == region)
        if r.live == False:
            return redirect('/')
        # Get the maximum date
        start_date = Summary.max_date(f"{region}-msa")
        view = {'title': r.name, 'name': r.tag, 'lat': r.lat, 'lon': r.lon, 'max_date': start_date}
        return render_template('map.html', region=r.tag, zoom=r.zoom, view=view)
    except DoesNotExist:
        return redirect('/')
Example #9
0
    def setUp(self):
        logging.basicConfig(level=logging.DEBUG)
        conf = MockConf(dbstring="sqlite://")
        self.db = DB(conf)
        self.db.create_all()
        self.sess = self.db.session()
        self.sess.add_all(Region.create_from_json(TEST_LANDS))

        self.sess.commit()
        # Create some users
        self.alice = self.create_user("alice", 0)
        self.bob = self.create_user("bob", 1)
Example #10
0
    def test_movement(self):
        """Move Alice from the Orangered capital to an adjacent region"""
        sess = self.sess
        cap = Region.capital_for(0, sess)
        # First of all, make sure alice is actually there
        self.assertEqual(self.alice.region.id, cap.id)

        londo = self.get_region("Orange Londo")
        self.assertIsNotNone(londo)

        self.alice.move(100, londo, 0)

        # Now she should be there
        self.assertEqual(self.alice.region.id, londo.id)
Example #11
0
def download_region(region):
    try:
        r = Region.get(Region.tag == region)
        if r.live == False:
            return redirect('/')
        dates = Run.select(Run.date, Run.note).where(Run.region == region).where(Run.live == True).order_by(Run.date.desc())
        datelist = []
        reliability = False
        if region in ['nyc', 'chicago', 'sf', 'philadelphia']:
            reliability = True
        for d in dates:
            datelist.append([d.date, d.note])
        return render_template('download.html', tag=r.tag, title=r.name, dates=datelist, reliability=reliability)
    except DoesNotExist:
        return redirect('/')
Example #12
0
    def test_extract(self):
        """Emergency movement back to capital"""
        sess = self.sess
        cap = Region.capital_for(0, sess)
        # Move Alice somewhere else
        londo = self.get_region("Orange Londo")
        self.alice.move(100, londo, 0)

        # Should be in londo
        self.assertEqual(self.alice.region, londo)
        # Emergency move!
        self.alice.extract()

        # Should be back in capital
        self.assertEqual(self.alice.region, cap)
Example #13
0
    def execute(self, context):
        dest = Region.get_region(self.where, context)
        if dest:
            now = time.mktime(time.localtime())
            begins = now + context.config["game"]["battle_delay"]
            battle = None

            if dest.capital is not None:
                invade = context.config['game']['capital_invasion']
                if invade == 'none':
                    context.reply("You cannot invade the enemy capital")
                    return

            try:
                battle = dest.invade(context.player, begins)
                if "battle_lockout" in context.config["game"]:
                    battle.lockout = context.config["game"]["battle_lockout"]
                    context.session.commit()
            except db.RankException:
                context.reply("You don't have the authority "
                              "to invade a region!")
            except db.TeamException:
                context.reply("You can't invade %s, you already own it!" %
                              dest.markdown())
            except db.NonAdjacentException:
                context.reply("%s is not next to any territory you control" %
                              dest.markdown())
            except db.InProgressException as ipe:
                context.reply("%s is %s being invaded!" % (dest.markdown(),
                              ipe.other.markdown("already")))
            except db.TimingException as te:
                context.reply(("%s is too fortified to be attacked.  "
                              "These fortifications will break down by %s") %
                              (dest.markdown(), timestr(te.expected)))

            if battle:
                context.reply("**Confirmed**  Battle will begin at %s" %
                              battle.begins_str())
                title = ("[Invasion] The %s armies march!" %
                 context.team_name())
                submitted = InvadeCommand.post_invasion(title, battle,
                                                        context.reddit)
                if submitted:
                    battle.submission_id = submitted.name
                    context.session.commit()
                else:
                    logging.warn("Couldn't submit invasion thread")
                    context.session.rollback()
Example #14
0
    def execute(self, context):
        dest = Region.get_region(self.where, context)
        if dest:
            now = time.mktime(time.localtime())
            begins = now + context.config["game"]["battle_delay"]
            battle = None

            if dest.capital is not None:
                invade = context.config['game']['capital_invasion']
                if invade == 'none':
                    context.reply("You cannot invade the enemy capital")
                    return

            try:
                battle = dest.invade(context.player, begins)
                if "battle_lockout" in context.config["game"]:
                    battle.lockout = context.config["game"]["battle_lockout"]
                    context.session.commit()
            except db.RankException:
                context.reply("You don't have the authority "
                              "to invade a region!")
            except db.TeamException:
                context.reply("You can't invade %s, you already own it!" %
                              dest.markdown())
            except db.NonAdjacentException:
                context.reply("%s is not next to any territory you control" %
                              dest.markdown())
            except db.InProgressException as ipe:
                context.reply("%s is %s being invaded!" % (dest.markdown(),
                              ipe.other.markdown("already")))
            except db.TimingException as te:
                context.reply(("%s is too fortified to be attacked.  "
                              "These fortifications will break down by %s") %
                              (dest.markdown(), timestr(te.expected)))

            if battle:
                context.reply("**Confirmed**  Battle will begin at %s" %
                              battle.begins_str())
                title = ("[Invasion] The %s armies march on %s!" %
                         (context.team_name(), dest.name))
                submitted = InvadeCommand.post_invasion(title, battle,
                                                        context.reddit)
                if submitted:
                    battle.submission_id = submitted.name
                    context.session.commit()
                else:
                    logging.warn("Couldn't submit invasion thread")
                    context.session.rollback()
Example #15
0
    def recruit_from_post(self, post):
        post.replace_more_comments(threshold=0)
        flat_comments = praw.helpers.flatten_tree(post.comments)
        session = self.session
        for comment in flat_comments:
            if not comment.author:  # Deleted comments don't have an author
                continue
            name = comment.author.name.lower()
            if name == self.config.username.lower():
                continue

            # Is this author already one of us?
            found = session.query(User).filter_by(name=name).first()
            if not found:
                team = 0
                assignment = self.config["game"]["assignment"]
                if assignment == "uid":
                    base10_id = base36decode(comment.author.id)
                    team = base10_id % 2
                elif assignment == "random":
                    team = random.randint(0, 1)
                is_leader = name in self.config["game"]["leaders"]
                newbie = User(name=name, team=team, loyalists=100, leader=is_leader)
                session.add(newbie)

                cap = Region.capital_for(newbie.team, session)
                if not cap:
                    logging.fatal("Could not find capital for %d" % newbie.team)
                newbie.region = cap

                session.commit()
                logging.info("Created combatant %s", newbie)

                reply = (
                    "Welcome to Chroma!  You are now a %s "
                    "in the %s army, commanding a force of loyalists "
                    "%d people strong. You are currently encamped at %s"
                ) % (newbie.rank, num_to_team(newbie.team, self.config), newbie.loyalists, cap.markdown())
                comment.reply(reply)
            else:
                # logging.info("Already registered %s", comment.author.name)
                pass
Example #16
0
def charts(region):
    try:
        r = Region.get(Region.tag == region)
        if r.live == False:
            return redirect('/')
        agencies = [model_to_dict(b) for b in Agency.agency_list(region)]
        maxDate = Summary.max_date(f"{region}-msa")
        auto = Summary.auto_access(region, maxDate)
        reliability = False
        if region in ['nyc', 'chicago', 'sf', 'philadelphia', 'dc']:
            reliability = True

        if region in ['boston', 'nyc', 'sf', 'dc']:
            fare = '5'
        else:
            fare = '4'
        view = {'title': r.name, 'name': r.tag, 'lat': r.lat, 'lon': r.lon, 
        'state': r.state, 'county': r.county, 'agencies': r.agencies, 'population': r.population,
        'max_date': maxDate, 'reliability': reliability, 'fare': fare, 'premium': agencies, 'car_access': auto}
        return render_template('charts.html', view=view, abstract=r.abstract)
    except DoesNotExist:
        return redirect('/')
Example #17
0
def documentation():
    agencies = Agency.select()
    regions = Region.select()
    return render_template('methodology.html', agencies=agencies, regions=regions)
Example #18
0
def home():
    status = SiteStatus.get_main_status()
    return render_template('home.html', regions=Region.select().order_by(Region.name.asc()), status=status)
Example #19
0
    def update_game(self):
        session = self.session
        MarchingOrder.update_all(session, self.config)

        results = Region.update_all(session, self.config)
        to_add = []
        for newternal in results['new_eternal']:
            title = "The Eternal Battle Rages On"
            post = InvadeCommand.post_invasion(title, newternal, self.reddit)
            if post:
                newternal.submission_id = post.name
                to_add.append(newternal)
            else:
                logging.warn("Couldn't submit eternal battle thread")
                session.rollback()
        if to_add:
            session.add_all(to_add)
            session.commit()

        results = Battle.update_all(session, self.config)

        for ready in results['begin']:
            ready.display_ends = (ready.begins +
                                  self.config["game"]["battle_time"])

            # Actual ending is within battle_lockout of the end
            chooserange = self.config["game"]["battle_lockout"]
            chosen = random.randint(0, chooserange)
            ready.ends = ready.display_ends - (chooserange / 2) + chosen

            text = ("War is now at your doorstep!  Mobilize your armies! "
                    "The battle has begun now, and will end at %s.\n\n"
                    "> Enter your commands in this thread, prefixed with "
                    "'>'") % ready.ends_str()
            post = self.reddit.get_submission(
                submission_id=name_to_id(ready.submission_id))
            post.edit(text)
            session.commit()

        self.update_skirmish_summaries(results['skirmish_ended'])

        for done in results['ended']:
            report = ["The battle is complete...\n"]
            report += done.report(self.config)

            report.append("")

            if done.old_buffs:
                report.append("Buffs in effect for Team %s\n" %
                              num_to_team(done.old_owner, self.config))
                for buff in done.old_buffs:
                    report.append("  * %s" % buff.name)
                report.append("")

            team0_name = num_to_team(0, self.config)
            team1_name = num_to_team(1, self.config)

            # Homeland buffs?
            if done.homeland_buffs:
                report.append("Homeland buffs in effect:")
                for team in range(0, 2):
                    name = num_to_team(team, self.config)
                    report.append("%s: %d%%" %
                                  (name, done.homeland_buffs[team]))

            report.append(("## Final Score:  Team %s: %d "
                           "Team %s: %d") %
                          (team0_name, done.score0, team1_name, done.score1))
            if done.victor is not None:
                report.append("\n# The Victor:  Team %s" %
                              num_to_team(done.victor, self.config))
            else:
                report.append("# TIE")

            text = "\n".join(report)
            post = self.reddit.get_submission(
                submission_id=name_to_id(done.submission_id))
            post.edit(text)

            # Update all the skirmish summaries
            self.update_skirmish_summaries(done.toplevel_skirmishes())

            session.delete(done)
            session.commit()
        db.Buff.update_all(session)
Example #20
0
    def update_game(self):
        session = self.session
        MarchingOrder.update_all(session, self.config)

        results = Region.update_all(session, self.config)
        to_add = []
        for newternal in results['new_eternal']:
            title = "The Eternal Battle Rages On"
            post = InvadeCommand.post_invasion(title, newternal, self.reddit)
            if post:
                newternal.submission_id = post.name
                to_add.append(newternal)
            else:
                logging.warn("Couldn't submit eternal battle thread")
                session.rollback()
        if to_add:
            session.add_all(to_add)
            session.commit()

        results = Battle.update_all(session, self.config)

        for ready in results['begin']:
            ready.display_ends = (ready.begins +
                self.config["game"]["battle_time"])

            # Actual ending is within battle_lockout of the end
            chooserange = self.config["game"]["battle_lockout"]
            chosen = random.randint(0, chooserange)
            ready.ends = ready.display_ends - (chooserange / 2) + chosen

            text = ("War is now at your doorstep!  Mobilize your armies! "
                    "The battle has begun now, and will end at %s.\n\n"
                    "> Enter your commands in this thread, prefixed with "
                    "'>'") % ready.ends_str()
            post = self.reddit.get_submission(
                submission_id=name_to_id(ready.submission_id))
            post.edit(text)
            session.commit()

        self.update_skirmish_summaries(results['skirmish_ended'])

        for done in results['ended']:
            report = ["The battle is complete...\n"]
            report += done.report(self.config)

            report.append("")

            if done.old_buffs:
                report.append("Buffs in effect for Team %s\n" %
                              num_to_team(done.old_owner, self.config))
                for buff in done.old_buffs:
                    report.append("  * %s" % buff.name)
                report.append("")

            team0_name = num_to_team(0, self.config)
            team1_name = num_to_team(1, self.config)

            # Homeland buffs?
            if done.homeland_buffs:
                report.append("Homeland buffs in effect:")
                for team in range(0, 2):
                    name = num_to_team(team, self.config)
                    report.append("%s: %d%%" %
                                  (name, done.homeland_buffs[team]))

            report.append(("## Final Score:  Team %s: %d "
                           "Team %s: %d") % (team0_name, done.score0,
                                             team1_name, done.score1))
            if done.victor is not None:
                report.append("\n# The Victor:  Team %s" %
                              num_to_team(done.victor, self.config))
            else:
                report.append("# TIE")

            text = "\n".join(report)
            post = self.reddit.get_submission(
                submission_id=name_to_id(done.submission_id))
            post.edit(text)

            # Update all the skirmish summaries
            self.update_skirmish_summaries(done.toplevel_skirmishes())

            session.delete(done)
            session.commit()
        db.Buff.update_all(session)