diff --git a/package.json b/package.json index 2e90a1cde..9d1e97723 100644 --- a/package.json +++ b/package.json @@ -83,6 +83,7 @@ "crypto": "0.0.3", "debug": "2.6.1", "deepcopy": "0.6.3", + "download": "5.0.3", "elasticsearch": "12.1.3", "escape-html": "1.0.3", "escape-regexp": "0.0.1", diff --git a/src/api/endpoints.ts b/src/api/endpoints.ts index 963d1df25..37e3348b8 100644 --- a/src/api/endpoints.ts +++ b/src/api/endpoints.ts @@ -54,19 +54,20 @@ export default [ { name: 'notifications/mark_as_read', shouldBeSignin: true, kind: 'notification-write' }, { name: 'notifications/mark_as_read_all', shouldBeSignin: true, kind: 'notification-write' }, - { name: 'drive', shouldBeSignin: true, kind: 'drive-read' }, - { name: 'drive/stream', shouldBeSignin: true, kind: 'drive-read' }, - { name: 'drive/files', shouldBeSignin: true, kind: 'drive-read' }, - { name: 'drive/files/create', shouldBeSignin: true, limitDuration: hour, limitMax: 100, withFile: true, kind: 'drive-write' }, - { name: 'drive/files/show', shouldBeSignin: true, kind: 'drive-read' }, - { name: 'drive/files/find', shouldBeSignin: true, kind: 'drive-read' }, - { name: 'drive/files/delete', shouldBeSignin: true, kind: 'drive-write' }, - { name: 'drive/files/update', shouldBeSignin: true, kind: 'drive-write' }, - { name: 'drive/folders', shouldBeSignin: true, kind: 'drive-read' }, - { name: 'drive/folders/create', shouldBeSignin: true, limitDuration: hour, limitMax: 50, kind: 'drive-write' }, - { name: 'drive/folders/show', shouldBeSignin: true, kind: 'drive-read' }, - { name: 'drive/folders/find', shouldBeSignin: true, kind: 'drive-read' }, - { name: 'drive/folders/update', shouldBeSignin: true, kind: 'drive-write' }, + { name: 'drive', shouldBeSignin: true, kind: 'drive-read' }, + { name: 'drive/stream', shouldBeSignin: true, kind: 'drive-read' }, + { name: 'drive/files', shouldBeSignin: true, kind: 'drive-read' }, + { name: 'drive/files/create', shouldBeSignin: true, limitDuration: hour, limitMax: 100, withFile: true, kind: 'drive-write' }, + { name: 'drive/files/upload_from_url', shouldBeSignin: true, limitDuration: hour, limitMax: 10, kind: 'drive-write' }, + { name: 'drive/files/show', shouldBeSignin: true, kind: 'drive-read' }, + { name: 'drive/files/find', shouldBeSignin: true, kind: 'drive-read' }, + { name: 'drive/files/delete', shouldBeSignin: true, kind: 'drive-write' }, + { name: 'drive/files/update', shouldBeSignin: true, kind: 'drive-write' }, + { name: 'drive/folders', shouldBeSignin: true, kind: 'drive-read' }, + { name: 'drive/folders/create', shouldBeSignin: true, limitDuration: hour, limitMax: 50, kind: 'drive-write' }, + { name: 'drive/folders/show', shouldBeSignin: true, kind: 'drive-read' }, + { name: 'drive/folders/find', shouldBeSignin: true, kind: 'drive-read' }, + { name: 'drive/folders/update', shouldBeSignin: true, kind: 'drive-write' }, { name: 'users', shouldBeSignin: false }, { name: 'users/show', shouldBeSignin: false }, diff --git a/src/api/endpoints/drive/files/upload_from_url.js b/src/api/endpoints/drive/files/upload_from_url.js new file mode 100644 index 000000000..3cc91b946 --- /dev/null +++ b/src/api/endpoints/drive/files/upload_from_url.js @@ -0,0 +1,55 @@ +'use strict'; + +/** + * Module dependencies + */ +import * as URL from 'url'; +const download = require('download'); +import * as mongo from 'mongodb'; +import File from '../../../models/drive-file'; +import { validateFileName } from '../../../models/drive-file'; +import User from '../../../models/user'; +import serialize from '../../../serializers/drive-file'; +import create from '../../../common/add-file-to-drive'; + +/** + * Create a file from a URL + * + * @param {Object} params + * @param {Object} user + * @return {Promise} + */ +module.exports = (params, user) => + new Promise(async (res, rej) => +{ + // Get 'url' parameter + const url = params.url; + if (url == null) { + return rej('url is required'); + } + + let name = URL.parse(url).pathname.split('/').pop(); + if (!validateFileName(name)) { + name = null; + } + + // Get 'folder_id' parameter + let folder = params.folder_id; + if (folder === undefined || folder === null) { + folder = null; + } else { + folder = new mongo.ObjectID(folder); + } + + // Download file + const data = await download(url); + + // Create file + const driveFile = await create(user, data, name, null, folder); + + // Serialize + const fileObj = await serialize(driveFile); + + // Response + res(fileObj); +}); diff --git a/src/web/app/desktop/tags/drive/base-contextmenu.tag b/src/web/app/desktop/tags/drive/base-contextmenu.tag index 4c6f13465..c3a613d32 100644 --- a/src/web/app/desktop/tags/drive/base-contextmenu.tag +++ b/src/web/app/desktop/tags/drive/base-contextmenu.tag @@ -7,6 +7,9 @@
  • ファイルをアップロード

  • +
  • +

    URLからアップロード

    +
  • diff --git a/src/web/app/desktop/tags/drive/browser.tag b/src/web/app/desktop/tags/drive/browser.tag index 640bf24b7..8ec90955f 100644 --- a/src/web/app/desktop/tags/drive/browser.tag +++ b/src/web/app/desktop/tags/drive/browser.tag @@ -455,6 +455,24 @@ @select-local-file = ~> @refs.file-input.click! + @url-upload = ~> + url <~ @input-dialog do + 'URLアップロード' + 'アップロードしたいファイルのURL' + null + + if url? and url != '' + @api \drive/files/upload_from_url do + url: url + folder_id: if @folder? then @folder.id else undefined + + @dialog do + 'アップロードをリクエストしました' + 'アップロードが完了するまで時間がかかる場合があります。' + [ + text: \OK + ] + @create-folder = ~> name <~ @input-dialog do 'フォルダー作成'