Wizeo commited on
Commit
5b8b409
·
verified ·
1 Parent(s): afb18da

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +442 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Test
3
- emoji: 🐠
4
- colorFrom: yellow
5
- colorTo: green
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: test
3
+ emoji: 🐳
4
+ colorFrom: purple
5
+ colorTo: red
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,442 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="fr">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>LinkedIn Profile Scraper</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ .video-preview {
11
+ background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
12
+ border: 2px dashed #0077b5;
13
+ position: relative;
14
+ overflow: hidden;
15
+ }
16
+ .progress-bar {
17
+ transition: width 0.3s ease;
18
+ }
19
+ .btn-primary {
20
+ background-color: #0077b5;
21
+ transition: all 0.3s ease;
22
+ }
23
+ .btn-primary:hover {
24
+ background-color: #005582;
25
+ transform: translateY(-2px);
26
+ }
27
+ .input-field:focus {
28
+ border-color: #0077b5;
29
+ box-shadow: 0 0 0 3px rgba(0, 119, 181, 0.2);
30
+ }
31
+ @keyframes pulse {
32
+ 0% { transform: scale(1); }
33
+ 50% { transform: scale(1.05); }
34
+ 100% { transform: scale(1); }
35
+ }
36
+ .pulse {
37
+ animation: pulse 2s infinite;
38
+ }
39
+ #fakeVideo {
40
+ width: 100%;
41
+ height: 100%;
42
+ object-fit: cover;
43
+ display: none;
44
+ }
45
+ .video-placeholder {
46
+ display: flex;
47
+ flex-direction: column;
48
+ align-items: center;
49
+ justify-content: center;
50
+ height: 100%;
51
+ }
52
+ </style>
53
+ </head>
54
+ <body class="bg-gray-50 min-h-screen">
55
+ <div class="container mx-auto px-4 py-8 max-w-4xl">
56
+ <header class="mb-10 text-center">
57
+ <h1 class="text-4xl font-bold text-gray-800 mb-2">
58
+ <i class="fab fa-linkedin text-blue-600 mr-2"></i> LinkedIn Profile Scraper
59
+ </h1>
60
+ <p class="text-gray-600">Automatisez les visites de profils et capturez des enregistrements vidéo</p>
61
+ </header>
62
+
63
+ <div class="bg-white rounded-xl shadow-lg overflow-hidden mb-8">
64
+ <div class="p-6">
65
+ <div class="flex flex-col md:flex-row gap-6">
66
+ <!-- Section Connexion -->
67
+ <div class="w-full md:w-1/2">
68
+ <h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
69
+ <i class="fas fa-sign-in-alt mr-2 text-blue-500"></i> Connexion LinkedIn
70
+ </h2>
71
+
72
+ <div class="space-y-4">
73
+ <div>
74
+ <label class="block text-gray-700 mb-2">Email</label>
75
+ <input type="email" id="email" class="w-full px-4 py-2 rounded-lg border input-field focus:outline-none" placeholder="votre@email.com">
76
+ </div>
77
+
78
+ <div>
79
+ <label class="block text-gray-700 mb-2">Mot de passe</label>
80
+ <input type="password" id="password" class="w-full px-4 py-2 rounded-lg border input-field focus:outline-none" placeholder="••••••••">
81
+ </div>
82
+
83
+ <button id="loginBtn" class="w-full btn-primary text-white py-3 rounded-lg font-medium flex items-center justify-center">
84
+ <i class="fas fa-lock-open mr-2"></i> Se connecter à LinkedIn
85
+ </button>
86
+
87
+ <div class="text-center text-sm text-gray-500">
88
+ <p>Nous ne stockons pas vos identifiants</p>
89
+ </div>
90
+ </div>
91
+ </div>
92
+
93
+ <!-- Section Profil -->
94
+ <div class="w-full md:w-1/2">
95
+ <h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
96
+ <i class="fas fa-user-circle mr-2 text-blue-500"></i> Paramètres du profil
97
+ </h2>
98
+
99
+ <div class="space-y-4">
100
+ <div>
101
+ <label class="block text-gray-700 mb-2">URL du profil</label>
102
+ <input type="url" id="profileUrl" class="w-full px-4 py-2 rounded-lg border input-field focus:outline-none" placeholder="https://linkedin.com/in/nomdutilisateur">
103
+ </div>
104
+
105
+ <div>
106
+ <label class="block text-gray-700 mb-2">Durée d'enregistrement</label>
107
+ <select id="duration" class="w-full px-4 py-2 rounded-lg border input-field focus:outline-none">
108
+ <option value="5" selected>5 secondes</option>
109
+ <option value="10">10 secondes</option>
110
+ <option value="15">15 secondes</option>
111
+ </select>
112
+ </div>
113
+
114
+ <button id="startBtn" class="w-full btn-primary text-white py-3 rounded-lg font-medium flex items-center justify-center opacity-50 cursor-not-allowed" disabled>
115
+ <i class="fas fa-play mr-2"></i> Démarrer l'enregistrement
116
+ </button>
117
+ </div>
118
+ </div>
119
+ </div>
120
+ </div>
121
+ </div>
122
+
123
+ <!-- Section État -->
124
+ <div id="statusSection" class="bg-white rounded-xl shadow-lg overflow-hidden mb-8 hidden">
125
+ <div class="p-6">
126
+ <h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
127
+ <i class="fas fa-tasks mr-2 text-blue-500"></i> État de l'opération
128
+ </h2>
129
+
130
+ <div class="space-y-6">
131
+ <div>
132
+ <div class="flex justify-between mb-1">
133
+ <span class="text-gray-700">Progression</span>
134
+ <span id="progressPercent" class="text-gray-700">0%</span>
135
+ </div>
136
+ <div class="w-full bg-gray-200 rounded-full h-2.5">
137
+ <div id="progressBar" class="bg-blue-600 h-2.5 rounded-full progress-bar" style="width: 0%"></div>
138
+ </div>
139
+ </div>
140
+
141
+ <div id="statusMessages" class="space-y-2">
142
+ <div class="flex items-start text-green-600">
143
+ <i class="fas fa-check-circle mt-1 mr-2"></i>
144
+ <span>Connecté avec succès à LinkedIn</span>
145
+ </div>
146
+ </div>
147
+ </div>
148
+ </div>
149
+ </div>
150
+
151
+ <!-- Section Aperçu -->
152
+ <div id="previewSection" class="bg-white rounded-xl shadow-lg overflow-hidden hidden">
153
+ <div class="p-6">
154
+ <h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
155
+ <i class="fas fa-video mr-2 text-blue-500"></i> Aperçu de la vidéo
156
+ </h2>
157
+
158
+ <div class="video-preview rounded-lg p-4 mb-4 flex flex-col items-center justify-center h-64">
159
+ <div class="video-placeholder">
160
+ <i class="fas fa-video text-4xl text-gray-400 mb-3"></i>
161
+ <p class="text-gray-500 text-center">Votre enregistrement apparaîtra ici</p>
162
+ </div>
163
+ <video id="fakeVideo" controls>
164
+ <source src="" type="video/mp4">
165
+ Votre navigateur ne supporte pas la vidéo.
166
+ </video>
167
+ </div>
168
+
169
+ <div class="flex justify-between">
170
+ <button id="downloadBtn" class="btn-primary text-white px-6 py-2 rounded-lg font-medium flex items-center">
171
+ <i class="fas fa-download mr-2"></i> Télécharger
172
+ </button>
173
+
174
+ <button id="newRecordingBtn" class="bg-gray-200 text-gray-800 px-6 py-2 rounded-lg font-medium flex items-center">
175
+ <i class="fas fa-redo mr-2"></i> Nouvel enregistrement
176
+ </button>
177
+ </div>
178
+ </div>
179
+ </div>
180
+
181
+ <!-- Instructions -->
182
+ <div class="bg-blue-50 rounded-xl p-6 mt-8 border border-blue-100">
183
+ <h3 class="text-lg font-semibold text-blue-800 mb-3 flex items-center">
184
+ <i class="fas fa-info-circle mr-2"></i> Comment ça marche
185
+ </h3>
186
+ <ol class="list-decimal list-inside space-y-2 text-blue-900">
187
+ <li>Entrez vos identifiants LinkedIn (non stockés)</li>
188
+ <li>Collez l'URL du profil que vous souhaitez visiter</li>
189
+ <li>Cliquez sur "Démarrer l'enregistrement"</li>
190
+ <li>L'outil va automatiquement défiler et enregistrer pendant 5 secondes</li>
191
+ <li>Téléchargez votre enregistrement vidéo</li>
192
+ </ol>
193
+ <div class="mt-4 p-3 bg-blue-100 rounded-lg text-blue-800 flex items-start">
194
+ <i class="fas fa-exclamation-triangle mt-1 mr-2"></i>
195
+ <span>Note : Ceci est une démonstration frontend. Une automatisation réelle de LinkedIn nécessiterait des services backend en raison des restrictions de sécurité des navigateurs.</span>
196
+ </div>
197
+ </div>
198
+ </div>
199
+
200
+ <script>
201
+ document.addEventListener('DOMContentLoaded', function() {
202
+ // Éléments
203
+ const emailInput = document.getElementById('email');
204
+ const passwordInput = document.getElementById('password');
205
+ const loginBtn = document.getElementById('loginBtn');
206
+ const profileUrlInput = document.getElementById('profileUrl');
207
+ const startBtn = document.getElementById('startBtn');
208
+ const statusSection = document.getElementById('statusSection');
209
+ const previewSection = document.getElementById('previewSection');
210
+ const progressBar = document.getElementById('progressBar');
211
+ const progressPercent = document.getElementById('progressPercent');
212
+ const statusMessages = document.getElementById('statusMessages');
213
+ const downloadBtn = document.getElementById('downloadBtn');
214
+ const newRecordingBtn = document.getElementById('newRecordingBtn');
215
+ const fakeVideo = document.getElementById('fakeVideo');
216
+ const videoPlaceholder = document.querySelector('.video-placeholder');
217
+ const durationSelect = document.getElementById('duration');
218
+
219
+ // Activer le bouton de démarrage quand l'URL est entrée
220
+ profileUrlInput.addEventListener('input', function() {
221
+ if (profileUrlInput.value.trim() !== '') {
222
+ startBtn.classList.remove('opacity-50', 'cursor-not-allowed');
223
+ startBtn.disabled = false;
224
+ } else {
225
+ startBtn.classList.add('opacity-50', 'cursor-not-allowed');
226
+ startBtn.disabled = true;
227
+ }
228
+ });
229
+
230
+ // Bouton de connexion
231
+ loginBtn.addEventListener('click', function() {
232
+ const email = emailInput.value.trim();
233
+ const password = passwordInput.value.trim();
234
+
235
+ if (!email || !password) {
236
+ addStatusMessage('Veuillez entrer un email et un mot de passe', 'error');
237
+ return;
238
+ }
239
+
240
+ // Simulation du processus de connexion
241
+ loginBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Connexion...';
242
+ loginBtn.disabled = true;
243
+
244
+ setTimeout(() => {
245
+ addStatusMessage('Connecté avec succès à LinkedIn', 'success');
246
+ loginBtn.innerHTML = '<i class="fas fa-check mr-2"></i> Connecté';
247
+ statusSection.classList.remove('hidden');
248
+ }, 2000);
249
+ });
250
+
251
+ // Bouton de démarrage de l'enregistrement
252
+ startBtn.addEventListener('click', function() {
253
+ const profileUrl = profileUrlInput.value.trim();
254
+ const duration = parseInt(durationSelect.value);
255
+
256
+ if (!profileUrl) {
257
+ addStatusMessage('Veuillez entrer une URL de profil', 'error');
258
+ return;
259
+ }
260
+
261
+ // Validation de l'URL
262
+ if (!isValidLinkedInUrl(profileUrl)) {
263
+ addStatusMessage('Veuillez entrer une URL de profil LinkedIn valide', 'error');
264
+ return;
265
+ }
266
+
267
+ // Simulation du processus d'enregistrement
268
+ simulateRecording(duration);
269
+ });
270
+
271
+ // Bouton de téléchargement
272
+ downloadBtn.addEventListener('click', function() {
273
+ addStatusMessage('Préparation du téléchargement...', 'info');
274
+
275
+ // Créer un lien de téléchargement simulé
276
+ const link = document.createElement('a');
277
+ link.href = 'data:text/plain;charset=utf-8,' + encodeURIComponent('Ceci est une simulation. Dans une application réelle, vous auriez ici votre vidéo.');
278
+ link.download = 'linkedin_recording_simulation.txt';
279
+ link.style.display = 'none';
280
+ document.body.appendChild(link);
281
+ link.click();
282
+ document.body.removeChild(link);
283
+
284
+ setTimeout(() => {
285
+ addStatusMessage('Téléchargement simulé terminé!', 'success');
286
+ }, 1500);
287
+ });
288
+
289
+ // Bouton nouvel enregistrement
290
+ newRecordingBtn.addEventListener('click', function() {
291
+ previewSection.classList.add('hidden');
292
+ profileUrlInput.value = '';
293
+ startBtn.classList.add('opacity-50', 'cursor-not-allowed');
294
+ startBtn.disabled = true;
295
+ statusMessages.innerHTML = '';
296
+ progressBar.style.width = '0%';
297
+ progressPercent.textContent = '0%';
298
+ fakeVideo.style.display = 'none';
299
+ videoPlaceholder.style.display = 'flex';
300
+ fakeVideo.pause();
301
+ fakeVideo.currentTime = 0;
302
+ });
303
+
304
+ // Fonction pour ajouter des messages d'état
305
+ function addStatusMessage(message, type) {
306
+ const icon = {
307
+ 'success': 'fa-check-circle',
308
+ 'error': 'fa-times-circle',
309
+ 'info': 'fa-info-circle',
310
+ 'warning': 'fa-exclamation-circle'
311
+ }[type];
312
+
313
+ const color = {
314
+ 'success': 'text-green-600',
315
+ 'error': 'text-red-600',
316
+ 'info': 'text-blue-600',
317
+ 'warning': 'text-yellow-600'
318
+ }[type];
319
+
320
+ const messageEl = document.createElement('div');
321
+ messageEl.className = `flex items-start ${color}`;
322
+ messageEl.innerHTML = `
323
+ <i class="fas ${icon} mt-1 mr-2"></i>
324
+ <span>${message}</span>
325
+ `;
326
+
327
+ statusMessages.prepend(messageEl);
328
+ }
329
+
330
+ // Simulation du processus d'enregistrement
331
+ function simulateRecording(duration) {
332
+ startBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Traitement...';
333
+ startBtn.disabled = true;
334
+
335
+ // Afficher la section d'état si cachée
336
+ statusSection.classList.remove('hidden');
337
+
338
+ // Effacer les messages précédents sauf la connexion réussie
339
+ if (statusMessages.children.length > 1) {
340
+ statusMessages.innerHTML = statusMessages.children[0].outerHTML;
341
+ }
342
+
343
+ addStatusMessage('Navigation vers la page du profil...', 'info');
344
+
345
+ // Simulation de progression
346
+ let progress = 0;
347
+ const totalSteps = 100;
348
+ const intervalTime = (duration * 1000) / (totalSteps / 5); // Ajuster pour la durée sélectionnée
349
+
350
+ const interval = setInterval(() => {
351
+ progress += 5;
352
+ progressBar.style.width = `${progress}%`;
353
+ progressPercent.textContent = `${progress}%`;
354
+
355
+ // Mettre à jour les messages à certains points de progression
356
+ if (progress === 20) {
357
+ addStatusMessage('Page de profil chargée avec succès', 'success');
358
+ } else if (progress === 40) {
359
+ addStatusMessage('Début de l\'enregistrement vidéo...', 'info');
360
+ } else if (progress === 60) {
361
+ addStatusMessage('Défilement du profil...', 'info');
362
+ } else if (progress === 80) {
363
+ addStatusMessage('Finalisation de l\'enregistrement...', 'info');
364
+ }
365
+
366
+ // Terminer le processus
367
+ if (progress >= 100) {
368
+ clearInterval(interval);
369
+ addStatusMessage('Enregistrement terminé!', 'success');
370
+ startBtn.innerHTML = '<i class="fas fa-check mr-2"></i> Terminé';
371
+
372
+ // Afficher la section d'aperçu avec une vidéo simulée
373
+ setTimeout(() => {
374
+ previewSection.classList.remove('hidden');
375
+ videoPlaceholder.style.display = 'none';
376
+ fakeVideo.style.display = 'block';
377
+
378
+ // Créer une vidéo simulée avec un canvas animé
379
+ simulateVideoPlayback();
380
+ }, 500);
381
+ }
382
+ }, intervalTime);
383
+ }
384
+
385
+ // Simulation de lecture vidéo
386
+ function simulateVideoPlayback() {
387
+ // Créer un canvas animé comme simulation de vidéo
388
+ const canvas = document.createElement('canvas');
389
+ canvas.width = 640;
390
+ canvas.height = 360;
391
+ canvas.style.width = '100%';
392
+ canvas.style.height = '100%';
393
+ canvas.style.objectFit = 'cover';
394
+
395
+ const ctx = canvas.getContext('2d');
396
+
397
+ // Effacer le contenu précédent de la vidéo
398
+ fakeVideo.innerHTML = '';
399
+ fakeVideo.appendChild(canvas);
400
+
401
+ // Animation de défilement simulée
402
+ let scrollPosition = 0;
403
+ const scrollInterval = setInterval(() => {
404
+ // Fond bleu LinkedIn
405
+ ctx.fillStyle = '#f3f6f8';
406
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
407
+
408
+ // Barre de navigation supérieure simulée
409
+ ctx.fillStyle = '#0077b5';
410
+ ctx.fillRect(0, 0, canvas.width, 60);
411
+
412
+ // Texte de simulation
413
+ ctx.fillStyle = '#000';
414
+ ctx.font = '20px Arial';
415
+ ctx.fillText('Simulation de défilement LinkedIn', 20, 100 + scrollPosition);
416
+
417
+ ctx.font = '16px Arial';
418
+ ctx.fillText('• Expérience professionnelle', 20, 140 + scrollPosition);
419
+ ctx.fillText('• Formation', 20, 180 + scrollPosition);
420
+ ctx.fillText('• Compétences', 20, 220 + scrollPosition);
421
+ ctx.fillText('• Recommandations', 20, 260 + scrollPosition);
422
+ ctx.fillText('• Publications', 20, 300 + scrollPosition);
423
+
424
+ scrollPosition -= 2;
425
+
426
+ if (scrollPosition < -300) {
427
+ clearInterval(scrollInterval);
428
+ }
429
+ }, 50);
430
+
431
+ fakeVideo.play(); // Lancer la lecture
432
+ }
433
+
434
+ // Validation simple d'URL LinkedIn
435
+ function isValidLinkedInUrl(url) {
436
+ return url.includes('linkedin.com/in/') &&
437
+ (url.startsWith('http://') || url.startsWith('https://'));
438
+ }
439
+ });
440
+ </script>
441
+ <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=Wizeo/test" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
442
+ </html>