|
1 | 1 | using System.Text; |
2 | 2 | using System.Text.RegularExpressions; |
| 3 | +using System.Text.Json; |
3 | 4 | using Azure; |
4 | 5 | using Azure.Data.Tables; |
| 6 | +using Azure.Storage.Blobs; |
5 | 7 | using Markdig; |
6 | 8 | using Shared; |
7 | 9 | using YamlDotNet.Serialization; |
|
36 | 38 | { |
37 | 39 | // Check if the path is a directory or a file |
38 | 40 | if (Directory.Exists(filePath)) |
39 | | - { |
40 | | - // Recursively get all markdown files in the directory |
| 41 | + { // Recursively get all markdown files |
41 | 42 | var mdFiles = Directory.GetFiles(filePath, "*.md", SearchOption.AllDirectories); |
| 43 | + |
| 44 | + // For each markdown file, look for images in its adjacent images folder |
| 45 | + var imageFiles = mdFiles |
| 46 | + .SelectMany(mdFile => |
| 47 | + { |
| 48 | + var mdDirectory = Path.GetDirectoryName(mdFile); |
| 49 | + var imagesPath = Path.Combine(mdDirectory!, "images"); |
| 50 | + return Directory.Exists(imagesPath) |
| 51 | + ? Directory.GetFiles(imagesPath, "*.*", SearchOption.AllDirectories) |
| 52 | + .Where(f => new[] { ".jpg", ".jpeg", ".png", ".gif", ".webp" } |
| 53 | + .Contains(Path.GetExtension(f).ToLowerInvariant())) |
| 54 | + : Array.Empty<string>(); |
| 55 | + }) |
| 56 | + .Distinct() |
| 57 | + .ToArray(); |
| 58 | + |
42 | 59 | if (mdFiles.Length == 0) |
43 | 60 | { |
44 | 61 | Console.WriteLine($"No markdown files found in directory: {filePath}"); |
45 | 62 | return 1; |
46 | | - } int addedCount = 0; |
| 63 | + } // Create blob service client for image uploads |
| 64 | + var blobServiceClient = new BlobServiceClient(connectionString); |
| 65 | + |
| 66 | + // Process images first |
| 67 | + Console.WriteLine("\nProcessing images..."); |
| 68 | + var imageUploadResults = new List<ImageInfo>(); |
| 69 | + foreach (var imageFile in imageFiles) |
| 70 | + { |
| 71 | + try |
| 72 | + { |
| 73 | + var imageInfo = await ImageUploadHelper.ProcessAndUploadImageAsync(imageFile, blobServiceClient); |
| 74 | + imageUploadResults.Add(imageInfo); |
| 75 | + Console.WriteLine($"Processed image: {imageFile}"); |
| 76 | + } |
| 77 | + catch (Exception ex) |
| 78 | + { |
| 79 | + Console.WriteLine($"Error processing image {imageFile}: {ex.Message}"); |
| 80 | + } |
| 81 | + } |
| 82 | + |
| 83 | + // Now process markdown files |
| 84 | + Console.WriteLine("\nProcessing markdown files..."); |
| 85 | + int addedCount = 0; |
47 | 86 | int updatedCount = 0; |
48 | 87 | int unchangedCount = 0; |
49 | 88 | int failedCount = 0; |
50 | 89 |
|
51 | 90 | foreach (var mdFile in mdFiles) |
52 | | - { |
53 | | - try |
| 91 | + { try |
54 | 92 | { |
| 93 | + // Parse markdown and look for image references |
55 | 94 | TipModel tip = Shared.ContentUploadHelper.ParseMarkdownFile(mdFile); |
| 95 | + // Replace image references in content with proper image IDs |
| 96 | + foreach (var image in imageUploadResults) |
| 97 | + { |
| 98 | + // Get the markdown file's directory |
| 99 | + var mdDirectory = Path.GetDirectoryName(mdFile)!; |
| 100 | + // Get the image's directory |
| 101 | + var imageDirectory = Path.GetDirectoryName(image.OriginalPath)!; |
| 102 | + // Calculate relative path from markdown to image |
| 103 | + var relativePath = Path.GetRelativePath(mdDirectory, imageDirectory); |
| 104 | + var localImagePath = Path.Combine(relativePath, image.FileName).Replace("\\", "/"); |
| 105 | + |
| 106 | + tip.Content = tip.Content.Replace( |
| 107 | + $"]({localImagePath}", |
| 108 | + $"](/article-images/{image.ImageId}/original.{Path.GetExtension(image.FileName).TrimStart('.')}" |
| 109 | + ); |
| 110 | + } |
| 111 | + |
| 112 | + // Add the image info to the content entity |
| 113 | + tip.Images = JsonSerializer.Serialize(imageUploadResults); |
| 114 | + |
56 | 115 | var status = await Shared.ContentUploadHelper.UploadToTableStorage(tip, connectionString); |
57 | 116 |
|
58 | 117 | switch (status) |
|
86 | 145 | Console.WriteLine($"Total: {mdFiles.Length}"); |
87 | 146 |
|
88 | 147 | return failedCount == 0 ? 0 : 1; |
89 | | - } |
90 | | - else |
| 148 | + } else |
91 | 149 | { |
92 | 150 | // Parse the markdown file |
93 | 151 | if (!File.Exists(filePath)) |
94 | 152 | { |
95 | 153 | Console.WriteLine($"File not found: {filePath}"); |
96 | 154 | return 1; |
97 | 155 | } |
| 156 | + |
| 157 | + // Create BlobServiceClient for single file |
| 158 | + var blobServiceClient = new BlobServiceClient(connectionString); |
| 159 | + var imageUploadResults = new List<ImageInfo>(); |
| 160 | + |
| 161 | + // Check if there are any images in the images directory |
| 162 | + var imageDir = Path.Combine(Path.GetDirectoryName(filePath)!, "images"); |
| 163 | + if (Directory.Exists(imageDir)) |
| 164 | + { |
| 165 | + var imageFiles = Directory.GetFiles(imageDir, "*.*") |
| 166 | + .Where(f => new[] { ".jpg", ".jpeg", ".png", ".gif", ".webp" } |
| 167 | + .Contains(Path.GetExtension(f).ToLowerInvariant())) |
| 168 | + .ToArray(); |
| 169 | + |
| 170 | + foreach (var imageFile in imageFiles) |
| 171 | + { |
| 172 | + try |
| 173 | + { |
| 174 | + var imageInfo = await ImageUploadHelper.ProcessAndUploadImageAsync(imageFile, blobServiceClient); |
| 175 | + imageUploadResults.Add(imageInfo); |
| 176 | + Console.WriteLine($"Processed image: {imageFile}"); |
| 177 | + } |
| 178 | + catch (Exception ex) |
| 179 | + { |
| 180 | + Console.WriteLine($"Error processing image {imageFile}: {ex.Message}"); |
| 181 | + } |
| 182 | + } |
| 183 | + } |
| 184 | + |
| 185 | + // Parse and process markdown |
98 | 186 | TipModel tip = Shared.ContentUploadHelper.ParseMarkdownFile(filePath); |
| 187 | + |
| 188 | + // Replace image references |
| 189 | + foreach (var image in imageUploadResults) |
| 190 | + { |
| 191 | + var localImagePath = $"images/{image.FileName}"; |
| 192 | + tip.Content = tip.Content.Replace( |
| 193 | + $"]({localImagePath}", |
| 194 | + $"](/images/{image.ImageId}/original" |
| 195 | + ); |
| 196 | + } |
| 197 | + |
| 198 | + // Add image info to content |
| 199 | + tip.Images = System.Text.Json.JsonSerializer.Serialize(imageUploadResults); |
| 200 | + |
99 | 201 | // Upload to Azure Table Storage |
100 | 202 | await Shared.ContentUploadHelper.UploadToTableStorage(tip, connectionString); |
101 | 203 | return 0; |
|
0 commit comments