Exemplo n.º 1
0
        public IHttpActionResult CleanClipboard(string id)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState.ToString()));
            }

            if (id == null)
            {
                throw new ArgumentNullException(nameof(id));
            }

            var uid       = Guid.Parse(id);
            var createdAt = GetOriginCreatedAt(uid);

            if (!createdAt.HasValue)
            {
                return(DtoResultV5.Success(Json, "Data already deleted"));
            }

            string path = GetFullClipboardDataPath(createdAt.Value); //ensure orig item and (soft)deleted item in the same file

            if (!File.Exists(path))
            {
                return(DtoResultV5.Success(Json, "no data"));
            }

            var notes     = ReadLskjson <Guid, DtoClipboardItem>(path, CollectLskjsonLineClipboard);
            var foundNote = notes.FirstOrDefault(n => n.Uid == uid);

            if (foundNote == null)
            {
                return(DtoResultV5.Success(Json, "already deleted"));
            }

            foundNote.HasDeleted = true;
            //todo - replace with real UserId(get by session id)
            foundNote.DeletedBy = Constants.DevDeleteUserId + DateTime.Now.ToString("dd");
            foundNote.DeletedAt = DateTime.Now;

            //need replace a line in the file - seems there is no way to just rewrite one line, have to re-write entire file
            // - https://stackoverflow.com/questions/1971008/edit-a-specific-line-of-a-text-file-in-c-sharp
            // - https://stackoverflow.com/questions/13509532/how-to-find-and-replace-text-in-a-file-with-c-sharp
            var backupPath = path.Replace(Constants.LskjsonPrefix, Constants.LskjsonPrefix + DateTime.Now.ToString("dd-HHmmss-"));

            File.Move(path, backupPath);
            var success = AppendNoteToFile(path, notes.ToArray());

            if (success)
            {
                File.Delete(backupPath);
                return(DtoResultV5.Success(Json, "Data deleted"));
            }
            else
            {
                File.Move(backupPath, path);
                return(DtoResultV5.Fail(Json, "Failed to delete data"));
            }
        }
Exemplo n.º 2
0
        public IHttpActionResult HeartBeat(string user)
        {
            _logger.Info("enter heart beat, user: "******"leave heart beat");

            return(DtoResultV5.Success(Json, $"heart heat. {count}"));
        }
Exemplo n.º 3
0
        public IHttpActionResult Get()
        {
            var fulfillments = ReadFulfillmentsOfThisYear(AuthMode.Simple);

            //for migrate
            if (fulfillments.Any(f => !f.HasMigrated || f.LastFulfill.HasValue))
            {
                foreach (var fulfill in fulfillments)
                {
                    if (!fulfill.HasMigrated)
                    {
                        fulfill.HasMigrated = true;

                        if (fulfill.HistoryFulfillments?.Length > 0)
                        {
                            var migrateUnit = fulfill.HistoryFulfillments.Select(h => new FulfillmentArchive(fulfill.Uid, null, h));
                            //var archivePath = GetFullIntrospectionDataPath(DateTime.Now, IntrospectionDataType.Archives);
                            //AppendObjectToFile(archivePath, migrateUnit.ToArray());

                            fulfill.StagedArchives = migrateUnit.ToArray();
                        }
                    }

                    if (fulfill.LastFulfill.HasValue)
                    {
                        var record = new FulfillmentArchive(fulfill.Uid, fulfill.LastRemark, fulfill.LastFulfill, fulfill.UpdateBy, fulfill.UpdateAt);

                        if (fulfill.StagedArchives?.Length > 0)
                        {
                            var staged = fulfill.StagedArchives.ToList();
                            staged.Add(record);
                            fulfill.StagedArchives = staged.ToArray();
                        }
                        else
                        {
                            fulfill.StagedArchives = new[] { record };
                        }

                        fulfill.LastFulfill = null;
                        fulfill.LastRemark  = null;
                    }
                }

                var path = GetFullIntrospectionDataPath(DateTime.Now, IntrospectionDataType.Fulfillments);

                WriteToFile(path, fulfillments);
            }

            var dtoList = fulfillments.Select(f => DtoRoutine.From(f, false));

            return(DtoResultV5.Success(Json, dtoList));
        }
