<commit_before>import re
import xbmc
from collections import namedtuple
from os.path import split, basename, dirname

from lib.libs.pykodi import log

SortedDisplay = namedtuple('SortedDisplay', ['sort', 'display'])

def natural_sort(string, split_regex=re.compile(r'([0-9]+)')):
    return [int(text) if text.isdigit() else text.lower() for text in re.split(split_regex, string)]

def get_pathsep(path):
    # The path separator can go either way on Windows, C:\Videos or smb://SERVER/Videos
    return '\\' if '\\' in path else '/'

def get_simpledict_updates(original, newdict):
    return dict(pair for pair in newdict.iteritems() if pair[1] != original.get(pair[0]))

# TODO: Load from advancedsettings.xml
moviestacking = [re.compile(r'(.*?)([ _.-]*(?:cd|dvd|p(?:ar)?t|dis[ck])[ _.-]*[0-9]+)(.*?)(\.[^.]+)$', re.IGNORECASE),
    re.compile(r'(.*?)([ _.-]*(?:cd|dvd|p(?:ar)?t|dis[ck])[ _.-]*[a-d])(.*?)(\.[^.]+)$', re.IGNORECASE),
    re.compile(r'(.*?)([ ._-]*[a-d])(.*?)(\.[^.]+)$', re.IGNORECASE)
]
def get_movie_path_list(stackedpath):
    """Returns a list of filenames that can be used to find a movie's supporting files.
    The list includes both possible filenames for stacks (from the first filename or from the common base of all
    provided parts), and the parent directory of VIDEO_TS/BDMV. If neither applies, returns a list of one item,
    the original path.
    Check for the supporting files from each of these results."""
    result = []
    if not stackedpath.startswith('stack://'):
        result = [stackedpath]
    else:
        firstpath, path2 = stackedpath[8:].split(' , ')[0:2]

        path, filename = split(firstpath)
        if filename:
            filename2 = basename(path2)
            for regex in moviestacking:
                offset = 0
                while True:
                    match = regex.match(filename, offset)
                    match2 = regex.match(filename2, offset)
                    if match != None and match2 != None and match.group(1).lower() == match2.group(1).lower():
                        if match.group(2).lower() == match2.group(2).lower():
                            offset = match.start(3)
                            continue
                        result = [firstpath, path + get_pathsep(path) + filename[:offset] +
                            match.group(1).rstrip() + match.group(4)]
                    break
        else: # folder stacking
            pass # I can't even get Kodi to add stacked VIDEO_TS rips period
        if not result:
            log("Couldn't get an unstacked path from \"{0}\"".format(stackedpath), xbmc.LOGWARNING)
            result = [firstpath]
    if basename(dirname(result[0])) in ('VIDEO_TS', 'BDMV'):
        result.append(dirname(dirname(result[0])) + get_pathsep(result[0]) + basename(result[0]))
    return result

replace_chars = ':?"/\\<>*|'
replace_with = ('', '_', '+', '-')
replace_colon_with = (' -',)
def iter_possible_cleannames(originalname, uniqueslug=None):
    if uniqueslug:
        firstname = originalname + '_' + uniqueslug<commit_msg>fix: artwork paths for stacked movie files<commit_after>import re
import xbmc
from collections import namedtuple
from os.path import split, basename, dirname

from lib.libs.pykodi import log

SortedDisplay = namedtuple('SortedDisplay', ['sort', 'display'])

def natural_sort(string, split_regex=re.compile(r'([0-9]+)')):
    return [int(text) if text.isdigit() else text.lower() for text in re.split(split_regex, string)]

def get_pathsep(path):
    # The path separator can go either way on Windows, C:\Videos or smb://SERVER/Videos
    return '\\' if '\\' in path else '/'

def get_simpledict_updates(original, newdict):
    return dict(pair for pair in newdict.iteritems() if pair[1] != original.get(pair[0]))

# TODO: Load from advancedsettings.xml
moviestacking = [re.compile(r'(.*?)([ _.-]*(?:cd|dvd|p(?:ar)?t|dis[ck])[ _.-]*[0-9]+)(.*?)(\.[^.]+)$', re.IGNORECASE),
    re.compile(r'(.*?)([ _.-]*(?:cd|dvd|p(?:ar)?t|dis[ck])[ _.-]*[a-d])(.*?)(\.[^.]+)$', re.IGNORECASE),
    re.compile(r'(.*?)([ ._-]*[a-d])(.*?)(\.[^.]+)$', re.IGNORECASE)
]
def get_movie_path_list(stackedpath):
    """Returns a list of filenames that can be used to find a movie's supporting files.
    The list includes both possible filenames for stacks (from the first filename or from the common base of all
    provided parts), and the parent directory of VIDEO_TS/BDMV. If neither applies, returns a list of one item,
    the original path.
    Check for the supporting files from each of these results."""
    result = []
    if not stackedpath.startswith('stack://'):
        result = [stackedpath]
    else:
        firstpath, path2 = stackedpath[8:].split(' , ')[0:2]

        path, filename = split(firstpath)
        if filename:
            filename2 = basename(path2)
            for regex in moviestacking:
                offset = 0
                while True:
                    match = regex.match(filename, offset)
                    match2 = regex.match(filename2, offset)
                    if match != None and match2 != None and match.group(1).lower() == match2.group(1).lower():
                        if match.group(2).lower() == match2.group(2).lower():
                            offset = match.start(3)
                            continue
                        # DEPRECATED: Returning the path to part1 doesn't seem to work in Kodi.
                        #  Not sure where I got that idea, but it shouldn't be used.
                        # Also, AB created the ones missing `group(3)` for awhile, but it is wrong.
                        # Adding both here so that file scanning still finds them.
                        pathbase = path + get_pathsep(path) + filename[:offset] + match.group(1)
                        result = [
                            pathbase + match.group(3) + match.group(4),
                            pathbase + match.group(4),
                            firstpath]
                    break
        else: # folder stacking
            pass # I can't even get Kodi to add stacked VIDEO_TS rips period
        if not result:
            log("Couldn't get an unstacked path from \"{0}\"".format(stackedpath), xbmc.LOGWARNING)
            result = [firstpath]
    if basename(dirname(result[0])) in ('VIDEO_TS', 'BDMV'):
        result.append(dirname(dirname(result[0])) + get_pathsep(result[0]) + basename(result[0]))
    return result

replace_chars = ':?"/\\<>*|'
replace_with = ('', '_', '+', '-')
replace_colon_with = (' -',)
def iter_possible_cleannames(originalname, uniqueslug=None):
    if uniqueslug:
        firstname = originalname + '_' + uniqueslug
{'fraction_non_alphanumeric': 0.14886925265837953, 'fraction_numerical': 0.009585143028306126, 'mean_word_length': 2.4945054945054945, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3466443', 'n_tokens_mistral': 2086, 'n_tokens_neox': 2012, 'n_words': 563}