1import os
2import sys
3from urllib.request import urlopen
4from urllib.parse import unquote
5
6
7PGN_ENCODING = "latin_1"
8
9
10def splitUri(uri):
11    uri = unquote(uri)  # escape special chars
12    uri = uri.strip('\r\n\x00')  # remove \r\n and NULL
13    if sys.platform == "win32":
14        return uri.split(":///")
15    else:
16        return uri.split("://")
17
18
19def protoopen(uri, encoding=PGN_ENCODING):
20    """ Function for opening many things """
21    splitted = splitUri(uri)
22
23    if splitted[0] == "file":
24        uri = splitted[1]
25
26    try:
27        handle = open(unquote(uri), "r", encoding=encoding, newline="")
28        handle.pgn_encoding = "utf-8" if os.path.basename(uri).startswith("lichess_") else encoding
29        return handle
30    except (IOError, OSError):
31        pass
32
33    try:
34        return urlopen(uri)
35    except (IOError, OSError):
36        pass
37
38    raise IOError("Protocol isn't supported by pychess")
39
40
41def protosave(uri, append=False):
42    """ Function for saving many things """
43
44    splitted = splitUri(uri)
45
46    if splitted[0] == "file":
47        if append:
48            return open(splitted[1], "a", encoding=PGN_ENCODING, newline="")
49        return open(splitted[1], "w", newline="")
50    elif len(splitted) == 1:
51        if append:
52            return open(splitted[0], "a", encoding=PGN_ENCODING, newline="")
53        return open(splitted[0], "w", encoding=PGN_ENCODING, newline="")
54
55    raise IOError("PyChess doesn't support writing to protocol")
56
57
58def isWriteable(uri):
59    """ Returns true if protoopen can open a write pipe to the uri """
60
61    splitted = splitUri(uri)
62
63    if splitted[0] == "file":
64        return os.access(splitted[1], os.W_OK)
65    elif len(splitted) == 1:
66        return os.access(splitted[0], os.W_OK)
67
68    return False
69