コード例 #1
0
    def post(self):
        user = users.get_current_user()
        if not user:
            self.redirect(users.create_login_url(self.request.uri))

        conflict_id = self.request.get("conflict_id")
        try:
            conflict = Conflict.get_by_id(int(conflict_id))
        except (db.BadKeyError, StandardError) as e:
            self.error(500)
            print >>sys.stderr, str(e)
            return

        char = Character.gql("WHERE user = :1 AND conflict = :2",
                             user, conflict).get()

        if char is None:
            char = Character(user=user, conflict=conflict)

        if not char.finalized:
            char.name = self.request.get("char_name")
            char.intent = self.request.get("intent")
            char.finalized = True
            char.put()
        self.redirect('/conflict?conflict_id=%s' % conflict_id)
コード例 #2
0
    def post(self):
        user = users.get_current_user()
        if not user:
            self.redirect(users.create_login_url(self.request.uri))

        conflict_id = self.request.get("conflict_id")
        try:
            conflict = Conflict.get_by_id(int(conflict_id))
        except (db.BadKeyError, StandardError) as e:
            self.error(500)
            print >> sys.stderr, str(e)
            return

        char = Character.gql("WHERE user = :1 AND conflict = :2", user,
                             conflict).get()

        if char is None:
            char = Character(user=user, conflict=conflict)

        if not char.finalized:
            char.name = self.request.get("char_name")
            char.intent = self.request.get("intent")
            char.finalized = True
            char.put()
        self.redirect('/conflict?conflict_id=%s' % conflict_id)
コード例 #3
0
    def get(self):
        conflict_id = self.request.get("conflict_id")
        if not conflict_id:
            # TODO: Add overview page
            print "lolfukt"
            return

        try:
            conflict = Conflict.get_by_id(int(conflict_id))
            if conflict is None:
                raise RuntimeError("Can't find Conflict")
        except StandardError:
            self.error(404)
            return

        if all(char.finalized for char in conflict.characters):
            conflict.ready = True

        html_page = 'run_conflict.html' if conflict.ready else 'create_conflict.html'

        user = users.get_current_user()
        if user is None:
            user_char = None
        else:
            # May still be none if user is not in this conflict
            # TODO: Have conflict track their users so it can be validated
            user_char = Character.gql("WHERE user = :1 AND conflict = :2",
                                      user, conflict).get()

        html_path = os.path.join(os.path.dirname(__file__), html_page)
        template_values = {'conflict': conflict, 'user_char': user_char}
        self.response.out.write(template.render(html_path, template_values))
コード例 #4
0
    def get(self):
        conflict_id = self.request.get("conflict_id")
        if not conflict_id:
            # TODO: Add overview page
            print "lolfukt"
            return

        try:
            conflict = Conflict.get_by_id(int(conflict_id))
            if conflict is None:
                raise RuntimeError("Can't find Conflict")
        except StandardError:
            self.error(404)
            return

        if all(char.finalized for char in conflict.characters):
            conflict.ready = True

        html_page = 'run_conflict.html' if conflict.ready else 'create_conflict.html'

        user = users.get_current_user()
        if user is None:
            user_char = None
        else:
            # May still be none if user is not in this conflict
            # TODO: Have conflict track their users so it can be validated
            user_char = Character.gql("WHERE user = :1 AND conflict = :2",
                                      user, conflict).get()

        html_path = os.path.join(os.path.dirname(__file__), html_page)
        template_values = {'conflict': conflict,
                           'user_char': user_char}
        self.response.out.write(template.render(html_path, template_values))
コード例 #5
0
 def next_conflicts(self):
     if self.aircraft1.itinerary is None or\
        self.aircraft2.itinerary is None:
         return []
     if self.aircraft1.itinerary.next_target is None or\
        self.aircraft2.itinerary.next_target is None:
         return []
     if self.aircraft1.itinerary.next_target == \
        self.aircraft2.itinerary.next_target:
         return [Conflict(None, [self.aircraft1, self.aircraft2])]
     return []
