Skip to content

Commit

Permalink
Adding the functionality for specify packaged project filename and ti…
Browse files Browse the repository at this point in the history
…tle (#94)

* Adding the functionality for add packaged project filename and title

Co-authored-by: Ivan Ivanov <suricactus@users.noreply.github.com>

Co-authored-by: Ivan Ivanov <suricactus@users.noreply.github.com>

Co-authored-by: Ivan Ivanov <suricactus@users.noreply.github.com>

Co-authored-by: Ivan Ivanov <suricactus@users.noreply.github.com>

Co-authored-by: Ivan Ivanov <suricactus@users.noreply.github.com>

Co-authored-by: Ivan Ivanov <suricactus@users.noreply.github.com>

* Adding improvement and suggestions

* Removing the old overwrite setTitle (this is not necessary)

* Adding suggestion on code styling and some air

* Removing optional parameters and other improvements

* Fixing basemap.gpkg and data.gpkg

* Fix tests

---------

Co-authored-by: Ivan Ivanov <suricactus@users.noreply.github.com>
  • Loading branch information
SeqLaz and suricactus authored Nov 12, 2024
1 parent 5ba992c commit 1b923ba
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 27 deletions.
29 changes: 17 additions & 12 deletions libqfieldsync/offline_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
***************************************************************************/
"""

import os
import sys
from enum import Enum
from pathlib import Path
Expand Down Expand Up @@ -84,14 +83,15 @@ class OfflineConverter(QObject):
def __init__(
self,
project: QgsProject,
export_folder: str,
export_filename: str,
area_of_interest_wkt: str,
area_of_interest_crs: Union[str, QgsCoordinateReferenceSystem],
attachment_dirs: List[str],
offliner: BaseOffliner,
export_type: ExportType = ExportType.Cable,
create_basemap: bool = True,
dirs_to_copy: Optional[Dict[str, bool]] = None,
export_title: str = "",
):
super(OfflineConverter, self).__init__(parent=None)
self.__max_task_progress = 0
Expand All @@ -102,7 +102,11 @@ def __init__(
# elipsis workaround
self.trUtf8 = self.tr

self.export_folder = Path(export_folder)
if not export_filename:
raise Exception("Empty export filename provided!")

self._export_filename = Path(export_filename)
self._export_title = export_title
self.export_type = export_type
self.create_basemap = create_basemap
self.area_of_interest = QgsPolygon()
Expand Down Expand Up @@ -188,7 +192,7 @@ def _convert(self, project: QgsProject) -> None:
# NOTE force delete the `QgsProject`, otherwise the `QgsApplication` might be deleted by the time the project is garbage collected
del tmp_project

self.export_folder.mkdir(parents=True, exist_ok=True)
self._export_filename.parent.mkdir(parents=True, exist_ok=True)
self.total_progress_updated.emit(0, 100, self.trUtf8("Converting project…"))

project_layers: List[QgsMapLayer] = list(project.mapLayers().values())
Expand Down Expand Up @@ -266,15 +270,16 @@ def _convert(self, project: QgsProject) -> None:
elif (
layer_action == SyncAction.COPY or layer_action == SyncAction.NO_ACTION
):
copied_files = layer_source.copy(self.export_folder, copied_files)
copied_files = layer_source.copy(
self._export_filename.parent,
copied_files,
)
elif layer_action == SyncAction.KEEP_EXISTENT:
layer_source.copy(self.export_folder, copied_files, True)
layer_source.copy(self._export_filename.parent, copied_files, True)
elif layer_action == SyncAction.REMOVE:
project.removeMapLayer(layer)

export_project_filename = self.export_folder.joinpath(
f"{self.original_filename.stem}_qfield.qgs"
)
export_project_filename = self._export_filename

# save the original project path
self.project_configuration.original_project_path = str(self.original_filename)
Expand Down Expand Up @@ -306,7 +311,6 @@ def _convert(self, project: QgsProject) -> None:
plugin_file, export_project_filename.parent.joinpath(plugin_file.name)
)

gpkg_filename = str(self.export_folder.joinpath("data.gpkg"))
if offline_layers:
bbox = None
if self.project_configuration.offline_copy_only_aoi:
Expand All @@ -317,9 +321,10 @@ def _convert(self, project: QgsProject) -> None:
).transformBoundingBox(self.area_of_interest.boundingBox())

is_success = self.offliner.convert_to_offline(
gpkg_filename,
str(self._export_filename.with_name("data.gpkg")),
offline_layers,
bbox,
self._export_title,
)

if not is_success:
Expand Down Expand Up @@ -543,7 +548,7 @@ def _export_basemap(self) -> bool:
"TILE_SIZE": self.project_configuration.base_map_tile_size,
"MAP_UNITS_PER_PIXEL": self.project_configuration.base_map_mupp,
"MAKE_BACKGROUND_TRANSPARENT": False,
"OUTPUT": os.path.join(self.export_folder, "basemap.gpkg"),
"OUTPUT": str(self._export_filename.with_name("basemap.gpkg")),
}

if base_map_type == ProjectProperties.BaseMapType.SINGLE_LAYER:
Expand Down
28 changes: 23 additions & 5 deletions libqfieldsync/offliners.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ def convert_to_offline(
offline_db_filename: str,
layers: List[QgsMapLayer],
bbox: Optional[QgsRectangle],
exported_project_title: str = "",
) -> bool:
raise NotImplementedError(
"Expected `BaseOffliner` to be extended by a class that implements `convert_to_offline`."
Expand Down Expand Up @@ -86,6 +87,7 @@ def convert_to_offline(
offline_db_filename: str,
layers: List[QgsMapLayer],
bbox: Optional[QgsRectangle],
exported_project_title: str = "",
) -> bool:
project = QgsProject.instance()
offline_db_path = Path(offline_db_filename).parent
Expand Down Expand Up @@ -124,6 +126,9 @@ def convert_to_offline(
if layer.selectedFeatureCount() == 0:
layer.selectByIds([FID_NULL])

if exported_project_title:
project.setTitle(exported_project_title)

is_success = self.offliner.convertToOfflineProject(
str(offline_db_path),
str(offline_db_filename),
Expand All @@ -144,8 +149,14 @@ def convert_to_offline(
offline_db_filename: str,
layers: List[QgsMapLayer],
bbox: Optional[QgsRectangle],
exported_project_title: str = "",
) -> bool:
self._convert_to_offline_project(str(offline_db_filename), layers, bbox)
self._convert_to_offline_project(
str(offline_db_filename),
layers,
bbox,
exported_project_title,
)
return True

def ogr_field_type(self, field: QgsField) -> ogr.FieldDefn:
Expand Down Expand Up @@ -351,6 +362,7 @@ def _convert_to_offline_project(
offline_gpkg_path: str,
offline_layers: Optional[List[QgsMapLayer]],
bbox: Optional[QgsRectangle],
exported_project_title: str = "",
) -> None:
"""Converts the currently loaded QgsProject to an offline project.
Offline layers are written to ``offline_gpkg_path``. Only valid vector layers are written.
Expand Down Expand Up @@ -444,12 +456,18 @@ class LayerInfo(NamedTuple):
self.update_data_provider(layer_info.layer, source)
layer_info.layer.setSubsetString(layer_info.subset_string)

project_title = project.title()
if not project_title:
project_title = QFileInfo(project.fileName()).baseName()
if exported_project_title:
project_title = exported_project_title
else:
project_title = project.title()

if not project_title:
project_title = QFileInfo(project.fileName()).baseName()

project_title += f"{project_title} (offline)"

project_title += f"{project_title} (offline)"
project.setTitle(project_title)

project.writeEntry(
PROJECT_ENTRY_SCOPE_OFFLINE,
PROJECT_ENTRY_KEY_OFFLINE_DB_PATH,
Expand Down
10 changes: 5 additions & 5 deletions tests/test_offline_converter_minioffliner.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def test_copy(self):
)
offline_converter = OfflineConverter(
project,
str(self.target_dir),
self.target_dir.joinpath("project_qfield.qgs"),
"POLYGON((1 1, 5 0, 5 5, 0 5, 1 1))",
QgsProject.instance().crs().authid(),
["DCIM"],
Expand Down Expand Up @@ -116,7 +116,7 @@ def test_primary_keys_custom_property(self):
)
offline_converter = OfflineConverter(
project,
str(self.target_dir),
self.target_dir.joinpath("project_qfield.qgs"),
"POLYGON((1 1, 5 0, 5 5, 0 5, 1 1))",
QgsProject.instance().crs().authid(),
["DCIM"],
Expand All @@ -141,7 +141,7 @@ def test_geometryless_layers(self):
)
offline_converter = OfflineConverter(
project,
str(self.target_dir),
self.target_dir.joinpath("project_qfield.qgs"),
"POLYGON((1 1, 5 0, 5 5, 0 5, 1 1))",
QgsProject.instance().crs().authid(),
["DCIM"],
Expand Down Expand Up @@ -195,7 +195,7 @@ def test_localized_layers(self):

offline_converter = OfflineConverter(
project,
str(self.target_dir),
self.target_dir.joinpath("project_qfield.qgs"),
"POLYGON((1 1, 5 0, 5 5, 0 5, 1 1))",
QgsProject.instance().crs().authid(),
["DCIM"],
Expand All @@ -219,7 +219,7 @@ def test_cloud_packaging_pk(self):
)
offline_converter = OfflineConverter(
project,
str(self.target_dir),
self.target_dir.joinpath("project_qfield.qgs"),
"POLYGON((1 1, 5 0, 5 5, 0 5, 1 1))",
QgsProject.instance().crs().authid(),
["DCIM"],
Expand Down
10 changes: 5 additions & 5 deletions tests/test_offline_converter_qgiscore.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def test_copy(self):
)
offline_converter = OfflineConverter(
project,
str(self.target_dir),
self.target_dir.joinpath("project_qfield.qgs"),
"POLYGON((1 1, 5 0, 5 5, 0 5, 1 1))",
QgsProject.instance().crs().authid(),
["DCIM"],
Expand Down Expand Up @@ -113,7 +113,7 @@ def test_primary_keys_custom_property(self):
)
offline_converter = OfflineConverter(
project,
str(self.target_dir),
self.target_dir.joinpath("project_qfield.qgs"),
"POLYGON((1 1, 5 0, 5 5, 0 5, 1 1))",
QgsProject.instance().crs().authid(),
["DCIM"],
Expand All @@ -138,7 +138,7 @@ def test_geometryless_layers(self):
)
offline_converter = OfflineConverter(
project,
str(self.target_dir),
self.target_dir.joinpath("project_qfield.qgs"),
"POLYGON((1 1, 5 0, 5 5, 0 5, 1 1))",
QgsProject.instance().crs().authid(),
["DCIM"],
Expand Down Expand Up @@ -192,7 +192,7 @@ def test_localized_layers(self):

offline_converter = OfflineConverter(
project,
str(self.target_dir),
self.target_dir.joinpath("project_qfield.qgs"),
"POLYGON((1 1, 5 0, 5 5, 0 5, 1 1))",
QgsProject.instance().crs().authid(),
["DCIM"],
Expand All @@ -216,7 +216,7 @@ def test_cloud_packaging_pk(self):
)
offline_converter = OfflineConverter(
project,
str(self.target_dir),
self.target_dir.joinpath("project_qfield.qgs"),
"POLYGON((1 1, 5 0, 5 5, 0 5, 1 1))",
QgsProject.instance().crs().authid(),
["DCIM"],
Expand Down

0 comments on commit 1b923ba

Please sign in to comment.