Exemplo n.º 1
0
 def update_summary(segment):
     """
     Calculate summary for segment and all nested segments
     """
     services = {}
     subscribers = {}
     # Calculate direct segments' coverage
     for o in six.itervalues(segment["objects"]):
         update_dict(services, o["services"])
         update_dict(subscribers, o["subscribers"])
     # Flatten objects
     segment["objects"] = sorted(six.itervalues(segment["objects"]),
                                 key=lambda x: -x["weight"])
     # Calculate children's coverage
     for s in six.itervalues(segment["segments"]):
         update_summary(s)
         update_dict(services, s["services"])
         update_dict(subscribers, s["subscribers"])
     segment["segments"] = sorted(six.itervalues(segment["segments"]),
                                  key=lambda x: -x["weight"])
     segment["services"] = services
     segment["subscribers"] = subscribers
     segment["summary"] = {
         "service": services,
         "subscriber": subscribers
     }
     segment["weight"] = ServiceSummary.get_weight(segment["summary"])
Exemplo n.º 2
0
    def get_ajax_data(self, **kwargs):
        def update_dict(d, s):
            for k in s:
                if k in d:
                    d[k] += s[k]
                else:
                    d[k] = s[k]

        zoom = int(self.handler.get_argument("z"))
        west = float(self.handler.get_argument("w"))
        east = float(self.handler.get_argument("e"))
        north = float(self.handler.get_argument("n"))
        south = float(self.handler.get_argument("s"))
        ms = int(self.handler.get_argument("maintenance"))
        active_layers = [
            l_r for l_r in self.get_pop_layers()
            if l_r.min_zoom <= zoom <= l_r.max_zoom
        ]
        alarms = []
        res = {}
        services = {}
        subscribers = {}
        t_data = defaultdict(list)
        mos = ManagedObject.objects.filter(is_managed=True).values(
            "id", "name", "x", "y")
        if not self.current_user.is_superuser:
            mos = mos.filter(administrative_domain__in=UserAccess.get_domains(
                self.current_user))
        for mo in mos:
            res[mo.pop("id")] = mo
        mos_id = list(res.keys())
        if ms == 0:
            mos_id = list(
                set(list(res.keys())) - set(Maintenance.currently_affected()))
        for a in ActiveAlarm._get_collection().find(
            {"managed_object": {
                "$in": mos_id,
                "$exists": True
            }},
            {
                "_id": 1,
                "managed_object": 1,
                "direct_subscribers": 1,
                "direct_services": 1
            },
        ):
            s_sub, s_service = {}, {}
            if a.get("direct_subscribers"):
                s_sub = {
                    dsub["profile"]: dsub["summary"]
                    for dsub in a["direct_subscribers"]
                }
            if a.get("direct_services"):
                s_service = {
                    dserv["profile"]: dserv["summary"]
                    for dserv in a["direct_services"]
                }
            mo = res.get(a["managed_object"])
            if not mo:
                continue
            if mo["x"] and mo["y"]:
                w = ServiceSummary.get_weight({
                    "subscriber": s_sub,
                    "service": s_service
                })
                # @todo: Should we add the object's weight to summary?
                # @todo: Check west/south hemisphere
                if active_layers and west <= mo["x"] <= east and south <= mo[
                        "y"] <= north:
                    t_data[mo["x"], mo["y"]] += [(mo, w)]
            else:
                w = 0
            alarms += [{
                "alarm_id": str(a.get("_id")),
                "managed_object": mo["name"],
                "x": mo["x"],
                "y": mo["y"],
                "w": max(w, 1),
            }]
            if s_service:
                update_dict(services, s_service)
            if s_sub:
                update_dict(subscribers, s_sub)
        links = None
        o_seen = set()
        points = None
        o_data = {}
        if t_data and active_layers:
            # Create lines
            bbox = get_bbox(west, east, north, south)
            lines = []
            for d in ObjectConnection._get_collection().find(
                {
                    "type": "pop_link",
                    "layer": {
                        "$in": [a_l.id for a_l in active_layers]
                    },
                    "line": {
                        "$geoIntersects": {
                            "$geometry": bbox
                        }
                    },
                },
                {
                    "_id": 0,
                    "connection": 1,
                    "line": 1
                },
            ):
                for c in d["line"]["coordinates"]:
                    if tuple(c) in t_data:
                        for c in d["line"]["coordinates"]:
                            tc = tuple(c)
                            o_data[tc] = t_data.get(tc, [])
                        o_seen.add(tuple(c))
                        lines += [d["line"]]
                        break
            if lines:
                links = geojson.FeatureCollection(features=lines)
            # Create points
            points = []
            for x, y in o_data:
                data = {}
                for mo, w in o_data[x, y]:
                    if mo not in data:
                        data[mo] = w
                data = sorted(data, key=lambda z: data[z],
                              reverse=True)[:self.TOOLTIP_LIMIT]
                points += [
                    geojson.Feature(
                        geometry=geojson.Point(coordinates=[x, y]),
                        properties={
                            "alarms":
                            len(t_data[x, y]),
                            "objects": [{
                                "id": mo.id,
                                "name": mo.name,
                                "address": mo.address
                            } for mo in mos],
                        },
                    )
                ]
            points = geojson.FeatureCollection(features=points)
        return {
            "alarms":
            alarms,
            "summary":
            self.f_glyph_summary({
                "service": services,
                "subscriber": subscribers
            }),
            "links":
            links,
            "pops":
            points,
        }