Exemplo n.º 4
0
        public IHttpActionResult Delete2(string id, [FromBody] DeleteBody body)
        {
            if (string.IsNullOrEmpty(id))
            {
                throw new ArgumentNullException(nameof(id));
            }
            if (body == null)
            {
                throw new ArgumentNullException(nameof(body));
            }

            var perf            = PerfCounter.NewThenCheck(this.ToString() + "." + MethodBase.GetCurrentMethod().Name);
            var fulfillmentPath = GetFullIntrospectionDataPath(DateTime.Now, IntrospectionDataType.Fulfillments);
            var antiSpamResult  = PassAntiSpamDefender(fulfillmentPath, AuthMode.SimpleDeletion);

            if (!antiSpamResult.Valid)
            {
                return(DtoResultV5.Fail(BadRequest, antiSpamResult.Message));
            }
            perf.Check("anti spam end");

            SyncRoutine(fulfillmentPath);
            perf.Check("sync routine end");

            var fulfillments = ReadLskjson <Guid, RoutineFulfillment>(fulfillmentPath, CollectLskjsonLineIncludeDeleted);

            perf.Check("read fulfillment end");

            var inputUid = Guid.Parse(id);
            var fulfill  = fulfillments.FirstOrDefault(f => f.Uid == inputUid);

            if (fulfill == null)
            {
                return(DtoResultV5.Fail(BadRequest, "Routine not found, may already deleted, please refresh page"));
            }

            fulfill.IsDeleted    = true;
            fulfill.DeleteAt     = DateTime.Now;
            fulfill.DeletedBy    = "fixme-delete";
            fulfill.DeleteReason = body.Reason;

            WriteToFile(fulfillmentPath, fulfillments);
            perf.End("override fulfill end", true);
            return(DtoResultV5.Success(Json, DtoRoutine.From(fulfill, false)));
        }
Exemplo n.º 5
0
        public IHttpActionResult PutRecursive(string id, [FromBody] PutRecursiveBody body)
        {
            if (id == null)
            {
                throw new ArgumentNullException(nameof(id));
            }
            if (body == null)
            {
                throw new ArgumentNullException(nameof(body));
            }
            if (body.Enable && (body.IntervalDays ?? 0) < 1)
            {
                throw new ArgumentException($"invalid recursive interval {body.IntervalDays}");
            }

            var perf            = PerfCounter.NewThenCheck(this.ToString() + "." + MethodBase.GetCurrentMethod().Name);
            var fulfillmentPath = GetFullIntrospectionDataPath(DateTime.Now, IntrospectionDataType.Fulfillments);

            SyncRoutine(fulfillmentPath);
            perf.Check("sync routine end");

            var fulfillments = ReadLskjson <Guid, RoutineFulfillment>(fulfillmentPath, CollectLskjsonLineIncludeDeleted);

            perf.Check("read fulfillment end");

            var inputUid = Guid.Parse(id);
            var fulfill  = fulfillments.FirstOrDefault(f => f.Uid == inputUid);

            if (fulfill == null)
            {
                return(DtoResultV5.Fail(BadRequest, "expired data found, please reload page first."));
            }

            fulfill.EnableSchedule = body.Enable;
            if (body.Enable)
            {
                fulfill.RecursiveIntervalDays = body.IntervalDays;
            }
            fulfill.UpdateBy = "fixme-put-rec";
            fulfill.UpdateAt = DateTime.Now;

            WriteToFile(fulfillmentPath, fulfillments);
            perf.End("override fulfill end", true);
            return(DtoResultV5.Success(Json, DtoRoutine.From(fulfill, false)));
        }
Exemplo n.º 6
0
        public IHttpActionResult Get(string id, string history = null)
        {
            if (string.IsNullOrWhiteSpace(id))
            {
                return(DtoResultV5.Fail(BadRequest, "id is empty"));
            }

            if (Constants.LskArchived.Equals(history, StringComparison.OrdinalIgnoreCase))
            {
                var archivePath        = GetFullIntrospectionDataPath(DateTime.Now, IntrospectionDataType.Archives);
                var archivedRecords    = ReadLskjson <Guid, FulfillmentArchive>(archivePath, CollectLskjsonLineIncludeDeleted);
                var recordsByParentUid = archivedRecords.Where(a => id.Equals(a.ParentUid.ToString(), StringComparison.OrdinalIgnoreCase));
                return(DtoResultV5.Success(Json, recordsByParentUid.Select(r => DtoFulfillmentArchive.From(r))));
            }
            else
            {
                var fulfillments = ReadFulfillmentsOfThisYear(AuthMode.None);
                var fulfillment  = fulfillments.FirstOrDefault(f => id.Equals(f.Uid.ToString(), StringComparison.OrdinalIgnoreCase));
                var dto          = fulfillment == null ? null : DtoRoutine.From(fulfillment, true);
                return(DtoResultV5.Success(Json, dto));
            }
        }
