1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3""" 4Comparators 5""" 6 7from functools import cmp_to_key 8 9 10def marker_comparator_predicate(match): 11 """ 12 Match predicate used in comparator 13 """ 14 return ( 15 not match.private 16 and match.name not in ('proper_count', 'title') 17 and not (match.name == 'container' and 'extension' in match.tags) 18 and not (match.name == 'other' and match.value == 'Rip') 19 ) 20 21 22def marker_weight(matches, marker, predicate): 23 """ 24 Compute the comparator weight of a marker 25 :param matches: 26 :param marker: 27 :param predicate: 28 :return: 29 """ 30 return len(set(match.name for match in matches.range(*marker.span, predicate=predicate))) 31 32 33def marker_comparator(matches, markers, predicate): 34 """ 35 Builds a comparator that returns markers sorted from the most valuable to the less. 36 37 Take the parts where matches count is higher, then when length is higher, then when position is at left. 38 39 :param matches: 40 :type matches: 41 :param markers: 42 :param predicate: 43 :return: 44 :rtype: 45 """ 46 47 def comparator(marker1, marker2): 48 """ 49 The actual comparator function. 50 """ 51 matches_count = marker_weight(matches, marker2, predicate) - marker_weight(matches, marker1, predicate) 52 if matches_count: 53 return matches_count 54 55 # give preference to rightmost path 56 return markers.index(marker2) - markers.index(marker1) 57 58 return comparator 59 60 61def marker_sorted(markers, matches, predicate=marker_comparator_predicate): 62 """ 63 Sort markers from matches, from the most valuable to the less. 64 65 :param markers: 66 :type markers: 67 :param matches: 68 :type matches: 69 :param predicate: 70 :return: 71 :rtype: 72 """ 73 return sorted(markers, key=cmp_to_key(marker_comparator(matches, markers, predicate=predicate))) 74