diff --git a/deployment/docker-pycsw/create_trigger.sql b/deployment/docker-pycsw/create_trigger.sql new file mode 100644 index 00000000..fc71d8ff --- /dev/null +++ b/deployment/docker-pycsw/create_trigger.sql @@ -0,0 +1,90 @@ +CREATE OR REPLACE FUNCTION insert_pycsw_catalogue_on_cbers() +RETURNS TRIGGER AS $pycsw_cbers_inserted$ +DECLARE + _keywords varchar(255); + _name varchar(255); + _launch_date varchar(255); + _description varchar(255); + _ref_url varchar(255); +BEGIN + SELECT + dit.keywords, ds.name, ds.launch_date, ds.description, ds.reference_url + INTO + _keywords, _name, _launch_date, _description, _ref_url + FROM + dictionaries_satellite ds + JOIN + dictionaries_satelliteinstrumentgroup dsig + ON ds.id = dsig.satellite_id + JOIN + dictionaries_instrumenttype dit + ON dit.id = dsig.instrument_type_id + WHERE + dit.abbreviation = NEW.sensor_abbreviation + AND + ds.abbreviation = NEW.satellite_abbreviation; + + IF (TG_OP = 'INSERT') THEN + INSERT INTO pycsw_catalogue + (identifier, typename, schema, mdsource, insert_date, + xml, anytext, language, title_alternate, + type, keywordstype, parentidentifier, + relation, time_begin, time_end, topicategory, resourcelanguage, + creator, publisher, contributor, organization, securityconstraints, + accessconstraints, otherconstraints, date, date_revision, + date_publication, date_modified, format, source, crs, + geodescode, denominator, distancevalue, distanceuom, wkt_geometry, + servicetype, servicetypeversion, operation, couplingtype, operateson, + operatesonidentifier, operatesoname, degree, classification, conditionapplyingtoaccessanduse, + lineage, responsiblepartyrole, specificationtitle, specificationdate, specificationdatetype, + keywords, title, date_creation, abstract, links) + VALUES + (NEW.identifier, NEW.type_name, NEW.schema, NEW.mdsource, NEW.insert_date, + NEW.xml, NEW.any_text, NEW.language, NEW.alternate_title, + NEW.any_text, NEW.keyword_type, NEW.parent_identifier, + NEW.relation, NEW.temp_extent_begin, NEW.temp_extent_end, NEW.topic_category, NEW.resource_language, + NEW.creator, NEW.publisher, NEW.contributor, NEW.organization_name, NEW.security_constraints, + NEW.access_constraints, NEW.other_constraints, NEW.date, NEW.revision_date, + to_char(now(), 'YYYY-MM-DD'), NEW.modified_date, NEW.format, NEW.source, NEW.crs, + NEW.geographic_description_code, NEW.denominator, NEW.distance_value, NEW.distance_uom, NEW.bounding_box, + NEW.service_type, NEW.service_type_version, NEW.operation, NEW.coupling_type, NEW.operates_on, + NEW.operates_on_identifier, NEW.operates_on_name, NEW.degree, NEW.classification, NEW.condition_applying_to_access_and_use, + NEW.lineage, NEW.responsible_party_role, NEW.specification_title, '', NEW.specification_date_type, + _keywords, _name, _launch_date, _description, _ref_url); + END IF; + if (TG_OP='UPDATE') THEN + UPDATE pycsw_catalogue + SET + (typename, schema, mdsource, insert_date, + xml, anytext, language, title, title_alternate, + type, abstract, keywords, keywordstype, parentidentifier, + relation, time_begin, time_end, topicategory, resourcelanguage, + creator, publisher, contributor, organization, securityconstraints, + accessconstraints, otherconstraints, date, date_revision, date_creation, + date_publication, date_modified, format, source, crs, + geodescode, denominator, distancevalue, distanceuom, wkt_geometry, + servicetype, servicetypeversion, operation, couplingtype, operateson, + operatesonidentifier, operatesoname, degree, classification, conditionapplyingtoaccessanduse, + lineage, responsiblepartyrole, specificationtitle, specificationdate, specificationdatetype, links) + = + (NEW.type_name, NEW.schema, NEW.mdsource, NEW.insert_date, + NEW.xml, NEW.any_text, NEW.language, _name, NEW.alternate_title, + NEW.any_text, _description, _keywords, NEW.keyword_type, NEW.parent_identifier, + NEW.relation, NEW.temp_extent_begin, NEW.temp_extent_end, NEW.topic_category, NEW.resource_language, + NEW.creator, NEW.publisher, NEW.contributor, NEW.organization_name, NEW.security_constraints, + NEW.access_constraints, NEW.other_constraints, NEW.date, NEW.revision_date, _launch_date, + NEW.publication_date, NEW.modified_date, NEW.format, NEW.source, NEW.crs, + NEW.geographic_description_code, NEW.denominator, NEW.distance_value, NEW.distance_uom, NEW.bounding_box, + NEW.service_type, NEW.service_type_version, NEW.operation, NEW.coupling_type, NEW.operates_on, + NEW.operates_on_identifier, NEW.operates_on_name, NEW.degree, NEW.classification, NEW.condition_applying_to_access_and_use, + NEW.lineage, NEW.responsible_party_role, NEW.specification_title, '', NEW.specification_date_type, _ref_url) + where identifier = NEW.identifier; + END IF; + RETURN new; +END; +$pycsw_cbers_inserted$ LANGUAGE plpgsql; + + +CREATE TRIGGER insert_pycsw_catalogue_cbers + AFTER INSERT OR UPDATE on catalogue_pycswextrafields + FOR EACH ROW EXECUTE PROCEDURE insert_pycsw_catalogue_on_cbers(); \ No newline at end of file diff --git a/deployment/docker-pycsw/setup_db.sql b/deployment/docker-pycsw/setup_db.sql new file mode 100644 index 00000000..f5771fe8 --- /dev/null +++ b/deployment/docker-pycsw/setup_db.sql @@ -0,0 +1,533 @@ +-- Table: public.pycsw_catalogue + +-- DROP TABLE public.pycsw_catalogue; + +CREATE TABLE public.pycsw_catalogue +( +-- id serial primary key, +-- identifier text NOT NULL references catalogue_pycswcbers(identifier), + identifier text primary key, + typename text NOT NULL, + schema text NOT NULL, + mdsource text NOT NULL, + insert_date text NOT NULL, + xml text NOT NULL, + anytext text NOT NULL, + language text, + title text, + title_alternate text, + type text, + abstract text, + keywords text, + keywordstype text, + parentidentifier text, + relation text, + time_begin text, + time_end text, + topicategory text, + resourcelanguage text, + creator text, + publisher text, + contributor text, + organization text, + securityconstraints text, + accessconstraints text, + otherconstraints text, + date text, + date_revision text, + date_creation text, + date_publication text, + date_modified text, + format text, + source text, + crs text, + geodescode text, + denominator text, + distancevalue text, + distanceuom text, + wkt_geometry text, + servicetype text, + servicetypeversion text, + operation text, + couplingtype text, + operateson text, + operatesonidentifier text, + operatesoname text, + degree text, + classification text, + conditionapplyingtoaccessanduse text, + lineage text, + responsiblepartyrole text, + specificationtitle text, + specificationdate text, + specificationdatetype text, + links text +) +WITH ( + OIDS=FALSE +); +ALTER TABLE public.pycsw_catalogue + OWNER TO docker; + +-- Index: public.ix_pycsw_catalogue_abstract + +-- DROP INDEX public.ix_pycsw_catalogue_abstract; + +CREATE INDEX ix_pycsw_catalogue_abstract + ON public.pycsw_catalogue + USING btree + (abstract COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_accessconstraints + +-- DROP INDEX public.ix_pycsw_catalogue_accessconstraints; + +CREATE INDEX ix_pycsw_catalogue_accessconstraints + ON public.pycsw_catalogue + USING btree + (accessconstraints COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_classification + +-- DROP INDEX public.ix_pycsw_catalogue_classification; + +CREATE INDEX ix_pycsw_catalogue_classification + ON public.pycsw_catalogue + USING btree + (classification COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_conditionapplyingtoaccessanduse + +-- DROP INDEX public.ix_pycsw_catalogue_conditionapplyingtoaccessanduse; + +CREATE INDEX ix_pycsw_catalogue_conditionapplyingtoaccessanduse + ON public.pycsw_catalogue + USING btree + (conditionapplyingtoaccessanduse COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_contributor + +-- DROP INDEX public.ix_pycsw_catalogue_contributor; + +CREATE INDEX ix_pycsw_catalogue_contributor + ON public.pycsw_catalogue + USING btree + (contributor COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_couplingtype + +-- DROP INDEX public.ix_pycsw_catalogue_couplingtype; + +CREATE INDEX ix_pycsw_catalogue_couplingtype + ON public.pycsw_catalogue + USING btree + (couplingtype COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_creator + +-- DROP INDEX public.ix_pycsw_catalogue_creator; + +CREATE INDEX ix_pycsw_catalogue_creator + ON public.pycsw_catalogue + USING btree + (creator COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_crs + +-- DROP INDEX public.ix_pycsw_catalogue_crs; + +CREATE INDEX ix_pycsw_catalogue_crs + ON public.pycsw_catalogue + USING btree + (crs COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_date + +-- DROP INDEX public.ix_pycsw_catalogue_date; + +CREATE INDEX ix_pycsw_catalogue_date + ON public.pycsw_catalogue + USING btree + (date COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_date_creation + +-- DROP INDEX public.ix_pycsw_catalogue_date_creation; + +CREATE INDEX ix_pycsw_catalogue_date_creation + ON public.pycsw_catalogue + USING btree + (date_creation COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_date_modified + +-- DROP INDEX public.ix_pycsw_catalogue_date_modified; + +CREATE INDEX ix_pycsw_catalogue_date_modified + ON public.pycsw_catalogue + USING btree + (date_modified COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_date_publication + +-- DROP INDEX public.ix_pycsw_catalogue_date_publication; + +CREATE INDEX ix_pycsw_catalogue_date_publication + ON public.pycsw_catalogue + USING btree + (date_publication COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_date_revision + +-- DROP INDEX public.ix_pycsw_catalogue_date_revision; + +CREATE INDEX ix_pycsw_catalogue_date_revision + ON public.pycsw_catalogue + USING btree + (date_revision COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_degree + +-- DROP INDEX public.ix_pycsw_catalogue_degree; + +CREATE INDEX ix_pycsw_catalogue_degree + ON public.pycsw_catalogue + USING btree + (degree COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_denominator + +-- DROP INDEX public.ix_pycsw_catalogue_denominator; + +CREATE INDEX ix_pycsw_catalogue_denominator + ON public.pycsw_catalogue + USING btree + (denominator COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_distanceuom + +-- DROP INDEX public.ix_pycsw_catalogue_distanceuom; + +CREATE INDEX ix_pycsw_catalogue_distanceuom + ON public.pycsw_catalogue + USING btree + (distanceuom COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_distancevalue + +-- DROP INDEX public.ix_pycsw_catalogue_distancevalue; + +CREATE INDEX ix_pycsw_catalogue_distancevalue + ON public.pycsw_catalogue + USING btree + (distancevalue COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_format + +-- DROP INDEX public.ix_pycsw_catalogue_format; + +CREATE INDEX ix_pycsw_catalogue_format + ON public.pycsw_catalogue + USING btree + (format COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_geodescode + +-- DROP INDEX public.ix_pycsw_catalogue_geodescode; + +CREATE INDEX ix_pycsw_catalogue_geodescode + ON public.pycsw_catalogue + USING btree + (geodescode COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_insert_date + +-- DROP INDEX public.ix_pycsw_catalogue_insert_date; + +CREATE INDEX ix_pycsw_catalogue_insert_date + ON public.pycsw_catalogue + USING btree + (insert_date COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_keywords + +-- DROP INDEX public.ix_pycsw_catalogue_keywords; + +CREATE INDEX ix_pycsw_catalogue_keywords + ON public.pycsw_catalogue + USING btree + (keywords COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_keywordstype + +-- DROP INDEX public.ix_pycsw_catalogue_keywordstype; + +CREATE INDEX ix_pycsw_catalogue_keywordstype + ON public.pycsw_catalogue + USING btree + (keywordstype COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_language + +-- DROP INDEX public.ix_pycsw_catalogue_language; + +CREATE INDEX ix_pycsw_catalogue_language + ON public.pycsw_catalogue + USING btree + (language COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_lineage + +-- DROP INDEX public.ix_pycsw_catalogue_lineage; + +CREATE INDEX ix_pycsw_catalogue_lineage + ON public.pycsw_catalogue + USING btree + (lineage COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_links + +-- DROP INDEX public.ix_pycsw_catalogue_links; + +CREATE INDEX ix_pycsw_catalogue_links + ON public.pycsw_catalogue + USING btree + (links COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_mdsource + +-- DROP INDEX public.ix_pycsw_catalogue_mdsource; + +CREATE INDEX ix_pycsw_catalogue_mdsource + ON public.pycsw_catalogue + USING btree + (mdsource COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_operateson + +-- DROP INDEX public.ix_pycsw_catalogue_operateson; + +CREATE INDEX ix_pycsw_catalogue_operateson + ON public.pycsw_catalogue + USING btree + (operateson COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_operatesoname + +-- DROP INDEX public.ix_pycsw_catalogue_operatesoname; + +CREATE INDEX ix_pycsw_catalogue_operatesoname + ON public.pycsw_catalogue + USING btree + (operatesoname COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_operatesonidentifier + +-- DROP INDEX public.ix_pycsw_catalogue_operatesonidentifier; + +CREATE INDEX ix_pycsw_catalogue_operatesonidentifier + ON public.pycsw_catalogue + USING btree + (operatesonidentifier COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_operation + +-- DROP INDEX public.ix_pycsw_catalogue_operation; + +CREATE INDEX ix_pycsw_catalogue_operation + ON public.pycsw_catalogue + USING btree + (operation COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_organization + +-- DROP INDEX public.ix_pycsw_catalogue_organization; + +CREATE INDEX ix_pycsw_catalogue_organization + ON public.pycsw_catalogue + USING btree + (organization COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_otherconstraints + +-- DROP INDEX public.ix_pycsw_catalogue_otherconstraints; + +CREATE INDEX ix_pycsw_catalogue_otherconstraints + ON public.pycsw_catalogue + USING btree + (otherconstraints COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_parentidentifier + +-- DROP INDEX public.ix_pycsw_catalogue_parentidentifier; + +CREATE INDEX ix_pycsw_catalogue_parentidentifier + ON public.pycsw_catalogue + USING btree + (parentidentifier COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_publisher + +-- DROP INDEX public.ix_pycsw_catalogue_publisher; + +CREATE INDEX ix_pycsw_catalogue_publisher + ON public.pycsw_catalogue + USING btree + (publisher COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_relation + +-- DROP INDEX public.ix_pycsw_catalogue_relation; + +CREATE INDEX ix_pycsw_catalogue_relation + ON public.pycsw_catalogue + USING btree + (relation COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_resourcelanguage + +-- DROP INDEX public.ix_pycsw_catalogue_resourcelanguage; + +CREATE INDEX ix_pycsw_catalogue_resourcelanguage + ON public.pycsw_catalogue + USING btree + (resourcelanguage COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_responsiblepartyrole + +-- DROP INDEX public.ix_pycsw_catalogue_responsiblepartyrole; + +CREATE INDEX ix_pycsw_catalogue_responsiblepartyrole + ON public.pycsw_catalogue + USING btree + (responsiblepartyrole COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_schema + +-- DROP INDEX public.ix_pycsw_catalogue_schema; + +CREATE INDEX ix_pycsw_catalogue_schema + ON public.pycsw_catalogue + USING btree + (schema COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_securityconstraints + +-- DROP INDEX public.ix_pycsw_catalogue_securityconstraints; + +CREATE INDEX ix_pycsw_catalogue_securityconstraints + ON public.pycsw_catalogue + USING btree + (securityconstraints COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_servicetype + +-- DROP INDEX public.ix_pycsw_catalogue_servicetype; + +CREATE INDEX ix_pycsw_catalogue_servicetype + ON public.pycsw_catalogue + USING btree + (servicetype COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_servicetypeversion + +-- DROP INDEX public.ix_pycsw_catalogue_servicetypeversion; + +CREATE INDEX ix_pycsw_catalogue_servicetypeversion + ON public.pycsw_catalogue + USING btree + (servicetypeversion COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_source + +-- DROP INDEX public.ix_pycsw_catalogue_source; + +CREATE INDEX ix_pycsw_catalogue_source + ON public.pycsw_catalogue + USING btree + (source COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_specificationdate + +-- DROP INDEX public.ix_pycsw_catalogue_specificationdate; + +CREATE INDEX ix_pycsw_catalogue_specificationdate + ON public.pycsw_catalogue + USING btree + (specificationdate COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_specificationdatetype + +-- DROP INDEX public.ix_pycsw_catalogue_specificationdatetype; + +CREATE INDEX ix_pycsw_catalogue_specificationdatetype + ON public.pycsw_catalogue + USING btree + (specificationdatetype COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_specificationtitle + +-- DROP INDEX public.ix_pycsw_catalogue_specificationtitle; + +CREATE INDEX ix_pycsw_catalogue_specificationtitle + ON public.pycsw_catalogue + USING btree + (specificationtitle COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_time_begin + +-- DROP INDEX public.ix_pycsw_catalogue_time_begin; + +CREATE INDEX ix_pycsw_catalogue_time_begin + ON public.pycsw_catalogue + USING btree + (time_begin COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_time_end + +-- DROP INDEX public.ix_pycsw_catalogue_time_end; + +CREATE INDEX ix_pycsw_catalogue_time_end + ON public.pycsw_catalogue + USING btree + (time_end COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_title + +-- DROP INDEX public.ix_pycsw_catalogue_title; + +CREATE INDEX ix_pycsw_catalogue_title + ON public.pycsw_catalogue + USING btree + (title COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_title_alternate + +-- DROP INDEX public.ix_pycsw_catalogue_title_alternate; + +CREATE INDEX ix_pycsw_catalogue_title_alternate + ON public.pycsw_catalogue + USING btree + (title_alternate COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_topicategory + +-- DROP INDEX public.ix_pycsw_catalogue_topicategory; + +CREATE INDEX ix_pycsw_catalogue_topicategory + ON public.pycsw_catalogue + USING btree + (topicategory COLLATE pg_catalog."default"); + +-- Index: public.ix_pycsw_catalogue_type + +-- DROP INDEX public.ix_pycsw_catalogue_type; + +-- Index: public.ix_pycsw_catalogue_typename + +-- DROP INDEX public.ix_pycsw_catalogue_typename; + +CREATE INDEX ix_pycsw_catalogue_typename + ON public.pycsw_catalogue + USING btree + (typename COLLATE pg_catalog."default"); diff --git a/django_project/catalogue/ingestors/cbers.py b/django_project/catalogue/ingestors/cbers.py index d5f9372a..50207655 100644 --- a/django_project/catalogue/ingestors/cbers.py +++ b/django_project/catalogue/ingestors/cbers.py @@ -27,6 +27,7 @@ Quality ) from catalogue.models import OpticalProduct +from catalogue.models.pycsw import PycswExtraFields def parse_date_time(date_stamp): @@ -346,6 +347,7 @@ def ingest( if we find we are missing a thumbnails. Default is False. :type ignore_missing_thumbs: bool """ + def log_message(message, level=1): """Log a message for a given leven. @@ -388,7 +390,7 @@ def log_message(message, level=1): log_message(product_folder, 2) # Find the first and only xml file in the folder - #search_path = os.path.join(str(myFolder), '*.XML') + # search_path = os.path.join(str(myFolder), '*.XML') log_message(myFolder, 2) xml_file = glob.glob(myFolder)[0] file = os.path.basename(xml_file) @@ -459,13 +461,13 @@ def log_message(message, level=1): update_mode = True try: log_message('Trying to update') - #original_product_id is not necessarily unique - #so we use product_id + # original_product_id is not necessarily unique + # so we use product_id product = OpticalProduct.objects.get( original_product_id=original_product_id ).getConcreteInstance() log_message(('Already in catalogue: updating %s.' - % original_product_id), 2) + % original_product_id), 2) new_record_flag = False message = product.ingestion_log message += '\n' @@ -490,9 +492,95 @@ def log_message(message, level=1): except Exception, e: print e.message + # now try to fill in the metadata + # populate metadata into temp pycsw table here + identifier = original_product_id + sensor_id = original_product_id[4:7] + satellite_id = original_product_id[0:4] + data_pycsw = { + 'identifier': identifier, + 'type_name': 'pycsw:CoreMetadata', + 'schema': 'http://www.opengis.net/cat/csw/2.0.2', + 'mdsource': 'local', + 'insert_date': today, + 'xml': myFolder, + 'any_text': myFolder, + 'language': 'EN', + # 'title': '', + # 'abstract': '', + # 'keywords': '', + # 'keyword_type': '', + 'format': 'jpg', + # 'source': '', + 'date': start_date_time, + 'modified_date': today, + # 'type': '', + 'bounding_box': '[%s,%s]' % (spatial_resolution_x, spatial_resolution_y), + 'crs': projection.epsg_code, + # 'alternate_title': '', + 'revision_date': today, + 'creation_date': today, + 'publication_date': today, + # 'organization_name': 'SANSA', + # 'security_constraints': '', + # 'parent_identifier': '', + # 'topic_category': '', + # 'resource_language': '', + # 'geo_desc_code': '', + # 'denominator': '', + # 'distance_value': '', + # 'distance_uom': '', + 'temp_extent_begin': today, + 'temp_extent_end': today, + # 'service_type': '', + # 'service_type_version': '', + # 'operation': '', + # 'coupling_type': '', + # 'operates_on': '', + # 'operates_on_identifier': '', + # 'operates_on_name': '', + # 'degree': '', + # 'access_constraints': '', + # 'other_constraints': '', + # 'classification': '', + # # 'condition_applying_tau': '', + # 'lineage': '', + # 'responsible_party_role': '', + # 'spec_title': '', + #'spec_date': today, + # 'spec_date_type': '', + 'creator': 'admin', + 'publisher': 'SANSA', + 'sensor_abbreviation': sensor_id, + 'satellite_abbreviation': satellite_id + # 'contributor': '', + # 'relation': '', + # 'links': '' + } + try: + # populate ingested_pycsw so it can be transferred to catalogue_pycsw later + # ingested_pycsw = PycswCbers.objects.get(identifier=identifier) + ingested_pycsw = PycswExtraFields.objects.get(identifier=identifier) + + + # pycsw part + ingested_pycsw.__dict__.update(data_pycsw) + + except ObjectDoesNotExist: + # pycsw part + try: + # ingested_pycsw = PycswCbers(**data_pycsw) + ingested_pycsw = PycswExtraFields(**data_pycsw) + + except Exception, e: + # log_message(e.message, 2) + log_message(e.message) + log_message('Saving product and setting thumb', 2) try: product.save() + ingested_pycsw.save() + if update_mode: updated_record_count += 1 else: @@ -513,8 +601,8 @@ def log_message(message, level=1): pass jpeg_path = os.path.join(str(myFolder)) - #log_message(jpeg_path, 2) - jpeg_path = jpeg_path.replace(".XML","-THUMB.JPG") + # log_message(jpeg_path, 2) + jpeg_path = jpeg_path.replace(".XML", "-THUMB.JPG") if jpeg_path: print jpeg_path @@ -533,7 +621,7 @@ def log_message(message, level=1): # elif ignore_missing_thumbs: # log_message('IGNORING missing thumb:') else: - raise Exception('Missing thumbnail in %s' %jpeg_path) + raise Exception('Missing thumbnail in %s' % jpeg_path) if new_record_flag: log_message('Product %s imported.' % record_count, 2) pass diff --git a/django_project/catalogue/ingestors/landsat.py b/django_project/catalogue/ingestors/landsat.py index c50e7e88..d71f7ec5 100644 --- a/django_project/catalogue/ingestors/landsat.py +++ b/django_project/catalogue/ingestors/landsat.py @@ -30,6 +30,7 @@ Quality ) from catalogue.models import OpticalProduct +from catalogue.models.pycsw import PycswExtraFields def parse_date_time(date_stamp): @@ -181,6 +182,19 @@ def get_spatial_resolution_y(filename): return 30 +def get_sensor_abbreviation(dom): + mission_index = dom.getElementsByTagName('PLATFORMNAME')[0] + mission_index_value = mission_index.firstChild.nodeValue + + if mission_index_value == 'Landsat-7': + mission_value = 'L7' + elif mission_index_value == 'Landsat-8': + mission_value = 'L8' + else: + raise Exception('Unknown mission in Landsat') + return mission_value + + def get_product_profile(log_message, dom): """Find the product_profile for this record. @@ -529,9 +543,91 @@ def log_message(log_message_content, level=1): except Exception, e: print e.message + # now try to fill in the metadata + # populate metadata into temp pycsw table here + identifier = original_product_id + data_pycsw = { + 'identifier': identifier, + 'type_name': 'pycsw:CoreMetadata', + 'schema': 'http://www.opengis.net/cat/csw/2.0.2', + 'mdsource': 'local', + 'insert_date': today, + 'xml': myFolder, + 'any_text': myFolder, + 'language': 'EN', + # 'title': '', + # 'abstract': '', + # 'keywords': '', + # 'keyword_type': '', + 'format': 'jpg', + # 'source': '', + 'date': start_date_time, + 'modified_date': today, + # 'type': '', + 'bounding_box': '[%s,%s]' % (spatial_resolution_x, spatial_resolution_y), + 'crs': projection.epsg_code, + # 'alternate_title': '', + 'revision_date': today, + 'creation_date': today, + 'publication_date': today, + # 'organization_name': 'SANSA', + # 'security_constraints': '', + # 'parent_identifier': '', + # 'topic_category': '', + # 'resource_language': '', + # 'geo_desc_code': '', + # 'denominator': '', + # 'distance_value': '', + # 'distance_uom': '', + 'temp_extent_begin': today, + 'temp_extent_end': today, + # 'service_type': '', + # 'service_type_version': '', + # 'operation': '', + # 'coupling_type': '', + # 'operates_on': '', + # 'operates_on_identifier': '', + # 'operates_on_name': '', + # 'degree': '', + # 'access_constraints': '', + # 'other_constraints': '', + # 'classification': '', + # 'condition_applying_tau': '', + # 'lineage': '', + # 'responsible_party_role': '', + # 'spec_title': '', + # 'spec_date': today, + # 'spec_date_type': '', + 'creator': 'admin', + 'publisher': 'SANSA', + 'sensor_abbreviation': get_sensor_abbreviation(dom), + 'satellite_abbreviation': product_profile.satellite_instrument.abbreviation + # 'contributor': '', + # 'relation': '', + # 'links': '' + } + try: + # populate ingested_pycsw so it can be transferred to catalogue_pycsw later + # ingested_pycsw = PycswCbers.objects.get(identifier=identifier) + ingested_pycsw = PycswExtraFields.objects.get(identifier=identifier) + + # pycsw part + ingested_pycsw.__dict__.update(data_pycsw) + + except ObjectDoesNotExist: + # pycsw part + try: + # ingested_pycsw = PycswCbers(**data_pycsw) + ingested_pycsw = PycswExtraFields(**data_pycsw) + + except Exception, e: + # log_message(e.message, 2) + log_message(e.message) + log_message('Saving product and setting thumb', 2) try: product.save() + ingested_pycsw.save() if update_mode: updated_record_count += 1 else: diff --git a/django_project/catalogue/ingestors/spot67.py b/django_project/catalogue/ingestors/spot67.py index 8bc1a83e..cf281ac0 100644 --- a/django_project/catalogue/ingestors/spot67.py +++ b/django_project/catalogue/ingestors/spot67.py @@ -28,6 +28,7 @@ Quality ) from catalogue.models import OpticalProduct +from catalogue.models.pycsw import PycswExtraFields def parse_date_time(date_stamp): @@ -152,6 +153,10 @@ def get_spatial_resolution_x(): def get_spatial_resolution_y(): return 1.5 +def get_satellite_abbreviation(dom): + return 'S%s' % \ + dom.getElementsByTagName('PLATFORM_SERIAL_NUMBER')[0].firstChild.nodeValue + def get_product_profile(log_message, dom): """Find the product_profile for this record. @@ -319,135 +324,218 @@ def log_message(message, level=1): # Find the first and only xml file in the folder search_path = os.path.join(str(myFolder), '*.xml') log_message(search_path, 2) - xml_file = glob.glob(search_path)[0] - log_message(xml_file, 2) - - # Create a DOM document from the file - dom = parse(xml_file) - # - # First grab all the generic properties that any spot will have... - geometry = get_geometry(log_message, dom) - start_date_time, center_date_time = get_dates( - log_message, dom) - # projection for GenericProduct - projection = get_projection() - original_product_id = get_original_product_id(dom) - # Band count for GenericImageryProduct - band_count = get_band_count() - orbit_number = get_orbit_number(dom) - # # Spatial resolution x for GenericImageryProduct - spatial_resolution_x = float(get_spatial_resolution_x()) - # # Spatial resolution y for GenericImageryProduct - spatial_resolution_y = float( - get_spatial_resolution_y()) - log_message('Spatial resolution y: %s' % spatial_resolution_y, 2) - # - # # Spatial resolution for GenericImageryProduct calculated as (x+y)/2 - spatial_resolution = (spatial_resolution_x + spatial_resolution_y) / 2 - log_message('Spatial resolution: %s' % spatial_resolution, 2) - radiometric_resolution = get_radiometric_resolution() - log_message('Radiometric resolution: %s' % radiometric_resolution, 2) - quality = get_quality() - # ProductProfile for OpticalProduct - product_profile = get_product_profile(log_message, dom) - # Get the original text file metadata - metadata_file = file(xml_file, 'rt') - metadata = metadata_file.readlines() - metadata_file.close() - log_message('Metadata retrieved', 2) - - unique_product_id = original_product_id - # Check if there is already a matching product based - # on original_product_id - - # Do the ingestion here... - data = { - 'metadata': metadata, - 'spatial_coverage': geometry, - 'radiometric_resolution': radiometric_resolution, - 'band_count': band_count, - 'original_product_id': original_product_id, - 'unique_product_id': unique_product_id, - 'spatial_resolution_x': spatial_resolution_x, - 'spatial_resolution_y': spatial_resolution_y, - 'spatial_resolution': spatial_resolution, - 'product_profile': product_profile, - 'product_acquisition_start': start_date_time, - 'product_date': center_date_time, - 'orbit_number': orbit_number, - 'projection': projection, - 'quality': quality - } - log_message(data, 3) - # Check if it's already in catalogue: - try: - today = datetime.today() - time_stamp = today.strftime("%Y-%m-%d") - log_message('Time Stamp: %s' % time_stamp, 2) - except Exception, e: - print e.message - update_mode = True - try: - log_message('Trying to update') - #original_product_id is not necessarily unique - #so we use product_id - product = OpticalProduct.objects.get( - original_product_id=original_product_id - ).getConcreteInstance() - log_message(('Already in catalogue: updating %s.' - % original_product_id), 2) - new_record_flag = False - message = product.ingestion_log - message += '\n' - message += '%s : %s - updating record' % ( - time_stamp, ingestor_version) - data['ingestion_log'] = message - product.__dict__.update(data) - except ObjectDoesNotExist: - log_message('Not in catalogue: creating.', 2) - update_mode = False - message = '%s : %s - creating record' % ( - time_stamp, ingestor_version) - data['ingestion_log'] = message + # xml_file = glob.glob(search_path)[0] + for xml_file in glob.glob(search_path): + log_message(xml_file, 2) + # Create a DOM document from the file + dom = parse(xml_file) + # + # First grab all the generic properties that any spot will have... + geometry = get_geometry(log_message, dom) + start_date_time, center_date_time = get_dates( + log_message, dom) + # projection for GenericProduct + projection = get_projection() + original_product_id = get_original_product_id(dom) + # Band count for GenericImageryProduct + band_count = get_band_count() + orbit_number = get_orbit_number(dom) + # # Spatial resolution x for GenericImageryProduct + spatial_resolution_x = float(get_spatial_resolution_x()) + # # Spatial resolution y for GenericImageryProduct + spatial_resolution_y = float( + get_spatial_resolution_y()) + log_message('Spatial resolution y: %s' % spatial_resolution_y, 2) + # + # # Spatial resolution for GenericImageryProduct calculated as (x+y)/2 + spatial_resolution = (spatial_resolution_x + spatial_resolution_y) / 2 + log_message('Spatial resolution: %s' % spatial_resolution, 2) + radiometric_resolution = get_radiometric_resolution() + log_message('Radiometric resolution: %s' % radiometric_resolution, 2) + quality = get_quality() + # ProductProfile for OpticalProduct + product_profile = get_product_profile(log_message, dom) + # Get the original text file metadata + metadata_file = file(xml_file, 'rt') + metadata = metadata_file.readlines() + metadata_file.close() + log_message('Metadata retrieved', 2) + + unique_product_id = original_product_id + # Check if there is already a matching product based + # on original_product_id + + # Do the ingestion here... + data = { + 'metadata': metadata, + 'spatial_coverage': geometry, + 'radiometric_resolution': radiometric_resolution, + 'band_count': band_count, + 'original_product_id': original_product_id, + 'unique_product_id': unique_product_id, + 'spatial_resolution_x': spatial_resolution_x, + 'spatial_resolution_y': spatial_resolution_y, + 'spatial_resolution': spatial_resolution, + 'product_profile': product_profile, + 'product_acquisition_start': start_date_time, + 'product_date': center_date_time, + 'orbit_number': orbit_number, + 'projection': projection, + 'quality': quality + } + log_message(data, 3) + # Check if it's already in catalogue: try: - product = OpticalProduct(**data) - log_message('Product: %s' % product) + today = datetime.today() + time_stamp = today.strftime("%Y-%m-%d") + log_message('Time Stamp: %s' % time_stamp, 2) + except Exception, e: + print e.message + update_mode = True + try: + log_message('Trying to update') + # original_product_id is not necessarily unique + # so we use product_id + product = OpticalProduct.objects.get( + original_product_id=original_product_id + ).getConcreteInstance() + log_message(('Already in catalogue: updating %s.' + % original_product_id), 2) + new_record_flag = False + message = product.ingestion_log + message += '\n' + message += '%s : %s - updating record' % ( + time_stamp, ingestor_version) + data['ingestion_log'] = message + product.__dict__.update(data) + except ObjectDoesNotExist: + log_message('Not in catalogue: creating.', 2) + update_mode = False + message = '%s : %s - creating record' % ( + time_stamp, ingestor_version) + data['ingestion_log'] = message + try: + product = OpticalProduct(**data) + log_message('Product: %s' % product) + + except Exception, e: + log_message(e.message, 2) + + new_record_flag = True except Exception, e: - log_message(e.message, 2) + print e.message + + # now try to fill in the metadata + # populate metadata into temp pycsw table here + data_pycsw = { + 'identifier': original_product_id, + 'type_name': 'pycsw:CoreMetadata', + 'schema': 'http://www.opengis.net/cat/csw/2.0.2', + 'mdsource': 'local', + 'insert_date': today, + 'xml': myFolder, + 'any_text': myFolder, + 'language': 'EN', + # 'title': '', + # 'abstract': '', + # 'keywords': '', + # 'keyword_type': '', + 'format': 'jpg', + # 'source': '', + 'date': start_date_time, + 'modified_date': today, + # 'type': '', + 'bounding_box': '[%s,%s]' % (spatial_resolution_x, spatial_resolution_y), + 'crs': projection.epsg_code, + # 'alternate_title': '', + 'revision_date': today, + 'creation_date': today, + 'publication_date': today, + # 'organization_name': 'SANSA', + # 'security_constraints': '', + # 'parent_identifier': '', + # 'topic_category': '', + # 'resource_language': '', + # 'geo_desc_code': '', + # 'denominator': '', + # 'distance_value': '', + # 'distance_uom': '', + 'temp_extent_begin': today, + 'temp_extent_end': today, + # 'service_type': '', + # 'service_type_version': '', + # 'operation': '', + # 'coupling_type': '', + # 'operates_on': '', + # 'operates_on_identifier': '', + # 'operates_on_name': '', + # 'degree': '', + # 'access_constraints': '', + # 'other_constraints': '', + # 'classification': '', + # # 'condition_applying_tau': '', + # 'lineage': '', + # 'responsible_party_role': '', + # 'spec_title': '', + # 'spec_date': today, + # 'spec_date_type': '', + 'creator': 'admin', + 'publisher': 'SANSA', + 'sensor_abbreviation': 'NAOMI', + 'satellite_abbreviation': get_satellite_abbreviation(dom) + # 'contributor': '', + # 'relation': '', + # 'links': '' + } + try: + # populate ingested_pycsw so it can be transferred to catalogue_pycsw later + # ingested_pycsw = PycswSpot.objects.get(identifier=identifier) + ingested_pycsw = PycswExtraFields.objects.get(identifier=original_product_id) - new_record_flag = True - except Exception, e: - print e.message + # pycsw part + ingested_pycsw.__dict__.update(data_pycsw) - log_message('Saving product and setting thumb', 2) - try: - product.save() - if update_mode: - updated_record_count += 1 - else: - created_record_count += 1 - if new_record_flag: - log_message('Product %s imported.' % record_count, 2) - pass + except ObjectDoesNotExist: + # pycsw part + try: + # ingested_pycsw = PycswSpot(**data_pycsw) + ingested_pycsw = PycswExtraFields(**data_pycsw) + + except Exception, e: + # log_message(e.message, 2) + log_message(e.message) + + log_message('Saving product and setting thumb', 2) + try: + product.save() + ingested_pycsw.save() + + if update_mode: + updated_record_count += 1 + else: + created_record_count += 1 + if new_record_flag: + log_message('Product %s imported.' % record_count, 2) + pass + else: + log_message('Product %s updated.' % updated_record_count, 2) + pass + except Exception, e: + traceback.print_exc(file=sys.stdout) + raise CommandError('Cannot import: %s' % e) + + if test_only_flag: + transaction.rollback() + log_message('Imported scene : %s' % product_folder, 1) + log_message('Testing only: transaction rollback.', 1) else: - log_message('Product %s updated.' % updated_record_count, 2) - pass - except Exception, e: - traceback.print_exc(file=sys.stdout) - raise CommandError('Cannot import: %s' % e) - - if test_only_flag: - transaction.rollback() - log_message('Imported scene : %s' % product_folder, 1) - log_message('Testing only: transaction rollback.', 1) - else: - transaction.commit() - log_message('Imported scene : %s' % product_folder, 1) + transaction.commit() + log_message('Imported scene : %s' % product_folder, 1) except Exception, e: - log_message('Record import failed. AAAAAAARGH! : %s' % - product_folder, 1) + log_message('Record import failed. AAAAAAARGH! : %s %s' % + (product_folder, e.message), 1) failed_record_count += 1 if halt_on_error_flag: print e.message diff --git a/django_project/catalogue/models/__init__.py b/django_project/catalogue/models/__init__.py index 1451fc09..0d751b4a 100644 --- a/django_project/catalogue/models/__init__.py +++ b/django_project/catalogue/models/__init__.py @@ -2,3 +2,4 @@ from .others import * from .signals import * from .website import * +from .pycsw import * diff --git a/django_project/catalogue/models/pycsw.py b/django_project/catalogue/models/pycsw.py new file mode 100644 index 00000000..a222de50 --- /dev/null +++ b/django_project/catalogue/models/pycsw.py @@ -0,0 +1,414 @@ +from django.db import models + + +class PycswBase(models.Model): + """ + Generic Imagery product, it is always a composite aggregated products + see: signals, to set spatial_resolution defaults and average + """ + identifier = models.CharField( + help_text='Original product id', + max_length=255, + primary_key=True, + unique=True) + type_name = models.CharField( + help_text=( + 'sensor type abbreviation'), + max_length=255, + null=True, + blank=True) + schema = models.CharField( + help_text=( + 'schema'), + max_length=255, + null=True, + blank=True) + mdsource = models.CharField( + help_text=( + 'MD source'), + max_length=255, + null=True, + blank=True) + insert_date = models.DateField() + xml = models.CharField( + help_text=( + 'XML'), + max_length=255, + null=True, + blank=True) + any_text = models.CharField( + help_text=( + 'Any Text'), + max_length=255, + null=True, + blank=True) + language = models.CharField( + help_text=( + 'Language'), + max_length=255, + null=True, + blank=True) + title = models.CharField( + help_text=( + 'Title'), + max_length=255, + null=True, + blank=True) + abstract = models.CharField( + help_text=( + 'Abstract'), + max_length=255, + null=True, + blank=True) + keywords = models.CharField( + help_text=( + 'Keywords'), + max_length=255, + null=True, + blank=True) + keyword_type = models.CharField( + help_text=( + 'Keyword Type'), + max_length=255, + null=True, + blank=True) + format = models.CharField( + help_text=( + 'Format'), + max_length=255, + null=True, + blank=True) + source = models.CharField( + help_text=( + 'Source'), + max_length=255, + null=True, + blank=True) + date = models.DateField() + modified_date = models.DateField() + type = models.CharField( + help_text=( + 'Type'), + max_length=255, + null=True, + blank=True) + bounding_box = models.CharField( + help_text=( + 'Bounding Box'), + max_length=255, + null=True, + blank=True) + crs = models.CharField( + help_text=( + 'CRS'), + max_length=255, + null=True, + blank=True) + alternate_title = models.CharField( + help_text=( + 'Alternate Title'), + max_length=255, + null=True, + blank=True) + revision_date = models.DateField() + creation_date = models.DateField() + publication_date = models.DateField() + organization_name = models.CharField( + help_text=( + 'Organization Name'), + max_length=255, + null=True, + blank=True) + security_constraints = models.CharField( + help_text=( + 'Security Constraints'), + max_length=255, + null=True, + blank=True) + parent_identifier = models.CharField( + help_text=( + 'Parent Identifier'), + max_length=255, + null=True, + blank=True) + topic_category = models.CharField( + help_text=( + 'Topic Category'), + max_length=255, + null=True, + blank=True) + resource_language = models.CharField( + help_text=( + 'Resource Language'), + max_length=255, + null=True, + blank=True) + geographic_description_code = models.CharField( + help_text=( + 'Geographic Description Code'), + max_length=255, + null=True, + blank=True) + denominator = models.CharField( + help_text=( + 'Denominator'), + max_length=255, + null=True, + blank=True) + distance_value = models.CharField( + help_text=( + 'Distance Value'), + max_length=255, + null=True, + blank=True) + distance_uom = models.CharField( + help_text=( + 'Distance UOM'), + max_length=255, + null=True, + blank=True) + temp_extent_begin = models.DateField() + temp_extent_end = models.DateField() + service_type = models.CharField( + help_text=( + 'Service Type'), + max_length=255, + null=True, + blank=True) + service_type_version = models.CharField( + help_text=( + 'Service Type Version'), + max_length=255, + null=True, + blank=True) + operation = models.CharField( + help_text=( + 'Operation'), + max_length=255, + null=True, + blank=True) + coupling_type = models.CharField( + help_text=( + 'Coupling Type'), + max_length=255, + null=True, + blank=True) + operates_on = models.CharField( + help_text=( + 'Operates On'), + max_length=255, + null=True, + blank=True) + operates_on = models.CharField( + help_text=( + 'Operates On'), + max_length=255, + null=True, + blank=True) + operates_on_identifier = models.CharField( + help_text=( + 'Operates On Identifier'), + max_length=255, + null=True, + blank=True) + operates_on_name = models.CharField( + help_text=( + 'Operates On Name'), + max_length=255, + null=True, + blank=True) + degree = models.CharField( + help_text=( + 'Degree'), + max_length=255, + null=True, + blank=True) + access_constraints = models.CharField( + help_text=( + 'Access Constraints'), + max_length=255, + null=True, + blank=True) + other_constraints = models.CharField( + help_text=( + 'Other Constraints'), + max_length=255, + null=True, + blank=True) + classification = models.CharField( + help_text=( + 'Classification'), + max_length=255, + null=True, + blank=True) + condition_applying_to_access_and_use = models.CharField( + help_text=( + 'Condition Applying To Access and Use'), + max_length=255, + null=True, + blank=True) + lineage = models.CharField( + help_text=( + 'Lineage'), + max_length=255, + null=True, + blank=True) + responsible_party_role = models.CharField( + help_text=( + 'Responsible Party Role'), + max_length=255, + null=True, + blank=True) + specification_title = models.CharField( + help_text=( + 'Specification Title'), + max_length=255, + null=True, + blank=True) + # specification_date = models.DateField() + specification_date_type = models.CharField( + help_text=( + 'Specification Date type'), + max_length=255, + null=True, + blank=True) + creator = models.CharField( + help_text=( + 'Creator'), + max_length=255, + null=True, + blank=True) + publisher = models.CharField( + help_text=( + 'Publisher'), + max_length=255, + null=True, + blank=True) + contributor = models.CharField( + help_text=( + 'Contributor'), + max_length=255, + null=True, + blank=True) + relation = models.CharField( + help_text=( + 'Relation'), + max_length=255, + null=True, + blank=True) + links = models.CharField( + help_text=( + 'Links'), + max_length=255, + null=True, + blank=True) + + objects = models.Manager() + + class Meta: + abstract = True + app_label = 'catalogue' + + def getMetadataDict(self): + """ + Returns metadata dictionary + """ + metadata = dict( + identifier=self.identifier, + type_name=self.type_name, + schema=self.schema, + mdsource=self.mdsource, + insert_date=self.insert_date, + xml='', + any_text='', + language=self.language(), + title='', + abstract='', + keywords='', + keyword_type='', + format=self.format, + source='', + date=self.date, + modified_date=self.modified_date, + type='', + bounding_box=self.bounding_box, + crs=self.crs, + alternate_title='', + revision_date=self.revision_date, + creation_date=self.creation_date, + publication_date='', + organization_name=self.organization_name, + security_constraints='', + parent_identifier='', + topic_category='', + resource_language='', + geo_desc_code='', + denominator='', + distance_value='', + distance_uom='', + temp_extent_begin='', + temp_extent_end='', + service_type='', + service_type_version='', + operation='', + coupling_type='', + operates_on='', + operates_on_identifier='', + operates_on_name='', + degree='', + access_constraints='', + other_constraints='', + classification='', + condition_applying_tau='', + lineage='', + responsible_party_role='', + spec_title='', + # spec_date='', + spec_date_type='', + creator=self.creator, + publisher=self.publisher, + contributor='', + relation='', + links=self.links,) + return metadata + + +# The use of the three classes below is for administering each satellite +# For a single metadata for all satellite, use PycswExtraFields class +class PycswCbers(PycswBase): + pass + + +class PycswLandsat(PycswBase): + pass + + +class PycswSpot(PycswBase): + pass + + +# Use this class for one table metadata +# Otherwise, use Pycsw class +class PycswExtraFields(PycswBase): + sensor_abbreviation = models.CharField( + help_text=( + 'Field to query to Dictionary_InstrumentType table using operator_abbreviation column'), + max_length=255, + null=True, + blank=True) + satellite_abbreviation = models.CharField( + help_text=( + 'Field to query to Dictionary_Satellite table using abbreviation column'), + max_length=255, + null=True, + blank=True) + + def getMetadataDict(self): + """ + Returns metadata dictionary + """ + super(PycswExtraFields, self).getMetadataDict() + metadata = dict( + sensor_abbreviation=self.sensor_abbreviation, + satellite_abbreviation=self.satellite_abbreviation,) + return metadata