notebook icon indicating copy to clipboard operation
notebook copied to clipboard

Users should be able to export individual universes

Open drusepth opened this issue 7 years ago • 2 comments

Instead of always downloading your entire notebook, users should be able to just download a specific universe's content (or some selection of universes' content) instead.

drusepth avatar Oct 10 '16 12:10 drusepth

Some considerations on this issue:

  • I'd love to build this with two different options for the user: 1) users can select which universe(s) (if any) to export, and 2) users can then select what pages (e.g. characters, locations, and creatures) within that universe. For example, allowing users to export just characters and locations in a specific universe. After those are chosen, we should have our normal export formats available (txt, csv, json, etc).

  • Because of the long hierarchy of models storing page data (pages have many attribute categories, which have many attribute fields, which have many attribute values), we should try to keep N+1 queries to a minimum to ensure we can serve a fast response.

  • If the time it takes to generate an export is a problem (we time out all requests after 30 seconds), we could also generate exports in a background worker and upload them to S3, then send a user a notification when the export is finished. If we take this approach, we probably want to do a little extra UI work to list a user's previous exports to them.

  • The features we're planning to scale the feature on are content pages and output formats. It should be easy to add additional content pages (e.g. #29) to exports, and relatively easy to add additional export formats in the future as well.

drusepth avatar Oct 22 '21 00:10 drusepth

Implementation details:

Right now, basically the full export flow is handled through the ExportController, with each format being a separate endpoint (csv, json, outline, etc). This is a fair nonconfigurable approach that doesn't support options (like selecting which universes to export), so it might be worth replacing all of those endpoints with something more generic like a generate endpoint -- that accepts a format and other options, like a list of universes or a list of page types to export.

The options we want to ideally include for a customizing an export are:

  • Format (txt, csv, json, yaml, etc)
  • Universes (a list of universe IDs will do)
  • Page types (characters, locations, etc)

Because exports are inherently query-heavy, we should try to structure our queries to fetch as many rows as we can at a time, rather than getting things field-by-field, page-by-page. For example, rather than looping over pages and getting Attribute values for each field (like we do currently in the horribly-written private methods in ExportController!), we should probably instead be getting all Attribute rows for a specific user, or maybe a specific page -- and then filtering/processing as need be. Since we can stick all this in a background worker if we need to, processing time isn't super important -- but reducing the huge currently load of database queries per export would be great.

Since exports already time out for some power users, I think we can go ahead and skip the background worker (and therefore uploading to S3, notifications, etc) and just follow the general flow we already have (user clicks something for an export, waits a moment, and then starts downloading the file), albeit just with more options.

drusepth avatar Oct 27 '21 01:10 drusepth