Exemplo n.º 3
0
    def get_data(self):
        def get_segment_path(segment):
            if segment.parent:
                return segment_path[segment.parent] + [segment]
            else:
                return [segment]

        def update_summary(segment):
            """
            Calculate summary for segment and all nested segments
            """
            services = {}
            subscribers = {}
            # Calculate direct segments' coverage
            for o in segment["objects"].values():
                update_dict(services, o["services"])
                update_dict(subscribers, o["subscribers"])
            # Flatten objects
            segment["objects"] = sorted(segment["objects"].values(), key=lambda x: -x["weight"])
            # Calculate children's coverage
            for s in segment["segments"].values():
                update_summary(s)
                update_dict(services, s["services"])
                update_dict(subscribers, s["subscribers"])
            segment["segments"] = sorted(segment["segments"].values(), key=lambda x: -x["weight"])
            segment["services"] = services
            segment["subscribers"] = subscribers
            segment["summary"] = {"service": services, "subscriber": subscribers}
            segment["weight"] = ServiceSummary.get_weight(segment["summary"])

        def update_dict(d1, d2):
            for k in d2:
                if k in d1:
                    d1[k] += d2[k]
                else:
                    d1[k] = d2[k]

        segment_path = cachetools.LRUCache(maxsize=10000)
        segment_path.__missing__ = get_segment_path
        # Build tree
        tree = {"segment": None, "segments": {}, "objects": {}, "subscribers": {}, "services": {}}
        if self.current_user.is_superuser:
            qs = ActiveAlarm.objects.filter(root__exists=False)
        else:
            qs = ActiveAlarm.objects.filter(
                adm_path__in=self.get_user_domains(), root__exists=False
            )
        now = datetime.datetime.now()
        for alarm in qs:
            if not alarm.total_services and not alarm.total_subscribers:
                continue
            ct = tree
            for sp in segment_path[alarm.managed_object.segment]:
                if sp.id not in ct["segments"]:
                    ct["segments"][sp.id] = {
                        "segment": sp,
                        "segments": {},
                        "objects": {},
                        "subscribers": {},
                        "services": {},
                    }
                ct = ct["segments"][sp.id]
            subscribers = SummaryItem.items_to_dict(alarm.total_subscribers)
            services = SummaryItem.items_to_dict(alarm.total_services)
            ct["objects"][alarm.id] = {
                "object": alarm.managed_object,
                "alarm": alarm,
                "severity": alarm.severity,
                "timestamp": alarm.timestamp,
                "duration": now - alarm.timestamp,
                "escalation_tt": alarm.escalation_tt,
                "subscribers": subscribers,
                "services": services,
                "summary": {"subscriber": subscribers, "service": services},
            }
            ct["objects"][alarm.id]["weight"] = ServiceSummary.get_weight(
                ct["objects"][alarm.id]["summary"]
            )
        # Calculate segment summaries
        update_summary(tree)
        # Calculate total summaries
        services = {}
        subscribers = {}
        for s in tree["segments"]:
            update_dict(services, s["summary"]["service"])
            update_dict(subscribers, s["summary"]["subscriber"])
        for o in tree["objects"]:
            update_dict(services, o["summary"]["service"])
            update_dict(subscribers, o["summary"]["subscriber"])
        tree["summary"] = {"subscriber": subscribers, "service": services}
        return tree
