uploadts commited on
Commit
7a319ff
·
verified ·
1 Parent(s): bdc505c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +133 -15
app.py CHANGED
@@ -6,16 +6,21 @@ import asyncio
6
  from typing import Dict
7
  import os
8
  import mimetypes
 
 
9
 
10
  app = FastAPI()
11
 
 
 
 
12
  HTML_CONTENT = """
13
  <!DOCTYPE html>
14
  <html lang="en">
15
  <head>
16
  <meta charset="UTF-8">
17
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
18
- <title>Radd PRO Uploader</title>
19
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
20
  <style>
21
  body {
@@ -445,7 +450,7 @@ HTML_CONTENT = """
445
  text-align: center;
446
  }
447
 
448
- .quick-open-content img,
449
  .quick-open-content video,
450
  .quick-open-content audio {
451
  max-width: 100%;
@@ -534,7 +539,7 @@ HTML_CONTENT = """
534
  </head>
535
  <body>
536
  <div class="container">
537
- <h1>Radd PRO Uploader</h1>
538
  <form id="uploadForm">
539
  <div id="dropZone" class="drop-zone">
540
  <input type="file" name="file" id="file" class="file-input" accept="*" required>
@@ -583,6 +588,18 @@ HTML_CONTENT = """
583
  </div>
584
  </div>
585
 
 
 
 
 
 
 
 
 
 
 
 
 
586
  <script>
587
  const fileInput = document.getElementById('file');
588
  const fileName = document.getElementById('fileName');
@@ -592,10 +609,12 @@ HTML_CONTENT = """
592
  const resultContainer = document.getElementById('resultContainer');
593
  const dropZone = document.getElementById('dropZone');
594
  const modal = document.getElementById('embedModal');
 
595
  const historyModal = document.getElementById('historyModal');
596
  const quickOpenModal = document.getElementById('quickOpenModal');
597
  const span = document.getElementsByClassName("close");
598
  const embedLinkInput = document.getElementById('embedLink');
 
599
  const uploadBtn = document.getElementById('uploadBtn');
600
  const historyBtn = document.getElementById('historyBtn');
601
  const clearHistoryBtn = document.getElementById('clearHistoryBtn');
@@ -637,16 +656,14 @@ HTML_CONTENT = """
637
  }
638
  });
639
 
640
- span[0].onclick = function() {
641
- modal.style.display = "none";
642
- }
643
-
644
- span[1].onclick = function() {
645
- historyModal.style.display = "none";
646
- }
647
-
648
- span[2].onclick = function() {
649
- quickOpenModal.style.display = "none";
650
  }
651
 
652
  window.onclick = function(event) {
@@ -659,6 +676,9 @@ HTML_CONTENT = """
659
  if (event.target == quickOpenModal) {
660
  quickOpenModal.style.display = "none";
661
  }
 
 
 
662
  }
663
 
664
  historyBtn.onclick = function() {
@@ -796,6 +816,14 @@ HTML_CONTENT = """
796
  };
797
  buttonsContainer.appendChild(copyBtn);
798
 
 
 
 
 
 
 
 
 
799
  const openBtn = document.createElement('button');
800
  openBtn.textContent = 'Open';
801
  openBtn.className = 'small-btn';
@@ -832,6 +860,33 @@ HTML_CONTENT = """
832
  alert('Embed link copied to clipboard!');
833
  }
834
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
835
  function saveToHistory(fileName, url, originalExtension) {
836
  let history = JSON.parse(localStorage.getItem('uploadHistory')) || [];
837
  history.unshift({ fileName, url, originalExtension, timestamp: new Date().toISOString() });
@@ -864,6 +919,15 @@ HTML_CONTENT = """
864
  };
865
  actionsContainer.appendChild(copyBtn);
866
 
 
 
 
 
 
 
 
 
 
867
  const openBtn = document.createElement('button');
868
  openBtn.textContent = 'Open';
869
  openBtn.className = 'small-btn';
