예제 #1
0
        private async Task SearchRecipe(SearchArguments a, Message message)
        {
            using (var db = new Database())
            {
                Stat stat        = a.RS3Stats.GetStatForName(a.Skill.ToString());
                int  levelDiff   = RSUtil.ExpBetweenLevels(stat, a.Level);
                var  dbLookup    = new Stopwatch();
                var  queryBuild  = new Stopwatch();
                var  upload      = new Stopwatch();
                var  convertText = new Stopwatch();

                queryBuild.Start();
                var tempQuery = db.recipes
                                .Where(r => r.Skill == (int)a.Skill)
                                .Where(r => r.Level <= stat.Level)
                                .Select(r => new Entity
                {
                    Id     = r.Id,
                    Name   = r.Name,
                    Level  = r.Level,
                    Exp    = r.Exp,
                    ExpH   = r.Exp * r.Units,
                    Number = (int)Math.Ceiling(levelDiff / r.Exp),
                    Cost   = (db.outputs.Where(o => o.RecipeId == r.Id).Sum(o => o.Quantity * o.item.Price)
                              - (db.inputs.Where(i => i.RecipeId == r.Id).Sum(i => i.Quantity * i.item.Price) + r.Extra))
                             * Math.Ceiling(levelDiff / r.Exp),
                    Time = Math.Ceiling(levelDiff / r.Exp) / r.Units
                });

                var firstOrder = a.Orders.First();
                IOrderedQueryable <Entity> query = null;

                // Doing first sort
                switch (firstOrder)
                {
                case SearchArguments.Order.Expensive:
                    query = tempQuery.OrderBy(r => r.Cost);
                    break;

                case SearchArguments.Order.Fast:
                    query = tempQuery.OrderBy(r => r.Time);
                    break;

                case SearchArguments.Order.Cheap:
                    query = tempQuery.OrderByDescending(r => r.Cost);
                    break;

                case SearchArguments.Order.Slow:
                    query = tempQuery.OrderByDescending(r => r.Time);
                    break;

                case SearchArguments.Order.Name:
                    query = tempQuery.OrderBy(r => r.Name);
                    break;

                case SearchArguments.Order.Level:
                    query = tempQuery.OrderBy(r => r.Level);
                    break;
                }

                // Consecutive sort
                for (var i = 1; i < a.Orders.Count; i++)
                {
                    switch (firstOrder)
                    {
                    case SearchArguments.Order.Expensive:
                        query = query.ThenByDescending(r => r.Cost);
                        break;

                    case SearchArguments.Order.Fast:
                        query = query.ThenBy(r => r.Time);
                        break;

                    case SearchArguments.Order.Cheap:
                        query = query.ThenBy(r => r.Cost);
                        break;

                    case SearchArguments.Order.Slow:
                        query = query.ThenByDescending(r => r.Time);
                        break;

                    case SearchArguments.Order.Name:
                        query = query.ThenBy(r => r.Name);
                        break;

                    case SearchArguments.Order.Level:
                        query = query.ThenBy(r => r.Level);
                        break;
                    }
                }

                // Stopping query builder timer
                queryBuild.Stop();

                var pages = Math.Ceiling((decimal)await query.LongCountAsync() / a.Limit);

                // Starting db lookup
                dbLookup.Start();

                var recipes = await query.Skip((a.Page - 1) *a.Limit)
                              .Take(a.Limit)
                              .ToListAsync();

                // END OF DB LOOKUP
                dbLookup.Stop();

                if (!recipes.Any())
                {
                    await message.Channel.SendMessage("No recipes found.");

                    return;
                }

                // Formatting
                Table table = new Table();
                table.SetTitle($"{a.Skill} Recipes ({a.Page}/{pages})");
                table.SetHeadings("Id", "Name", "Level", "Xp", "Xp/H", "Number", "Cost", "Time");
                recipes.ForEach(r => table.AddRow(
                                    r.Id
                                    , r.Name
                                    , new Table.Column(r.Level, Table.Column.Alignment.Right)
                                    , new Table.Column(r.Exp.ToString("#,##0.##"), Table.Column.Alignment.Right)
                                    , new Table.Column(r.ExpH.ToString("#,##0.##"), Table.Column.Alignment.Right)
                                    , new Table.Column(r.Number.ToString("#,##0"), Table.Column.Alignment.Right)
                                    , new Table.Column(r.Cost.ToString("#,##0"), Table.Column.Alignment.Right)
                                    , new Table.Column(r.Time.ToFormattedTime(), Table.Column.Alignment.Right)));

                string @out = $"{table}";

                // Outputing image
                if (a.Image)
                {
                    var img  = convertText.TimeTask(() => ImageUtil.ToImage(@out));
                    var link = await upload.TimeTaskAsync(async() => await ImageUtil.PostToImgur(img));

                    await message.Channel.SendMessage(link + "\n" +
                                                      $"**Build Query**: {dbLookup.ElapsedMilliseconds}ms | " +
                                                      $"**Query DB**: {queryBuild.Elapsed.Milliseconds}ms | " +
                                                      $"**Convert Text**: {convertText.ElapsedMilliseconds}ms | " +
                                                      $"**Upload Image**: {upload.ElapsedMilliseconds}ms");
                }
                else
                {
                    await message.Channel.SendMessage($"**Build Query**: {dbLookup.ElapsedMilliseconds}ms | " +
                                                      $"**Query DB**: {queryBuild.Elapsed.Milliseconds}ms" +
                                                      $"```{@out}```");
                }
            }
        }