Beispiel #1
0
        private Dictionary <string, object> GetData(Article?article, bool isTwoColumn, bool isWide)
        {
            if (article is null)
            {
                return(new Dictionary <string, object>());
            }

            var(width, height, wrapperWidth) = GetImageSize(article.Image, isTwoColumn, isWide);

            return(new Dictionary <string, object>
            {
                { "id", article.Id },
                { "headline", article.Headline },
                { "description", RenderMarkdown(article.Description) },
                { "imageCaption", article.Excerpt },
                {
                    "image", new Dictionary <string, object>
                    {
                        { "url", article.Image?.Url ?? string.Empty },
                        { "width", width },
                        { "height", height },
                        { "wrapperWidth", wrapperWidth }
                    }
                },
                {
                    "category", new Dictionary <string, object>
                    {
                        { "slug", article.Category?.Slug ?? string.Empty },
                        { "name", article.Category?.Name ?? string.Empty },
                        { "color", article.Category?.Color ?? string.Empty },
                        { "image", article.Category?.Image?.Url ?? string.Empty }
                    }
                }
            });
        }
Beispiel #2
0
        private Dictionary <string, object> GetData(Article?article)
        {
            if (article is null)
            {
                return(new Dictionary <string, object>());
            }

            return(new Dictionary <string, object>
            {
                { "id", article.Id },
                { "headline", article.Headline },
                { "description", article.Description },
                {
                    "image", new Dictionary <string, object>
                    {
                        { "url", article.Image?.Url ?? string.Empty }
                    }
                },
                {
                    "category", new Dictionary <string, object>
                    {
                        { "slug", article.Category?.Slug ?? string.Empty },
                        { "name", article.Category?.Name ?? string.Empty },
                        { "color", article.Category?.Color ?? string.Empty },
                        { "image", article.Category?.Image?.Url ?? string.Empty }
                    }
                }
            });
        }
Beispiel #3
0
    /// <summary>Parses a/an, the, many/multiple/several. Will eat "the many" as "many".</summary>
    static Article?ParseArticle(string[] words)
    {
        Article?found = null;
        string  word  = words[index];

        index++;
        if (stringnums.IndefiniteArticles.Contains(word))
        {
            found = Article.a;
        }
        if (stringnums.DefiniteArticles.Contains(word))
        {
            found = Article.the;
        }
        if (stringnums.ListDeterminers.Contains(word))
        {
            found = Article.many;
        }
        if (found != null)
        {
            var found2nd = ParseArticle(words);
            return(found2nd ?? found); // eat "the many", returning "many"; otherwise just return whatever one word we found
        }
        index--;
        return(null);
    }
Beispiel #4
0
        private IEnumerable <Article?> Parse()
        {
            MainPageScenarios.OpenFreshSection();

            for (var i = 0; i < _applicationConfiguration.ContentAmount; i++)
            {
                Log.Debug($"Began parsing article {i + 1}");

                Article?article = null;

                try
                {
                    string title = MainPageScenarios.GetTitle(i);

                    article = new Article(title)
                    {
                        Image = MainPageScenarios.GetImage(i),
                        Video = MainPageScenarios.GetVideo(i)
                    };

                    Log.Debug($"Article {i + 1} (\"{article}\") has been parsed");
                }
                catch (ControlDoesntExistException exception)
                {
                    var logBuilder = new StringBuilder();

                    logBuilder.AppendLine($"Article {i + 1} hasn't been parsed")
                    .Append(exception);

                    Log.Warning(logBuilder.ToString());
                }

                yield return(article);
            }
        }
