enzostvs HF Staff commited on
Commit
d81515f
·
1 Parent(s): c47c635

add remix feature

Browse files
Files changed (2) hide show
  1. server.js +57 -13
  2. src/components/App.tsx +29 -1
server.js CHANGED
@@ -3,12 +3,19 @@ import path from "path";
3
  import { fileURLToPath } from "url";
4
  import dotenv from "dotenv";
5
  import cookieParser from "cookie-parser";
6
- import { createRepo, uploadFiles, whoAmI } from "@huggingface/hub";
 
 
 
 
 
 
7
  import { InferenceClient } from "@huggingface/inference";
8
  import bodyParser from "body-parser";
9
 
10
  import checkUser from "./middlewares/checkUser.js";
11
  import { PROVIDERS } from "./utils/providers.js";
 
12
 
13
  // Load environment variables from .env file
14
  dotenv.config();
@@ -30,6 +37,10 @@ app.use(cookieParser());
30
  app.use(bodyParser.json());
31
  app.use(express.static(path.join(__dirname, "dist")));
32
 
 
 
 
 
33
  app.get("/api/login", (_req, res) => {
34
  res.redirect(
35
  302,
@@ -103,18 +114,6 @@ app.post("/api/deploy", checkUser, async (req, res) => {
103
  });
104
  }
105
 
106
- let newHtml = html;
107
-
108
- if (!path) {
109
- newHtml = html.replace(
110
- /<\/body>/,
111
- `<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <a href="https://enzostvs-deepsite.hf.space" style="color: #fff;" target="_blank" >DeepSite</a> <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;"></p></body>`
112
- );
113
- }
114
-
115
- const file = new Blob([newHtml], { type: "text/html" });
116
- file.name = "index.html"; // Add name property to the Blob
117
-
118
  const { hf_token } = req.cookies;
119
  try {
120
  const repo = {
@@ -123,6 +122,7 @@ app.post("/api/deploy", checkUser, async (req, res) => {
123
  };
124
 
125
  let readme;
 
126
 
127
  if (!path || path === "") {
128
  const { name: username } = await whoAmI({ accessToken: hf_token });
@@ -136,6 +136,9 @@ app.post("/api/deploy", checkUser, async (req, res) => {
136
 
137
  const repoId = `${username}/${newTitle}`;
138
  repo.name = repoId;
 
 
 
139
  await createRepo({
140
  repo,
141
  accessToken: hf_token,
@@ -154,6 +157,9 @@ tags:
154
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference`;
155
  }
156
 
 
 
 
157
  const files = [file];
158
  if (readme) {
159
  const readmeFile = new Blob([readme], { type: "text/markdown" });
@@ -315,6 +321,44 @@ app.post("/api/ask-ai", async (req, res) => {
315
  }
316
  });
317
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
318
  app.get("*", (_req, res) => {
319
  res.sendFile(path.join(__dirname, "dist", "index.html"));
320
  });
 
3
  import { fileURLToPath } from "url";
4
  import dotenv from "dotenv";
5
  import cookieParser from "cookie-parser";
6
+ import {
7
+ createRepo,
8
+ uploadFiles,
9
+ whoAmI,
10
+ spaceInfo,
11
+ fileExists,
12
+ } from "@huggingface/hub";
13
  import { InferenceClient } from "@huggingface/inference";
14
  import bodyParser from "body-parser";
15
 
16
  import checkUser from "./middlewares/checkUser.js";
17
  import { PROVIDERS } from "./utils/providers.js";
18
+ import { type } from "os";
19
 
20
  // Load environment variables from .env file
21
  dotenv.config();
 
37
  app.use(bodyParser.json());
38
  app.use(express.static(path.join(__dirname, "dist")));
39
 
40
+ const getPTag = (repoId) => {
41
+ return `<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - <a href="https://enzostvs-deepsite.hf.space?remix=${repoId}" style="color: #fff;text-decoration: underline;" target="_blank" >🧬 Remix</a></p>`;
42
+ };
43
+
44
  app.get("/api/login", (_req, res) => {
45
  res.redirect(
46
  302,
 
114
  });
115
  }
116
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  const { hf_token } = req.cookies;
118
  try {
119
  const repo = {
 
122
  };
123
 
124
  let readme;
125
+ let newHtml = html;
126
 
127
  if (!path || path === "") {
128
  const { name: username } = await whoAmI({ accessToken: hf_token });
 
136
 
137
  const repoId = `${username}/${newTitle}`;
138
  repo.name = repoId;
139
+
140
+ newHtml = html.replace(/<\/body>/, `${getPTag(repoId)}</body>`);
141
+
142
  await createRepo({
143
  repo,
144
  accessToken: hf_token,
 
157
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference`;
158
  }
159
 
160
+ const file = new Blob([newHtml], { type: "text/html" });
161
+ file.name = "index.html"; // Add name property to the Blob
162
+
163
  const files = [file];
164
  if (readme) {
165
  const readmeFile = new Blob([readme], { type: "text/markdown" });
 
321
  }
322
  });
323
 
324
+ app.get("/api/remix/:username/:repo", async (req, res) => {
325
+ const { username, repo } = req.params;
326
+ const { hf_token } = req.cookies;
327
+
328
+ const token = hf_token || process.env.DEFAULT_HF_TOKEN;
329
+
330
+ const repoId = `${username}/${repo}`;
331
+ const space = await spaceInfo({
332
+ name: repoId,
333
+ });
334
+
335
+ console.log(space);
336
+
337
+ if (!space || space.sdk !== "static" || space.private) {
338
+ return res.status(404).send({
339
+ ok: false,
340
+ message: "Space not found",
341
+ });
342
+ }
343
+
344
+ const url = `https://huggingface.co/spaces/${repoId}/raw/main/index.html`;
345
+ const response = await fetch(url);
346
+ if (!response.ok) {
347
+ return res.status(404).send({
348
+ ok: false,
349
+ message: "Space not found",
350
+ });
351
+ }
352
+ let html = await response.text();
353
+ // remove the last p tag including this url https://enzostvs-deepsite.hf.space
354
+ html = html.replace(getPTag(repoId), "");
355
+
356
+ res.status(200).send({
357
+ ok: true,
358
+ html,
359
+ });
360
+ });
361
+
362
  app.get("*", (_req, res) => {
363
  res.sendFile(path.join(__dirname, "dist", "index.html"));
364
  });
src/components/App.tsx CHANGED
@@ -2,7 +2,13 @@ import { useRef, useState } from "react";
2
  import Editor from "@monaco-editor/react";
3
  import classNames from "classnames";
4
  import { editor } from "monaco-editor";
5
- import { useMount, useUnmount, useEvent, useLocalStorage } from "react-use";
 
 
 
 
 
 
6
  import { toast } from "react-toastify";
7
 
8
  import Header from "./header/header";
@@ -15,6 +21,9 @@ import Preview from "./preview/preview";
15
 
16
  function App() {
17
  const [htmlStorage, , removeHtmlStorage] = useLocalStorage("html_content");
 
 
 
18
 
19
  const preview = useRef<HTMLDivElement>(null);
20
  const editor = useRef<HTMLDivElement>(null);
@@ -40,6 +49,24 @@ function App() {
40
  }
41
  };
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  /**
44
  * Resets the layout based on screen size
45
  * - For desktop: Sets editor to 1/3 width and preview to 2/3
@@ -111,6 +138,7 @@ function App() {
111
  useMount(() => {
112
  // Fetch user data
113
  fetchMe();
 
114
 
115
  // Restore content from storage if available
116
  if (htmlStorage) {
 
2
  import Editor from "@monaco-editor/react";
3
  import classNames from "classnames";
4
  import { editor } from "monaco-editor";
5
+ import {
6
+ useMount,
7
+ useUnmount,
8
+ useEvent,
9
+ useLocalStorage,
10
+ useSearchParam,
11
+ } from "react-use";
12
  import { toast } from "react-toastify";
13
 
14
  import Header from "./header/header";
 
21
 
22
  function App() {
23
  const [htmlStorage, , removeHtmlStorage] = useLocalStorage("html_content");
24
+ const remix = useSearchParam("remix");
25
+
26
+ console.log("REMIX => ", remix);
27
 
28
  const preview = useRef<HTMLDivElement>(null);
29
  const editor = useRef<HTMLDivElement>(null);
 
49
  }
50
  };
51
 
52
+ const fetchRemix = async () => {
53
+ if (!remix) return;
54
+ const res = await fetch(`/api/remix/${remix}`);
55
+ if (res.ok) {
56
+ const data = await res.json();
57
+ if (data.html) {
58
+ setHtml(data.html);
59
+ toast.success("Remix content loaded successfully.");
60
+ }
61
+ // remove search param from url
62
+ const url = new URL(window.location.href);
63
+ url.searchParams.delete("remix");
64
+ window.history.replaceState({}, document.title, url.toString());
65
+ } else {
66
+ toast.error("Failed to load remix content.");
67
+ }
68
+ };
69
+
70
  /**
71
  * Resets the layout based on screen size
72
  * - For desktop: Sets editor to 1/3 width and preview to 2/3
 
138
  useMount(() => {
139
  // Fetch user data
140
  fetchMe();
141
+ fetchRemix();
142
 
143
  // Restore content from storage if available
144
  if (htmlStorage) {