Unifies the currently saved IPs.
        Unification is based on last IP segment.
        So if there are is e.g. 192.168.128.121 and 192.168.128.122 tthey will be merged to 192.168.128.121.
        This is a little aggressive but the spammers are aggressive, too.
        :return: number of merged ips
        :rtype: int

def unify_ips():
        """
        Unifies the currently saved IPs.
        Unification is based on last IP segment.
        So if there are is e.g. 192.168.128.121 and 192.168.128.122 tthey will be merged to 192.168.128.121.
        This is a little aggressive but the spammers are aggressive, too.
        :return: number of merged ips
        :rtype: int
        """
        processed_ips = 0
        ips = {}

        # query for the IPs, also includes the starred IPs
        for ip in IP.objects.raw(
            'select distinct a.id, a.seg_0, a.seg_1, a.seg_2 '
            'from ip_assembler_ip a, ip_assembler_ip b '
            'where a.seg_0 = b.seg_0 and a.seg_1 = b.seg_1 and a.seg_2 = b.seg_2 and a.seg_3 != b.seg_3 '
            'order by a.seg_0, a.seg_1, a.seg_2',
        ):
            key = '%d.%d.%d' % (int(ip.seg_0), int(ip.seg_1), int(ip.seg_2))
            if not key in ips:
                ips[key] = []
            ips[key].append(ip)

        for key, ip_list in ips.items():
            # check if a starred ip is in list
            starred_ip = None
            for ip in ip_list:
                if ip.seg_3 == '*':
                    starred_ip = ip

            if starred_ip is None:
                IP.objects.create(seg_0=ip_list[0].seg_0, seg_1=ip_list[0].seg_1, seg_2=ip_list[0].seg_2, seg_3='*', )

            # delete the other ips
            for ip in ip_list:
                if ip != starred_ip:
                    processed_ips += 1
                    ip.delete()

        return processed_ips