Beispiel #5
0
    /// <summary>A somewhat high-level function to parse (only) a single indeterminate noun phrase like "a numeric entry", "a number",
    /// "a car", "a vertical percentage", "several cars", "anything", "the manager" (if the NP is the subject of its
    /// sentence), "many gadgets" (when gadget itself hasn't been established yet), or a number of specifically invalid
    /// combinations, that describes a typed parameter in the definition of a multimethod's signature.
    /// Will soon need ability to parse -ing phrases and sub-predicates as in "To learn (repairing a car with a tool)".
    /// Uses ParseArticle, ParseNewIdentifier, ParseAdjectiveType, Parse enum, ParseAnyType, and multiple NameOfType.
    /// Finally calls CreateParameterObject after all but the worst parses.
    /// </summary>
    static parameter ParseNounPhraseForParameter(string[] words, bool isSubject = false)
    {
        StandardType?type       = null;
        string       ident      = "";
        int          savedIndex = index;
        bool         identIsAdjectiveTypeIsNoun = false;
        // usually if the type is the noun, there is no adjective: "the task"
        // and usually if both adj & noun are present, the type is the adjective: "the numeric virtue"
        // this is for constructions like "the horizontal percent, the vertical percent"

        // step 1: try parsing "something", "an adjective-type noun" "nountype", etc., or as a last resort, just a new identifier
        Article?              mode    = ParseArticle(words) ?? ((isQuestion && isSubject) ? Article.a : (Article?)null);
        OtherParameterTypes?  opt     = Parse <OtherParameterTypes>(words[index]);
        StandardTypeAdjective?adjtype = ParseAdjectiveType(words);

        if (adjtype != null)
        {
            ident = ParseNewIdentifier(words, ref type);
            if (type != null && type != (StandardType)adjtype)
            {
                Console.WriteLine("ERROR: I'm unsure whether '{0} {1}' is a {1} nicknamed {0} or is something {0} nicknamed {1}.", adjtype, type);
                method_being_constructed.problems++;
                return(null);
            }
            type = (StandardType)adjtype;
            if (ident == "")
            {
                Console.WriteLine("ERROR: must provide a name after the adjective '{0}' or use its noun form instead, '{1}'.", adjtype, (StandardType)adjtype);
                method_being_constructed.problems++;
                return(null);
            }
        }
        else if (opt != null)
        {
            type = (StandardType)opt;
        }
        else
        {
            fiveforms ing = PresentParticiple(words[index]);
            if (ing != null)
            {
                return(CreateFunctionParameterObject(words, ing, isSubject));
            }
            type  = ParseAnyType(words);
            ident = (type == null) ? "" : NameOfType(type.Value);
        }
        if (ident == "" && type == null /*&& isSubject*/) // then we have no type info whatsoever. Just get a new ident
        {
            ident = ParseNewIdentifier(words, ref type);
            identIsAdjectiveTypeIsNoun = (type != null);
        }

        if (type == null && mode == null)
        {   // if we know nothing, abort
            index = savedIndex;
            return(null);
        }
        return(CreateParameterObject(words, mode, type, adjtype, ident, identIsAdjectiveTypeIsNoun, isSubject));
    }
Beispiel #6
0
 /// <summary>
 /// Initializes a new instance of <see cref="WikiLink"/>.
 /// </summary>
 /// <param name="article">
 /// The linked article (if any).
 /// </param>
 /// <param name="missing">
 /// Whether this is a link to a missing page.
 /// </param>
 /// <param name="isCategory">
 /// Whether this is a link to a category.
 /// </param>
 /// <param name="isNamespaceEscaped">
 /// Whether a leading ':' precedes the namespace.
 /// </param>
 /// <param name="isTalk">
 /// Whether this is a link to a discussion page.
 /// </param>
 /// <param name="title">
 /// The title for the linked article.
 /// </param>
 /// <param name="wikiNamespace">
 /// The namespace for the linked article.
 /// </param>
 public WikiLink(
     Article?article,
     bool missing,
     bool isCategory,
     bool isNamespaceEscaped,
     bool isTalk,
     string title,
     string wikiNamespace)
 {
     Article            = article;
     Missing            = missing;
     IsCategory         = isCategory;
     IsNamespaceEscaped = isNamespaceEscaped;
     IsTalk             = isTalk;
     Title         = title;
     WikiNamespace = wikiNamespace;
 }
Beispiel #7
0
        private (Article?, List <Article>) PickArticle(List <Article> articles, Func <Article, bool> selector)
        {
            var     remainingArticles = new List <Article>();
            Article?result            = null;

            foreach (var article in articles)
            {
                if (result == null && selector(article))
                {
                    result = article;
                }
                else
                {
                    remainingArticles.Add(article);
                }
            }

            return(result, remainingArticles);
        }
Beispiel #8
0
 private static Article GetArticle(string markdown)
 {
     if (_Article is null)
     {
         _Article = Article.NewAsync(
             _Options,
             _DataStore,
             Title,
             Editor,
             markdown)
                    .GetAwaiter()
                    .GetResult();
     }
     else
     {
         _Article.ReviseAsync(_Options, _DataStore, Editor, markdown: markdown).GetAwaiter().GetResult();
     }
     return(_Article);
 }