コード例 #6
0
 def next_conflicts(self):
     loc1, loc2 = self.aircraft1.get_next_location(Aircraft.LOCATION_LEVEL_COARSE), \
                  self.aircraft2.get_next_location(Aircraft.LOCATION_LEVEL_COARSE)
     print("83", loc1, loc2)
     if not loc1 or not loc2 or not loc1.is_close_to(loc2):
         return []
     if loc1 == self.aircraft1.itinerary.targets[-1].nodes[-1] \
         and loc2 == self.aircraft2.itinerary.targets[-1].nodes[-1]:
         print("success")
         return []
     return [Conflict((loc1, loc2), [self.aircraft1, self.aircraft2])]
コード例 #7
0
 def __get_conflicts(self, is_next=False):
     __conflicts = []
     aircraft_pairs = list(itertools.combinations(self.aircrafts, 2))
     for pair in aircraft_pairs:
         if is_next:
             loc1, loc2 = pair[0].next_location, pair[1].next_location
         else:
             loc1, loc2 = pair[0].location, pair[1].location
         if not loc1.is_close_to(loc2):
             continue
         __conflicts.append(Conflict((loc1, loc2), pair))
     return __conflicts
コード例 #8
0
    def post(self):
        """
        Create a new conflict
        """
        user = users.get_current_user()
        if not user:
            self.redirect(users.create_login_url(self.request.uri))

        conflict = Conflict.new()
        Character(user=user, conflict=conflict).put()

        html_path = os.path.join(os.path.dirname(__file__), 'create_conflict.html')
        template_values = {'conflict': conflict}
        self.response.out.write(template.render(html_path, template_values))
コード例 #9
0
 def __get_next_conflict(self):
     __conflicts = []
     __conflicts_dist = []
     aircraft_pairs = list(itertools.combinations(self.aircrafts, 2))
     for pair in aircraft_pairs:
         if pair[0] == pair[1]:
             continue
         loc1, loc2 = pair[0].get_next_location(Aircraft.LOCATION_LEVEL_PRECISE), \
                      pair[1].get_next_location(Aircraft.LOCATION_LEVEL_PRECISE)
         if not loc1 or not loc2 or not loc1.is_close_to_plan(loc2):
             continue
         dist = loc1.get_distance_to(loc2)
         __conflicts.append(Conflict((loc1, loc2), pair))
         __conflicts_dist.append(dist)
     return __conflicts
コード例 #10
0
    def post(self):
        """
        Create a new conflict
        """
        user = users.get_current_user()
        if not user:
            self.redirect(users.create_login_url(self.request.uri))

        conflict = Conflict.new()
        Character(user=user, conflict=conflict).put()

        html_path = os.path.join(os.path.dirname(__file__),
                                 'create_conflict.html')
        template_values = {'conflict': conflict}
        self.response.out.write(template.render(html_path, template_values))
コード例 #11
0
    def __get_conflicts(self, is_next=False):
        # Remove departed aircraft or
        __conflicts = []
        aircraft_pairs = list(itertools.combinations(self.aircrafts, 2))
        for pair in aircraft_pairs:
            if pair[0] == pair[1]:
                continue

            if is_next:
                loc1, loc2 = pair[0].get_next_location(Aircraft.LOCATION_LEVEL_PRECISE), \
                             pair[1].get_next_location(Aircraft.LOCATION_LEVEL_PRECISE)
            else:
                loc1, loc2 = pair[0].precise_location, pair[1].precise_location
            if not loc1 or not loc2 or not loc1.is_close_to(loc2):
                continue

            __conflicts.append(Conflict((loc1, loc2), pair))
        return __conflicts
コード例 #12
0
 def conflicts(self):
     if self.aircraft1.location == self.aircraft2.location:
         return [Conflict(None, [self.aircraft1, self.aircraft2])]
     return []
