diff options
| author | unwox <me@unwox.com> | 2024-10-09 10:49:19 +0600 |
|---|---|---|
| committer | unwox <me@unwox.com> | 2024-10-09 10:49:19 +0600 |
| commit | 469a210832d2e89038a8732414aafe42f928a14f (patch) | |
| tree | cb3f79b361f7c08766f4128447bc063db30dc53e | |
| parent | af76f6151244bdccd745f86b1edca3038718b551 (diff) | |
integrate chaekshop.ru
| -rw-r--r-- | bin/fetch.fnl | 2 | ||||
| -rw-r--r-- | bin/serve.fnl | 10 | ||||
| -rw-r--r-- | parser/chaekshop.fnl | 88 | ||||
| -rw-r--r-- | static/chaekshop.svg | 3 |
4 files changed, 101 insertions, 2 deletions
diff --git a/bin/fetch.fnl b/bin/fetch.fnl index c51d0f9..3dcaded 100644 --- a/bin/fetch.fnl +++ b/bin/fetch.fnl @@ -7,6 +7,7 @@ (local ipuer (require :parser.ipuer)) (local artoftea (require :parser.artoftea)) (local clubcha (require :parser.clubcha)) +(local chaekshop (require :parser.chaekshop)) (local db (luna.db.open "file:var/db.sqlite?_journal=WAL&_sync=NORMAL")) (luna.db.exec db " @@ -72,6 +73,7 @@ FROM products;" []) (luna.db.commit tx)) +(store-products (chaekshop.products)) (store-products (clubcha.products)) (store-products (artoftea.products)) (store-products (ipuer.products)) diff --git a/bin/serve.fnl b/bin/serve.fnl index eb56d8a..bec5a94 100644 --- a/bin/serve.fnl +++ b/bin/serve.fnl @@ -56,6 +56,11 @@ :alt "Логотип Железный Феникс"} [:img {:src "/static/clubcha.png"}] "Железный Феникс"] + (= name "chaekshop") + [:a {:class "site-icon" :href "https://chaekshop.ru" + :alt "Логотип Интернет-магазин фермерского китайского чая «Чаёк»"} + [:img {:src "/static/chaekshop.svg"}] + "Интернет-магазин «Чаёк»"] "")) (fn item-template [product] @@ -75,7 +80,8 @@ (< 0 product.price-per)) [:NO-ESCAPE (.. " (" product.price-per "₽ за 1 гр.)")] "")] - [:small {} (unescape (str.truncate product.description 200))]]) + ;; FIXME: security issue + [:small {} [:NO-ESCAPE (unescape (str.truncate product.description 200))]]]) (fn paginator-template [query page limit total] (local last-page (math.ceil (/ total limit))) @@ -120,7 +126,7 @@ :alt "Логотип meicha.ru" :title "Логотип meicha.ru"}]) [:form {:class "form"} [:input {:type :search :name :query :value query - :autofocus true :placeholder "Введите поисковый запрос"}] + :autofocus true :placeholder "Поисковый запрос"}] [:button {:type :submit} "Искать"]] paginator]] [:section {} diff --git a/parser/chaekshop.fnl b/parser/chaekshop.fnl new file mode 100644 index 0000000..b1e4b4e --- /dev/null +++ b/parser/chaekshop.fnl @@ -0,0 +1,88 @@ +(import-macros {: map} :lib.macro) + +(local peg + (if (pick-values 1 (pcall require :lpeg)) + (require :lpeg) + (require :lpeglj))) +(local parser (require :parser.parser)) +(local number (require :lib.number)) +(local fetcher (require :fetcher)) + +(fn format-url [path page] + (.. "https://chaekshop.ru/catalog/" path "?page=" page)) + +(local data-v-peg + (* (peg.P "data-v-") (^ (+ parser.pegs.letters parser.pegs.number) 1))) + +(local product-peg + (* + (parser.anywhere + (parser.tag :a {data-v-peg "" :href (peg.Cg (parser.till "\"") :url) + :class "*" :itemprop "url" :section_id "*"})) + (parser.anywhere + (parser.tag :img {:src (peg.Cg (parser.till "\"") :image) + :alt "*" + :title (peg.Cg (parser.till "\"") :title) + :loading "lazy" + data-v-peg ""})) + (parser.anywhere + (parser.tag :p {:itemprop "price" :class "*" data-v-peg ""} + (* (peg.Cg (^ (+ parser.pegs.number " " ",") 1) :price) "₽"))) + (parser.anywhere + (parser.tag :p {:class "*" data-v-peg ""} + (+ (* (peg.Cg parser.pegs.number :weight) " грамм") + (* parser.pegs.number " шт")))))) + +(fn normalize [product] + (local weight (or (number.string->number product.weight) + (parser.guess-weight product.title))) + (local price (number.string->number (string.gsub product.price "," "."))) + {:site "chaekshop" + :id (.. "https://chaekshop.ru/" product.url) + :title product.title + :url (.. "https://chaekshop.ru/" product.url) + :description "" + :image (.. "https://chaekshop.ru" product.image) + :year (parser.guess-year product.title) + :price price + :weight weight + :price-per (if (and price weight (< 0 weight)) + (/ (math.ceil (* (/ price weight) 10)) 10) + nil)}) + +(fn products [] + (fetcher.from-html + [{:path "chay/belyy_chay" :category "Белый чай"} + {:path "chay/guandunskie_uluny" :category "Улун"} + {:path "chay/zhyeltyy_chay" :category "Желтый чай"} + {:path "chay/zelyenyy_chay" :category "Зеленый чай"} + {:path "chay/krasnyy_chay" :category "Красный чай"} + {:path "chay/severo_futszyanskie_uluny" :category "Улун"} + {:path "chay/tayvanskie_uluny" :category "Улун"} + {:path "chay/khey_cha" :category "Хэй ча"} + {:path "chay/shen_puer" :category "Шэн пуэр"} + {:path "chay/shu_puery" :category "Шу пуэр"} + {:path "chay/yuzhno_futszyanskie_uluny_" :category "Улун"} + {:path "chay/yunnanskie_uluny" :category "Улун"} + {:path "chay/gaba_chay" :category "Улун"} + {:path "chay/na_kazhdyy_den"} + {:path "chay/eksklyuziv"} + {:path "posuda_i_aksessuary/pialy" :category "Посуда"} + {:path "posuda_i_aksessuary/isinskaya_glina" :category "Посуда"} + {:path "posuda_i_aksessuary/keramika_iz_tszindechzhen" :category "Посуда"} + {:path "posuda_i_aksessuary/keramika_iz_tszyanshuy" :category "Посуда"} + {:path "posuda_i_aksessuary/kolby_termosy_nabory" :category "Посуда"} + {:path "posuda_i_aksessuary/chabani" :category "Посуда"} + {:path "posuda_i_aksessuary/chaynye_figurki" :category "Посуда"} + {:path "posuda_i_aksessuary/slivniki" :category "Посуда"} + {:path "posuda_i_aksessuary/gayvani" :category "Посуда"} + {:path "posuda_i_aksessuary/keramika_iz_tsinchzhou" :category "Посуда"} + {:path "posuda_i_aksessuary/aksessuary"} + {:path "posuda_i_aksessuary/pialy_tszindechzhen" :category "Посуда"} + {:path "posuda_i_aksessuary/keramika_dekhua" :category "Посуда"} + {:path "posuda_i_aksessuary/chayniki_iz_farfora" :category "Посуда"}] + format-url + product-peg + normalize)) + +{: products} diff --git a/static/chaekshop.svg b/static/chaekshop.svg new file mode 100644 index 0000000..00146bd --- /dev/null +++ b/static/chaekshop.svg @@ -0,0 +1,3 @@ +<svg width="120" height="120" viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M86.7327 48.8756L81.7889 39.3407H65.7517L54.3689 33L42.9861 39.2454H27.1901L21.0164 51.164L6.25731 40.8425L1 43.6076L14.5291 64.6797L3.79747 86.8246H109.764L110.752 82.7722L117.119 56.5512L117.264 55.9076L117.891 53.357L119 48.8518L86.7327 48.8756ZM54.3689 36.2657L59.795 39.2454H48.9428L54.3689 36.2657ZM19.4247 77.0513L33.0503 49.6861H75.5187L89.4337 77.0513H19.4247ZM103.445 81.342L90.7118 56.5751H110.174L103.445 81.342Z" fill="#65A30D"/> +</svg> |
