diff --git a/.github/workflows/partial-backend.yml b/.github/workflows/partial-backend.yml index 80afa791eb6..154d98626b5 100644 --- a/.github/workflows/partial-backend.yml +++ b/.github/workflows/partial-backend.yml @@ -67,7 +67,7 @@ jobs: - name: Install dependencies run: | sudo apt-get update - sudo apt-get install libsasl2-dev libldap2-dev libssl-dev tesseract-ocr-all + sudo apt-get install libsasl2-dev libldap2-dev libssl-dev poetry install poetry add "psycopg2-binary==2.8.6" if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' || steps.cache-validate.outputs.cache-hit-success != 'true' diff --git a/docker/Dockerfile b/docker/Dockerfile index 9594c0faffb..ee422ff643e 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -50,7 +50,6 @@ RUN apt-get update \ build-essential \ libpq-dev \ libwebp-dev \ - tesseract-ocr-all \ # LDAP Dependencies libsasl2-dev libldap2-dev libssl-dev \ gnupg gnupg2 gnupg1 \ @@ -89,7 +88,6 @@ RUN apt-get update \ && apt-get install --no-install-recommends -y \ gosu \ iproute2 \ - tesseract-ocr-all \ libldap-common \ && rm -rf /var/lib/apt/lists/* diff --git a/docs/docs/overrides/api.html b/docs/docs/overrides/api.html index a54d6bf3c39..83038e2aead 100644 --- a/docs/docs/overrides/api.html +++ b/docs/docs/overrides/api.html @@ -14,7 +14,7 @@
diff --git a/frontend/components/Domain/Recipe/RecipeActionMenu.vue b/frontend/components/Domain/Recipe/RecipeActionMenu.vue index c5b6a72e76c..ad24e0ed8b1 100644 --- a/frontend/components/Domain/Recipe/RecipeActionMenu.vue +++ b/frontend/components/Domain/Recipe/RecipeActionMenu.vue @@ -102,7 +102,6 @@ const SAVE_EVENT = "save"; const DELETE_EVENT = "delete"; const CLOSE_EVENT = "close"; const JSON_EVENT = "json"; -const OCR_EVENT = "ocr"; export default defineComponent({ components: { RecipeContextMenu, RecipeFavoriteBadge, RecipeTimerMenu, RecipeTimelineBadge }, @@ -139,10 +138,6 @@ export default defineComponent({ type: Boolean, default: false, }, - showOcrButton: { - type: Boolean, - default: false, - }, }, setup(props, context) { const deleteDialog = ref(false); @@ -175,15 +170,6 @@ export default defineComponent({ }, ]; - if (props.showOcrButton) { - editorButtons.splice(2, 0, { - text: i18n.t("ocr-editor.ocr-editor"), - icon: $globals.icons.eye, - event: OCR_EVENT, - color: "accent", - }); - } - function emitHandler(event: string) { switch (event) { case CLOSE_EVENT: diff --git a/frontend/components/Domain/Recipe/RecipeOcrEditorPage/RecipeOcrEditorPage.vue b/frontend/components/Domain/Recipe/RecipeOcrEditorPage/RecipeOcrEditorPage.vue deleted file mode 100644 index 28b96d60969..00000000000 --- a/frontend/components/Domain/Recipe/RecipeOcrEditorPage/RecipeOcrEditorPage.vue +++ /dev/null @@ -1,390 +0,0 @@ - - - - - diff --git a/frontend/components/Domain/Recipe/RecipeOcrEditorPage/RecipeOcrEditorPageParts/RecipeOcrEditorPageCanvas.vue b/frontend/components/Domain/Recipe/RecipeOcrEditorPage/RecipeOcrEditorPageParts/RecipeOcrEditorPageCanvas.vue deleted file mode 100644 index bcba5f4fce9..00000000000 --- a/frontend/components/Domain/Recipe/RecipeOcrEditorPage/RecipeOcrEditorPageParts/RecipeOcrEditorPageCanvas.vue +++ /dev/null @@ -1,488 +0,0 @@ - - - diff --git a/frontend/components/Domain/Recipe/RecipeOcrEditorPage/RecipeOcrEditorPageParts/RecipeOcrEditorPageHelp.vue b/frontend/components/Domain/Recipe/RecipeOcrEditorPage/RecipeOcrEditorPageParts/RecipeOcrEditorPageHelp.vue deleted file mode 100644 index 39ddf6e8338..00000000000 --- a/frontend/components/Domain/Recipe/RecipeOcrEditorPage/RecipeOcrEditorPageParts/RecipeOcrEditorPageHelp.vue +++ /dev/null @@ -1,54 +0,0 @@ - - - diff --git a/frontend/components/Domain/Recipe/RecipeOcrEditorPage/index.ts b/frontend/components/Domain/Recipe/RecipeOcrEditorPage/index.ts deleted file mode 100644 index ff8b655f3d1..00000000000 --- a/frontend/components/Domain/Recipe/RecipeOcrEditorPage/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import RecipeOcrEditorPage from "./RecipeOcrEditorPage.vue"; - -export default RecipeOcrEditorPage; diff --git a/frontend/components/Domain/Recipe/RecipePage/RecipePageParts/RecipePageHeader.vue b/frontend/components/Domain/Recipe/RecipePage/RecipePageParts/RecipePageHeader.vue index c9e4934534e..b17cab0ca17 100644 --- a/frontend/components/Domain/Recipe/RecipePage/RecipePageParts/RecipePageHeader.vue +++ b/frontend/components/Domain/Recipe/RecipePage/RecipePageParts/RecipePageHeader.vue @@ -50,7 +50,6 @@ :logged-in="isOwnGroup" :open="isEditMode" :recipe-id="recipe.id" - :show-ocr-button="recipe.isOcrRecipe" class="ml-auto mt-n8 pb-4" @close="setMode(PageMode.VIEW)" @json="toggleEditMode()" @@ -58,13 +57,12 @@ @save="$emit('save')" @delete="$emit('delete')" @print="printRecipe" - @ocr="goToOcrEditor" /> - - diff --git a/frontend/pages/g/_groupSlug/r/create.vue b/frontend/pages/g/_groupSlug/r/create.vue index 72463ef0ff0..dad973528bc 100644 --- a/frontend/pages/g/_groupSlug/r/create.vue +++ b/frontend/pages/g/_groupSlug/r/create.vue @@ -52,11 +52,6 @@ export default defineComponent({ text: i18n.tc("recipe.import-with-zip"), value: "zip", }, - { - icon: $globals.icons.fileImage, - text: i18n.tc("recipe.create-recipe-from-an-image"), - value: "ocr", - }, { icon: $globals.icons.link, text: i18n.tc("recipe.bulk-url-import"), diff --git a/frontend/pages/g/_groupSlug/r/create/ocr.vue b/frontend/pages/g/_groupSlug/r/create/ocr.vue deleted file mode 100644 index 63acd2b6124..00000000000 --- a/frontend/pages/g/_groupSlug/r/create/ocr.vue +++ /dev/null @@ -1,85 +0,0 @@ - - diff --git a/frontend/types/ocr-types.ts b/frontend/types/ocr-types.ts deleted file mode 100644 index 2b363cf239f..00000000000 --- a/frontend/types/ocr-types.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { OcrTsvResponse } from "~/lib/api/types/ocr"; -import { Recipe } from "~/lib/api/types/recipe"; - -export type CanvasRect = { - startX: number; - startY: number; - w: number; - h: number; -}; - -export type ImagePosition = { - sx: number; - sy: number; - sWidth: number; - sHeight: number; - dx: number; - dy: number; - dWidth: number; - dHeight: number; - scale: number; - panStartPoint: { - x: number; - y: number; - }; -}; - -export type Mouse = { - current: { - x: number; - y: number; - }; - down: boolean; -}; - -// https://stackoverflow.com/questions/58434389/export typescript-deep-keyof-of-a-nested-object/58436959#58436959 -type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...0[]]; - -type Join = K extends string | number - ? P extends string | number - ? `${K}${"" extends P ? "" : "."}${P}` - : never - : never; - -export type Leaves = [D] extends [never] - ? never - : T extends object - ? { [K in keyof T]-?: Join> }[keyof T] - : ""; - -export type Paths = [D] extends [never] - ? never - : T extends object - ? { - [K in keyof T]-?: K extends string | number ? `${K}` | Join> : never; - }[keyof T] - : ""; - -export type SelectedRecipeLeaves = Leaves; - -export type CanvasModes = "selection" | "panAndZoom"; - -export type SelectedTextSplitModes = keyof OcrTsvResponse | "flatten"; - -export type ToolbarIcons = { - sectionTitle: string; - eventHandler(mode: T): void; - highlight: T; - icons: { - name: T; - icon: string; - tooltip: string; - }[]; -}[]; diff --git a/mealie/routes/__init__.py b/mealie/routes/__init__.py index e421c01ae5a..849ec5b571f 100644 --- a/mealie/routes/__init__.py +++ b/mealie/routes/__init__.py @@ -7,7 +7,6 @@ comments, explore, groups, - ocr, organizers, parser, recipe, @@ -32,4 +31,3 @@ router.include_router(admin.router) router.include_router(validators.router) router.include_router(explore.router) -router.include_router(ocr.router) diff --git a/mealie/routes/ocr/__init__.py b/mealie/routes/ocr/__init__.py deleted file mode 100644 index e23bbc92ec8..00000000000 --- a/mealie/routes/ocr/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from fastapi import APIRouter - -from . import pytesseract - -router = APIRouter(prefix="/ocr") - -router.include_router(pytesseract.router) diff --git a/mealie/routes/ocr/pytesseract.py b/mealie/routes/ocr/pytesseract.py deleted file mode 100644 index d2ffdec6212..00000000000 --- a/mealie/routes/ocr/pytesseract.py +++ /dev/null @@ -1,37 +0,0 @@ -from fastapi import APIRouter, File - -from mealie.routes._base import BaseUserController, controller -from mealie.schema.ocr.ocr import OcrAssetReq, OcrTsvResponse -from mealie.services.ocr.pytesseract import OcrService -from mealie.services.recipe.recipe_data_service import RecipeDataService -from mealie.services.recipe.recipe_service import RecipeService - -router = APIRouter() - - -@controller(router) -class OCRController(BaseUserController): - def __init__(self): - self.ocr_service = OcrService() - - @router.post("/", response_model=str) - def image_to_string(self, file: bytes = File(...)): - return self.ocr_service.image_to_string(file) - - @router.post("/file-to-tsv", response_model=list[OcrTsvResponse]) - def file_to_tsv(self, file: bytes = File(...)): - tsv = self.ocr_service.image_to_tsv(file) - return self.ocr_service.format_tsv_output(tsv) - - @router.post("/asset-to-tsv", response_model=list[OcrTsvResponse]) - def asset_to_tsv(self, req: OcrAssetReq): - recipe_service = RecipeService(self.repos, self.user, self.group) - recipe = recipe_service._get_recipe(req.recipe_slug) - if recipe.id is None: - return [] - data_service = RecipeDataService(recipe.id, recipe.group_id) - asset_path = data_service.dir_assets.joinpath(req.asset_name) - file = open(asset_path, "rb") - tsv = self.ocr_service.image_to_tsv(file.read()) - - return self.ocr_service.format_tsv_output(tsv) diff --git a/mealie/routes/recipe/recipe_crud_routes.py b/mealie/routes/recipe/recipe_crud_routes.py index bace402ebd2..16b7bc687d0 100644 --- a/mealie/routes/recipe/recipe_crud_routes.py +++ b/mealie/routes/recipe/recipe_crud_routes.py @@ -27,10 +27,7 @@ from mealie.schema.recipe import Recipe, RecipeImageTypes, ScrapeRecipe from mealie.schema.recipe.recipe import CreateRecipe, CreateRecipeByUrlBulk, RecipeLastMade, RecipeSummary from mealie.schema.recipe.recipe_asset import RecipeAsset -from mealie.schema.recipe.recipe_ingredient import RecipeIngredient from mealie.schema.recipe.recipe_scraper import ScrapeRecipeTest -from mealie.schema.recipe.recipe_settings import RecipeSettings -from mealie.schema.recipe.recipe_step import RecipeStep from mealie.schema.recipe.request_helpers import RecipeDuplicate, RecipeZipTokenResponse, UpdateImageResponse from mealie.schema.response import PaginationBase, PaginationQuery from mealie.schema.response.pagination import RecipeSearchQuery @@ -489,37 +486,3 @@ def upload_recipe_asset( self.mixins.update_one(recipe, slug) return asset_in - - # ================================================================================================================== - # OCR - @router.post("/create-ocr", status_code=201, response_model=str) - def create_recipe_ocr( - self, extension: str = Form(...), file: UploadFile = File(...), makefilerecipeimage: bool = Form(...) - ): - """Takes an image and creates a recipe based on the image""" - slug = self.service.create_one( - Recipe( - name="New OCR Recipe", - recipe_ingredient=[RecipeIngredient(note="", title=None, unit=None, food=None, original_text=None)], - recipe_instructions=[RecipeStep(text="")], - is_ocr_recipe=True, - settings=RecipeSettings(show_assets=True), - id=None, - image=None, - recipe_yield=None, - rating=None, - orgURL=None, - date_added=None, - date_updated=None, - created_at=None, - update_at=None, - nutrition=None, - ) - ).slug - RecipeController.upload_recipe_asset(self, slug, "Original recipe image", "", extension, file) - if makefilerecipeimage: - # Get the pointer to the beginning of the file to read it once more - file.file.seek(0) - self.update_recipe_image(slug, file.file.read(), extension) - - return slug diff --git a/mealie/schema/ocr/__init__.py b/mealie/schema/ocr/__init__.py deleted file mode 100644 index 1c28eee01c6..00000000000 --- a/mealie/schema/ocr/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# This file is auto-generated by gen_schema_exports.py -from .ocr import OcrAssetReq, OcrTsvResponse - -__all__ = [ - "OcrAssetReq", - "OcrTsvResponse", -] diff --git a/mealie/schema/ocr/ocr.py b/mealie/schema/ocr/ocr.py deleted file mode 100644 index fd535111066..00000000000 --- a/mealie/schema/ocr/ocr.py +++ /dev/null @@ -1,21 +0,0 @@ -from mealie.schema._mealie import MealieModel - - -class OcrTsvResponse(MealieModel): - level: int = 0 - page_num: int = 0 - block_num: int = 0 - par_num: int = 0 - line_num: int = 0 - word_num: int = 0 - left: int = 0 - top: int = 0 - width: int = 0 - height: int = 0 - conf: float = 0.0 - text: str = "" - - -class OcrAssetReq(MealieModel): - recipe_slug: str - asset_name: str diff --git a/mealie/schema/recipe/recipe.py b/mealie/schema/recipe/recipe.py index ba49e00cd07..5b5cca65aed 100644 --- a/mealie/schema/recipe/recipe.py +++ b/mealie/schema/recipe/recipe.py @@ -128,7 +128,6 @@ class Recipe(RecipeSummary): assets: list[RecipeAsset] | None = [] notes: list[RecipeNote] | None = [] extras: dict | None = {} - is_ocr_recipe: bool | None = False comments: list[RecipeCommentOut] | None = [] diff --git a/mealie/services/ocr/__init__.py b/mealie/services/ocr/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/mealie/services/ocr/pytesseract.py b/mealie/services/ocr/pytesseract.py deleted file mode 100644 index 83d84b676b0..00000000000 --- a/mealie/services/ocr/pytesseract.py +++ /dev/null @@ -1,56 +0,0 @@ -from io import BytesIO - -import pytesseract -from PIL import Image - -from mealie.schema.ocr.ocr import OcrTsvResponse -from mealie.services._base_service import BaseService - - -class OcrService(BaseService): - """ - Class for ocr engines. - """ - - def image_to_string(self, image_data): - """ - Returns a plain text translation of an image - """ - return pytesseract.image_to_string(Image.open(image_data)) - - def image_to_tsv(self, image_data, lang=None): - """ - Returns the pytesseract default tsv output - """ - if lang is not None: - return pytesseract.image_to_data(Image.open(BytesIO(image_data)), lang=lang) - - return pytesseract.image_to_data(Image.open(BytesIO(image_data))) - - def format_tsv_output(self, tsv: str) -> list[OcrTsvResponse]: - """ - Returns a OcrTsvResponse from a default pytesseract tsv output - """ - lines = tsv.split("\n") - titles = [t.strip() for t in lines[0].split("\t")] - response: list[OcrTsvResponse] = [] - - for i in range(1, len(lines)): - if lines[i] == "": - continue - - line = OcrTsvResponse() - for key, value in zip(titles, lines[i].split("\t"), strict=False): - if key == "text": - setattr(line, key, value.strip()) - elif key == "conf": - setattr(line, key, float(value.strip())) - elif key in OcrTsvResponse.__fields__: - setattr(line, key, int(value.strip())) - else: - continue - - if isinstance(line, OcrTsvResponse): - response.append(line) - - return response diff --git a/poetry.lock b/poetry.lock index 9bbd67e294d..3059793799b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -605,6 +605,7 @@ files = [ {file = "greenlet-2.0.2-cp27-cp27m-win32.whl", hash = "sha256:6c3acb79b0bfd4fe733dff8bc62695283b57949ebcca05ae5c129eb606ff2d74"}, {file = "greenlet-2.0.2-cp27-cp27m-win_amd64.whl", hash = "sha256:283737e0da3f08bd637b5ad058507e578dd462db259f7f6e4c5c365ba4ee9343"}, {file = "greenlet-2.0.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:d27ec7509b9c18b6d73f2f5ede2622441de812e7b1a80bbd446cb0633bd3d5ae"}, + {file = "greenlet-2.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d967650d3f56af314b72df7089d96cda1083a7fc2da05b375d2bc48c82ab3f3c"}, {file = "greenlet-2.0.2-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:30bcf80dda7f15ac77ba5af2b961bdd9dbc77fd4ac6105cee85b0d0a5fcf74df"}, {file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26fbfce90728d82bc9e6c38ea4d038cba20b7faf8a0ca53a9c07b67318d46088"}, {file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9190f09060ea4debddd24665d6804b995a9c122ef5917ab26e1566dcc712ceeb"}, @@ -613,6 +614,7 @@ files = [ {file = "greenlet-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:76ae285c8104046b3a7f06b42f29c7b73f77683df18c49ab5af7983994c2dd91"}, {file = "greenlet-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:2d4686f195e32d36b4d7cf2d166857dbd0ee9f3d20ae349b6bf8afc8485b3645"}, {file = "greenlet-2.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c4302695ad8027363e96311df24ee28978162cdcdd2006476c43970b384a244c"}, + {file = "greenlet-2.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d4606a527e30548153be1a9f155f4e283d109ffba663a15856089fb55f933e47"}, {file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c48f54ef8e05f04d6eff74b8233f6063cb1ed960243eacc474ee73a2ea8573ca"}, {file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1846f1b999e78e13837c93c778dcfc3365902cfb8d1bdb7dd73ead37059f0d0"}, {file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a06ad5312349fec0ab944664b01d26f8d1f05009566339ac6f63f56589bc1a2"}, @@ -642,6 +644,7 @@ files = [ {file = "greenlet-2.0.2-cp37-cp37m-win32.whl", hash = "sha256:3f6ea9bd35eb450837a3d80e77b517ea5bc56b4647f5502cd28de13675ee12f7"}, {file = "greenlet-2.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:7492e2b7bd7c9b9916388d9df23fa49d9b88ac0640db0a5b4ecc2b653bf451e3"}, {file = "greenlet-2.0.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:b864ba53912b6c3ab6bcb2beb19f19edd01a6bfcbdfe1f37ddd1778abfe75a30"}, + {file = "greenlet-2.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1087300cf9700bbf455b1b97e24db18f2f77b55302a68272c56209d5587c12d1"}, {file = "greenlet-2.0.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:ba2956617f1c42598a308a84c6cf021a90ff3862eddafd20c3333d50f0edb45b"}, {file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc3a569657468b6f3fb60587e48356fe512c1754ca05a564f11366ac9e306526"}, {file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8eab883b3b2a38cc1e050819ef06a7e6344d4a990d24d45bc6f2cf959045a45b"}, @@ -650,6 +653,7 @@ files = [ {file = "greenlet-2.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b0ef99cdbe2b682b9ccbb964743a6aca37905fda5e0452e5ee239b1654d37f2a"}, {file = "greenlet-2.0.2-cp38-cp38-win32.whl", hash = "sha256:b80f600eddddce72320dbbc8e3784d16bd3fb7b517e82476d8da921f27d4b249"}, {file = "greenlet-2.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:4d2e11331fc0c02b6e84b0d28ece3a36e0548ee1a1ce9ddde03752d9b79bba40"}, + {file = "greenlet-2.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8512a0c38cfd4e66a858ddd1b17705587900dd760c6003998e9472b77b56d417"}, {file = "greenlet-2.0.2-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:88d9ab96491d38a5ab7c56dd7a3cc37d83336ecc564e4e8816dbed12e5aaefc8"}, {file = "greenlet-2.0.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:561091a7be172ab497a3527602d467e2b3fbe75f9e783d8b8ce403fa414f71a6"}, {file = "greenlet-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:971ce5e14dc5e73715755d0ca2975ac88cfdaefcaab078a284fea6cfabf866df"}, @@ -1862,21 +1866,6 @@ files = [ html5lib = "*" rdflib = "*" -[[package]] -name = "pytesseract" -version = "0.3.10" -description = "Python-tesseract is a python wrapper for Google's Tesseract-OCR" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytesseract-0.3.10-py3-none-any.whl", hash = "sha256:8f22cc98f765bf13517ead0c70effedb46c153540d25783e04014f28b55a5fc6"}, - {file = "pytesseract-0.3.10.tar.gz", hash = "sha256:f1c3a8b0f07fd01a1085d451f5b8315be6eec1d5577a6796d46dc7a62bd4120f"}, -] - -[package.dependencies] -packaging = ">=21.3" -Pillow = ">=8.0.0" - [[package]] name = "pytest" version = "7.2.2" @@ -2024,6 +2013,7 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -2031,8 +2021,15 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -2049,6 +2046,7 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -2056,6 +2054,7 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -2972,6 +2971,16 @@ files = [ {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c"}, {file = "wrapt-1.14.1-cp310-cp310-win32.whl", hash = "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8"}, {file = "wrapt-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164"}, + {file = "wrapt-1.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ecee4132c6cd2ce5308e21672015ddfed1ff975ad0ac8d27168ea82e71413f55"}, + {file = "wrapt-1.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2020f391008ef874c6d9e208b24f28e31bcb85ccff4f335f15a3251d222b92d9"}, + {file = "wrapt-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2feecf86e1f7a86517cab34ae6c2f081fd2d0dac860cb0c0ded96d799d20b335"}, + {file = "wrapt-1.14.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:240b1686f38ae665d1b15475966fe0472f78e71b1b4903c143a842659c8e4cb9"}, + {file = "wrapt-1.14.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9008dad07d71f68487c91e96579c8567c98ca4c3881b9b113bc7b33e9fd78b8"}, + {file = "wrapt-1.14.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6447e9f3ba72f8e2b985a1da758767698efa72723d5b59accefd716e9e8272bf"}, + {file = "wrapt-1.14.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:acae32e13a4153809db37405f5eba5bac5fbe2e2ba61ab227926a22901051c0a"}, + {file = "wrapt-1.14.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49ef582b7a1152ae2766557f0550a9fcbf7bbd76f43fbdc94dd3bf07cc7168be"}, + {file = "wrapt-1.14.1-cp311-cp311-win32.whl", hash = "sha256:358fe87cc899c6bb0ddc185bf3dbfa4ba646f05b1b0b9b5a27c2cb92c2cea204"}, + {file = "wrapt-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:26046cd03936ae745a502abf44dac702a5e6880b2b01c29aea8ddf3353b68224"}, {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907"}, {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3"}, {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3"}, @@ -3025,4 +3034,4 @@ pgsql = ["psycopg2-binary"] [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "5e0cc403c1ec022e6a75a4969dd97c55ce312daafd7d2024a3617eca25b2129f" +content-hash = "984d725b667165ebbf82eeea32a38e4f4891192fc8c6be60864d25d5b36e7970" diff --git a/pyproject.toml b/pyproject.toml index 79cb8a450b5..b1fba8d7f90 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,6 @@ passlib = "^1.7.4" psycopg2-binary = { version = "^2.9.1", optional = true } pydantic = "^1.10.4" pyhumps = "^3.5.3" -pytesseract = "^0.3.9" python = "^3.10" python-dateutil = "^2.8.2" python-dotenv = "^1.0.0" diff --git a/tests/data/images/test-ocr.png b/tests/data/images/test-ocr.png deleted file mode 100644 index 1b699c9778d..00000000000 Binary files a/tests/data/images/test-ocr.png and /dev/null differ diff --git a/tests/data/text/test-ocr.tsv b/tests/data/text/test-ocr.tsv deleted file mode 100644 index 4cb717e199d..00000000000 --- a/tests/data/text/test-ocr.tsv +++ /dev/null @@ -1,73 +0,0 @@ -level page_num block_num par_num line_num word_num left top width height conf text -1 1 0 0 0 0 0 0 640 480 -1 -2 1 1 0 0 0 36 92 582 269 -1 -3 1 1 1 0 0 36 92 582 92 -1 -4 1 1 1 1 0 36 92 544 30 -1 -5 1 1 1 1 1 36 92 60 24 87.137558 This -5 1 1 1 1 2 109 92 20 24 87.137558 is -5 1 1 1 1 3 141 98 15 18 87.823906 a -5 1 1 1 1 4 169 92 32 24 87.823906 lot -5 1 1 1 1 5 212 92 28 24 92.965874 of -5 1 1 1 1 6 251 92 31 24 93.247513 12 -5 1 1 1 1 7 296 92 68 30 92.734741 point -5 1 1 1 1 8 374 93 53 23 92.996040 text -5 1 1 1 1 9 437 93 26 23 93.160057 to -5 1 1 1 1 10 474 93 52 23 92.312637 test -5 1 1 1 1 11 536 92 44 24 92.312637 the -4 1 1 1 2 0 36 126 582 31 -1 -5 1 1 1 2 1 36 132 45 18 90.505524 ocr -5 1 1 1 2 2 91 126 69 24 90.505524 code -5 1 1 1 2 3 172 126 51 24 91.169167 and -5 1 1 1 2 4 236 132 50 18 89.765854 see -5 1 1 1 2 5 299 126 15 24 85.827324 if -5 1 1 1 2 6 325 126 14 24 93.116241 it -5 1 1 1 2 7 348 126 85 24 92.394562 works -5 1 1 1 2 8 445 132 33 18 30.119690 on -5 1 1 1 2 9 500 126 29 24 30.119690 all -5 1 1 1 2 10 541 127 77 30 92.090988 types -4 1 1 1 3 0 36 160 187 24 -1 -5 1 1 1 3 1 36 160 28 24 92.476135 of -5 1 1 1 3 2 72 160 41 24 90.919365 file -5 1 1 1 3 3 123 160 100 24 91.360367 format. -3 1 1 2 0 0 36 194 561 167 -1 -4 1 1 2 1 0 36 194 549 31 -1 -5 1 1 2 1 1 36 194 55 24 89.098892 The -5 1 1 2 1 2 102 194 75 30 89.098892 quick -5 1 1 2 1 3 189 194 85 24 91.415680 brown -5 1 1 2 1 4 287 194 52 31 91.943085 dog -5 1 1 2 1 5 348 194 108 31 92.167969 jumped -5 1 1 2 1 6 468 200 63 18 91.970985 over -5 1 1 2 1 7 540 194 45 24 92.843704 the -4 1 1 2 2 0 37 228 548 31 -1 -5 1 1 2 2 1 37 228 55 31 92.262550 lazy -5 1 1 2 2 2 103 228 50 24 92.693161 fox. -5 1 1 2 2 3 165 228 55 24 92.947639 The -5 1 1 2 2 4 232 228 75 30 90.589806 quick -5 1 1 2 2 5 319 228 85 24 91.051247 brown -5 1 1 2 2 6 417 228 51 31 91.925011 dog -5 1 1 2 2 7 478 228 107 31 91.471077 jumped -4 1 1 2 3 0 36 262 561 31 -1 -5 1 1 2 3 1 36 268 63 18 90.210129 over -5 1 1 2 3 2 109 262 44 24 90.210129 the -5 1 1 2 3 3 165 262 56 31 91.178192 lazy -5 1 1 2 3 4 231 262 50 24 92.794647 fox. -5 1 1 2 3 5 294 262 55 24 91.388016 The -5 1 1 2 3 6 360 262 75 30 92.525742 quick -5 1 1 2 3 7 447 262 85 24 90.425552 brown -5 1 1 2 3 8 545 262 52 31 90.425552 dog -4 1 1 2 4 0 43 296 518 31 -1 -5 1 1 2 4 1 43 296 107 31 91.759590 jumped -5 1 1 2 4 2 162 302 64 18 92.923576 over -5 1 1 2 4 3 235 296 44 24 92.017929 the -5 1 1 2 4 4 292 296 55 31 91.558884 lazy -5 1 1 2 4 5 357 296 50 24 92.687485 fox. -5 1 1 2 4 6 420 296 55 24 91.922661 The -5 1 1 2 4 7 486 296 75 30 91.870224 quick -4 1 1 2 5 0 37 330 524 31 -1 -5 1 1 2 5 1 37 330 85 24 92.923935 brown -5 1 1 2 5 2 135 330 52 31 91.468765 dog -5 1 1 2 5 3 196 330 108 31 91.425491 jumped -5 1 1 2 5 4 316 336 63 18 91.489830 over -5 1 1 2 5 5 388 330 45 24 91.740379 the -5 1 1 2 5 6 445 330 55 31 92.110054 lazy -5 1 1 2 5 7 511 330 50 24 93.180054 fox. diff --git a/tests/data/text/test-ocr.txt b/tests/data/text/test-ocr.txt deleted file mode 100644 index 02d3a77cbb5..00000000000 --- a/tests/data/text/test-ocr.txt +++ /dev/null @@ -1,9 +0,0 @@ -This is a lot of 12 point text to test the -ocr code and see if it works on all types -of file format. - -The quick brown dog jumped over the -lazy fox. The quick brown dog jumped -over the lazy fox. The quick brown dog -jumped over the lazy fox. The quick -brown dog jumped over the lazy fox. diff --git a/tests/unit_tests/services_tests/test_ocr_service.py b/tests/unit_tests/services_tests/test_ocr_service.py deleted file mode 100644 index aee3487e92b..00000000000 --- a/tests/unit_tests/services_tests/test_ocr_service.py +++ /dev/null @@ -1,58 +0,0 @@ -from pathlib import Path - -import pytest - -from mealie.services.ocr.pytesseract import OcrService - -ocr_service = OcrService() - - -@pytest.mark.skip("Tesseract is not reliable between environments") -def test_image_to_string(): - with open(Path("tests/data/images/test-ocr.png"), "rb") as image: - result = ocr_service.image_to_string(image) - with open(Path("tests/data/text/test-ocr.txt"), encoding="utf-8") as expected_result: - assert result == expected_result.read() - - -@pytest.mark.skip("Tesseract is not reliable between environments") -def test_image_to_tsv(): - with open(Path("tests/data/images/test-ocr.png"), "rb") as image: - result = ocr_service.image_to_tsv(image.read()) - with open(Path("tests/data/text/test-ocr.tsv"), encoding="utf-8") as expected_result: - assert result == expected_result.read() - - -def test_format_tsv_output(): - tsv = " level\tpage_num\tblock_num\tpar_num\tline_num\tword_num\tleft\ttop\twidth\theight\tconf\ttext \n1\t1\t0\t0\t0\t0\t0\t0\t640\t480\t-1\t\n5\t1\t1\t1\t1\t1\t36\t92\t60\t24\t87.137558\tThis" - expected_result = [ - { - "level": 1, - "page_num": 1, - "block_num": 0, - "par_num": 0, - "line_num": 0, - "word_num": 0, - "left": 0, - "top": 0, - "width": 640, - "height": 480, - "conf": -1.0, - "text": "", - }, - { - "level": 5, - "page_num": 1, - "block_num": 1, - "par_num": 1, - "line_num": 1, - "word_num": 1, - "left": 36, - "top": 92, - "width": 60, - "height": 24, - "conf": 87.137558, - "text": "This", - }, - ] - assert ocr_service.format_tsv_output(tsv) == expected_result diff --git a/tests/utils/api_routes/__init__.py b/tests/utils/api_routes/__init__.py index 1f881f198a8..de1cf2c27e9 100644 --- a/tests/utils/api_routes/__init__.py +++ b/tests/utils/api_routes/__init__.py @@ -113,12 +113,6 @@ """`/api/groups/webhooks/rerun`""" media_docker_validate_txt = "/api/media/docker/validate.txt" """`/api/media/docker/validate.txt`""" -ocr = "/api/ocr/" -"""`/api/ocr/`""" -ocr_asset_to_tsv = "/api/ocr/asset-to-tsv" -"""`/api/ocr/asset-to-tsv`""" -ocr_file_to_tsv = "/api/ocr/file-to-tsv" -"""`/api/ocr/file-to-tsv`""" organizers_categories = "/api/organizers/categories" """`/api/organizers/categories`""" organizers_categories_empty = "/api/organizers/categories/empty" @@ -151,8 +145,6 @@ """`/api/recipes/bulk-actions/tag`""" recipes_create_from_zip = "/api/recipes/create-from-zip" """`/api/recipes/create-from-zip`""" -recipes_create_ocr = "/api/recipes/create-ocr" -"""`/api/recipes/create-ocr`""" recipes_create_url = "/api/recipes/create-url" """`/api/recipes/create-url`""" recipes_create_url_bulk = "/api/recipes/create-url/bulk"