static void Main(string[] args) { var user = new User { Id = 1, Name = "Name" }; var phone = new Phone { Id = 1, PhoneCode = "123", Value = "123124" }; var userRepository = new ObjectRepository <User>(); userRepository.Add(user); var contactRepository = new ObjectRepository <Phone>(); contactRepository.Add(phone); foreach (var value in contactRepository.GetAll()) { var contact = (Contact)value; Console.WriteLine(contact.Value); } contactRepository.Add(user); foreach (var value in contactRepository.GetAll()) { var contact = (Contact)value; Console.WriteLine(contact.Value); } }
public async Task <IActionResult> SmsIfThisThenThat() { var success = GetJsonResponseForSms(true); try { string data; using (var ms = new MemoryStream()) { await HttpContext.Request.Body.CopyToAsync(ms); ms.Position = 0; data = await new HttpRequestStreamReader(ms, Encoding.UTF8).ReadToEndAsync(); } _logger.LogInformation(data); var items = JObject.Parse(data); var from = items["from"].Value <string>(); if (string.IsNullOrWhiteSpace(from)) { from = items["fromNumber"].Value <string>(); } var message = items["message"].Value <string>(); var when = items["sent_timestamp"].Value <string>(); var whenDate = DateTime.Parse(when.Replace("at", "")); var smsModel = new SmsModel(@from, message, whenDate); lock (typeof(SmsModel)) { var existingMessage = _objectRepository.Set <SmsModel>() .FirstOrDefault(s => Math.Abs((s.When - smsModel.When).TotalMinutes) < 2 && smsModel.Message.StartsWith(s.Message)); if (existingMessage == null) { _objectRepository.Add(smsModel); } else { existingMessage.Message = smsModel.Message; } } _logger.LogInformation($"parsed form: {from} {message} {when}"); } catch (Exception ex) { _logger.LogError(ex, "Failed to parse sms"); success = GetJsonResponseForSms(false, "failed to get result " + ex); } return(Content(success, "application/json")); }
public void EditDebt(Debt request) { DebtModel model; if (request.Id.ToGuid() == Guid.Empty) { model = new DebtModel(); ObjectRepository.Add(model); } else { model = ObjectRepository.Set <DebtModel>().First(v => v.Id == request.Id.ToGuid()); } model.When = request.Issued.ToDateTime(); model.Amount = request.Amount; model.Ccy = request.Ccy; model.Percentage = request.Percentage; model.DaysCount = request.DaysCount; model.Description = request.Description; try { if (!string.IsNullOrWhiteSpace(request.RegexForTransfer)) { // ReSharper disable once ReturnValueOfPureMethodIsNotUsed new Regex(request.RegexForTransfer, RegexOptions.None, TimeSpan.FromSeconds(0.1)).Match("test"); } } catch { request.RegexForTransfer = ""; } model.RegexForTransfer = request.RegexForTransfer; }
public IActionResult CreateRule(RuleType ruleType, string regexSender, string regexText) { try { // ReSharper disable once ReturnValueOfPureMethodIsNotUsed if (!string.IsNullOrEmpty(regexSender)) { Regex.Match("test", regexSender); } // ReSharper disable once ReturnValueOfPureMethodIsNotUsed if (!string.IsNullOrEmpty(regexText)) { Regex.Match("test", regexText); } } catch { return(RedirectToAction(nameof(SmsRules))); } var rule = new RuleModel(ruleType, regexSender, regexText); _objectRepository.Add(rule); return(RedirectToAction(nameof(SmsRules))); }
public void EditCategory(SpentCategory request) { if (request.Id.ToGuid() == Guid.Empty) { try { if (!string.IsNullOrWhiteSpace(request.Pattern)) { // ReSharper disable once ReturnValueOfPureMethodIsNotUsed new Regex(request.Pattern, RegexOptions.None, TimeSpan.FromSeconds(0.1)).Match("test"); } } catch { request.Pattern = ""; } var spentCategoryModel = new SpentCategoryModel(request.Pattern, request.Category, request.Kind); ObjectRepository.Add(spentCategoryModel); } else { var id = request.Id.ToGuid(); var categoryObj = ObjectRepository.Set <SpentCategoryModel>().First(v => v.Id == id); categoryObj.Pattern = request.Pattern; categoryObj.Category = request.Category; categoryObj.Kind = request.Kind; } }
public OkResult CreateCategory(string pattern, string category, PaymentKind kind) { try { if (!string.IsNullOrWhiteSpace(pattern)) { // ReSharper disable once ReturnValueOfPureMethodIsNotUsed new Regex(pattern, RegexOptions.None, TimeSpan.FromSeconds(0.1)).Match("test"); } } catch { pattern = ""; } _objectRepository.Add(new SpentCategoryModel(pattern, category, kind)); return(Ok()); }
static void Main(string[] args) { ObjectRepository.Add("object1", new Object()); ObjectRepository.Add("dir/obj", new Object()); IObject proxy = new ProxyObj("object1"); Console.WriteLine(proxy.Method(15)); proxy = new ProxyObj("dir/obj"); Console.WriteLine(proxy.Method(15)); }
public void AddScraper(string name, string login, string password) { var scm = new ScraperConfigurationModel(name) { Login = login, Password = password }; ObjectRepository.Add(scm); }
public void Process() { try { Monitor.Enter(this); var smsList = _objectRepository.Set <SmsModel>().Where(v => v.AppliedRule == null).ToList(); var rules = _objectRepository.Set <RuleModel>(); var regexOptions = RegexOptions.Multiline | RegexOptions.Compiled | RegexOptions.IgnoreCase; foreach (RuleModel rule in rules) { var sReg = string.IsNullOrEmpty(rule.RegexSender) ? null : new Regex(rule.RegexSender, regexOptions); var sText = string.IsNullOrEmpty(rule.RegexText) ? null : new Regex(rule.RegexText, regexOptions); foreach (SmsModel sms in smsList) { if (sReg?.IsMatch(sms.From) != false && sText?.IsMatch(sms.Message) != false) { try { if (rule.RuleType == RuleType.Money) { _objectRepository.Add(new PaymentModel(sms, rule)); } sms.AppliedRule = rule; } catch { } } } } var oldSms = _objectRepository.Set <SmsModel>() .Where(v => v.AppliedRule != null && v.When.AddDays(7) < DateTime.UtcNow).ToList(); foreach (var item in oldSms) { foreach (var p in item.Payments) { p.Sms = null; } } _objectRepository.RemoveRange(oldSms); } finally { Monitor.Exit(this); } }
public void SplitPayment(SplitPaymentRequest request) { var amount = request.Amount; var id = request.Id.ToGuid(); var payment = ObjectRepository.Set <PaymentModel>().First(v => v.Id == id); var newKind = amount < 0 ? PaymentKind.Expense : PaymentKind.Income; if (payment.Kind != PaymentKind.Expense && payment.Kind != PaymentKind.Income) { newKind = payment.Kind; payment.Amount -= amount; } else { amount = Math.Abs(amount); if (payment.Kind == newKind.GetOpposite()) { amount = -amount; } payment.Amount -= amount; amount = Math.Abs(amount); } if (Math.Abs(amount) > 0.01) { if (payment.Amount < 0 && payment.Kind != payment.Kind.GetOpposite()) { payment.Kind = payment.Kind.GetOpposite(); payment.Amount = Math.Abs(payment.Amount); } var newPayment = new PaymentModel(payment.When, payment.What, amount, newKind, payment.Ccy, null, payment.Column); ObjectRepository.Add(newPayment); newPayment.UserEdited = true; } SendUpdate(new PaymentsStream { Snapshot = new PaymentsList { ShowCategorized = ShowCategorized, Payments = { _collection.Select(v => v.ToMonthSummary()) } } }); }
public IActionResult CreateCategory(string pattern, string category, PaymentKind kind) { try { // ReSharper disable once ReturnValueOfPureMethodIsNotUsed Regex.Match("test", pattern); } catch { return(RedirectToAction(nameof(SpentCategories))); } _objectRepository.Add(new SpentCategoryModel(pattern, category, kind)); return(RedirectToAction(nameof(SpentCategories))); }
public OkResult CreateRule(RuleType ruleType, string regexSender, string regexText) { // ReSharper disable once ReturnValueOfPureMethodIsNotUsed if (!string.IsNullOrEmpty(regexSender)) { new Regex(regexSender, RegexOptions.None, TimeSpan.FromSeconds(0.1)).Match("test"); } // ReSharper disable once ReturnValueOfPureMethodIsNotUsed if (!string.IsNullOrEmpty(regexText)) { new Regex(regexText, RegexOptions.None, TimeSpan.FromSeconds(0.1)).Match("test"); } var rule = new RuleModel(ruleType, regexSender, regexText); _objectRepository.Add(rule); return(Ok()); }
public OkResult MetadataEdit(Guid id, string userFriendlyName, string function, bool autogenerateStatements) { MoneyColumnMetadataModel existingModel; if (id == Guid.Empty) { existingModel = new MoneyColumnMetadataModel(MoneyColumnMetadataModel.ComputedProdiver, null); _objectRepository.Add(existingModel); } else { existingModel = _objectRepository.Set <MoneyColumnMetadataModel>().First(v => v.Id == id); } existingModel.Function = function ?? ""; existingModel.UserFriendlyName = userFriendlyName; existingModel.AutogenerateStatements = autogenerateStatements; return(Ok()); }
public IActionResult MetadataEdit(Guid id, string userFriendlyName, bool isVisible, string function, string charts) { MoneyColumnMetadataModel existingModel; if (id == Guid.Empty) { existingModel = new MoneyColumnMetadataModel(MoneyColumnMetadataModel.ComputedProdiver, null); _objectRepository.Add(existingModel); } else { existingModel = _objectRepository.Set <MoneyColumnMetadataModel>().First(v => v.Id == id); } existingModel.Function = function; existingModel.UserFriendlyName = userFriendlyName; existingModel.IsVisible = isVisible; return(RedirectToAction(nameof(Index))); }
public void ScrapeImpl(String name, Action <GenericScraper, ScraperConfigurationModel> action, [CallerMemberName] string caller = null) { if (!Startup.IsProduction) { return; } var scrapeConfig = _objectRepository.Set <ScraperConfigurationModel>().FirstOrDefault(v => v.ScraperName == name); var scraper = _scrapers.FirstOrDefault(v => v.ProviderName == name); if (scrapeConfig == null || scraper == null) { _logger.LogInformation($"Not enabled scraper {name}"); return; } lock (_chrome) { _chrome.Reset(); try { _logger.LogInformation($"Scraping {name} {caller}"); action(scraper, scrapeConfig); } catch (Exception ex) { _logger.LogError(ex, $"Failed to get state for {scraper.ProviderName}..."); throw; } finally { _chrome.Reset(); } } // default strategy - generated money statements from diff between states. foreach (var column in _objectRepository.Set <MoneyColumnMetadataModel>().Where(v => v.AutogenerateStatements)) { var payments = _objectRepository.Set <PaymentModel>() .Where(v => v.Column == column) .ToList(); var models = _objectRepository.Set <MoneyStateModel>() .Where(v => v.Column == column) .OrderBy(v => v.When) .ToList(); if (models.Any()) { var emptyModel = new MoneyStateModel { Amount = 0, Ccy = models.First().Ccy, Column = models.First().Column, When = models.First().When.AddDays(-1) }; models.Insert(0, emptyModel); models.Aggregate((a, b) => { var delta = b.Amount - a.Amount; var matchingPayments = payments .Where(v => v.Column == column && v.When >= a.When && v.When <= b.When).ToList(); delta -= matchingPayments.Sum(v => v.Amount); delta = Math.Round(delta * 100, MidpointRounding.AwayFromZero) / 100; if (Math.Abs(delta) >= 0.01) { var when = a.When + (b.When - a.When) / 2; var kind = delta > 0 ? PaymentKind.Income : PaymentKind.Expense; var paymentModel = payments.FirstOrDefault(v => v.Column == column && v.When >= a.When && v.When <= b.When && v.Autogenerated); if (paymentModel == null) { paymentModel = new PaymentModel(when, "Коррекция баланса " + column.Provider + " " + column.AccountName, delta, kind, a.Ccy, "N/A-" + DateTime.Now.Ticks, column); _objectRepository.Add(paymentModel); } else { paymentModel.Amount += delta; } paymentModel.Autogenerated = true; } return(b); }); } } }
public void Scrape() { lock (_chrome) { _chrome.Reset(); var logger = _logger; var currentState = _objectRepository.Set <MoneyStateModel>(); var scrapeConfigs = _objectRepository.Set <ScraperConfigurationModel>().ToList(); foreach (var scraperConfig in scrapeConfigs) { var scraper = _scrapers.FirstOrDefault(v => v.ProviderName == scraperConfig.ScraperName); if (scraper == null) { logger.LogError($"Failed to find scraper {scraperConfig.ScraperName}"); continue; } logger.LogInformation($"Scraping {scraper.ProviderName}"); if (scraper is IStatementScraper ss) { try { var minDates = new[] { _objectRepository.Set <PaymentModel>() .Where(v => v.Provider == scraper.ProviderName) .OrderByDescending(v => v.When) .FirstOrDefault()?.When, _objectRepository.Set <MoneyStateModel>().OrderBy(v => v.When) .FirstOrDefault()?.When, _objectRepository.Set <PaymentModel>().OrderBy(v => v.When) .FirstOrDefault()?.When }; var lastPayment = minDates.Where(v => v != null).OrderBy(v => v).FirstOrDefault() ?? DateTime.MinValue; if (lastPayment.AddHours(24) > DateTime.Now) { continue; // Let's not scrape statements too often - it's hard } logger.LogInformation($"Scraping statement for {scraper.ProviderName} since {lastPayment}..."); var statements = ss.ScrapeStatement(scraperConfig, _chrome, lastPayment).ToList(); logger.LogInformation($"Got statement of {statements.Count} items..."); foreach (var s in statements) { var existingItem = _objectRepository.Set <PaymentModel>().FirstOrDefault(v => v.When.Date == s.When.Date && Math.Abs(v.Amount - s.Amount) < 0.01 && v.Ccy == s.Ccy && v.StatementReference == null || v.StatementReference == s.StatementReference); if (existingItem == null) { _objectRepository.Add(s); } else { if (existingItem.Provider == null) { existingItem.Provider = s.Provider; } if (existingItem.Account == null) { existingItem.Account = s.Account; } if (existingItem.StatementReference == null) { existingItem.StatementReference = s.StatementReference; } } } } catch (Exception ex) { logger.LogError(ex, $"Failed to get statement for {scraper.ProviderName}..."); } } _chrome.Reset(); var accountCount = currentState.Where(s => s.Provider == scraper.ProviderName && s.When.Date == DateTime.UtcNow.Date.AddDays(-1)) .Select(s => s.AccountName).Distinct() .ToList(); var todayState = currentState.Where(s => s.Provider == scraper.ProviderName && s.When.Date == DateTime.UtcNow.Date) .Select(s => s.AccountName).Distinct() .ToList(); var toScrape = accountCount.Count == 0 || accountCount.Except(todayState).Any(); if (toScrape) { try { logger.LogInformation("No cached items, scraping..."); var items = scraper.Scrape(scraperConfig, _chrome.Driver); logger.LogInformation($"Found {items.Count()} items, indexing..."); foreach (var item in items) { logger.LogInformation($" - {item.Provider} / {item.AccountName}: {item.Amount} ({item.Ccy})"); if (!string.IsNullOrWhiteSpace(item.Provider)) { if (item.Amount <= 0.001) { if (!_objectRepository.Set <MoneyStateModel>().Any(s => s.Provider == item.Provider && s.AccountName == item.AccountName && s.Amount > 0 )) { continue; } } if (todayState.Contains(item.AccountName)) { continue; } _objectRepository.Add(item); } } logger.LogInformation("Indexed..."); } catch (Exception ex) { logger.LogError(ex, "There were an issue scraping"); } } else { logger.LogInformation("For today there are already scraped items, continuing..."); } } } foreach (var item in _objectRepository.Set <MoneyStateModel>().GroupBy(v => v.Provider, v => v.AccountName)) { foreach (var sub in item.Distinct()) { var existing = _objectRepository.Set <MoneyColumnMetadataModel>() .FirstOrDefault(v => v.Provider == item.Key && v.AccountName == sub); if (existing == null) { existing = new MoneyColumnMetadataModel(item.Key, sub) { UserFriendlyName = sub, IsVisible = true }; _objectRepository.Add(existing); } } } }
public TableViewModel(ObjectRepository repository) { var headersDictionary = repository.Set <MoneyColumnMetadataModel>().SortColumns() .ToDictionary(v => new MoneyColumnMetadataJsModel(v), v => v); Headers = headersDictionary.Keys.ToList(); var headersCached = new Dictionary <string, MoneyColumnMetadataJsModel>(); foreach (var h in Headers) { if (!string.IsNullOrWhiteSpace(h.UserFriendlyName)) { headersCached[h.UserFriendlyName] = h; } headersCached[h.Provider + "/" + h.AccountName] = h; } var paymentsToExempt = repository.Set <PaymentModel>().Where(v => v.Kind == PaymentKind.Transfer).ToList().GroupBy(v => v.Column) .ToDictionary(v => new MoneyColumnMetadataJsModel(v.Key), v => { var d = new Dictionary <DateTime, double>(); foreach (var item in v) { d[item.When.Date] = d.GetValueOrDefault(item.When.Date, 0) + item.Amount; } return(d); }); var rows = repository.Set <MoneyStateModel>() .GroupBy(x => x.When.Date) .OrderByDescending(v => v.Key) .ToList(); var end = rows.Select(v => (DateTime?)v.Key.Date).FirstOrDefault(); foreach (var col in paymentsToExempt) { var cumulative = 0.0; DateTime start = col.Value.Keys.Min(); for (; start <= (end ?? start); start = start.AddDays(1)) { var curValue = col.Value.GetValueOrDefault(start, 0); if (Math.Abs(cumulative + curValue) >= 0.0001) { col.Value[start] = -(curValue + cumulative); cumulative += curValue; } } } Values = rows .Select(v => new TableRowViewModel(v.ToList(), Headers, headersCached, paymentsToExempt)) .ToList(); for (int i = 0; i < Values.Count - 1; i++) { var row = Values[i]; row.Previous = Values[i + 1]; foreach (var value in row.CalculatedCells.Values) { var previous = Values[i + 1]; value.PreviousValue = previous.CalculatedCells.GetValueOrDefault(value.Column); } } var markedAsOkCells = Enumerable.Empty <MoneyColumnMetadataJsModel>(); for (int i = Values.Count - 1; i >= 0; i--) { var row = Values[i]; var toAddMissing = markedAsOkCells.Except(row.CalculatedCells.Keys).ToList(); foreach (var item in toAddMissing) { row.CalculatedCells.Add(item, CalculatedResult.Empty(item)); } markedAsOkCells = row.CalculatedCells.Values.Where(v => !(v is ExpressionCalculatedResult) && v.Value != null && double.IsNaN(v.Value.Value)) .Select(v => v.Column).ToList(); } var columnsToCheck = Values.SelectMany(v => v.CalculatedCells.Keys).Distinct() .Where(v => !v.IsComputed).ToList(); for (int i = Values.Count - 1; i >= 0; i--) { var row = Values[i]; columnsToCheck = columnsToCheck.Except(row.CalculatedCells.Keys).ToList(); foreach (var item in columnsToCheck) { row.CalculatedCells.Add(item, CalculatedResult.Empty(item)); } } foreach (var r in Values) { foreach (var cell in r.CalculatedCells.Values.OfType <ExpressionCalculatedResult>()) { if (cell.IsOk && cell.Value != null) { repository.Add(new MoneyStateModel { Amount = cell.Value.Value, Ccy = cell.Ccy, Column = headersDictionary[cell.Column], When = r.When, Description = cell.TooltipWithoutAdjustment }); } } } }