Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: import files to MFS #810

Merged
merged 28 commits into from
Dec 3, 2019
Merged

feat: import files to MFS #810

merged 28 commits into from
Dec 3, 2019

Conversation

colinfruit
Copy link
Contributor

@colinfruit colinfruit commented Nov 7, 2019

This PR changes the upload target from ipfs add to MFS. Currently, it uses the default directory ipfs-companion-uploads with the user option to change this on the upload page. On successful upload, it will open the Web UI, at the directory used for the upload.

closes #415 and closes #635

Copy link
Member

@lidel lidel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is awesome, thank you @colinfruit!
Apologies for not getting to this sooner.

Big 👍, but before we merge this, some things to address:

  1. Please change labels and variable names from "upload" to "import"
    (eg. "import to IPFS", /ipfs-companion-imports/ directory on MFS, etc).
    Context: We generally avoid the 'upload' word, because it suggests data is pushed to some external machine, but thats not how IPFS works, and ipfs add may be renamed to ipfs import in the future (see RFC: unite the files APIs ipfs-inactive/interface-js-ipfs-core#552).

  2. Would it be possible to expose the name of default directory for uploads as an editable setting on Preferences screen? Its ok to add it to "Experiments" section for now, as we may change it in the future.

  3. I am bit worried what happens to /ipfs-companion-imports/ when user uploads 10th, 100th file. To illustrate, I've shared multiple files over times, and today I shared death-button.jpg. After it got imported, Companion opened /ipfs-companion-imports/ and the file is lost in the noise.
    (see screenshot)
    Potential solution is to shard per timestamp (/ipfs-companion-imports/2019-11-11_184500) to keep this in check. Perhaps we could make the default /ipfs-companion-imports/%Y-%m-%d_%H%M%S/ and replace timestamp on the fly, enabling people to define their own destinations, eg. if they want to shard per day instead of per second?

Copy link
Member

@lidel lidel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two more things:

add-on/src/popup/quick-upload.js Outdated Show resolved Hide resolved
}
let result
state.progress = `Uploading ${streams.length} files...`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: it looks like we are losing import progress report, but it never worked correctly over HTTP API (https://github.com/ipfs/js-ipfs-http-client/issues/842), so its ok to drop it for now.

Comment on lines 796 to 748
get openWebUiAtDirectory () {
return openWebUiAtDirectory
},
Copy link
Member

@lidel lidel Nov 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh, another realization: we can't open webui if embedded js-ipfs is used in non-Brave browser.
We need to check if getState().ipfsNodeType === 'embedded' and open resource at public gateway instead (Brave uses embedded:chromesockets, so it won't match and open WebUI)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we could make this even more useful:
What if we add toggle "Open imported files in WebUI"?
Enabled by default, but when disabled it would open at Gateway (restoring old behavior).

Copy link
Contributor Author

@colinfruit colinfruit Nov 14, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. It would be great to find a way of opening the WebUI when using embedded nodes in a subsequent issue. Has this been looked at before?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Embedded node is unable to open port to provide HTTP API, so the only option I see is to open WebUI from third party server, eg. https://webui.ipfs.io and make it use API of embedded node from Companion via window.ipfs. At the moment we don't support window.ipfs in WebUI because it is sandboxed, and WebUI requires full read-write access to MFS and config.
Details in: #514

@colinfruit
Copy link
Contributor Author

colinfruit commented Nov 15, 2019

Thanks, @lidel!

Please change labels and variable names from "upload" to "import"

Makes sense. I changed all the user-facing labels this PR introduces from "upload" to "import". I did not change the variable names, because it feels inconsistent with the existing code. References to upload are everywhere, even the file name is quick-upload.js. If you want to make an issue, I'll be glad to remove upload references throughout the code base.

Would it be possible to expose the name of default directory for uploads as an editable setting on Preferences screen?

Sure. Also, I removed it from the upload screen, because it seemed redundant. On the other hand, it provides useful functionality there as well. What do you think?
Edit: added it back.

I am bit worried what happens to /ipfs-companion-imports/ when user uploads 10th, 100th file.

I'm looking into the best way to handle user-generated date symbols (%Y-%m-%d), and the best way to demonstrate this functionality to the user. What if they removed them, and then forgot what the symbols were, or weren't sure what they meant to begin with? Maybe a result field on the Preferences screen (and upload screen if we return the functionality) that show what directory will be used? Or an instruction in the description?
Edit: added the feature.

@lidel
Copy link
Member

lidel commented Nov 19, 2019

Thank you @colinfruit! I am travelling this week, but will review this as soon I have some uninterrupted time.

Copy link
Member

@lidel lidel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@colinfruit Apologies for slowness on my end. Good news is that after 32h travel I am finally back :-)

This PR is great, we are nearly there: small cosmetic asks below and inline.

  1. Let's add "File Import" section to Options page and move related settings there
    (This can be a separate PR if you want to ship this sooner)

  2. Please change newly added labels, variables and keys in this PR to use "import" instead of "upload" (mainly uploadDirimportDir). To keep this PR small I created Language: replace "upload" with "import" #817 for the rest.

    • FYI I've added you as a Collaborator, so you no longer need to work from your fork, you can close this original repo and create feature branches in it (it makes easier to work on PRs together)

Can't wait for pushing this over the finish line ❤️

<input
id="uploadDir"
type="text"
pattern="^\/(.*)"
Copy link
Member

@lidel lidel Nov 25, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing slash may be missing. To avoid bugs caused by that, either require it to end with / (easy, fix below) or programmatically add it if missing (harder)

Suggested change
pattern="^\/(.*)"
pattern="^\/(.+)\/"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this before import happens in quick-upload.js, to account for the potential case of someone forgetting the trailing slash on the import page. It handles both cases, and prevents the user from having to guess that a trailing slash is necessary. https://github.com/ipfs-shipyard/ipfs-companion/pull/810/files#diff-9984375a8301f7832fa0da0a5aafd803R75

add-on/src/popup/quick-upload.js Outdated Show resolved Hide resolved
add-on/src/popup/quick-upload.js Outdated Show resolved Hide resolved
add-on/src/popup/quick-upload.js Outdated Show resolved Hide resolved
add-on/_locales/en/messages.json Outdated Show resolved Hide resolved
add-on/_locales/en/messages.json Outdated Show resolved Hide resolved
add-on/_locales/en/messages.json Outdated Show resolved Hide resolved
@colinfruit
Copy link
Contributor Author

colinfruit commented Nov 26, 2019

Let's add "File Import" section to Options page and move related settings there

Sounds good, one thing we need is to handle preloadAtPublicGateway more consistently.

Please change newly added labels, variables and keys in this PR to use "import" instead of "upload" (mainly uploadDir → importDir). To keep this PR small I created #817 for the rest.

Sure.

// unless and embedded node is in use (no access to web UI)
// in which case, open resource.
if (state.ipfsNodeType === 'embedded' || !state.openViaWebUI) {
await ipfsCompanion.uploadResultHandler({ result, openRootInNewTab: true })
Copy link
Contributor Author

@colinfruit colinfruit Nov 26, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not working as expected for me tonight, when importing multiple files without using the webUI, the context menu simply hangs. Maybe it's some weirdness with my connection; I'll take a look at this tomorrow.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue this morning, importing multiple files and opening them in a context menu hangs. However, it is reproducible on current master, so I won't deal with it in this PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the issue you described is due to slow content discovery by the gateway at https://ipfs.io/ipfs/.
Embedded node in Firefox/Chrome can't run own gateway, so we use public one instead.

Potential fix would be to update preloadAtPublicGateway and apart from existing HTTP HEAD request to user-specified public gateway, do additional recursive preload via HTTP GET request to one of preload nodes:

https://node0.preload.ipfs.io/api/v0/refs?arg={CID}&r=true
https://node1.preload.ipfs.io/api/v0/refs?arg={CID}&r=true

In case of "quick-upload" screen, the CID should be of the wrapping directory.

This should not block this PR, let's track this in #546

@@ -134,6 +134,8 @@ function file2buffer (file) {

function formatImportDirectory (path) {
path = path.replace(/\/$|$/, '/')
path = path.replace(/(\/)\/+/g, '$1')
Copy link
Contributor Author

@colinfruit colinfruit Nov 27, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this just because it makes a nicer user experience. Files will appear in the Web UI with multiple slashes (only on auto-open, from import page), despite being stored without them, if multiple slashes are not removed on format.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Do you mind adding unit tests for formatImportDirectory, so we don't break this during future refactors?

For now it can be test/functional/lib/quick-upload.test.js (similar to existing test/functional/lib/ipfs-path.test.js)

Copy link
Member

@lidel lidel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more ask: some users will prefer old behavior of opening at the gateway.
Please add a global setting Open imported files in Web UI to the "File Imports" section:

2019-11-27--22-01-16

It should set the initial state of Open in Web UI checkbox on the quick-upload screen.

// unless and embedded node is in use (no access to web UI)
// in which case, open resource.
if (state.ipfsNodeType === 'embedded' || !state.openViaWebUI) {
await ipfsCompanion.uploadResultHandler({ result, openRootInNewTab: true })
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the issue you described is due to slow content discovery by the gateway at https://ipfs.io/ipfs/.
Embedded node in Firefox/Chrome can't run own gateway, so we use public one instead.

Potential fix would be to update preloadAtPublicGateway and apart from existing HTTP HEAD request to user-specified public gateway, do additional recursive preload via HTTP GET request to one of preload nodes:

https://node0.preload.ipfs.io/api/v0/refs?arg={CID}&r=true
https://node1.preload.ipfs.io/api/v0/refs?arg={CID}&r=true

In case of "quick-upload" screen, the CID should be of the wrapping directory.

This should not block this PR, let's track this in #546

Comment on lines 796 to 748
get openWebUiAtDirectory () {
return openWebUiAtDirectory
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Embedded node is unable to open port to provide HTTP API, so the only option I see is to open WebUI from third party server, eg. https://webui.ipfs.io and make it use API of embedded node from Companion via window.ipfs. At the moment we don't support window.ipfs in WebUI because it is sandboxed, and WebUI requires full read-write access to MFS and config.
Details in: #514

Copy link
Member

@lidel lidel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@colinfruit Thanks! The UX of this is looking pretty nice ❤️ 👍

I believe we could go extra mile and switch everything to MFS, namely close #635 in this PR as well.

If you right click on image there will be context menu option to Add to IPFS.
The code responsible for that is in add-on/src/lib/ipfs-companion.js#onAddFromContext – do you think you could make it work the same as sharing screen?

  • copy to MFS instead of pinning
  • opening in WebUI instead of gateway
  • rename labels from Add to IPFS to Import to IPFS
    • perhaps we should only keep the one that remembers the filename? CID-as-filename does not make much sense in MFS context, and CID can be copied via context menu anyway
  • respect global File Import preferences

Thoughts?

add-on/src/popup/quick-upload.js Outdated Show resolved Hide resolved
Copy link
Member

@lidel lidel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you @colinfruit!

Is there anything you want to add to this PR, or is it ok to merge & release to beta?

@colinfruit
Copy link
Contributor Author

@lidel, fine to merge this. Thanks!

@lidel lidel changed the title feat: upload files to MFS feat: import files to MFS Dec 3, 2019
@lidel lidel merged commit 92fd07a into ipfs:master Dec 3, 2019
lidel pushed a commit that referenced this pull request Dec 11, 2019
* language: replace upload with import terminology
* update privacy policy language and last updated date

Following up on the changes made in #810. 
This replaces references to `upload` with `import` 

Closes #817
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Context action to "Add to MFS" Save all uploads to MFS (via ipfs.files API)
2 participants