Exemplo n.º 7
0
        public IHttpActionResult Clipboard([FromBody] PostBody body)
        {
            if (body == null)
            {
                throw new ArgumentNullException(nameof(body));
            }
            if (string.IsNullOrEmpty(body.Data))
            {
                throw new ArgumentNullException(nameof(body.Data));
            }

            //todo improve this, hard coded as dev session id for now
            if (!CheckHeaderSession())
            {
                //return Unauthorized();
            }

            var time = body.CreatedAt ?? DateTime.Now;
            var item = new DtoClipboardItem()
            {
                Uid       = Guid.NewGuid(),
                CreatedBy = MapToUserId(Request.Headers.GetValues(Constants.HeaderSessionId).First()),
                CreatedAt = time,
                Data      = body.Data
            };

            string path = GetFullClipboardDataPath(time);

            AppendNoteToFile(path, item);

            string indexPath = GetFullClipboardIndexPath(time);

            AppendObjectToFile(indexPath, DtoLskjsonIndex.From(item));

            return(DtoResultV5.Success(Json, $"{body.Data.Length} characters saved to clipboard."));
        }
Exemplo n.º 8
0
        public IHttpActionResult Clipboard([FromBody] PutBody putBody)
        {
            if (putBody == null)
            {
                throw new ArgumentNullException(nameof(putBody));
            }
            if (putBody.Uid == null)
            {
                throw new ArgumentNullException(nameof(putBody.Uid));
            }

            var inputUid = Guid.Parse(putBody.Uid);

            //todo improve this, hard coded as dev session id for now
            if (!CheckHeaderSession())
            {
                //return Unauthorized();
            }

            var createdAt = GetOriginCreatedAt(inputUid);

            if (!createdAt.HasValue)
            {
                throw new InvalidOperationException("Data already deleted, please reload to latest then edit");
            }

            var path = GetFullClipboardDataPath(createdAt.Value); //ensure orig item and updated item in the same file

            if (!File.Exists(path))
            {
                return(DtoResultV5.Success(this.Json, "no data"));
            }

            //perf - O(n) is 2n here, can be optimized to n
            var notes      = ReadLskjson <Guid, DtoClipboardItem>(path, CollectLskjsonLineClipboard);
            var foundNote  = notes.FirstOrDefault(n => n.Uid == inputUid);
            var foundChild = notes.FirstOrDefault(n => n.ParentUid == inputUid);

            //ensure the relation is a chain, not a tree
            if (foundChild != null)
            {
                throw new InvalidOperationException("Data already changed, please reload to latest then edit");
            }

            if (foundNote != null)
            {
                var newNote = Utility.DeepClone(foundNote);

                newNote.Uid  = Guid.NewGuid(); //reset
                newNote.Data = putBody.Data;

                //todo - replace with real UserId(get by session id)
                newNote.HasUpdated    = true;
                newNote.LastUpdatedBy = Constants.DevUpdateUserId + DateTime.Now.ToString("dd");
                newNote.LastUpdatedAt = DateTime.Now;
                newNote.ParentUid     = foundNote.Uid;

                AppendNoteToFile(path, newNote);
                AppendObjectToFile(GetFullClipboardIndexPath(newNote.CreatedAt), DtoLskjsonIndex.From(newNote));

                //return DtoResultV5.Success(Json, MapToJSNameConvention(newNote), "Data updated");
                return(DtoResultV5.Success(Json, newNote, "Data updated")); //do the map on client side
            }
            else
            {
                return(DtoResultV5.Fail(Json, "The data you want to update may have been deleted"));
            }
        }
