Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions server/content.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,11 +257,20 @@ func searchContent(query string, pageNum int) (TMDBSearchMultiResponse, error) {
}

func searchMovies(query string, pageNum int) (TMDBSearchMoviesResponse, error) {
return searchMoviesWithYear(query, pageNum, 0)
}

func searchMoviesWithYear(query string, pageNum int, year int) (TMDBSearchMoviesResponse, error) {
resp := new(TMDBSearchMoviesResponse)
if pageNum == 0 {
pageNum = 1
}
err := tmdbRequest("/search/movie", map[string]string{"query": query, "page": strconv.Itoa(pageNum)}, &resp)
params := map[string]string{"query": query, "page": strconv.Itoa(pageNum)}
if year != 0 {
params["year"] = strconv.Itoa(year)
}
err := tmdbRequest("/search/movie", params, &resp)

if err != nil {
slog.Error("Failed to complete movie search request!", "error", err.Error())
return TMDBSearchMoviesResponse{}, errors.New("failed to complete movie search request")
Expand All @@ -273,11 +282,19 @@ func searchMovies(query string, pageNum int) (TMDBSearchMoviesResponse, error) {
}

func searchTv(query string, pageNum int) (TMDBSearchShowsResponse, error) {
return searchTvWithYear(query, pageNum, 0)
}

func searchTvWithYear(query string, pageNum int, year int) (TMDBSearchShowsResponse, error) {
resp := new(TMDBSearchShowsResponse)
if pageNum == 0 {
pageNum = 1
}
err := tmdbRequest("/search/tv", map[string]string{"query": query, "page": strconv.Itoa(pageNum)}, &resp)
params := map[string]string{"query": query, "page": strconv.Itoa(pageNum)}
if year != 0 {
params["year"] = strconv.Itoa(year)
}
err := tmdbRequest("/search/tv", params, &resp)
if err != nil {
slog.Error("Failed to complete tv search request!", "error", err.Error())
return TMDBSearchShowsResponse{}, errors.New("failed to complete tv search request")
Expand Down
77 changes: 69 additions & 8 deletions server/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type ImportRequest struct {
WatchedEpisodes []WatchedEpisode `json:"watchedEpisodes"`
WatchedSeason []WatchedSeason `json:"watchedSeasons"`
Tags []TagAddRequest `json:"tags"`
Year int `json:"year"`
}

type ImportResponse struct {
Expand Down Expand Up @@ -72,15 +73,75 @@ func importContent(db *gorm.DB, userId uint, ar ImportRequest) (ImportResponse,
}
}
// tmdbId not passed.. search for the content by name.
sr, err := searchContent(ar.Name, 1)
if err != nil {
slog.Error("import: content search failed", "error", err)
return ImportResponse{}, errors.New("Content search failed")
}
// if a type is passed, use that type to filter the search results.
pMatches := []TMDBSearchMultiResults{}
for _, r := range sr.Results {
if r.MediaType != "person" {
pMatches = append(pMatches, r)
if ar.Type == MOVIE {
movieRes, err := searchMoviesWithYear(ar.Name, 1, ar.Year)
if err != nil {
slog.Error("import: content search failed", "error", err)
return ImportResponse{}, errors.New("Content search failed")
}
for _, m := range movieRes.Results {
// Convert []int to []int64
genreIds := make([]int64, len(m.GenreIds))
for i, id := range m.GenreIds {
genreIds[i] = int64(id)
}
pMatches = append(pMatches, TMDBSearchMultiResults{
Adult: m.Adult,
BackdropPath: m.BackdropPath,
GenreIds: genreIds,
ID: m.ID,
OriginalLanguage: m.OriginalLanguage,
Overview: m.Overview,
Popularity: float32(m.Popularity),
PosterPath: m.PosterPath,
Title: m.Title,
VoteAverage: float32(m.VoteAverage),
VoteCount: uint32(m.VoteCount),
MediaType: "movie",
})
}
} else if ar.Type == SHOW {
tvRes, err := searchTvWithYear(ar.Name, 1, ar.Year)
if err != nil {
slog.Error("import: content search failed", "error", err)
return ImportResponse{}, errors.New("Content search failed")
}
for _, m := range tvRes.Results {
genreIds := make([]int64, len(m.GenreIds))
for i, id := range m.GenreIds {
genreIds[i] = int64(id)
}
pMatches = append(pMatches, TMDBSearchMultiResults{
Adult: m.Adult,
BackdropPath: m.BackdropPath,
GenreIds: genreIds,
ID: m.ID,
OriginalLanguage: m.OriginalLanguage,
OriginalName: m.OriginalName,
OriginCountry: m.OriginCountry,
Overview: m.Overview,
Popularity: float32(m.Popularity),
PosterPath: m.PosterPath,
FirstAirDate: m.FirstAirDate,
Name: m.Name,
VoteAverage: float32(m.VoteAverage),
VoteCount: uint32(m.VoteCount),
MediaType: "tv",
})
}
}
if len(pMatches) == 0 {
sr, err := searchContent(ar.Name, 1)
if err != nil {
slog.Error("import: content search failed", "error", err)
return ImportResponse{}, errors.New("Content search failed")
}
for _, r := range sr.Results {
if r.MediaType != "person" {
pMatches = append(pMatches, r)
}
}
}
resLen := len(pMatches)
Expand Down
11 changes: 11 additions & 0 deletions src/lib/Icon.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,17 @@
d="M490.18 181.4l-44.13-44.13a20 20 0 00-27-1 30.81 30.81 0 01-41.68-1.6 30.81 30.81 0 01-1.6-41.67 20 20 0 00-1-27L330.6 21.82a19.91 19.91 0 00-28.13 0l-70.35 70.34a39.87 39.87 0 00-9.57 15.5 7.71 7.71 0 01-4.83 4.83 39.78 39.78 0 00-15.5 9.58l-180.4 180.4a19.91 19.91 0 000 28.13L66 374.73a20 20 0 0027 1 30.69 30.69 0 0143.28 43.28 20 20 0 001 27l44.13 44.13a19.91 19.91 0 0028.13 0l180.4-180.4a39.82 39.82 0 009.58-15.49 7.69 7.69 0 014.84-4.84 39.84 39.84 0 0015.49-9.57l70.34-70.35a19.91 19.91 0 00-.01-28.09zm-228.37-29.65a16 16 0 01-22.63 0l-11.51-11.51a16 16 0 0122.63-22.62l11.51 11.5a16 16 0 010 22.63zm44 44a16 16 0 01-22.62 0l-11-11a16 16 0 1122.63-22.63l11 11a16 16 0 01.01 22.66zm44 44a16 16 0 01-22.63 0l-11-11a16 16 0 0122.63-22.62l11 11a16 16 0 01.05 22.67zm44.43 44.54a16 16 0 01-22.63 0l-11.44-11.5a16 16 0 1122.68-22.57l11.45 11.49a16 16 0 01-.01 22.63z"
/>
</svg>
{:else if i === "anilist"}
<svg xmlns="http://www.w3.org/2000/svg" width={wh} height={wh} viewBox="0 0 512 512">
<path
fill="#02a9ff"
d="M321.92 323.27V136.6c0-10.698-5.887-16.602-16.558-16.602h-36.433c-10.672 0-16.561 5.904-16.561 16.602v88.651c0 2.497 23.996 14.089 24.623 16.541 18.282 71.61 3.972 128.92-13.359 131.6 28.337 1.405 31.455 15.064 10.348 5.731 3.229-38.209 15.828-38.134 52.049-1.406.31.317 7.427 15.282 7.87 15.282h85.545c10.672 0 16.558-5.9 16.558-16.6v-36.524c0-10.698-5.886-16.602-16.558-16.602z"
/>
<path
fill="currentColor"
d="M170.68 120 74.999 393h74.338l16.192-47.222h80.96L262.315 393h73.968l-95.314-273zm11.776 165.28 23.183-75.629 25.393 75.629z"
/>
</svg>
{/if}

<style lang="scss">
Expand Down
87 changes: 76 additions & 11 deletions src/routes/(app)/import/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@
import { importedList } from "@/store";
import { onMount } from "svelte";
import papa from "papaparse";
import type {
ImportedList,
MovaryHistory,
MovaryRatings,
MovaryWatchlist,
Watched,
WatchedStatus,
TodoMoviesExport,
TagAddRequest,
TodoMoviesCustomList,
TodoMoviesMovie
import {
type ImportedList,
type MovaryHistory,
type MovaryRatings,
type MovaryWatchlist,
type Watched,
type WatchedStatus,
type TodoMoviesExport,
type TagAddRequest,
type TodoMoviesCustomList,
type TodoMoviesMovie
} from "@/types";
import Icon from "@/lib/Icon.svelte";

Expand Down Expand Up @@ -375,6 +375,65 @@
}
}

async function processAniListFile(files?: FileList | null) {
try {
console.log("processFilesAniList", files);
if (!files || files?.length <= 0) {
console.error("processFilesAniList", "No files to process!");
notify({
type: "error",
text: "File not found in dropped items. Please try again or refresh.",
time: 6000
});
isDragOver = false;
return;
}
isLoading = true;
if (files.length > 1) {
notify({
type: "error",
text: "Only one file at a time is supported. Continuing with the first.",
time: 6000
});
}

// Currently only support for importing one file at a time
const file = files[0];
if (file.type !== "" && !file.name.endsWith(".json")) {
notify({
type: "error",
text: "Must be a AniList GDPR Data Export (.json). https://anilist.co/gdpr/download"
});
isLoading = false;
isDragOver = false;
return;
}

// Read file data into strings
let exportAniListStr: string | undefined;
const r = new FileReader();
exportAniListStr = await readFile(r, file);
if (!exportAniListStr) {
notify({
type: "error",
text: "Failed to read export file. Ensure you have attached the correct file.",
time: 6000
});
}

importedList.set({
data: exportAniListStr,
type: "anilist"
});

goto("/import/process");
} catch (err) {
isLoading = false;
notify({ type: "error", text: "Failed to read files!" });
console.error("import: Failed to read files!", err);
}
}

async function processRyotFile(files?: FileList | null) {
try {
console.log("processRyotFile", files);
Expand Down Expand Up @@ -687,6 +746,12 @@
text="TodoMovies"
filesSelected={(f) => processTodoMoviesFile(f)}
/>

<DropFileButton
icon="anilist"
text="AniList"
filesSelected={(f) => processAniListFile(f)}
/>
{/if}
</div>
</div>
Expand Down
Loading