{"id":21028231,"url":"https://github.com/exyi/autoduchodce","last_synced_at":"2026-04-29T06:33:12.456Z","repository":{"id":38048659,"uuid":"212799092","full_name":"exyi/autoduchodce","owner":"exyi","description":"AutoDůchodce - automatický monitoring slev z kupi.cz","archived":false,"fork":false,"pushed_at":"2022-12-08T04:32:32.000Z","size":7,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-01-02T15:20:10.199Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"F#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/exyi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-10-04T11:25:55.000Z","updated_at":"2025-03-24T08:06:55.000Z","dependencies_parsed_at":"2023-01-24T15:45:11.983Z","dependency_job_id":null,"html_url":"https://github.com/exyi/autoduchodce","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/exyi/autoduchodce","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exyi%2Fautoduchodce","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exyi%2Fautoduchodce/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exyi%2Fautoduchodce/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exyi%2Fautoduchodce/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/exyi","download_url":"https://codeload.github.com/exyi/autoduchodce/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exyi%2Fautoduchodce/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32414416,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T06:29:02.080Z","status":"ssl_error","status_checked_at":"2026-04-29T06:29:00.631Z","response_time":110,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-19T11:54:30.630Z","updated_at":"2026-04-29T06:33:12.428Z","avatar_url":"https://github.com/exyi.png","language":"F#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AutoDůchodce\n\nSystémek, který stáhne z kupi.cz aktuální slevy, prožene je nadefinovanými pravidly a pošle emailem report co je kde za zajímavé ceny.\n\n\n## Konfigurace\n\nAutodůchodce se konfiguruje oeditováním souboru `Config.fs` (ano je to zdroják, ale nechtělo se mi vymýšlet nějaké mapování do JSONu), přesný formát je popsaný níže.\n\nV principu se tam napíše seznam \"triggerů\", které říkají čím se vyznačuje zajímavá nabidka.\n* Jedna možnost je určit zboží a výhodnout jednotkovou cenu.\n    - Když botík najde nabídku daného zboží za zadanou cenu (nebo nižší), tak jej přidá do seznamu.\n    - Tato možnost je výhodná na trvanlivé věci.\n* Druhá možnost je určit zboží, jeho normální cenu typický objem ve kterém bych jej koupil\n    - Pak je nabídka zahrnuta do reportu jen když se v jednom obchodě dá nakoupit se slevou větší než zadaný limit (`DealLimit`)\n    - Toto se hodí na netrvanlivé věci, které se nadají nakoupit ve velkém.\n\nDefinice zboží je taky trochu netriviální, protože na kupi.cz není vždy snadné vybrat prostě \"surové kakao\", když tam na to není kategorie. Je možné zboží zadat jako seznam zdrojů, což jsou prakticky stránky na kupi.cz a pak se dají dále filtrovat regulárními výrazů (podle názvu).\n\nFormát vypadá následovně. Toto seznam konfigurací (je možné najednou spustit několik definic pro různé lidi nebo tak)\n\n```F#\nlet configs = [\n    {\n        Settings.Recipients = [ \"autoduchodce@mailinator.com\" ] // https://www.mailinator.com/v3/index.jsp?zone=public\u0026query=autoduchodce\n        SaveFile = \"laststuff.json\" // soubor kam se ukládá poslední stav\n        DealLimit = 100.0 // limit na kombinovanou slevu (v korunách)\n        Defs = [\n            ... // definice triggerů\n        ]\n    }\n]\n```\n\nTrigger na cenu vypadá asi takto:\n\n```F#\nDefs = [\n    KupiPriceTrigger (68.0, { Sources = [ Page \"sleva/sirup-yo\" ]; Filters = [] }) // https://www.kupi.cz/sleva/sirup-yo za méně než 68.0Kč za litr\n]\n```\n\nTrigger na celkovou výší slevy může vypadat takto:\n\n```F#\nDefs = [\n    KupiAggregatedDealTrigger (3.5, 15.0, { Sources = [ Search \"vejce\"]; Filters = [] }) // \"normálně\" kupuju 15 vajec za 3.5 koruny, kolik na tom ušetřím?\n    KupiAggregatedDealTrigger (15., 10., { Sources = [ Category \"medy\" ]; Filters = [] }) // \"normálně\" kupuju 10x100g medu za 150 korun\n]\n```\n\nDefinice zboží už byla vidět výše, ale je to objekt se seznamem zdrojů (`Sources`) a filtrů (`Filters`). V `Sources` může být:\n* `Search \"vyhledávaný text\"` - V podstatě `https://www.kupi.cz/hledej?f=vyhledávaný text`\n* `Category \"název-kategorie\"` - V podstatě kategorie `https://www.kupi.cz/slevy/název-kategorie`\n* `Page \"sleva/med-kvetovy-pastovany-medokomerc\"` - přesná adresa na `https://kupi.cz`\n\nJe možné mít zdrojů víc, v F# se oddělují novým řádkem nebo středníkem.\n\nFiltry se koukají regulárním výrazem na název výrobku a jsou dvou typů:\n* `IncludeByRegex \"regex, který musí ta věc splňovat\"`\n* `ExcludeByRegex \"regex, který nesmí splňovat\"`\n\nProtože je konfigurace F# kód, je samozřejmě možné konfiguraci kdejak vygenerovat nebo třeba jenom používat proměnné:\n\n```F#\nlet musli = { Sources = [ Page \"sleva/musli-mysli-na-zdravi-emco\"; Page \"sleva/musli-zapekane-bonavita\"; Page \"sleva/musli-bonavita\" ]; Filters = [] }\n\nlet configs = [\n    {\n        Settings.Recipients = [ \"autoduchodce@mailinator.com\" ]\n        SaveFile = \"laststuff.json\"\n        DealLimit = 100.0\n        Defs = [\n            KupiPriceTrigger (7.60, musli)\n        ]\n    }\n]\n```\n\n## Spouštění\n\nProgram se spustí pomocí příkazu `dotnet run -- smtp-server:port username password` (vyžaduje nainstalované dotnet SDK).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexyi%2Fautoduchodce","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fexyi%2Fautoduchodce","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexyi%2Fautoduchodce/lists"}