kacapower commited on
Commit
4bab0e0
·
verified ·
1 Parent(s): 8681aca

Delete main.py

Browse files
Files changed (1) hide show
  1. main.py +0 -116
main.py DELETED
@@ -1,116 +0,0 @@
1
- import os
2
- import subprocess
3
- import shutil
4
- import tempfile
5
- from fastapi import FastAPI, UploadFile, File, Form, HTTPException, Security, Depends
6
- from fastapi.responses import FileResponse
7
- from fastapi.security.api_key import APIKeyHeader
8
- from tempfile import NamedTemporaryFile
9
- import uvicorn
10
-
11
- app = FastAPI(title="Universal File Converter API - SECURED")
12
-
13
- # =========================================================
14
- # BRIDGE CONTROL (SECURITY)
15
- # =========================================================
16
- # Define the header name the backend will look for
17
- API_KEY_NAME = "X-Bridge-Key"
18
- api_key_header = APIKeyHeader(name=API_KEY_NAME, auto_error=False)
19
-
20
- # This key must match the frontend exactly
21
- API_SECRET_KEY = os.environ.get("BRIDGE_SECRET_KEY", "my_secure_bridge_token_2026")
22
-
23
- async def get_api_key(api_key_header: str = Security(api_key_header)):
24
- """Verifies the Bridge Control badge."""
25
- if api_key_header == API_SECRET_KEY:
26
- return api_key_header
27
- raise HTTPException(
28
- status_code=403,
29
- detail="Bridge Control: Access Denied. Unauthorized connection attempt."
30
- )
31
-
32
- # =========================================================
33
- # THE 300+ FORMAT ROUTING DICTIONARY
34
- # =========================================================
35
- CONVERSION_ENGINES = {
36
- **{ext: 'imagemagick' for ext in['jpg', 'jpeg', 'png', 'webp', 'gif', 'bmp', 'tiff', 'ico', 'svg', 'heic', 'eps', 'ps', 'tga', 'jp2', 'pcx', 'pnm', 'pgm', 'ppm', 'pbm', 'xbm', 'xpm', 'cr2', 'crw', 'nef', 'arw', 'dng', 'orf', 'raf', 'rw2', 'pef', 'srw', 'exr', 'hdr', 'dds', 'avif', 'jxl', 'dib', 'jpe', 'tpf', 'vtf', 'wmf', 'emf', 'cdr', 'cpt', 'svgz', 'cgm', 'djvu', 'pcd', 'pict', 'raw', 'xcf','apng', 'bpg', 'jxr', 'wdp', 'hdp', 'heif', 'fits', 'fit', 'fts', 'jbig', 'jbig2', 'pgf', 'sgi', 'ras', 'sun', 'pix', 'mrw', 'mef', 'mos', 'nrw', 'ptx', 'r3d', 'rwz', 'sr2', 'kdc', 'erf', 'fff', 'bay', 'cap', 'iiq', '3fr', 'ari', 'cine', 'kc2', 'mdc', 'pef', 'srw', 'x3f', 'yuv', 'ycbcr', 'ciff', 'drf', 'dcr', 'dcs', 'srf', 'k25', 'pxn', 'gpr', 'hif', 'avifs', 'jls', 'jng', 'mtv', 'psd', 'psb', 'ora', 'art']},
37
- **{ext: 'ffmpeg' for ext in['mp4', 'avi', 'mkv','m2t', '8svx', 'aa', 'aa3', 'aacp', 'adt', 'adts', 'afc', 'aif', 'aifc', 'aifff', 'al', 'alaw', 'amrnb', 'amrwb', 'amrwb+', 'ast', 'at3', 'atrac', 'awb', 'brstm', 'bwav', 'cdda', 'cdr', 'daud', 'dfpwm', 'dsp', 'fsb', 'g721', 'g723', 'g726', 'g729', 'hcom', 'mka', 'mlp', 'mp1', 'mpa', 'mpc', 'mpga', 'mpp', 'oga', 'oma', 'sds', 'sf', 'smp', 'tak', 'ulaw', 'vag', 'vox', 'w64', 'wve', 'wv','m2t', 'm2ts', 'mts', 'm2v', 'mpv', 'h264', 'h265', 'hevc', 'vp8', 'vp9', 'ivf', 'fli', 'flc', 'roq', 'bik', 'bik2', 'smk', 'nut', 'dpg', 'evo', 'mve', 'ogm', 'ogx', 'mxg', 'mvi', 'avs', 'avs2', 'avs3', 'dvr-ms', 'idx', 'sub', 'sup', 'thp', 'pva', 'm2p', 'vivo', 'viv', 'wm', 'y4m', 'yuv4mpeg', 'webm', 'mov', 'flv', 'wmv', 'm4v', 'mpeg', '3gp', 'ogv', 'asf', 'rm', 'rmvb', 'ts', 'm2ts', 'vob', 'mxf', 'roq', 'nsv', 'f4v', 'f4p', 'f4a', 'f4b', 'drc', 'yuv', 'nut', 'amv', 'svt', 'ivf', 'mpe', 'mp2v', 'm2v', 'm4p', 'mpg', 'wtv', 'gxf', 'mjpg', 'mts', 'xvid', 'divx', 'mp3', 'wav', 'flac', 'ogg', 'aac', 'm4a', 'wma', 'aiff', 'opus', 'alac', 'amr', 'au', 'snd', 'mid', 'midi', 'kar', 'mka', 'mac', 'ape', 'spx', 'rka', 'shn', 'tta', 'smp', 'dts', 'pcm', 'gsm', 'dct', 'voc', 'aup', 'band', 'bwf', 'cda', 'ds2', 'dss', 'dvf', 'm4r', 'm4b', 'mus', 'qcp', 'ra', 'ram', 'rx2', 's3m', 'srm', 'uax', 'xm', 'it', 'ac3', 'caf']},
38
- **{ext: 'libreoffice' for ext in['pdf','abw', 'ai', 'ans', '123', 'bks', 'gnm', 'gnx', 'pxl', 'sdc', 'sxc', 'uos', 'wb1', 'wb2', 'wb3', 'wks', 'wq2', 'xlk', 'xlm', 'xlt', 'xlv','asc', 'ascii', 'csvs', 'docbook', 'fods', 'markdown', 'pdb', 'pdfa', 'ps', 'text', 'tsv', 'txt2', 'docx', 'doc', 'odt', 'rtf', 'wpd', 'wps', 'sdw', 'sgl', 'lwp', 'docm', 'dot', 'dotx', 'dotm', 'pages', 'xps', 'oxps', 'abw', 'log', 'msg', 'eml', 'p7s', '1st', 'ans', 'asc', 'diz', 'err', 'faq', 'readme', 'sub', 'ltr', 'dvi', 'xlsx', 'xls', 'ods', 'csv', 'tsv', 'xlsm', 'xlsb', 'xltx', 'xltm', 'xlw', 'xlr', 'wk1', 'wk2', 'wk3', 'wk4', 'wq1', 'sd1', 'dbf', 'dif', 'slk', 'prn', 'numbers', 'fods', 'ots', 'gnumeric', 'pptx', 'ppt', 'odp', 'pptm', 'pps', 'ppsx', 'ppsm', 'pot', 'potx', 'potm', 'sda', 'sdd', 'sti', 'thmx', 'key', 'pez', 'otp']},
39
- **{ext: 'calibre' for ext in['epub','asc', 'ascii', 'markdown', 'pdb', 'text', 'mobi', 'azw3', 'fb2', 'lit', 'prc', 'tcr', 'cbr', 'cbz', 'cb7', 'cbt', 'cba', 'chm', 'djv', 'ibooks', 'kfx', 'pdb', 'snb', 'tmd', 'lrf']},
40
- **{ext: 'pandoc' for ext in ['html', 'md', 'rst', 'tex']},
41
- **{ext: 'assimp' for ext in['stl', 'obj', 'fbx', 'dae', '3ds', 'blend', 'ply', 'gltf', 'glb', 'step', 'stp', 'iges', 'igs', 'dxf', 'dwg', 'x3d', 'wrl', 'amf']},
42
- **{ext: 'fontforge' for ext in['ttf','afm', 'bdf', 'lwfn', 'mf', 'otc', 'pfm', 'pk', 'sfd', 'tfm', 'ufo', 'vfb', 'otf', 'woff', 'woff2', 'eot', 'dfont', 'fon', 'pfa', 'pfb', 'suit', 'fnt']},
43
- **{ext: 'archive_engine' for ext in['zip','001', '002', '003', '004', '005', '006', '007', '008', '009', '010', 'dd', 'ear', 'part1', 'part2', 'part3', 'pax', 'rar5', 'tar.gz', 'tar.bz', 'tar.lz', 'tar.lzma', 'tar.z', 'war', 'tar', 'gz', 'bz2', '7z', 'rar', 'xz', 'lzma', 'wim', 'swm', 'cab', 'iso', 'dmg', 'img', 'vdi', 'vhd', 'vmdk', 'squashfs', 'qcow2', 'z', 'taz', 'tgz', 'tbz2', 'tz2', 'tbz', 'jar', 'apk', 'xpi', 'crx', 'nupkg', 'pak', 'lz', 'sit', 'sitx', 'pea', 'ar', 'cpio', 'shar', 'lha', 'lzh', 'alz']},
44
- **{ext: 'rename' for ext in['py', 'js', 'java', 'c', 'cpp', 'cs', 'rb', 'go', 'rs', 'php', 'swift', 'kt', 'sh', 'bat', 'ps1', 'pl', 'lua', 'm', 'r', 'vbs', 'asm', 'dart', 'ts', 'css', 'scss', 'less', 'txt', 'xml', 'json', 'yaml', 'yml', 'rss', 'atom', 'rdf', 'owl', 'xsd', 'dtd', 'xslt', 'xsl', 'plist', 'ini', 'cfg', 'conf', 'toml', 'sql', 'hdf5', 'h5', 'nc', 'sqlite', 'db', 'mdb', 'accdb', 'bson', 'avro', 'parquet']}
45
- }
46
-
47
- def execute_conversion(input_path: str, output_path: str, target_ext: str):
48
- engine = CONVERSION_ENGINES.get(target_ext)
49
- if not engine:
50
- raise ValueError(f"Target format '{target_ext}' is not mapped to an engine.")
51
-
52
- try:
53
- if engine == 'rename':
54
- shutil.copy(input_path, output_path)
55
- return
56
- elif engine == 'libreoffice':
57
- out_dir = os.path.dirname(output_path)
58
- cmd =['soffice', '--headless', '--convert-to', target_ext, '--outdir', out_dir, input_path]
59
- elif engine == 'imagemagick':
60
- cmd =['magick', input_path, output_path]
61
- elif engine == 'ffmpeg':
62
- cmd =['ffmpeg', '-y', '-i', input_path, output_path]
63
- elif engine == 'pandoc':
64
- cmd =['pandoc', input_path, '-o', output_path]
65
- elif engine == 'calibre':
66
- cmd =['ebook-convert', input_path, output_path]
67
- elif engine == 'assimp':
68
- cmd = ['assimp', 'export', input_path, output_path]
69
- elif engine == 'fontforge':
70
- script = f'Open("{input_path}"); Generate("{output_path}")'
71
- cmd = ['fontforge', '-lang=ff', '-c', script]
72
- elif engine == 'archive_engine':
73
- with tempfile.TemporaryDirectory() as temp_dir:
74
- subprocess.run(['7z', 'x', f'-o{temp_dir}', input_path], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
75
- subprocess.run(['7z', 'a', output_path, f'{temp_dir}/*'], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
76
- return
77
-
78
- subprocess.run(cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
79
- except FileNotFoundError:
80
- raise RuntimeError(f"Required server tool for engine '{engine}' is missing or not installed.")
81
- except subprocess.CalledProcessError as e:
82
- err_msg = e.stderr.decode('utf-8') if e.stderr else str(e)
83
- raise RuntimeError(f"Engine Error ({engine}): {err_msg}")
84
-
85
- @app.post("/convert")
86
- async def convert_file(
87
- file: UploadFile = File(...),
88
- target_format: str = Form(...),
89
- api_key: str = Depends(get_api_key) # <-- SECURITY BRIDGE CHECK HAPPENS HERE
90
- ):
91
- target_format = target_format.lower().strip('.')
92
-
93
- filename_parts = file.filename.rsplit('.', 1)
94
- input_ext = filename_parts[-1] if len(filename_parts) > 1 else "tmp"
95
- base_name = filename_parts[0] if len(filename_parts) > 1 else "file"
96
-
97
- # Memory-safe chunked streaming (Prevents RAM explosions)
98
- with NamedTemporaryFile(delete=False, suffix=f".{input_ext}") as tmp_in:
99
- shutil.copyfileobj(file.file, tmp_in)
100
- input_path = tmp_in.name
101
-
102
- output_path = input_path.rsplit('.', 1)[0] + f".{target_format}"
103
-
104
- try:
105
- execute_conversion(input_path, output_path, target_format)
106
-
107
- return FileResponse(
108
- path=output_path,
109
- filename=f"{base_name}_converted.{target_format}",
110
- media_type='application/octet-stream'
111
- )
112
- except Exception as e:
113
- raise HTTPException(status_code=500, detail=str(e))
114
-
115
- if __name__ == "__main__":
116
- uvicorn.run(app, host="0.0.0.0", port=7860)