Example #1
0
        private async Task ProcessContracts(bool isCorp, ContractNotifyGroup group, long characterID, string token)
        {
            if (group == null)
            {
                return;
            }
            var maxContracts = Settings.ContractNotificationsModule.MaxTrackingCount > 0 ? Settings.ContractNotificationsModule.MaxTrackingCount : 150;
            List <JsonClasses.Contract> contracts;

            var corpID = isCorp ? (await APIHelper.ESIAPI.GetCharacterData(Reason, characterID))?.corporation_id ?? 0 : 0;

            if (isCorp)
            {
                var etag   = _corpEtokens.GetOrNull(characterID);
                var result = await APIHelper.ESIAPI.GetCorpContracts(Reason, corpID, token, etag);

                if (result?.Data == null || result.Data.IsNotModified)
                {
                    return;
                }
                _corpEtokens.AddOrUpdateEx(characterID, result.Data.ETag);

                contracts = result.Result?.OrderByDescending(a => a.contract_id).ToList();
            }
            else
            {
                var etag   = _etokens.GetOrNull(characterID);
                var result = await APIHelper.ESIAPI.GetCharacterContracts(Reason, characterID, token, etag);

                if (result?.Data == null || result.Data.IsNotModified)
                {
                    return;
                }
                _etokens.AddOrUpdateEx(characterID, result.Data.ETag);

                contracts = result.Result?.OrderByDescending(a => a.contract_id).ToList();
            }

            if (contracts == null || !contracts.Any())
            {
                return;
            }

            var lastContractId = contracts.FirstOrDefault()?.contract_id ?? 0;

            if (lastContractId == 0)
            {
                return;
            }

            var lst = !isCorp ? await SQLHelper.LoadContracts(characterID, false) : await SQLHelper.LoadContracts(characterID, true);

            var otherList = isCorp ? await SQLHelper.LoadContracts(characterID, false) : null;

            if (lst == null)
            {
                lst = new List <JsonClasses.Contract>(contracts.Where(a => _activeStatuses.ContainsCaseInsensitive(a.status)).TakeSmart(maxContracts));
                await SQLHelper.SaveContracts(characterID, lst, isCorp);

                return;
            }

            /*
             * if (lst == null)
             * {
             *  var cs = contracts.Where(a => !_completeStatuses.Contains(a.status)).TakeSmart(maxContracts).ToList();
             *  //initial cache - only progressing contracts
             *  await SQLHelper.SaveContracts(characterID, cs, isCorp);
             *  return;
             * }*/

            //process cache
            foreach (var contract in lst.ToList())
            {
                var freshContract = contracts.FirstOrDefault(a => a.contract_id == contract.contract_id);
                //check if it present
                if (freshContract == null)
                {
                    lst.Remove(contract);
                    continue;
                }

                if (group.Filters == null)
                {
                    continue;
                }
                foreach (var filter in group.Filters.Values)
                {
                    if (filter.Types.Any() && !filter.Types.Contains(contract.type))
                    {
                        continue;
                    }

                    if (filter.Availability.Any() && !filter.Availability.ContainsCaseInsensitive(contract.availability))
                    {
                        continue;
                    }

                    //check for completion
                    if (_completeStatuses.Contains(freshContract.status) && filter.Statuses.Contains(freshContract.status))
                    {
                        if (filter.DiscordChannelId > 0 && APIHelper.DiscordAPI.GetChannel(filter.DiscordChannelId) != null)
                        {
                            await PrepareFinishedDiscordMessage(filter.DiscordChannelId, freshContract, group.DefaultMention, isCorp, characterID, corpID, token, filter);
                        }
                        else
                        {
                            await LogHelper.LogWarning($"Specified filter channel ID: {filter.DiscordChannelId} is not accessible!", Category);
                        }
                        await LogHelper.LogModule($"--> Contract {freshContract.contract_id} is {freshContract.status}!", Category);

                        if (lst.Contains(contract))
                        {
                            lst.Remove(contract);
                        }
                        continue;
                    }
                    //check for accepted
                    if (contract.type == "courier" && contract.status == "outstanding" && freshContract.status == "in_progress" && filter.Statuses.Contains("in_progress"))
                    {
                        await PrepareAcceptedDiscordMessage(filter.DiscordChannelId, freshContract, group.DefaultMention, isCorp, characterID, corpID, token, filter);

                        var index = lst.IndexOf(contract);
                        lst.Remove(contract);
                        lst.Insert(index < 0 ? 0 : index, freshContract);
                        await LogHelper.LogModule($"--> Contract {freshContract.contract_id} is accepted!", Category);

                        continue;
                    }
                }
            }


            //silently remove filtered out expired contracts
            var lefties = lst.Where(a => _completeStatuses.Contains(a.status)).ToList();

            foreach (var lefty in lefties)
            {
                lst.Remove(lefty);
            }

            //update cache list and look for new contracts
            var lastRememberedId = lst.FirstOrDefault()?.contract_id ?? 0;

            if (lastContractId > lastRememberedId)
            {
                //get and report new contracts, forget already finished
                var list = contracts.Where(a => a.contract_id > lastRememberedId && !_completeStatuses.Contains(a.status)).ToList();
                if (otherList != null)
                {
                    list = list.Where(a => otherList.All(b => b.contract_id != a.contract_id)).ToList();
                }

                //fix loop
                foreach (var contract in list)
                {
                    var isCharAssignee = await APIHelper.ESIAPI.GetCharacterData(Reason, contract.assignee_id) != null;

                    bool isCorpAssignee = false;
                    bool isAllyAssignee = false;
                    if (!isCharAssignee)
                    {
                        isCorpAssignee = await APIHelper.ESIAPI.GetCorporationData(Reason, contract.assignee_id) != null;

                        isAllyAssignee = !isCorpAssignee;
                    }

                    contract.availability = isCharAssignee ? "personal" : (isCorpAssignee ? "corporation" : "alliance");
                }

                bool stop = false;
                foreach (var contract in list)
                {
                    foreach (var(filterName, filter) in group.Filters)
                    {
                        if (stop)
                        {
                            break;
                        }
                        if (!filter.Statuses.Contains(contract.status))
                        {
                            continue;
                        }
                        //types
                        if (filter.Types.Any() && !filter.Types.Contains(contract.type))
                        {
                            continue;
                        }
                        //availability
                        if (filter.Availability.Any() && !filter.Availability.ContainsCaseInsensitive(contract.availability))
                        {
                            continue;
                        }

                        //filter by issue target
                        if (!filter.FeedIssuedBy)
                        {
                            if (isCorp)
                            {
                                if (contract.for_corporation && contract.issuer_corporation_id == corpID)
                                {
                                    continue;
                                }
                            }
                            else
                            {
                                if (contract.issuer_id == characterID)
                                {
                                    continue;
                                }
                            }
                        }

                        if (!filter.FeedIssuedTo)
                        {
                            if (isCorp)
                            {
                                if (contract.assignee_id == corpID)
                                {
                                    continue;
                                }
                                else if (contract.assignee_id == characterID)
                                {
                                    continue;
                                }
                            }
                        }

                        try
                        {
                            await LogHelper.LogModule($"--> New Contract {contract.contract_id} found!", Category);

                            if (filter.DiscordChannelId != 0)
                            {
                                await PrepareDiscordMessage(filter.DiscordChannelId, contract, group.DefaultMention, isCorp, characterID, corpID, token, filter);
                            }
                            if (group.StopOnFirstFilterMatch)
                            {
                                stop = true;
                            }
                        }
                        catch (Exception ex)
                        {
                            await LogHelper.LogEx($"Contract {contract.contract_id}", ex, Category);
                        }
                    }
                }

                if (list.Count > 0)
                {
                    lst.InsertRange(0, list);
                    //cut
                    if (lst.Count >= maxContracts)
                    {
                        var count = lst.Count - maxContracts;
                        lst.RemoveRange(lst.Count - count, count);
                    }
                }
            }

            //kill dupes
            var rr = lst.GroupBy(a => a.contract_id).Where(a => a.Count() > 1).Select(a => a.Key).Distinct();

            foreach (var item in rr)
            {
                var o = lst.FirstOrDefault(a => a.contract_id == item);
                if (o != null)
                {
                    lst.Remove(o);
                }
            }

            await SQLHelper.SaveContracts(characterID, lst, isCorp);
        }
        private async Task ProcessContracts(bool isCorp, ContractNotifyGroup group, long characterID, string token)
        {
            var maxContracts = Settings.ContractNotificationsModule.MaxTrackingCount > 0 ? Settings.ContractNotificationsModule.MaxTrackingCount : 150;
            List <JsonClasses.Contract> contracts;

            var corpID = isCorp ? (await APIHelper.ESIAPI.GetCharacterData(Reason, characterID))?.corporation_id ?? 0 : 0;

            if (isCorp)
            {
                var etag   = _corpEtokens.GetOrNull(characterID);
                var result = await APIHelper.ESIAPI.GetCorpContracts(Reason, corpID, token, etag);

                _corpEtokens.AddOrUpdateEx(characterID, result.Data.ETag);
                if (result.Data.IsNotModified)
                {
                    return;
                }
                contracts = result.Result?.OrderByDescending(a => a.contract_id).ToList();
            }
            else
            {
                var etag   = _etokens.GetOrNull(characterID);
                var result = await APIHelper.ESIAPI.GetCharacterContracts(Reason, characterID, token, etag);

                _etokens.AddOrUpdateEx(characterID, result.Data.ETag);
                if (result.Data.IsNotModified)
                {
                    return;
                }

                contracts = result.Result?.OrderByDescending(a => a.contract_id).ToList();
            }

            if (contracts == null || !contracts.Any())
            {
                return;
            }

            var lastContractId = contracts.FirstOrDefault()?.contract_id ?? 0;

            if (lastContractId == 0)
            {
                return;
            }

            var lst = !isCorp ? await SQLHelper.LoadContracts(characterID, false) : await SQLHelper.LoadContracts(characterID, true);

            var otherList = isCorp ? await SQLHelper.LoadContracts(characterID, false) : null;


            if (lst == null)
            {
                var cs = contracts.Where(a => !_completeStatuses.Contains(a.status)).TakeSmart(maxContracts).ToList();
                //initial cache - only progressing contracts
                await SQLHelper.SaveContracts(characterID, cs, isCorp);

                return;
            }

            //process cache
            foreach (var contract in lst.ToList())
            {
                var freshContract = contracts.FirstOrDefault(a => a.contract_id == contract.contract_id);
                //check if it present
                if (freshContract == null)
                {
                    lst.Remove(contract);
                    continue;
                }

                foreach (var filter in group.Filters.Values)
                {
                    if (filter.Types.Any() && !filter.Types.Contains(contract.type))
                    {
                        continue;
                    }

                    //check for completion
                    if (_completeStatuses.Contains(freshContract.status) && filter.Statuses.Contains(freshContract.status))
                    {
                        await PrepareFinishedDiscordMessage(filter.DiscordChannelId, freshContract, group.DefaultMention, isCorp, characterID, corpID, token, filter.ShowIngameOpen);

                        await LogHelper.LogModule($"--> Contract {freshContract.contract_id} is expired!", Category);

                        lst.Remove(contract);
                        continue;
                    }
                    //check for accepted
                    if (contract.type == "courier" && contract.status == "outstanding" && freshContract.status == "in_progress" && filter.Statuses.Contains("in_progress"))
                    {
                        await PrepareAcceptedDiscordMessage(filter.DiscordChannelId, freshContract, group.DefaultMention, isCorp, characterID, corpID, token, filter.ShowIngameOpen);

                        var index = lst.IndexOf(contract);
                        lst.Remove(contract);
                        lst.Insert(index, freshContract);
                        await LogHelper.LogModule($"--> Contract {freshContract.contract_id} is accepted!", Category);

                        continue;
                    }
                }

                //silently remove filtered out expired contracts
                var lefties = lst.Where(a => _completeStatuses.Contains(a.status)).ToList();
                foreach (var lefty in lefties)
                {
                    lst.Remove(lefty);
                }
            }

            //update cache list and look for new contracts
            var lastRememberedId = lst.FirstOrDefault()?.contract_id ?? 0;

            if (lastContractId > lastRememberedId)
            {
                //get and report new contracts, forget already finished
                var list = contracts.Where(a => a.contract_id > lastRememberedId && !_completeStatuses.Contains(a.status)).ToList();
                if (otherList != null)
                {
                    list = list.Where(a => otherList.All(b => b.contract_id != a.contract_id)).ToList();
                }

                var crFilter        = group.Filters.Values.FirstOrDefault(a => a.Statuses.Contains("outstanding"));
                var crFilterChannel = crFilter?.DiscordChannelId ?? 0;

                //filter by issue target
                if (!crFilter?.FeedIssuedBy ?? false)
                {
                    list = list.Where(a => a.issuer_id != characterID && (a.issuer_corporation_id != corpID || a.issuer_corporation_id == 0)).ToList();
                }
                if (!crFilter?.FeedIssuedTo ?? false)
                {
                    list = list.Where(a => a.assignee_id != characterID && a.assignee_id != corpID).ToList();
                }

                if (crFilter != null && crFilter.Types.Any())
                {
                    list = list.Where(a => crFilter.Types.Contains(a.type)).ToList();
                }

                foreach (var contract in list)
                {
                    try
                    {
                        await LogHelper.LogModule($"--> New Contract {contract.contract_id} found!", Category);

                        if (crFilterChannel != 0)
                        {
                            await PrepareDiscordMessage(crFilterChannel, contract, group.DefaultMention, isCorp, characterID, corpID, token, crFilter.ShowIngameOpen);
                        }
                    }
                    catch (Exception ex)
                    {
                        await LogHelper.LogEx($"Contract {contract.contract_id}", ex, Category);
                    }
                }

                if (list.Count > 0)
                {
                    lst.InsertRange(0, list);
                    //cut
                    if (lst.Count >= maxContracts)
                    {
                        var count = lst.Count - maxContracts;
                        lst.RemoveRange(lst.Count - count, count);
                    }
                }
            }

            await SQLHelper.SaveContracts(characterID, lst, isCorp);
        }