Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/treetrek.git
includes/helpers.php
<?php
-/**
- * Helper utility functions
- */
-
function isImageFile($filename) {
- $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
- return in_array($ext, ['png', 'jpg', 'jpeg', 'gif', 'svg', 'webp', 'bmp', 'ico']);
+ $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
+ return in_array($ext, ['png', 'jpg', 'jpeg', 'gif', 'svg', 'webp', 'bmp', 'ico']);
+}
+
+function isVideoFile($filename) {
+ $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
+ return in_array($ext, ['mp4', 'webm', 'ogg', 'mov', 'avi', 'mkv', 'm4v']);
}
function getImageMimeType($filename) {
- $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
- $mimeTypes = [
- 'png' => 'image/png',
- 'jpg' => 'image/jpeg',
- 'jpeg' => 'image/jpeg',
- 'gif' => 'image/gif',
- 'svg' => 'image/svg+xml',
- 'webp' => 'image/webp',
- 'bmp' => 'image/bmp',
- 'ico' => 'image/x-icon'
- ];
- return $mimeTypes[$ext] ?? 'application/octet-stream';
+ $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
+ $mimeTypes = [
+ 'png' => 'image/png',
+ 'jpg' => 'image/jpeg',
+ 'jpeg' => 'image/jpeg',
+ 'gif' => 'image/gif',
+ 'svg' => 'image/svg+xml',
+ 'webp' => 'image/webp',
+ 'bmp' => 'image/bmp',
+ 'ico' => 'image/x-icon'
+ ];
+ return $mimeTypes[$ext] ?? 'application/octet-stream';
+}
+
+function getVideoMimeType($filename) {
+ $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
+ $mimeTypes = [
+ 'mp4' => 'video/mp4',
+ 'webm' => 'video/webm',
+ 'ogg' => 'video/ogg',
+ 'mov' => 'video/quicktime',
+ 'avi' => 'video/x-msvideo',
+ 'mkv' => 'video/x-matroska',
+ 'm4v' => 'video/x-m4v'
+ ];
+ return $mimeTypes[$ext] ?? 'application/octet-stream';
}
function formatDate($timestamp) {
- return date('M j, Y H:i', intval($timestamp));
+ return date('M j, Y H:i', intval($timestamp));
}
function timeAgo($timestamp) {
- $diff = time() - intval($timestamp);
+ $diff = time() - intval($timestamp);
- if ($diff < 60) {
- return 'just now';
- }
+ if ($diff < 60) {
+ return 'just now';
+ }
- $units = [
- 31536000 => 'year',
- 2592000 => 'month',
- 604800 => 'week',
- 86400 => 'day',
- 3600 => 'hour',
- 60 => 'minute',
- ];
+ $units = [
+ 31536000 => 'year',
+ 2592000 => 'month',
+ 604800 => 'week',
+ 86400 => 'day',
+ 3600 => 'hour',
+ 60 => 'minute',
+ ];
- foreach ($units as $seconds => $unit_name) {
- if ($diff >= $seconds) {
- $value = floor($diff / $seconds);
- $plural = ($value > 1) ? 's' : '';
- return $value . ' ' . $unit_name . $plural . ' ago';
- }
+ foreach ($units as $seconds => $unit_name) {
+ if ($diff >= $seconds) {
+ $value = floor($diff / $seconds);
+ $plural = ($value > 1) ? 's' : '';
+ return $value . ' ' . $unit_name . $plural . ' ago';
}
+ }
}
views/blob.php
$name = $_GET['name'] ?? 'file';
$isImage = isImageFile($name);
+$isVideo = isVideoFile($name);
// Check file size before loading
$repoPath = REPOS_PATH . '/' . basename($repo);
$isBare = is_file($repoPath . '/HEAD') && !is_dir($repoPath . '/.git');
if ($isBare) {
- $sizeCmd = "git --git-dir=" . escapeshellarg($repoPath) . " cat-file -s " . escapeshellarg($hash);
+ $sizeCmd = "git --git-dir=" . escapeshellarg($repoPath) . " cat-file -s " . escapeshellarg($hash);
} else {
- $sizeCmd = "cd " . escapeshellarg($repoPath) . " && git cat-file -s " . escapeshellarg($hash);
+ $sizeCmd = "cd " . escapeshellarg($repoPath) . " && git cat-file -s " . escapeshellarg($hash);
}
$fileSize = intval(trim(shell_exec($sizeCmd)));
$maxDisplaySize = 10 * 1024 * 1024; // 10MB limit for display
+$maxVideoSize = 100 * 1024 * 1024; // 100MB limit for video playback
$tooLarge = $fileSize > $maxDisplaySize;
+$videoTooLarge = $isVideo && $fileSize > $maxVideoSize;
?>
<div class="breadcrumb">
- <a href="?theme=<?php echo $current_theme; ?>">Repositories</a> <span>/</span>
- <a href="?action=repo&repo=<?php echo urlencode($repo); ?>&theme=<?php echo $current_theme; ?>"><?php echo htmlspecialchars($repo); ?></a> <span>/</span>
- <a href="?action=repo&repo=<?php echo urlencode($repo); ?>&view=tree&theme=<?php echo $current_theme; ?>">Files</a> <span>/</span>
- <strong><?php echo htmlspecialchars($name); ?></strong>
+ <a href="?theme=<?php echo $current_theme; ?>">Repositories</a> <span>/</span>
+ <a href="?action=repo&repo=<?php echo urlencode($repo); ?>&theme=<?php echo $current_theme; ?>"><?php echo htmlspecialchars($repo); ?></a> <span>/</span>
+ <a href="?action=repo&repo=<?php echo urlencode($repo); ?>&view=tree&theme=<?php echo $current_theme; ?>">Files</a> <span>/</span>
+ <strong><?php echo htmlspecialchars($name); ?></strong>
</div>
<div class="card">
- <div class="card-header">
- <?php echo htmlspecialchars($name); ?>
- <span style="color: #666; font-size: 0.9em; margin-left: 10px;">
- (<?php echo number_format($fileSize / 1024, 2); ?> KB)
- </span>
+ <div class="card-header">
+ <?php echo htmlspecialchars($name); ?>
+ <span style="color: #666; font-size: 0.9em; margin-left: 10px;">
+ (<?php echo number_format($fileSize / 1024, 2); ?> KB)
+ </span>
+ </div>
+ <div class="file-actions">
+ <a href="?action=raw&repo=<?php echo urlencode($repo); ?>&hash=<?php echo urlencode($hash); ?>&name=<?php echo urlencode($name); ?>" class="btn" download>
+ 📥 Download
+ </a>
+ </div>
+
+ <?php if ($videoTooLarge): ?>
+ <div class="empty-state">
+ <div class="empty-state-icon">⚠️</div>
+ <p>Video file is too large to play in browser (<?php echo number_format($fileSize / 1024 / 1024, 2); ?> MB)</p>
+ <p>Please download it to view the contents.</p>
</div>
- <div class="file-actions">
- <a href="?action=raw&repo=<?php echo urlencode($repo); ?>&hash=<?php echo urlencode($hash); ?>&name=<?php echo urlencode($name); ?>" class="btn" download>
- 📥 Download
- </a>
+ <?php elseif ($isVideo): ?>
+ <div class="video-preview">
+ <video controls style="max-width: 100%; height: auto;">
+ <source src="data:<?php echo getVideoMimeType($name); ?>;base64,<?php echo base64_encode(getBlobBinary($repo, $hash)); ?>" type="<?php echo getVideoMimeType($name); ?>">
+ Your browser does not support the video tag.
+ </video>
</div>
-
- <?php if ($tooLarge): ?>
- <div class="empty-state">
- <div class="empty-state-icon">⚠️</div>
- <p>File is too large to display (<?php echo number_format($fileSize / 1024 / 1024, 2); ?> MB)</p>
- <p>Please download it to view the contents.</p>
- </div>
- <?php elseif ($isImage): ?>
- <div class="image-preview">
- <img src="data:<?php echo getImageMimeType($name); ?>;base64,<?php echo base64_encode(getBlobBinary($repo, $hash)); ?>" alt="<?php echo htmlspecialchars($name); ?>">
- </div>
- <?php else:
- $content = getBlob($repo, $hash);
- if (empty($content) || mb_detect_encoding($content, 'UTF-8', true) === false):
- ?>
- <div class="empty-state">
- <div class="empty-state-icon">📦</div>
- <p>This appears to be a binary file.</p>
- <p>Please download it to view the contents.</p>
- </div>
- <?php else: ?>
- <div class="code-block">
- <pre><?php echo htmlspecialchars($content); ?></pre>
- </div>
- <?php endif; ?>
+ <?php elseif ($tooLarge): ?>
+ <div class="empty-state">
+ <div class="empty-state-icon">⚠️</div>
+ <p>File is too large to display (<?php echo number_format($fileSize / 1024 / 1024, 2); ?> MB)</p>
+ <p>Please download it to view the contents.</p>
+ </div>
+ <?php elseif ($isImage): ?>
+ <div class="image-preview">
+ <img src="data:<?php echo getImageMimeType($name); ?>;base64,<?php echo base64_encode(getBlobBinary($repo, $hash)); ?>" alt="<?php echo htmlspecialchars($name); ?>">
+ </div>
+ <?php else:
+ $content = getBlob($repo, $hash);
+ if (empty($content) || mb_detect_encoding($content, 'UTF-8', true) === false):
+ ?>
+ <div class="empty-state">
+ <div class="empty-state-icon">📦</div>
+ <p>This appears to be a binary file.</p>
+ <p>Please download it to view the contents.</p>
+ </div>
+ <?php else: ?>
+ <div class="code-block">
+ <pre><?php echo htmlspecialchars($content); ?></pre>
+ </div>
<?php endif; ?>
+ <?php endif; ?>
</div>
-

Adds support for playing videos

Author Dave Jarvis <email>
Date 2026-01-14 22:10:15 GMT-0800
Commit 04707ac61d876649099e13d1a3a7058ae5d970c1
Parent 833cf09
Delta 108 lines added, 78 lines removed, 30-line increase