Skip to content

Commit

Permalink
Include xml in frontend attribution options (#4499)
Browse files Browse the repository at this point in the history
* include xml in frontend attribution options

* Revert redundant snapshot changes

* Use license url for dc:rights

* Ensure elements embedded in XML text are escaped

* Update snapshots

---------

Co-authored-by: Dhruv Bhanushali <[email protected]>
Co-authored-by: sarayourfriend <[email protected]>
  • Loading branch information
3 people authored Jun 26, 2024
1 parent 35ce27d commit 049e7f8
Show file tree
Hide file tree
Showing 46 changed files with 66 additions and 13 deletions.
8 changes: 6 additions & 2 deletions frontend/src/assets/error_images.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
"creator": "The British Library",
"license": "cc0",
"license_version": "1.0",
"license_url": "https://creativecommons.org/publicdomain/zero/1.0/"
"license_url": "https://creativecommons.org/publicdomain/zero/1.0/",
"frontendMediaType": "image",
"attribution": "\"Depressed musician vintage drawing\" by The British Library is marked with CC0 1.0. To view a copy of this license, visit https://creativecommons.org/publicdomain/zero/1.0/?ref=openverse."
}
},
{
Expand All @@ -23,7 +25,9 @@
"creator": "Edward Lagarde, American, 19th century",
"license": "cc0",
"license_version": "1.0",
"license_url": "https://creativecommons.org/publicdomain/zero/1.0/"
"license_url": "https://creativecommons.org/publicdomain/zero/1.0/",
"frontendMediaType": "image",
"attribution": "\"Depressed musician vintage drawing\" by The British Library is marked with CC0 1.0. To view a copy of this license, visit https://creativecommons.org/publicdomain/zero/1.0/?ref=openverse."
}
}
]
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/VErrorSection/VErrorImage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import imageInfo from "~/assets/error_images.json"
interface ErrorImage extends AttributableMedia {
src: string
alt: string
attribution?: string
}
/**
Expand Down Expand Up @@ -54,6 +53,7 @@ export default defineComponent({
alt: `errorImages.${image.id}`,
license: image.license as License,
license_version: image.license_version as LicenseVersion,
frontendMediaType: "image",
}
errorImage.attribution = getAttribution(errorImage, i18n)
return [errorItem.error, errorImage]
Expand Down
14 changes: 13 additions & 1 deletion frontend/src/components/VMediaInfo/VCopyLicense.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,18 @@
>
<p>{{ getAttributionMarkup({ isPlaintext: true }) }}</p>
</VLicenseTabPanel>
<VLicenseTabPanel
:tab="tabs[3]"
:media-id="media.id"
:media-type="media.frontendMediaType"
>
<pre
id="attribution-xml"
class="whitespace-pre-wrap break-all"
dir="ltr"
>{{ getAttributionMarkup({ isXml: true }) }}</pre
>
</VLicenseTabPanel>
</VTabs>
</div>
</template>
Expand All @@ -55,7 +67,7 @@ import VTabs from "~/components/VTabs/VTabs.vue"
import VTab from "~/components/VTabs/VTab.vue"
import VLicenseTabPanel from "~/components/VMediaInfo/VLicenseTabPanel.vue"
const tabs = ["rich", "html", "plain"] as const
const tabs = ["rich", "html", "plain", "xml"] as const
export default defineComponent({
name: "VCopyLicense",
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/VMediaInfo/VLicenseTabPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default defineComponent({
* The kind of attribution shown in the tab.
*/
tab: {
type: String as PropType<"rich" | "html" | "plain">,
type: String as PropType<"rich" | "html" | "plain" | "xml">,
required: true,
},
/**
Expand Down
1 change: 1 addition & 0 deletions frontend/src/locales/scripts/en.json5
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,7 @@
plain: "Plain text",
copyText: "Copy text",
copied: "Copied!",
xml: "XML",
},
attribution: "This image was marked with a {link} license:",
},
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/types/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ export type Events = {
/** The unique ID of the media */
id: string
/** The format of the copied attribution */
format: "plain" | "rich" | "html"
format: "plain" | "rich" | "html" | "xml"
/** The media type being searched */
mediaType: MediaType
}
Expand Down
38 changes: 34 additions & 4 deletions frontend/src/utils/attribution-html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,21 @@ const licenseElementImg = (licenseElement: LicenseElement): string => {
const extLink = (href: string, text: string) =>
h("a", { rel: "noopener noreferrer", href }, [text])

/**
* Generate a Dublin Core conforming XML attribution snippet.
*
* @param mediaItem - the media item being attributed
* @returns the XML markup of the attribution
*/
const xmlAttribution = (mediaItem: Record<string, string>) =>
`<attribution xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:creator>${mediaItem.creator}</dc:creator>
<dc:title>${mediaItem.title}</dc:title>
<dc:rights>${mediaItem.license_url}</dc:rights>
<dc:identifier>${mediaItem.foreign_landing_url}</dc:identifier>
<dc:type>${mediaItem.type}</dc:type>
</attribution>`

/* Interfaces */

/**
Expand All @@ -139,6 +154,8 @@ export type AttributableMedia = Pick<
| "license"
| "license_version"
| "license_url"
| "frontendMediaType"
| "attribution"
>

/**
Expand All @@ -148,6 +165,7 @@ export type AttributableMedia = Pick<
export interface AttributionOptions {
includeIcons?: boolean
isPlaintext?: boolean
isXml?: boolean
}

/* Actual util */
Expand All @@ -163,9 +181,10 @@ export interface AttributionOptions {
export const getAttribution = (
mediaItem: AttributableMedia,
i18n: VueI18n | null = null,
{ includeIcons, isPlaintext }: AttributionOptions = {
{ includeIcons, isPlaintext, isXml }: AttributionOptions = {
isPlaintext: false,
includeIcons: true,
isXml: false,
}
): string => {
if (!mediaItem) {
Expand Down Expand Up @@ -248,7 +267,18 @@ export const getAttribution = (
.replace(/\s{2}/g, " ")
.trim()

return isPlaintext
? attribution
: h("p", { class: "attribution" }, [attribution])
if (isXml) {
const { frontendMediaType, ...restMediaItem } = mediaItem

const xmlAttributionParts = {
...restMediaItem,
type: frontendMediaType === "audio" ? "Sound" : "StillImage",
}

return xmlAttribution(xmlAttributionParts)
} else if (isPlaintext) {
return attribution
} else {
return h("p", { class: "attribution" }, [attribution])
}
}
3 changes: 2 additions & 1 deletion frontend/test/locales/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,8 @@
"html": "لغة البرمجة",
"plain": "نص عادي",
"copyText": "نسخ النص",
"copied": "نسخ!"
"copied": "نسخ!",
"xml": "إك سم إل"
},
"attribution": "تم تمييز هذه الصورة بترخيص {link}:"
},
Expand Down
3 changes: 2 additions & 1 deletion frontend/test/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,8 @@
"html": "HTML",
"plain": "Texto sin formato",
"copyText": "Copiar el texto",
"copied": "¡Copiado!"
"copied": "¡Copiado!",
"xml": "XML"
},
"attribution": "Esta imagen se ha marcado con una licencia {link}:"
},
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const tabs = [
{ id: "rich", name: "Rich Text" },
{ id: "html", name: "HTML" },
{ id: "plain", name: "Plain text" },
{ id: "xml", name: "XML" },
]
const defaultUrl = "/iframe.html?id=components-vmediainfo-vmediareuse--default"
const pageUrl = (dir: (typeof languageDirections)[number]) =>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ describe("VCopyLicense", () => {

it("should contain the correct contents", () => {
const { queryAllByText } = render(VCopyLicense, options)
expect(queryAllByText(/Copy text/i)).toHaveLength(3)
expect(queryAllByText(/Copy text/i)).toHaveLength(4)
})
})
3 changes: 3 additions & 0 deletions frontend/test/unit/specs/utils/attribution-html.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ const mediaItem: AttributableMedia = {
license: "pdm",
license_version: "1.0",
license_url: "https://license/url",
frontendMediaType: "image",
attribution:
'"Title" by Creator is marked with Public Domain Mark 1.0 . To view a copy of this license, visit https://creativecommons.org/publicdomain/zero/1.0/?ref=openverse.',
}

describe("getAttribution", () => {
Expand Down

0 comments on commit 049e7f8

Please sign in to comment.