Files
photoassistant/TODO

210 lines
8.1 KiB
Plaintext

### GENERAL
* allow changing dates in move dbox and then re-scan for existing folders OR just have a browse for existing...
- for use on scanned photos, they register as 2010, but are datestamped in visuals for 95
(is there a library for this???)
* sqlalchemy 2 migration:
* fix unmapped (in fact make all the code properly sqlachemy 2.0 compliant)
-- path.py has the __allow_unmapped__ = True
* remove all '.execute' from *.py
* allow actions for wrong person:
-> someone else? OR override no match for this person ever for this image?
* read this: https://flask.palletsprojects.com/en/2.2.x/testing/#faking-resources-and-context
* could get better AI optim, by keeping track of just new files since scan (even if we did this from the DB),
then we could just feed those eid's explicitly into a 'run_ai_on_new_files' :) -- maybe particularly
if count('new files') < say 1000 do eids, otherwise do path AND no new refimgs
* ignore face should ignore ALL matching faces (re: Declan)
* should allow context menu from View thumbs (particularly useful on search) to show other files around this one by date (maybe that folder or something?)
* folder manipulation
- does search of matching dirname give all entries of subdirs of subdirs, etc. (think not)
- delete
- rename (does this work already somehow? see issue below)
- dont allow me to stupidly move a folder to itself
* browser back/forward buttons dont work -- use POST -> redirect to GET
- need some sort of clean-up of pa_user_state -- I spose its triggered by browser session, so maybe just after a week is lazy/good enough
-- pa_user_state has last_used as a timestamp so can be used to delete old entries
* back button will fail if we do these POSTs:
job.py:@app.route("/jobs", methods=["GET", "POST"])
job.py:@app.route("/job/<id>", methods=["GET","POST"])
-- these need to store 'job prefs' somewhere... (extras?)
* if on jobs page and jobs increase, then 'rebuild' the content of the page to show new jobs, and potentially do that every 5 seconds...
- THINK: could also 'refresh' /job/id via Ajax not a reload, to avoid the POST issue above needing to remember job prefs somewhere?
files.py:@app.route("/fix_dups", methods=["POST"])
???
* allow user to choose default log level to show
* GUI overhaul?
* on a phone, the files.html page header is a mess "Oldest.." line is too large to fit on 1 line (make it a hamburger?)
- searched for text overlaps buttons above and below
- < 10 files > is subsequently not centered
- the folder/bin icons might be best below search then? (and on same line as XS/S, etc.)
* on phone login page, job* pages, etc. are all squished
* when search, have a way to hide deleted files
-> not sure where to put this on GUI, its so busy...
* comment your code -> only html files remaining
* dup issues:
* when we have lots of dups, sort the directories by alpha so its consistent when choosing
* fix up logging in general
ProcessFileForJob --> really need to better handle log levels and counting
* video player cannot handle non mp4 formats... do I care? (could just offer a download link and hope the client deals with it)
--> OR? https://jsmpeg.com/
--> OR? convert all videos to mp4/webm
* support animated gifs in html5 canvas
* read that guys face matching / clustering / nearest neighbour examples, for a whole new AI capability
https://www.pyimagesearch.com/2018/07/09/face-clustering-with-python/
### DB
* Dir can have date in the DB, so we can do Oldest/Newest dirs in Folder view
### BACKEND
* revisit SymlinkName() and make it simpler (see comment in shared.py)
*** Need to use thread-safe sessions per Thread, half-assed version did not work
Admin
-> do I want to have admin roles/users?
-> purge deleted files (and associated DB data) needs a dbox or privs
(only show in DEV for now)
### AI
* faces per file - need a threshold for too many?
### UI
* viewer needs to allow toggle to scan_model (and prob. right-click on file... AI (with CNN) AI (with hog)
- make the form-select AI_Model actually do the change (but need more mem on mara really -- even mem is not enough
need graphic support --> need to allow pa_job_manager run on borric with acceleration)
For AI / rescan:
way to override per file:
the threshold used?
file details is sort of crap - only works on import path
- probably better to have a different 'view', e.g. folders/flat/detailed
timelineview? (I think maybe sunburst for large amounts of files, then maybe something more timeline-series for drilling in?)
(vertical timeline, date has thumbnails (small) horizontally along
a page, etc.?
https://www.highcharts.com/docs/chart-and-series-types/timeline-series
https://www.highcharts.com/demo/sunburst
https://www.highcharts.com/demo/heatmap
https://www.highcharts.com/demo/packed-bubble-split
### SORTER
* exif processing?
* location stuff - test a new photo from my camera out
-- image is in dir, need to look at exifread output
### FUTURE:
* real first-run, 'no or empty settings' -- need to think this through
- should set base_path to /pa (and then either /pa or /pa/import, /pa/storage, etc. can be 1 or more volume(s) in docker)
* deal with changing a path in settings
* can emby use nfo for images (for AI/tags?)
-NO sadly
* work out why gitignore does not ignore say .pa_bin but has to ignore .pa_metada
#### CHAT GPT f/b
docstrings for documentation / example:
def AddRefimgToPerson(person, refimg):
"""
Adds a reference image to a person object's list of reference images.
Args:
person (Person): A Person object to which the reference image should be added.
refimg (str): The filepath to the reference image to be added.
Returns:
None
Raises:
ValueError: If person or refimg are None or empty strings.
TypeError: If person is not an instance of the Person class.
Example:
person = Person(name="John Doe")
AddRefimgToPerson(person, "/path/to/reference/image.jpg")
"""
if not person:
raise ValueError("person is None or empty")
if not refimg:
raise ValueError("refimg is None or empty")
if not isinstance(person, Person):
raise TypeError("person must be an instance of the Person class")
person.add_reference_image(refimg)
TESTING:
def test_AddRefimgToPerson():
# Create a test person object
person = Person(name='John Doe', age=30)
# Create a test image object
image = Image(file_path='test.jpg', caption='Test image')
# Call the function to add the image to the person
AddRefimgToPerson(person, image)
# Check that the image was added to the person's list of images
assert image in person.images, "Image was not added to person's list of images"
# Check that the image's reference to the person is set correctly
assert image.person == person, "Image's reference to person is not set correctly"
TYPING:
look at from typing, e.g. ...
from typing import Type
def get_person_info(person: Type[Person]) -> str:
OR:
from typing import List
def AddRefimgToPerson(person_id: int, ref_images: List[str]) -> bool:
"""
Adds reference images to a person's profile.
Args:
person_id (int): The ID of the person whose profile should be updated.
ref_images (List[str]): A list of file paths or URLs for the reference images to add.
Returns:
bool: True if the images were successfully added, False otherwise.
Raises:
ValueError: If person_id is not a positive integer or if ref_images is empty or contains
any non-string values.
Example:
>>> AddRefimgToPerson(123, ['http://example.com/img1.jpg', '/path/to/img2.png'])
True
"""