Exporting
You need to have S3 configured to export your data. You can use this guide to set it up. The necessary configuration parameters can be found under the FileStorageConfig
section. The export will be made in JSON format and always follows the schema (CompleteExport
) described below.
You can export your data from the app by going to the "Imports and Exports" settings page and then clicking the button under the "Export" tab. Once the export is complete, it will appear along with a button to download it.
You can import it back using the Generic JSON Importer.
Exporting the entire database
While debugging, I might ask you to send me a database dump. You can do this by exporting the entire database and emailing the file.
bash
docker exec -u postgres -i ryot-db pg_dump -Fc --no-acl --no-owner > /tmp/ryot.file.sql
To restore the above dump, run the following command:
bash
docker exec -u postgres -i ryot-db pg_restore -U postgres -d postgres < /tmp/ryot.file.sql
Type definitions
ts
// Automatically generated by schematic. DO NOT MODIFY!
/* eslint-disable */
export interface IdAndNamedObject {
id: string;
name: string;
}
export interface UserToCollectionExtraInformation {
isHidden: boolean | null;
}
export interface CollectionItemCollaboratorInformation {
collaborator: IdAndNamedObject;
extraInformation: UserToCollectionExtraInformation | null;
}
export type CollectionExtraInformationLot = 'date' | 'number' | 'string' | 'boolean' | 'date-time' | 'string-array';
export interface CollectionExtraInformation {
defaultValue: string | null;
description: string;
/**
* @default 'string'
* @type {'date' | 'number' | 'string' | 'boolean' | 'date-time' | 'string-array'}
*/
lot: CollectionExtraInformationLot;
name: string;
possibleValues: string[] | null;
required: boolean | null;
}
export interface CollectionItem {
collaborators: CollectionItemCollaboratorInformation[];
count: number;
creator: IdAndNamedObject;
description: string | null;
id: string;
informationTemplate: CollectionExtraInformation[] | null;
isDefault: boolean;
name: string;
}
export interface CollectionToEntityDetails {
collectionId: string;
collectionName: string;
createdOn: string;
creatorUserId: string;
information: unknown | null;
lastUpdatedOn: string;
/** The rank of this entity in the collection. This is ignored during importing. */
rank?: string;
}
/** Comments left in replies to posted reviews. */
export interface ImportOrExportItemReviewComment {
created_on: string;
id: string;
/** The user ids of all those who liked it. */
liked_by: string[];
text: string;
user: IdAndNamedObject;
}
export type Visibility = 'public' | 'private';
/** Review data associated to a rating. */
export interface ImportOrExportItemReview {
/** The date the review was posted. */
date: string | null;
/** Whether to mark the review as a spoiler. Defaults to false. */
spoiler: boolean | null;
/** Actual text for the review. */
text: string | null;
/**
* The visibility set by the user.
*
* @default 'public'
*/
visibility: Visibility | null;
}
/** A rating given to an entity. */
export interface ImportOrExportItemRating {
/** If for an anime, the episode for which this review was for. */
anime_episode_number: number | null;
/** The comments attached to this review. */
comments: ImportOrExportItemReviewComment[] | null;
/** If for a manga, the chapter for which this review was for. */
manga_chapter_number: string | null;
/** If for a podcast, the episode for which this review was for. */
podcast_episode_number: number | null;
/** The score of the review. */
rating: string | null;
/** Data about the review. */
review: ImportOrExportItemReview | null;
/** If for a show, the episode for which this review was for. */
show_episode_number: number | null;
/** If for a show, the season for which this review was for. */
show_season_number: number | null;
}
/** Details about a specific exercise item that needs to be exported. */
export interface ImportOrExportExerciseItem {
/** The collections this entity was added to. */
collections: CollectionToEntityDetails[];
/** The unique identifier of the exercise. */
id: string;
/** The name of the exercise. */
name: string;
/** The review history for the user. */
reviews: ImportOrExportItemRating[];
}
export type EntityRemoteVideoSource = 'youtube' | 'dailymotion';
/** The data that a remote video can have. */
export interface EntityRemoteVideo {
/**
* @default 'youtube'
* @type {'youtube' | 'dailymotion'}
*/
source: EntityRemoteVideoSource;
url: string;
}
/** The assets related to an entity. */
export interface EntityAssets {
/** The urls of the remote images. */
remote_images: string[];
/** The urls of the remote videos. */
remote_videos: EntityRemoteVideo[];
/** The keys of the S3 images. */
s3_images: string[];
/** The keys of the S3 videos. */
s3_videos: string[];
}
export interface UserMeasurementStatistic {
name: string;
value: string;
}
/** The actual statistics that were logged in a user measurement. */
export interface UserMeasurementInformation {
assets: EntityAssets;
statistics: UserMeasurementStatistic[];
}
/** An export of a measurement taken at a point in time. */
export interface UserMeasurement {
/** Any comment associated entered by the user. */
comment: string | null;
/** The contents of the actual measurement. */
information: UserMeasurementInformation;
/** The name given to this measurement by the user. */
name: string | null;
/** The date and time this measurement was made. */
timestamp: string;
}
/** The different types of media that can be stored. */
export type MediaLot = 'book' | 'show' | 'movie' | 'anime' | 'manga' | 'music' | 'podcast' | 'audio_book' | 'video_game' | 'visual_novel';
/** A specific instance when an entity was seen. */
export interface ImportOrExportMetadataItemSeen {
/** If for an anime, the episode which was seen. */
anime_episode_number: number | null;
/** The timestamp when finished watching. */
ended_on: string | null;
/** If for a manga, the chapter which was seen. */
manga_chapter_number: string | null;
/** If for a manga, the volume which was seen. */
manga_volume_number: number | null;
/** If for a podcast, the episode which was seen. */
podcast_episode_number: number | null;
/** The progress of media done. If none, it is considered as done. */
progress: string | null;
/** The providers this item was watched on. */
providers_consumed_on: string[] | null;
/** If for a show, the episode which was seen. */
show_episode_number: number | null;
/** If for a show, the season which was seen. */
show_season_number: number | null;
/** The timestamp when started watching. */
started_on: string | null;
}
/** The different sources (or providers) from which data can be obtained from. */
export type MediaSource = 'igdb' | 'tmdb' | 'vndb' | 'custom' | 'itunes' | 'anilist' | 'audible' | 'spotify' | 'giant_bomb' | 'hardcover' | 'myanimelist' | 'listennotes' | 'google_books' | 'openlibrary' | 'manga_updates' | 'youtube_music';
/** Details about a specific media item that needs to be imported or exported. */
export interface ImportOrExportMetadataItem {
/** The collections this entity was added to. */
collections: CollectionToEntityDetails[];
/** The provider identifier. For eg: TMDB-ID, Openlibrary ID and so on. */
identifier: string;
/**
* The type of media.
*
* @default 'book'
* @type {'book' | 'show' | 'movie' | 'anime' | 'manga' | 'music' | 'podcast' | 'audio_book' | 'video_game' | 'visual_novel'}
*/
lot: MediaLot;
/** The review history for the user. */
reviews: ImportOrExportItemRating[];
/** The seen history for the user. */
seen_history: ImportOrExportMetadataItemSeen[];
/**
* The source of media.
*
* @default 'custom'
* @type {'igdb' | 'tmdb' | 'vndb' | 'custom' | 'itunes' | 'anilist' | 'audible' | 'spotify' | 'giant_bomb' | 'hardcover' | 'myanimelist' | 'listennotes' | 'google_books' | 'openlibrary' | 'manga_updates' | 'youtube_music'}
*/
source: MediaSource;
/** An string to help identify it in the original source. */
source_id: string;
}
/** Details about a specific media group item that needs to be imported or exported. */
export interface ImportOrExportMetadataGroupItem {
/** The collections this entity was added to. */
collections: CollectionToEntityDetails[];
/** The provider identifier. For eg: TMDB-ID, Openlibrary ID and so on. */
identifier: string;
/**
* The type of media.
*
* @default 'book'
* @type {'book' | 'show' | 'movie' | 'anime' | 'manga' | 'music' | 'podcast' | 'audio_book' | 'video_game' | 'visual_novel'}
*/
lot: MediaLot;
/** The review history for the user. */
reviews: ImportOrExportItemRating[];
/**
* The source of media.
*
* @default 'custom'
* @type {'igdb' | 'tmdb' | 'vndb' | 'custom' | 'itunes' | 'anilist' | 'audible' | 'spotify' | 'giant_bomb' | 'hardcover' | 'myanimelist' | 'listennotes' | 'google_books' | 'openlibrary' | 'manga_updates' | 'youtube_music'}
*/
source: MediaSource;
/** Name of the group. */
title: string;
}
export interface PersonSourceSpecifics {
is_anilist_studio: boolean | null;
is_giant_bomb_company: boolean | null;
is_hardcover_publisher: boolean | null;
is_tmdb_company: boolean | null;
}
/** Details about a specific creator item that needs to be exported. */
export interface ImportOrExportPersonItem {
/** The collections this entity was added to. */
collections: CollectionToEntityDetails[];
/** The provider identifier. */
identifier: string;
/** The name of the creator. */
name: string;
/** The review history for the user. */
reviews: ImportOrExportItemRating[];
/**
* The source of data.
*
* @default 'custom'
* @type {'igdb' | 'tmdb' | 'vndb' | 'custom' | 'itunes' | 'anilist' | 'audible' | 'spotify' | 'giant_bomb' | 'hardcover' | 'myanimelist' | 'listennotes' | 'google_books' | 'openlibrary' | 'manga_updates' | 'youtube_music'}
*/
source: MediaSource;
/** The source specific data. */
source_specifics: PersonSourceSpecifics | null;
}
/** The different types of exercises that can be done. */
export type ExerciseLot = 'reps' | 'duration' | 'reps_and_weight' | 'reps_and_duration' | 'distance_and_duration' | 'reps_and_duration_and_distance';
/** The types of set (mostly characterized by exertion level). */
export type SetLot = 'normal' | 'warm_up' | 'drop' | 'failure';
/** The different types of personal bests that can be achieved on a set. */
export type WorkoutSetPersonalBest = 'time' | 'pace' | 'reps' | 'one_rm' | 'volume' | 'weight' | 'distance';
/** Details about the statistics of the set performed. */
export interface WorkoutSetStatistic {
distance: string | null;
duration: string | null;
one_rm: string | null;
pace: string | null;
reps: string | null;
volume: string | null;
weight: string | null;
}
export interface WorkoutSetTotals {
weight: string | null;
}
/** Details about the set performed. */
export interface WorkoutSetRecord {
confirmed_at: string | null;
/**
* @default 'normal'
* @type {'normal' | 'warm_up' | 'drop' | 'failure'}
*/
lot: SetLot;
note: string | null;
personal_bests: WorkoutSetPersonalBest[] | null;
rest_time: number | null;
rest_timer_started_at: string | null;
rpe: number | null;
statistic: WorkoutSetStatistic;
totals: WorkoutSetTotals | null;
}
/** The totals of a workout and the different bests achieved. */
export interface WorkoutOrExerciseTotals {
distance: string;
duration: string;
/** The number of personal bests achieved. */
personal_bests_achieved: number;
reps: string;
/** The total seconds that were logged in the rest timer. */
rest_time?: number;
weight: string;
}
export type UserUnitSystem = 'metric' | 'imperial';
/** An exercise that has been processed and committed to the database. */
export interface ProcessedExercise {
assets: EntityAssets | null;
id: string;
/**
* @default 'reps_and_weight'
* @type {'reps' | 'duration' | 'reps_and_weight' | 'reps_and_duration' | 'distance_and_duration' | 'reps_and_duration_and_distance'}
*/
lot: ExerciseLot;
notes: string[];
sets: WorkoutSetRecord[];
total: WorkoutOrExerciseTotals | null;
/**
* @default 'metric'
* @type {'metric' | 'imperial'}
*/
unit_system: UserUnitSystem;
}
export interface WorkoutSupersetsInformation {
/** A color that will be displayed on the frontend. */
color: string;
/** The identifier of all the exercises which are in the same superset */
exercises: number[];
}
/** Information about a workout done. */
export interface WorkoutInformation {
assets: EntityAssets | null;
comment: string | null;
exercises: ProcessedExercise[];
supersets: WorkoutSupersetsInformation[];
}
/** The summary about an exercise done in a workout. */
export interface WorkoutSummaryExercise {
best_set: WorkoutSetRecord | null;
id: string;
/** @default 'reps_and_weight' */
lot: ExerciseLot | null;
num_sets: number;
/**
* @default 'metric'
* @type {'metric' | 'imperial'}
*/
unit_system: UserUnitSystem;
}
export type ExerciseEquipment = 'bands' | 'cable' | 'other' | 'barbell' | 'machine' | 'body_only' | 'dumbbell' | 'foam_roll' | 'ez_curl_bar' | 'kettlebells' | 'exercise_ball' | 'medicine_ball';
export interface WorkoutEquipmentFocusedSummary {
/**
* @default 'barbell'
* @type {'bands' | 'cable' | 'other' | 'barbell' | 'machine' | 'body_only' | 'dumbbell' | 'foam_roll' | 'ez_curl_bar' | 'kettlebells' | 'exercise_ball' | 'medicine_ball'}
*/
equipment: ExerciseEquipment;
exercises: number[];
}
export type ExerciseForce = 'pull' | 'push' | 'static';
export interface WorkoutForceFocusedSummary {
exercises: number[];
/**
* @default 'pull'
* @type {'pull' | 'push' | 'static'}
*/
force: ExerciseForce;
}
export type ExerciseLevel = 'beginner' | 'expert' | 'intermediate';
export interface WorkoutLevelFocusedSummary {
exercises: number[];
/**
* @default 'beginner'
* @type {'beginner' | 'expert' | 'intermediate'}
*/
level: ExerciseLevel;
}
export interface WorkoutLotFocusedSummary {
exercises: number[];
/**
* @default 'reps_and_weight'
* @type {'reps' | 'duration' | 'reps_and_weight' | 'reps_and_duration' | 'distance_and_duration' | 'reps_and_duration_and_distance'}
*/
lot: ExerciseLot;
}
export type ExerciseMuscle = 'lats' | 'neck' | 'traps' | 'chest' | 'biceps' | 'calves' | 'glutes' | 'triceps' | 'forearms' | 'abductors' | 'adductors' | 'lower_back' | 'shoulders' | 'abdominals' | 'hamstrings' | 'middle_back' | 'quadriceps';
export interface WorkoutMuscleFocusedSummary {
exercises: number[];
/**
* @default 'abdominals'
* @type {'lats' | 'neck' | 'traps' | 'chest' | 'biceps' | 'calves' | 'glutes' | 'triceps' | 'forearms' | 'abductors' | 'adductors' | 'lower_back' | 'shoulders' | 'abdominals' | 'hamstrings' | 'middle_back' | 'quadriceps'}
*/
muscle: ExerciseMuscle;
}
export interface WorkoutFocusedSummary {
equipments: WorkoutEquipmentFocusedSummary[];
forces: WorkoutForceFocusedSummary[];
levels: WorkoutLevelFocusedSummary[];
lots: WorkoutLotFocusedSummary[];
muscles: WorkoutMuscleFocusedSummary[];
}
export interface WorkoutSummary {
exercises: WorkoutSummaryExercise[];
focused: WorkoutFocusedSummary;
total: WorkoutOrExerciseTotals | null;
}
export interface WorkoutTemplate {
created_on: string;
id: string;
information: WorkoutInformation;
name: string;
summary: WorkoutSummary;
}
export interface ImportOrExportWorkoutTemplateItem {
collections: CollectionToEntityDetails[];
details: WorkoutTemplate;
}
/** A workout that was completed by the user. */
export interface Workout {
calories_burnt: string | null;
duration: number;
end_time: string;
id: string;
information: WorkoutInformation;
name: string;
start_time: string;
summary: WorkoutSummary;
template_id: string | null;
}
/** Details about a specific exercise item that needs to be exported. */
export interface ImportOrExportWorkoutItem {
/** The collections this entity was added to. */
collections: CollectionToEntityDetails[];
/** The details of the workout. */
details: Workout;
}
/** Complete export of the user. */
export interface CompleteExport {
/** Data about user's collections. */
collections: CollectionItem[] | null;
/** Data about user's exercises. */
exercises: ImportOrExportExerciseItem[] | null;
/** Data about user's measurements. */
measurements: UserMeasurement[] | null;
/** Data about user's media. */
metadata: ImportOrExportMetadataItem[] | null;
/** Data about user's media groups. */
metadata_groups: ImportOrExportMetadataGroupItem[] | null;
/** Data about user's people. */
people: ImportOrExportPersonItem[] | null;
/** Data about user's workout templates. */
workout_templates: ImportOrExportWorkoutTemplateItem[] | null;
/** Data about user's workouts. */
workouts: ImportOrExportWorkoutItem[] | null;
}