def __init__(self, avm_dict=None, xmp=None, version="1.1"): # Dictionary storage for AVM, synchronizes with the XMP packet self.data = {} # Create an XMPMeta object self.xmp = libxmp.XMPMeta() # Check the version type if version == "1.1": self.specs = SPECS_1_1 # Register all avm schema for SCHEMA, PREFIX in AVM_SCHEMAS.items(): self.xmp.register_namespace(SCHEMA, PREFIX) # Pass an XMPMeta object if xmp: # Parse for AVM self.xmp = xmp # Synchronize XMP data with dictionary for key, value in self.specs.items(): avmdt = self.specs[key] try: if avmdt.get_data(self.xmp): self.data[key] = avmdt.get_data(self.xmp) except: continue # Pass an AVM dictionary if avm_dict: for key, item in avm_dict.iteritems(): try: self[key] = item except: # Suppress error for items not in specs dictionary continue
def test(*dummy): if exception is not None: raise exception if libxmp is None: raise SkipTest(libxmp_import_error) meta = libxmp.XMPMeta() def get(namespace, key): return meta.get_property(namespace, key) meta.parse_from_str(xmp_file.read()) assert_equal(get(ns.dc, 'format'), 'image/x-test') mod_date = get(ns.xmp, 'ModifyDate') metadata_date = get(ns.xmp, 'MetadataDate') assert_equal(mod_date, metadata_date) document_id = get(ns.xmpmm, 'DocumentID') assert_uuid_urn(document_id) instance_id = get(ns.xmpmm, 'InstanceID') assert_uuid_urn(instance_id) assert_equal(get(ns.xmpmm, 'History[1]/stEvt:action'), 'converted') software_agent = get(ns.xmpmm, 'History[1]/stEvt:softwareAgent') assert_correct_software_agent(software_agent) assert_equal(get(ns.xmpmm, 'History[1]/stEvt:parameters'), 'to image/x-test') assert_equal(get(ns.xmpmm, 'History[1]/stEvt:instanceID'), instance_id) assert_equal(get(ns.xmpmm, 'History[1]/stEvt:when'), str(mod_date)) assert_equal(get(ns.didjvu, 'test_int'), '42') assert_equal(get(ns.didjvu, 'test_str'), 'eggs') assert_equal(get(ns.didjvu, 'test_bool'), 'True')
def avm_to_file(file_path, dict={}, replace=False): """ Function to inject AVM into a file. Preserves existing XMP in the file, while replacing fields passed through dict. If a field is an unordered list, then data is appended to existing values :param file_path: Path to file :param dict: A dictionary containing AVM metadata :param xmp: An XMPMeta instance :param replace: Boolean to replace the exisiting XMP in the file. By default it is set to False. :return: Boolean .. todo:: Improve avm_to_file function. Add ability to input an XMP file """ xmpfile = libxmp.files.XMPFiles() try: xmpfile.open_file(file_path, open_forupdate=True) except libxmp.XMPError: return False if replace is True: xmp = libxmp.XMPMeta() else: xmp = xmpfile.get_xmp() if xmp: pass else: xmp = libxmp.XMPMeta() avm = libavm.AVMMeta(xmp=xmp, avm_dict=dict) if xmpfile.can_put_xmp(avm.xmp): xmpfile.put_xmp(avm.xmp) xmpfile.close_file() return True else: return False
def test(*dummy): if exception is not None: raise exception if libxmp is None: raise SkipTest(libxmp_import_error) meta = libxmp.XMPMeta() def get(namespace, key): return meta.get_property(namespace, key) meta.parse_from_str(xmp_file.read()) assert_equal(get(ns.dc, 'format'), 'image/x-test') assert_equal(get(ns.tiff, 'ImageWidth'), '69') assert_equal(get(ns.tiff, 'ImageHeight'), '42') assert_equal(get(ns.xmp, 'CreatorTool'), self._original_software_agent) create_date = get(ns.xmp, 'CreateDate') assert_equal(create_date, self._original_create_date) mod_date = get(ns.xmp, 'ModifyDate') assert_greater(mod_date, create_date) metadata_date = get(ns.xmp, 'MetadataDate') assert_equal(mod_date, metadata_date) # (Original)DocumentID: original_document_id = get(ns.xmpmm, 'OriginalDocumentID') assert_equal(original_document_id, self._original_document_id) document_id = get(ns.xmpmm, 'DocumentID') assert_uuid_urn(document_id) assert_not_equal(document_id, original_document_id) assert_uuid_urn(document_id) # InstanceID: instance_id = get(ns.xmpmm, 'InstanceID') assert_uuid_urn(instance_id) # History[1]: assert_equal(get(ns.xmpmm, 'History[1]/stEvt:action'), 'created') assert_equal(get(ns.xmpmm, 'History[1]/stEvt:softwareAgent'), self._original_software_agent) original_instance_id = get(ns.xmpmm, 'History[1]/stEvt:instanceID') assert_equal(original_instance_id, self._original_instance_id) assert_not_equal(instance_id, original_instance_id) assert_equal(get(ns.xmpmm, 'History[1]/stEvt:when'), create_date) # History[2]: assert_equal(get(ns.xmpmm, 'History[2]/stEvt:action'), 'converted') software_agent = get(ns.xmpmm, 'History[2]/stEvt:softwareAgent') assert_correct_software_agent(software_agent) assert_equal(get(ns.xmpmm, 'History[2]/stEvt:parameters'), 'from image/png to image/x-test') assert_equal(get(ns.xmpmm, 'History[2]/stEvt:instanceID'), instance_id) assert_equal(get(ns.xmpmm, 'History[2]/stEvt:when'), mod_date) # internal properties: assert_equal(get(ns.didjvu, 'test_int'), '42') assert_equal(get(ns.didjvu, 'test_str'), 'eggs') assert_equal(get(ns.didjvu, 'test_bool'), 'True')
def __init__(self, pdf_metadata): self.pdf_metadata = pdf_metadata self.n_thumbnail = 0 # some XMP set-up self.md = libxmp.XMPMeta() self.dc = libxmp.consts.XMP_NS_DC self.pdf = libxmp.consts.XMP_NS_PDF self.pdfaid = libxmp.consts.XMP_NS_PDFA_ID self.xmp = libxmp.consts.XMP_NS_XMP self.xmpGImg = "http://ns.adobe.com/xap/1.0/g/img/" self.md.register_namespace(self.pdf, "pdf") self.md.register_namespace(self.dc, "dc") self.md.register_namespace(self.pdfaid, "pdfaid") self.md.register_namespace(self.xmp, "xmp") self.md.register_namespace(self.xmpGImg, "xmpGImg")
def _extract_labels(self, filename): if not LIBXMP: return None xmp = libxmp.utils.file_to_dict(filename) meta = libxmp.XMPMeta() ns = libxmp.consts.XMP_NS_DM p = meta.get_prefix_for_namespace(ns) #track_re = re.compile("^" + p + r"Tracks\[(\d+)\]$") #n_tracks = 0 cp_track = None new_xmp = {} for prop in xmp[ns]: new_xmp[prop[0]] = prop[1:] # find the cuepoint markers track name_re = re.compile("^" + p + r"Tracks\[(\d+)\]/" + p + "trackName$") for prop, val in new_xmp.iteritems(): match = name_re.match(prop) if match: if val[0] == "CuePoint Markers": cp_track = match.group(1) # get all the markers from it cp_path = re.compile(r"^%sTracks\[%s\]/%smarkers\[(\d+)\]$" % (p, cp_track, p)) markers = [] #sr = float(new_xmp["%sTracks[%s]/%sframeRate" % # (p, cp_track, p)][0].replace('f', '')) sr = float(self.samplerate) for prop, val in new_xmp.iteritems(): match = cp_path.match(prop) if match: markers.append( Label(new_xmp[prop + '/' + p + 'name'][0], float(new_xmp[prop + '/' + p + 'startTime'][0]) / sr)) if len(markers) is 0: return None return markers
def test(*dummy): if exception is not None: raise exception if libxmp is None: raise SkipTest(libxmp_import_error) meta = libxmp.XMPMeta() meta.parse_from_str(xmp_file.read()) xml_meta = meta.serialize_to_str(omit_all_formatting=True, omit_packet_wrapper=True) logging.debug(repr(xml_meta)) xml_meta = io.StringIO(xml_meta) iterator = etree.iterparse(xml_meta, events=('start', 'end')) iterator = iter(iterator) # odd, but needed for Python 2.6 def pop(): return next(iterator) event, element = pop() assert_equal(event, 'start') assert_equal(element.tag, '{adobe:ns:meta/}xmpmeta') event, element = pop() assert_equal(event, 'start') assert_equal(element.tag, '{%s}RDF' % ns.rdf) event, element = pop() assert_equal(event, 'start') assert_equal(element.tag, '{%s}Description' % ns.rdf) assert_equal(element.attrib['{%s}about' % ns.rdf], '') event, element = pop() assert_equal(event, 'end') event, element = pop() assert_equal(event, 'end') event, element = pop() assert_equal(event, 'end') try: event, element = pop() except StopIteration: event, element = None, None assert_is_none(event)
# Returns base64-encoded ZIP archive with all files in file listing def generate_payload(file_listing): zip_buffer = io.BytesIO() with zipfile.ZipFile(zip_buffer, mode='w', compression=zipfile.ZIP_LZMA) as zip_file: for filename in file_listing: logging.info(f'Compressing file {filename}') zip_file.write(filename, os.path.basename(filename)) return base64.b64encode(zip_buffer.getbuffer()).decode('utf8') if __name__ == '__main__': args = parser.parse_args() logging.basicConfig(level=logging.DEBUG) # Create a copy of the input file with open(args.output, 'wb') as output_io: output_io.write(open(args.input, 'rb').read()) logging.info(f'Reading input image {args.input}') xmp_file = libxmp.XMPFiles(file_path=args.output, open_forupdate=True) xmp_meta = libxmp.XMPMeta() xmp_meta.set_property(libxmp.consts.XMP_NS_DC, u'embedded_payload', generate_payload(args.filename)) logging.info(f'Writing output image {args.output}') xmp_file.put_xmp(xmp_meta) xmp_file.close_file()
def export(self, **kwargs): """ Generate audio file from composition. :param str. filename: Output filename (no extension) :param str. filetype: Output file type (only .wav supported for now) :param integer samplerate: Sample rate of output audio :param integer channels: Channels in output audio, if different than originally specified :param bool. separate_tracks: Also generate audio file for each track in composition :param int min_length: Minimum length of output array (in frames). Will zero pad extra length. :param bool. adjust_dynamics: Automatically adjust dynamics (will document later) """ # get optional args filename = kwargs.pop('filename', 'out') filetype = kwargs.pop('filetype', 'wav') adjust_dynamics = kwargs.pop('adjust_dynamics', False) samplerate = kwargs.pop('samplerate', None) channels = kwargs.pop('channels', self.channels) separate_tracks = kwargs.pop('separate_tracks', False) min_length = kwargs.pop('min_length', None) if samplerate is None: samplerate = np.min([track.samplerate for track in self.tracks]) encoding = 'pcm16' to_mp3 = False if filetype == 'ogg': encoding = 'vorbis' elif filetype == 'mp3': filetype = 'wav' to_mp3 = True if separate_tracks: # build the separate parts of the composition if desired for track in self.tracks: out = self.build(track_list=[track], adjust_dynamics=adjust_dynamics, min_length=min_length, channels=channels) out_file = Sndfile( "%s-%s.%s" % (filename, track.name, filetype), 'w', Format(filetype, encoding=encoding), channels, samplerate) out_file.write_frames(out) out_file.close() # always build the complete composition out = self.build(adjust_dynamics=adjust_dynamics, min_length=min_length, channels=channels) out_filename = "%s.%s" % (filename, filetype) out_file = Sndfile(out_filename, 'w', Format(filetype, encoding=encoding), channels, samplerate) out_file.write_frames(out) out_file.close() if LIBXMP and filetype == "wav": xmp = libxmp.XMPMeta() ns = libxmp.consts.XMP_NS_DM p = xmp.get_prefix_for_namespace(ns) xpath = p + 'Tracks' xmp.append_array_item(ns, xpath, None, array_options={"prop_value_is_array": True}, prop_value_is_struct=True) xpath += '[1]/' + p xmp.set_property(ns, xpath + "trackName", "CuePoint Markers") xmp.set_property(ns, xpath + "trackType", "Cue") xmp.set_property(ns, xpath + "frameRate", "f%d" % samplerate) for i, lab in enumerate(self.labels): xmp.append_array_item( ns, xpath + "markers", None, array_options={"prop_value_is_array": True}, prop_value_is_struct=True) xmp.set_property(ns, xpath + "markers[%d]/%sname" % (i + 1, p), lab.name) xmp.set_property( ns, xpath + "markers[%d]/%sstartTime" % (i + 1, p), str(lab.sample(samplerate))) xmpfile = libxmp.XMPFiles(file_path=out_filename, open_forupdate=True) if xmpfile.can_put_xmp(xmp): xmpfile.put_xmp(xmp) xmpfile.close_file() if to_mp3: wav_to_mp3(out_filename, delete_wav=True) return out
def __init__(self): backend = self._backend = libxmp.XMPMeta() prefix = backend.register_namespace(ns.didjvu, 'didjvu') if prefix is None: raise XmpError('Cannot register namespace for didjvu internal properties') # no coverage