תגובה: העלאת קובץ בapi לימות המשיח | קוד שבפייתון עובד וב nodejs לא כל כך
כתבתי את המחלקה הזו,
הקובץ המועלה - ריק,
כשהוספתי דיבאג להעלאת החלקים, אני מקבל אחרי כל חלק את השגיאה:
Failed to upload chunk 1: {"error":"Server error. Uploads directory isn't
writable","uploadName":null}
זה המחלקה,
(השוותי ידנית וגם ניסיתי עם קלוד, למחלקות בפייתון וnode שפורסמו שם, ללא הצלחה)
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Windows.Forms;
public class YemotUploader
{
// הגדרה אחת בלבד של גודל הצ'אנק
private static readonly int ChunkSizeBytes = 8000000; // 8MB
private byte[] ReadFileBytes(string filePath)
{
return File.ReadAllBytes(filePath);
}
private List<byte[]> ReadInChunks(string filePath)
{
var fileBytes = ReadFileBytes(filePath);
var chunks = new List<byte[]>();
for (int offset = 0; offset < fileBytes.Length; offset += ChunkSizeBytes)
{
int currentChunkSize = Math.Min(ChunkSizeBytes, fileBytes.Length - offset);
var chunk = new byte[currentChunkSize];
Array.Copy(fileBytes, offset, chunk, 0, currentChunkSize);
chunks.Add(chunk);
}
return chunks;
}
public async Task<string> UploadFileAsync(string filePath, string tokenYemot, string path, string convertAudio, string autoNumbering)
{
var fileInfo = new FileInfo(filePath);
var contentName = Path.GetFileName(filePath);
var contentSize = fileInfo.Length;
if (contentSize <= ChunkSizeBytes)
{
// העלאת קובץ קטן
return await UploadSmallFileAsync(filePath, tokenYemot, path, convertAudio, autoNumbering);
}
else
{
// העלאת קובץ גדול
return await UploadLargeFileAsync(filePath, tokenYemot, path, convertAudio, autoNumbering);
}
}
private async Task<string> UploadSmallFileAsync(string filePath, string tokenYemot, string path, string convertAudio, string autoNumbering)
{
using (var httpClient = new HttpClient())
using (var formData = new MultipartFormDataContent())
{
formData.Add(new StringContent(tokenYemot), "token");
formData.Add(new StringContent(path), "path");
formData.Add(new StringContent(convertAudio), "convertAudio");
formData.Add(new StringContent(autoNumbering), "autoNumbering");
var fileBytes = File.ReadAllBytes(filePath);
var fileContent = new ByteArrayContent(fileBytes);
fileContent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("form-data")
{
Name = "\"file\"",
FileName = $"\"{Path.GetFileName(filePath)}\""
};
fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
formData.Add(fileContent, "file");
var response = await httpClient.PostAsync("https://www.call2all.co.il/ym/api/UploadFile", formData);
return await response.Content.ReadAsStringAsync();
}
}
private async Task<string> UploadLargeFileAsync(string filePath, string tokenYemot, string path, string convertAudio, string autoNumbering)
{
var contentName = Path.GetFileName(filePath);
var contentSize = new FileInfo(filePath).Length;
var qquuid = Guid.NewGuid().ToString();
var chunks = ReadInChunks(filePath);
var failedChunks = new List<int>();
// העלאת כל הצ'אנקים
for (int i = 0; i < chunks.Count; i++)
{
try
{
using (var httpClient = new HttpClient())
using (var content = new MultipartFormDataContent())
{
var chunk = chunks[i];
var offset = i * ChunkSizeBytes;
content.Add(new StringContent(tokenYemot), "token");
content.Add(new StringContent(path), "path");
content.Add(new StringContent(qquuid), "qquuid");
content.Add(new StringContent(convertAudio), "convertAudio");
content.Add(new StringContent(autoNumbering), "autoNumbering");
content.Add(new StringContent("yemot-admin"), "uploader");
content.Add(new StringContent(contentName), "qqfilename");
content.Add(new StringContent(contentSize.ToString()), "qqtotalfilesize");
content.Add(new StringContent(chunks.Count.ToString()), "qqtotalparts");
content.Add(new StringContent(chunk.Length.ToString()), "qqchunksize");
content.Add(new StringContent(offset.ToString()), "qqpartbyteoffset");
content.Add(new StringContent(i.ToString()), "qqpartindex");
var fileContent = new ByteArrayContent(chunk);
fileContent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("form-data")
{
Name = "\"qqfile\"",
FileName = $"\"{contentName}\""
};
fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
content.Add(fileContent, "qqfile");
var response = await httpClient.PostAsync("https://www.call2all.co.il/ym/api/UploadFile", content);
var responseText = await response.Content.ReadAsStringAsync();
// בדיקה האם התגובה תקינה
if (!response.IsSuccessStatusCode || responseText.Contains("error"))
{
failedChunks.Add(i);
MessageBox.Show($"Failed to upload chunk {i}: {responseText}");
Console.WriteLine($"Failed to upload chunk {i}: {responseText}");
}
else
{
Console.WriteLine($"Successfully uploaded chunk {i}");
}
}
}
catch (Exception ex)
{
failedChunks.Add(i);
Console.WriteLine($"Error uploading chunk {i}: {ex.Message}");
}
}
// בדיקה האם כל הצ'אנקים הועלו בהצלחה
if (failedChunks.Count > 0)
{
throw new Exception($"Failed to upload chunks: {string.Join(", ", failedChunks)}");
}
// שליחת בקשת סיום
using (var httpClient = new HttpClient())
{
var finalFormData = new FormUrlEncodedContent(new Dictionary<string, string>
{
{ "token", tokenYemot },
{ "path", path },
{ "uploader", "yemot-admin" },
{ "convertAudio", convertAudio },
{ "autoNumbering", autoNumbering },
{ "qquuid", qquuid },
{ "qqfilename", contentName },
{ "qqtotalfilesize", contentSize.ToString() },
{ "qqtotalparts", chunks.Count.ToString() }
});
try
{
var doneResponse = await httpClient.PostAsync(
"https://www.call2all.co.il/ym/api/UploadFile?done",
finalFormData
);
var responseText = await doneResponse.Content.ReadAsStringAsync();
Console.WriteLine($"Done response: {responseText}");
// ניסיון לפרסור של הjson הכפול
if (!string.IsNullOrEmpty(responseText))
{
// מציאת ה-JSON הראשון בתגובה
int firstBrace = responseText.IndexOf('{');
int lastBrace = responseText.LastIndexOf('}');
if (firstBrace >= 0 && lastBrace > firstBrace)
{
string jsonPart = responseText.Substring(firstBrace, lastBrace - firstBrace + 1);
try
{
// בדיקה האם ה-JSON תקין
var jObject = JObject.Parse(jsonPart);
return jsonPart;
}
catch (JsonReaderException)
{
Console.WriteLine($"Invalid JSON response: {jsonPart}");
}
}
}
return responseText;
}
catch (Exception ex)
{
Console.WriteLine($"Error in done request: {ex.Message}");
throw;
}
}
}
}