Beispiel #9
0
 private static Article GetNestedArticle(string markdown, string?wikiNamespace = null)
 {
     if (_NestedArticle is null)
     {
         _NestedArticle = Article.NewAsync(
             _Options,
             _DataStore,
             NestedTitle,
             Editor,
             markdown,
             wikiNamespace ?? _Options.TransclusionNamespace)
                          .GetAwaiter()
                          .GetResult();
     }
     else
     {
         _NestedArticle.ReviseAsync(_Options, _DataStore, Editor, markdown: markdown).GetAwaiter().GetResult();
     }
     return(_NestedArticle);
 }
Beispiel #10
0
    /// <summary>When defining a parameter of a new function's signature, and once parsing of that parameter is done, this converts
    /// the information into a parameter object. Uses CreateListParameterObject since that is a tome in itself.</summary>
    static parameter CreateParameterObject(string[] words, Article?mode, StandardType?type, StandardTypeAdjective?adjtype, string ident, bool identIsAdjectiveTypeIsNoun = false, bool isSubject = false)
    {
        // something/nothing/anything aren't preceded by an article. Treat as "a thing"
        if (type.HasValue && type <= StandardType.something)
        {
            Console.WriteLine("  declaring a parameter which {0}", type == StandardType.nothing ? "must be nothing" : type == StandardType.anything ? "could be anything" : "mustn't be nothing");
            return(new parameter("", type.Value.ToString(), Article.a, type.Value, identIsAdjectiveTypeIsNoun));
        }

        switch (mode)
        {
        case Article.the:
            if (type.HasValue)
            {
                if (adjtype == null)
                {
                    Console.WriteLine("ERROR: we say 'the {0}' to use it later in the sentence. Here we should say 'a {0}'.", NameOfType(type.Value));
                }
                else
                {
                    Console.WriteLine("ERROR: we say 'the {0}' to use it later in the sentence. Here we should say 'a {0} {1}'.", adjtype, ident == "" ? "name-of-it" : ident);
                }
                method_being_constructed.problems++;
                return(null);
            }
            if (isSubject || isQuestion)
            {
                just_declared_new_type = isSubject;     // and a global instance, as well
                return(new parameter("", ident, mode ?? Article.the, type ?? StandardType.number, identIsAdjectiveTypeIsNoun));
            }
            Console.WriteLine("ERROR: we should use 'a' not 'the' in this part of the sentence.");
            method_being_constructed.problems++;
            return(null);

        case Article.many:
            return(CreateListParameterObject(ref type, ident, identIsAdjectiveTypeIsNoun));

        case Article.a:
            if (type.HasValue)     // also, should we disallow it when the ident is also a type? "numeric car"
            {
                Console.WriteLine("  declaring a parameter of type {0} called '{1}'", NameOfType(type.Value), ident);
                InheritedType it = InheritanceTree.Find(item => item.name == ident);
                if (it != null && it.typeid != type.Value)
                {
                    Console.WriteLine("  WARNING: '{0}' is declared elsewhere as a '{1}', not a '{2}'", it.name, NameOfType(it.typeid), NameOfType(type.Value));
                }
            }
            else if (isQuestion && incarnations == TheVerbIs)
            {
                for (IdentEndsAt = index; IdentEndsAt < words.Length && words[IdentEndsAt] != "?"; IdentEndsAt++)
                {
                    ;
                }
                if (IdentEndsAt >= words.Length)
                {
                    Console.WriteLine("  ERROR: I thought #{0} was a question because it began with '{1}', but I couldn't find a question mark afterward.", method_being_constructed.prompt, method_being_constructed.question);
                    method_being_constructed.problems++;
                    return(null);
                }
                Console.WriteLine("  defining a {0} by Q&A.", ident);
                ident = ParseNewIdentifier(words, ref type);
            }
            else if (!isSubject)
            {
                if (ident == "")     // then we have no type info whatsoever. Just get a new ident
                {
                    ident = ParseNewIdentifier(words, ref type);
                }
                Console.WriteLine("  TODO: is '{0}' textual? Numeric? Or something more complex?", ident);
                method_being_constructed.todo++;
            }
            // defining a new type
            else if (InheritanceTree.Find(item => item.name == ident) != null)
            {
                Console.WriteLine("  ERROR: re-defining type '{0}'.", ident);
                method_being_constructed.problems++;
                //return null; // let it parse for now
                return(new parameter("", ident, mode ?? Article.a, type ?? (StandardType)0, identIsAdjectiveTypeIsNoun));
            }
            else
            {
                // object until proven otherwise. heck, it may not even be a type, it might be an instance or variable.
                var newType = CreateNewType(ident);
                Console.WriteLine("  assuming '{0}' is a new type", newType.name, newType.typeid);
            }
            break;

        case null:
            if (type == null)
            {
                return(null);
            }
            if (ident == null)
            {
                Console.WriteLine("  plural(?) parameter of type {0}", type);
            }
            else
            {
                Console.WriteLine("  plural(?) parameter of type {1} called the {0}", ident, NameOfType(type.Value));
            }
            break;
        }
        return(new parameter("", ident, mode ?? Article.a, type ?? (StandardType)0, identIsAdjectiveTypeIsNoun));
    }
