openfree commited on
Commit
cd1d350
ยท
verified ยท
1 Parent(s): 8afc77e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +99 -98
app.py CHANGED
@@ -1,95 +1,4 @@
1
- function addBatchUrls() {
2
- const textarea = document.getElementById('batch-urls');
3
- const text = textarea.value.trim();
4
-
5
- if (!text) {
6
- showStatus('add-status', 'Please enter at least one URL', false);
7
- return;
8
- }
9
-
10
- // Split by newlines and filter out empty lines
11
- let urls = text.split(/\r?\n/).filter(url => url.trim() !== '');
12
-
13
- // Limit to 100 URLs
14
- if (urls.length > 100) {
15
- showStatus('add-status', 'Too many URLs. Limited to 100 at once.', false);
16
- urls = urls.slice(0, 100);
17
- }
18
-
19
- if (urls.length === 0) {
20
- showStatus('add-status', 'No valid URLs found', false);
21
- return;
22
- }
23
-
24
- // Show progress bar
25
- const progressBar = document.getElementById('progress-bar');
26
- const progressFill = document.getElementById('progress-fill');
27
- const progressText = document.getElementById('progress-text');
28
- progressBar.style.display = 'block';
29
- progressFill.style.width = '0%';
30
- progressText.textContent = '0%';
31
-
32
- // Add URLs one by one
33
- let processed = 0;
34
- let succeeded = 0;
35
-
36
- function updateProgress() {
37
- const percentage = Math.round((processed / urls.length) * 100);
38
- progressFill.style.width = percentage + '%';
39
- progressText.textContent = `${processed}/${urls.length} (${percentage}%)`;
40
- }
41
-
42
- function addNextUrl(index) {
43
- if (index >= urls.length) {
44
- // All done
45
- setTimeout(() => {
46
- progressBar.style.display = 'none';
47
- textarea.value = '';
48
- showStatus('add-status', `Added ${succeeded} of ${urls.length} URLs successfully`, true);
49
-
50
- // Reload URL list and favorites
51
- loadUrlList();
52
- if (active === 'Favorites') {
53
- loadFavorites(currentPage);
54
- }
55
- }, 500);
56
- return;
57
- }
58
-
59
- const url = urls[index].trim();
60
- if (!url) {
61
- // Skip empty URLs
62
- processed++;
63
- updateProgress();
64
- addNextUrl(index + 1);
65
- return;
66
- }
67
-
68
- const formData = new FormData();
69
- formData.append('url', url);
70
-
71
- makeRequest('/api/url/add', 'POST', formData, function(data) {
72
- processed++;
73
-
74
- if (data.success) {
75
- succeeded++;
76
-
77
- // Update localStorage
78
- const localUrls = loadFromLocalStorage() || [];
79
- if (!localUrls.includes(url)) {
80
- localUrls.unshift(url);
81
- saveToLocalStorage(localUrls);
82
- }
83
- }
84
-
85
- updateProgress();
86
- addNextUrl(index + 1);
87
- });
88
- }
89
-
90
- // Start adding URLs
91
- addNextUrl(0);
92
- }from flask import Flask, render_template, request, jsonify
93
  import os, re, json, sqlite3, logging
94
 
95
  app = Flask(__name__)