コード例 #13
0
    def merge_with(self, ours, theirs):

        our_added = ours.get_added_tracks_compared_to(self)
        their_added = theirs.get_added_tracks_compared_to(self)

        our_removed = ours.get_removed_tracks_compared_to(self)
        their_removed = theirs.get_removed_tracks_compared_to(self)

        # Any removed from both
        our_removed_ids = [t.track_id for t in our_removed]
        their_removed_ids = [t.track_id for t in their_removed]
        both_removed_ids = [
            t for t in our_removed_ids if t in their_removed_ids
        ]

        # Remove the tracks from self
        both_removed = [
            t for t in self.tracks if t.track_id in both_removed_ids
        ]
        self.tracks = [
            t for t in self.tracks if t.track_id not in both_removed_ids
        ]

        for t in both_removed:
            # NOTE: This might not work if merging multiple times as the elements
            # will have changed after reconcilliation
            self.tree.find('LiveSet').find('Tracks').remove(t.elem)

        # Get all of the return value mappings for each track in each version
        # Added can be ignored because they won't have any conflicting sends (they are new)
        # As can removed
        # Only care about maintained?
        # We have track.return_map at this point for ours and theirs
        our_same = ours.get_intersection_tracks_compared_to(self)
        their_same = theirs.get_intersection_tracks_compared_to(self)

        def get_updated_tracks(branch, branch_same_tracks, base):
            base_tracks = base.tracks
            updated_tracks = []
            for track in branch_same_tracks:
                original_track = [
                    t for t in base_tracks if t.track_id == track.track_id
                ][0]
                # Create mapping of returns
                # See note in equal.py for why this is necessary
                branch_return = branch.get_return_tracks()
                base_return = base.get_return_tracks()
                return_intersection_ids = [
                    t.track_id for t in branch_return
                    if t.track_id in [b.track_id for b in base_return]
                ]
                # Get send ID mapping of these tracks to eachother
                # Their send id is based on their ordering
                # The key will be the base send ID
                # The value will be that send's ID in the branch track
                send_map = {}
                branch_r_ids = [t.track_id for t in branch_return]
                base_r_ids = [t.track_id for t in base_return]
                for i in return_intersection_ids:
                    br_loc = branch_r_ids.index(i)
                    ba_loc = base_r_ids.index(i)
                    send_map[ba_loc] = br_loc

                if not tree_equal(track.elem, original_track.elem, send_map):
                    updated_tracks.append(track)
                else:
                    pass
            return updated_tracks

        # Can guarantee only one track in array
        updated_in_ours = get_updated_tracks(ours, our_same, self)
        updated_in_theirs = get_updated_tracks(theirs, their_same, self)

        # Intersection of both of these
        conflicting_track_ids = [
            t.track_id for t in updated_in_ours
            if t.track_id in [h.track_id for h in updated_in_theirs]
        ]
        conflicts = [
            Conflict(*map(
                lambda x: ET.tostring(x.get_track_with_id(id_).elem).decode(),
                [self, ours, theirs])) for id_ in conflicting_track_ids
        ]

        updates = [
            t for t in updated_in_ours
            if t.track_id not in conflicting_track_ids
        ]
        updates += [
            t for t in updated_in_theirs
            if t.track_id not in conflicting_track_ids
        ]

        for track in updates:
            self.replace_track(track)

        # Can safely add the tracks now
        for track in our_added:
            self.add_track(track)

        for track in their_added:
            self.add_track(track)

        ours.reconcile_send_values()
        theirs.reconcile_send_values()
        # Await conflicts here
        # need to make barebones files
        # notify macOS app using webbrowser
        # await file creation of some variety
        # if it's a normal track, get both versions leave returns? which returns?
        # if it's a return track, get a track as well that uses
        # it
        if len(conflicts) > 0:
            conflict_files = []
            for i, conf in enumerate(conflicts):
                # Create a new project from blank.xml to hold the sample project for viewing the conflicts
                sample_root = ET.parse('.merge/blank.xml').getroot()

                # Remove any residual tracks from the blank file's tracks
                sample_tracks = sample_root.find('LiveSet').find('Tracks')
                for c in list(sample_tracks):
                    sample_tracks.remove(c)

                # Add our branch to sample
                sample_ours = ET.fromstring(conf.ours)
                sample_ours.attrib['Id'] = "10"
                sample_ours.find('Name').find(
                    'UserName').attrib['Value'] = 'Ours'

                # Add their branch to sample
                sample_theirs = ET.fromstring(conf.theirs)
                sample_theirs.attrib['Id'] = "20"
                sample_theirs.find('Name').find(
                    'UserName').attrib['Value'] = 'Theirs'

                # Remove send values
                sample_ours_sends = sample_ours.find('DeviceChain').find(
                    'Mixer').find('Sends')
                sample_theirs_sends = sample_theirs.find('DeviceChain').find(
                    'Mixer').find('Sends')
                for c in list(sample_ours_sends):
                    sample_ours_sends.remove(c)
                for c in list(sample_theirs_sends):
                    sample_theirs_sends.remove(c)

                # Add our tracks to the sample
                sample_tracks.append(sample_ours)
                sample_tracks.append(sample_theirs)
                sample_tree = ET.ElementTree(sample_root)

                # Create a temporary folder to hold the samples
                temp_folder_name = '.conftemp'
                if not os.path.exists(temp_folder_name):
                    os.makedirs(temp_folder_name)

                # Create the sample file path
                filename = 'conf_' + str(i) + '.xml'
                full_path = temp_folder_name + '/' + filename
                full_als_path = temp_folder_name + '/' + 'conf_' + str(
                    i) + '.als'

                # Write the samples to the folder
                sample_tree.write(full_path,
                                  encoding='utf-8',
                                  xml_declaration=True)
                with open(full_path,
                          'rb') as f_in, gzip.open(full_als_path,
                                                   'wb') as f_out:
                    f_out.writelines(f_in)

                # Add the file path to the list of sample file paths
                conflict_files.append(full_als_path)

            # Make a call to the url scheme for the jackdaw app
            # appending the paths of the sample files
            url_scheme = 'jackdaw://merge/'
            for cpath in conflict_files:
                url_scheme += cpath + '+'
            url_scheme = url_scheme[:-1]
            webbrowser.open(url_scheme)

            # Wait until the resolution file is present
            # created by the jackdaw app
            import time
            done_file = '.merge/done'
            while not os.path.exists(done_file):
                time.sleep(1)

            resolutions = []

            # Eventually make this so that it reloads from
            # the actual als file so that user edits are saved

            # Open the resolution file
            with open(done_file) as json_data:
                # Load the contents of the file into json
                conf_branch_map = json.load(json_data)
                for conf, branch in conf_branch_map.items():
                    # For each path: true/false ours/theirs
                    # Get the index of the resolution from the original list of files
                    conf_i = conflict_files.index('.conftemp/' + conf)
                    # Get the Conflict object for this version
                    conflict = conflicts[conf_i]
                    if branch:
                        resolutions.append(ours)
                    else:
                        resolutions.append(theirs)

            for i, track_id in enumerate(conflicting_track_ids):
                # Get the chosen version
                chosen_branch = resolutions[i]
                # Get the track from the chosen branch with the selected ID
                to_replace_with = chosen_branch.get_track_with_id(track_id)
                # Replace the track with that ID
                self.replace_track(to_replace_with)

            os.remove('.merge/done')
            import shutil
            shutil.rmtree('.conftemp')

        self.move_return_tracks_to_end()
        self.reconcile_send_values()

        self.amend_track_collisions()

        self.generate_sends()
        self.amend_global_id_collisions()
        self.amend_sends_pre()
