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

Upload "assets" (i.e. JSON, Images, Audio, Video, text files) #100

Open
therewasaguy opened this issue Jan 8, 2016 · 11 comments
Open

Upload "assets" (i.e. JSON, Images, Audio, Video, text files) #100

therewasaguy opened this issue Jan 8, 2016 · 11 comments

Comments

@therewasaguy
Copy link
Owner

Background

Right now, users could add a new file called 'myData.json'. But if they use a p5 method like loadJSON('myData.json'), that won't work because it's not an actual filesystem and the relative path won't resolve as expected. Same goes for images and other assets. Users could save the data as a JS variable, but the p5 load___ methods won't work.

Relative paths do resolve when users import .css and .js in their index.html, but this involves some crazy hacks when parsing the sketch contents.

So thinking about how to handle assets, is it worth continuing to mimic the filesystem? If so, how?

How to handle Assets?

Here's one idea:

Add an "assets" area to the sidebar that is separate from the files. Registered users have limited space to upload assets to their project(s). We'd check that it is a recognized filetype for JSON, text / csv, audio, video, images etc. The files would be uploaded to a server that allows cross origin requests from the editor. The assets would show up in the Assets area. Multiple projects can refer to the same asset and users can add to their project by searching/browsing their existing assets.

Each asset would have a clipboard icon to copy its path/url and paste it as needed into their sketch. Dragging the asset might also paste the url.

To start, the easiest thing would be for the URL to point directly to the file on the server, rather than mimic the filesystem as if the files are inside of the sketch folder. Or there could be an API to fetch files for projects so we don't reveal the absolute paths, something like ../projectID/assets/fileName. But what happens when a user downloads the sketch as a zip? Would it include the assets? If so, would it change the path?

I'd love to hear feedback / new ideas!

@shiffman
Copy link

shiffman commented Jan 8, 2016

Would it be wrong to just actually implement a file system, i.e. when a user creates a sketch a folder is created on the server with files with relative paths. The "hash" for the project id could just be the directory:

http://p5ide.herokuapp.com/56899c0c66d9570300507582/

or even just use a username as the directory and use project names as paths (the id would be more behind the scenes)?

http://p5ide.herokuapp.com/shiffman/week1_homework/

And then the editor would simply point to this directory while you are working and the iframe would open this directory literally?

I'm imagining an interface something like what cloud9 has where you can see a file directory structure, move things around, and drag and drop to upload:

screen shot 2016-01-08 at 9 44 47 am

We could treat p5.js, p5.dom.js, and p5.sound.js so that they are not duplicated for every project but let everything else just be a relative path?

But perhaps there are obvious reasons why this can't work that I am missing!

@shiffman
Copy link

shiffman commented Jan 8, 2016

@therewasaguy and I had a discussion today regarding the above and feel we are at a bit of a crossroads. Some ways of moving forward:

  1. Each "sketch" is a directory of files. This is how the desktop editor works. With the possible exception of p5.js library files, every file is an actual file sitting in the directory of that sketch. If you have the same cat.jpg in 10 sketches, then there are 10 copies of cat.jpg in the directory for each sketch on the server.
  2. Each "sketch" is a directory of files for your code. However, for things like images, sounds, data files, etc. you have a separate "asset manager". This allows you to have a single version of an image or sound file that is usable across multiple sketches. You would then write something like loadImage('shiffman/assets/cat.jpg') for accessing these files.

It's my feeling that option 1 would be so much easier to build and maintain, and therefore would be a good place to start. @therewasaguy I think is a bit inclined towards option 2 since it affords a lot of possibilities for sharing assets and saves on disk space.

I also wonder if there is a way we can secretly not duplicate files behind the scenes through the use of "hard links". To the user and to our web application, every single instance of a media file would look like a new instance as in option 1 above. However, when you "save as" or duplicate a sketch, no new data would be written to the hard disk, just a hard link would be made.

I do not feel experienced or knowledgable enough to make this decision and would love feedback. @therewasaguy please add your thoughts!

@therewasaguy
Copy link
Owner Author

I'm hesitant to make each "sketch" an actual directory of files (option 1), but I think our goal should be to make it appear that way to the user. And I think it might be possible!

I talked this over with @antiboredom who suggested using the html5 history API to add projectID info to the url, rather than hash (#101). If we do that, then the projectID would be part of the "referrer" url that gets sent to the server. So we could use that to serve the file that has that name and is part of that project. The actual file might be hosted in an Amazon S3 bucket, but the user doesn't need to know that and could use a relative url to load the file within their project.

I'd like to continue down this path I've started where multiple projects can refer to the same file in the database. This has helped save storage space, and made it faster to do things like "save as," because we only need to copy files if their contents have changed.

@therewasaguy
Copy link
Owner Author

One note for the above solution to work, the project would need to be saved because retrieving the proper files relies on the url having a projectID. That's probably fine as long as

  1. uploads are only enabled for logged-in users, and
  2. new projects are saved to the user's account by default ("New" sketch not saved to account by default #95).

@antiboredom
Copy link

Hey - actually you could still use s3. This might be the best solution: https://medium.com/@stockholmux/node-js-streams-proxies-and-amazon-s3-50b4fabdedbd#.75mqannyz

@REAS
Copy link

REAS commented Jan 12, 2016

From an interface perspective, have you checked out how they work with assets for the Scratch community? What about over at Studio Sketchpad?

@benfry
Copy link

benfry commented Jan 12, 2016

@shiffman asked for thoughts, here are mine:

I’d recommend something that has a simple free tier, i.e. S3 and Dropbox. Dropbox can work all client side via JS, if I’m not mistaken, but S3 (as noted above) will need a little on the backend. Another option would be using Github—much trickier to get working but much nicer payoff (version control, free hosting, etc).

But most important, it’s not something to reinvent (on the first round). All three of those give you something like a file system, just use it. The “sharing assets” feature would be a huge distraction for a first pass. Also agree w/ Casey’s comment about seeing what others are doing, though I’m guessing the answer will be “custom PHP + MySQL + local file system with quotas enforced somehow”.

@therewasaguy
Copy link
Owner Author

Thanks for the feedback!

@REAS, yes! If "assets" needs its own interface, Scratch's approach is a big inspiration. I also like how projects like Scratch, and the Khan editor, give every project access to some existing images and audio.

As I look into this more, I don't think we'll need to create a separate interface for uploading assets. Thimble has a good approach where "upload" is just another option for creating a new file.
screenshot 2016-01-12 10 52 46

When previewing a project in Thimble, the project assets—including JS and CSS files—are all blobs—raw file data that only exists on the clientside. I'm not sure how they resolve relative paths, but it only seems to work for html—I found that I wasn't able to use p5 methods like loadImage in their preview mode (example linked below). However, the relative paths resolve in JS when you publish a project because at that point the assets are saved on a server/filesystem like this.

@GoToLoop
Copy link

GoToLoop commented Aug 11, 2016

Is it already fixed? Any hope in sight? I'd like to loadJSON() from a tab. 😕

@therewasaguy
Copy link
Owner Author

Hi @GoToLoop, this repo is not in active development. Check out the new iteration of the project here: https://github.com/catarak/p5.js-web-editor

@GoToLoop
Copy link

Ah, OK. But it seems like there's no online version of it yet?

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

No branches or pull requests

6 participants