33import math
44import os
55import re
6- import shutil
76from typing import List , Optional , Dict
87import typing
98import uuid
4140 import pygeodiff
4241
4342
44- class GeoDiffLongPath :
45- """
46- Wraps a pygeodiff.GeoDiff instance so that every filesystem path passed to it is prefixed
47- with the Windows extended-length ("\\ ?\" ) marker.
48-
49- Only the geodiff methods that take path arguments are listed explicitly.
50- """
51-
52- def __init__ (self , geodiff ):
53- self ._geodiff = geodiff
54-
55- def create_changeset (self , base , modified , changeset ):
56- return self ._geodiff .create_changeset (long_path (base ), long_path (modified ), long_path (changeset ))
57-
58- def apply_changeset (self , base , changeset ):
59- return self ._geodiff .apply_changeset (long_path (base ), long_path (changeset ))
60-
61- def rebase (self , base , modified_their , modified , conflict ):
62- return self ._geodiff .rebase (
63- long_path (base ), long_path (modified_their ), long_path (modified ), long_path (conflict )
64- )
65-
66- def make_copy_sqlite (self , src , dst ):
67- return self ._geodiff .make_copy_sqlite (long_path (src ), long_path (dst ))
68-
69- def has_changes (self , changeset ):
70- return self ._geodiff .has_changes (long_path (changeset ))
71-
72- def changes_count (self , changeset ):
73- return self ._geodiff .changes_count (long_path (changeset ))
74-
75- def read_changeset (self , changeset ):
76- return self ._geodiff .read_changeset (long_path (changeset ))
77-
78- def list_changes_summary (self , changeset , json ):
79- return self ._geodiff .list_changes_summary (long_path (changeset ), long_path (json ))
80-
81- def concat_changes (self , list_changesets , output_changeset ):
82- return self ._geodiff .concat_changes ([long_path (p ) for p in list_changesets ], long_path (output_changeset ))
83-
84- def schema (self , driver , driver_info , src , json ):
85- return self ._geodiff .schema (driver , driver_info , long_path (src ), long_path (json ))
86-
87- def __getattr__ (self , name ):
88- # everything without path arguments (set_logger_callback, level/table setters, version(), ...)
89- return getattr (self ._geodiff , name )
90-
91-
9243class MerginProject :
9344 """Base class for Mergin Maps local projects.
9445
@@ -97,19 +48,19 @@ class MerginProject:
9748
9849 def __init__ (self , directory ):
9950 self .dir = os .path .abspath (directory )
100- if not os . path .exists (self .dir ):
51+ if not fs .exists (self .dir ):
10152 raise InvalidProject ("Project directory does not exist" )
10253
10354 self .meta_dir = os .path .join (self .dir , ".mergin" )
104- if not os . path .exists (self .meta_dir ):
105- os .mkdir (self .meta_dir )
55+ if not fs .exists (self .meta_dir ):
56+ fs .mkdir (self .meta_dir )
10657
10758 # location for files from unfinished pull
10859 self .unfinished_pull_dir = os .path .join (self .meta_dir , "unfinished_pull" )
10960
11061 self .cache_dir = os .path .join (self .meta_dir , ".cache" )
111- if not os . path .exists (self .cache_dir ):
112- os .mkdir (self .cache_dir )
62+ if not fs .exists (self .cache_dir ):
63+ fs .mkdir (self .cache_dir )
11364
11465 # metadata from JSON are lazy loaded
11566 self ._metadata = None
@@ -119,7 +70,7 @@ def __init__(self, directory):
11970
12071 # make sure we can load correct pygeodiff
12172 try :
122- self .geodiff = GeoDiffLongPath ( pygeodiff .GeoDiff () )
73+ self .geodiff = pygeodiff .GeoDiff ()
12374 except pygeodiff .geodifflib .GeoDiffLibVersionError :
12475 # this is a fatal error, we can't live without geodiff
12576 self .log .error ("Unable to load geodiff! (lib version error)" )
@@ -145,7 +96,9 @@ def setup_logging(self, logger_name):
14596 if not self .log .handlers :
14697 # we only need to set the handler once
14798 # (otherwise we would get things logged multiple times as loggers are cached)
148- log_handler = logging .FileHandler (os .path .join (self .meta_dir , "client-log.txt" ), encoding = "utf-8" )
99+ log_handler = logging .FileHandler (
100+ long_path (os .path .join (self .meta_dir , "client-log.txt" )), encoding = "utf-8"
101+ )
149102 log_handler .setFormatter (logging .Formatter ("%(asctime)s %(message)s" ))
150103 self .log .addHandler (log_handler )
151104
@@ -172,7 +125,7 @@ def fpath(self, file, other_dir=None):
172125 root = other_dir or self .dir
173126 abs_path = os .path .abspath (os .path .join (root , file ))
174127 f_dir = os .path .dirname (abs_path )
175- os .makedirs (f_dir , exist_ok = True )
128+ fs .makedirs (f_dir , exist_ok = True )
176129 return abs_path
177130
178131 def fpath_meta (self , file ):
@@ -280,9 +233,9 @@ def _read_metadata(self) -> None:
280233 """Loads the project's metadata from JSON"""
281234 if self ._metadata is not None :
282235 return
283- if not os . path .exists (self .fpath_meta ("mergin.json" )):
236+ if not fs .exists (self .fpath_meta ("mergin.json" )):
284237 raise InvalidProject ("Project metadata has not been created yet" )
285- with open (self .fpath_meta ("mergin.json" ), "r" ) as file :
238+ with fs . open_file (self .fpath_meta ("mergin.json" ), "r" ) as file :
286239 self ._metadata = json .load (file )
287240
288241 self .is_old_metadata = "/" in self ._metadata ["name" ]
@@ -302,9 +255,9 @@ def write_metadata(project_directory: str, data: dict):
302255 (and therefore creating MerginProject would fail).
303256 """
304257 meta_dir = os .path .join (project_directory , ".mergin" )
305- os .makedirs (meta_dir , exist_ok = True )
258+ fs .makedirs (meta_dir , exist_ok = True )
306259 metadata_json_file = os .path .abspath (os .path .join (meta_dir , "mergin.json" ))
307- with open (metadata_json_file , "w" ) as file :
260+ with fs . open_file (metadata_json_file , "w" ) as file :
308261 json .dump (data , file , indent = 2 )
309262
310263 def is_versioned_file (self , file ):
@@ -760,7 +713,7 @@ def copy_versioned_file_for_upload(self, f: FileChange, tmp_dir: str) -> str:
760713 path = f .path
761714 self .log .info ("Making a temporary copy (full upload): " + path )
762715 tmp_file = os .path .join (tmp_dir , path )
763- os .makedirs (os .path .dirname (tmp_file ), exist_ok = True )
716+ fs .makedirs (os .path .dirname (tmp_file ), exist_ok = True )
764717 self .geodiff .make_copy_sqlite (self .fpath (path ), tmp_file )
765718 f .size = fs .getsize (tmp_file )
766719 f .checksum = generate_checksum (tmp_file )
@@ -777,10 +730,10 @@ def get_list_of_push_changes(self, push_changes):
777730 result_file = self .fpath ("change_list" + str (idx ), self .meta_dir )
778731 try :
779732 self .geodiff .list_changes_summary (changeset , result_file )
780- with open (result_file , "r" ) as f :
733+ with fs . open_file (result_file , "r" ) as f :
781734 change = f .read ()
782735 changes [file ["path" ]] = json .loads (change )
783- os .remove (result_file )
736+ fs .remove (result_file )
784737 except (pygeodiff .GeoDiffLibError , pygeodiff .GeoDiffLibConflictError ):
785738 pass
786739 return changes
@@ -1061,7 +1014,7 @@ def has_unfinished_pull(self):
10611014 :returns: whether there is an unfinished pull
10621015 :rtype: bool
10631016 """
1064- return os . path .exists (self .unfinished_pull_dir )
1017+ return fs .exists (self .unfinished_pull_dir )
10651018
10661019 def resolve_unfinished_pull (self , user_name ):
10671020 """
@@ -1093,9 +1046,8 @@ def resolve_unfinished_pull(self, user_name):
10931046
10941047 for root , dirs , files in fs .walk (self .unfinished_pull_dir ):
10951048 for file_name in files :
1096- src = os .path .join (root , file_name )
1097- # the relpath base must be prefixed as well to strip it correctly.
1098- file_path = os .path .relpath (src , long_path (self .unfinished_pull_dir ))
1049+ file_path = os .path .relpath (os .path .join (root , file_name ), long_path (self .unfinished_pull_dir ))
1050+ src = self .fpath_unfinished_pull (file_path )
10991051 dest = self .fpath (file_path )
11001052 basefile = self .fpath_meta (file_path )
11011053
@@ -1116,7 +1068,7 @@ def resolve_unfinished_pull(self, user_name):
11161068 self .log .error ("unable to apply changes from previous unfinished pull!" )
11171069 raise ClientError ("Unable to resolve unfinished pull!" )
11181070
1119- shutil .rmtree (self .unfinished_pull_dir )
1071+ fs .rmtree (self .unfinished_pull_dir )
11201072 self .log .info ("unfinished pull resolved successfuly!" )
11211073 return conflicts
11221074
@@ -1162,7 +1114,7 @@ def get_geodiff_changes_count(self, diff_rel_path: str):
11621114
11631115 diff_abs = self .fpath_meta (diff_rel_path )
11641116 try :
1165- return GeoDiffLongPath ( pygeodiff .GeoDiff () ).changes_count (diff_abs )
1117+ return pygeodiff .GeoDiff ().changes_count (diff_abs )
11661118 except (
11671119 pygeodiff .GeoDiffLibError ,
11681120 pygeodiff .GeoDiffLibConflictError ,
0 commit comments