{"id":15408719,"url":"https://github.com/attomos/hdoc-tracker","last_synced_at":"2025-10-11T07:31:18.015Z","repository":{"id":40538455,"uuid":"456184783","full_name":"attomos/hdoc-tracker","owner":"attomos","description":"My personal #100DaysOfCode tracker","archived":true,"fork":false,"pushed_at":"2023-07-26T16:22:41.000Z","size":1362,"stargazers_count":6,"open_issues_count":3,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-28T17:39:32.301Z","etag":null,"topics":["100daysofcode"],"latest_commit_sha":null,"homepage":"https://hdoc-tracker.vercel.app","language":"Python","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/attomos.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-02-06T15:08:56.000Z","updated_at":"2024-06-01T16:20:52.000Z","dependencies_parsed_at":"2025-01-28T17:33:23.054Z","dependency_job_id":"ce117ba4-9e23-48ae-bcee-d636234ceaab","html_url":"https://github.com/attomos/hdoc-tracker","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/attomos/hdoc-tracker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/attomos%2Fhdoc-tracker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/attomos%2Fhdoc-tracker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/attomos%2Fhdoc-tracker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/attomos%2Fhdoc-tracker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/attomos","download_url":"https://codeload.github.com/attomos/hdoc-tracker/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/attomos%2Fhdoc-tracker/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279006618,"owners_count":26084131,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-11T02:00:06.511Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["100daysofcode"],"created_at":"2024-10-01T16:34:56.743Z","updated_at":"2025-10-11T07:31:17.614Z","avatar_url":"https://github.com/attomos.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# hdoc-tracker [28/62]\n\n## TODO\n\n- [x] GitHub actions\n- [x] Streak count (longest and current)\n- [x] extract more entities (link to src, demo, etc.)\n- [x] list view\n  - [x] timestamp\n  - [x] extra entities (demo, src, etc.)\n  - [x] Link to original tweet\n- [x] thread view\n  - [x] YouTube reply clone\n- [x] Keyboard shortcuts dialog + ? binding to display it\n- [x] improve color contrast (thanks to VisBug)\n- [ ] pytest\n  - [x] at least have some tests\n  - [ ] 80% coverage\n  - [x] coverage\n  - [ ] GitHub Actions\n- [ ] jest unit tests\n  - [x] at least have some tests\n  - [ ] 80% coverage\n  - [ ] GitHub Actions\n- [ ] cypress\n- [x] routing\n- [ ] refactor UI code\n- [ ] refactor backend code\n- [x] responsive\n- [x] mobile friendly\n- [x] Search functionality\n- [x] dark mode\n- [-] adaptive SVG favicon\n- [x] SVG className instead of other state prop\n- [ ] performance measurement\n  - [ ] get_tweets time taken (incremental fetch already?)\n  - [ ] Lighthouse Mobile score\n  - [ ] Lighthouse Desktop score\n- [ ] performance improvements\n- [ ] about page with Mermaid https://www.youtube.com/watch?v=6TiIrJf63Xs\n- [ ] support for new rounds (backend)\n  - [x] folder-based? nope\n  - [x] Filter by round\n  - [x] need an API for new rounds (or for the sake of learning 😏)\n- [ ] support for new rounds (UI)\n  - [ ] round selector (that ListBox)\n  - [ ] ListBox could use some CSS and custom div\n  - [ ] routing\n- [ ] data fetching\n  - [x] merge tweets\n  - [x] merge tweets unit test\n  - [ ] create a single commit for multiple JSON files update\n- [ ] put more context in automatic commits\n  - [ ] time taken\n  - [ ] pretty stats table (probably better add a comment in each automatic tweet)\n- [ ] new data storage design\n  - [ ] where to keep the backend state (everything in upstash?)\n  - [ ] data backup (S3 or some storage service)\n- [ ] more entity support\n  - [ ] npm\n  - [ ] pypi\n  - [ ] rust package\n  - [ ] go package\n- [ ] round 2 (migrated to Mastodon)\n  - [x] Make sure content are always in HTML?? https://docs.joinmastodon.org/entities/Status/#content\n  - [ ] prepare new component for round 2 content\n\n## bugs\n\n- [x] time zone bug in `formatTwitterDate` function\n- [x] no streaks, but display the most recent streak instead\n- [x] compare_tweets bug (counting number of tweets has some issues, e.g., what about replies tweets)\n- [ ] plus4months bug, activity graph should continue as long as it has new data or reach day 100\n\n## useful resources\n\n- mocking Date in jest\n  - https://github.com/facebook/jest/issues/2234#issuecomment-731451275\n- crop PNG\n  - https://www.iloveimg.com/crop-image/crop-png\n- PyGithub update multiple files\n  - https://github.com/PyGithub/PyGithub/issues/1628#issuecomment-671173979\n\n## layout resource, inspirations\n\n- grid layout with side navigation rails\n  - https://developer.chrome.com/\n\n## design\n\n### data to keep in stats file (sample)\n\n| field                  | data                                |\n| ---------------------- | ----------------------------------- |\n| since_id               | 1234567 (loaded from metadata file) |\n| total tweets count     | 300                                 |\n| tweets count (round 1) | 120                                 |\n| tweets count (round 2) | 180                                 |\n| elapsed time (seconds) | 3.33                                |\n\n### flowchart for data fetching/processing pipeline\n\n```mermaid\ngraph TD\n    S0[Daily run] --\u003e A1\n    S1[manual or weekly run] --\u003e|pass start_time parameter| A\n    A1(Determine where should the script start fetching tweets) --\u003e D1{stats file exists}\n    D1 --\u003e|does not exist| F1(run script without since_id)\n    D1 --\u003e|exists| F2(run script with since_id)\n    F1 --\u003e A\n    F2 --\u003e A\n    subgraph get_tweets.py\n    A(Fetch tweets from Twitter API) --\u003e B(Extract metadata)\n    B --\u003e B2(group tweets by conversation_id)\n    B2 --\u003e B3(group tweets by round)\n    B3 --\u003e B4(write the results to files)\n    end\n    B4 --\u003e U1(push changes to GitHub)\n    U1 --\u003e U2(upload data to Upstash)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fattomos%2Fhdoc-tracker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fattomos%2Fhdoc-tracker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fattomos%2Fhdoc-tracker/lists"}