{"id":26541579,"url":"https://github.com/peter-juhasz/azurearchiver","last_synced_at":"2026-02-14T05:34:35.206Z","repository":{"id":89618047,"uuid":"199150305","full_name":"Peter-Juhasz/AzureArchiver","owner":"Peter-Juhasz","description":"Archive your 📷 photos and 🎬 videos to Azure Storage","archived":false,"fork":false,"pushed_at":"2025-09-27T11:39:31.000Z","size":279,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-09-27T13:24:53.089Z","etag":null,"topics":["archive","azure","azure-storage","csharp","dotnet","photos"],"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/Peter-Juhasz.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2019-07-27T10:28:14.000Z","updated_at":"2025-09-27T11:39:34.000Z","dependencies_parsed_at":"2024-01-20T20:30:25.369Z","dependency_job_id":"df5e9bd3-411f-4892-9fc4-ade246db3e61","html_url":"https://github.com/Peter-Juhasz/AzureArchiver","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/Peter-Juhasz/AzureArchiver","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Peter-Juhasz%2FAzureArchiver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Peter-Juhasz%2FAzureArchiver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Peter-Juhasz%2FAzureArchiver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Peter-Juhasz%2FAzureArchiver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Peter-Juhasz","download_url":"https://codeload.github.com/Peter-Juhasz/AzureArchiver/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Peter-Juhasz%2FAzureArchiver/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29438608,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-14T05:24:35.651Z","status":"ssl_error","status_checked_at":"2026-02-14T05:24:34.830Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["archive","azure","azure-storage","csharp","dotnet","photos"],"created_at":"2025-03-22T01:39:13.664Z","updated_at":"2026-02-14T05:34:35.192Z","avatar_url":"https://github.com/Peter-Juhasz.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿# Archive photos to Azure Storage\n\nArchive your photos and videos to [Azure Archive Storage](https://azure.microsoft.com/en-us/services/storage/archive/) with the lowest cost of €0.00084/GB/mo or €0.8/TB/mo. See detailed [pricing](https://azure.microsoft.com/en-us/pricing/details/storage/blobs/).\n\nThis app uploads and optionally encrypts your files like `IMG_20190727_123456.jpg` or `DSC_5438.NEF`, groups them by date into directories like `2019`/`07`/`27` and sets their tiers to Archive to save cost.\n\n## Usage\n\nRequirements:\n - [Microsoft Azure subscription](https://azure.microsoft.com/)\n   - [Azure Storage Account](https://azure.microsoft.com/en-us/services/storage/) (General Purpose v2 or Blob)\n - [.NET Core 9 Runtime](https://dotnet.microsoft.com/download) installed on your machine\n\nDownload [executable from Releases](https://github.com/Peter-Juhasz/AzureArchiver/releases) or clone the source code and build it yourself. [Read the best practices.](https://github.com/Peter-Juhasz/AzureArchiver/wiki/Best-Practices)\n\n### Upload files to storage\nFor basic usage, you have to specify only the path to the folder to upload and the connection string to your storage account.\n\nRun on Windows:\n```ps\n.\\PhotoArchiver.exe upload \"D:\\OneDrive\\Camera Roll\"\n```\n\nRun on Linux/Unix:\n```sh\ndotnet PhotoArchiver.dll upload \"D:\\OneDrive\\Camera Roll\"\n```\n\nYou can also save your credentials to a configuration file. See below.\n\n### Download blobs\nStart download of blobs that are immediately accessible.\n\n```ps\n.\\PhotoArchiver.exe download \"2019-08-14\" \"D:\\OneDrive\\Camera Roll\"\n```\n\nYou may see that your archived blobs are not accessible right now and they are being rehydrated. In that case, check back after 12 hours and continue:\n\n```ps\n.\\PhotoArchiver.exe rehydrate \"2019-08-14\"\n.\\PhotoArchiver.exe download \"2019-08-14\" \"D:\\OneDrive\\Camera Roll\"\n```\n\n## Configuration\nConfiguration is based on the .NET Standard library and the application reads it from JSON file and/or command-line arguments.\n\n - `Storage` properties of Storage Account\n   - **`ConnectionString`**: the connection string for your Azure Storage\n   - `Container` (default `\"photos\"`): the name of the container to upload files to\n   - `DirectoryFormat` (default `\"{0:yyyy}/{0:MM}/{0:dd}\"`): format string for blob directories that blob are organized into ([see docs](https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings))\n - `Upload` upload settings\n   - **`Path`**: the directory to upload the files from\n   - `AccessTier` (default `\"Cool\"`): possible values: `\"Hot\"`, `\"Cold\"`, `\"Archive\"`\n   - `SearchPattern` (default `\"**/*\"`): glob search pattern for files to upload ([see docs](https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.filesystemglobbing.matcher#remarks))\n   - `Delete` (default `false`): delete files after successful upload\n   - `Verify` (default `true`): verifies uploaded blob by its MD5 hash\n   - `Skip` (default `0`): skip the first given number of files (by name ascending)\n   - `Take` (default `null`): upload only the first given number of files (by name ascending), can be combined with `Skip`\n   - `ConflictResolution` (default `\"Skip\"`) possible values:\n     - `\"Skip\"`: whenever a conflict is found, log as warning and skip\n     - `\"KeepBoth\"`: the hash of the file to be uploaded is appended to its file name, right before its extension, and gets uploaded. The already existing blob is kept and not modified.\n     - `\"Overwrite\"`: the existing blob gets overwritten, if it is in Archive tier, deleted and then reuploaded with the same name\n     - `\"SnapshotAndOverwrite\"`: a snapshot is taken of the existing blob and then it gets overwritten (see `\"Overwrite\"` option). If the blob is in Archive tier, taking a snapshot is not possible, so it is skipped and logged as a warning.\n   - `ParallelBlockCount` (default `1`): the number of blocks of a single blob that may be simultaneously uploaded ([see docs](https://docs.microsoft.com/en-us/dotnet/api/microsoft.azure.storage.blob.blobrequestoptions.paralleloperationthreadcount?view=azure-dotnet))\n - `Thumbnails` thumbnail settings\n   - `MaxWidth`: maximum width of the thumbnail images\n   - `MaxHeight`: maximum height of the thumbnail images\n   - `Quality` (default `0.50`): quality of JPEG compression (0-1: min-max quality)\n   - `Container` (default `\"photos-thumbnails\"`): blob container to put the thumbnails to\n   - `Force` (default `false`): create thumbnails for existing blobs\n - `Download` download settings\n   - **`Path`**: the directory to download the blobs to\n   - **`Date`** (or `StartDate` and `EndDate`): the creation date of the media to download\n   - `StartDate`: the earliest creation date of the media to download\n   - `EndDate`: the latest creation date of the media to download\n   - `Tags`: filter by tags (tagged by Computer Vision)\n   - `People`: filter by IDs of people (tagged by Face API)\n   - `RehydrationTier` (default `\"Hot\"`): rehydrate archived blobs to this tier temporarily for download\n   - `Verify` (default `false`): verify downloaded files by MD5 hash\n   - `Archive` (default `false`): set access tier of blobs to `Archive` after download\n\n### Configuration file\nYou can persist your configuration into a file named `appsettings.json`, for example:\n```json\n{\n\t\"Storage\": {\n\t\t\"ConnectionString\": \"SECRET\"\n\t},\n\t\"Upload\": {\n\t\t\"Delete\": true\n\t}\n}\n```\n\nOr supply as CLI arguments:\n```ps\n.\\PhotoArchiver.exe --Upload:Path \"D:\\OneDrive\\Camera Roll\" --Storage:Archive false --Upload:Delete true\n```\n\n## Advanced features\n\n### Cost estimation\nEstimates transaction and storage costs for your uploaded data.\n\nRequirements:\n - Configuration, get pricing from [Azure Storage Pricing](https://azure.microsoft.com/en-us/pricing/details/storage/blobs/)\n\nConfiguration:\n - `Costs` set the prices based on your region and redundancy for cost estimations (see [pricing](https://azure.microsoft.com/en-us/pricing/details/storage/blobs/))\n   - `Currency` (default `\"$\"`): currency to display costs\n   - `ListOrCreateContainerPricePer10000`\n   - `ReadPricePer10000`\n   - `WritePricePer10000`\n   - `OtherPricePer10000`\n   - `DataStoragePricePerGB`\n   - `GRSDataTransferPricePerGB`: leave it empty if your Storage Account is not geo-replicated\n   - `KeyVaultTransactionPricePer10000`: leave it empty if you don't use Key Vault\n   - `ComputerVisionDescribeTransactionPricePer1000`: leave if empty if you don't use Computer Vision\n   - `OutboundDataTransferPricePerGB`\n\n### Application Insights\nCollect detailed operational logs.\n\nRequirements:\n - [Azure Application Insights](https://azure.microsoft.com/en-us/services/monitor/)\n\nConfiguration:\n - `ApplicationInsights` see [ApplicationInsightsServiceOptions](https://docs.microsoft.com/en-us/azure/azure-monitor/app/asp-net-core#using-applicationinsightsserviceoptions) for reference\n   - **`ConnectionString`**: connection string for the resource\n   - `EnableAdaptiveSampling`: enable/disable Adaptive Sampling\n\n### Updates\nConfigure update options.\n\nConfiguration:\n - `Update`\n   - `Enabled`: check for updates at startup\n   - `Stop`: do not proceed if an update is found\n\n## Information\n\nSupported file types:\n - Photos\n    - Any JPEG with EXIF\n\t- Android\n    - iOS (.JPG, .HEIF, .HEIC)\n\t- Office Lens\n\t- Windows Phone\n - Videos\n\t- Any video with Quick Time metadata (.MOV, .MP4)\n    - Any video with RIFF IDIT metadat (.AVI)\n    - Android (.MP4)\n    - iOS (.MOV)\n    - Windows Phone (.MP4)\n - RAW (with EXIF, matching JPEG or date in file name)\n\t- Canon Raw Version 2 (.CR2)\n\t- Digital Negative (.DNG), iOS/Windows Phone RAW\n\t- Nikon Electric Format (.NEF)\n    - GoPro (.GPR, .WAV)\n\nSupported sources to upload from:\n - Local File System\n - Synced cloud storage\n   - OneDrive\n   - Google Drive\n - USB, CD, DVD drives\n\nMetadata appended to blobs:\n - `OriginalFileName`: the full path of the file on the disk\n - `OriginalFileSize`: the size of the unencrypted file which may be different when encrypted\n - `CreatedAt`: the detected date and time the media was originally created\n - `Caption`: the image description generated by Computer Vision\n - `Tags`: tags generated by Computer Vision\n - `People`: IDs of persons identified by Face API\n\nA single file is uploaded at a time.\n\n## Disclaimer\n\nUse at your own risk. The creator of this software takes no responsibility in moving, storing, deleting or processing your data in any form. It is your responsibility to keep your encryption keys safe. Also, cost estimations are only for information purposes, to get exact and detailed information view Azure Storage pricing page, or check your actual consumption in Azure Portal.\n\n## Development\n\nRequirements:\n - Visual Studio 2022\n - .NET 9 SDK\n\nAlso, set `Update:Enabled` to `false`, if you want to turn off update checks.\n\n## Troubleshooting\n\n - Make sure you have a valid key for your Storage Account. You can try it in another tool like Storage Explorer.\n - Make sure your Storage Account is accessible from your network. You can check this on the Firewall tab of your Storage Account.\n - If you want to archive blobs, make sure your Storage Account is the new kind (GPv2 or Blob), so it supports blob level tiers.\n - Make sure you (and this application) have at least Read permission to the folder you want to upload.\n   - If you want to delete the files as well, make sure you have Delete permission.\n   - Also, that the files are not in use anywhere else.\n - If you want to encrypt using Key Vault, make sure your AD App is defined in the Key Vault access policies.\n - Computer Vision and Face API supports files up to 4 MB in size and only JPEG images.\n \n## Related resources\n - [Create a Storage Account](https://docs.microsoft.com/en-us/azure/storage/common/storage-quickstart-create-account?tabs=azure-portal)\n - [Manage blobs on Azure Portal](https://docs.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-portal)\n - [Manage blobs using Azure Storage Explorer](https://azure.microsoft.com/en-us/features/storage-explorer/)\n - [Use lifecycle management policies to archive blobs](https://docs.microsoft.com/en-us/azure/storage/blobs/archive-blob?tabs=azure-portal#use-lifecycle-management-policies-to-archive-blobs)\n\n## Special thanks\n - [ImageSharp](https://github.com/SixLabors/ImageSharp) library for resizing images\n - [MetadataExtractor](https://github.com/drewnoakes/metadata-extractor-dotnet) library for reading metadata from videos","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeter-juhasz%2Fazurearchiver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpeter-juhasz%2Fazurearchiver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeter-juhasz%2Fazurearchiver/lists"}