def convert_win32_to_posix(rootfs, cwd, path): # rootfs is a concrete path. rootfs = Path(rootfs) # cwd and path are pure paths cwd = PurePosixPath(cwd[1:]) result = None # Things are complicated here. # See https://docs.microsoft.com/zh-cn/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN if PureWindowsPath(path).is_absolute(): if (len(path) >= 2 and path[0] == '\\' and path[1] == '\\') or \ (len(path) >= 3 and path[0].isalpha() and path[2] == '\\'): # \\.\PhysicalDrive0 or \\Server\Share\Directory or X:\ # UNC path should be handled in fs mapping. If not, append it to rootfs directly. pw = PureWindowsPath(path) result = rootfs / pw.relative_to(pw.anchor) else: # code should never reach here. result = rootfs / path else: if len( path ) >= 3 and path[:3] == r'\\?' or path[:3] == r'\??': # \??\ or \\?\ or \Device\.. # Similair to \\.\, it should be handled in fs mapping. pw = PureWindowsPath(path) result = rootfs / cwd / pw.relative_to(pw.anchor) else: # a normal relative path result = rootfs / cwd / PureWindowsPath(path) return result
def convert_win32_to_posix(rootfs: Union[str, Path], cwd: str, path: str) -> Path: _rootfs = Path(rootfs) _cwd = PurePosixPath(cwd[1:]) # Things are complicated here. # See https://docs.microsoft.com/zh-cn/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN if PureWindowsPath(path).is_absolute(): if (len(path) >= 2 and path.startswith(r'\\')) or \ (len(path) >= 3 and path[0].isalpha() and path[1:3] == ':\\'): # \\.\PhysicalDrive0 or \\Server\Share\Directory or X:\ # UNC path should be handled in fs mapping. If not, append it to rootfs directly. pw = PureWindowsPath(path) result = _rootfs / QlPathManager.normalize(pw) else: # code should never reach here. result = _rootfs / QlPathManager.normalize(path) else: if len( path ) >= 3 and path[:3] == r'\\?' or path[:3] == r'\??': # \??\ or \\?\ or \Device\.. # Similair to \\.\, it should be handled in fs mapping. pw = PureWindowsPath(path) result = _rootfs / QlPathManager.normalize( _cwd / pw.relative_to(pw.anchor).as_posix()) else: # a normal relative path result = _rootfs / QlPathManager.normalize( _cwd / PureWindowsPath(path).as_posix()) return result
def main(playlist_dir, output_dir, replace=None, overwrite=False, update_only=False, preserve_comments=False): for playlist in playlist_dir.rglob('*.m3u*'): dest = playlist.relative_to(playlist_dir) dest = output_dir / dest if not (overwrite or update_only) and dest.exists(): print(f'{dest} already exists, skipping.') continue if (update_only and dest.exists() and dest.stat().st_mtime > playlist.stat().st_mtime): continue dest.parent.mkdir(parents=True, exist_ok=True) if dest.exists() and preserve_comments: smart_update(playlist, dest, replace) else: # dumb write with path updates with open(playlist) as fin, open(dest, 'wb') as fout: for track in fin: track = track.strip() if re.match(r'\w:', track) or '\\' in track: track = PureWindowsPath(track) else: track = Path(track) if replace: old_m_dir, new_m_dir = replace track = new_m_dir / track.relative_to(old_m_dir) fout.write(bytes(str(track), 'utf8')) fout.write(b'\n')
def write(self, filename, arcname=None, compress_type=None, unk1=None): """Write the file named `filename` into the archive. Args: filename: File to write into archive. arcname: If given, the archive file entry will be named `arcname`. By default, `arcname` will be the same as `filename`, but with any drive letter and leading path separators removed. Posix paths will be replaced with equivalent Windows paths. compress_type (`LMCompressType`): If given, the file will be compressed with the specified method (defaults to uncompressed for files < 5MB in size, and zlib compressed for files >= 5MB). Returns: The number of (compressed) bytes written. Raises: FileExistsError: If an entry matching `arcname` already exists in this archive. UnsupportedLiveMakerCompression: If the `compress_type` is unsupported. """ if self.closed: raise ValueError("Archive is already closed.") if self.mode != "w": raise ValueError("Cannot write to archive opened for reading.") if arcname is None: arcpath = PureWindowsPath(filename) else: arcpath = PureWindowsPath(arcname) # strip drive and leading pathsep name = str(arcpath.relative_to(arcpath.anchor)) if name in self.name_info: raise FileExistsError( "{} already exists in this archive.".format(name)) if compress_type is not None and compress_type not in SUPPORTED_COMPRESSIONS: raise UnsupportedLiveMakerCompression( "{} is not supported.".format(compress_type)) info = LMArchiveInfo(name) with open(filename, "rb") as f: data = f.read() if compress_type is None: if len(data) >= 0x500000: compress_type = LMCompressType.ZLIB else: compress_type = LMCompressType.NONE if compress_type == LMCompressType.ZLIB: data = zlib.compress(data) if unk1 is not None: info.unk1 = unk1 info.compress_type = compress_type info.compressed_size = len(data) info.checksum = LMArchiveDirectory.checksum(data) info._offset = self.tmpfp.tell() self.tmpfp.write(data) self.filelist.append(info) self.name_info[name] = info return info.compressed_size
def remove_drive_letter(path): """ Given a Windows path string, remove the leading drive letter and return the path string as a POSIX-styled path. """ # Remove leading drive letter ("C:\\") path = PureWindowsPath(path) path_no_drive_letter = path.relative_to(*path.parts[:1]) # POSIX-ize the path posixed_path = path_no_drive_letter.as_posix() return posixed_path
def make_merge_structs(source, dest, replace=None): """get linked lists and lookup tables for both files as well as a duplicate table""" if replace: old_m_dir, new_m_dir = replace if '\\' in str(old_m_dir) or re.match(r'\w:', str(old_m_dir)): old_m_dir = PureWindowsPath(old_m_dir) heads = [] maps = [] dups = defaultdict(list) for fl in (source, dest): s_head = None s_map = {} with open(fl) as s: for i, a in enumerate(s): a = a.strip() if replace and fl is source: if re.match(r'\w:', a) or '\\' in a: p = PureWindowsPath(a) else: p = Path(a) a = str(new_m_dir / p.relative_to(old_m_dir)) a = Node(a, index=i) if s_head is None: s_head = a prev_a = None if fl is source: if a.value in s_map: dups[a.value].append(a) continue s_map[a.value] = a if prev_a: prev_a.next = a a.prev = prev_a prev_a = a heads.append(s_head) maps.append(s_map) return maps[0], heads[0], maps[1], heads[1], dups
from pathlib import Path, PurePosixPath, PureWindowsPath from platform import uname import os appdata = PureWindowsPath(os.getenv('APPDATA')) if 'Microsoft' in uname().release: if Path.cwd().drive == "": appdata = Path(appdata.relative_to(Path(appdata.drive) / '\\')) appdata = Path('/mnt/c/') / appdata data_dir = appdata / 'league-picker' def run(): if not data_dir.exists(): data_dir.mkdir() if not (data_dir / '.tmp').exists(): (data_dir / '.tmp').mkdir() if not (data_dir / 'lists').exists(): (data_dir / 'lists').mkdir() champ_file = Path(__file__).parent / "champ_data.json" data_file = Path(__file__).parent / "game_data.json" champ_data = data_dir / "champ_data.json" data_data = data_dir / "game_data.json" if not champ_data.exists(): champ_data.touch() champ_data.write_text(champ_file.read_text()) if not data_data.exists(): data_data.touch() data_data.write_text(data_file.read_text())