Skip to content

Commit

Permalink
feat: import listens from spotify extended streaming history (#305)
Browse files Browse the repository at this point in the history
  • Loading branch information
apricote authored Oct 1, 2023
1 parent 23d7ea0 commit 7140cb0
Show file tree
Hide file tree
Showing 50 changed files with 1,051 additions and 215 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@
!frontend/tsconfig.json
!frontend/vite.config.js
!frontend/index.html
!frontend/*.d.ts
!frontend/src/**/*
!frontend/public/**/*
5 changes: 0 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
# syntax=docker/dockerfile:1.5

FROM scratch as ignore

WORKDIR /listory
COPY . /listory/

##################
## common
##################
Expand Down
6 changes: 4 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ services:
OTEL_EXPORTER_OTLP_ENDPOINT: http://tempo:4318
env_file: .env
volumes:
- ./src:/app/src
- ./src:/app/src:ro
- ./dist:/app/dist # build cache
ports:
- 3000 # API
- "9464:9464" # Metrics
Expand Down Expand Up @@ -115,7 +116,8 @@ services:
OTEL_EXPORTER_OTLP_ENDPOINT: http://tempo:4318
env_file: .env
volumes:
- ./src:/app/src
- ./src:/app/src:ro
- ./dist:/app/dist # build cache
ports:
- "9464:9464" # Metrics
networks:
Expand Down
16 changes: 16 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"prettier": "3.0.3",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-files": "3.0.0",
"react-router-dom": "6.16.0",
"recharts": "2.8.0",
"tailwind-merge": "1.14.0",
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from "react";
import { Route, Routes } from "react-router-dom";
import { AuthApiTokens } from "./components/AuthApiTokens";
import { Footer } from "./components/Footer";
import { ImportListens } from "./components/ImportListens";
import { LoginFailure } from "./components/LoginFailure";
import { LoginLoading } from "./components/LoginLoading";
import { NavBar } from "./components/NavBar";
Expand Down Expand Up @@ -53,6 +54,7 @@ export function App() {
element={<ReportTopGenres />}
/>
<Route path="/auth/api-tokens" element={<AuthApiTokens />} />
<Route path="/import" element={<ImportListens />} />
</Routes>
)}
{!user && (
Expand Down
51 changes: 50 additions & 1 deletion frontend/src/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import { TopGenresItem } from "./entities/top-genres-item";
import { TopGenresOptions } from "./entities/top-genres-options";
import { TopTracksItem } from "./entities/top-tracks-item";
import { TopTracksOptions } from "./entities/top-tracks-options";
import { SpotifyExtendedStreamingHistoryItem } from "./entities/spotify-extended-streaming-history-item";
import { ExtendedStreamingHistoryStatus } from "./entities/extended-streaming-history-status";

export class UnauthenticatedError extends Error {}

Expand Down Expand Up @@ -276,7 +278,7 @@ export const revokeApiToken = async (
id: string,
client: AxiosInstance,
): Promise<void> => {
const res = await client.delete<NewApiToken>(`/api/v1/auth/api-tokens/${id}`);
const res = await client.delete(`/api/v1/auth/api-tokens/${id}`);

switch (res.status) {
case 200: {
Expand All @@ -290,3 +292,50 @@ export const revokeApiToken = async (
}
}
};

export const importExtendedStreamingHistory = async (
listens: SpotifyExtendedStreamingHistoryItem[],
client: AxiosInstance
): Promise<void> => {
const res = await client.post(`/api/v1/import/extended-streaming-history`, {
listens,
});

switch (res.status) {
case 201: {
break;
}
case 401: {
throw new UnauthenticatedError(`No token or token expired`);
}
default: {
throw new Error(
`Unable to importExtendedStreamingHistory: ${res.status}`
);
}
}
};

export const getExtendedStreamingHistoryStatus = async (
client: AxiosInstance
): Promise<ExtendedStreamingHistoryStatus> => {
const res = await client.get<ExtendedStreamingHistoryStatus>(
`/api/v1/import/extended-streaming-history/status`
);

switch (res.status) {
case 200: {
break;
}
case 401: {
throw new UnauthenticatedError(`No token or token expired`);
}
default: {
throw new Error(
`Unable to getExtendedStreamingHistoryStatus: ${res.status}`
);
}
}

return res.data;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface ExtendedStreamingHistoryStatus {
total: number;
imported: number;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface SpotifyExtendedStreamingHistoryItem {
ts: string;
spotify_track_uri: string;
}
1 change: 0 additions & 1 deletion frontend/src/components/AuthApiTokens.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { format, formatDistanceToNow } from "date-fns";
import React, { FormEvent, useCallback, useMemo, useState } from "react";
import { ApiToken, NewApiToken } from "../api/entities/api-token";
import { useApiTokens } from "../hooks/use-api";
import { useAuthProtection } from "../hooks/use-auth-protection";
import { SpinnerIcon } from "../icons/Spinner";
import TrashcanIcon from "../icons/Trashcan";
import { Spinner } from "./ui/Spinner";
Expand Down
Loading

0 comments on commit 7140cb0

Please sign in to comment.