Skip to content
Merged
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
84 changes: 84 additions & 0 deletions backend/src/importMetArtworks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { MongoClient } from "mongodb";

const mongoUri = process.env.MONGODB_URI;

if (!mongoUri) {
throw new Error("MONGODB_URI mangler");
}

const client = new MongoClient(mongoUri);

type MetArtwork = {
objectID: number;
title: string;
artistDisplayName: string;
objectDate: string;
primaryImageSmall: string;
isPublicDomain: boolean;
};

async function importArtworks() {
try {
await client.connect();

const database = client.db("artex");
const collection = database.collection("met_artworks");

const searchResponse = await fetch(
"https://collectionapi.metmuseum.org/public/collection/v1.1/search?hasImages=true&q=painting&limit=100",
);

if (!searchResponse.ok) {
throw new Error(`Search failed: ${searchResponse.status}`);
}

const searchData = (await searchResponse.json()) as {
objectIDs: number[] | null;
};

if (!searchData.objectIDs) {
throw new Error("Ingen kunstverk funnet");
}

let imported = 0;

for (const id of searchData.objectIDs) {
if (imported >= 20) break;

const response = await fetch(
`https://collectionapi.metmuseum.org/public/collection/v1/objects/${id}`,
);

if (!response.ok) continue;

const artwork = (await response.json()) as MetArtwork;

if (!artwork.isPublicDomain || !artwork.primaryImageSmall) {
continue;
}

await collection.updateOne(
{ id: artwork.objectID },
{
$set: {
id: artwork.objectID,
title: artwork.title,
artist_display: artwork.artistDisplayName,
date_display: artwork.objectDate,
image_url: artwork.primaryImageSmall,
},
},
{ upsert: true },
);

imported++;
console.log(`Imported ${imported}/20: ${artwork.title}`);
}

console.log(`Completed! Imported ${imported} artworks.`);
} finally {
await client.close();
}
}

importArtworks().catch(console.error);
19 changes: 16 additions & 3 deletions backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,36 @@ import { ApolloServer } from "@apollo/server";
import { startStandaloneServer } from "@apollo/server/standalone";
import { connectToDatabase } from "./db.js";

// Connect to MongoDB
const db = await connectToDatabase();

// Define the GraphQL schema
const typeDefs = `#graphql
type Artwork {
id: Int!
title: String!
artist_display: String
date_display: String
image_url: String
}
type Query {
hello: String!
artworks: [Artwork!]!
}
`;

// Define how queries are resolved
const resolvers = {
Query: {
hello: () => "Hello from Artex backend!",

artworks: async () => {
return await db.collection("met_artworks").find({}).toArray();
},
},
};

// Connect to MongoDB before starting the server
await connectToDatabase();

// Create the Apollo Server
const server = new ApolloServer({
typeDefs,
Expand Down
148 changes: 148 additions & 0 deletions frontend/package-lock.json

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

3 changes: 3 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
"preview": "vite preview"
},
"dependencies": {
"@apollo/client": "^4.3.3",
"@tailwindcss/vite": "^4.3.3",
"graphql": "^16.14.2",
"rxjs": "^7.8.2",
"lucide-react": "^1.57.0",
"react": "^19.2.8",
"react-dom": "^19.2.8",
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@

import { Routes, Route } from "react-router-dom";
import './index.css'
import HomePage from './pages/HomePage'
import Login from "./pages/login";
import Artworks from "./pages/Artworks";

function App() {

return (
<Routes>
<Route path="/" element={<HomePage />} />
Expand All @@ -13,4 +14,4 @@ function App() {
);
}

export default App
export default App;
Loading