enzostvs HF staff commited on
Commit
7e19cbb
1 Parent(s): fdd9b16

replace prisma blob saved with datasets

Browse files
app/api/collections/route.ts CHANGED
@@ -5,7 +5,7 @@ const prisma = new PrismaClient()
5
  export async function POST(request: Request) {
6
  const { ids, page } = await request.json()
7
 
8
- const images = await prisma.image.findMany({
9
  orderBy: {
10
  id: 'desc'
11
  },
@@ -18,11 +18,11 @@ export async function POST(request: Request) {
18
  skip: page * 15
19
  })
20
 
21
- const total = await prisma.image.count()
22
 
23
  return Response.json(
24
  {
25
- images,
26
  pagination: {
27
  total,
28
  page: page + 1,
 
5
  export async function POST(request: Request) {
6
  const { ids, page } = await request.json()
7
 
8
+ const collections = await prisma.collection.findMany({
9
  orderBy: {
10
  id: 'desc'
11
  },
 
18
  skip: page * 15
19
  })
20
 
21
+ const total = await prisma.collection.count()
22
 
23
  return Response.json(
24
  {
25
+ collections,
26
  pagination: {
27
  total,
28
  page: page + 1,
app/api/route.ts CHANGED
@@ -1,5 +1,7 @@
1
  import { PrismaClient } from '@prisma/client'
2
 
 
 
3
  const prisma = new PrismaClient()
4
 
5
  export async function POST(
@@ -43,11 +45,12 @@ export async function POST(
43
  if (isNSFW?.error && isNSFW?.estimated_time) {
44
  setTimeout(() => {
45
  checkIfIsNSFW(blob)
 
46
  }, isNSFW?.estimated_time * 100);
47
  } else resolve(isNSFW)
48
  })
49
  }
50
-
51
  const isNSFW: any = await checkIfIsNSFW(blob)
52
  if (isNSFW?.error) return Response.json({ status: 500, ok: false, message: isNSFW?.error });
53
  if (isNSFW?.length) {
@@ -56,17 +59,19 @@ export async function POST(
56
  return Response.json({ status: 401, ok: false, message: "Image is not safe for work." });
57
  }
58
  }
59
-
60
- const arrayBuffer = await blob.arrayBuffer()
61
- const bytes = Buffer.from(arrayBuffer)
62
 
63
- const new_blob = await prisma.image.create({
 
 
 
 
 
64
  data: {
65
  prompt: inputs,
66
- blob: bytes,
67
  },
68
  })
69
 
70
- return Response.json({ blob: new_blob, status: 200, ok: true, headers });
71
 
72
  }
 
1
  import { PrismaClient } from '@prisma/client'
2
 
3
+ import { UploaderDataset } from './uploader'
4
+
5
  const prisma = new PrismaClient()
6
 
7
  export async function POST(
 
45
  if (isNSFW?.error && isNSFW?.estimated_time) {
46
  setTimeout(() => {
47
  checkIfIsNSFW(blob)
48
+ console.log('retry')
49
  }, isNSFW?.estimated_time * 100);
50
  } else resolve(isNSFW)
51
  })
52
  }
53
+
54
  const isNSFW: any = await checkIfIsNSFW(blob)
55
  if (isNSFW?.error) return Response.json({ status: 500, ok: false, message: isNSFW?.error });
56
  if (isNSFW?.length) {
 
59
  return Response.json({ status: 401, ok: false, message: "Image is not safe for work." });
60
  }
61
  }
 
 
 
62
 
63
+ const name = Date.now() + `-${inputs.replace(/[^a-zA-Z0-9]/g, '-').slice(0, 10).toLowerCase()}`
64
+ const { ok, message } = await UploaderDataset(blob, name)
65
+
66
+ if (!ok) return Response.json({ status: 500, ok: false, message });
67
+
68
+ const new_image = await prisma.collection.create({
69
  data: {
70
  prompt: inputs,
71
+ file_name: name,
72
  },
73
  })
74
 
75
+ return Response.json({ image: new_image, status: 200, ok: true, headers });
76
 
77
  }
app/api/uploader.ts ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { uploadFiles } from "@huggingface/hub";
2
+ import type { RepoDesignation, Credentials } from "@huggingface/hub";
3
+
4
+ export const UploaderDataset = async (blob: Blob, name: string) => {
5
+ const repo: RepoDesignation = { type: "dataset", name: "enzostvs/stable-diffusion-tpu-generations" };
6
+ const credentials: Credentials = { accessToken: process.env.NEXT_PUBLIC_APP_HF_TOKEN as string };
7
+
8
+ const res: any = await uploadFiles({
9
+ repo,
10
+ credentials,
11
+ files: [
12
+ {
13
+ path: `images/${name}.png`,
14
+ content: blob,
15
+ },
16
+ ],
17
+ });
18
+
19
+ if (res?.error) return {
20
+ status: 500,
21
+ ok: false,
22
+ message: res?.error
23
+ };
24
+
25
+ return {
26
+ status: 200,
27
+ ok: true,
28
+ };
29
+
30
+ }
components/main/collections/collection.tsx CHANGED
@@ -20,12 +20,6 @@ export const Collection: React.FC<Props> = ({
20
  }) => {
21
  const { setPrompt } = useInputGeneration();
22
 
23
- const bufferToBase64 = useMemo(() => {
24
- const base64Flag = "data:image/jpeg;base64,";
25
- const imageStr = arrayBufferToBase64(collection.blob.data);
26
- return base64Flag + imageStr;
27
- }, [collection]);
28
-
29
  const formatDate = useMemo(() => {
30
  const date = new Date(collection.createdAt);
31
  return date.toLocaleDateString();
@@ -66,9 +60,9 @@ export const Collection: React.FC<Props> = ({
66
  </div>
67
  <div
68
  style={{
69
- backgroundImage: `url(${bufferToBase64})`,
70
  }}
71
- className="rounded-[33px] bg-red-400 bg-cover absolute top-0 left-0 w-full h-full z-[-1] transition-all duration-200 group-hover:scale-110 bg-center"
72
  />
73
  </motion.div>
74
  </div>
 
20
  }) => {
21
  const { setPrompt } = useInputGeneration();
22
 
 
 
 
 
 
 
23
  const formatDate = useMemo(() => {
24
  const date = new Date(collection.createdAt);
25
  return date.toLocaleDateString();
 
60
  </div>
61
  <div
62
  style={{
63
+ backgroundImage: `url(https://huggingface.co/datasets/enzostvs/stable-diffusion-tpu-generations/resolve/main/images/${collection.file_name}.png)`,
64
  }}
65
+ className="rounded-[33px] bg-gray-950 bg-cover absolute top-0 left-0 w-full h-full z-[-1] transition-all duration-200 group-hover:scale-110 bg-center"
66
  />
67
  </motion.div>
68
  </div>
components/main/hooks/useCollections.ts CHANGED
@@ -28,8 +28,9 @@ export const useCollections = (category: string) => {
28
  if (!response.ok) {
29
  throw new Error(data.message)
30
  }
 
31
  return {
32
- images: data?.images,
33
  pagination: data?.pagination,
34
  };
35
  },
 
28
  if (!response.ok) {
29
  throw new Error(data.message)
30
  }
31
+ console.log(data)
32
  return {
33
+ images: data?.collections,
34
  pagination: data?.pagination,
35
  };
36
  },
components/main/hooks/useInputGeneration.ts CHANGED
@@ -41,16 +41,12 @@ export const useInputGeneration = () => {
41
  if (!hasMadeFirstGeneration) setFirstGenerationDone()
42
  client.setQueryData(["collections"], (old: any) => {
43
  return {
44
- pagination: old.pagination,
45
  images: [{
46
  id,
47
  loading: true,
48
- blob: {
49
- type: "image/png",
50
- data: new ArrayBuffer(0),
51
- },
52
  prompt
53
- }, ...old.images as Image[]]
54
  }
55
  })
56
 
@@ -72,7 +68,7 @@ export const useInputGeneration = () => {
72
  newArray[index] = !data.ok ? {
73
  ...newArray[index],
74
  error: data.message
75
- } : data?.blob as Image
76
 
77
  return {
78
  ...old,
@@ -82,8 +78,8 @@ export const useInputGeneration = () => {
82
 
83
  if (!data.ok) return null
84
 
85
- setGenerationsId(myGenerationsId?.length ? [...myGenerationsId, data?.blob?.id] : [data?.blob?.id])
86
- setOpen(data?.blob?.id)
87
  return data ?? {}
88
  }
89
  )
 
41
  if (!hasMadeFirstGeneration) setFirstGenerationDone()
42
  client.setQueryData(["collections"], (old: any) => {
43
  return {
44
+ pagination: old?.pagination,
45
  images: [{
46
  id,
47
  loading: true,
 
 
 
 
48
  prompt
49
+ }, ...old?.images as Image[]]
50
  }
51
  })
52
 
 
68
  newArray[index] = !data.ok ? {
69
  ...newArray[index],
70
  error: data.message
71
+ } : data?.image as Image
72
 
73
  return {
74
  ...old,
 
78
 
79
  if (!data.ok) return null
80
 
81
+ setGenerationsId(myGenerationsId?.length ? [...myGenerationsId, data?.image?.id] : [data?.image?.id])
82
+ setOpen(data?.image?.id)
83
  return data ?? {}
84
  }
85
  )
components/modal/modal.tsx CHANGED
@@ -34,13 +34,6 @@ export const Modal: React.FC<Props> = ({ id, onClose }) => {
34
 
35
  if (!collection) return null;
36
 
37
- const bufferToBase64 = useMemo(() => {
38
- if (!collection) return;
39
- const base64Flag = "data:image/jpeg;base64,";
40
- const imageStr = arrayBufferToBase64(collection.blob.data);
41
- return base64Flag + imageStr;
42
- }, [collection]);
43
-
44
  const formatDate = useMemo(() => {
45
  if (!collection) return;
46
  const date = new Date(collection.createdAt);
@@ -64,7 +57,7 @@ export const Modal: React.FC<Props> = ({ id, onClose }) => {
64
  exit="exit"
65
  >
66
  <Image
67
- src={bufferToBase64 as string}
68
  alt="Generated image"
69
  className="object-center object-contain w-full h-full rounded-2xl"
70
  width={1024}
@@ -73,7 +66,7 @@ export const Modal: React.FC<Props> = ({ id, onClose }) => {
73
  <div
74
  className="bg-cover bg-center w-full h-full rounded-2xl bg-no-repeat z-[-1] absolute top-0 left-0 opacity-90 blur-xl"
75
  style={{
76
- backgroundImage: `url(${bufferToBase64})`,
77
  }}
78
  />
79
  <div className="text-left w-full px-4 pb-3 pt-2">
 
34
 
35
  if (!collection) return null;
36
 
 
 
 
 
 
 
 
37
  const formatDate = useMemo(() => {
38
  if (!collection) return;
39
  const date = new Date(collection.createdAt);
 
57
  exit="exit"
58
  >
59
  <Image
60
+ src={`https://huggingface.co/datasets/enzostvs/stable-diffusion-tpu-generations/resolve/main/images/${collection.file_name}.png?raw=true`}
61
  alt="Generated image"
62
  className="object-center object-contain w-full h-full rounded-2xl"
63
  width={1024}
 
66
  <div
67
  className="bg-cover bg-center w-full h-full rounded-2xl bg-no-repeat z-[-1] absolute top-0 left-0 opacity-90 blur-xl"
68
  style={{
69
+ backgroundImage: `url(https://huggingface.co/datasets/enzostvs/stable-diffusion-tpu-generations/resolve/main/images/${collection.file_name}.png?raw=true)`,
70
  }}
71
  />
72
  <div className="text-left w-full px-4 pb-3 pt-2">
next.config.js CHANGED
@@ -4,6 +4,14 @@ const nextConfig = {
4
  serverActions: true,
5
  serverComponentsExternalPackages: ['sharp', 'onnxruntime-node'],
6
  },
 
 
 
 
 
 
 
 
7
  }
8
 
9
  module.exports = nextConfig
 
4
  serverActions: true,
5
  serverComponentsExternalPackages: ['sharp', 'onnxruntime-node'],
6
  },
7
+ images: {
8
+ remotePatterns: [
9
+ {
10
+ protocol: "https",
11
+ hostname: "huggingface.co",
12
+ },
13
+ ],
14
+ },
15
  }
16
 
17
  module.exports = nextConfig
package-lock.json CHANGED
@@ -8,6 +8,7 @@
8
  "name": "hf-fast-image-generation",
9
  "version": "0.1.0",
10
  "dependencies": {
 
11
  "@prisma/client": "^5.5.2",
12
  "@tanstack/react-query": "^4.32.6",
13
  "classnames": "^2.3.2",
@@ -162,6 +163,17 @@
162
  "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
163
  }
164
  },
 
 
 
 
 
 
 
 
 
 
 
165
  "node_modules/@humanwhocodes/config-array": {
166
  "version": "0.11.13",
167
  "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
@@ -2496,6 +2508,11 @@
2496
  "url": "https://github.com/sponsors/ljharb"
2497
  }
2498
  },
 
 
 
 
 
2499
  "node_modules/hasown": {
2500
  "version": "2.0.0",
2501
  "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
 
8
  "name": "hf-fast-image-generation",
9
  "version": "0.1.0",
10
  "dependencies": {
11
+ "@huggingface/hub": "^0.11.3",
12
  "@prisma/client": "^5.5.2",
13
  "@tanstack/react-query": "^4.32.6",
14
  "classnames": "^2.3.2",
 
163
  "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
164
  }
165
  },
166
+ "node_modules/@huggingface/hub": {
167
+ "version": "0.11.3",
168
+ "resolved": "https://registry.npmjs.org/@huggingface/hub/-/hub-0.11.3.tgz",
169
+ "integrity": "sha512-GpdW09CQNgmZsSvVDlh7A1Vrr1NSfeEcAdtvRPaF9Cs6q2/6fywK0HInZHgrbPcXuawsnoIFvuePkboTol2Ttg==",
170
+ "dependencies": {
171
+ "hash-wasm": "^4.9.0"
172
+ },
173
+ "engines": {
174
+ "node": ">=18"
175
+ }
176
+ },
177
  "node_modules/@humanwhocodes/config-array": {
178
  "version": "0.11.13",
179
  "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
 
2508
  "url": "https://github.com/sponsors/ljharb"
2509
  }
2510
  },
2511
+ "node_modules/hash-wasm": {
2512
+ "version": "4.10.0",
2513
+ "resolved": "https://registry.npmjs.org/hash-wasm/-/hash-wasm-4.10.0.tgz",
2514
+ "integrity": "sha512-a0NjBNWjavvMalm/pPSEJ00MPDjRG8rv9D5BK7dBQTLGwAOVWqnTEUggaYs5szATB5UK5ULeIQr7QJXbczAZYA=="
2515
+ },
2516
  "node_modules/hasown": {
2517
  "version": "2.0.0",
2518
  "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
package.json CHANGED
@@ -9,6 +9,7 @@
9
  "lint": "next lint"
10
  },
11
  "dependencies": {
 
12
  "@prisma/client": "^5.5.2",
13
  "@tanstack/react-query": "^4.32.6",
14
  "classnames": "^2.3.2",
 
9
  "lint": "next lint"
10
  },
11
  "dependencies": {
12
+ "@huggingface/hub": "^0.11.3",
13
  "@prisma/client": "^5.5.2",
14
  "@tanstack/react-query": "^4.32.6",
15
  "classnames": "^2.3.2",
prisma/migrations/20231027162901_/migration.sql DELETED
@@ -1,7 +0,0 @@
1
- -- CreateTable
2
- CREATE TABLE "Image" (
3
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
4
- "prompt" TEXT NOT NULL,
5
- "blob" BLOB NOT NULL,
6
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
7
- );
 
 
 
 
 
 
 
 
prisma/migrations/migration_lock.toml DELETED
@@ -1,3 +0,0 @@
1
- # Please do not edit this file manually
2
- # It should be added in your version-control system (i.e. Git)
3
- provider = "sqlite"
 
 
 
 
prisma/schema.prisma CHANGED
@@ -7,9 +7,9 @@ datasource db {
7
  url = "file://data/dev.db"
8
  }
9
 
10
- model Image {
11
  id Int @id @default(autoincrement())
12
  prompt String
13
- blob Bytes
14
  createdAt DateTime @default(now())
15
  }
 
7
  url = "file://data/dev.db"
8
  }
9
 
10
+ model Collection {
11
  id Int @id @default(autoincrement())
12
  prompt String
13
+ file_name String
14
  createdAt DateTime @default(now())
15
  }
utils/type.ts CHANGED
@@ -9,10 +9,7 @@ export interface Collection {
9
 
10
  export interface Image {
11
  id: string;
12
- blob: {
13
- type: string;
14
- data: ArrayBuffer
15
- };
16
  prompt: string;
17
  createdAt: string;
18
  error?: string;
 
9
 
10
  export interface Image {
11
  id: string;
12
+ file_name: string;
 
 
 
13
  prompt: string;
14
  createdAt: string;
15
  error?: string;