Skip to content
Snippets Groups Projects
graph3.py 4.05 KiB
Newer Older
  • Learn to ignore specific revisions
  • import argparse
    import cgi
    import datetime
    
    import pydot
    import simplejson as json
    
    from synapse.events import FrozenEvent
    from synapse.util.frozenutils import unfreeze
    
    
    # Copyright 2016 OpenMarket Ltd
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    
    def make_graph(file_name, room_id, file_prefix, limit):
    
        print("Reading lines")
    
        with open(file_name) as f:
            lines = f.readlines()
    
    
    
        events = [FrozenEvent(json.loads(line)) for line in lines]
    
    
        print("Loaded events.")
    
    
        events.sort(key=lambda e: e.depth)
    
    
        print("Sorted events")
    
    
        if limit:
    
    Amber Brown's avatar
    Amber Brown committed
            events = events[-int(limit) :]
    
    
        node_map = {}
    
        graph = pydot.Dot(graph_name="Test")
    
        for event in events:
            t = datetime.datetime.fromtimestamp(
                float(event.origin_server_ts) / 1000
    
    Amber Brown's avatar
    Amber Brown committed
            ).strftime("%Y-%m-%d %H:%M:%S,%f")
    
    
            content = json.dumps(unfreeze(event.get_dict()["content"]), indent=4)
            content = content.replace("\n", "<br/>\n")
    
    
            content = []
            for key, value in unfreeze(event.get_dict()["content"]).items():
                if value is None:
                    value = "<null>"
    
                    pass
                else:
                    value = json.dumps(value)
    
                content.append(
    
    Amber Brown's avatar
    Amber Brown committed
                    "<b>%s</b>: %s,"
                    % (
                        cgi.escape(key, quote=True).encode("ascii", "xmlcharrefreplace"),
                        cgi.escape(value, quote=True).encode("ascii", "xmlcharrefreplace"),
    
                    )
                )
    
            content = "<br/>\n".join(content)
    
    
    
            label = (
                "<"
                "<b>%(name)s </b><br/>"
                "Type: <b>%(type)s </b><br/>"
                "State key: <b>%(state_key)s </b><br/>"
                "Content: <b>%(content)s </b><br/>"
                "Time: <b>%(time)s </b><br/>"
                "Depth: <b>%(depth)s </b><br/>"
                ">"
            ) % {
                "name": event.event_id,
                "type": event.type,
                "state_key": event.get("state_key", None),
                "content": content,
                "time": t,
                "depth": event.depth,
            }
    
    
    Amber Brown's avatar
    Amber Brown committed
            node = pydot.Node(name=event.event_id, label=label)
    
    
            node_map[event.event_id] = node
            graph.add_node(node)
    
    
        print("Created Nodes")
    
    
        for event in events:
            for prev_id, _ in event.prev_events:
                try:
                    end_node = node_map[prev_id]
    
    Amber Brown's avatar
    Amber Brown committed
                    end_node = pydot.Node(name=prev_id, label="<<b>%s</b>>" % (prev_id,))
    
    
                    node_map[prev_id] = end_node
                    graph.add_node(end_node)
    
                edge = pydot.Edge(node_map[event.event_id], end_node)
                graph.add_edge(edge)
    
    
        print("Created edges")
    
    Amber Brown's avatar
    Amber Brown committed
        graph.write("%s.dot" % file_prefix, format="raw", prog="dot")
    
    Amber Brown's avatar
    Amber Brown committed
        graph.write_svg("%s.svg" % file_prefix, prog="dot")
    
    Amber Brown's avatar
    Amber Brown committed
    
    
    if __name__ == "__main__":
        parser = argparse.ArgumentParser(
            description="Generate a PDU graph for a given room by reading "
    
    Amber Brown's avatar
    Amber Brown committed
            "from a file with line deliminated events. \n"
            "Requires pydot."
    
        )
        parser.add_argument(
    
    Amber Brown's avatar
    Amber Brown committed
            "-p",
            "--prefix",
            dest="prefix",
    
            help="String to prefix output files with",
    
    Amber Brown's avatar
    Amber Brown committed
            default="graph_output",
    
    Amber Brown's avatar
    Amber Brown committed
        parser.add_argument("-l", "--limit", help="Only retrieve the last N events.")
        parser.add_argument("event_file")
        parser.add_argument("room")
    
    
        args = parser.parse_args()
    
        make_graph(args.event_file, args.room, args.prefix, args.limit)