euler314 commited on
Commit
8089b19
·
verified ·
1 Parent(s): e9acc95

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +684 -27
app.py CHANGED
@@ -40,6 +40,55 @@ logging.basicConfig(
40
  )
41
  logger = logging.getLogger(__name__)
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  # Model configuration mapping for different API requirements and limits
44
  MODEL_CONFIGS = {
45
  "DeepSeek-V3-0324": {"max_tokens": 4000, "param_name": "max_tokens", "api_version": None, "category": "DeepSeek", "warning": None},
@@ -115,7 +164,9 @@ def check_password():
115
  return False
116
  return True
117
 
 
118
  def ensure_packages():
 
119
  required_packages = {
120
  'manim': '0.17.3',
121
  'Pillow': '9.0.0',
@@ -124,19 +175,109 @@ def ensure_packages():
124
  'torch': '2.0.0',
125
  'pygments': '2.15.1',
126
  'streamlit-ace': '0.1.1',
127
- 'pydub': '0.25.1', # For audio processing
128
- 'plotly': '5.14.0', # For timeline editor
129
- 'pandas': '2.0.0', # For data manipulation
130
- 'python-pptx': '0.6.21', # For PowerPoint export
131
- 'markdown': '3.4.3', # For markdown processing
132
- 'fpdf': '1.7.2', # For PDF generation
133
- 'matplotlib': '3.5.0', # For Python script runner
134
- 'seaborn': '0.11.2', # For enhanced visualizations
135
- 'scipy': '1.7.3', # For scientific computations
136
- 'huggingface_hub': '0.16.0', # For Hugging Face API
 
 
 
137
  }
138
 
139
- with st.spinner("Checking required packages..."):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  # First, quickly check if packages are already installed
141
  missing_packages = {}
142
  for package, version in required_packages.items():
@@ -177,29 +318,69 @@ def ensure_packages():
177
  import scipy
178
  elif package == 'huggingface_hub':
179
  import huggingface_hub
 
 
 
 
 
 
180
  except ImportError:
181
  missing_packages[package] = version
182
 
183
  # If no packages are missing, return success immediately
184
  if not missing_packages:
185
- logger.info("All required packages already installed.")
186
  return True
187
 
188
  # If there are missing packages, install them with progress reporting
189
  progress_bar = st.progress(0)
190
  status_text = st.empty()
191
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
  for i, (package, version) in enumerate(missing_packages.items()):
193
  try:
194
  progress = (i / len(missing_packages))
195
  progress_bar.progress(progress)
196
  status_text.text(f"Installing {package}...")
197
 
198
- result = subprocess.run(
199
- [sys.executable, "-m", "pip", "install", f"{package}>={version}"],
200
- capture_output=True,
201
- text=True
202
- )
 
 
 
 
 
 
 
 
 
 
 
203
 
204
  if result.returncode != 0:
205
  st.error(f"Failed to install {package}: {result.stderr}")
@@ -212,14 +393,14 @@ def ensure_packages():
212
  return False
213
 
214
  progress_bar.progress(1.0)
215
- status_text.text("All packages installed successfully!")
216
  time.sleep(0.5)
217
  progress_bar.empty()
218
  status_text.empty()
219
  return True
220
 
221
  def install_custom_packages(package_list):
222
- """Install custom packages specified by the user without page refresh"""
223
  if not package_list.strip():
224
  return True, "No packages specified"
225
 
@@ -232,6 +413,29 @@ def install_custom_packages(package_list):
232
  status_placeholder = st.sidebar.empty()
233
  progress_bar = st.sidebar.progress(0)
234
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
  results = []
236
  success = True
237
 
@@ -241,11 +445,22 @@ def install_custom_packages(package_list):
241
  progress_bar.progress(progress)
242
  status_placeholder.text(f"Installing {package}...")
243
 
244
- result = subprocess.run(
245
- [sys.executable, "-m", "pip", "install", package],
246
- capture_output=True,
247
- text=True
248
- )
 
 
 
 
 
 
 
 
 
 
 
249
 
250
  if result.returncode != 0:
251
  error_msg = f"Failed to install {package}: {result.stderr}"
@@ -270,6 +485,267 @@ def install_custom_packages(package_list):
270
 
271
  return success, "\n".join(results)
272
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
273
  @st.cache_resource(ttl=3600)
274
  def init_ai_models_direct():
275
  """Direct implementation using the exact pattern from the example code"""
@@ -822,8 +1298,6 @@ def generate_manim_video(python_code, format_type, quality_preset, animation_spe
822
  # IMPORTANT: Wait a moment for file system to catch up
823
  time.sleep(3)
824
 
825
- # Rest of the function remains the same
826
-
827
  # Special handling for GIF format - if Manim failed to generate a GIF but we have an MP4
828
  if format_type == "gif" and (not output_file_path or not os.path.exists(output_file_path)) and mp4_output_path and os.path.exists(mp4_output_path):
829
  status_placeholder.info("GIF generation via Manim failed. Trying FFmpeg conversion...")
@@ -1509,6 +1983,42 @@ def compile_cpp_code_enhanced(code, settings, project_files=None, enable_debug=F
1509
  if enable_debug:
1510
  compile_cmd.append("-g")
1511
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1512
  # Add preprocessor definitions
1513
  for definition in settings.get("definitions", []):
1514
  if "=" in definition:
@@ -1518,7 +2028,7 @@ def compile_cpp_code_enhanced(code, settings, project_files=None, enable_debug=F
1518
  compile_cmd.append(f"-D{definition}")
1519
 
1520
  # Add include paths
1521
- for path in settings.get("include_paths", []):
1522
  compile_cmd.append(f"-I{path}")
1523
 
1524
  # Add library paths
@@ -2517,6 +3027,153 @@ int main() {
2517
  with st.expander("Installation Results"):
2518
  st.code(st.session_state.custom_library_result)
2519
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2520
  # C/C++ Library Options
2521
  with st.sidebar.expander("C/C++ Library Options"):
2522
  st.markdown("### Advanced C/C++ Settings")
 
40
  )
41
  logger = logging.getLogger(__name__)
42
 
43
+ # Check if sudo is available on the system
44
+ def is_sudo_available():
45
+ """Check if sudo command is available on the system"""
46
+ if platform.system() == "Windows":
47
+ return False # Windows doesn't use sudo
48
+
49
+ try:
50
+ result = subprocess.run(
51
+ ["which", "sudo"],
52
+ capture_output=True,
53
+ text=True,
54
+ check=False
55
+ )
56
+ return result.returncode == 0
57
+ except Exception:
58
+ return False
59
+
60
+ # Try to use sudo if available, with password prompt if needed
61
+ def run_with_sudo(command, password=None):
62
+ """Run a command with sudo if available, with optional password"""
63
+ if not is_sudo_available():
64
+ # Fall back to running without sudo
65
+ return subprocess.run(command, capture_output=True, text=True)
66
+
67
+ # Prepare sudo command
68
+ sudo_cmd = ["sudo", "-S"] + command
69
+
70
+ try:
71
+ if password:
72
+ # Run with provided password
73
+ process = subprocess.Popen(
74
+ sudo_cmd,
75
+ stdin=subprocess.PIPE,
76
+ stdout=subprocess.PIPE,
77
+ stderr=subprocess.PIPE,
78
+ text=True
79
+ )
80
+ stdout, stderr = process.communicate(input=password + "\n")
81
+ return subprocess.CompletedProcess(
82
+ sudo_cmd, process.returncode, stdout, stderr
83
+ )
84
+ else:
85
+ # Run without password (relies on cached sudo credentials)
86
+ return subprocess.run(sudo_cmd, capture_output=True, text=True)
87
+ except Exception as e:
88
+ logger.error(f"Error running sudo command: {str(e)}")
89
+ # Fall back to running without sudo
90
+ return subprocess.run(command, capture_output=True, text=True)
91
+
92
  # Model configuration mapping for different API requirements and limits
93
  MODEL_CONFIGS = {
94
  "DeepSeek-V3-0324": {"max_tokens": 4000, "param_name": "max_tokens", "api_version": None, "category": "DeepSeek", "warning": None},
 
164
  return False
165
  return True
166
 
167
+ # Enhanced package management
168
  def ensure_packages():
169
+ """Install required packages with sudo if available"""
170
  required_packages = {
171
  'manim': '0.17.3',
172
  'Pillow': '9.0.0',
 
175
  'torch': '2.0.0',
176
  'pygments': '2.15.1',
177
  'streamlit-ace': '0.1.1',
178
+ 'pydub': '0.25.1',
179
+ 'plotly': '5.14.0',
180
+ 'pandas': '2.0.0',
181
+ 'python-pptx': '0.6.21',
182
+ 'markdown': '3.4.3',
183
+ 'fpdf': '1.7.2',
184
+ 'matplotlib': '3.5.0',
185
+ 'seaborn': '0.11.2',
186
+ 'scipy': '1.7.3',
187
+ 'huggingface_hub': '0.16.0',
188
+ 'azure-ai-inference': '1.0.0b9',
189
+ 'azure-core': '1.33.0',
190
+ 'openai': '1.0.0'
191
  }
192
 
193
+ # System dependencies for manim (Ubuntu/Debian-based systems)
194
+ system_dependencies = [
195
+ "libcairo2-dev",
196
+ "pkg-config",
197
+ "python3-dev",
198
+ "libpango1.0-dev",
199
+ "ffmpeg",
200
+ "texlive-latex-recommended",
201
+ "texlive-fonts-recommended",
202
+ "texlive-latex-extra",
203
+ "fonts-dejavu-core",
204
+ "libsndfile1"
205
+ ]
206
+
207
+ with st.spinner("Checking and installing system dependencies..."):
208
+ # Check if we're on a system that uses apt
209
+ apt_available = False
210
+ try:
211
+ result = subprocess.run(
212
+ ["which", "apt-get"],
213
+ capture_output=True,
214
+ text=True,
215
+ check=False
216
+ )
217
+ apt_available = result.returncode == 0
218
+ except Exception:
219
+ apt_available = False
220
+
221
+ if apt_available:
222
+ # Install system dependencies
223
+ progress_bar = st.progress(0)
224
+ status_text = st.empty()
225
+
226
+ # Update apt
227
+ status_text.text("Updating package lists...")
228
+ try:
229
+ # First try with sudo
230
+ sudo_password = None
231
+ if is_sudo_available():
232
+ sudo_password = st.text_input("Enter sudo password for system package installation:", type="password")
233
+ if sudo_password:
234
+ run_with_sudo(["apt-get", "update"], sudo_password)
235
+ else:
236
+ # Try without password (cached sudo credentials)
237
+ run_with_sudo(["apt-get", "update"])
238
+ else:
239
+ # Try without sudo
240
+ subprocess.run(["apt-get", "update"], capture_output=True)
241
+ except Exception as e:
242
+ logger.warning(f"Error updating apt: {str(e)}")
243
+
244
+ # Install each dependency
245
+ for i, package in enumerate(system_dependencies):
246
+ progress = (i / len(system_dependencies))
247
+ progress_bar.progress(progress)
248
+ status_text.text(f"Installing system dependency: {package}...")
249
+
250
+ try:
251
+ # Try with sudo
252
+ if is_sudo_available() and sudo_password:
253
+ result = run_with_sudo(
254
+ ["apt-get", "install", "-y", package],
255
+ sudo_password
256
+ )
257
+ else:
258
+ # Try without sudo
259
+ result = subprocess.run(
260
+ ["apt-get", "install", "-y", package],
261
+ capture_output=True,
262
+ text=True
263
+ )
264
+
265
+ if result.returncode != 0:
266
+ logger.warning(f"Could not install system package {package}: {result.stderr}")
267
+ except Exception as e:
268
+ logger.warning(f"Error installing system package {package}: {str(e)}")
269
+
270
+ progress_bar.progress(1.0)
271
+ status_text.text("System dependencies installation complete!")
272
+ time.sleep(0.5)
273
+ progress_bar.empty()
274
+ status_text.empty()
275
+ else:
276
+ # If not on an apt-based system, show message
277
+ st.warning("System dependencies may need to be installed manually. See the documentation for details.")
278
+
279
+ # Check and install Python packages
280
+ with st.spinner("Checking required Python packages..."):
281
  # First, quickly check if packages are already installed
282
  missing_packages = {}
283
  for package, version in required_packages.items():
 
318
  import scipy
319
  elif package == 'huggingface_hub':
320
  import huggingface_hub
321
+ elif package == 'azure-ai-inference':
322
+ import azure.ai.inference
323
+ elif package == 'azure-core':
324
+ import azure.core
325
+ elif package == 'openai':
326
+ import openai
327
  except ImportError:
328
  missing_packages[package] = version
329
 
330
  # If no packages are missing, return success immediately
331
  if not missing_packages:
332
+ logger.info("All required Python packages already installed.")
333
  return True
334
 
335
  # If there are missing packages, install them with progress reporting
336
  progress_bar = st.progress(0)
337
  status_text = st.empty()
338
 
339
+ # Check if pip install requires sudo
340
+ pip_requires_sudo = False
341
+ try:
342
+ # Try to write to site-packages
343
+ import site
344
+ site_packages = site.getsitepackages()[0]
345
+ # Check if we have write access
346
+ test_file = os.path.join(site_packages, "test_write_access.txt")
347
+ try:
348
+ with open(test_file, "w") as f:
349
+ f.write("test")
350
+ os.remove(test_file)
351
+ except (PermissionError, OSError):
352
+ pip_requires_sudo = True
353
+ except Exception:
354
+ # If anything goes wrong, assume we might need sudo
355
+ pip_requires_sudo = True
356
+
357
+ # Ask for sudo password if needed
358
+ sudo_password = None
359
+ if pip_requires_sudo and is_sudo_available():
360
+ sudo_password = st.text_input("Enter sudo password for Python package installation:", type="password")
361
+
362
  for i, (package, version) in enumerate(missing_packages.items()):
363
  try:
364
  progress = (i / len(missing_packages))
365
  progress_bar.progress(progress)
366
  status_text.text(f"Installing {package}...")
367
 
368
+ pip_install_cmd = [sys.executable, "-m", "pip", "install", f"{package}>={version}"]
369
+
370
+ if pip_requires_sudo and is_sudo_available():
371
+ # Use sudo for pip install
372
+ if sudo_password:
373
+ result = run_with_sudo(pip_install_cmd, sudo_password)
374
+ else:
375
+ # Try without password (cached sudo credentials)
376
+ result = run_with_sudo(pip_install_cmd)
377
+ else:
378
+ # Use normal pip install
379
+ result = subprocess.run(
380
+ pip_install_cmd,
381
+ capture_output=True,
382
+ text=True
383
+ )
384
 
385
  if result.returncode != 0:
386
  st.error(f"Failed to install {package}: {result.stderr}")
 
393
  return False
394
 
395
  progress_bar.progress(1.0)
396
+ status_text.text("All Python packages installed successfully!")
397
  time.sleep(0.5)
398
  progress_bar.empty()
399
  status_text.empty()
400
  return True
401
 
402
  def install_custom_packages(package_list):
403
+ """Install custom packages specified by the user with sudo if needed"""
404
  if not package_list.strip():
405
  return True, "No packages specified"
406
 
 
413
  status_placeholder = st.sidebar.empty()
414
  progress_bar = st.sidebar.progress(0)
415
 
416
+ # Check if pip install requires sudo
417
+ pip_requires_sudo = False
418
+ try:
419
+ # Try to write to site-packages
420
+ import site
421
+ site_packages = site.getsitepackages()[0]
422
+ # Check if we have write access
423
+ test_file = os.path.join(site_packages, "test_write_access.txt")
424
+ try:
425
+ with open(test_file, "w") as f:
426
+ f.write("test")
427
+ os.remove(test_file)
428
+ except (PermissionError, OSError):
429
+ pip_requires_sudo = True
430
+ except Exception:
431
+ # If anything goes wrong, assume we might need sudo
432
+ pip_requires_sudo = True
433
+
434
+ # Ask for sudo password if needed
435
+ sudo_password = None
436
+ if pip_requires_sudo and is_sudo_available():
437
+ sudo_password = st.text_input("Enter sudo password for custom package installation:", type="password")
438
+
439
  results = []
440
  success = True
441
 
 
445
  progress_bar.progress(progress)
446
  status_placeholder.text(f"Installing {package}...")
447
 
448
+ pip_install_cmd = [sys.executable, "-m", "pip", "install", package]
449
+
450
+ if pip_requires_sudo and is_sudo_available():
451
+ # Use sudo for pip install
452
+ if sudo_password:
453
+ result = run_with_sudo(pip_install_cmd, sudo_password)
454
+ else:
455
+ # Try without password (cached sudo credentials)
456
+ result = run_with_sudo(pip_install_cmd)
457
+ else:
458
+ # Use normal pip install
459
+ result = subprocess.run(
460
+ pip_install_cmd,
461
+ capture_output=True,
462
+ text=True
463
+ )
464
 
465
  if result.returncode != 0:
466
  error_msg = f"Failed to install {package}: {result.stderr}"
 
485
 
486
  return success, "\n".join(results)
487
 
488
+ # Install C/C++ libraries with sudo if needed
489
+ def install_cpp_libraries(libraries):
490
+ """Install C/C++ libraries using system package manager with sudo if needed"""
491
+ if not libraries:
492
+ return True, "No libraries specified"
493
+
494
+ # Library to package mappings for different systems
495
+ library_packages = {
496
+ "Ubuntu": {
497
+ "Eigen": ["libeigen3-dev"],
498
+ "Boost": ["libboost-all-dev"],
499
+ "OpenCV": ["libopencv-dev", "python3-opencv"],
500
+ "FFTW": ["libfftw3-dev"],
501
+ "SDL2": ["libsdl2-dev"],
502
+ "SFML": ["libsfml-dev"],
503
+ "OpenGL": ["libgl1-mesa-dev", "libglu1-mesa-dev", "freeglut3-dev"]
504
+ },
505
+ "Debian": {
506
+ "Eigen": ["libeigen3-dev"],
507
+ "Boost": ["libboost-all-dev"],
508
+ "OpenCV": ["libopencv-dev", "python3-opencv"],
509
+ "FFTW": ["libfftw3-dev"],
510
+ "SDL2": ["libsdl2-dev"],
511
+ "SFML": ["libsfml-dev"],
512
+ "OpenGL": ["libgl1-mesa-dev", "libglu1-mesa-dev", "freeglut3-dev"]
513
+ },
514
+ "Fedora": {
515
+ "Eigen": ["eigen3-devel"],
516
+ "Boost": ["boost-devel"],
517
+ "OpenCV": ["opencv-devel", "python3-opencv"],
518
+ "FFTW": ["fftw-devel"],
519
+ "SDL2": ["SDL2-devel"],
520
+ "SFML": ["SFML-devel"],
521
+ "OpenGL": ["mesa-libGL-devel", "mesa-libGLU-devel", "freeglut-devel"]
522
+ },
523
+ "CentOS": {
524
+ "Eigen": ["eigen3-devel"],
525
+ "Boost": ["boost-devel"],
526
+ "OpenCV": ["opencv-devel"],
527
+ "FFTW": ["fftw-devel"],
528
+ "SDL2": ["SDL2-devel"],
529
+ "SFML": ["SFML-devel"],
530
+ "OpenGL": ["mesa-libGL-devel", "mesa-libGLU-devel", "freeglut-devel"]
531
+ },
532
+ "Arch": {
533
+ "Eigen": ["eigen"],
534
+ "Boost": ["boost"],
535
+ "OpenCV": ["opencv"],
536
+ "FFTW": ["fftw"],
537
+ "SDL2": ["sdl2"],
538
+ "SFML": ["sfml"],
539
+ "OpenGL": ["mesa", "glu", "freeglut"]
540
+ },
541
+ "MacOS": {
542
+ "Eigen": ["eigen"],
543
+ "Boost": ["boost"],
544
+ "OpenCV": ["opencv"],
545
+ "FFTW": ["fftw"],
546
+ "SDL2": ["sdl2"],
547
+ "SFML": ["sfml"],
548
+ "OpenGL": ["mesa", "freeglut"]
549
+ }
550
+ }
551
+
552
+ # Detect OS
553
+ os_name = "Unknown"
554
+ package_manager = None
555
+ install_cmd = []
556
+
557
+ if platform.system() == "Linux":
558
+ # Try to detect Linux distribution
559
+ try:
560
+ if os.path.exists("/etc/os-release"):
561
+ with open("/etc/os-release", "r") as f:
562
+ os_release = f.read()
563
+ if "Ubuntu" in os_release:
564
+ os_name = "Ubuntu"
565
+ package_manager = "apt-get"
566
+ install_cmd = ["apt-get", "install", "-y"]
567
+ elif "Debian" in os_release:
568
+ os_name = "Debian"
569
+ package_manager = "apt-get"
570
+ install_cmd = ["apt-get", "install", "-y"]
571
+ elif "Fedora" in os_release:
572
+ os_name = "Fedora"
573
+ package_manager = "dnf"
574
+ install_cmd = ["dnf", "install", "-y"]
575
+ elif "CentOS" in os_release:
576
+ os_name = "CentOS"
577
+ package_manager = "yum"
578
+ install_cmd = ["yum", "install", "-y"]
579
+ elif "Arch" in os_release:
580
+ os_name = "Arch"
581
+ package_manager = "pacman"
582
+ install_cmd = ["pacman", "-S", "--noconfirm"]
583
+
584
+ # Fallback detection
585
+ if os_name == "Unknown":
586
+ which_apt = subprocess.run(["which", "apt-get"], capture_output=True, text=True)
587
+ which_dnf = subprocess.run(["which", "dnf"], capture_output=True, text=True)
588
+ which_yum = subprocess.run(["which", "yum"], capture_output=True, text=True)
589
+ which_pacman = subprocess.run(["which", "pacman"], capture_output=True, text=True)
590
+
591
+ if which_apt.returncode == 0:
592
+ os_name = "Debian"
593
+ package_manager = "apt-get"
594
+ install_cmd = ["apt-get", "install", "-y"]
595
+ elif which_dnf.returncode == 0:
596
+ os_name = "Fedora"
597
+ package_manager = "dnf"
598
+ install_cmd = ["dnf", "install", "-y"]
599
+ elif which_yum.returncode == 0:
600
+ os_name = "CentOS"
601
+ package_manager = "yum"
602
+ install_cmd = ["yum", "install", "-y"]
603
+ elif which_pacman.returncode == 0:
604
+ os_name = "Arch"
605
+ package_manager = "pacman"
606
+ install_cmd = ["pacman", "-S", "--noconfirm"]
607
+ except Exception as e:
608
+ logger.error(f"Error detecting Linux distribution: {str(e)}")
609
+
610
+ elif platform.system() == "Darwin":
611
+ os_name = "MacOS"
612
+ which_brew = subprocess.run(["which", "brew"], capture_output=True, text=True)
613
+ if which_brew.returncode == 0:
614
+ package_manager = "brew"
615
+ install_cmd = ["brew", "install"]
616
+
617
+ # If package manager not detected, return error
618
+ if not package_manager:
619
+ return False, f"Could not detect package manager for {platform.system()}. Please install libraries manually."
620
+
621
+ # Get packages to install
622
+ all_packages = []
623
+ for library in libraries:
624
+ if os_name in library_packages and library in library_packages[os_name]:
625
+ all_packages.extend(library_packages[os_name][library])
626
+
627
+ if not all_packages:
628
+ return False, f"No packages found for the selected libraries on {os_name}. Please install libraries manually."
629
+
630
+ # Display progress
631
+ status_placeholder = st.sidebar.empty()
632
+ progress_bar = st.sidebar.progress(0)
633
+
634
+ # Ask for sudo password if needed (most package managers need sudo)
635
+ sudo_password = None
636
+ if is_sudo_available() and platform.system() != "Darwin": # macOS Homebrew doesn't need sudo
637
+ sudo_password = st.text_input("Enter sudo password for C/C++ library installation:", type="password")
638
+
639
+ results = []
640
+ success = True
641
+
642
+ # Update package lists if needed
643
+ if package_manager in ["apt-get", "apt"]:
644
+ status_placeholder.text("Updating package lists...")
645
+ try:
646
+ if is_sudo_available() and sudo_password:
647
+ result = run_with_sudo(["apt-get", "update"], sudo_password)
648
+ elif is_sudo_available():
649
+ result = run_with_sudo(["apt-get", "update"])
650
+ else:
651
+ result = subprocess.run(["apt-get", "update"], capture_output=True, text=True)
652
+
653
+ if result.returncode != 0:
654
+ logger.warning(f"Failed to update package lists: {result.stderr}")
655
+ results.append(f"Warning: Failed to update package lists: {result.stderr}")
656
+ except Exception as e:
657
+ logger.warning(f"Error updating package lists: {str(e)}")
658
+ results.append(f"Warning: Error updating package lists: {str(e)}")
659
+
660
+ # Install each package
661
+ for i, package in enumerate(all_packages):
662
+ try:
663
+ progress = (i / len(all_packages))
664
+ progress_bar.progress(progress)
665
+ status_placeholder.text(f"Installing {package}...")
666
+
667
+ cmd = install_cmd + [package]
668
+
669
+ if is_sudo_available() and platform.system() != "Darwin": # macOS Homebrew doesn't need sudo
670
+ if sudo_password:
671
+ result = run_with_sudo(cmd, sudo_password)
672
+ else:
673
+ result = run_with_sudo(cmd)
674
+ else:
675
+ result = subprocess.run(cmd, capture_output=True, text=True)
676
+
677
+ if result.returncode != 0:
678
+ error_msg = f"Failed to install {package}: {result.stderr}"
679
+ results.append(error_msg)
680
+ logger.error(error_msg)
681
+ success = False
682
+ else:
683
+ results.append(f"Successfully installed {package}")
684
+ logger.info(f"Successfully installed C/C++ library package: {package}")
685
+
686
+ except Exception as e:
687
+ error_msg = f"Error installing {package}: {str(e)}"
688
+ results.append(error_msg)
689
+ logger.error(error_msg)
690
+ success = False
691
+
692
+ progress_bar.progress(1.0)
693
+ status_placeholder.text("Installation complete!")
694
+ time.sleep(0.5)
695
+ progress_bar.empty()
696
+ status_placeholder.empty()
697
+
698
+ return success, "\n".join(results)
699
+
700
+ # Auto-detect C/C++ libraries
701
+ def detect_cpp_libraries():
702
+ """Auto-detect installed C/C++ libraries on the system"""
703
+ libraries = {}
704
+
705
+ # Function to check if a library is installed
706
+ def check_library(name, headers, pkg_config=None):
707
+ # Check if headers exist
708
+ header_found = False
709
+ for header in headers:
710
+ # Common include directories
711
+ include_dirs = [
712
+ "/usr/include",
713
+ "/usr/local/include",
714
+ "/opt/local/include",
715
+ "/opt/homebrew/include"
716
+ ]
717
+
718
+ for include_dir in include_dirs:
719
+ if os.path.exists(os.path.join(include_dir, header)):
720
+ header_found = True
721
+ break
722
+
723
+ # Check using pkg-config if available
724
+ pkg_config_found = False
725
+ if pkg_config:
726
+ try:
727
+ result = subprocess.run(
728
+ ["pkg-config", "--exists", pkg_config],
729
+ capture_output=True,
730
+ check=False
731
+ )
732
+ pkg_config_found = result.returncode == 0
733
+ except Exception:
734
+ pass
735
+
736
+ return header_found or pkg_config_found
737
+
738
+ # Check for common libraries
739
+ libraries["Eigen"] = check_library("Eigen", ["Eigen/Core", "eigen3/Eigen/Core"])
740
+ libraries["Boost"] = check_library("Boost", ["boost/config.hpp", "boost/version.hpp"])
741
+ libraries["OpenCV"] = check_library("OpenCV", ["opencv2/opencv.hpp"], "opencv4")
742
+ libraries["FFTW"] = check_library("FFTW", ["fftw3.h"], "fftw3")
743
+ libraries["SDL2"] = check_library("SDL2", ["SDL2/SDL.h"], "sdl2")
744
+ libraries["SFML"] = check_library("SFML", ["SFML/Graphics.hpp"], "sfml-all")
745
+ libraries["OpenGL"] = check_library("OpenGL", ["GL/gl.h", "OpenGL/gl.h"])
746
+
747
+ return libraries
748
+
749
  @st.cache_resource(ttl=3600)
750
  def init_ai_models_direct():
751
  """Direct implementation using the exact pattern from the example code"""
 
1298
  # IMPORTANT: Wait a moment for file system to catch up
1299
  time.sleep(3)
1300
 
 
 
1301
  # Special handling for GIF format - if Manim failed to generate a GIF but we have an MP4
1302
  if format_type == "gif" and (not output_file_path or not os.path.exists(output_file_path)) and mp4_output_path and os.path.exists(mp4_output_path):
1303
  status_placeholder.info("GIF generation via Manim failed. Trying FFmpeg conversion...")
 
1983
  if enable_debug:
1984
  compile_cmd.append("-g")
1985
 
1986
+ # Auto-detect include paths if not specified
1987
+ include_paths = settings.get("include_paths", [])
1988
+ if not include_paths:
1989
+ # Common include directories
1990
+ common_include_dirs = [
1991
+ "/usr/include",
1992
+ "/usr/local/include",
1993
+ "/opt/local/include",
1994
+ "/opt/homebrew/include"
1995
+ ]
1996
+
1997
+ # Add detected paths for specified libraries
1998
+ for lib in settings.get("libraries", []):
1999
+ if lib == "Eigen":
2000
+ for dir in common_include_dirs:
2001
+ if os.path.exists(os.path.join(dir, "Eigen")):
2002
+ include_paths.append(dir)
2003
+ elif os.path.exists(os.path.join(dir, "eigen3")):
2004
+ include_paths.append(dir)
2005
+ elif lib == "OpenCV":
2006
+ try:
2007
+ # Get OpenCV include paths using pkg-config
2008
+ result = subprocess.run(
2009
+ ["pkg-config", "--cflags", "opencv4"],
2010
+ capture_output=True,
2011
+ text=True,
2012
+ check=False
2013
+ )
2014
+ if result.returncode == 0:
2015
+ # Extract include paths from pkg-config output
2016
+ for flag in result.stdout.strip().split():
2017
+ if flag.startswith("-I"):
2018
+ include_paths.append(flag[2:])
2019
+ except Exception:
2020
+ pass
2021
+
2022
  # Add preprocessor definitions
2023
  for definition in settings.get("definitions", []):
2024
  if "=" in definition:
 
2028
  compile_cmd.append(f"-D{definition}")
2029
 
2030
  # Add include paths
2031
+ for path in include_paths:
2032
  compile_cmd.append(f"-I{path}")
2033
 
2034
  # Add library paths
 
3027
  with st.expander("Installation Results"):
3028
  st.code(st.session_state.custom_library_result)
3029
 
3030
+ # System Package Management section
3031
+ with st.sidebar.expander("🛠️ System Package Management"):
3032
+ st.markdown("## System Dependencies")
3033
+ st.markdown("Manage system packages and libraries")
3034
+
3035
+ # Auto-detect C/C++ libraries
3036
+ if st.button("Detect Installed Libraries", key="detect_system_libs"):
3037
+ with st.spinner("Detecting installed libraries..."):
3038
+ libraries = detect_cpp_libraries()
3039
+
3040
+ # Display results
3041
+ st.markdown("### Detected Libraries")
3042
+ for lib, installed in libraries.items():
3043
+ if installed:
3044
+ st.success(f"✅ {lib}: Installed")
3045
+ else:
3046
+ st.warning(f"⚠️ {lib}: Not detected")
3047
+
3048
+ # Install C/C++ libraries
3049
+ st.markdown("### Install C/C++ Libraries")
3050
+ cpp_libs_to_install = st.multiselect(
3051
+ "Select libraries to install",
3052
+ options=["Eigen", "Boost", "OpenCV", "FFTW", "SDL2", "SFML", "OpenGL"],
3053
+ default=[]
3054
+ )
3055
+
3056
+ if st.button("Install Selected Libraries", key="install_cpp_libs"):
3057
+ success, result = install_cpp_libraries(cpp_libs_to_install)
3058
+ if success:
3059
+ st.success("Libraries installed successfully!")
3060
+ else:
3061
+ st.error("Failed to install some libraries")
3062
+ st.code(result)
3063
+
3064
+ # System package installation
3065
+ st.markdown("### Install System Packages")
3066
+ system_packages = st.text_area(
3067
+ "Enter system packages to install (comma separated)",
3068
+ placeholder="e.g., ffmpeg, git, cmake"
3069
+ )
3070
+
3071
+ if st.button("Install System Packages", key="install_system_packages"):
3072
+ if not system_packages.strip():
3073
+ st.warning("No packages specified")
3074
+ else:
3075
+ packages = [pkg.strip() for pkg in system_packages.split(',') if pkg.strip()]
3076
+
3077
+ # Detect package manager
3078
+ package_manager = None
3079
+ install_cmd = []
3080
+
3081
+ if platform.system() == "Linux":
3082
+ which_apt = subprocess.run(["which", "apt-get"], capture_output=True, text=True)
3083
+ which_dnf = subprocess.run(["which", "dnf"], capture_output=True, text=True)
3084
+ which_yum = subprocess.run(["which", "yum"], capture_output=True, text=True)
3085
+ which_pacman = subprocess.run(["which", "pacman"], capture_output=True, text=True)
3086
+
3087
+ if which_apt.returncode == 0:
3088
+ package_manager = "apt-get"
3089
+ install_cmd = ["apt-get", "install", "-y"]
3090
+ elif which_dnf.returncode == 0:
3091
+ package_manager = "dnf"
3092
+ install_cmd = ["dnf", "install", "-y"]
3093
+ elif which_yum.returncode == 0:
3094
+ package_manager = "yum"
3095
+ install_cmd = ["yum", "install", "-y"]
3096
+ elif which_pacman.returncode == 0:
3097
+ package_manager = "pacman"
3098
+ install_cmd = ["pacman", "-S", "--noconfirm"]
3099
+
3100
+ elif platform.system() == "Darwin":
3101
+ which_brew = subprocess.run(["which", "brew"], capture_output=True, text=True)
3102
+ if which_brew.returncode == 0:
3103
+ package_manager = "brew"
3104
+ install_cmd = ["brew", "install"]
3105
+
3106
+ if not package_manager:
3107
+ st.error(f"Could not detect package manager for {platform.system()}. Please install packages manually.")
3108
+ else:
3109
+ # Ask for sudo password if needed
3110
+ sudo_password = None
3111
+ if is_sudo_available() and platform.system() != "Darwin": # macOS Homebrew doesn't need sudo
3112
+ sudo_password = st.text_input("Enter sudo password for system package installation:", type="password")
3113
+
3114
+ # Update package lists if needed
3115
+ if package_manager in ["apt-get", "apt"]:
3116
+ with st.spinner("Updating package lists..."):
3117
+ try:
3118
+ if is_sudo_available() and sudo_password:
3119
+ result = run_with_sudo(["apt-get", "update"], sudo_password)
3120
+ elif is_sudo_available():
3121
+ result = run_with_sudo(["apt-get", "update"])
3122
+ else:
3123
+ result = subprocess.run(["apt-get", "update"], capture_output=True, text=True)
3124
+
3125
+ if result.returncode != 0:
3126
+ st.warning(f"Failed to update package lists: {result.stderr}")
3127
+ except Exception as e:
3128
+ st.warning(f"Error updating package lists: {str(e)}")
3129
+
3130
+ # Install packages
3131
+ results = []
3132
+ success = True
3133
+
3134
+ progress_bar = st.sidebar.progress(0)
3135
+ status_text = st.sidebar.empty()
3136
+
3137
+ for i, package in enumerate(packages):
3138
+ try:
3139
+ progress = (i / len(packages))
3140
+ progress_bar.progress(progress)
3141
+ status_text.text(f"Installing {package}...")
3142
+
3143
+ cmd = install_cmd + [package]
3144
+
3145
+ if is_sudo_available() and platform.system() != "Darwin": # macOS Homebrew doesn't need sudo
3146
+ if sudo_password:
3147
+ result = run_with_sudo(cmd, sudo_password)
3148
+ else:
3149
+ result = run_with_sudo(cmd)
3150
+ else:
3151
+ result = subprocess.run(cmd, capture_output=True, text=True)
3152
+
3153
+ if result.returncode != 0:
3154
+ error_msg = f"Failed to install {package}: {result.stderr}"
3155
+ results.append(error_msg)
3156
+ success = False
3157
+ else:
3158
+ results.append(f"Successfully installed {package}")
3159
+
3160
+ except Exception as e:
3161
+ error_msg = f"Error installing {package}: {str(e)}"
3162
+ results.append(error_msg)
3163
+ success = False
3164
+
3165
+ progress_bar.progress(1.0)
3166
+ time.sleep(0.5)
3167
+ progress_bar.empty()
3168
+ status_text.empty()
3169
+
3170
+ if success:
3171
+ st.success("All packages installed successfully!")
3172
+ else:
3173
+ st.error("Failed to install some packages")
3174
+
3175
+ st.code("\n".join(results))
3176
+
3177
  # C/C++ Library Options
3178
  with st.sidebar.expander("C/C++ Library Options"):
3179
  st.markdown("### Advanced C/C++ Settings")