Commit c019fb93 authored by Thomas Bernhart's avatar Thomas Bernhart
Browse files

Refactor into separate scripts for FOXML and media export

parent fa8bef4b
import logging
import os
import sys
import traceback
from os import listdir, makedirs, path, walk
from shutil import copy2
from ch.memobase.media import MediaFileSearcher
from ch.memobase.records_sets import RecordSetIdMapper
from ch.memobase.foxml import FoxmlReader
def _copy_file(source_file, destination_directory, destination_filename):
if not path.exists(destination_directory):
makedirs(destination_directory)
destination_path = path.join(destination_directory, destination_filename)
copy2(source_file, destination_path, follow_symlinks=False)
def _normalize_document_id(document_id):
return document_id.replace("/", "_")
def _normalize_file_extension(file_extension):
file_ext_mapping = {
"jpg": "jpeg"
}
return file_ext_mapping.get(file_extension.lower(), file_extension)
def foxml_export(objectstore_path, output_path, recordsets_csv_file):
if not path.exists(output_path):
makedirs(output_path)
# configure logger:
logger = logging.getLogger("foxml_export")
logger.setLevel(logging.DEBUG)
logging_fh = logging.FileHandler(path.join(output_path, "foxml_export.log"))
logging_fh.setLevel(logging.INFO)
logger.addHandler(logging_fh)
recordset_id_mapper = RecordSetIdMapper(recordsets_csv_file)
for r, d, f in walk(objectstore_path): # r=root, d=directories, f = files
for file in f:
foxml_path = path.join(r, file)
try:
logger.debug("Parsing FOXML file: '" + foxml_path + "'")
foxml_reader = FoxmlReader(foxml_path)
old_record_set_id = foxml_reader.get_recordset_id()
if old_record_set_id is not None:
logger.debug("FOXML file " + foxml_path + " belongs to record set " + old_record_set_id)
if recordset_id_mapper.mapping_exists(old_record_set_id):
new_record_set_id = recordset_id_mapper.get_new_record_set_id(old_record_set_id)
record_set_export_path = path.join(output_path, new_record_set_id)
if not path.exists(record_set_export_path):
makedirs(record_set_export_path)
foxml_destination_path = path.join(record_set_export_path, path.basename(foxml_path) + ".xml")
copy2(foxml_path, foxml_destination_path, follow_symlinks=False)
logger.info("Exported FOXML file '" + foxml_path + "' to '" + foxml_destination_path + "'")
else:
logger.info("Ignored FOXML file '" + foxml_path +
"': Old recordset ID not listed in 'record_sets_ids.csv'")
else:
logger.warning("Ignored FOXML file '" + foxml_path +
"': No recordset ID found in FOXML")
except: # catch *all* exceptions
traceback.print_exc(limit=1, file=sys.stdout)
logger.info("Finished FOXML export")
def media_export(record_set_path, http_files_path, rtmp_files_path):
# configure logger:
logger = logging.getLogger("media_export")
logger.setLevel(logging.DEBUG)
logging_fh = logging.FileHandler(path.join(record_set_path, "media_export.log"))
logging_fh.setLevel(logging.INFO)
logger.addHandler(logging_fh)
for foxml_path in listdir(record_set_path):
logger.info("Exporting media files for file: '" + foxml_path + "'")
foxml_reader = FoxmlReader(foxml_path)
document_id = foxml_reader.get_document_id()
media_file_searcher = MediaFileSearcher(foxml_reader, http_files_path, rtmp_files_path)
accesscopy_file = media_file_searcher.search_media_file()
if accesscopy_file is not None:
_copy_file(accesscopy_file[0], path.join(record_set_path, "media"),
_normalize_document_id(document_id) + "." + _normalize_file_extension(accesscopy_file[1]))
thumbnail_file = media_file_searcher.search_thumbnail_file()
if thumbnail_file is not None:
_copy_file(thumbnail_file[0], path.join(record_set_path, "thumbnails"),
_normalize_document_id(document_id) + "." + _normalize_file_extension(thumbnail_file[1]))
from os import path
from xml.etree import ElementTree
from hashlib import md5
from urllib.parse import quote
def parse_into_fedora_object(file):
reader = FoxmlReader(file)
return FedoraObject(
reader.get_recordset_id(),
reader.get_document_id(),
reader.get_locator(),
# reader.get_object_type(),
reader.get_thumbnail_datastream_original_filename(),
reader.get_thumbnail_datastream_file(),
reader.get_accesscopy_datastream_original_filename(),
reader.get_accesscopy_datastream_file())
def _get_element_text(start_element, xpath_expression):
el = start_element.find(xpath_expression, FoxmlReader.NAMESPACES)
if el is not None and el.text is not None:
return el.text
else:
return None
def _get_attribute_value(start_element, element_xpath_expression, attribute_label):
el = start_element.find(element_xpath_expression, FoxmlReader.NAMESPACES)
if el is not None and el.attrib[attribute_label] is not None:
return el.attrib[attribute_label]
else:
return None
def _get_last_element(start_element, xpath_expression, sort_by_attrib):
elements = start_element.findall(xpath_expression, FoxmlReader.NAMESPACES)
if len(elements) > 0:
elements.sort(reverse=True, key=lambda elem: elem.attrib[sort_by_attrib])
return elements[0]
else:
return None
def _get_metadata_datastream_element(root_element):
return _get_last_element(
root_element,
"foxml:datastream[@ID='TRANSFORMED_METADATA_0']/foxml:datastreamVersion[@LABEL='Internal Memobase Metadata']",
"CREATED")
def _get_thumbnail_datastream_element(root_element):
return _get_last_element(
root_element,
".//foxml:datastream[@ID='THUMBNAIL_0']/foxml:datastreamVersion",
"CREATED")
def _get_accesscopy_datastream_element(root_element):
return _get_last_element(
root_element,
".//foxml:datastream[@ID='ACCESSCOPY_0']/foxml:datastreamVersion",
"CREATED")
def _calculate_data_stream_path(datastream_id):
full_id = "info:fedora/" + datastream_id.replace('+', '/')
quoted_full_id = quote(full_id, safe='').replace('_', '%5F')
hash_object = md5((full_id).encode())
return path.join(hash_object.hexdigest()[0:2], quoted_full_id)
class FoxmlReader:
NAMESPACES = {
'foxml': 'info:fedora/fedora-system:def/foxml#',
'oai_dc': 'http://www.openarchives.org/OAI/2.0/oai_dc/',
'dc': 'http://purl.org/dc/elements/1.1/',
'ebucore': 'urn:ebu:metadata-schema:ebuCore_2012',
'ns2': 'http://purl.org/dc/elements/1.1/'
}
def __init__(self, file):
root_element = ElementTree.parse(file).getroot()
self.metadata_datastream_element = _get_metadata_datastream_element(root_element)
self.thumbnail_datastream_element = _get_thumbnail_datastream_element(root_element)
self.accesscopy_datastream_element = _get_accesscopy_datastream_element(root_element)
def get_recordset_id(self):
return _get_element_text(
self.metadata_datastream_element,
"foxml:xmlContent/ebucore:ebuCoreMain/ebucore:coreMetadata/ebucore:isMemberOf/ns2:relation")
def get_document_id(self):
return _get_element_text(
self.metadata_datastream_element,
"foxml:xmlContent/ebucore:ebuCoreMain/ebucore:coreMetadata/ebucore:identifier[@typeLabel='Original']/ns2:identifier")
def get_locator(self):
return _get_element_text(
self.metadata_datastream_element,
"foxml:xmlContent/ebucore:ebuCoreMain/ebucore:coreMetadata/ebucore:format/ebucore:essenceLocator/ebucore:locatorInfo")
# def get_object_type(self):
# return _get_attribute_value(
# self.metadata_datastream_element,
# "foxml:xmlContent/ebucore:ebuCoreMain/ebucore:coreMetadata/ebucore:type/ebucore:objectType",
# "typeLabel")
def get_accesscopy_datastream_original_filename(self):
if self.accesscopy_datastream_element is not None:
return self.accesscopy_datastream_element.attrib['LABEL']
else:
return None
def get_accesscopy_datastream_file(self):
if self.accesscopy_datastream_element is not None:
accesscopy_ref = _get_attribute_value(self.accesscopy_datastream_element, "foxml:contentLocation", "REF")
return _calculate_data_stream_path(accesscopy_ref)
else:
return None
def get_thumbnail_datastream_original_filename(self):
if self.thumbnail_datastream_element is not None:
return self.thumbnail_datastream_element.attrib['LABEL']
else:
return None
def get_thumbnail_datastream_file(self):
if self.thumbnail_datastream_element is not None:
thumbnail_ref = _get_attribute_value(self.thumbnail_datastream_element, "foxml:contentLocation", "REF")
return _calculate_data_stream_path(thumbnail_ref)
else:
return None
# class FoxmlParsingError(Exception):
# pass
class FedoraObject:
# def __init__(self, record_set, document_id, locator, object_type, thumbnail_datastream_original_filename,
# thumbnail_datastream_file, accesscopy_datastream_original_filename, accesscopy_datastream_file):
def __init__(self, record_set, document_id, locator, thumbnail_datastream_original_filename,
thumbnail_datastream_file, accesscopy_datastream_original_filename, accesscopy_datastream_file):
self.record_set = record_set
self.document_id = document_id
self.locator = locator
# self.object_type = object_type
self.thumbnail_original_filename = thumbnail_datastream_original_filename
self.thumbnail_datastream_file = thumbnail_datastream_file
self.accesscopy_original_filename = accesscopy_datastream_original_filename
self.accesscopy_datastream_file = accesscopy_datastream_file
from os import path
from ch.memobase.foxml import FoxmlReader
class MediaFileSearcher:
def __init__(self, foxml_reader: FoxmlReader, http_files_path, rtmp_files_path):
self.foxml_reader = foxml_reader
self.http_files_path = http_files_path
self.rtmp_files_path = rtmp_files_path
def search_media_file(self):
accesscopy_file = self.foxml_reader.get_accesscopy_datastream_file()
if accesscopy_file is not None:
ext = path.splitext(self.foxml_reader.get_accesscopy_datastream_original_filename())[1]
return accesscopy_file, ext
else:
locator = self.foxml_reader.get_locator()
if locator is not None:
# copy streaming resource
if locator.startswith('https://memobase.ch/files/'):
http_resource_file = self.__get_http_resource_file(locator)
ext = path.splitext(http_resource_file)[1]
return http_resource_file, ext
elif locator.startswith('rtmp://intstream.memobase.ch:1935/memobase/'):
rtmp_resource_file = self.__get_rtmp_resource_file(locator)
ext = path.splitext(rtmp_resource_file)[1]
return rtmp_resource_file, ext
else:
return None
else:
return None
def search_thumbnail_file(self):
thumbnail_file = self.foxml_reader.get_thumbnail_datastream_file()
if thumbnail_file is not None:
ext = path.splitext(self.foxml_reader.get_thumbnail_datastream_original_filename())[1]
return thumbnail_file, ext
else:
return None
def __get_http_resource_file(self, locator):
return path.join(self.http_files_path, locator[len('https://memobase.ch/files/'):])
def __get_rtmp_resource_file(self, locator):
rtmp_rel_path = locator[len('rtmp://intstream.memobase.ch:1935/memobase/'):]
source_filename = rtmp_rel_path[rtmp_rel_path.find(':') + 1:]
source_path1 = path.join(self.rtmp_files_path, source_filename)
source_path2 = path.join(self.rtmp_files_path, 'open', source_filename)
if path.isfile(source_path1):
return source_path1
elif path.isfile(source_path2):
return source_path2
else:
return None
from csv import DictReader
class RecordSetIdMapper:
def __init__(self, records_sets_file):
self.__old2new = {}
with open(records_sets_file, 'r') as csv_file:
for row in DictReader(csv_file):
old_id = row['identifier_old']
new_id = row['identifier_new']
self.__old2new[old_id] = new_id
def mapping_exists(self, old_id):
return old_id in self.__old2new
def get_new_record_set_id(self, old_id):
return self.__old2new[old_id]
#!/usr/bin/env python
# coding: utf-8
from ch.memobase.export import foxml_export
import logging
import os
import sys
import traceback
from ch.memobase.foxml import parse_into_fedora_object
from ch.memobase.foxml import FoxmlReader
from ch.memobase.records_sets import RecordSetIdMapper
from shutil import copy2
# class FoxmlParsingError(Exception):
# pass
#
#
# def get_last_element(tree, xpath_expression, namespaces, sort_by_attrib):
# elements = tree.findall(xpath_expression, namespaces)
# if (len(elements) > 0):
# elements.sort(reverse=True, key=lambda elem:elem.attrib[sort_by_attrib])
# return elements[0]
# else:
# return None
#
#
# def parse_into_fedora_object(tree, namespaces, metadata_datastream_version):
# relation_el = metadata_datastream_version.find("foxml:xmlContent/ebucore:ebuCoreMain/ebucore:coreMetadata/ebucore:isMemberOf/ns2:relation", namespaces)
#
# if (relation_el is None or relation_el.text is None):
# return None
# else:
# fedora_object = {}
# fedora_object['record_set'] = relation_el.text
#
# identifier_el = metadata_datastream_version.find("foxml:xmlContent/ebucore:ebuCoreMain/ebucore:coreMetadata/ebucore:identifier[@typeLabel='Original']/ns2:identifier", namespaces)
# if (identifier_el is not None and identifier_el.text is not None):
# fedora_object['document_id'] = identifier_el.text
#
# return fedora_object
#
#
# def parse_foxml(file):
# namespaces = {
# 'foxml': 'info:fedora/fedora-system:def/foxml#',
# 'oai_dc': 'http://www.openarchives.org/OAI/2.0/oai_dc/',
# 'dc': 'http://purl.org/dc/elements/1.1/',
# 'ebucore': 'urn:ebu:metadata-schema:ebuCore_2012',
# 'ns2': 'http://purl.org/dc/elements/1.1/'
# }
#
# tree = ET.parse(file)
#
# metadata_datastream_version = get_last_element(tree, "foxml:datastream[@ID='TRANSFORMED_METADATA_0']/foxml:datastreamVersion[@LABEL='Internal Memobase Metadata']", namespaces, 'CREATED')
# if (metadata_datastream_version is None):
# return None
# else:
# return parse_into_fedora_object(tree, namespaces, metadata_datastream_version)
objectstore_path = '/mnt/docuteam-intern/scratch/570-8_Memobase-Datenexport_loeschen-2021_be/Datenexport/objectStore'
# output_directory = '/mnt/docuteam-intern/scratch/570-8_Memobase-Datenexport_loeschen-2021_be/sftp_20210228'
output_directory = './sftp_20210228'
foxml_export(objectstore_path, output_directory, "./record_sets_ids.csv")
# recordset_id_mapper = RecordSetIdMapper('./record_sets_ids.csv')
#
# if not os.path.exists(output_directory):
# os.makedirs(output_directory)
#
# for r, d, f in os.walk(objectstore_path): # r=root, d=directories, f = files
# for file in f:
# foxml_path = os.path.join(r, file)
# try:
# logging.info("Parsing FOXML file: " + foxml_path)
# foxml_reader = FoxmlReader(foxml_path)
# old_record_set_id = foxml_reader.get_recordset_id()
# logging.debug("FOXML file " + foxml_path + " belongs to record set " + old_record_set_id)
#
# new_record_set_id = recordset_id_mapper.get_new_record_set_id(old_record_set_id)
# record_set_export_path = os.path.join(output_directory, new_record_set_id)
# if not os.path.exists(record_set_export_path):
# os.makedirs(record_set_export_path)
# foxml_destination_path = os.path.join(record_set_export_path, os.path.basename(foxml_path) + ".xml")
# copy2(foxml_path, foxml_destination_path, follow_symlinks=False)
# logging.info("Exported FOXML file '" + foxml_path + "' to '" + foxml_destination_path + "'")
# except: # catch *all* exceptions
# traceback.print_exc(limit=1, file=sys.stdout)
#
# logging.info("Finished FOXML export")
#!/usr/bin/env python
# coding: utf-8
from ch.memobase.export import foxml_export, media_export
from os import listdir
from os import path
objectstore_path = '/mnt/docuteam-intern/scratch/570-8_Memobase-Datenexport_loeschen-2021_be/Datenexport/objectStore'
http_files_path = '/mnt/docuteam-intern/scratch/570-8_Memobase-Datenexport_loeschen-2021_be/Datenexport/public-files'
rtmp_files_path = '/mnt/docuteam-intern/scratch/570-8_Memobase-Datenexport_loeschen-2021_be/Datenexport/library'
# output_directory = '/mnt/docuteam-intern/scratch/570-8_Memobase-Datenexport_loeschen-2021_be/sftp_20210228'
output_directory = './sftp_20210228'
foxml_export(objectstore_path, output_directory, "./record_sets_ids.csv")
for record_set_directory in listdir(output_directory):
record_set_path = path.join(output_directory, record_set_directory)
if path.isdir(record_set_path):
media_export(record_set_path, http_files_path, rtmp_files_path)
#!/usr/bin/env python
# coding: utf-8
from ch.memobase.export import media_export
exported_record_set_path = './sftp_20210228/adg-001'
http_files_path = '/mnt/docuteam-intern/scratch/570-8_Memobase-Datenexport_loeschen-2021_be/Datenexport/public-files'
rtmp_files_path = '/mnt/docuteam-intern/scratch/570-8_Memobase-Datenexport_loeschen-2021_be/Datenexport/library'
media_export(exported_record_set_path, http_files_path, rtmp_files_path)
import os
import sy
import traceback
import xml.etree.ElementTree as ET
from hashlib import md5
from shutil import copy2
from urllib.parse import quote
# def copy_thumbnail(datastream_store_path, thumbnail_directory, fedora_object):
# if not os.path.exists(thumbnail_directory):
# os.makedirs(thumbnail_directory)
#
# thumbnail_filename = fedora_object['document_id'] + os.path.splitext(fedora_object['thumbnail_original_filename'])[1]
# destination_path = os.path.join(thumbnail_directory, thumbnail_filename)
# thumbnail_path = calculate_data_stream_path(datastream_store_path, fedora_object['thumbnail_ref'])
# copy2(thumbnail_path, destination_path, follow_symlinks=False)
# print("Copied '{}' to '{}'".format(thumbnail_path, destination_path))
#
#
# def copy_accesscopy(datastream_store_path, accesscopy_directory, fedora_object):
# if not os.path.exists(accesscopy_directory):
# os.makedirs(accesscopy_directory)
#
# accesscopy_filename = fedora_object['document_id'] + os.path.splitext(fedora_object['accesscopy_original_filename'])[1]
# destination_path = os.path.join(accesscopy_directory, accesscopy_filename)
# accesscopy_path = calculate_data_stream_path(datastream_store_path, fedora_object['accesscopy_ref'])
# copy2(accesscopy_path, destination_path, follow_symlinks=False)
# print("Copied '{}' to '{}'".format(accesscopy_path, destination_path))
#
#
# def copy_http_resource(accesscopy_path, accesscopy_directory, fedora_object):
# if not os.path.exists(accesscopy_directory):
# os.makedirs(accesscopy_directory)
#
# locator = fedora_object['locator']
# source_path = os.path.join(http_files_path, locator[len('https://memobase.ch/files/'):])
# destination_filename = fedora_object['document_id'] + os.path.splitext(accesscopy_path)[1]
# destination_path = os.path.join(accesscopy_directory, destination_filename)
# copy2(source_path, destination_path, follow_symlinks=False)
# print("Copied '{}' to '{}'".format(source_path, destination_path))
#
#
# def copy_rtmp_resource(rtmp_files_path, accesscopy_directory, fedora_object):
# if not os.path.exists(accesscopy_directory):
# os.makedirs(accesscopy_directory)
#
# locator = fedora_object['locator']
# rtmp_rel_path = locator[len('rtmp://intstream.memobase.ch:1935/memobase/'):]
# source_filename = rtmp_rel_path[rtmp_rel_path.find(':') + 1:]
# source_path1 = os.path.join(rtmp_files_path, source_filename)
# source_path2 = os.path.join(rtmp_files_path, 'open', source_filename)
# destination_filename = fedora_object['document_id'] + os.path.splitext(source_filename)[1]
# destination_path = os.path.join(accesscopy_directory, destination_filename)
# if (os.path.isfile(source_path1)):
# copy2(source_path1, destination_path, follow_symlinks=False)
# print("Copied '{}' to '{}'".format(source_path1, destination_path))
# elif (os.path.isfile(source_path2)):
# copy2(source_path2, destination_path, follow_symlinks=False)
# print("Copied '{}' to '{}'".format(source_path2, destination_path))
# else:
# raise Exception('rtmp resource not found.')
#
#
# # r=root, d=directories, f = files
# record_set_path = '/mnt/docuteam-intern/scratch/570-8_Memobase-Datenexport_loeschen-2021_be/Datenexport/objectStore'
# datastreamstore_path = '/mnt/docuteam-intern/scratch/570-8_Memobase-Datenexport_loeschen-2021_be/Datenexport/datastreamStore'
# http_files_path = '/mnt/docuteam-intern/scratch/570-8_Memobase-Datenexport_loeschen-2021_be/Datenexport/public-files'
# rtmp_files_path = '/mnt/docuteam-intern/scratch/570-8_Memobase-Datenexport_loeschen-2021_be/Datenexport/library'
#
# for foxml_file in os.listdir(objectstore_path):
# try:
# print("Parsing FOXML file: " + foxml_file)
# foxml_reader = FoxmlReader(foxml_path)
# print("Extracting files for: record set: " + fedora_object['record_set'] + ' ; document: ' + fedora_object['document_id'])
#
# record_set_path = os.path.join(record_set_path, fedora_object['record_set'])
# if not os.path.exists(record_set_path):
# os.makedirs(record_set_path)
#
# foxml_destination_path = os.path.join(record_set_path, os.path.basename(foxml_file) + ".xml")
# copy2(foxml_file, foxml_destination_path, follow_symlinks=False)
# './record_sets_ids.csv'./record_sets_ids.csv''
# if ('thumbnail_ref' in fedora_object):
# thumbnail_directory = os.path.join(record_set_path, fedora_object['record_set'], 'thumbnails')
# copy_thumbnail(datastreamstore_path, thumbnail_directory, fedora_object)
#
# accesscopy_directory = os.path.join(record_set_path, fedora_object['record_set'], 'media')
# if 'accesscopy_ref' in fedora_object:
# copy_accesscopy(datastreamstore_path, accesscopy_directory, fedora_object)
# elif 'locator' in fedora_object:
# # copy streaming resource
# if (fedora_object['locator'].startswith('https://memobase.ch/files/')):
# copy_http_resource(http_files_path, accesscopy_directory, fedora_object)
# elif (fedora_object['locator'].startswith('rtmp://intstream.memobase.ch:1935/memobase/')):
# copy_rtmp_resource(rtmp_files_path, accesscopy_directory, fedora_object)
#
# print("Successfully extracted any files")
# except: # catch *all* exceptions
# traceback.print_exc(limit=1, file=sys.stdout)
#
# print("Finished data extraction")
identifier_new,identifier_old,institution_id
csa-001,CS-CS_CF,csa
cdt-001,CdT-SON,cdt
ati-002,ASTi-FPC,ati
rti-001,Radiotelevisionesvizzera-Documentario,rti
srf-001,SRF-bv8,srf
srf-002,SRF-BPBV8,srf
srf-003,SRF-CH-M,srf
srf-004,SRF-Karussell,srf
srf-005,SRF-Kassensturz,srf
srf-006,SRF-LSR,srf
srf-007,SRF-MTW,srf
srf-008,SRF-Netto,srf
srf-009,SRF-PDW,srf
srf-010,SRF-RJ,srf
srf-011,SRF-RS,srf
srf-012,SRF-TS,srf
mfk-001,mfk-FLM,mfk
soz-005,SozArch-Sozarch_F_9045,soz
afz-001,AfZ-Lutz,afz
maa-001,SMA-IBA,maa
zem-001,ZEM-F,zem
soz-001,SozArch-F_9005,soz
soz-002,SozArch-F_9004,soz
lfg-001,LJ-Filmbestand_Langjahr_GmbH,lfg
kbg-001,KBGR-AV,kbg
maa-002,SMA-SK,maa
agl-001,LAGL-PA_111_Sch_Y,agl
bar-001,SFW_CJS_CGS-SFW_CJS_CGS,bar
bar-002,BAR-SABZ,bar
soz-003,SozArch-F_9003,soz
afz-002,AfZ-Bosshard,afz
mav-001,Memoriav-MB_alt_film,mav
clg-001,CL-Leuzinger,clg
lkb-001,LS-film,lkb
ati-001,ASTi-Monotti,ati
mem-001,CentroElisarion-vonKupffervonMayer,mem
fad-001,ArchivioDonetta-Donetta,fad
rti-002,Radiotelevisionesvizzera-DM,rti
cde-001,Cde-LEYDI,cde
fer-001,FER-RPN,fer
rti-003,Radiotelevisionesvizzera-Archiv,rti
cdt-002,CdT-gar,cdt
cic-001,ICRC-V-F-CR-H,cic
ikr-001,IFRC-FILM,ikr
mgb-001,Museegruerien-Morel,mgb
mhl-001,MHL-Constant,mhl
mws-001,Mediatheque-Schmid,mws
mgb-002,Museegruerien-Prangey,mgb
bcf-001,BCUF-Thevoz,bcf
mdl-001,MdL-ML,mdl
ias-001,IASA-Collart,ias
kmm-001,MuseeLaNeuveville-Hirt,kmm
mgb-003,Museegruerien-Glasson,mgb
bpu-001,BPUN-WIRI,bpu
rts-001,RTS-DM_GE,rts
rts-002,RTS-DM_LS,rts