@@ -113,7 +22,7 @@ BLOCKED_DOMAINS = [
113
 
114
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 2. CURATED CATEGORIES โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
115
  CATEGORIES = {
116
- "Productivity": [
117
  "https://huggingface.co/spaces/ginigen/perflexity-clone",
118
  "https://huggingface.co/spaces/ginipick/IDEA-DESIGN",
119
  "https://huggingface.co/spaces/VIDraft/mouse-webgen",
@@ -124,7 +33,7 @@ CATEGORIES = {
124
  "https://huggingface.co/spaces/fantaxy/Space-Leaderboard",
125
  "https://huggingface.co/spaces/openfree/Korean-Leaderboard",
126
  ],
127
- "Multimodal": [
128
  "https://huggingface.co/spaces/openfree/DreamO-video",
129
  "https://huggingface.co/spaces/Heartsync/NSFW-Uncensored-photo",
130
  "https://huggingface.co/spaces/Heartsync/NSFW-Uncensored",
@@ -134,7 +43,7 @@ CATEGORIES = {
134
  "https://huggingface.co/spaces/aiqcamp/MCP-kokoro",
135
  "https://huggingface.co/spaces/aiqcamp/ENGLISH-Speaking-Scoring",
136
  ],
137
- "Professional": [
138
  "https://huggingface.co/spaces/ginigen/blogger",
139
  "https://huggingface.co/spaces/VIDraft/money-radar",
140
  "https://huggingface.co/spaces/immunobiotech/drug-discovery",
@@ -144,7 +53,7 @@ CATEGORIES = {
144
  "https://huggingface.co/spaces/ginipick/AgentX-Papers",
145
  "https://huggingface.co/spaces/openfree/Cycle-Navigator",
146
  ],
147
- "Image": [
148
  "https://huggingface.co/spaces/ginigen/interior-design",
149
  "https://huggingface.co/spaces/ginigen/Workflow-Canvas",
150
  "https://huggingface.co/spaces/ginigen/Multi-LoRAgen",
@@ -158,7 +67,7 @@ CATEGORIES = {
158
  "https://huggingface.co/spaces/VIDraft/Open-Meme-Studio",
159
  "https://huggingface.co/spaces/ginigen/3D-LLAMA",
160
  ],
161
- "LLM / VLM": [
162
  "https://huggingface.co/spaces/VIDraft/Gemma-3-R1984-4B",
163
  "https://huggingface.co/spaces/VIDraft/Gemma-3-R1984-12B",
164
  "https://huggingface.co/spaces/ginigen/Mistral-Perflexity",
@@ -921,7 +830,6 @@ function loadUrlList() {
921
  urlList.innerHTML = html;
922
  });
923
  }
924
- }
925
 
926
  function addUrl() {
927
  const url = document.getElementById('new-url').value.trim();
@@ -955,6 +863,99 @@ function addUrl() {
955
  });
956
  }
957
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
958
  function editUrl(url) {
959
  // Decode URL if it was previously escaped
960
  const decodedUrl = url.replace(/\\'/g, "'");
 
1
+ from flask import Flask, render_template, request, jsonify
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  import os, re, json, sqlite3, logging
3
 
4
  app = Flask(__name__)
 
22
 
23
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 2. CURATED CATEGORIES โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
24
  CATEGORIES = {
25
+ "Free AI: Productivity": [
26
  "https://huggingface.co/spaces/ginigen/perflexity-clone",
27
  "https://huggingface.co/spaces/ginipick/IDEA-DESIGN",
28
  "https://huggingface.co/spaces/VIDraft/mouse-webgen",
 
33
  "https://huggingface.co/spaces/fantaxy/Space-Leaderboard",
34
  "https://huggingface.co/spaces/openfree/Korean-Leaderboard",
35
  ],
36
+ "Free AI: Multimodal": [
37
  "https://huggingface.co/spaces/openfree/DreamO-video",
38
  "https://huggingface.co/spaces/Heartsync/NSFW-Uncensored-photo",
39
  "https://huggingface.co/spaces/Heartsync/NSFW-Uncensored",
 
43
  "https://huggingface.co/spaces/aiqcamp/MCP-kokoro",
44
  "https://huggingface.co/spaces/aiqcamp/ENGLISH-Speaking-Scoring",
45
  ],
46
+ "Free AI: Professional": [
47
  "https://huggingface.co/spaces/ginigen/blogger",
48
  "https://huggingface.co/spaces/VIDraft/money-radar",
49
  "https://huggingface.co/spaces/immunobiotech/drug-discovery",
 
53
  "https://huggingface.co/spaces/ginipick/AgentX-Papers",
54
  "https://huggingface.co/spaces/openfree/Cycle-Navigator",
55
  ],
56
+ "Free AI: Image": [
57
  "https://huggingface.co/spaces/ginigen/interior-design",
58
  "https://huggingface.co/spaces/ginigen/Workflow-Canvas",
59
  "https://huggingface.co/spaces/ginigen/Multi-LoRAgen",
 
67
  "https://huggingface.co/spaces/VIDraft/Open-Meme-Studio",
68
  "https://huggingface.co/spaces/ginigen/3D-LLAMA",
69
  ],
70
+ "Free AI: LLM / VLM": [
71
  "https://huggingface.co/spaces/VIDraft/Gemma-3-R1984-4B",
72
  "https://huggingface.co/spaces/VIDraft/Gemma-3-R1984-12B",
73
  "https://huggingface.co/spaces/ginigen/Mistral-Perflexity",
 
830
  urlList.innerHTML = html;
831
  });
832
  }
 
833
 
834
  function addUrl() {
835
  const url = document.getElementById('new-url').value.trim();
 
863
  });
864
  }
865
 
866
+ function addBatchUrls() {
867
+ const textarea = document.getElementById('batch-urls');
868
+ const text = textarea.value.trim();
869
+
870
+ if (!text) {
871
+ showStatus('add-status', 'Please enter at least one URL', false);
872
+ return;
873
+ }
874
+
875
+ // Split by newlines and filter out empty lines
876
+ let urls = text.split(/\r?\n/).filter(url => url.trim() !== '');
877
+
878
+ // Limit to 100 URLs
879
+ if (urls.length > 100) {
880
+ showStatus('add-status', 'Too many URLs. Limited to 100 at once.', false);
881
+ urls = urls.slice(0, 100);
882
+ }
883
+
884
+ if (urls.length === 0) {
885
+ showStatus('add-status', 'No valid URLs found', false);
886
+ return;
887
+ }
888
+
889
+ // Show progress bar
890
+ const progressBar = document.getElementById('progress-bar');
891
+ const progressFill = document.getElementById('progress-fill');
892
+ const progressText = document.getElementById('progress-text');
893
+ progressBar.style.display = 'block';
894
+ progressFill.style.width = '0%';
895
+ progressText.textContent = '0%';
896
+
897
+ // Add URLs one by one
898
+ let processed = 0;
899
+ let succeeded = 0;
900
+
901
+ function updateProgress() {
902
+ const percentage = Math.round((processed / urls.length) * 100);
903
+ progressFill.style.width = percentage + '%';
904
+ progressText.textContent = `${processed}/${urls.length} (${percentage}%)`;
905
+ }
906
+
907
+ function addNextUrl(index) {
908
+ if (index >= urls.length) {
909
+ // All done
910
+ setTimeout(() => {
911
+ progressBar.style.display = 'none';
912
+ textarea.value = '';
913
+ showStatus('add-status', `Added ${succeeded} of ${urls.length} URLs successfully`, true);
914
+
915
+ // Reload URL list and favorites
916
+ loadUrlList();
917
+ if (active === 'Favorites') {
918
+ loadFavorites(currentPage);
919
+ }
920
+ }, 500);
921
+ return;
922
+ }
923
+
924
+ const url = urls[index].trim();
925
+ if (!url) {
926
+ // Skip empty URLs
927
+ processed++;
928
+ updateProgress();
929
+ addNextUrl(index + 1);
930
+ return;
931
+ }
932
+
933
+ const formData = new FormData();
934
+ formData.append('url', url);
935
+
936
+ makeRequest('/api/url/add', 'POST', formData, function(data) {
937
+ processed++;
938
+
939
+ if (data.success) {
940
+ succeeded++;
941
+
942
+ // Update localStorage
943
+ const localUrls = loadFromLocalStorage() || [];
944
+ if (!localUrls.includes(url)) {
945
+ localUrls.unshift(url);
946
+ saveToLocalStorage(localUrls);
947
+ }
948
+ }
949
+
950
+ updateProgress();
951
+ addNextUrl(index + 1);
952
+ });
953
+ }
954
+
955
+ // Start adding URLs
956
+ addNextUrl(0);
957
+ }
958
+
959
  function editUrl(url) {
960
  // Decode URL if it was previously escaped
961
  const decodedUrl = url.replace(/\\'/g, "'");