gitextract_0h3h3ffo/ ├── .coveragerc ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.md │ │ └── enhancement-request.md │ └── workflows/ │ ├── docker-publish.yml │ └── pre-commit.yml ├── .gitignore ├── .pre-commit-config.yaml ├── CLAUDE.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── api/ │ ├── __init__.py │ ├── admin.py │ ├── all_tasks.py │ ├── api_util.py │ ├── apps.py │ ├── autoalbum.py │ ├── background_tasks.py │ ├── batch_jobs.py │ ├── burst_detection_rules.py │ ├── cluster_manager.py │ ├── date_time_extractor.py │ ├── directory_watcher/ │ │ ├── __init__.py │ │ ├── file_grouping.py │ │ ├── file_handlers.py │ │ ├── processing_jobs.py │ │ ├── repair_jobs.py │ │ ├── scan_jobs.py │ │ └── utils.py │ ├── drf_optimize.py │ ├── duplicate_detection.py │ ├── face_classify.py │ ├── face_extractor.py │ ├── face_recognition.py │ ├── feature/ │ │ ├── __init__.py │ │ ├── embedded_media.py │ │ └── tests/ │ │ ├── __init__.py │ │ └── test_embedded_media.py │ ├── filters.py │ ├── geocode/ │ │ ├── __init__.py │ │ ├── config.py │ │ ├── geocode.py │ │ └── parsers/ │ │ ├── __init__.py │ │ ├── mapbox.py │ │ ├── nominatim.py │ │ ├── opencage.py │ │ └── tomtom.py │ ├── image_captioning.py │ ├── image_similarity.py │ ├── llm.py │ ├── management/ │ │ ├── __init__.py │ │ └── commands/ │ │ ├── build_similarity_index.py │ │ ├── clear_cache.py │ │ ├── createadmin.py │ │ ├── createuser.py │ │ ├── save_metadata.py │ │ ├── scan.py │ │ ├── start_cleaning_service.py │ │ ├── start_job_cleanup_service.py │ │ └── start_service.py │ ├── metadata/ │ │ ├── __init__.py │ │ ├── face_regions.py │ │ ├── reader.py │ │ ├── tags.py │ │ └── writer.py │ ├── middleware.py │ ├── migrations/ │ │ ├── 0001_initial.py │ │ ├── 0002_add_confidence.py │ │ ├── 0003_remove_unused_thumbs.py │ │ ├── 0004_fix_album_thing_constraint.py │ │ ├── 0005_add_video_to_photo.py │ │ ├── 0006_migrate_to_boolean_field.py │ │ ├── 0007_migrate_to_json_field.py │ │ ├── 0008_remove_image_path.py │ │ ├── 0009_add_aspect_ratio.py │ │ ├── 0009_add_clip_embedding_field.py │ │ ├── 0010_merge_20210725_1547.py │ │ ├── 0011_a_add_rating.py │ │ ├── 0011_b_migrate_favorited_to_rating.py │ │ ├── 0011_c_remove_favorited.py │ │ ├── 0012_add_favorite_min_rating.py │ │ ├── 0013_add_image_scale_and_misc.py │ │ ├── 0014_add_save_metadata_to_disk.py │ │ ├── 0015_add_dominant_color.py │ │ ├── 0016_add_transcode_videos.py │ │ ├── 0017_add_cover_photo.py │ │ ├── 0018_user_config_datetime_rules.py │ │ ├── 0019_change_config_datetime_rules.py │ │ ├── 0020_add_default_timezone.py │ │ ├── 0021_remove_photo_image.py │ │ ├── 0022_photo_video_length.py │ │ ├── 0023_photo_deleted.py │ │ ├── 0024_photo_timestamp.py │ │ ├── 0025_add_cover_photo.py │ │ ├── 0026_add_cluster_info.py │ │ ├── 0027_rename_unknown_person.py │ │ ├── 0028_add_metadata_fields.py │ │ ├── 0029_change_to_text_field.py │ │ ├── 0030_user_confidence_person.py │ │ ├── 0031_remove_account.py │ │ ├── 0032_always_have_owner.py │ │ ├── 0033_add_post_delete_person.py │ │ ├── 0034_allow_deleting_person.py │ │ ├── 0035_add_files_model.py │ │ ├── 0036_handle_missing_files.py │ │ ├── 0037_migrate_to_files.py │ │ ├── 0038_add_main_file.py │ │ ├── 0039_remove_photo_image_paths.py │ │ ├── 0040_add_user_public_sharing_flag.py │ │ ├── 0041_apply_user_enum_for_person.py │ │ ├── 0042_alter_albumuser_cover_photo_alter_photo_main_file.py │ │ ├── 0043_alter_photo_size.py │ │ ├── 0044_alter_cluster_person_alter_person_cluster_owner.py │ │ ├── 0045_alter_face_cluster.py │ │ ├── 0046_add_embedded_media.py │ │ ├── 0047_alter_file_embedded_media.py │ │ ├── 0048_fix_null_height.py │ │ ├── 0049_fix_metadata_files_as_main_files.py │ │ ├── 0050_person_face_count.py │ │ ├── 0051_set_person_defaults.py │ │ ├── 0052_alter_person_name.py │ │ ├── 0053_user_confidence_unknown_face_and_more.py │ │ ├── 0054_user_cluster_selection_epsilon_user_min_samples.py │ │ ├── 0055_alter_longrunningjob_job_type.py │ │ ├── 0056_user_llm_settings_alter_longrunningjob_job_type.py │ │ ├── 0057_remove_face_image_path_and_more.py │ │ ├── 0058_alter_user_avatar_alter_user_nextcloud_app_password_and_more.py │ │ ├── 0059_person_cover_face.py │ │ ├── 0060_apply_default_face_cover.py │ │ ├── 0061_alter_person_name.py │ │ ├── 0062_albumthing_cover_photos.py │ │ ├── 0063_apply_default_album_things_cover.py │ │ ├── 0064_albumthing_photo_count.py │ │ ├── 0065_apply_default_photo_count.py │ │ ├── 0066_photo_last_modified_alter_longrunningjob_job_type.py │ │ ├── 0067_alter_longrunningjob_job_type.py │ │ ├── 0068_remove_longrunningjob_result_and_more.py │ │ ├── 0069_rename_to_in_trashcan.py │ │ ├── 0070_photo_removed.py │ │ ├── 0071_rename_person_label_probability_face_cluster_probability_and_more.py │ │ ├── 0072_alter_face_person.py │ │ ├── 0073_remove_unknown_person.py │ │ ├── 0074_migrate_cluster_person.py │ │ ├── 0075_alter_face_cluster_person.py │ │ ├── 0076_alter_file_path_alter_longrunningjob_job_type_and_more.py │ │ ├── 0077_alter_albumdate_title.py │ │ ├── 0078_create_photo_thumbnail.py │ │ ├── 0079_alter_albumauto_title.py │ │ ├── 0080_create_photo_caption.py │ │ ├── 0081_remove_caption_fields_from_photo.py │ │ ├── 0082_create_photo_search.py │ │ ├── 0083_remove_search_fields.py │ │ ├── 0084_convert_arrayfield_to_json.py │ │ ├── 0085_albumuser_public_expires_at_albumuser_public_slug.py │ │ ├── 0086_remove_albumuser_public_and_more.py │ │ ├── 0087_add_folder_album.py │ │ ├── 0088_remove_folder_album.py │ │ ├── 0089_add_text_alignment.py │ │ ├── 0090_add_header_size.py │ │ ├── 0091_alter_user_scan_directory.py │ │ ├── 0092_add_skip_raw_files_field.py │ │ ├── 0093_migrate_photon_to_nominatim.py │ │ ├── 0094_add_slideshow_interval.py │ │ ├── 0095_photo_perceptual_hash_alter_longrunningjob_job_type_and_more.py │ │ ├── 0096_add_progress_step_and_result_to_longrunningjob.py │ │ ├── 0097_add_duplicate_detection_settings_to_user.py │ │ ├── 0098_add_photo_stack.py │ │ ├── 0099_photo_uuid_primary_key.py │ │ ├── 0100_metadataedit_metadatafile_photometadata_stackreview_and_more.py │ │ ├── 0101_populate_photo_metadata.py │ │ ├── 0102_photo_stacks_manytomany.py │ │ ├── 0103_remove_photo_metadata_fields.py │ │ ├── 0104_remove_photostack_potential_savings_and_more.py │ │ ├── 0105_alter_photo_image_hash.py │ │ ├── 0106_alter_longrunningjob_options.py │ │ ├── 0107_add_burst_detection_rules.py │ │ ├── 0108_add_stack_raw_jpeg_field.py │ │ ├── 0109_migrate_skip_raw_to_stack_raw_jpeg.py │ │ ├── 0110_fix_file_embedded_media_self_reference.py │ │ ├── 0111_alter_file_embedded_media.py │ │ ├── 0112_convert_file_stacks_to_variants.py │ │ ├── 0113_alter_photostack_stack_type.py │ │ ├── 0114_add_file_path_unique.py │ │ ├── 0115_cleanup_duplicate_photos.py │ │ ├── 0116_cleanup_duplicate_groups_removed_photos.py │ │ ├── 0117_delete_removed_photos.py │ │ ├── 0118_alter_longrunningjob_job_type.py │ │ ├── 0119_add_public_sharing_options.py │ │ ├── 0120_rename_thumbnails_uuid_to_hash.py │ │ ├── 0121_add_default_tagging_model.py │ │ ├── 0121_user_save_face_tags_to_disk.py │ │ └── __init__.py │ ├── ml_models.py │ ├── models/ │ │ ├── __init__.py │ │ ├── album_auto.py │ │ ├── album_date.py │ │ ├── album_place.py │ │ ├── album_thing.py │ │ ├── album_user.py │ │ ├── album_user_share.py │ │ ├── cluster.py │ │ ├── duplicate.py │ │ ├── face.py │ │ ├── file.py │ │ ├── long_running_job.py │ │ ├── person.py │ │ ├── photo.py │ │ ├── photo_caption.py │ │ ├── photo_metadata.py │ │ ├── photo_search.py │ │ ├── photo_stack.py │ │ ├── stack_review.py │ │ ├── thumbnail.py │ │ └── user.py │ ├── nextcloud.py │ ├── perceptual_hash.py │ ├── permissions.py │ ├── schemas/ │ │ └── site_settings.py │ ├── semantic_search.py │ ├── serializers/ │ │ ├── PhotosGroupedByDate.py │ │ ├── __init__.py │ │ ├── album_auto.py │ │ ├── album_date.py │ │ ├── album_place.py │ │ ├── album_thing.py │ │ ├── album_user.py │ │ ├── face.py │ │ ├── job.py │ │ ├── person.py │ │ ├── photo_metadata.py │ │ ├── photos.py │ │ ├── simple.py │ │ └── user.py │ ├── services.py │ ├── social_graph.py │ ├── stack_detection.py │ ├── stacks/ │ │ ├── __init__.py │ │ └── live_photo.py │ ├── stats.py │ ├── tests/ │ │ ├── __init__.py │ │ ├── fixtures/ │ │ │ ├── __init__.py │ │ │ ├── api_util/ │ │ │ │ ├── captions_json.py │ │ │ │ ├── expectation.py │ │ │ │ ├── photos.py │ │ │ │ └── sunburst_expectation.py │ │ │ ├── geocode/ │ │ │ │ ├── __init__.py │ │ │ │ ├── expectations/ │ │ │ │ │ ├── mapbox.py │ │ │ │ │ ├── nominatim.py │ │ │ │ │ ├── opencage.py │ │ │ │ │ └── tomtom.py │ │ │ │ └── responses/ │ │ │ │ ├── mapbox.py │ │ │ │ ├── nominatim.py │ │ │ │ ├── opencage.py │ │ │ │ └── tomtom.py │ │ │ ├── location_timeline_test_data.csv │ │ │ └── niaz.xmp │ │ ├── test_api_robustness.py │ │ ├── test_api_util.py │ │ ├── test_auto_select_and_savings.py │ │ ├── test_background_tasks.py │ │ ├── test_bktree_and_duplicate_detection.py │ │ ├── test_bulk_operations.py │ │ ├── test_burst_detection_rules.py │ │ ├── test_burst_filename_patterns.py │ │ ├── test_delete_photos.py │ │ ├── test_detection_edge_cases.py │ │ ├── test_directory_watcher_fix.py │ │ ├── test_dirtree.py │ │ ├── test_duplicate_api_edge_cases.py │ │ ├── test_duplicate_detection.py │ │ ├── test_duplicate_detection_logic.py │ │ ├── test_duplicate_filtering.py │ │ ├── test_edge_cases_integration.py │ │ ├── test_edit_photo_details.py │ │ ├── test_face_extractor.py │ │ ├── test_face_writeback.py │ │ ├── test_favorite_photos.py │ │ ├── test_file_model.py │ │ ├── test_file_path_uniqueness.py │ │ ├── test_geocode.py │ │ ├── test_get_faces.py │ │ ├── test_hide_photos.py │ │ ├── test_im2txt.py │ │ ├── test_live_photo.py │ │ ├── test_location_timeline.py │ │ ├── test_metadata_ordering_sentinel.py │ │ ├── test_migration_0099.py │ │ ├── test_migration_0101.py │ │ ├── test_multi_user_isolation.py │ │ ├── test_only_photos_or_only_videos.py │ │ ├── test_perceptual_hash.py │ │ ├── test_photo_caption_model.py │ │ ├── test_photo_captions.py │ │ ├── test_photo_lifecycle.py │ │ ├── test_photo_list_without_timestamp.py │ │ ├── test_photo_metadata.py │ │ ├── test_photo_metadata_api.py │ │ ├── test_photo_model_integration.py │ │ ├── test_photo_search_model.py │ │ ├── test_photo_search_refactor.py │ │ ├── test_photo_summary.py │ │ ├── test_photo_viewset_permissions.py │ │ ├── test_predefined_rules.py │ │ ├── test_public_photos.py │ │ ├── test_reading_exif.py │ │ ├── test_recently_added_photos.py │ │ ├── test_redetection_idempotency.py │ │ ├── test_regenerate_titles.py │ │ ├── test_retrieve_photo.py │ │ ├── test_scan_percentage_bug.py │ │ ├── test_scan_photos.py │ │ ├── test_scan_photos_directories.py │ │ ├── test_search_term_examples.py │ │ ├── test_search_terms.py │ │ ├── test_services.py │ │ ├── test_setup_directory.py │ │ ├── test_share_photos.py │ │ ├── test_skip_raw_files.py │ │ ├── test_social_graph.py │ │ ├── test_stack_api_edge_cases.py │ │ ├── test_stack_detection.py │ │ ├── test_stack_detection_edge_cases.py │ │ ├── test_stack_detection_logic.py │ │ ├── test_stack_duplicate_integration.py │ │ ├── test_stack_review.py │ │ ├── test_stack_validation_edge_cases.py │ │ ├── test_stats_accuracy.py │ │ ├── test_thumbnail_migration.py │ │ ├── test_thumbnail_naming.py │ │ ├── test_trash_api.py │ │ ├── test_user.py │ │ ├── test_xmp_association.py │ │ ├── test_zip_list_photos_view_v2.py │ │ └── utils.py │ ├── thumbnails.py │ ├── util.py │ └── views/ │ ├── __init__.py │ ├── album_auto.py │ ├── album_folder.py │ ├── albums.py │ ├── custom_api_view.py │ ├── dataviz.py │ ├── duplicates.py │ ├── faces.py │ ├── geocode.py │ ├── jobs.py │ ├── pagination.py │ ├── photo_filters.py │ ├── photo_metadata.py │ ├── photos.py │ ├── public_albums.py │ ├── search.py │ ├── services.py │ ├── sharing.py │ ├── stacks.py │ ├── timezone.py │ ├── upload.py │ ├── user.py │ └── views.py ├── image_similarity/ │ ├── __init__.py │ ├── main.py │ ├── retrieval_index.py │ └── utils.py ├── librephotos/ │ ├── __init__.py │ ├── settings/ │ │ ├── __init__.py │ │ ├── development.py │ │ ├── production.py │ │ ├── test.py │ │ └── test_sqlite.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── nextcloud/ │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── directory_watcher.py │ ├── models.py │ ├── tests.py │ └── views.py ├── pyproject.toml ├── renovate.json ├── requirements.dev.txt ├── requirements.mlval.txt ├── requirements.txt └── service/ ├── __init__.py ├── clip_embeddings/ │ ├── __init__.py │ ├── main.py │ └── semantic_search/ │ ├── __init__.py │ └── semantic_search.py ├── exif/ │ ├── __init__.py │ └── main.py ├── face_recognition/ │ ├── __init__.py │ └── main.py ├── image_captioning/ │ ├── __init__.py │ ├── api/ │ │ └── im2txt/ │ │ ├── README.md │ │ ├── blip/ │ │ │ ├── blip.py │ │ │ ├── med.py │ │ │ └── vit.py │ │ ├── build_vocab.py │ │ ├── data_loader.py │ │ ├── model.py │ │ ├── resize.py │ │ ├── sample.py │ │ └── train.py │ └── main.py ├── llm/ │ ├── __init__.py │ └── main.py ├── tags/ │ ├── __init__.py │ ├── main.py │ ├── places365/ │ │ ├── __init__.py │ │ ├── places365.py │ │ └── wideresnet.py │ └── siglip2/ │ ├── __init__.py │ ├── siglip2.py │ └── tags.txt └── thumbnail/ ├── __init__.py ├── main.py └── test/ ├── .gitignore ├── __init__.py ├── samples/ │ ├── .gitkeep │ └── README.md └── test_thumbnail_worker.py