Beispiel #11
0
 private void AddArticleToData(string key, Dictionary <string, object> data, Article?article)
 {
     data.Add(key, GetData(article));
 }
Beispiel #12
0
    /// <summary>Called from ParseAnInvocation2.
    /// Tries to match the current words in the source to exactly one in-scope thing which satisfies the given parameter's type.
    /// On success returns the Instance (literal value, variable which holds the value, etc.)
    /// Uses IsNameOfTypeWhich, ParseRelativeInvocation, ParseNumberOrdinalPercent, MatchToNamedStorageLocation.</summary>
    static instance ParseInvokedNoun(List <string> words, parameter satisfyMe, bool allowUnboundVariables = false)
    {
        if (index >= words.Count)
        {
            return(null);
        }
        int savedIndex = index;

        while (words[index] == "the")
        {
            index++;
        }
        theTypeWhich theTypeWhich = null;
        invocation   inv          = null;
        long?        number       = null;
        Article?     art          = null;

        if (words[index].StartsWith("__litstring"))
        {
            return (IsA(StandardType.text, satisfyMe.type)) ? null : new instance()
                   {
                       var = satisfyMe, literalString = Say(words[index++]), type = StandardType.text, toAccess = Indirectedness.literal
                   }
        }
        ;
        if ((theTypeWhich = IsNameOfTypeWhich(words)) != null && ((inv = ParseARelativeInvocation(theTypeWhich, words)) != null))
        {
            return new instance()
                   {
                       var = satisfyMe, type = theTypeWhich.type.typeid, inner = inv, toAccess = Indirectedness.nested_invocation
                   }
        }
        ;
        if (satisfyMe.isAggregate && words[index].EndsWith("ing") && (inv = ParseAGerundInvocation(satisfyMe, words)) != null)
        {
            return new instance()
                   {
                       var = satisfyMe, type = satisfyMe.type, inner = inv, toAccess = Indirectedness.nested_invocation
                   }
        }
        ;
        if ((number = ParseNumberOrdinalPercent(words)) != null)
        {
            return (!IsA(numtype.AsStandardType(), satisfyMe.type)) ? null : new instance()
                   {
                       var = satisfyMe, literalValue = number.Value, type = numtype.AsStandardType(), toAccess = Indirectedness.literal
                   }
        }
        ;
        if (allowUnboundVariables && (art = ParseArticle(words.ToArray())) != null)
        {
            index = savedIndex; // back up over the article(s) for the following function to eat

            parameter unbound = ParseNounPhraseForParameter(words.ToArray(), false);
            if (unbound == null)
            {
                return(null);
            }
            return(new instance()
            {
                var = unbound, toAccess = Indirectedness.unbound
            });
        }
        return(MatchToNamedStackLocation(words));
    }