Exemplo n.º 9
0
        public IHttpActionResult Clipboard()
        {
            int      pageSize  = 50;
            int      pageIndex = 0;
            DateTime time      = DateTime.Now;

            if (!CheckHeaderSession())
            {
                //return Unauthorized();
            }

            string path = GetFullClipboardDataPath(time);

            if (!File.Exists(path))
            {
                return(DtoResultV5.Success(Json, "no data"));
            }

            var items = ReadLskjson <Guid, DtoClipboardItem>(path, CollectLskjsonLineClipboard, pageIndex, pageSize);

            //read all files created this year and till the month of passed in time
            var oldFileTime = new DateTime(time.Year, time.Month, 1);
            var endFileTime = new DateTime(time.Year, 1, 1);

            while (oldFileTime > endFileTime)
            {
                oldFileTime = oldFileTime.AddMonths(-1);
                var oldFilePath = GetFullClipboardDataPath(oldFileTime);

                if (File.Exists(oldFilePath))
                {
                    var oldData           = ReadLskjson <Guid, DtoClipboardItem>(oldFilePath, CollectLskjsonLineClipboard, 0, int.MaxValue);
                    var numberOfDataToAdd = Constants.LskMaxReturnNoteCount - items.Count;
                    items.AddRange(oldData.Take(Math.Min(numberOfDataToAdd, oldData.Count)));

                    if (items.Count >= Constants.LskMaxReturnNoteCount)
                    {
                        break;
                    }
                }
            }


            //todo - filter items by lskjson index file??

            //var jsonObjects = MapToJSNameConvention(items);
            var jsonObjects = items; //do the mapping on client side

            return(DtoResultV5.Success(Json, jsonObjects, "v5"));

            //following code works only when the entire file is in valid format - which is not the case here
            //since we just append new line to the file(a proper json array string should quote by '[]' and item separated by ',')
            //  - a workaround for saving is deserialize entire file into a collection, add the new item then save the collection to the file again which is poor performance
            //using (var reader = File.OpenText(GetFullClipboardDataPath(DateTime.MinValue)))
            //using (var jsonReader = new Newtonsoft.Json.JsonTextReader(reader))
            //{
            //    var serializer = new Newtonsoft.Json.JsonSerializer();
            //    var items = serializer.Deserialize<DtoClipboardItem[]>(jsonReader);
            //    return Json(items);
            //}
        }
Exemplo n.º 10
0
        public IHttpActionResult DeleteHistoryRecord2(string parentId, string id, [FromBody] DeleteHistoryBody body)
        {
            if (string.IsNullOrEmpty(parentId))
            {
                throw new ArgumentNullException(nameof(parentId));
            }
            if (body == null)
            {
                throw new ArgumentNullException(nameof(body));
            }
            if (body.Kind != Constants.LskArchived && body.Kind != Constants.LskStaged)
            {
                return(DtoResultV5.Fail(BadRequest, $"unsupported deletion: '{body.Kind}'"));
            }


            var perf            = PerfCounter.NewThenCheck(this.ToString() + "." + MethodBase.GetCurrentMethod().Name);
            var fulfillmentPath = GetFullIntrospectionDataPath(DateTime.Now, IntrospectionDataType.Fulfillments);
            var antiSpamResult  = PassAntiSpamDefender(fulfillmentPath, AuthMode.SimpleDeletion);

            if (!antiSpamResult.Valid)
            {
                return(DtoResultV5.Fail(BadRequest, antiSpamResult.Message));
            }
            perf.Check("anti spam end");

            SyncRoutine(fulfillmentPath);
            perf.Check("sync routine end");

            var inputParentUid = Guid.Parse(parentId);
            var inputUid       = Guid.Parse(id);

            string filePath = null;
            List <ILskjsonLine> allRecords = null;
            FulfillmentArchive  history    = null;

            if (body.Kind == Constants.LskStaged)
            {
                filePath = fulfillmentPath;
                var fulfillments = ReadLskjson <Guid, RoutineFulfillment>(filePath, CollectLskjsonLineIncludeDeleted);
                var fulfill      = fulfillments.FirstOrDefault(f => f.Uid == inputParentUid);

                if (fulfill == null)
                {
                    return(DtoResultV5.Fail(BadRequest, "Routine not found, may already deleted, please refresh page"));
                }
                if (!fulfill.HasMigrated)
                {
                    return(DtoResultV5.Fail(BadRequest, "Migrate routine first"));
                }
                if (fulfill.StagedArchives == null || fulfill.StagedArchives.Length == 0)
                {
                    return(DtoResultV5.Fail(BadRequest, "No staged history found, please refresh page"));
                }

                allRecords = fulfillments.ToList <ILskjsonLine>();
                history    = fulfill.StagedArchives.FirstOrDefault(s => s.Uid == inputUid);
            }
            else if (body.Kind == Constants.LskArchived)
            {
                filePath = GetFullIntrospectionDataPath(DateTime.Now, IntrospectionDataType.Archives);
                var historyRecords = ReadLskjson <Guid, FulfillmentArchive>(filePath, CollectLskjsonLineIncludeDeleted);
                allRecords = historyRecords.ToList <ILskjsonLine>();
                history    = historyRecords.FirstOrDefault(h => h.ParentUid == inputParentUid && h.Uid == inputUid);
            }

            if (history == null)
            {
                return(DtoResultV5.Fail(BadRequest, $"No {body.Kind} history matches with provided id, please refresh page"));
            }

            history.IsDeleted    = true;
            history.DeleteAt     = DateTime.Now;
            history.DeletedBy    = "fixme-del";
            history.DeleteReason = body.Reason;

            WriteToFile(filePath, allRecords);
            perf.End($"delete {body.Kind} history end", true);
            return(DtoResultV5.Success(Json, body.Kind));
        }
