Trying to upload an attachment with Meteor-Files

This commit is contained in:
Romulus Urakagi Tsai 2019-11-18 01:47:26 +00:00
parent 9fd14f7ecb
commit 05c53ca01d
8 changed files with 132 additions and 84 deletions

View file

@ -96,3 +96,4 @@ konecty:mongo-counter
percolate:synced-cron percolate:synced-cron
easylogic:summernote easylogic:summernote
cfs:filesystem cfs:filesystem
ostrio:files

View file

@ -133,6 +133,8 @@ oauth2@1.2.1
observe-sequence@1.0.16 observe-sequence@1.0.16
ongoworks:speakingurl@1.1.0 ongoworks:speakingurl@1.1.0
ordered-dict@1.1.0 ordered-dict@1.1.0
ostrio:cookies@2.5.0
ostrio:files@1.13.0
peerlibrary:assert@0.2.5 peerlibrary:assert@0.2.5
peerlibrary:base-component@0.16.0 peerlibrary:base-component@0.16.0
peerlibrary:blaze-components@0.15.1 peerlibrary:blaze-components@0.15.1

View file

@ -149,20 +149,28 @@ Template.previewClipboardImagePopup.events({
if (results && results.file) { if (results && results.file) {
window.oPasted = pastedResults; window.oPasted = pastedResults;
const card = this; const card = this;
const file = new FS.File(results.file); const settings = {
file: results.file,
streams: 'dynamic',
chunkSize: 'dynamic'
};
if (!results.name) { if (!results.name) {
// if no filename, it's from clipboard. then we give it a name, with ext name from MIME type // if no filename, it's from clipboard. then we give it a name, with ext name from MIME type
// FIXME: Check this behavior
if (typeof results.file.type === 'string') { if (typeof results.file.type === 'string') {
file.name(results.file.type.replace('image/', 'clipboard.')); settings.fileName = new Date().getTime() + results.file.type.replace('.+/', '');
} }
} }
file.updatedAt(new Date()); settings.meta = {};
file.boardId = card.boardId; settings.meta.updatedAt = new Date().getTime();
file.cardId = card._id; settings.meta.boardId = card.boardId;
file.userId = Meteor.userId(); settings.meta.cardId = card._id;
const attachment = Attachments.insert(file); settings.meta.userId = Meteor.userId();
console.log('settings', settings);
const attachment = Attachments.insert(settings, false);
if (attachment && attachment._id && attachment.isImage()) { // TODO: Check image cover behavior
if (attachment && attachment._id && attachment.isImage) {
card.setCover(attachment._id); card.setCover(attachment._id);
} }

View file

@ -34,21 +34,27 @@ Utils = {
if (!card) { if (!card) {
return next(); return next();
} }
const file = new FS.File(fileObj); let settings = {
file: fileObj,
streams: 'dynamic',
chunkSize: 'dynamic'
};
settings.meta = {};
if (card.isLinkedCard()) { if (card.isLinkedCard()) {
file.boardId = Cards.findOne(card.linkedId).boardId; settings.meta.boardId = Cards.findOne(card.linkedId).boardId;
file.cardId = card.linkedId; settings.meta.cardId = card.linkedId;
} else { } else {
file.boardId = card.boardId; settings.meta.boardId = card.boardId;
file.swimlaneId = card.swimlaneId; settings.meta.swimlaneId = card.swimlaneId;
file.listId = card.listId; settings.meta.listId = card.listId;
file.cardId = card._id; settings.meta.cardId = card._id;
} }
file.userId = Meteor.userId(); settings.meta.userId = Meteor.userId();
if (file.original) { // FIXME: What is this?
/* if (file.original) {
file.original.name = fileObj.name; file.original.name = fileObj.name;
} }*/
return next(Attachments.insert(file)); return next(Attachments.insert(settings, false));
}, },
shrinkImage(options) { shrinkImage(options) {
// shrink image to certain size // shrink image to certain size

View file

@ -1,3 +1,29 @@
import { FilesCollection } from 'meteor/ostrio:files';
Attachments = new FilesCollection({
storagePath: storagePath(),
debug: true, // FIXME: Remove debug mode
collectionName: 'attachments2',
allowClientCode: false, // Disallow remove files from Client
});
if (Meteor.isServer) {
Meteor.startup(() => {
Attachments.collection._ensureIndex({ cardId: 1 });
});
// TODO: Permission related
// TODO: Add Activity update
// TODO: publish and subscribe
// Meteor.publish('files.attachments.all', function () {
// return Attachments.find().cursor;
// });
} else {
// Meteor.subscribe('files.attachments.all');
}
// ---------- Deprecated fallback ---------- //
const localFSStore = process.env.ATTACHMENTS_STORE_PATH; const localFSStore = process.env.ATTACHMENTS_STORE_PATH;
const storeName = 'attachments'; const storeName = 'attachments';
const defaultStoreOptions = { const defaultStoreOptions = {
@ -171,16 +197,16 @@ if (localFSStore) {
...defaultStoreOptions, ...defaultStoreOptions,
}); });
} }
Attachments = new FS.Collection('attachments', { DeprecatedAttachs = new FS.Collection('attachments', {
stores: [store], stores: [store],
}); });
if (Meteor.isServer) { if (Meteor.isServer) {
Meteor.startup(() => { Meteor.startup(() => {
Attachments.files._ensureIndex({ cardId: 1 }); DeprecatedAttachs.files._ensureIndex({ cardId: 1 });
}); });
Attachments.allow({ DeprecatedAttachs.allow({
insert(userId, doc) { insert(userId, doc) {
return allowIsBoardMember(userId, Boards.findOne(doc.boardId)); return allowIsBoardMember(userId, Boards.findOne(doc.boardId));
}, },
@ -206,10 +232,10 @@ if (Meteor.isServer) {
}); });
} }
// XXX Enforce a schema for the Attachments CollectionFS // XXX Enforce a schema for the DeprecatedAttachs CollectionFS
if (Meteor.isServer) { if (Meteor.isServer) {
Attachments.files.after.insert((userId, doc) => { DeprecatedAttachs.files.after.insert((userId, doc) => {
// If the attachment doesn't have a source field // If the attachment doesn't have a source field
// or its source is different than import // or its source is different than import
if (!doc.source || doc.source !== 'import') { if (!doc.source || doc.source !== 'import') {
@ -227,7 +253,7 @@ if (Meteor.isServer) {
} else { } else {
// Don't add activity about adding the attachment as the activity // Don't add activity about adding the attachment as the activity
// be imported and delete source field // be imported and delete source field
Attachments.update( DeprecatedAttachs.update(
{ {
_id: doc._id, _id: doc._id,
}, },
@ -240,7 +266,7 @@ if (Meteor.isServer) {
} }
}); });
Attachments.files.before.remove((userId, doc) => { DeprecatedAttachs.files.before.remove((userId, doc) => {
Activities.insert({ Activities.insert({
userId, userId,
type: 'card', type: 'card',
@ -253,11 +279,16 @@ if (Meteor.isServer) {
}); });
}); });
Attachments.files.after.remove((userId, doc) => { DeprecatedAttachs.files.after.remove((userId, doc) => {
Activities.remove({ Activities.remove({
attachmentId: doc._id, attachmentId: doc._id,
}); });
}); });
} }
function storagePath(defaultPath) {
const storePath = process.env.ATTACHMENTS_STORE_PATH;
return storePath ? storePath : defaultPath;
}
export default Attachments; export default Attachments;

View file

@ -1,56 +1,56 @@
@ECHO OFF @ECHO OFF
REM NOTE: THIS .BAT DOES NOT WORK !! REM NOTE: THIS .BAT DOES NOT WORK !!
REM Use instead this webpage instructions to build on Windows: REM Use instead this webpage instructions to build on Windows:
REM https://github.com/wekan/wekan/wiki/Install-Wekan-from-source-on-Windows REM https://github.com/wekan/wekan/wiki/Install-Wekan-from-source-on-Windows
REM Please add fix PRs, like config of MongoDB etc. REM Please add fix PRs, like config of MongoDB etc.
md C:\repos md C:\repos
cd C:\repos cd C:\repos
REM Install chocolatey REM Install chocolatey
@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin" @"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
choco install -y git curl python2 dotnet4.5.2 nano mongodb-3 mongoclient meteor choco install -y git curl python2 dotnet4.5.2 nano mongodb-3 mongoclient meteor
curl -O https://nodejs.org/dist/v8.16.1/node-v8.16.1-x64.msi curl -O https://nodejs.org/dist/v8.16.1/node-v8.16.1-x64.msi
call node-v8.16.1-x64.msi call node-v8.16.1-x64.msi
call npm config -g set msvs_version 2015 call npm config -g set msvs_version 2015
call meteor npm config -g set msvs_version 2015 call meteor npm config -g set msvs_version 2015
call npm -g install npm call npm -g install npm
call npm -g install node-gyp call npm -g install node-gyp
call npm -g install fibers call npm -g install fibers
cd C:\repos cd C:\repos
git clone https://github.com/wekan/wekan.git git clone https://github.com/wekan/wekan.git
cd wekan cd wekan
git checkout edge git checkout edge
echo "Building Wekan." echo "Building Wekan."
REM del /S /F /Q packages REM del /S /F /Q packages
REM ## REPOS BELOW ARE INCLUDED TO WEKAN REM ## REPOS BELOW ARE INCLUDED TO WEKAN
REM md packages REM md packages
REM cd packages REM cd packages
REM git clone --depth 1 -b master https://github.com/wekan/flow-router.git kadira-flow-router REM git clone --depth 1 -b master https://github.com/wekan/flow-router.git kadira-flow-router
REM git clone --depth 1 -b master https://github.com/meteor-useraccounts/core.git meteor-useraccounts-core REM git clone --depth 1 -b master https://github.com/meteor-useraccounts/core.git meteor-useraccounts-core
REM git clone --depth 1 -b master https://github.com/wekan/meteor-accounts-cas.git REM git clone --depth 1 -b master https://github.com/wekan/meteor-accounts-cas.git
REM git clone --depth 1 -b master https://github.com/wekan/wekan-ldap.git REM git clone --depth 1 -b master https://github.com/wekan/wekan-ldap.git
REM git clone --depth 1 -b master https://github.com/wekan/wekan-scrollbar.git REM git clone --depth 1 -b master https://github.com/wekan/wekan-scrollbar.git
REM git clone --depth 1 -b master https://github.com/wekan/meteor-accounts-oidc.git REM git clone --depth 1 -b master https://github.com/wekan/meteor-accounts-oidc.git
REM git clone --depth 1 -b master --recurse-submodules https://github.com/wekan/markdown.git REM git clone --depth 1 -b master --recurse-submodules https://github.com/wekan/markdown.git
REM move meteor-accounts-oidc/packages/switch_accounts-oidc wekan_accounts-oidc REM move meteor-accounts-oidc/packages/switch_accounts-oidc wekan_accounts-oidc
REM move meteor-accounts-oidc/packages/switch_oidc wekan_oidc REM move meteor-accounts-oidc/packages/switch_oidc wekan_oidc
REM del /S /F /Q meteor-accounts-oidc REM del /S /F /Q meteor-accounts-oidc
REM sed -i 's/api\.versionsFrom/\/\/api.versionsFrom/' ~/repos/wekan/packages/meteor-useraccounts-core/package.js REM sed -i 's/api\.versionsFrom/\/\/api.versionsFrom/' ~/repos/wekan/packages/meteor-useraccounts-core/package.js
cd .. cd ..
REM del /S /F /Q node_modules REM del /S /F /Q node_modules
call meteor npm install call meteor npm install
REM del /S /F /Q .build REM del /S /F /Q .build
call meteor build .build --directory call meteor build .build --directory
copy fix-download-unicode\cfs_access-point.txt .build\bundle\programs\server\packages\cfs_access-point.js copy fix-download-unicode\cfs_access-point.txt .build\bundle\programs\server\packages\cfs_access-point.js
cd .build\bundle\programs\server cd .build\bundle\programs\server
call meteor npm install call meteor npm install
REM cd C:\repos\wekan\.meteor\local\build\programs\server REM cd C:\repos\wekan\.meteor\local\build\programs\server
REM del node_modules REM del node_modules
cd C:\repos\wekan cd C:\repos\wekan
call start-wekan.bat call start-wekan.bat

View file

@ -128,7 +128,7 @@ Meteor.publishRelations('board', function(boardId, isArchived) {
// Gather queries and send in bulk // Gather queries and send in bulk
const cardComments = this.join(CardComments); const cardComments = this.join(CardComments);
cardComments.selector = _ids => ({ cardId: _ids }); cardComments.selector = _ids => ({ cardId: _ids });
const attachments = this.join(Attachments); const attachments = this.join(Attachments.collection);
attachments.selector = _ids => ({ cardId: _ids }); attachments.selector = _ids => ({ cardId: _ids });
const checklists = this.join(Checklists); const checklists = this.join(Checklists);
checklists.selector = _ids => ({ cardId: _ids }); checklists.selector = _ids => ({ cardId: _ids });