Browse Source

import 调整

JAELYS 4 years ago
parent
commit
751c87b4dc
1 changed files with 340 additions and 0 deletions
  1. 340 0
      TEAMModelOS/Controllers/Import/ImportExerciseController.cs

+ 340 - 0
TEAMModelOS/Controllers/Import/ImportExerciseController.cs

@@ -0,0 +1,340 @@
+using Azure.Storage.Blobs.Models;
+using Azure.Storage.Sas;
+using HTEXLib;
+using HTEXLib.Builders;
+using HTEXLib.Helpers.ShapeHelpers;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IdentityModel.Tokens.Jwt;
+using System.IO;
+using System.Linq;
+using System.Net.Http;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+using TEAMModelOS.SDK.Models;
+using TEAMModelOS.Models.Dto;
+using TEAMModelOS.Models.PowerPoint;
+using TEAMModelOS.SDK;
+using TEAMModelOS.SDK.Context.Constant;
+using TEAMModelOS.SDK.Context.Constant.Common;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.SDK.Extension;
+using TEAMModelOS.SDK.Module.AzureBlob.Configuration;
+using TEAMModelOS.SDK.Module.AzureBlob.Container;
+using TEAMModelOS.Services;
+using HTEXLib.Translator;
+using HTEXLib.DOCX.Models;
+
+namespace TEAMModelOS.Controllers
+{
+    [Route("import")]
+    [ApiController]
+    public class ImportController : ControllerBase
+    {
+        public PPTX2HTEXTranslator _PPTX2HTEXTranslator { get; set; }
+        public DOXC2HTMLTranslator _DOXC2HTMLTranslator { get; set; }
+        public HTML2ITEMTranslator _HTML2ITEMTranslator { get; set; }
+        //  private readonly IHtexService htexService;
+        private readonly AzureStorageFactory _azureStorage;
+        private readonly IWebHostEnvironment _webHostEnvironment;
+        private  List<LangConfig> langConfigs { get; set; }
+        private readonly IHttpClientFactory _clientFactory;
+        public ImportController(   AzureStorageFactory azureStorage, IWebHostEnvironment webHostEnvironment,
+            PPTX2HTEXTranslator PPTX2HTEXTranslator, IHttpClientFactory clientFactory,
+            DOXC2HTMLTranslator DOXC2HTMLTranslator, HTML2ITEMTranslator HTML2ITEMTranslator)
+        {
+            _HTML2ITEMTranslator = HTML2ITEMTranslator;
+            _DOXC2HTMLTranslator = DOXC2HTMLTranslator;
+            _clientFactory = clientFactory;
+            this._PPTX2HTEXTranslator = PPTX2HTEXTranslator;
+            _webHostEnvironment = webHostEnvironment;
+            _azureStorage = azureStorage;
+            string path = _webHostEnvironment.ContentRootPath + "/JsonFile/Core/LangConfig.json";
+            FileStream fs = new FileStream(path, System.IO.FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
+            StreamReader sr = new StreamReader(fs, System.Text.Encoding.UTF8);
+            String line;
+            StringBuilder builder = new StringBuilder();
+            while ((line = sr.ReadLine()) != null)
+            {
+                builder.Append(line.ToString());
+            }
+
+            sr.Close();
+            string text = builder.ToString();
+            langConfigs = text.ToObject<List<LangConfig>>();
+        }
+       
+
+        /// <summary>
+        /// {"url":"https://***.blob.core.cn/xxx/1.pptx"}
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("pptx")]
+        [RequestSizeLimit(102_400_000_00)] //最大10000m左右
+        public async Task<IActionResult> ParsePPTX(JsonElement request)
+        {
+            //string id_token = HttpContext.GetXAuth("IdToken");
+            //if (string.IsNullOrEmpty(id_token)) return BadRequest();
+            //var jwt = new JwtSecurityToken(id_token);
+            //if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.OrdinalIgnoreCase)) return BadRequest();
+            //var id = jwt.Payload.Sub;
+
+            request.TryGetProperty("file", out JsonElement code);
+            string azureBlobSAS = System.Web.HttpUtility.UrlDecode(code.ToString(), Encoding.UTF8);
+            (string, string) a = BlobUrlString(azureBlobSAS);
+            string ContainerName = a.Item1;
+            string BlobName = a.Item2;
+            bool flg = IsBlobName(BlobName);
+            var codes = azureBlobSAS.Split("/");
+            var file = codes[codes.Length - 1].Split(".");
+            var FileName = file[0];
+            var ext = file[1];
+            if (flg)
+            {
+                BlobAuth blobAuth = _azureStorage.GetBlobSasUriRead(ContainerName, BlobName);
+                var response = await _clientFactory.CreateClient().GetAsync(new Uri(blobAuth.url));
+                response.EnsureSuccessStatusCode();
+                Stream stream=  await response.Content.ReadAsStreamAsync();
+
+                if (ext.ToLower() == "pptx" || ext.ToLower() == "xml")
+                {
+                    string index = await PPTXTranslator(ContainerName, FileName, stream);
+                    return Ok(new { index = index });
+                }
+                else if (ext.ToLower() == "docx" || ext.ToLower() == "doc")
+                {
+                    return Ok(new { index = "" });
+                }
+                else {
+                    return BadRequest("不支持该文件类型的解析!");
+                }
+            }
+            else { return BadRequest("不是正确的Blob链接!"); }
+        }
+
+        [HttpPost("docx")]
+        [RequestSizeLimit(102_400_000_00)] //最大10000m左右
+        public async Task<IActionResult> ParseDocx(JsonElement request)
+        {
+            return Ok();
+        }
+        private static (string, string) BlobUrlString(string sasUrl)
+        {
+            sasUrl = sasUrl.Substring(8);
+            string[] sasUrls = sasUrl.Split("/");
+            string ContainerName;
+            ContainerName = sasUrls[1].Clone().ToString();
+            string item = sasUrls[0] + "/" + sasUrls[1] + "/";
+            string blob = sasUrl.Replace(item, "");
+            return (ContainerName, blob);
+        }
+        public static bool IsBlobName(string BlobName)
+        {
+            return System.Text.RegularExpressions.Regex.IsMatch(BlobName,
+             @"(?!((^(con)$)|^(con)\\..*|(^(prn)$)|^(prn)\\..*|(^(aux)$)|^(aux)\\..*|(^(nul)$)|^(nul)\\..*|(^(com)[1-9]$)|^(com)[1-9]\\..*|(^(lpt)[1-9]$)|^(lpt)[1-9]\\..*)|^\\s+|.*\\s$)(^[^\\\\\\:\\<\\>\\*\\?\\\\\\""\\\\|]{1,255}$)");
+        }
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("upload-pptx")]
+        [RequestSizeLimit(102_400_000_00)] //最大10000m左右
+        public async Task<IActionResult> UploadPPTX([FromForm] IFormFile file)
+        {
+
+            string id_token = HttpContext.GetXAuth("IdToken");
+            if (string.IsNullOrEmpty(id_token)) return BadRequest();
+            var jwt = new JwtSecurityToken(id_token);
+            if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.OrdinalIgnoreCase)) return BadRequest();
+            var id = jwt.Payload.Sub;
+            if (FileType.GetExtention(file.FileName).ToLower().Equals("pptx") || FileType.GetExtention(file.FileName).ToLower().Equals("xml"))
+            {
+                string FileName = file.FileName.Split(".")[0];
+                Stream streamFile = file.OpenReadStream();
+                string index = await PPTXTranslator(id, FileName, streamFile);
+                return Ok(new { index = index });
+            }
+            else {
+                return BadRequest("type is not pptx or xml !");
+            }
+            
+           
+        }
+
+        /// <summary>
+        /// docUrl
+        /// folder
+        /// shaCode
+        /// 
+        /// UploadWord
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("upload-word")]
+        [RequestSizeLimit(102_400_000_00)] //最大10000m左右
+        public   IActionResult UploadWord([FromForm] IFormFile file)
+        {
+          //  ResponseBuilder responseBuilder = new ResponseBuilder();
+            if (!FileType.GetExtention(file.FileName).ToLower().Equals("docx"))
+            {
+                return BadRequest(new Dictionary<string, object> { {"msg", "type is not docx!" },{ "code",ResponseCode.FAILED} });
+            }
+
+            var doc= _DOXC2HTMLTranslator.Translate(file.OpenReadStream());
+           // Dictionary<string, object> model = await ImportExerciseService.UploadWord(_azureStorage, file);
+            return Ok(doc);
+        }
+
+        /// <summary>
+        /// htmlString AnalyzeHtml
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("parse-html")]
+        public  IActionResult  AnalyzeHtml(JsonElement request)
+        {
+            //ResponseBuilder builder = ResponseBuilder.custom();
+            Dictionary<string, object> dict = new Dictionary<string, object>();
+            var emobj = request.EnumerateObject();
+            while (emobj.MoveNext())
+            {
+                dict[emobj.Current.Name] = emobj.Current.Value;
+            }
+            bool flag = dict.TryGetValue("htmlString", out object htmlString);
+            bool flagLang = dict.TryGetValue("lang", out object lang);
+            if (flag && htmlString != null && !string.IsNullOrEmpty(htmlString.ToString()))
+            {
+                LangConfig langConfig= langConfigs.Where(x => x.Lang == lang.ToString()).FirstOrDefault();
+                var exercises= _HTML2ITEMTranslator.Translate(htmlString.ToString(), langConfig);
+                return Ok(exercises);
+            }
+            else
+            {
+                return BadRequest();
+            }
+        }
+       
+
+        private async Task<string> PPTXTranslator(string id, string FileName, Stream streamFile)
+        {
+            var status = await _azureStorage.GetBlobServiceClient().DelectBlobs(id, $"res/{FileName}");
+            string shaCode = Guid.NewGuid().ToString("N");
+            HTEXLib.Htex htex = _PPTX2HTEXTranslator.Translate(streamFile);
+            htex.name = FileName;
+            var slides = htex.slides;
+            List<Task> tasks = new List<Task>();
+            HTEX hTEX = new HTEX() { name = FileName, size = htex.size, thumbnail = htex.thumbnail, id = shaCode };
+            Dictionary<string, string> texts = new Dictionary<string, string>();
+            List<string> shas = new List<string>();
+            foreach (var slide in slides)
+            {
+                string text = JsonHelper.ToJson(slide, ignoreNullValue: false);
+                string sha = Guid.NewGuid().ToString("N");
+                texts.Add(sha, text);
+                shas.Add(sha);
+            }
+            Dictionary<string, string> bloburls = new Dictionary<string, string>();
+            foreach (var key in texts.Keys)
+            {
+                tasks.Add(_azureStorage.UploadFileByContainer(id, texts[key], "res", FileName + "/" + key + ".json", false)
+                    .ContinueWith((Task<AzureBlobModel> blob) =>
+                    {
+                        bloburls.Add(key, blob.Result.BlobUrl);
+                    })
+                    );
+            }
+            await Task.WhenAll(tasks);
+            List<Sld> slds = new List<Sld>();
+            foreach (string sha in shas)
+            {
+                slds.Add(new Sld { type = "normal", url = System.Web.HttpUtility.UrlDecode(bloburls[sha], Encoding.UTF8), scoring = null }); ;
+            }
+            Dictionary<string, Store> dict = new Dictionary<string, Store>();
+            List<Task> tasksFiles = new List<Task>();
+            foreach (var key in htex.stores.Keys)
+            {
+                if (key.EndsWith(".wdp") || key.EndsWith(".xlsx"))
+                {
+                    htex.stores.Remove(key);
+                    continue;
+                }
+                var store = htex.stores[key];
+                Store str = new Store() { path = key, contentType = store.contentType, isLazy = store.isLazy };
+                if (!store.isLazy && store.contentType != null && ContentTypeDict.extdict.TryGetValue(store.contentType, out string ext) && store.url.Contains(";base64,"))
+                {
+                    string[] strs = store.url.Split(',');
+                    Stream stream = new MemoryStream(Convert.FromBase64String(strs[1]));
+                    var urlstrs = key.Split("/");
+                    var name = urlstrs[urlstrs.Length - 1];
+                    tasksFiles.Add(_azureStorage.UploadFileByContainer(id, stream, "res", FileName + "/" + name, false)
+                        .ContinueWith((Task<AzureBlobModel> blob) =>
+                        {
+                            str.url = System.Web.HttpUtility.UrlDecode(blob.Result.BlobUrl, Encoding.UTF8);
+                        })
+                        );
+                }
+                else
+                {
+                    str.url = System.Web.HttpUtility.UrlDecode(store.url, Encoding.UTF8);
+                }
+                dict.TryAdd(key, str);
+            }
+            await Task.WhenAll(tasksFiles);
+            hTEX.stores = dict;
+            hTEX.slides = slds;
+            var blob=  await _azureStorage.UploadFileByContainer(id, JsonHelper.ToJson(hTEX, ignoreNullValue: false), "res", FileName + "/" + "index.json", false);
+            return System.Web.HttpUtility.UrlDecode(blob.BlobUrl, Encoding.UTF8);
+        }
+    }
+
+    public class HTEX {
+        public string id { get; set; }
+        public string version { get; set; } = "1.0.20201210";
+        public string name { get; set; }
+        public HTEXLib.HtexSize size { get; set; }
+        public List<Sld> slides { get; set; }
+        //缩略图
+        public string thumbnail { get; set; }
+        //  public int page { get; set; }
+        public Dictionary<string, Store> stores { get; set; }
+        public List<string> points { get; set; }
+        public string periodId { get; set; }
+        public List<string> gradeIds { get; set; }
+        public string subjectId { get; set; }
+        public string subjectName { get; set; }
+        public string score { get; set; }
+        public string code { get; set; }
+        public string scope { get; set; }
+        public int? multipleRule { get; set; }
+    }
+    public class Sld {
+        /// <summary>
+        /// normal,普通的hte页面 single 单选题 multiple 多选题 judge 判断题 complete 填空题 subjective 问答题 compose 综合题 
+        /// </summary>
+        public string type { get; set; }
+        /// <summary>
+        /// 单页PPTx htex 的解析链接或一个题目的链接
+        /// </summary>
+        public string url { get; set; }
+        /// <summary>
+        /// 题目的配分,如果为type为normal 及compose ,则 scoring=null
+        /// </summary>
+        public Scoring scoring { get; set; }
+        /// <summary>
+        /// 单页PPTx htex 的缩略图
+        /// </summary>
+        public string thumbnail { get; set; }
+    }
+
+    public class Scoring { 
+        public double score { get; set; }
+        public List<string> ans { get; set; } = new List<string>();
+    }
+}