Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 19 additions & 11 deletions mergin/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

from pip._vendor import distro

from .common import ClientError, SyncError
from .common import ClientError
from .merginproject import MerginProject
from .client_pull import download_project_async, download_project_wait, download_project_finalize
from .client_pull import pull_project_async, pull_project_wait, pull_project_finalize
Expand Down Expand Up @@ -218,30 +218,31 @@ def login(self, login, password):
}
return session

def create_project(self, project_name, directory=None, is_public=False):
def username(self):
""" Returns user name used in this session or None if not authenticated """
if not self._user_info:
return None # not authenticated
return self._user_info["username"]

def create_project(self, project_name, is_public=False):
"""
Create new project repository in user namespace on Mergin server.
Optionally initialized from given local directory.

:param project_name: Project name
:type project_name: String

:param directory: Local project directory, defaults to None
:type directory: String

:param is_public: Flag for public/private project, defaults to False
:type directory: Boolean
"""
if not self._user_info:
raise Exception("Authentication required")
if directory and not os.path.exists(directory):
raise Exception("Project directory does not exists")

params = {
"name": project_name,
"public": is_public
}
namespace = self._user_info["username"]
namespace = self.username()
try:
self.post("/v1/project/%s" % namespace, params, {"Content-Type": "application/json"})
data = {
Expand All @@ -251,10 +252,17 @@ def create_project(self, project_name, directory=None, is_public=False):
}
except Exception as e:
detail = f"Namespace: {namespace}, project name: {project_name}"
raise SyncError(str(e), detail)
raise ClientError(str(e), detail)

def create_project_and_push(self, project_name, directory, is_public=False):
"""
Convenience method to create project and push the initial version right after that.
"""
self.create_project(project_name, is_public)
if directory:
mp = MerginProject(directory)
mp.metadata = data
full_project_name = "{}/{}".format(self.username(), project_name)
mp.metadata = {"name": full_project_name, "version": "v0", "files": []}
if mp.inspect_files():
self.push_project(directory)

Expand Down Expand Up @@ -330,7 +338,7 @@ def download_project(self, project_path, directory):
download_project_finalize(job)

def enough_storage_available(self, data):
user_name = self._user_info["username"]
user_name = self.username()
resp = self.get('/v1/user/' + user_name)
info = json.load(resp)
free_space = int(info["storage_limit"]) - int(info["disk_usage"])
Expand Down
4 changes: 2 additions & 2 deletions mergin/client_push.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import pprint
import concurrent.futures

from .common import UPLOAD_CHUNK_SIZE, ClientError, SyncError
from .common import UPLOAD_CHUNK_SIZE, ClientError
from .merginproject import MerginProject
from .utils import generate_checksum, do_sqlite_checkpoint

Expand Down Expand Up @@ -99,7 +99,7 @@ def push_project_async(mc, directory):
if not enough_free_space:
freespace = int(freespace/(1024*1024))
mp.log.error(f"--- push {project_path} - not enough space")
raise SyncError("Storage limit has been reached. Only " + str(freespace) + "MB left")
raise ClientError("Storage limit has been reached. Only " + str(freespace) + "MB left")

if not sum(len(v) for v in changes.values()):
mp.log.info(f"--- push {project_path} - nothing to do")
Expand Down
6 changes: 0 additions & 6 deletions mergin/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,6 @@ class ClientError(Exception):
pass


class SyncError(Exception):
def __init__(self, msg, detail=""):
super().__init__(msg)
self.detail = detail


try:
import dateutil.parser
from dateutil.tz import tzlocal
Expand Down
16 changes: 8 additions & 8 deletions mergin/test/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import pytest
import pytz

from ..client import MerginClient, ClientError, MerginProject, SyncError, LoginError
from ..client import MerginClient, ClientError, MerginProject, LoginError
from ..utils import generate_checksum

SERVER_URL = os.environ.get('TEST_MERGIN_URL')
Expand Down Expand Up @@ -56,7 +56,7 @@ def test_create_delete_project(mc):
assert any(p for p in projects if p['name'] == test_project and p['namespace'] == API_USER)

# try again
with pytest.raises(SyncError, match=f'Project {test_project} already exists'):
with pytest.raises(ClientError, match=f'Project {test_project} already exists'):
mc.create_project(test_project)

# remove project
Expand All @@ -80,7 +80,7 @@ def test_create_remote_project_from_local(mc):
shutil.copytree(TEST_DATA_DIR, project_dir)

# create remote project
mc.create_project(test_project, directory=project_dir)
mc.create_project_and_push(test_project, directory=project_dir)

# check basic metadata about created project
project_info = mc.project_info(project)
Expand Down Expand Up @@ -119,7 +119,7 @@ def test_push_pull_changes(mc):
cleanup(mc, project, [project_dir, project_dir_2])
# create remote project
shutil.copytree(TEST_DATA_DIR, project_dir)
mc.create_project(test_project, project_dir)
mc.create_project_and_push(test_project, project_dir)

# make sure we have v1 also in concurrent project dir
mc.download_project(project, project_dir_2)
Expand Down Expand Up @@ -196,7 +196,7 @@ def test_ignore_files(mc):
# create remote project
shutil.copytree(TEST_DATA_DIR, project_dir)
shutil.copy(os.path.join(project_dir, 'test.qgs'), os.path.join(project_dir, 'test.qgs~'))
mc.create_project(test_project, project_dir)
mc.create_project_and_push(test_project, project_dir)
project_info = mc.project_info(project)
assert not next((f for f in project_info['files'] if f['path'] == 'test.qgs~'), None)

Expand Down Expand Up @@ -228,7 +228,7 @@ def test_sync_diff(mc, push_geodiff_enabled, pull_geodiff_enabled):
# create remote project
toggle_geodiff(push_geodiff_enabled)
shutil.copytree(TEST_DATA_DIR, project_dir)
mc.create_project(test_project, project_dir)
mc.create_project_and_push(test_project, project_dir)

# make sure we have v1 also in concurrent project dirs
toggle_geodiff(pull_geodiff_enabled)
Expand Down Expand Up @@ -318,7 +318,7 @@ def test_list_of_push_changes(mc):
cleanup(mc, project, [project_dir])
shutil.copytree(TEST_DATA_DIR, project_dir)
toggle_geodiff(True)
mc.create_project(test_project, project_dir)
mc.create_project_and_push(test_project, project_dir)

f_updated = 'base.gpkg'
mp = MerginProject(project_dir)
Expand All @@ -342,7 +342,7 @@ def test_force_gpkg_update(mc):
cleanup(mc, project, [project_dir])
# create remote project
shutil.copytree(TEST_DATA_DIR, project_dir)
mc.create_project(test_project, project_dir)
mc.create_project_and_push(test_project, project_dir)

# test push changes with force gpkg file upload:
mp = MerginProject(project_dir)
Expand Down