From ba8a99930bbca1a2f334705c3e85d25813f259db Mon Sep 17 00:00:00 2001 From: Yoshihiro OKUMURA Date: Tue, 21 May 2019 14:27:49 +0900 Subject: [PATCH] use original file name for downloading file. --- public/.htaccess | 16 ++- .../database/DatabaseDetailItem.tsx | 14 +-- .../lib/field/FileDownloadButton.tsx | 2 +- .../lib/field/LicenseAgreementDialog.tsx | 2 +- .../database/item-type/lib/field/Preview.tsx | 5 +- .../item-type/lib/field/RelatedTo.tsx | 17 +-- .../database/item-type/url/UrlUtil.tsx | 2 +- src/components/database/lib/ItemUtil.ts | 108 +++++++++++++----- 8 files changed, 104 insertions(+), 62 deletions(-) diff --git a/public/.htaccess b/public/.htaccess index c4d6249..0ef88a9 100644 --- a/public/.htaccess +++ b/public/.htaccess @@ -3,18 +3,22 @@ RewriteBase / RewriteRule ^index\.html$ - [L] RewriteCond %{QUERY_STRING} (^|&)index_id=([0-9]+)($|&) -RewriteRule ^modules/xoonips/listitem.php /database/list/%2? [L,R=301] +RewriteRule ^modules/xoonips/listitem.php /database/list/%2? [R=301,L] RewriteCond %{QUERY_STRING} (^|&)item_id=([0-9]+)($|&) -RewriteRule ^modules/xoonips/detail.php /database/item/%2? [L,R=301] +RewriteRule ^modules/xoonips/detail.php /database/item/%2? [R=301,L] RewriteCond %{QUERY_STRING} (^|&)id=([^&]+)($|&) -RewriteRule ^modules/xoonips/detail.php /database/item/id/%2? [L,R=301] +RewriteRule ^modules/xoonips/detail.php /database/item/id/%2? [R=301,L] -RewriteCond %{QUERY_STRING} (^|&)file_id=([^&]+)($|&) -RewriteRule ^modules/xoonips/download.php /database/file/%2? [L,R=301] +RewriteCond %{QUERY_STRING} (^|&)file_id=([0-9]+)($|&) +RewriteRule ^modules/xoonips/download.php /database/file/%2? [R=301,L] -RewriteRule ^modules/xoonips/advanced_search.php /database/advanced? [L,R=301] +RewriteRule ^modules/xoonips/advanced_search.php /database/advanced? [R=301,L] + +#RewriteCond %{QUERY_STRING} (^|&)op=itemtypesearch($|&) +#RewriteCond %{QUERY_STRING} (^|&)search_itemtype=xnp([^&]+)($|&) +#RewriteRule ^modules/xoonips/itemselect.php /database/search/itemtype/%2? [R=301,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d diff --git a/src/components/database/DatabaseDetailItem.tsx b/src/components/database/DatabaseDetailItem.tsx index f9ab4a7..800901c 100644 --- a/src/components/database/DatabaseDetailItem.tsx +++ b/src/components/database/DatabaseDetailItem.tsx @@ -41,18 +41,14 @@ class DatabaseDetailItem extends Component { this.updateItem(); } - updateItem() { + async updateItem() { + let item = null; if (this.doi !== '') { - ItemUtil.getByDoi(this.doi, (item) => { - this.setState({ loading: false, item }); - }); + item = await ItemUtil.getByDoi(this.doi); } else if (this.id !== 0) { - ItemUtil.get(this.id, (item) => { - this.setState({ loading: false, item }); - }); - } else { - this.setState({ loading: false }); + item = await ItemUtil.get(this.id); } + this.setState({ loading: false, item }); } render() { diff --git a/src/components/database/item-type/lib/field/FileDownloadButton.tsx b/src/components/database/item-type/lib/field/FileDownloadButton.tsx index 2cff4c9..653bdfc 100644 --- a/src/components/database/item-type/lib/field/FileDownloadButton.tsx +++ b/src/components/database/item-type/lib/field/FileDownloadButton.tsx @@ -48,7 +48,7 @@ class FileDownloadButton extends Component { if (this.state.file === null) { return null; } - const url = ItemUtil.getFileUrl(this.state.file.file_id); + const url = ItemUtil.getFileUrl(this.state.file); return ( <> Download diff --git a/src/components/database/item-type/lib/field/LicenseAgreementDialog.tsx b/src/components/database/item-type/lib/field/LicenseAgreementDialog.tsx index 72d4494..72f11e2 100644 --- a/src/components/database/item-type/lib/field/LicenseAgreementDialog.tsx +++ b/src/components/database/item-type/lib/field/LicenseAgreementDialog.tsx @@ -80,7 +80,7 @@ class LicenseAgreementDialog extends Component { } const date = new Date(this.state.file.timestamp); const timestamp = Math.floor(date.valueOf() / 1000); - const url = ItemUtil.getFileUrl(this.state.file.file_id); + const url = ItemUtil.getFileUrl(this.state.file); return (
diff --git a/src/components/database/item-type/lib/field/Preview.tsx b/src/components/database/item-type/lib/field/Preview.tsx index 0427a32..73e20d4 100644 --- a/src/components/database/item-type/lib/field/Preview.tsx +++ b/src/components/database/item-type/lib/field/Preview.tsx @@ -11,12 +11,11 @@ const Preview = (props: { file: ItemBasicFile[] }) => { return null; } const previews = data.map((value) => { - const fileUrl = ItemUtil.getFileUrl(value.file_id); - const previewUrl = fileUrl + '.png'; + const fileUrl = ItemUtil.getPreviewFileUrl(value); return (
- {value.original_file_name} + {value.original_file_name} {value.caption}
diff --git a/src/components/database/item-type/lib/field/RelatedTo.tsx b/src/components/database/item-type/lib/field/RelatedTo.tsx index 504af73..9b611eb 100644 --- a/src/components/database/item-type/lib/field/RelatedTo.tsx +++ b/src/components/database/item-type/lib/field/RelatedTo.tsx @@ -2,7 +2,6 @@ import React, { Component } from 'react'; import ItemUtil from '../../../lib/ItemUtil'; import ItemType from '../..'; - interface Props { relatedTo: number[]; } @@ -32,21 +31,17 @@ class RelatedTo extends Component { this.updateElements(this.state.relatedTo); } - updateElements(relatedTo: number[]) { + async updateElements(relatedTo: number[]) { let evenodd = 'even'; let elements: JSX.Element[] = []; - relatedTo.forEach(async (itemId, i) => { - await ItemUtil.get(itemId, (item) => { - if (item === null) { - return; - } + for (let itemId of relatedTo) { + const item = await ItemUtil.get(itemId); + if (item !== null) { evenodd = evenodd === 'even' ? 'odd' : 'even'; elements.push(); - }); - if (i + 1 === relatedTo.length) { - this.setState({ elements }); } - }); + } + this.setState({ elements }); } render() { diff --git a/src/components/database/item-type/url/UrlUtil.tsx b/src/components/database/item-type/url/UrlUtil.tsx index 0c99549..090f8ed 100644 --- a/src/components/database/item-type/url/UrlUtil.tsx +++ b/src/components/database/item-type/url/UrlUtil.tsx @@ -10,7 +10,7 @@ const BannerFile = (props: { file: ItemBasicFile[] })=> { if (typeof data === 'undefined') { return null; } - const url = ItemUtil.getFileUrl(data.file_id); + const url = ItemUtil.getFileUrl(data); return ( banner ); diff --git a/src/components/database/lib/ItemUtil.ts b/src/components/database/lib/ItemUtil.ts index 764cfe4..0dda030 100644 --- a/src/components/database/lib/ItemUtil.ts +++ b/src/components/database/lib/ItemUtil.ts @@ -5,6 +5,8 @@ import AdvancedSearchQuery from './AdvancedSearchQuery'; const LokiIndexedAdapter = require('lokijs/src/loki-indexed-adapter.js'); export const APPLICATION_NAME = 'pupil'; +export const APPLICATION_VERSION = 0; +export const APPLICATION_USE_INDEXEDDB = false; export type ItemBasicLang = 'eng' | 'jpn' | 'fra' | 'deu' | 'esl' | 'ita' | 'dut' | 'sve' | 'nor' | 'dan' | 'fin' | 'por' | 'chi' | 'kor'; export interface ItemBasicIndex { @@ -178,45 +180,89 @@ export interface SearchResult { } class ItemDatabase { + private db: loki; private items: Collection | null = null; - private initizalizing: boolean = true; + private loading: boolean = true; + private name: string; + private version: number; + private useIndexedDB: boolean; - constructor(name: string) { - const idbAdapter = new LokiIndexedAdapter(name); - this.db = new loki('database', { adapter: idbAdapter }); - this.db.loadDatabase({}, (err: any) => { - this.items = this.db.getCollection('items'); - if (this.items !== null) { - this.initizalizing = false; - return; - } - axios.get('/database/items.json', { responseType: 'json' }).then((response) => { - const itemsJson: Item[] = response.data; - const items = this.db.addCollection('items'); - if (items !== null) { - itemsJson.forEach((json) => { - items.insert(json); - }); - this.items = items; + constructor(name: string, version: number, useIndexedDB: boolean) { + this.name = name; + this.version = version; + this.useIndexedDB = useIndexedDB; + if (this.useIndexedDB) { + const idbAdapter = new LokiIndexedAdapter(this.name); + const paAdapter = new loki.LokiPartitioningAdapter(idbAdapter, { paging: true }); + this.db = new loki('database', { adapter: paAdapter }); + this.loadDatabaseFromIndexedDB(); + } else { + this.db = new loki('database'); + this.loadDatabaseFromJson(); + } + } + + loadDatabaseFromJson() { + axios.get('/database/items.json', { responseType: 'json' }).then((response) => { + const itemsJson: Item[] = response.data; + const items = this.db.addCollection('items'); + if (items !== null) { + itemsJson.forEach((json) => { + items.insert(json); + }); + this.items = items; + if (this.useIndexedDB) { this.db.saveDatabase(); } - this.initizalizing = false; - }).catch(() => { - this.initizalizing = false; - }); + } + this.loading = false; + }).catch(() => { + this.loading = false; + }); + } + + loadDatabaseFromIndexedDB() { + this.db.loadDatabase({}, (err: any) => { + let forceLoad = true; + if (this.useIndexedDB) { + let colVersion = this.db.getCollection('version'); + if (colVersion === null) { + colVersion = this.db.addCollection('version'); + colVersion.insert({ type: 'items', version: this.version }); + } else { + const v = colVersion.findOne({ type: 'items' }); + if (v === null) { + colVersion.insert({ type: 'items', version: this.version }); + } else if (v.version !== this.version) { + v.version = this.version; + colVersion.update(v); + } else { + forceLoad = false; + } + } + } + if (forceLoad) { + this.db.removeCollection('items'); + } + this.items = this.db.getCollection('items'); + if (this.items !== null) { + this.loading = false; + return; + } + this.loadDatabaseFromJson(); }); } async getItems() { - while (this.initizalizing) { + while (this.loading) { await new Promise(r => setTimeout(r, 200)); } return this.items as Collection; } } -const database = new ItemDatabase(APPLICATION_NAME); +const database = new ItemDatabase(APPLICATION_NAME, APPLICATION_VERSION, APPLICATION_USE_INDEXEDDB); class ItemSorter { @@ -276,8 +322,12 @@ class ItemUtil { return '/database/item/' + String(item.item_id); } - static getFileUrl(fileId: number) { - return '/database/file/' + fileId; + static getFileUrl(file: ItemBasicFile) { + return '/database/file/' + file.file_id + '/' + file.original_file_name; + } + + static getPreviewFileUrl(file: ItemBasicFile) { + return '/database/file/' + file.file_id + '.png'; } static getSearchByKeywordUrl(type: SearchByKeywordType, keyword: string) { @@ -312,23 +362,21 @@ class ItemUtil { return query; } - static async get(itemId: number, callback: (item: any) => void) { + static async get(itemId: number) { const items = await database.getItems(); const filter = { 'item_id': itemId } const item = items.findOne(filter); - callback(item); return item; } - static async getByDoi(doi: string, callback: (item: any) => void) { + static async getByDoi(doi: string) { const items = await database.getItems(); const filter = { 'doi': doi } const item = items.findOne(filter); - callback(item); return item; }