@@ -889,7 +953,7 @@ HTML_CONTENT = """
889
  historyModal.style.display = "block";
890
  }
891
 
892
- function quickOpen(url, fileName, originalExtension) {
893
  quickOpenContent.innerHTML = '';
894
  const fullUrl = window.location.origin + url;
895
 
@@ -976,6 +1040,60 @@ async def handle_upload(file: UploadFile = File(...)):
976
 
977
  return JSONResponse(content={"url": mirrored_url, "originalExtension": original_extension})
978
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
979
  @app.get("/rbxg/{path:path}")
980
  async def handle_file_stream(path: str, request: Request):
981
  original_url = f'https://replicate.delivery/pbxt/{path}'
@@ -1099,4 +1217,4 @@ async def retry_upload(upload_url: str, file_content: bytes, content_type: str,
1099
  await asyncio.sleep(delay)
1100
  delay = min(delay * 2, 60)
1101
 
1102
- return False
 
6
  from typing import Dict
7
  import os
8
  import mimetypes
9
+ import secrets
10
+ import json
11
 
12
  app = FastAPI()
13
 
14
+ # Store shortened URLs
15
+ SHORTENED_URLS = {}
16
+
17
  HTML_CONTENT = """
18
  <!DOCTYPE html>
19
  <html lang="en">
20
  <head>
21
  <meta charset="UTF-8">
22
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
23
+ <title>File Uploader</title>
24
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
25
  <style>
26
  body {
 
450
  text-align: center;
451
  }
452
 
453
+ .quick-open-content img,
454
  .quick-open-content video,
455
  .quick-open-content audio {
456
  max-width: 100%;
 
539
  </head>
540
  <body>
541
  <div class="container">
542
+ <h1>File Uploader</h1>
543
  <form id="uploadForm">
544
  <div id="dropZone" class="drop-zone">
545
  <input type="file" name="file" id="file" class="file-input" accept="*" required>
 
588
  </div>
589
  </div>
590
 
591
+ <div id="shortenModal" class="modal">
592
+ <div class="modal-content">
593
+ <span class="close">&times;</span>
594
+ <h2>Short Link</h2>
595
+ <p>Share this shortened link:</p>
596
+ <div class="embed-container">
597
+ <input type="text" id="shortenedLink" readonly>
598
+ <button onclick="copyShortenedLink()" class="small-btn">Copy</button>
599
+ </div>
600
+ </div>
601
+ </div>
602
+
603
  <script>
604
  const fileInput = document.getElementById('file');
605
  const fileName = document.getElementById('fileName');
 
609
  const resultContainer = document.getElementById('resultContainer');
610
  const dropZone = document.getElementById('dropZone');
611
  const modal = document.getElementById('embedModal');
612
+ const shortenModal = document.getElementById('shortenModal');
613
  const historyModal = document.getElementById('historyModal');
614
  const quickOpenModal = document.getElementById('quickOpenModal');
615
  const span = document.getElementsByClassName("close");
616
  const embedLinkInput = document.getElementById('embedLink');
617
+ const shortenedLinkInput = document.getElementById('shortenedLink');
618
  const uploadBtn = document.getElementById('uploadBtn');
619
  const historyBtn = document.getElementById('historyBtn');
620
  const clearHistoryBtn = document.getElementById('clearHistoryBtn');
 
656
  }
657
  });
658
 
659
+ // Close modals when clicking X
660
+ for (let i = 0; i < span.length; i++) {
661
+ span[i].onclick = function() {
662
+ modal.style.display = "none";
663
+ historyModal.style.display = "none";
664
+ quickOpenModal.style.display = "none";
665
+ shortenModal.style.display = "none";
666
+ }
 
 
667
  }
668
 
669
  window.onclick = function(event) {
 
676
  if (event.target == quickOpenModal) {
677
  quickOpenModal.style.display = "none";
678
  }
679
+ if (event.target == shortenModal) {
680
+ shortenModal.style.display = "none";
681
+ }
682
  }
683
 
684
  historyBtn.onclick = function() {
 
816
  };
817
  buttonsContainer.appendChild(copyBtn);
818
 
819
+ const shortenBtn = document.createElement('button');
820
+ shortenBtn.textContent = 'Create Short Link';
821
+ shortenBtn.className = 'small-btn';
822
+ shortenBtn.onclick = () => {
823
+ createShortLink(url);
824
+ };
825
+ buttonsContainer.appendChild(shortenBtn);
826
+
827
  const openBtn = document.createElement('button');
828
  openBtn.textContent = 'Open';
829
  openBtn.className = 'small-btn';
 
860
  alert('Embed link copied to clipboard!');
861
  }
862
 