Exemplo n.º 11
0
        public IHttpActionResult Put(string id, [FromBody] PutBody body)
        {
            if (id == null)
            {
                throw new ArgumentNullException(nameof(id));
            }
            if (body == null)
            {
                throw new ArgumentNullException(nameof(body));
            }

            var perf            = PerfCounter.NewThenCheck(this.ToString() + "." + MethodBase.GetCurrentMethod().Name);
            var fulfillmentPath = GetFullIntrospectionDataPath(DateTime.Now, IntrospectionDataType.Fulfillments);
            var antiSpamResult  = PassAntiSpamDefender(fulfillmentPath, AuthMode.None);

            if (!antiSpamResult.Valid)
            {
                return(DtoResultV5.Fail(BadRequest, antiSpamResult.Message));
            }
            perf.Check("anti spam end");

            SyncRoutine(fulfillmentPath);
            perf.Check("sync routine end");

            var fulfillments = ReadLskjson <Guid, RoutineFulfillment>(fulfillmentPath, CollectLskjsonLineIncludeDeleted);

            perf.Check("read fulfillment end");

            var inputUid = Guid.Parse(id);
            var fulfill  = fulfillments.FirstOrDefault(f => f.Uid == inputUid);

            if (fulfill == null)
            {
                return(DtoResultV5.Fail(BadRequest, "expired data found, please reload page first."));
            }

            var offsetDays = int.Parse(antiSpamResult.Message);
            var date       = DateTime.Now.AddDays(-1 * Math.Abs(offsetDays));
            var record     = new FulfillmentArchive(fulfill.Uid, body.LastRemark, date, "fixme-put", DateTime.Now);

            if (fulfill.StagedArchives == null)
            {
                fulfill.StagedArchives = new[] { record };
            }
            else
            {
                var staged = fulfill.StagedArchives.ToList();
                staged.Add(record);

                if (staged.Count >= Constants.LskFulfillmentActiveRecords + Constants.LskFulfillmentArchiveUnit)
                {
                    const int startIndex  = 0;
                    var       archiveUnit = staged.GetRange(startIndex, Constants.LskFulfillmentArchiveUnit);
                    var       archivePath = GetFullIntrospectionDataPath(DateTime.Now, IntrospectionDataType.Archives);
                    AppendObjectToFile(archivePath, archiveUnit.ToArray());
                    staged.RemoveRange(startIndex, archiveUnit.Count);
                    fulfill.HasArchived = true;
                }

                fulfill.StagedArchives = staged.ToArray();
            }

            //fulfill.StagedArchives = fulfill.StagedArchives.Concat(new[] { record }).ToArray();
            fulfill.UpdateBy = "fixme-update";
            fulfill.UpdateAt = DateTime.Now;

            WriteToFile(fulfillmentPath, fulfillments);
            perf.End("override fulfill end", true);
            return(DtoResultV5.Success(Json, DtoRoutine.From(fulfill, false)));
        }