def embed(tcop, files): # embed the specified claim in each file for filename in files: try: metadata(filename).setClaim(tcop) except: traceback.print_exc() sys.exit(2)
def embed (self, event=None): # get form values license = self.getField('licenseurl').getValue() verify_url = self.verificationUrl year = self.getField('copyrightyear').getValue() holder = self.getField('copyrightholder').getValue() for filename in self.files: try: metadata(filename).embed(license, verify_url, year, holder) except NotImplementedError, e: pass
def lookup(filename, displayOnly=False): # retrieve the license claim mdata = metadata(filename) claim = mdata.getClaim() # check if it actually exists if claim is None: # no license; bail out print "%s does not contain a copyright/license claim." % filename return None else: print "%s contains the following claim:" % filename print claim if displayOnly: # only displaying; bail out return None # verify the file try: if cctagutils.lookup.lookup(filename): print "Verified." else: print "Unable to verify claim." except: # an error occured while trying to verify the claim... # print a traceback to stderr and return the appropriate exit code pprint.pprint(sys.exc_info(), sys.stderr) sys.exit(3)
def itemSelected(event): """IItemSelected event subscriber which provides ID3 metadata for MP3 files.""" # make sure a FileItem was selected if (p6.storage.interfaces.IFileItem in zope.interface.implementedBy(event.item.__class__)): try: id3 = metadata(event.item.getIdentifier()) if id3 is None: return # this is a file item; try to extract ID3 updateEvent = p6.metadata.events.UpdateMetadataEvent( event.item, 'http://purl.org/dc/elements/1.1/title', id3.getTitle() ) zope.component.handle(updateEvent) except NotImplementedError, e: """NotImplementedError simply indicates the cctagutils metadata framework can not extract the field; nothing to see here, move along.""" return
def getMetadata(self, filename=None): ### TODO: use storage metadata classes. meta = {} formats = {'Other':None, 'Audio':'Sound', 'Video':'MovingImage', 'Image':'StillImage', 'Text':'Text', 'Interactive':'InteractiveResource' } controls = {'TXT_WORK_TITLE':'title', 'TXT_DESCRIPTION':'description', 'TXT_CREATOR':'creator', 'TXT_SOURCE_URL':'source', 'TXT_KEYWORDS':'subjects' } # get the text control values for c in controls: if XRCCTRL(self, c).GetValue(): meta[controls[c]] = XRCCTRL(self, c).GetValue() # get the work format meta['format'] = formats[XRCCTRL(self, "CMB_WORK_FORMAT").GetValue()] if filename is None: return meta try: if 'creator' not in meta: meta['creator'] = metadata(filename).getArtist() if 'title' not in meta: meta['title'] = metadata(filename).getTitle() except NotImplementedError, e: pass
def embed(options, files): # get option values license = options.license verify_url = options.validation year = options.year holder = options.holder # embed the specified license in each file for filename in files: try: metadata(filename).embed(license, verify_url, str(year), holder) except: pprint.pprint(sys.exc_info(), sys.stderr) sys.exit(2) # generate the verification RDF try: verification = rdf.generate(files, verify_url, license, str(year), holder) except: traceback.print_exc() sys.exit(3) return verification
def verify(filename): """Extracts license claim information from a file and verifies it. Returns the following status codes: 1 Verified 0 No RDF -1 Work information not found (possible SHA1 mismatch) -2 Verification license does not match claim. """ status = 0 claim = metadata(filename).getClaim() if claim is None: raise cctag.exceptions.NotLicensedException fileinfo = parseClaim(claim) fileinfo["sha"] = "urn:sha1:%s" % cctag.rdf.fileHash(filename) verifyRdf = rdfextract.RdfExtractor().extractRdfText(rdfextract.retrieveUrl(fileinfo["verify at"])) # check if we found any RDF at all, and update the status code if len(verifyRdf) > 0: status = -1 # check each block of RDF # (a verification page may also have it's own license RDF embedded) for block in verifyRdf: # parse/validate the RDF verifyCc = ccrdf.ccRdf() verifyCc.parse(block) # for each work in the RDF block... for work in verifyCc.works(): # if the subject matches... if work.subject == fileinfo["sha"]: # we found the work information; # only one reason left to not verify status = -2 # we found the work, now make sure the license matches for license in work.licenses(): if license == fileinfo["license"]: return 1 # either the file wasn't found, or the license didn't match return status
def selectFile(self, filename): self.reset() # set the filename label self.fileInfo['filename'] = filename self.fileInfo['short_filename'] = os.path.basename(filename) self.fileInfo['status'] = 'working...' # reset the UI self.updateInterface() # set the cursor to busy __cur_cursor = self.GetCursor() self.SetCursor(wx.StockCursor(wx.CURSOR_WAIT)) # update the app wx.Yield() # retrieve the file metadata self.fileInfo['metadata'] = mdata = metadata(filename) # try to verify the license claim (if it exists) status = mdata.verify() # determine the status message if status == cctagutils.VERIFY_VERIFIED: self.fileInfo['status'] = "Embedded license claim verified." elif status == cctagutils.VERIFY_NO_RDF: self.fileInfo['status'] = "Unable to compare claims; no verification metadata found." elif status == cctagutils.VERIFY_NO_WORK: self.fileInfo['status'] = "Unable to verify; no work information found." elif status == cctagutils.VERIFY_NO_MATCH: self.fileInfo['status'] = "Embedded claim does not match verification information." elif status == cctagutils.VERIFY_NO_CLAIM: self.fileInfo['status'] = "No verification information found." else: self.fileInfo['status'] = '' self.updateInterface() self.SetCursor(__cur_cursor) self.Layout()
def selectFile(self, event): print 'in selectfile' print event print event.item_id if not(event.removed): # set the value of copyright holder (artist) and copyright year file_info = metadata(event.item_id) try: artist = str(file_info.getArtist()) self.getField('copyright_holder').setValue(artist) self.getField('copyright_year').setValue(str(file_info.getYear())) self.getField('title').setValue(str(file_info.getTitle())) except NotImplementedError: # the file type is not supported by the metadata framework pass
def itemSelected(event): """IItemSelected event subscriber which provides ID3 metadata for MP3 files.""" def group(groupid): """Convenience function for finding a metadata group by id.""" # XXX should this go into p6.api? return [n for n in p6.api.getApp().groups if n.id == groupid][0] # make sure a FileItem was selected if (p6.storage.interfaces.IFileItem in zope.interface.providedBy(event.item)): id3 = metadata(event.item.getIdentifier()) if id3 is None: # the cctagutils framework doesn't know how to handle this file return # this is a file item; try to extract ID3 # only actually publish an update event when the file contains a value # XXX this should really update the metadata for this item instead of # the work -- would be a more generic solution, but will require # handling in the UI # Title updateEvent = p6.metadata.events.UpdateMetadataEvent( p6.storage.interfaces.IWork, group('workinfo').get('http://purl.org/dc/elements/1.1/title'), id3.getTitle() ) if id3.getTitle(): zope.component.handle(updateEvent) # Author updateEvent = p6.metadata.events.UpdateMetadataEvent( p6.storage.interfaces.IWork, group('workinfo').get('holder'), id3.getArtist() ) if id3.getArtist(): zope.component.handle(updateEvent) # Copyright Year updateEvent = p6.metadata.events.UpdateMetadataEvent( p6.storage.interfaces.IWork, group('workinfo').get('year'), id3.getYear() ) if id3.getYear(): zope.component.handle(updateEvent) # License updateEvent = p6.metadata.events.UpdateMetadataEvent( p6.storage.interfaces.IWork, group('license').get('license'), id3.getLicenseUrl() ) if id3.getLicenseUrl(): zope.component.handle(updateEvent)
def verify(filename): """Extracts license claim information from a file and verifies it. Returns the following status codes: 1 Verified 0 No RDF -1 Work information not found (possible SHA1 mismatch) -2 Verification license does not match claim. Verification is performed against an embedded "claim" as well as checking the page specified by the "web statement". """ status = cctagutils.VERIFY_NO_RDF file_metadata = metadata(filename) sha1 = 'urn:sha1:%s' % cctagutils.rdf.fileHash(filename) rdf_urls = [] # get the claim URL if available claim = file_metadata.getClaim() if claim: fileinfo = parseClaim(claim) rdf_urls.append(fileinfo['verify at']) # get the web statement URL if available if file_metadata.getMetadataUrl(): rdf_urls.append(file_metadata.getMetadataUrl()) # parse/extract the metadata rdf_store = ccrdf.rdfdict.rdfStore() extractor = rdfextract.RdfExtractor() for u in rdf_urls: extractor.extractUrlToGraph(u, rdf_store.graph) # look for a license assertion about this file license_assertions = [l for l in rdf_store.graph.objects(sha1, cc.license)] license_assertions += [l for l in rdf_store.graph.objects(sha1, xhtml.license)] if len(license_assertions) == 1 and \ license_assertions[0] == file_metadata.getLicense(): # one matching assertion, hooray! return cctagutils.VERIFY_VERIFIED elif len(license_assertions) == 0: # no license assertions return cctagutils.VERIFY_NO_MATCH else: # multiple assertions... see if any of them match if file_metadata.getLicense() not in license_assertions: # none of them match return cctagutils.VERIFY_NO_MATCH # see if they're all the same, or if ambiguity exists for l in license_assertions: if l != file_metadata.getLicense(): # at least one doesn't match return cctagutils.VERIFY_CONFLICTING_ASSERTIONS # all are the same, we match return cctagutils.VERIFY_VERIFIED # either the file wasn't found, or the license didn't match return status