863
+ function copyShortenedLink() {
864
+ shortenedLinkInput.select();
865
+ document.execCommand('copy');
866
+ alert('Short link copied to clipboard!');
867
+ }
868
+
869
+ function createShortLink(url) {
870
+ fetch('/shorten', {
871
+ method: 'POST',
872
+ headers: {
873
+ 'Content-Type': 'application/json',
874
+ },
875
+ body: JSON.stringify({ url: url })
876
+ })
877
+ .then(response => response.json())
878
+ .then(data => {
879
+ if (data.shortUrl) {
880
+ shortenedLinkInput.value = window.location.origin + data.shortUrl;
881
+ shortenModal.style.display = "block";
882
+ }
883
+ })
884
+ .catch(error => {
885
+ console.error('Error creating short link:', error);
886
+ alert('Failed to create short link');
887
+ });
888
+ }
889
+
890
  function saveToHistory(fileName, url, originalExtension) {
891
  let history = JSON.parse(localStorage.getItem('uploadHistory')) || [];
892
  history.unshift({ fileName, url, originalExtension, timestamp: new Date().toISOString() });
 
919
  };
920
  actionsContainer.appendChild(copyBtn);
921
 
922
+ const shortenBtn = document.createElement('button');
923
+ shortenBtn.textContent = 'Short Link';
924
+ shortenBtn.className = 'small-btn';
925
+ shortenBtn.onclick = () => {
926
+ createShortLink(item.url);
927
+ historyModal.style.display = "none";
928
+ };
929
+ actionsContainer.appendChild(shortenBtn);
930
+
931
  const openBtn = document.createElement('button');
932
  openBtn.textContent = 'Open';
933
  openBtn.className = 'small-btn';
 
953
  historyModal.style.display = "block";
954
  }
955
 
956
+ function quickOpen(url, fileName, originalExtension) {
957
  quickOpenContent.innerHTML = '';
958
  const fullUrl = window.location.origin + url;
959
 
 
1040
 
1041
  return JSONResponse(content={"url": mirrored_url, "originalExtension": original_extension})
1042
 
1043
+ @app.post("/shorten")
1044
+ async def shorten_url(request: Request):
1045
+ data = await request.json()
1046
+ original_url = data.get("url")
1047
+
1048
+ if not original_url:
1049
+ return JSONResponse(content={"error": "No URL provided"}, status_code=400)
1050
+
1051
+ # Generate a short code
1052
+ short_code = ''.join(secrets.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') for _ in range(6))
1053
+
1054
+ # Store the mapping
1055
+ SHORTENED_URLS[short_code] = original_url
1056
+
1057
+ # Save to file for persistence
1058
+ try:
1059
+ with open("shortened_urls.json", "w") as f:
1060
+ json.dump(SHORTENED_URLS, f)
1061
+ except:
1062
+ # Not critical if it fails to save
1063
+ pass
1064
+
1065
+ return JSONResponse(content={"shortUrl": f"/s/{short_code}"})
1066
+
1067
+ @app.get("/s/{short_code}")
1068
+ async def redirect_short_url(short_code: str):
1069
+ # Try to load from file first (for persistence)
1070
+ try:
1071
+ if not SHORTENED_URLS and os.path.exists("shortened_urls.json"):
1072
+ with open("shortened_urls.json", "r") as f:
1073
+ shortened_urls_data = json.load(f)
1074
+ SHORTENED_URLS.update(shortened_urls_data)
1075
+ except:
1076
+ pass
1077
+
1078
+ # Get the original URL
1079
+ original_url = SHORTENED_URLS.get(short_code)
1080
+ if not original_url:
1081
+ return JSONResponse(content={"error": "Short URL not found"}, status_code=404)
1082
+
1083
+ # HTML for redirecting
1084
+ html_content = f"""
1085
+ <!DOCTYPE html>
1086
+ <html>
1087
+ <head>
1088
+ <meta http-equiv="refresh" content="0;url={original_url}">
1089
+ </head>
1090
+ <body>
1091
+ <p>Redirecting...</p>
1092
+ </body>
1093
+ </html>
1094
+ """
1095
+ return HTMLResponse(content=html_content)
1096
+
1097
  @app.get("/rbxg/{path:path}")
1098
  async def handle_file_stream(path: str, request: Request):
1099
  original_url = f'https://replicate.delivery/pbxt/{path}'
 
1217
  await asyncio.sleep(delay)
1218
  delay = min(delay * 2, 60)
1219
 
1220
+ return False