diff --git a/src/app/app-routing-paths.ts b/src/app/app-routing-paths.ts index 5e0d22fdcd1..a4f80232b9b 100644 --- a/src/app/app-routing-paths.ts +++ b/src/app/app-routing-paths.ts @@ -24,9 +24,13 @@ export function getBitstreamModuleRoute() { } export function getBitstreamRoute(item, bitstream): Observable { + const name = (bitstream.metadata["dc.description"] && bitstream.metadata["dc.description"][0] ? bitstream.metadata["dc.description"][0].value : item._name) + .split('') + .map(char => ['!', '#', '$', '%', '&', '(', ')', '*', '+', ',', '/', ':', ';', '=', '?', '@', '[', ']', ' ', '\''].includes(char) ? '_' : char) + .join(''); return from(fetch(bitstream._links.self.href) .then(response => response.json()) - .then(data => `/${LEGACY_BITSTREAM_MODULE_PATH}/handle/${item.handle}/${bitstream.name}?sequence=${data.sequenceId}`)); + .then(data => `/${LEGACY_BITSTREAM_MODULE_PATH}/handle/${item.handle}/${name}.pdf?sequence=${data.sequenceId}`)); } export function getBitstreamDownloadRoute(bitstream): string { diff --git a/src/app/bitstream-page/legacy-bitstream-url-redirect.guard.ts b/src/app/bitstream-page/legacy-bitstream-url-redirect.guard.ts index 78403ed7e3f..419492b4af4 100644 --- a/src/app/bitstream-page/legacy-bitstream-url-redirect.guard.ts +++ b/src/app/bitstream-page/legacy-bitstream-url-redirect.guard.ts @@ -37,7 +37,7 @@ export const legacyBitstreamURLRedirectGuard: CanActivateFn = ( const filename = route.params.filename; let sequenceId = route.params.sequence_id; if (hasNoValue(sequenceId)) { - sequenceId = route.queryParams.sequenceId; + sequenceId = route.queryParams.sequence; } return bitstreamDataService.findByItemHandle( `${prefix}/${suffix}`, diff --git a/src/app/core/data/bitstream-data.service.ts b/src/app/core/data/bitstream-data.service.ts index 81d1d74535b..e9048f76123 100644 --- a/src/app/core/data/bitstream-data.service.ts +++ b/src/app/core/data/bitstream-data.service.ts @@ -195,7 +195,7 @@ export class BitstreamDataService extends IdentifiableDataService imp const searchParams = []; searchParams.push(new RequestParam('handle', handle)); if (hasValue(sequenceId)) { - searchParams.push(new RequestParam('sequenceId', sequenceId)); + searchParams.push(new RequestParam('sequence', sequenceId)); } if (hasValue(filename)) { searchParams.push(new RequestParam('filename', filename)); diff --git a/src/app/core/metadata/head-tag-sedici.service.ts b/src/app/core/metadata/head-tag-sedici.service.ts index a651fa84bb9..fc37534eef2 100644 --- a/src/app/core/metadata/head-tag-sedici.service.ts +++ b/src/app/core/metadata/head-tag-sedici.service.ts @@ -89,7 +89,7 @@ export class HeadTagSEDICIService extends HeadTagService { this.setTypeTags(); this.setLicenseTags(); this.setRightsTags(); - this.setProvenanceTags(); + // this.setProvenanceTags(); this.setContributorTags(); this.setIsVersionOfTags(); this.setPublisherTags(); @@ -129,21 +129,33 @@ export class HeadTagSEDICIService extends HeadTagService { this.addMetaTag('citation_title', value); } + /** + * Add to the + */ protected setCitationAuthorTags(): void { const values: string[] = this.getMetaTagValues(['sedici.creator.person', 'sedici.creator.corporate', 'sedici.contributor.compiler', 'sedici.creator.interprete', 'sedici.contributor.editor']); this.addMetaTags('citation_author', values); } + /** + * Add to the + */ protected setCitationPublicationDateTag(): void { const value = this.getFirstMetaTagValue(['dc.date.issued', 'sedici.date.exposure', 'dc.date.created']); this.addMetaTag('citation_publication_date', value); } + /** + * Add to the + */ protected setCitationISSNTag(): void { const value = this.getMetaTagValue('sedici.identifier.issn'); this.addMetaTag('citation_issn', value); } + /** + * Add to the + */ protected setCitationISBNTag(): void { const value = this.getMetaTagValue('sedici.identifier.isbn'); this.addMetaTag('citation_isbn', value); @@ -166,131 +178,134 @@ export class HeadTagSEDICIService extends HeadTagService { } /** - * Add dc.publisher to the . The tag name depends on the item type. + * Add to the */ protected setCitationPublisherTag(): void { const value = this.getMetaTagValue('dc.publisher'); this.addMetaTag('citation_publisher', value); } + /** + * Add to the + */ protected setCitationKeywordsTag(): void { const value = this.getMultipleMetaTagValuesAndCombine(['dc.subject', 'sedici.subject.materias']); this.addMetaTag('citation_keywords', value); } // PARCHE PDF - // setCitationPdfUrlTag(): void { - // if (this.currentObject.value instanceof Item) { - // const item = this.currentObject.value as Item; - - // // Retrieve the ORIGINAL bundle for the item - // this.bundleDataService.findByItemAndName( - // item, - // 'ORIGINAL', - // true, - // true, - // followLink('primaryBitstream'), - // followLink('bitstreams', { - // findListOptions: { - // // limit the number of bitstreams used to find the citation pdf url to the number - // // shown by default on an item page - // elementsPerPage: this.appConfig.item.bitstream.pageSize, - // }, - // }, followLink('format')), - // ).pipe( - // getFirstSucceededRemoteDataPayload(), - // switchMap((bundle: Bundle) => - // // First try the primary bitstream - // bundle.primaryBitstream.pipe( - // getFirstCompletedRemoteData(), - // map((rd: RemoteData) => { - // if (hasValue(rd.payload)) { - // return rd.payload; - // } else { - // return null; - // } - // }), - // getDownloadableBitstream(this.authorizationService), - // // return the bundle as well so we can use it again if there's no primary bitstream - // map((bitstream: Bitstream) => [bundle, bitstream]), - // ), - // ), - // switchMap(([bundle, primaryBitstream]: [Bundle, Bitstream]) => { - // if (hasValue(primaryBitstream)) { - // // If there was a downloadable primary bitstream, emit its link - // return getBitstreamRoute(item, primaryBitstream); - // } else { - // // Otherwise consider the regular bitstreams in the bundle - // return bundle.bitstreams.pipe( - // getFirstCompletedRemoteData(), - // switchMap((bitstreamRd: RemoteData>) => { - // if (hasValue(bitstreamRd.payload) && bitstreamRd.payload.totalElements === 1) { - // // If there's only one bitstream in the bundle, emit its link if its downloadable - // return this.getBitLinkIfDownloadable(bitstreamRd.payload.page[0], bitstreamRd); - // } else { - // // Otherwise check all bitstreams to see if one matches the format whitelist - // return this.getFirstAllowedFormatBitstreamLink(bitstreamRd); - // } - // }), - // ); - // } - // }), - // take(1), - // ).subscribe((link: string) => { - // // Use the found link to set the tag - // this.addMetaTag( - // 'citation_pdf_url', - // new URLCombiner(this.hardRedirectService.getCurrentOrigin(), link).toString(), - // ); - // }); - // } - // } - - // getBitLinkIfDownloadable(bitstream: Bitstream, bitstreamRd: RemoteData>): Observable { - // return observableOf(bitstream).pipe( - // getDownloadableBitstream(this.authorizationService), - // switchMap((bit: Bitstream) => { - // if (hasValue(bit)) { - // const item = this.currentObject.value as Item; - // return getBitstreamRoute(item, bit); - // } else { - // // Otherwise check all bitstreams to see if one matches the format whitelist - // return this.getFirstAllowedFormatBitstreamLink(bitstreamRd); - // } - // }), - // ); - // } + setCitationPdfUrlTag(): void { + if (this.currentObject.value instanceof Item) { + const item = this.currentObject.value as Item; + + // Retrieve the ORIGINAL bundle for the item + this.bundleDataService.findByItemAndName( + item, + 'ORIGINAL', + true, + true, + followLink('primaryBitstream'), + followLink('bitstreams', { + findListOptions: { + // limit the number of bitstreams used to find the citation pdf url to the number + // shown by default on an item page + elementsPerPage: this.appConfig.item.bitstream.pageSize, + }, + }, followLink('format')), + ).pipe( + getFirstSucceededRemoteDataPayload(), + switchMap((bundle: Bundle) => + // First try the primary bitstream + bundle.primaryBitstream.pipe( + getFirstCompletedRemoteData(), + map((rd: RemoteData) => { + if (hasValue(rd.payload)) { + return rd.payload; + } else { + return null; + } + }), + getDownloadableBitstream(this.authorizationService), + // return the bundle as well so we can use it again if there's no primary bitstream + map((bitstream: Bitstream) => [bundle, bitstream]), + ), + ), + switchMap(([bundle, primaryBitstream]: [Bundle, Bitstream]) => { + if (hasValue(primaryBitstream)) { + // If there was a downloadable primary bitstream, emit its link + return getBitstreamRoute(item, primaryBitstream); + } else { + // Otherwise consider the regular bitstreams in the bundle + return bundle.bitstreams.pipe( + getFirstCompletedRemoteData(), + switchMap((bitstreamRd: RemoteData>) => { + if (hasValue(bitstreamRd.payload) && bitstreamRd.payload.totalElements === 1) { + // If there's only one bitstream in the bundle, emit its link if its downloadable + return this.getBitLinkIfDownloadable(bitstreamRd.payload.page[0], bitstreamRd); + } else { + // Otherwise check all bitstreams to see if one matches the format whitelist + return this.getFirstAllowedFormatBitstreamLink(bitstreamRd); + } + }), + ); + } + }), + take(1), + ).subscribe((link: string) => { + // Use the found link to set the tag + this.addMetaTag( + 'citation_pdf_url', + new URLCombiner(this.hardRedirectService.getCurrentOrigin(), link).toString(), + ); + }); + } + } - // protected getFirstAllowedFormatBitstreamLink(bitstreamRd: RemoteData>): Observable { - // const item = this.currentObject.value as Item; - // if (hasValue(bitstreamRd.payload) && isNotEmpty(bitstreamRd.payload.page)) { - // // Retrieve the formats of all bitstreams in the page sequentially - // return observableConcat( - // ...bitstreamRd.payload.page.map((bitstream: Bitstream) => bitstream.format.pipe( - // getFirstSucceededRemoteDataPayload(), - // // Keep the original bitstream, because it, not the format, is what we'll need - // // for the link at the end - // map((format: BitstreamFormat) => [bitstream, format]), - // )), - // ).pipe( - // // Verify that the bitstream is downloadable - // mergeMap(([bitstream, format]: [Bitstream, BitstreamFormat]) => observableOf(bitstream).pipe( - // getDownloadableBitstream(this.authorizationService), - // map((bit: Bitstream) => [bit, format]), - // )), - // // Filter out only pairs with whitelisted formats and non-null bitstreams, null from download check - // filter(([bitstream, format]: [Bitstream, BitstreamFormat]) => - // hasValue(format) && hasValue(bitstream) && this.CITATION_PDF_URL_MIMETYPES.includes(format.mimetype)), - // // We only need 1 - // take(1), - // // Emit the link of the match - // // tap((v) => console.log('result', v)), - // mergeMap(([bitstream ]: [Bitstream, BitstreamFormat]) => getBitstreamRoute(item, bitstream)), - // ); - // } else { - // return EMPTY; - // } - // } + getBitLinkIfDownloadable(bitstream: Bitstream, bitstreamRd: RemoteData>): Observable { + return observableOf(bitstream).pipe( + getDownloadableBitstream(this.authorizationService), + switchMap((bit: Bitstream) => { + if (hasValue(bit)) { + const item = this.currentObject.value as Item; + return getBitstreamRoute(item, bit); + } else { + // Otherwise check all bitstreams to see if one matches the format whitelist + return this.getFirstAllowedFormatBitstreamLink(bitstreamRd); + } + }), + ); + } + + protected getFirstAllowedFormatBitstreamLink(bitstreamRd: RemoteData>): Observable { + const item = this.currentObject.value as Item; + if (hasValue(bitstreamRd.payload) && isNotEmpty(bitstreamRd.payload.page)) { + // Retrieve the formats of all bitstreams in the page sequentially + return observableConcat( + ...bitstreamRd.payload.page.map((bitstream: Bitstream) => bitstream.format.pipe( + getFirstSucceededRemoteDataPayload(), + // Keep the original bitstream, because it, not the format, is what we'll need + // for the link at the end + map((format: BitstreamFormat) => [bitstream, format]), + )), + ).pipe( + // Verify that the bitstream is downloadable + mergeMap(([bitstream, format]: [Bitstream, BitstreamFormat]) => observableOf(bitstream).pipe( + getDownloadableBitstream(this.authorizationService), + map((bit: Bitstream) => [bit, format]), + )), + // Filter out only pairs with whitelisted formats and non-null bitstreams, null from download check + filter(([bitstream, format]: [Bitstream, BitstreamFormat]) => + hasValue(format) && hasValue(bitstream) && this.CITATION_PDF_URL_MIMETYPES.includes(format.mimetype)), + // We only need 1 + take(1), + // Emit the link of the match + // tap((v) => console.log('result', v)), + mergeMap(([bitstream ]: [Bitstream, BitstreamFormat]) => getBitstreamRoute(item, bitstream)), + ); + } else { + return EMPTY; + } + } /** * Add to the @@ -420,9 +435,9 @@ export class HeadTagSEDICIService extends HeadTagService { this.setMetaTags('DC.rights', ['sedici.rights.uri'], 'DCTERMS.URI'); } - protected setProvenanceTags(): void { - this.setMetaTags('DCTERMS.provenance', ['dc.description.provenance']); - } + // protected setProvenanceTags(): void { + // this.setMetaTags('DCTERMS.provenance', ['dc.description.provenance']); + // } protected setContributorTags(): void { this.setMetaTags('DC.contributor', ['sedici.contributor.director', 'sedici.contributor.codirector', 'sedici.contributor.colaborator', 'sedici.contributor.translator', 'sedici.contributor.juror', 'sedici.contributor.inscriber']); diff --git a/src/app/core/metadata/head-tag.service.ts b/src/app/core/metadata/head-tag.service.ts index cf554557382..efc5ecbfb8c 100644 --- a/src/app/core/metadata/head-tag.service.ts +++ b/src/app/core/metadata/head-tag.service.ts @@ -101,7 +101,7 @@ export class HeadTagService { * See {@linkcode getFirstAllowedFormatBitstreamLink} * @private */ - private readonly CITATION_PDF_URL_MIMETYPES = [ + protected readonly CITATION_PDF_URL_MIMETYPES = [ 'application/pdf', // .pdf 'application/postscript', // .ps 'application/msword', // .doc