satupeta-main/services/datasets/publish_geonetwork.py

694 lines
22 KiB
Python
Raw Normal View History

2026-01-27 02:52:02 +00:00
from fastapi import HTTPException
import requests
from sqlalchemy import text
from core.config import GEONETWORK_PASS, GEONETWORK_URL, GEONETWORK_USER
2026-02-10 01:54:35 +00:00
from database.connection import engine
2026-01-27 02:52:02 +00:00
from datetime import datetime
from uuid import uuid4
import re
def create_gn_session():
session = requests.Session()
session.auth = (GEONETWORK_USER, GEONETWORK_PASS)
session.get(f"{GEONETWORK_URL}/srv/eng/info?type=me")
xsrf_token = session.cookies.get("XSRF-TOKEN")
if not xsrf_token:
raise Exception("XSRF token missing")
return session, xsrf_token
def escape_url_params(url: str) -> str:
"""
Escape karakter berbahaya di dalam URL agar valid dalam XML.
Khususnya mengganti '&' menjadi '&' kecuali jika sudah '&'.
"""
# Ganti semua & yang bukan bagian dari &
url = re.sub(r'&(?!amp;)', '&', url)
return url
def fix_xml_urls(xml: str) -> str:
"""
Temukan semua <gmd:URL> ... </gmd:URL> dalam XML dan escape URL-nya.
"""
def replacer(match):
original = match.group(1).strip()
fixed = escape_url_params(original)
return f"<gmd:URL>{fixed}</gmd:URL>"
# Replace semua <gmd:URL> ... </gmd:URL>
xml_fixed = re.sub(
r"<gmd:URL>(.*?)</gmd:URL>",
replacer,
xml,
flags=re.DOTALL
)
return xml_fixed
2026-02-10 01:54:35 +00:00
async def get_extent(table_name: str):
2026-01-27 02:52:02 +00:00
sql = f"""
SELECT
ST_XMin(extent), ST_YMin(extent),
ST_XMax(extent), ST_YMax(extent)
FROM (
SELECT ST_Extent(geom) AS extent
2026-02-10 01:54:35 +00:00
FROM public."{table_name}"
2026-01-27 02:52:02 +00:00
) AS box;
"""
2026-02-10 01:54:35 +00:00
async with engine.connect() as conn:
result = await conn.execute(sql)
row = result.fetchone()
2026-01-27 02:52:02 +00:00
if not row or row[0] is None:
return None
# return {
2026-02-10 01:54:35 +00:00
# "xmin": row[0],
# "ymin": row[1],
# "xmax": row[2],
# "ymax": row[3]
2026-01-27 02:52:02 +00:00
# }
return {
"xmin": 110.1372, # west
"ymin": -9.3029, # south
"xmax": 114.5287, # east
"ymax": -5.4819 # north
}
2026-02-10 01:54:35 +00:00
async def get_author_metadata(table_name: str):
2026-01-27 02:52:02 +00:00
sql = """
SELECT am.table_title, am.dataset_title, am.dataset_abstract, am.keywords, am.date_created,
am.organization_name, am.contact_person_name, am.created_at,
am.contact_email, am.contact_phone, am.geom_type,
u.organization_id,
o.address AS organization_address,
o.email AS organization_email,
o.phone_number AS organization_phone
FROM backend.author_metadata AS am
LEFT JOIN backend.users u ON am.user_id = u.id
LEFT JOIN backend.organizations o ON u.organization_id = o.id
WHERE am.table_title = :table
LIMIT 1
"""
2026-02-10 01:54:35 +00:00
async with engine.connect() as conn:
result = await conn.execute(sql, {"table": table_name})
row = result.fetchone()
2026-01-27 02:52:02 +00:00
if not row:
raise Exception(f"Tidak ada metadata untuk tabel: {table_name}")
2026-02-10 01:54:35 +00:00
# SQLAlchemy Async row support ._mapping untuk convert ke dict
2026-01-27 02:52:02 +00:00
return dict(row._mapping)
def map_geom_type(gtype):
if gtype is None:
return "surface"
# Jika LIST → ambil elemen pertama
if isinstance(gtype, list):
if len(gtype) > 0:
gtype = gtype[0]
else:
return "surface"
# Setelah pasti string
gtype = str(gtype).lower()
if "polygon" in gtype or "multi" in gtype:
return "surface"
if "line" in gtype:
return "curve"
if "point" in gtype:
return "point"
return "surface"
def generate_metadata_xml(table_name, meta, extent, geoserver_links):
keywords_xml = "".join([
f"""
<gmd:keyword><gco:CharacterString>{kw.strip()}</gco:CharacterString></gmd:keyword>
""" for kw in meta["keywords"].split(",")
])
geom_type_code = map_geom_type(meta["geom_type"])
print('type', geom_type_code)
uuid = str(uuid4())
return f"""
<gmd:MD_Metadata
xmlns:gmd="http://www.isotc211.org/2005/gmd"
xmlns:gco="http://www.isotc211.org/2005/gco"
xmlns:srv="http://www.isotc211.org/2005/srv"
xmlns:gmx="http://www.isotc211.org/2005/gmx"
xmlns:gts="http://www.isotc211.org/2005/gts"
xmlns:gsr="http://www.isotc211.org/2005/gsr"
xmlns:gmi="http://www.isotc211.org/2005/gmi"
xmlns:gml="http://www.opengis.net/gml/3.2"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/csw/2.0.2/profiles/apiso/1.0.0/apiso.xsd">
<gmd:fileIdentifier>
<gco:CharacterString>{uuid}</gco:CharacterString>
</gmd:fileIdentifier>
<gmd:language>
<gmd:LanguageCode codeList="http://www.loc.gov/standards/iso639-2/" codeListValue="eng"/>
</gmd:language>
<gmd:characterSet>
<gmd:MD_CharacterSetCode codeListValue="utf8" codeList="http://standards.iso.org/iso/19139/resources/gmxCodelists.xml#MD_CharacterSetCode"/>
</gmd:characterSet>
<gmd:hierarchyLevel>
<gmd:MD_ScopeCode codeList="http://standards.iso.org/iso/19139/resources/gmxCodelists.xml#MD_ScopeCode" codeListValue="feature"/>
</gmd:hierarchyLevel>
<gmd:contact>
<gmd:CI_ResponsibleParty>
<gmd:individualName>
<gco:CharacterString>{meta['contact_person_name']}</gco:CharacterString>
</gmd:individualName>
<gmd:organisationName>
<gco:CharacterString>{meta['organization_name']}</gco:CharacterString>
</gmd:organisationName>
<gmd:contactInfo>
<gmd:CI_Contact>
<gmd:phone>
<gmd:CI_Telephone>
<gmd:voice>
<gco:CharacterString>{meta['organization_phone']}</gco:CharacterString>
</gmd:voice>
<gmd:facsimile>
<gco:CharacterString>{meta['organization_phone']}</gco:CharacterString>
</gmd:facsimile>
</gmd:CI_Telephone>
</gmd:phone>
<gmd:address>
<gmd:CI_Address>
<gmd:deliveryPoint>
<gco:CharacterString>{meta['organization_address']}</gco:CharacterString>
</gmd:deliveryPoint>
<gmd:city>
<gco:CharacterString>Surabaya</gco:CharacterString>
</gmd:city>
<gmd:administrativeArea>
<gco:CharacterString>Jawa Timur</gco:CharacterString>
</gmd:administrativeArea>
<gmd:country>
<gco:CharacterString>Indonesia</gco:CharacterString>
</gmd:country>
<gmd:electronicMailAddress>
<gco:CharacterString>{meta['organization_email']}</gco:CharacterString>
</gmd:electronicMailAddress>
</gmd:CI_Address>
</gmd:address>
<gmd:hoursOfService>
<gco:CharacterString>08.00-16.00</gco:CharacterString>
</gmd:hoursOfService>
</gmd:CI_Contact>
</gmd:contactInfo>
<gmd:role>
<gmd:CI_RoleCode codeListValue="pointOfContact" codeList="http://standards.iso.org/iso/19139/resources/gmxCodelists.xml#CI_RoleCode"/>
</gmd:role>
</gmd:CI_ResponsibleParty>
</gmd:contact>
<gmd:dateStamp>
<gco:DateTime>{datetime.utcnow().isoformat()}+07:00</gco:DateTime>
</gmd:dateStamp>
<gmd:metadataStandardName>
<gco:CharacterString>ISO 19115:2003/19139</gco:CharacterString>
</gmd:metadataStandardName>
<gmd:metadataStandardVersion>
<gco:CharacterString>1.0</gco:CharacterString>
</gmd:metadataStandardVersion>
<gmd:spatialRepresentationInfo>
<gmd:MD_VectorSpatialRepresentation>
<gmd:geometricObjects>
<gmd:MD_GeometricObjects>
<gmd:geometricObjectType>
<gmd:MD_GeometricObjectTypeCode codeList="http://standards.iso.org/iso/19139/resources/gmxCodelists.xml#MD_GeometricObjectTypeCode" codeListValue="{geom_type_code}"/>
</gmd:geometricObjectType>
<gmd:geometricObjectCount>
<gco:Integer>38</gco:Integer>
</gmd:geometricObjectCount>
</gmd:MD_GeometricObjects>
</gmd:geometricObjects>
</gmd:MD_VectorSpatialRepresentation>
</gmd:spatialRepresentationInfo>
<gmd:referenceSystemInfo>
<gmd:MD_ReferenceSystem>
<gmd:referenceSystemIdentifier>
<gmd:RS_Identifier>
<gmd:code>
<gco:CharacterString>4326</gco:CharacterString>
</gmd:code>
<gmd:codeSpace>
<gco:CharacterString>EPSG</gco:CharacterString>
</gmd:codeSpace>
</gmd:RS_Identifier>
</gmd:referenceSystemIdentifier>
</gmd:MD_ReferenceSystem>
</gmd:referenceSystemInfo>
<gmd:identificationInfo>
<gmd:MD_DataIdentification>
<gmd:citation>
<gmd:CI_Citation>
<gmd:title>
<gco:CharacterString>{meta['dataset_title']}</gco:CharacterString>
</gmd:title>
<gmd:date>
<gmd:CI_Date>
<gmd:date>
<gco:DateTime>{meta['created_at'].isoformat()}+07:00</gco:DateTime>
</gmd:date>
<gmd:dateType>
<gmd:CI_DateTypeCode codeListValue="publication" codeList="http://standards.iso.org/iso/19139/resources/gmxCodelists.xml#CI_DateTypeCode"/>
</gmd:dateType>
</gmd:CI_Date>
</gmd:date>
<gmd:edition>
<gco:CharacterString>{meta['date_created'].year}</gco:CharacterString>
</gmd:edition>
<gmd:citedResponsibleParty>
<gmd:CI_ResponsibleParty>
<gmd:individualName>
<gco:CharacterString>{meta['contact_person_name']}</gco:CharacterString>
</gmd:individualName>
<gmd:organisationName>
<gco:CharacterString>{meta['organization_name']}</gco:CharacterString>
</gmd:organisationName>
<gmd:contactInfo>
<gmd:CI_Contact>
<gmd:phone>
<gmd:CI_Telephone>
<gmd:voice>
<gco:CharacterString>{meta['organization_phone']}</gco:CharacterString>
</gmd:voice>
<gmd:facsimile>
<gco:CharacterString>{meta['organization_phone']}</gco:CharacterString>
</gmd:facsimile>
</gmd:CI_Telephone>
</gmd:phone>
<gmd:address>
<gmd:CI_Address>
<gmd:deliveryPoint>
<gco:CharacterString>{meta['organization_address']}</gco:CharacterString>
</gmd:deliveryPoint>
<gmd:city>
<gco:CharacterString>Surabaya</gco:CharacterString>
</gmd:city>
<gmd:country>
<gco:CharacterString>Indonesia</gco:CharacterString>
</gmd:country>
<gmd:electronicMailAddress>
<gco:CharacterString>{meta['organization_email']}</gco:CharacterString>
</gmd:electronicMailAddress>
</gmd:CI_Address>
</gmd:address>
<gmd:hoursOfService>
<gco:CharacterString>08.00-16.00</gco:CharacterString>
</gmd:hoursOfService>
</gmd:CI_Contact>
</gmd:contactInfo>
<gmd:role>
<gmd:CI_RoleCode codeList="http://standards.iso.org/iso/19139/resources/gmxCodelists.xml#CI_RoleCode" codeListValue="custodian"/>
</gmd:role>
</gmd:CI_ResponsibleParty>
</gmd:citedResponsibleParty>
<gmd:otherCitationDetails>
<gco:CharacterString>Timezone: UTC+7 (Asia/Jakarta)</gco:CharacterString>
</gmd:otherCitationDetails>
</gmd:CI_Citation>
</gmd:citation>
<gmd:abstract>
<gco:CharacterString>{meta['dataset_abstract']}</gco:CharacterString>
</gmd:abstract>
<gmd:purpose>
<gco:CharacterString>{meta['dataset_abstract']}</gco:CharacterString>
</gmd:purpose>
<gmd:status>
<gmd:MD_ProgressCode codeListValue="completed" codeList="http://standards.iso.org/iso/19139/resources/gmxCodelists.xml#MD_ProgressCode"/>
</gmd:status>
<gmd:pointOfContact>
<gmd:CI_ResponsibleParty>
<gmd:individualName>
2026-01-29 03:16:34 +00:00
<gco:CharacterString>Lab AI Polinema</gco:CharacterString>
2026-01-27 02:52:02 +00:00
</gmd:individualName>
<gmd:organisationName>
2026-01-29 03:16:34 +00:00
<gco:CharacterString>Lab AI Polinema</gco:CharacterString>
2026-01-27 02:52:02 +00:00
</gmd:organisationName>
<gmd:positionName gco:nilReason="missing"/>
<gmd:contactInfo>
<gmd:CI_Contact>
<gmd:phone>
<gmd:CI_Telephone>
<gmd:voice>
<gco:CharacterString>{meta['organization_phone']}</gco:CharacterString>
</gmd:voice>
<gmd:facsimile>
<gco:CharacterString>{meta['organization_phone']}</gco:CharacterString>
</gmd:facsimile>
</gmd:CI_Telephone>
</gmd:phone>
<gmd:address>
<gmd:CI_Address>
<gmd:deliveryPoint>
<gco:CharacterString>{meta['organization_address']}</gco:CharacterString>
</gmd:deliveryPoint>
<gmd:city>
<gco:CharacterString>Surabaya</gco:CharacterString>
</gmd:city>
<gmd:administrativeArea>
<gco:CharacterString>Jawa Timur</gco:CharacterString>
</gmd:administrativeArea>
<gmd:country>
<gco:CharacterString>Indonesia</gco:CharacterString>
</gmd:country>
<gmd:electronicMailAddress>
<gco:CharacterString>{meta['organization_email']}</gco:CharacterString>
</gmd:electronicMailAddress>
</gmd:CI_Address>
</gmd:address>
</gmd:CI_Contact>
</gmd:contactInfo>
<gmd:role>
<gmd:CI_RoleCode codeListValue="owner" codeList="http://standards.iso.org/iso/19139/resources/gmxCodelists.xml#CI_RoleCode"/>
</gmd:role>
</gmd:CI_ResponsibleParty>
</gmd:pointOfContact>
<gmd:resourceMaintenance>
<gmd:MD_MaintenanceInformation>
<gmd:maintenanceAndUpdateFrequency>
<gmd:MD_MaintenanceFrequencyCode codeListValue="annually" codeList="http://standards.iso.org/iso/19139/resources/gmxCodelists.xml#MD_MaintenanceFrequencyCode"/>
</gmd:maintenanceAndUpdateFrequency>
</gmd:MD_MaintenanceInformation>
</gmd:resourceMaintenance>
<gmd:descriptiveKeywords>
<gmd:MD_Keywords>
{keywords_xml}
</gmd:MD_Keywords>
</gmd:descriptiveKeywords>
<gmd:resourceConstraints>
<gmd:MD_LegalConstraints>
<gmd:accessConstraints>
<gmd:MD_RestrictionCode codeListValue="copyright" codeList="http://standards.iso.org/iso/19139/resources/gmxCodelists.xml#MD_RestrictionCode"/>
</gmd:accessConstraints>
<gmd:useConstraints>
<gmd:MD_RestrictionCode codeListValue="otherRestrictions" codeList="http://standards.iso.org/iso/19139/resources/gmxCodelists.xml#MD_RestrictionCode"/>
</gmd:useConstraints>
<gmd:otherConstraints>
<gco:CharacterString>Penggunaan data harus mencantumkan sumber: {meta['organization_name']}.</gco:CharacterString>
</gmd:otherConstraints>
</gmd:MD_LegalConstraints>
</gmd:resourceConstraints>
<gmd:spatialRepresentationType>
<gmd:MD_SpatialRepresentationTypeCode codeListValue="vector" codeList="http://standards.iso.org/iso/19139/resources/gmxCodelists.xml#MD_SpatialRepresentationTypeCode"/>
</gmd:spatialRepresentationType>
<gmd:spatialResolution>
<gmd:MD_Resolution>
<gmd:equivalentScale>
<gmd:MD_RepresentativeFraction>
<gmd:denominator>
<gco:Integer>25000</gco:Integer>
</gmd:denominator>
</gmd:MD_RepresentativeFraction>
</gmd:equivalentScale>
</gmd:MD_Resolution>
</gmd:spatialResolution>
<gmd:language>
<gmd:LanguageCode codeList="http://www.loc.gov/standards/iso639-2/" codeListValue="eng"/>
</gmd:language>
<gmd:characterSet>
<gmd:MD_CharacterSetCode codeListValue="utf8" codeList="http://standards.iso.org/iso/19139/resources/gmxCodelists.xml#MD_CharacterSetCode"/>
</gmd:characterSet>
<gmd:extent>
<gmd:EX_Extent>
<gmd:geographicElement>
<gmd:EX_GeographicBoundingBox>
<gmd:westBoundLongitude><gco:Decimal>{extent['xmin']}</gco:Decimal></gmd:westBoundLongitude>
<gmd:eastBoundLongitude><gco:Decimal>{extent['xmax']}</gco:Decimal></gmd:eastBoundLongitude>
<gmd:southBoundLatitude><gco:Decimal>{extent['ymin']}</gco:Decimal></gmd:southBoundLatitude>
<gmd:northBoundLatitude><gco:Decimal>{extent['ymax']}</gco:Decimal></gmd:northBoundLatitude>
</gmd:EX_GeographicBoundingBox>
</gmd:geographicElement>
</gmd:EX_Extent>
</gmd:extent>
</gmd:MD_DataIdentification>
</gmd:identificationInfo>
<gmd:contentInfo>
<gmd:MD_FeatureCatalogueDescription>
<gmd:complianceCode>
<gco:Boolean>true</gco:Boolean>
</gmd:complianceCode>
<gmd:includedWithDataset gco:nilReason="unknown"/>
<gmd:featureCatalogueCitation>
<gmd:CI_Citation>
<gmd:title>
<gco:CharacterString>{meta['dataset_title']}</gco:CharacterString>
</gmd:title>
<gmd:date>
<gmd:CI_Date>
<gmd:date>
<gco:DateTime>{meta['created_at'].isoformat()}+07:00</gco:DateTime>
</gmd:date>
<gmd:dateType>
<gmd:CI_DateTypeCode codeListValue="publication" codeList="http://standards.iso.org/iso/19139/resources/gmxCodelists.xml#CI_DateTypeCode"/>
</gmd:dateType>
</gmd:CI_Date>
</gmd:date>
<gmd:edition>
<gco:CharacterString>{meta['date_created'].year}</gco:CharacterString>
</gmd:edition>
</gmd:CI_Citation>
</gmd:featureCatalogueCitation>
</gmd:MD_FeatureCatalogueDescription>
</gmd:contentInfo>
<gmd:distributionInfo>
<gmd:MD_Distribution>
<gmd:transferOptions>
<gmd:MD_DigitalTransferOptions>
<gmd:onLine>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>{geoserver_links["wms_url"]}</gmd:URL>
</gmd:linkage>
<gmd:protocol>
<gco:CharacterString>DB:POSTGIS</gco:CharacterString>
</gmd:protocol>
<gmd:name>
<gco:CharacterString>{meta["dataset_title"]}</gco:CharacterString>
</gmd:name>
<gmd:description>
<gco:CharacterString>{meta["dataset_title"]}</gco:CharacterString>
</gmd:description>
</gmd:CI_OnlineResource>
</gmd:onLine>
<gmd:onLine>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>{geoserver_links["wms_url"]}</gmd:URL>
</gmd:linkage>
<gmd:protocol>
<gco:CharacterString>WWW:LINK-1.0-http--link</gco:CharacterString>
</gmd:protocol>
<gmd:name>
<gco:CharacterString>{meta["dataset_title"]}</gco:CharacterString>
</gmd:name>
<gmd:description>
<gco:CharacterString>{meta["dataset_title"]}</gco:CharacterString>
</gmd:description>
</gmd:CI_OnlineResource>
</gmd:onLine>
<gmd:onLine>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>{geoserver_links["wms_url"]}</gmd:URL>
</gmd:linkage>
<gmd:protocol>
<gco:CharacterString>OGC:WMS</gco:CharacterString>
</gmd:protocol>
<gmd:name>
<gco:CharacterString>{meta["dataset_title"]}</gco:CharacterString>
</gmd:name>
</gmd:CI_OnlineResource>
</gmd:onLine>
<gmd:onLine>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>{geoserver_links["wfs_url"]}</gmd:URL>
</gmd:linkage>
<gmd:protocol>
<gco:CharacterString>OGC:WFS</gco:CharacterString>
</gmd:protocol>
<gmd:name>
<gco:CharacterString>{meta["dataset_title"]}</gco:CharacterString>
</gmd:name>
</gmd:CI_OnlineResource>
</gmd:onLine>
</gmd:MD_DigitalTransferOptions>
</gmd:transferOptions>
</gmd:MD_Distribution>
</gmd:distributionInfo>
<gmd:dataQualityInfo>
<gmd:DQ_DataQuality>
<gmd:scope>
<gmd:DQ_Scope>
<gmd:level>
<gmd:MD_ScopeCode codeListValue="dataset" codeList="http://standards.iso.org/iso/19139/resources/gmxCodelists.xml#MD_ScopeCode"/>
</gmd:level>
</gmd:DQ_Scope>
</gmd:scope>
<gmd:lineage>
<gmd:LI_Lineage>
<gmd:statement>
<gco:CharacterString>Data dihasilkan dari digitasi peta dasar skala 1:25000 menggunakan QGIS.</gco:CharacterString>
</gmd:statement>
</gmd:LI_Lineage>
</gmd:lineage>
</gmd:DQ_DataQuality>
</gmd:dataQualityInfo>
</gmd:MD_Metadata>
"""
# Geonetwork version 4.4.9.0
def upload_metadata_to_geonetwork(xml_metadata: str):
# session = requests.Session()
# session.auth = (GEONETWORK_USER, GEONETWORK_PASS)
# # 1. Get XSRF token
# try:
# info_url = f"{GEONETWORK_URL}/srv/eng/info?type=me"
# session.get(info_url)
# except requests.exceptions.RequestException as e:
# raise HTTPException(status_code=503, detail=f"Failed to connect to GeoNetwork: {e}")
# xsrf_token = session.cookies.get('XSRF-TOKEN')
# if not xsrf_token:
# raise HTTPException(status_code=500, detail="Could not retrieve XSRF-TOKEN from GeoNetwork.")
session, xsrf_token = create_gn_session()
headers = {
'X-XSRF-TOKEN': xsrf_token,
'Accept': 'application/json'
}
GN_API_RECORDS_URL = f"{GEONETWORK_URL}/srv/api/records"
# 2. GeoNetwork requires a multipart/form-data upload
files = {
'file': ('metadata.xml', xml_metadata, 'application/xml')
}
params = {
"ownerGroup": 1, # all
"ownerUser": 1 # admin
}
response = session.post(
GN_API_RECORDS_URL,
params=params,
files=files,
headers=headers,
cookies=session.cookies.get_dict()
)
metadata_infos = response.json().get("metadataInfos", {})
uuid = None
for records in metadata_infos.values():
if records and isinstance(records, list):
uuid = records[0].get("uuid")
break
if not uuid:
raise ValueError("UUID not found in GeoNetwork response")
publish_record(session, uuid)
# print("response", response.json())
return uuid
2026-02-10 01:54:35 +00:00
async def publish_metadata(table_name: str, geoserver_links: dict):
2026-01-27 02:52:02 +00:00
2026-02-10 01:54:35 +00:00
extent = await get_extent(table_name)
meta = await get_author_metadata(table_name)
2026-01-27 02:52:02 +00:00
xml = generate_metadata_xml(
table_name=meta["dataset_title"],
meta=meta,
extent=extent,
geoserver_links=geoserver_links
)
xml_clean = fix_xml_urls(xml)
uuid = upload_metadata_to_geonetwork(xml_clean)
print(f"[GeoNetwork] Metadata uploaded. UUID = {uuid}")
return uuid
def publish_record(session, uuid):
print('[uuid]', uuid)
xsrf_token = session.cookies.get('XSRF-TOKEN')
headers = {
"X-XSRF-TOKEN": xsrf_token,
"Accept": "application/json",
"Content-Type": "application/json"
}
url = f"{GEONETWORK_URL}/srv/api/records/{uuid}/sharing"
payload = {
"clear": True,
"privileges": [
{
"group": 1,
"operations": {
"view": True
}
}
]
}
response = session.put(url, json=payload, headers=headers)
response.raise_for_status()
# single stand func
# def publish_record(uuid):
# session, xsrf_token = create_gn_session()
# headers = {
# "X-XSRF-TOKEN": xsrf_token,
# "Content-Type": "application/json"
# }
# url = f"{GEONETWORK_URL}/srv/api/records/{uuid}/sharing"
# payload = {
# "clear": True,
# "privileges": [
# {"group": 1, "operations": {"view": True}}
# ]
# }
# resp = session.put(url, json=payload, headers=headers)
# resp.raise_for_status()