Skip to content

Commit a127966

Browse files
authored
Merge pull request #272 from obulat/xmp_download
2 parents cc9c74e + c806ded commit a127966

File tree

4 files changed

+116
-9
lines changed

4 files changed

+116
-9
lines changed

src/App.vue

+1-2
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ import { mapMutations } from 'vuex'
7272
import ChooserModal from './components/ChooserModal'
7373
import HelpSection from './components/HelpSection'
7474
import Stepper from './components/Stepper'
75-
import LicenseUseCard from './components/LicenseUseCard'
7675
import HeaderSection from './components/HeaderSection'
7776
import FooterSection from './components/FooterSection'
7877
import LicenseDetailsCard from './components/LicenseDetailsCard'
@@ -83,7 +82,7 @@ export default {
8382
HelpSection,
8483
Stepper,
8584
LicenseDetailsCard,
86-
LicenseUseCard,
85+
LicenseUseCard: () => import('@/components/LicenseUseCard'),
8786
HeaderSection,
8887
FooterSection,
8988
ChooserModal

src/components/CopyTools.vue

+4-7
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,18 @@
1212
>
1313
{{ copyLabel }}
1414
</v-button>
15-
<v-button
16-
v-else
17-
class="donate small copy-button is-xmp"
18-
>
19-
{{ xmpLabel }}
20-
</v-button>
15+
<xmp-button v-if="clipboardTarget==='.xmp'" />
2116
</div>
2217
</template>
2318

2419
<script>
2520
import CopyTypeSwitch from '@/components/CopyTypeSwitch'
2621
import Clipboard from 'clipboard'
22+
import XmpButton from '@/components/XmpButton'
23+
2724
export default {
2825
name: 'CopyTools',
29-
components: { CopyTypeSwitch },
26+
components: { CopyTypeSwitch, XmpButton },
3027
props: {
3128
clipboardTarget: {
3229
type: String,

src/components/XmpButton.vue

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<template>
2+
<a
3+
ref="xmp"
4+
class="button donate small copy-button is-xmp"
5+
type="text/xml"
6+
:href="xmpHref"
7+
:download="xmpFilename"
8+
>
9+
{{ xmpLabel }}
10+
</a>
11+
</template>
12+
13+
<script>
14+
import { createXMP } from '@/utils/xmp'
15+
import { mapGetters } from 'vuex'
16+
17+
export default {
18+
name: 'XmpButton',
19+
computed: {
20+
...mapGetters(['shortName']),
21+
xmpLabel() { return this.$t('license-use.xmp-label') },
22+
xmpFilename() {
23+
return `${this.shortName}.xmp`
24+
},
25+
xmpHref() {
26+
const shortName = this.$store.getters.shortName
27+
const { workUrl, workTitle, creatorName } = this.$store.state.attributionDetails
28+
const xmp = createXMP({ shortName, workUrl, workTitle, creatorName })
29+
const xmpBlob = new Blob([xmp], { type: 'text/xml;charset=utf-8' })
30+
return URL.createObjectURL(xmpBlob)
31+
}
32+
}
33+
}
34+
</script>

src/utils/xmp.js

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/* eslint-disable indent, quotes */
2+
import { LICENSES, licenseSlug } from '@/utils/license-utilities'
3+
4+
/** The xmp metadata is structured in accordance with the Adobe XMP specifications from 2012:
5+
https://wwwimages2.adobe.com/content/dam/acom/en/devnet/xmp/pdfs/XMP%20SDK%20Release%20cc-2016-08/XMPSpecificationPart1.pdf
6+
7+
The following data is written into the xmp file:
8+
9+
xapRights:WebStatement: A Web URL for a statement of the ownership and usage rights for this resource.
10+
Uses the value of the 'Link to Work' field from the Attribution details form.
11+
xapRights:Marked: Indicates that this is a public-domain or CC0 resource if false. Otherwise, one of the 6 CC licenses.
12+
xapRights:Owner: A list of legal owners of the resource.
13+
Uses the value of the 'Creator of Work' field from the Attribution details form.
14+
xapRights:UsageTerms: A collection of text instructions on how a resource can be legally used, given in a variety of languages.
15+
Uses license statement with the link to the license deed, with '<>"' characters escaped.
16+
dc:title: A name or title given to the resource, by which it is formally known, given in various languages.
17+
Uses the value of the 'Title of Work' field from the Attribution details form.
18+
cc:license: the link to the CC license deed.
19+
cc:attributionName
20+
Uses the value of the 'Creator of Work' field from the Attribution details form.
21+
*/
22+
23+
export const createXMP = ({ shortName, workUrl = '', workTitle = '', creatorName = '', lang = 'en-US' }) => {
24+
const slug = licenseSlug(shortName).replace(/-/gi, '_').toUpperCase()
25+
26+
const licenseUrl = LICENSES[slug].URL
27+
const licenseFullName = LICENSES[slug].FULL
28+
29+
const ccLicenseNotice = `This work is licensed under <a href="${licenseUrl}">${licenseFullName}</a>`
30+
.replace(/</gi, '&lt;')
31+
.replace(/>/gi, '&gt;')
32+
.replace(/"/gi, '&#34;')
33+
34+
const isLicensed = shortName !== LICENSES.CC0.SHORT ? 'True' : 'False'
35+
36+
return (`<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?>
37+
<x:xmpmeta xmlns:x='adobe:ns:meta/'>
38+
<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
39+
xmlns:xapRights='http://ns.adobe.com/xap/1.0/rights/'
40+
xmlns:cc='http://creativecommons.org/ns#'${workTitle
41+
? `xmlns:dc='http://purl.org/dc/elements/1.1/'`
42+
: ''}>
43+
<rdf:Description rdf:about=''>
44+
${`<xapRights:Marked>${isLicensed}</xapRights:Marked>`}${creatorName
45+
? `
46+
<xapRights:Owner>
47+
<rdf:Bag>
48+
<rdf:li>${creatorName}</rdf:li>
49+
</rdf:Bag>
50+
</xapRights:Owner>`
51+
: ''}${workUrl
52+
? `
53+
<xapRights:WebStatement rdf:resource='${workUrl}'/>`
54+
: ''}
55+
<xapRights:UsageTerms>
56+
<rdf:Alt>
57+
<rdf:li xml:lang='x-default'>${ccLicenseNotice}</rdf:li>
58+
<rdf:li xml:lang='${lang}' >${ccLicenseNotice}</rdf:li>
59+
</rdf:Alt>
60+
</xapRights:UsageTerms>
61+
<cc:license rdf:resource='${licenseUrl}'/>${creatorName
62+
? `
63+
<cc:attributionName>${creatorName}</cc:attributionName>`
64+
: ''}${workTitle
65+
? `
66+
<dc:title>
67+
<rdf:Alt>
68+
<rdf:li xml:lang='x-default'>${workTitle}</rdf:li>
69+
<rdf:li xml:lang='${lang}'>${workTitle}</rdf:li>
70+
</rdf:Alt>
71+
</dc:title>`
72+
: ''}
73+
</rdf:Description>
74+
</rdf:RDF>
75+
</x:xmpmeta>
76+
<?xpacket end='r'?>`)
77+
}

0 commit comments

Comments
 (0)