コード例 #14
0
def main(args):
    level_data = None

    # Read server messages from stdin.
    msg_server_action("Starfish")
    level_data = sys.stdin

    # Create client using server messages
    starfish_client = Client(level_data)
    current_state = starfish_client.initial_state
    walls = starfish_client.walls

    # Solve and print
    # TODO: configuration when an agent is blocking all the others
    solution = starfish_client.solve_level()
    if isListEmpty(solution):
        coop = Cooperation(current_state, starfish_client.goal_state,
                           starfish_client.walls)
        queries = coop.get_needed_coop()
        solution = starfish_client.queries_to_action(queries, current_state)

    nb_agents = len(solution)
    printer = ";".join(['{}'] * nb_agents)

    verified = False
    while (not isListEmpty(solution)) or (verified == False):
        missing_goals = get_missing_goals(current_state,
                                          starfish_client.goal_state)

        if len(missing_goals) == 0:
            verified = True

        for i, elt in enumerate(solution):
            if len(elt) == 0 and str(i) not in missing_goals:
                padding_state = current_state
                solution[i].append(padding_state)
                solution[i][-1].action = Action(ActionType.NoOp, None, None)

            elif len(elt) == 0 and str(
                    i
            ) in missing_goals:  # and not starfish_client.agents[i].has_goal():
                starfish_client.agents[i].current_state = current_state
                starfish_client.agents[i].assign_goal(
                    starfish_client.goal_state, (missing_goals[str(i)][0], 0))
                new_path = starfish_client.agents[i].find_path_to_goal(
                    starfish_client.walls)

                if new_path is not None and len(new_path) > 0:
                    solution[i].extend(new_path)
                else:
                    padding_state = current_state
                    solution[i].append(padding_state)
                    solution[i][-1].action = Action(ActionType.NoOp, None,
                                                    None)

        # grabbing state for each agent
        state = [elt[0] for elt in solution]

        joint_action = [agent.action for agent in state]

        index_non_applicable, current_state, is_applicable = check_action(
            joint_action, current_state, walls)
        msg_server_comment(
            printer.format(*joint_action) +
            " - applicable: {}".format(is_applicable))

        # if there is a conflict between agents
        if not is_applicable:
            conflict = Conflict(current_state, index_non_applicable,
                                joint_action, solution, walls)
            agents, actions = conflict.handle_conflicts()

            joint_action = [Action(ActionType.NoOp, None, None)] * nb_agents
            for (agent, action) in zip(agents, actions):
                if action is not None:
                    joint_action[int(agent)] = action
                    # forgetting goal in order to help fix the conflict
                    padding_state = current_state
                    solution[int(agent)] = [padding_state]
                    solution[int(agent)][-1].action = Action(
                        ActionType.NoOp, None, None)
                    solution[int(agent)].append(solution[int(agent)][-1])
                    starfish_client.agents[int(agent)].forget_goal()

                else:
                    box_key = starfish_client.agents[int(agent)].box_key
                    starfish_client.agents[int(agent)] = Agent(
                        current_state, agent)
                    starfish_client.agents[int(agent)].assign_goal(
                        starfish_client.goal_state, box_key)
                    new_path_to_goal = starfish_client.agents[int(
                        agent)].find_path_to_goal(walls)
                    solution[int(agent)] = new_path_to_goal
                    # print(new_path_to_goal)
                    # sys.exit()

            # updating state
            _, current_state, _ = check_action(joint_action, current_state,
                                               walls)
            msg_server_comment("New action: " + printer.format(*joint_action))

        msg_server_action(printer.format(*joint_action))

        if is_applicable:
            for i, elt in enumerate(solution):
                elt.pop(0)

        response = level_data.readline().rstrip()
        if 'false' in response:
            msg_server_err("Server answered with error to the action " +
                           printer.format(*joint_action))