{"id":15169855,"url":"https://github.com/htomsik/urlreader","last_synced_at":"2025-10-01T03:31:50.241Z","repository":{"id":111125830,"uuid":"535854671","full_name":"Htomsik/UrlReader","owner":"Htomsik","description":"Read Urls from file and count some tags from urls","archived":true,"fork":false,"pushed_at":"2023-02-04T19:27:05.000Z","size":4362,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-10-01T01:52:31.527Z","etag":null,"topics":["mvvm","parser","reactiveui","wpf"],"latest_commit_sha":null,"homepage":"","language":"C#","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/Htomsik.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-09-12T21:20:48.000Z","updated_at":"2024-05-28T11:54:51.000Z","dependencies_parsed_at":"2023-04-03T21:32:45.158Z","dependency_job_id":null,"html_url":"https://github.com/Htomsik/UrlReader","commit_stats":{"total_commits":64,"total_committers":1,"mean_commits":64.0,"dds":0.0,"last_synced_commit":"71733b3a0674a9d92b06c463e6d0adbd8299617c"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Htomsik%2FUrlReader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Htomsik%2FUrlReader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Htomsik%2FUrlReader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Htomsik%2FUrlReader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Htomsik","download_url":"https://codeload.github.com/Htomsik/UrlReader/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234821016,"owners_count":18891965,"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","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":["mvvm","parser","reactiveui","wpf"],"created_at":"2024-09-27T07:40:21.466Z","updated_at":"2025-10-01T03:31:44.844Z","avatar_url":"https://github.com/Htomsik.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- PROJECT LOGO --\u003e\n\u003cbr /\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003ca\u003e\n    \u003cimg src=\"https://raw.githubusercontent.com/Htomsik/Htomsik/main/Assets/AllTestTasks/TestIcon.png\" alt=\"Logo\" width=\"200\"\u003e\n  \u003c/a\u003e\n\n\u003c/div\u003e\n\n\u003ch3 align=\"center\"\u003eUrlReader (Тестовое задание)\u003c/h3\u003e\n\n\u003cdiv align=\"left\"\u003e\n  \u003col\u003e\n    \u003cli\u003e\n      \u003ca href=\"#О-проекте\"\u003eО проекте\u003c/a\u003e\n      \u003cul\u003e\n        \u003cli\u003e\u003ca href=\"#Краткая-сводка\"\u003eКраткая сводка\u003c/a\u003e\u003c/li\u003e\n      \u003c/ul\u003e\n      \u003cul\u003e\n        \u003cli\u003e\u003ca href=\"#Установка\"\u003eУстановка\u003c/a\u003e\u003c/li\u003e\n      \u003c/ul\u003e\n      \u003cul\u003e\n        \u003cli\u003e\u003ca href=\"#Использованные-библиотеки\"\u003eИспользованные библиотеки\u003c/a\u003e\u003c/li\u003e\n      \u003c/ul\u003e\n    \u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#Функционал\"\u003eФункционал\u003c/a\u003e\u003c/li\u003e\n      \u003cul\u003e\n        \u003cli\u003e\u003ca href=\"#Интерфейс\"\u003eИнтерфейс\u003c/a\u003e\u003c/li\u003e\n      \u003c/ul\u003e\n      \u003cul\u003e\n        \u003cli\u003e\u003ca href=\"#Видео-демонстрация\"\u003eВидео-демонстрация\u003c/a\u003e\u003c/li\u003e\n      \u003c/ul\u003e\n      \u003cul\u003e\n        \u003cli\u003e\u003ca href=\"#Структура-приложения\"\u003eСтруктура приложения\u003c/a\u003e\u003c/li\u003e\n      \u003c/ul\u003e\n    \u003cli\u003e\u003ca href=\"#Возникшие-сложности\"\u003eВозникшие сложности и как решал\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#Не-решённые-на-данный-момент-проблемы\"\u003eНе решенные проблемы\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#Возможные-улучшения-функционала\"\u003eВозможные улучшения функционала\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#Связь-со-мной\"\u003eСвязь со мной\u003c/a\u003e\u003c/li\u003e\n  \u003c/ol\u003e\n\u003c/div\u003e\n\n\n\n\u003c!-- ABOUT THE PROJECT --\u003e\n\u003cdiv align=\"center\"\u003e\n\n# О проекте\n\n\n\n\u003cimg width=\"80%\" src=\"https://raw.githubusercontent.com/Htomsik/UrlReader/master/Assets/Preview/Prewiew.png\"/\u003e\n\n\u003c/div\u003e\n\n## Краткая сводка\n\n\u003ch3 aligh=\"right\"\u003eUrlRead - Программа для считывания ссылок на веб страницы из файла в формате Json и ведения некоторой статистики по ним.\u003c/h2\u003e\n\n## Использованные библиотеки\n\n| Библиотека                                                                                          | Как использовал                                                                                                                                                |\n|-----------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| [![Serilog][.Serilog-shield]][.Serilog-url]                                                         | Лоигрование в файл и интерфейс для отображения выполняемых действий                                                                                            |\n| [![FastJson][.FastJson-shield]][.FastJson-url]                                                      | Для десериализации данных из загружаемых файлов                                                                                                                |\n | [![AngleSharp][.AngleSharp-shield]][.AngleSharp-url]                                                | Для парсинга тегов с html страницы                                                                                                                             |\n| [![ReactiveUi][.ReactiveUi-shield]][.ReactiveUi-url]                                                | Для создания базовой инфраструктуры mvvm приложения                                                                                                            |\n| [![LiteApp][.LiteApp-shield]][.LiteApp-url]                                                         | Для создания базовой инфраструктуры хранилищ и сервисов (Собственная библиотека, возникли некоторые сложности, но в целом потихоньку расширяется и улучшается) |\n| [![Microsoft.Extension.Hosting][.Microsoft.Extension.Hosting-shield]][.Microsoft.Extension.Hosting-url] | Для создания хоста приложения и DI контейнера                                                                                                                  |\n| [![MaterialDesignThemes][.MaterialDesignThemes-shield]][.MaterialDesignThemes-url]                  | Для дизайна WPF (Готовая xaml тема)                                                                                                                            |\n\n\n\n## Установка\n\n**Последнюю версию установщика, а также пояснения по запуску находятся [тут](https://github.com/Htomsik/UrlReader/releases)**\n\n\u003cdiv align=\"center\"\u003e\n\n## Функционал\n\n### Интерфейс\n\n\u003cimg src=\"https://raw.githubusercontent.com/Htomsik/UrlReader/master/Assets/Preview/Functional%20Interface%20diagram.png\"/\u003e\n\n\n### Видео-демонстрация\n\n\n\u003ca href=\"https://www.youtube.com/watch?v=1EPAk54lnmY\u0026t=7s\"\u003e\n\u003cimg width=\"60%\" src=\"https://raw.githubusercontent.com/Htomsik/UrlReader/master/Assets/Preview/VideoPrewiew.png\"/\u003e\n\u003c/a\u003e\n\n\u003cdiv align=\"left\"\u003e\n\n\u003c/div\u003e\n\n\n\n ### Структура приложения\n\n\u003c/div\u003e\n\nОсобенности структуры работы с данными:\n\n* Хранилища - зарегистрированные в IOC re-used контейнеры с данными. Базовые реализации и пояснения как работают определены в [LiteApp][.LiteApp-url]\n* Сервисы - обьекты управляющие данными, зачастую в хранилишах.\n\nОсобенности реализации mvvm:\n* Модели - в данном случае модели реализуют INPC для отображения их изменений в интерфейсе\n* ViewModel (дальше: vmd) - обычно я разделю vmd на два типа:\n  * Управляющие отображением других vmd.\n  \u003e Например если бы я готовил это приложение с учётом того что в будующем оно будет обрастать функционалом \n  \u003e то блоки показанные на схеме выше были бы отдельными UserControl со своими vmd, а управлением этими блокми бы занимался отдельный vmd.\n  * Упавляющий отображением данных.\n  \u003e В данном случае такими блоками были бы: Статистика, таблица с данными и верхнее меню.\n\nНо в этот раз я точно знал какой функционал должен быть в приложении, поэтому не стал создавать навигационную инфраструктуру.\n\n\n\u003cdiv align=\"center\"\u003e\n\n## Возникшие сложности\n\n\u003c/div\u003e\n\n### Утечка памяти (Частичное решение)\n\n\u003cdetails\u003e\n  \u003csummary\u003eОписание внутри\u003c/summary\u003e\n\n**Причина:** Изначальное незнание правильной работы с подписками в ReactiveUi (Уже понял что делал не так)\n\n**Как решал:** с помощью dotMemory находил моменты когда потребляемая память вела себя ненормально и смотрел что вызывалось в этот момент, также пользовался разными средствами в Rider.\n\n**Удалось решить?:** Основная утечка устранена, однако периодически из за неправильного использования ReactiveUi всплывают небольшие утечки, а также данные после очистки стираются не сразу.\n\n\u003c/details\u003e\n\n\n### Ускорение алгоритмов загрузки данных в приложение и парсинга (Удалось решить)\n\n\u003cdetails\u003e\n \u003csummary\u003eОписание внутри\u003c/summary\u003e\n\n**Причина:** Первая версия приложения была асинхронная, но операции с данными выполнялись в одном потоке.\n\n**Как решал:** Добавил для загрузки из json файла асинхронную передачу из стрима и сменил библиотеку для десериализации, а сам парсинг разбил на блоки по 100 потоков.\n\n**Удалось решить?:** Скорость ввода и обработки данных значительно повысилась, однако для парсинга наложились проблемы с http (о них ниже)\n\n\u003c/details\u003e\n\n\n### Пробемы с Http (Частичное решение)\n\n\u003cdetails\u003e\n \u003csummary\u003eОписание внутри\u003c/summary\u003e\n\n**Суть:** http оставляет после себя открытые соединения, настройки хандлеров для http не приносили успеха\n\n**Как решал:** Ограничил одновременных запросов до 100 за раз, а также снизил TimeOut запроса до нескольких секунд и для компенсации количества необработанных соединений добавил несколько подходов на один блок запрашиваемых данных.\n\n**Удалось решить?:** Частично. Количество успешно обработанных соединений (любые не Unknown статусы) возросло в несколько раз, однако общий покаатель отработанных запросов находиться в районе 80%.\n\n\u003c/details\u003e\n\n\n\u003cdiv align=\"center\"\u003e\n\n## Не решенные на данный момент проблемы\n\n\u003c/div\u003e\n\n### Провисания во время отображения больших массивов данных в таблице\n\n\u003cdetails\u003e\n \u003csummary\u003eОписание внутри\u003c/summary\u003e\n\n**Причина:** Загрузка одновременно свыше 100к данных в таблицу.\n\n**Степень критичности:** Низкая, провисание на несколько секунд.\n\n**Возможное решение:** Разбивка большого массива на блоки по 10к и загрузка по очереди\n\n**Почему сразу не исправил:** Ограничение по времени. Реализация хранилищ в LiteApp не асинхронная и некоторые операции можно будет сделать только после доработки в библиотеке.\n\n\u003c/details\u003e\n\n### Проблемы асинхонных обращений к хранилищам\n\n\u003cdetails\u003e\n \u003csummary\u003eОписание внутри\u003c/summary\u003e\n\n**Причина:** Отсуствие реализации асинхронных хранилищ в LiteApp\n\n**Степень критичности:** Критическое. Многие функции приложения были урезаны или не могут быть реализованны по этой причине\n\n**Затронутые сферы:** \n\n* Обновление у сервиса статискики происходит только в моменты когда хранилище никто не использует\n* Невозможность исправить провисания при загрузке больших данных\n* Невозможность использования хранилища для сообщений от логгера в многопоточном режиме\n\n**Почему сразу не исправил:** Ограничение по времени. Реализация хранилищ в LiteApp не асинхронная и некоторые операции можно будет сделать только после доработки в библиотеке.\n\n\u003c/details\u003e\n\n\n\u003cdiv align=\"center\"\u003e\n\n## Возможные улучшения функционала\n\n\u003c/div\u003e\n\n### Если решить вышеописанные проблемы то можно было бы\n\n* Добавить вывод последних 50 сообщений от логгера в отдельной таблице как возможную функцию\n* Добавить одновременную загрузка из файла, десериализацию и запуск парсинга.\n* Значительно расширить статистику\n* Выводить в разные таблицы отфильтрованные данные по различным параметрам (по выбору)\n* Добавить фильтры для парсинга: максимальный вес скачиваемого сайта, время ожидания и тд.\n* Добавить drag and drop для файлов и т.д.\n\n\n### Что требуется улучшить\n\n* Алгоритм проверки данных в файле (сейчас он очень простой и требует соблюдения от пользователя конкретных норм)\n* Код написанный криворукими руками (моими)\n\n\n# Связь со мной\n\nПочта:lhz4ru822@mozmail.com\n\n[![Konstantin](https://img.shields.io/badge/Konstantin-090909?style=for-the-badge\u0026logo=vk\u0026logoColor=red)](https://vk.com/jessnjake)\n\n\n\n[.Serilog-shield]: https://img.shields.io/badge/Serilog-090909?style=for-the-badge\u0026logo=\n[.Serilog-url]: https://serilog.net/\n\n[.AngleSharp-shield]: https://img.shields.io/badge/AngleSharp-090909?style=for-the-badge\u0026logo=\n[.AngleSharp-url]: https://anglesharp.github.io/\n\n[.FastJson-shield]: https://img.shields.io/badge/FastJson-090909?style=for-the-badge\u0026logo=\n[.FastJson-url]: https://www.codeproject.com/Articles/159450/fastJSON-Smallest-Fastest-Polymorphic-JSON-Seriali\n\n[.ReactiveUi-shield]: https://img.shields.io/badge/ReactiveUi-090909?style=for-the-badge\u0026logo=\n[.ReactiveUi-url]: https://www.reactiveui.net/\n\n[.ReactiveUi-shield]: https://img.shields.io/badge/ReactiveUi-090909?style=for-the-badge\u0026logo=\n[.ReactiveUi-url]: https://www.reactiveui.net/\n\n[.Microsoft.Extension.Hosting-shield]: https://img.shields.io/badge/Microsoft_Extension_Hosting-090909?style=for-the-badge\u0026logo=\n[.Microsoft.Extension.Hosting-url]: https://dotnet.microsoft.com/en-us/\n\n[.MaterialDesignThemes-shield]: https://img.shields.io/badge/Material_Design_Themes-090909?style=for-the-badge\u0026logo=\n[.MaterialDesignThemes-url]: https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit\n\n[.LiteApp-shield]: https://img.shields.io/badge/Lite_App-090909?style=for-the-badge\u0026logo=\n[.LiteApp-url]: https://github.com/Htomsik/LiteApp\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhtomsik%2Furlreader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhtomsik%2Furlreader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhtomsik%2Furlreader/lists"}