Exemplo n.º 4
0
    def get_ajax_data(self, **kwargs):
        def update_dict(d, s):
            for k in s:
                if k in d:
                    d[k] += s[k]
                else:
                    d[k] = s[k]

        zoom = int(self.handler.get_argument("z"))
        west = float(self.handler.get_argument("w"))
        east = float(self.handler.get_argument("e"))
        north = float(self.handler.get_argument("n"))
        south = float(self.handler.get_argument("s"))
        ms = int(self.handler.get_argument("maintenance"))
        active_layers = [
            l for l in self.get_pop_layers()
            if l.min_zoom <= zoom <= l.max_zoom
        ]
        alarms = []
        services = {}
        subscribers = {}
        t_data = defaultdict(list)
        if self.current_user.is_superuser:
            qs = ActiveAlarm.objects.all()
        else:
            qs = ActiveAlarm.objects.filter(
                adm_path__in=self.get_user_domains())
        if ms == 0:
            # Filter out equipment under maintenance
            qs = qs.filter(
                managed_object__nin=Maintenance.currently_affected())
        for a in qs.only("id", "managed_object", "direct_subscribers",
                         "direct_services"):
            s_sub, s_service = {}, {}
            if a.direct_subscribers:
                s_sub = SummaryItem.items_to_dict(a.direct_subscribers)
            if a.direct_services:
                s_service = SummaryItem.items_to_dict(a.direct_services)
            mo = a.managed_object
            if not mo:
                continue
            if mo.x and mo.y:
                w = ServiceSummary.get_weight({
                    "subscriber": s_sub,
                    "service": s_service
                })
                # @todo: Should we add the object's weight to summary?
                # @todo: Check west/south hemisphere
                if active_layers and west <= mo.x <= east and south <= mo.y <= north:
                    t_data[mo.x, mo.y] += [(mo, w)]
            else:
                w = 0
            alarms += [{
                "alarm_id": str(a.id),
                "managed_object": mo.name,
                "x": mo.x,
                "y": mo.y,
                "w": max(w, 1),
            }]
            if s_service:
                update_dict(services, s_service)
            if s_sub:
                update_dict(subscribers, s_sub)
        links = None
        o_seen = set()
        points = None
        o_data = {}
        if t_data and active_layers:
            # Create lines
            bbox = get_bbox(west, east, north, south)
            lines = []
            for d in ObjectConnection._get_collection().find(
                {
                    "type": "pop_link",
                    "layer": {
                        "$in": [l.id for l in active_layers]
                    },
                    "line": {
                        "$geoIntersects": {
                            "$geometry": bbox
                        }
                    },
                },
                {
                    "_id": 0,
                    "connection": 1,
                    "line": 1
                },
            ):
                for c in d["line"]["coordinates"]:
                    if tuple(c) in t_data:
                        for c in d["line"]["coordinates"]:
                            tc = tuple(c)
                            o_data[tc] = t_data.get(tc, [])
                        o_seen.add(tuple(c))
                        lines += [d["line"]]
                        break
            if lines:
                links = geojson.FeatureCollection(features=lines)
            # Create points
            points = []
            for x, y in o_data:
                mos = {}
                for mo, w in o_data[x, y]:
                    if mo not in mos:
                        mos[mo] = w
                mos = sorted(mos, key=lambda z: mos[z],
                             reverse=True)[:self.TOOLTIP_LIMIT]
                points += [
                    geojson.Feature(
                        geometry=geojson.Point(coordinates=[x, y]),
                        properties={
                            "alarms":
                            len(t_data[x, y]),
                            "objects": [{
                                "id": mo.id,
                                "name": mo.name,
                                "address": mo.address
                            } for mo in mos],
                        },
                    )
                ]
            points = geojson.FeatureCollection(features=points)
        return {
            "alarms":
            alarms,
            "summary":
            self.f_glyph_summary({
                "service": services,
                "subscriber": subscribers
            }),
            "links":
            links,
            "pops":
            points,
        }