22
33import json
44import logging
5- import sys
6- import time
75import uuid
86from datetime import UTC , datetime
97from importlib .metadata import version as get_version
108from pathlib import Path
11- from typing import TypedDict
129
1310import click
1411import typer
1512from bma_client_lib import BmaClient
13+ from bma_client_lib .datastructures import job_types
1614
1715APP_NAME = "bma-cli"
1816app = typer .Typer ()
3129logging .getLogger ("bma_client" ).setLevel (logging .DEBUG )
3230
3331
34- class BaseJob (TypedDict ):
35- """Base class inherited by ImageConversionJob and ImageExifExtractionJob."""
36-
37- job_type : str
38- job_uuid : uuid .UUID
39- basefile_uuid : uuid .UUID
40- user_uuid : uuid .UUID
41- client_uuid : uuid .UUID
42- useragent : str
43- finished : bool
44-
45-
46- class ImageConversionJob (BaseJob ):
47- """Represent an ImageConversionJob."""
48-
49- filetype : str
50- width : int
51- height : int
52- mimetype : str
53- custom_aspect_ratio : bool
54-
55-
56- class ImageExifExtractionJob (BaseJob ):
57- """Represent an ImageExifExtractionJob."""
58-
59-
6032@app .command ()
6133def version () -> None :
6234 """Return the version of bma-cli and bma-client."""
@@ -73,12 +45,12 @@ def fileinfo(file_uuid: uuid.UUID) -> None:
7345
7446
7547@app .command ()
76- def jobs () -> None :
48+ def jobs (filter : str = "?limit=0&finished=false" ) -> None : # noqa: A002
7749 """Get info on unfinished jobs."""
7850 client , config = init ()
79- jobs = client .get_jobs (job_filter = "?limit=0&finished=false" )
51+ jobs = client .get_jobs (job_filter = filter )
8052 click .echo (json .dumps (jobs ))
81- click .echo (f"Total { len (jobs )} unfinished jobs." , err = True )
53+ click .echo (f"Total { len (jobs )} jobs returned by filter { filter } ." , err = True )
8254
8355
8456@app .command ()
@@ -94,26 +66,24 @@ def download(file_uuid: uuid.UUID) -> None:
9466def grind () -> None :
9567 """Get jobs from the server and handle them."""
9668 client , config = init ()
97-
9869 while True :
99- # get any unfinished jobs already assigned to this client
70+ # first get any unfinished jobs already assigned to this client
10071 jobs = client .get_jobs (job_filter = f"?limit=0&finished=false&client_uuid={ client .uuid } " )
10172 if not jobs :
10273 # no unfinished jobs assigned to this client, ask for new assignment
10374 jobs = client .get_job_assignment ()
10475
10576 if not jobs :
10677 click .echo ("Nothing left to do." )
107- return
78+ break
10879
10980 # loop over jobs and handle each
11081 click .echo (f"Processing { len (jobs )} jobs for file { jobs [0 ]['basefile_uuid' ]} ..." )
111- for job in jobs :
112- # make sure we have the original file locally
113- fileinfo = client .download (file_uuid = job ["basefile_uuid" ])
114- path = Path (config ["path" ], fileinfo ["filename" ])
115- handle_job (f = path , job = job , client = client , config = config )
116- click .echo ("Done!" )
82+ for dictjob in jobs :
83+ job = job_types [dictjob ["job_type" ]](** dictjob )
84+ click .echo (f"Handling { job .job_type } { job .job_uuid } ..." )
85+ client .handle_job (job = job )
86+ click .echo ("Done grinding for now!" )
11787
11888
11989@app .command ()
@@ -128,27 +98,12 @@ def upload(files: list[str]) -> None:
12898 metadata = result ["bma_response" ]
12999 click .echo (f"File { metadata ['uuid' ]} uploaded OK!" )
130100 file_uuids .append (metadata ["uuid" ])
131- # check for jobs
132- if metadata ["jobs_unfinished" ] == 0 :
133- continue
134-
135- # it seems there is work to do for the newly uploaded file!
136- jobs = client .get_job_assignment (file_uuid = metadata ["uuid" ])
137- if not jobs :
138- click .echo ("No unassigned unfinished jobs found for this file." )
139- continue
140-
141- # the grind
142- click .echo (f"Handling { len (jobs )} jobs for file { pf } ..." )
143- for j in jobs :
144- # load job in a typeddict, but why?
145- klass = getattr (sys .modules [__name__ ], j ["job_type" ])
146- job = klass (** j )
147- handle_job (f = pf , job = job , client = client , config = config )
148101 click .echo (f"Finished uploading { len (file_uuids )} files, creating album..." )
149102 now = datetime .isoformat (datetime .now (tz = UTC ))
150103 album = client .create_album (file_uuids = file_uuids , title = f"Created-{ now } " , description = f"Created-{ now } " )
151104 url = f"{ client .base_url } /albums/{ album ['uuid' ]} /"
105+ if config .get ("handle_jobs" ):
106+ grind ()
152107 click .echo (f"Created album { album ['uuid' ]} with the uploaded file(s) see it at { url } " )
153108 click .echo ("Done!" )
154109
@@ -167,15 +122,6 @@ def settings() -> None:
167122 click .echo (json .dumps (client .get_server_settings ()))
168123
169124
170- def handle_job (f : Path , job : ImageConversionJob | ImageExifExtractionJob , client : BmaClient , config : dict ) -> None :
171- """Handle a job and upload the result."""
172- click .echo ("======================================================" )
173- click .echo (f"Handling job { job ['job_type' ]} { job ['job_uuid' ]} ..." )
174- start = time .time ()
175- result = client .handle_job (job = job , orig = f )
176- logger .debug (f"Getting result took { time .time () - start } seconds: { result } " )
177-
178-
179125def load_config () -> dict [str , str ]:
180126 """Load config file."""
181127 # bail out on missing config
0 commit comments