diff --git a/src/common/redux/actions/import/index.ts b/src/common/redux/actions/import/index.ts index 317ea6ba6..f5492f4a6 100644 --- a/src/common/redux/actions/import/index.ts +++ b/src/common/redux/actions/import/index.ts @@ -1,12 +1,12 @@ -// ==LICENSE-BEGIN== -// Copyright 2017 European Digital Reading Lab. All rights reserved. -// Licensed to the Readium Foundation under one or more contributor license agreements. -// Use of this source code is governed by a BSD-style license -// that can be found in the LICENSE file exposed on Github (readium) in the project repository. -// ==LICENSE-END== +// // ==LICENSE-BEGIN== +// // Copyright 2017 European Digital Reading Lab. All rights reserved. +// // Licensed to the Readium Foundation under one or more contributor license agreements. +// // Use of this source code is governed by a BSD-style license +// // that can be found in the LICENSE file exposed on Github (readium) in the project repository. +// // ==LICENSE-END== -import * as verify from "./verify"; +// import * as verify from "./verify"; -export { - verify, -}; +// export { +// verify, +// }; diff --git a/src/common/redux/actions/import/verify.ts b/src/common/redux/actions/import/verify.ts index c732774d3..4eb643b1a 100644 --- a/src/common/redux/actions/import/verify.ts +++ b/src/common/redux/actions/import/verify.ts @@ -1,32 +1,32 @@ -// ==LICENSE-BEGIN== -// Copyright 2017 European Digital Reading Lab. All rights reserved. -// Licensed to the Readium Foundation under one or more contributor license agreements. -// Use of this source code is governed by a BSD-style license -// that can be found in the LICENSE file exposed on Github (readium) in the project repository. -// ==LICENSE-END== +// // ==LICENSE-BEGIN== +// // Copyright 2017 European Digital Reading Lab. All rights reserved. +// // Licensed to the Readium Foundation under one or more contributor license agreements. +// // Use of this source code is governed by a BSD-style license +// // that can be found in the LICENSE file exposed on Github (readium) in the project repository. +// // ==LICENSE-END== -import { Action } from "readium-desktop/common/models/redux"; -import { IOpdsLinkView, IOpdsPublicationView } from "readium-desktop/common/views/opds"; +// import { Action } from "readium-desktop/common/models/redux"; +// import { IOpdsLinkView, IOpdsPublicationView } from "readium-desktop/common/views/opds"; -export const ID = "IMPORT_VERIFICATION_REQUEST"; +// export const ID = "IMPORT_VERIFICATION_REQUEST"; -export interface Payload { - link: IOpdsLinkView; - pub: IOpdsPublicationView; -} +// export interface Payload { +// link: IOpdsLinkView; +// pub: IOpdsPublicationView; +// } -export function build( - link: IOpdsLinkView, - pub: IOpdsPublicationView, -): Action { +// export function build( +// link: IOpdsLinkView, +// pub: IOpdsPublicationView, +// ): Action { - return { - type: ID, - payload: { - link, - pub, - }, - }; -} -build.toString = () => ID; // Redux StringableActionCreator -export type TAction = ReturnType; +// return { +// type: ID, +// payload: { +// link, +// pub, +// }, +// }; +// } +// build.toString = () => ID; // Redux StringableActionCreator +// export type TAction = ReturnType; diff --git a/src/common/redux/actions/index.ts b/src/common/redux/actions/index.ts index efc3ee322..48e8ddd3b 100644 --- a/src/common/redux/actions/index.ts +++ b/src/common/redux/actions/index.ts @@ -11,7 +11,7 @@ import * as dialogActions from "./dialog/"; import * as downloadActions from "./download/"; import * as historyActions from "./history"; import * as i18nActions from "./i18n/"; -import * as importActions from "./import/"; +// import * as importActions from "./import/"; import * as keyboardActions from "./keyboard/"; import * as lcpActions from "./lcp/"; import * as loadActions from "./load"; @@ -37,7 +37,7 @@ export { netActions, readerActions, lcpActions, - importActions, + // importActions, toastActions, downloadActions, keyboardActions, diff --git a/src/main/redux/sagas/api/browser/browse.ts b/src/main/redux/sagas/api/browser/browse.ts index 2dc0e6258..bc51eeca9 100644 --- a/src/main/redux/sagas/api/browser/browse.ts +++ b/src/main/redux/sagas/api/browser/browse.ts @@ -182,6 +182,8 @@ export function* browse(urlRaw: string): SagaGenerator); if (dataFromOpdsParser) { data.data = { diff --git a/src/main/services/opds.ts b/src/main/services/opds.ts index 55061f3b3..ca4c68332 100644 --- a/src/main/services/opds.ts +++ b/src/main/services/opds.ts @@ -36,6 +36,8 @@ import { diSymbolTable } from "../diSymbolTable"; import { getOpdsAuthenticationChannel } from "../event"; import { OPDSLink } from "@r2-opds-js/opds/opds2/opds2-link"; import { IDigestDataParsed, parseDigestString } from "readium-desktop/utils/digest"; +import { diMainGet } from "../di"; +import { importFromLinkService } from "../redux/sagas/api/publication/import/importFromLink"; // Logger const debug = debug_("readium-desktop:main#services/opds"); @@ -84,12 +86,11 @@ export class OpdsService { contentType: _contentType, } = httpGetData; const baseUrl = `${_baseUrl}`; - const contentType = parseContentType(_contentType); + const contentType = parseContentType(_contentType); - if (contentTypeisXml(contentType)) { + if (contentTypeisXml(contentType)) { - - // TODO response.buffer deprecated by node-fetch + // TODO: response.buffer deprecated by node-fetch const buffer = await httpGetData.response.buffer(); const result = await this.opdsRequestXmlTransformer(buffer, baseUrl); @@ -129,6 +130,33 @@ export class OpdsService { } } + // TODO: + // now sample and open access pub acquisition will be handled like an opds feed + // with a download fallback if it is not parsable to an opds format + // What it means that a misconfigured or rotten opds feed can download anything to the user disk + // I suggest a user confirmation dialog modal to accept the download of the target link if legit + + // To implement this need to switch to redux saga to ask and wait response in saga mode + + // For the moment let's user download without confirmation + + const downloadLink: IOpdsLinkView = { + url: _baseUrl.toString(), + type: contentType, + }; + + const sagaMiddleware = diMainGet("saga-middleware"); + sagaMiddleware.run(importFromLinkService, downloadLink); + + // https://github.com/edrlab/thorium-reader/issues/1261 + // publication in OPDS2 feed might be an OPDSPublication or an R2Publication + // now downloaded and packaged in importFromLinkService saga function ! + + + // TODO: what return when the publication is not an opds feed, we have to close the current publication info and reload the previous history odps link !?! + + + // TODO: What return here, when we have to reload the history previous link instead !?! return undefined; } @@ -239,14 +267,6 @@ export class OpdsService { !jsonObj.groups && !jsonObj.catalogs); - const isR2Pub = contentType === ContentType.webpub || - jsonObj.metadata && - jsonObj["@context"] === "https://readium.org/webpub-manifest/context.jsonld" && - !!(!jsonObj.publications && - !jsonObj.navigation && - !jsonObj.groups && - !jsonObj.catalogs); - const isAuth = contentTypeisOpdsAuth(contentType) || typeof jsonObj.authentication !== "undefined"; @@ -256,7 +276,7 @@ export class OpdsService { jsonObj.groups || jsonObj.catalogs); - debug("isAuth, isOpdsPub, isR2Pub, isFeed", isAuth, isOpdsPub, isR2Pub, isFeed); + debug("isAuth, isOpdsPub, isR2Pub, isFeed", isAuth, isOpdsPub, isFeed); // debug(jsonObj); // console.log(JSON.stringify(jsonObj, null, 4)); if (isAuth) { @@ -283,47 +303,7 @@ export class OpdsService { publications: [pubView], }; - } else if (isR2Pub) { - - // TODO : https://github.com/edrlab/thorium-reader/issues/1261 - // publication in OPDS2 feed might be an OPDSPublication or an R2Publication - - debug("R2Publication in OPDS not supported"); - - // const r2Publication = TaJsonDeserialize( - // jsonObj, - // R2Publication, - // ); - - // const pub = new OPDSPublication(); - - // if (typeof r2Publication.Metadata === "object") { - // pub.Metadata = r2Publication.Metadata; - // } - - // const coverLink = r2Publication.searchLinkByRel("cover"); - // if (coverLink) { - // pub.AddImage( - // coverLink.Href, - // coverLink.TypeLink, - // coverLink.Height, coverLink.Width); - // } - - // pub.AddLink_(, "application/webpub+json", "http://opds-spec.org/acquisition/open-access", ""); - - // const pubView = this.opdsFeedViewConverter.convertOpdsPublicationToView(r2Publication, baseUrl); - - // return { - // title: pubView.documentTitle, - // publications: [pubView], - // } as IOpdsResultView; - - return { - title: "", - publications: [], - }; - - } else if (isFeed) { + } else if (isFeed) { const r2OpdsFeed = TaJsonDeserialize( jsonObj, OPDSFeed, @@ -332,7 +312,6 @@ export class OpdsService { } return undefined; - } private async opdsRequestXmlTransformer(buffer: Buffer, baseUrl: string) { diff --git a/src/renderer/library/components/dialog/publicationInfos/opdsControls/OpdsControls.tsx b/src/renderer/library/components/dialog/publicationInfos/opdsControls/OpdsControls.tsx index 15d26d32a..369e59644 100644 --- a/src/renderer/library/components/dialog/publicationInfos/opdsControls/OpdsControls.tsx +++ b/src/renderer/library/components/dialog/publicationInfos/opdsControls/OpdsControls.tsx @@ -11,7 +11,7 @@ import * as stylesGlobal from "readium-desktop/renderer/assets/styles/global.scs import classNames from "classnames"; import * as React from "react"; import { connect } from "react-redux"; -import { dialogActions, importActions } from "readium-desktop/common/redux/actions/"; +// import { dialogActions, importActions } from "readium-desktop/common/redux/actions/"; import { IOpdsLinkView, IOpdsPublicationView } from "readium-desktop/common/views/opds"; import * as CartFillIcon from "readium-desktop/renderer/assets/icons/cart-icon.svg"; import * as BorrowIcon from "readium-desktop/renderer/assets/icons/borrow-icon.svg"; @@ -54,7 +54,7 @@ export class OpdsControls extends React.Component { const { opdsPublicationView, - verifyImport, + // verifyImport, openAccessButtonIsDisabled, sampleButtonIsDisabled, __, @@ -103,9 +103,15 @@ export class OpdsControls extends React.Component { ); } else { - verifyImport( + // verifyImport( + // ln, + // opdsPublicationView, + // ); + + this.props.link( ln, - opdsPublicationView, + this.props.location, + `${"open access book"} (${opdsPublicationView.documentTitle}))`, ); } }} @@ -137,9 +143,15 @@ export class OpdsControls extends React.Component { ); } else { - verifyImport( + // verifyImport( + // ln, + // opdsPublicationView, + // ); + + this.props.link( ln, - opdsPublicationView, + this.props.location, + `${"sample book"} (${opdsPublicationView.documentTitle}))`, ); } }} @@ -295,10 +307,10 @@ export class OpdsControls extends React.Component { const mapDispatchToProps = (dispatch: TDispatch, _props: IBaseProps) => { return { - verifyImport: (...data: Parameters) => { - dispatch(dialogActions.closeRequest.build()); - dispatch(importActions.verify.build(...data)); - }, + // verifyImport: (...data: Parameters) => { + // dispatch(dialogActions.closeRequest.build()); + // dispatch(importActions.verify.build(...data)); + // }, link: (...data: Parameters>) => dispatchOpdsLink(dispatch)(...data), }; diff --git a/src/renderer/library/opds/handleLink.ts b/src/renderer/library/opds/handleLink.ts index e1f50ce3d..466b74627 100644 --- a/src/renderer/library/opds/handleLink.ts +++ b/src/renderer/library/opds/handleLink.ts @@ -11,7 +11,7 @@ import { IOpdsLinkView } from "readium-desktop/common/views/opds"; import { decodeB64 } from "readium-desktop/renderer/common/logics/base64"; import { buildOpdsBrowserRoute } from "readium-desktop/renderer/library/opds/route"; import { TDispatch } from "readium-desktop/typings/redux"; -import { ContentType, parseContentType } from "readium-desktop/utils/contentType"; +import { parseContentType } from "readium-desktop/utils/contentType"; import { Location } from "history"; @@ -29,12 +29,10 @@ export const dispatchOpdsLink = dispatch(dialogActions.closeRequest.build()); const contentType = parseContentType(ln.type); - if (contentType === ContentType.Opds2 || - contentType === ContentType.Opds2Auth || - contentType === ContentType.Opds2Pub || - contentType === ContentType.AtomXml || + if ( + contentType || REL_NAVIGATION_TYPES.includes(ln.rel) - ) { + ) { const param = extractParamFromOpdsRoutePathname(location.pathname); diff --git a/src/renderer/library/redux/sagas/index.ts b/src/renderer/library/redux/sagas/index.ts index b2a4ba883..655aab24d 100644 --- a/src/renderer/library/redux/sagas/index.ts +++ b/src/renderer/library/redux/sagas/index.ts @@ -18,7 +18,7 @@ import * as i18n from "./i18n"; import * as lcp from "./lcp"; import * as load from "./load"; import * as opds from "./opds"; -import * as sameFileImport from "./sameFileImport"; +// import * as sameFileImport from "./sameFileImport"; import * as winInit from "./win"; // Logger @@ -45,7 +45,7 @@ export function* rootSaga() { publicationInfoReaderAndLib.saga(), - sameFileImport.saga(), + // sameFileImport.saga(), history.saga(), publicationInfoSyncTags.saga(), diff --git a/src/renderer/library/redux/sagas/sameFileImport.ts b/src/renderer/library/redux/sagas/sameFileImport.ts index 4e0d77403..c744a99d3 100644 --- a/src/renderer/library/redux/sagas/sameFileImport.ts +++ b/src/renderer/library/redux/sagas/sameFileImport.ts @@ -1,64 +1,64 @@ -// ==LICENSE-BEGIN== -// Copyright 2017 European Digital Reading Lab. All rights reserved. -// Licensed to the Readium Foundation under one or more contributor license agreements. -// Use of this source code is governed by a BSD-style license -// that can be found in the LICENSE file exposed on Github (readium) in the project repository. -// ==LICENSE-END== +// // ==LICENSE-BEGIN== +// // Copyright 2017 European Digital Reading Lab. All rights reserved. +// // Licensed to the Readium Foundation under one or more contributor license agreements. +// // Use of this source code is governed by a BSD-style license +// // that can be found in the LICENSE file exposed on Github (readium) in the project repository. +// // ==LICENSE-END== -import * as debug_ from "debug"; -import { ToastType } from "readium-desktop/common/models/toast"; -import { importActions, toastActions } from "readium-desktop/common/redux/actions"; -import { takeSpawnLeading } from "readium-desktop/common/redux/sagas/takeSpawnLeading"; -import { apiSaga } from "readium-desktop/renderer/common/redux/sagas/api"; -import { ILibraryRootState } from "readium-desktop/common/redux/states/renderer/libraryRootState"; -// eslint-disable-next-line local-rules/typed-redux-saga-use-typed-effects -import { all, put } from "redux-saga/effects"; -import { select as selectTyped } from "typed-redux-saga/macro"; -import { getTranslator } from "readium-desktop/common/services/translator"; +// import * as debug_ from "debug"; +// import { ToastType } from "readium-desktop/common/models/toast"; +// import { importActions, toastActions } from "readium-desktop/common/redux/actions"; +// import { takeSpawnLeading } from "readium-desktop/common/redux/sagas/takeSpawnLeading"; +// import { apiSaga } from "readium-desktop/renderer/common/redux/sagas/api"; +// import { ILibraryRootState } from "readium-desktop/common/redux/states/renderer/libraryRootState"; +// // eslint-disable-next-line local-rules/typed-redux-saga-use-typed-effects +// import { all, put } from "redux-saga/effects"; +// import { select as selectTyped } from "typed-redux-saga/macro"; +// import { getTranslator } from "readium-desktop/common/services/translator"; -const REQUEST_ID = "SAME_FILE_IMPORT_REQUEST"; +// const REQUEST_ID = "SAME_FILE_IMPORT_REQUEST"; -// Logger -const filename_ = "readium-desktop:renderer:redux:saga:same-file-import"; -const debug = debug_(filename_); +// // Logger +// const filename_ = "readium-desktop:renderer:redux:saga:same-file-import"; +// const debug = debug_(filename_); -function* sameFileImport(action: importActions.verify.TAction) { +// function* sameFileImport(action: importActions.verify.TAction) { - const { link, pub } = action.payload; +// const { link, pub } = action.payload; - const downloads = yield* selectTyped( - (state: ILibraryRootState) => state.download); +// const downloads = yield* selectTyped( +// (state: ILibraryRootState) => state.download); - if (Array.isArray(downloads) - && downloads.map(([{ downloadUrl }]) => downloadUrl).find((ln) => ln === link.url)) { +// if (Array.isArray(downloads) +// && downloads.map(([{ downloadUrl }]) => downloadUrl).find((ln) => ln === link.url)) { - yield put( - toastActions.openRequest.build( - ToastType.Success, - getTranslator().__("message.import.alreadyImport", - { - title: pub.documentTitle || "", - }, - ), - ), - ); +// yield put( +// toastActions.openRequest.build( +// ToastType.Success, +// getTranslator().__("message.import.alreadyImport", +// { +// title: pub.documentTitle || "", +// }, +// ), +// ), +// ); - } else { +// } else { - yield apiSaga("publication/importFromLink", - REQUEST_ID, - link, - pub, - ); - } -} +// yield apiSaga("publication/importFromLink", +// REQUEST_ID, +// link, +// pub, +// ); +// } +// } -export function saga() { - return all([ - takeSpawnLeading( - importActions.verify.ID, - sameFileImport, - (e) => debug(e), - ), - ]); -} +// export function saga() { +// return all([ +// takeSpawnLeading( +// importActions.verify.ID, +// sameFileImport, +// (e) => debug(e), +// ), +// ]); +// }