Beispiel #13
0
        public void DeleteArticle(string articleTitle)
        {
            Article?toDelete = articles.SingleOrDefault(a => a.Title.Equals(articleTitle));

            if (toDelete is {})
Beispiel #14
0
        public async Task <ReceiptModel> Handle(ImportReceipt request, CancellationToken cancellationToken)
        {
            Store store = await dbContext.Stores
                          .Include(x => x.Products).ThenInclude(x => x.Article)
                          .SingleOrDefaultAsync(x => x.Uuid == request.Model.StoreId, cancellationToken)
                          ?? throw new NotFoundException(nameof(request.Model.StoreId));

            if (store.AccountId != appContext.Account !.Id)
            {
                throw new ForbiddenException();
            }

            Dictionary <long, Article> articles = await dbContext.Articles
                                                  .Where(x => x.AccountId == appContext.Account.Id && x.Gtin.HasValue)
                                                  .ToDictionaryAsync(x => x.Gtin !.Value, x => x, cancellationToken);

            Dictionary <string, Department> departments = await dbContext.Departments
                                                          .Where(x => x.StoreId == store.Id && x.Number != null)
                                                          .ToDictionaryAsync(x => x.Number !, x => x, cancellationToken);

            Dictionary <int, Product> productsByArticle = store.Products
                                                          .ToDictionary(x => x.ArticleId, x => x);
            Dictionary <string, Product> productsBySku = store.Products
                                                         .Where(x => x.Sku != null)
                                                         .ToDictionary(x => x.Sku !, x => x);

            DateTimeOffset now     = dateTimeOffset.Now;
            var            receipt = new Receipt
            {
                CreatedAt = now,
                IssuedAt  = request.Model.IssuedAt ?? now,
                Number    = request.Model.Number?.CleanTrim(),
                Store     = store,
                StoreId   = store.Id,
                UpdatedAt = now,
                Uuid      = guid.NewGuid()
            };

            var gst = new Tax
            {
                Code = "GST",
                Rate = taxOptions.Gst
            };

            receipt.Taxes.Add(gst);

            var qst = new Tax
            {
                Code = "QST",
                Rate = taxOptions.Qst
            };

            receipt.Taxes.Add(qst);

            IEnumerable <LineInfo> lines = parser.Execute(request.Model.Lines);

            foreach (LineInfo line in lines)
            {
                Article?   article    = null;
                Department?department = null;
                Product?   product    = null;

                if (line.Department != null)
                {
                    if (!departments.TryGetValue(line.Department.Number, out department))
                    {
                        department = new Department
                        {
                            CreatedAt = now,
                            Name      = line.Department.Name,
                            Number    = line.Department.Number,
                            Store     = store,
                            StoreId   = store.Id,
                            UpdatedAt = now,
                            Uuid      = guid.NewGuid()
                        };
                        departments.Add(department.Number, department);

                        dbContext.Departments.Add(department);
                        await dbContext.SaveChangesAsync(cancellationToken);
                    }
                }

                string?sku  = null;
                long?  gtin = ParseGtin(line.Id);
                if (gtin.HasValue)
                {
                    if (articles.TryGetValue(gtin.Value, out article))
                    {
                        productsByArticle.TryGetValue(article.Id, out product);
                    }
                }
                else
                {
                    sku = line.Id;
                    productsBySku.TryGetValue(sku, out product);
                }

                if (product == null)
                {
                    if (article == null)
                    {
                        article = new Article
                        {
                            AccountId = appContext.Account.Id,
                            CreatedAt = now,
                            Gtin      = gtin,
                            Name      = line.ToString(),
                            UpdatedAt = now,
                            Uuid      = guid.NewGuid()
                        };
                        dbContext.Articles.Add(article);

                        if (gtin.HasValue)
                        {
                            articles.Add(gtin.Value, article);
                        }
                    }

                    product = new Product
                    {
                        CreatedAt    = now,
                        Department   = department,
                        DepartmentId = department?.Id,
                        Flags        = line.Flags,
                        Label        = line.Label,
                        Sku          = sku,
                        Store        = store,
                        StoreId      = store.Id,
                        UnitPrice    = line.UnitPrice,
                        UpdatedAt    = now,
                        Uuid         = guid.NewGuid()
                    };
                    article.Products.Add(product);

                    if (sku != null)
                    {
                        productsBySku.Add(sku, product);
                    }

                    await dbContext.SaveChangesAsync(cancellationToken);

                    productsByArticle.Add(article.Id, product);
                }

                receipt.Items.Add(new Item
                {
                    Price     = line.Price,
                    Product   = product,
                    ProductId = product.Id,
                    Quantity  = line.Quantity ?? 1,
                    UnitPrice = line.UnitPrice ?? line.Price,
                    Uuid      = guid.NewGuid()
                });

                receipt.SubTotal += line.Price;

                if (product.Flags?.Any(x => x.Contains("F")) == true)
                {
                    gst.TaxableAmount += line.Price;
                }
                if (product.Flags?.Any(x => x.Contains("P")) == true)
                {
                    qst.TaxableAmount += line.Price;
                }
            }

            receipt.Total = receipt.SubTotal;
            foreach (Tax tax in receipt.Taxes)
            {
                tax.Amount     = tax.TaxableAmount * (decimal)tax.Rate;
                receipt.Total += tax.Amount;
            }

            dbContext.Receipts.Add(receipt);
            await dbContext.SaveChangesAsync(cancellationToken);

            return(mapper.Map <ReceiptModel>(receipt));
        }