Compare commits
66 Commits
v0.3-dev
...
v1.4.0-dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9cbd5d1b0c | ||
|
|
80fd664cc8 | ||
|
|
041c711cb9 | ||
|
|
dd9c5244fd | ||
|
|
fe693db84f | ||
|
|
5c9d3cd08b | ||
|
|
725ab5622f | ||
|
|
e9acd21733 | ||
|
|
ce1ab1ed50 | ||
|
|
3e918ffd18 | ||
|
|
678ce23c16 | ||
|
|
31c18ff34c | ||
|
|
e407a4fa13 | ||
|
|
be72df70fe | ||
|
|
dbd79f4797 | ||
|
|
f790315d3f | ||
|
|
f1ab700334 | ||
|
|
afc29a67d2 | ||
|
|
ba816babee | ||
|
|
6e0ac79eae | ||
|
|
94514cfeea | ||
|
|
8c7080eaef | ||
|
|
348d395b21 | ||
|
|
2e7e97ea13 | ||
|
|
d71e7ebff1 | ||
|
|
9755936950 | ||
|
|
347052f82f | ||
|
|
e196ff1e2f | ||
|
|
46e344bb92 | ||
|
|
7f038cae90 | ||
|
|
489a34b10c | ||
|
|
46b2b6b558 | ||
|
|
bb7566426c | ||
|
|
7df552e767 | ||
|
|
274fba1bd2 | ||
|
|
db366aac08 | ||
|
|
1359418745 | ||
|
|
8da3f231e0 | ||
|
|
b3cfe6d9e9 | ||
|
|
424845d924 | ||
|
|
4630ca5321 | ||
|
|
e13d4a6b9c | ||
|
|
c624580596 | ||
|
|
e085a10cf3 | ||
|
|
21d1920d68 | ||
|
|
94cc1d7dbd | ||
|
|
026f3c24e9 | ||
|
|
251c92ff1e | ||
|
|
135e1a7a7b | ||
|
|
9008093cce | ||
|
|
5990a28870 | ||
|
|
bd34be92e6 | ||
|
|
e608c61ba5 | ||
|
|
d2edc0bffe | ||
|
|
bfde308492 | ||
|
|
f181dba964 | ||
|
|
c894e36855 | ||
|
|
01e906e99c | ||
|
|
352800223e | ||
|
|
619735fea0 | ||
|
|
75b1ed08b4 | ||
|
|
c234c95880 | ||
|
|
7cc7fc0a0c | ||
|
|
897d49f734 | ||
|
|
051c958c8b | ||
|
|
56627caf5b |
3
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# These are supported funding model platforms
|
||||||
|
|
||||||
|
github: alextran1502
|
||||||
35
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: "[BUG]"
|
||||||
|
labels: bug
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
**Desktop (please complete the following information):**
|
||||||
|
- OS: [e.g. iOS]
|
||||||
|
|
||||||
|
**Smartphone (please complete the following information):**
|
||||||
|
- Device: [e.g. iPhone6]
|
||||||
|
- OS: [e.g. iOS8.1]
|
||||||
|
- Version [e.g. 22]
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
||||||
32
.github/workflows/build_apk.yml
vendored
@@ -1,32 +0,0 @@
|
|||||||
name: Build APK Android
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
push:
|
|
||||||
branches: [main]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
working-directory: ./mobile
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
|
|
||||||
# Build
|
|
||||||
- uses: subosito/flutter-action@v2
|
|
||||||
with:
|
|
||||||
channel: "stable"
|
|
||||||
cache: true
|
|
||||||
cache-key: flutter2.10 # optional, change this to force refresh cache
|
|
||||||
- run: flutter --version
|
|
||||||
- run: flutter pub get
|
|
||||||
- run: flutter build apk
|
|
||||||
- run: flutter build appbundle
|
|
||||||
|
|
||||||
# Upload Artifact
|
|
||||||
- uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: release-apk
|
|
||||||
path: mobile/build/app/outputs/apk/release/app-release.apk
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
name: Build+push Immich
|
name: Build Server
|
||||||
|
|
||||||
on:
|
on:
|
||||||
# Triggers the workflow on push or pull request events but only for the main branch
|
# Triggers the workflow on push or pull request events but only for the main branch
|
||||||
@@ -16,7 +16,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2.4.0
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
ref: "main" # branch
|
ref: "main" # branch
|
||||||
# https://github.com/docker/setup-qemu-action#usage
|
# https://github.com/docker/setup-qemu-action#usage
|
||||||
@@ -34,7 +34,7 @@ jobs:
|
|||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
# https://github.com/docker/build-push-action#multi-platform-image
|
# https://github.com/docker/build-push-action#multi-platform-image
|
||||||
- name: Build and push Immich
|
- name: Build and push Immich
|
||||||
uses: docker/build-push-action@v2.9.0
|
uses: docker/build-push-action@v2.10.0
|
||||||
with:
|
with:
|
||||||
context: ./server
|
context: ./server
|
||||||
file: ./server/Dockerfile
|
file: ./server/Dockerfile
|
||||||
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
.DS_Store
|
||||||
|
.vscode
|
||||||
|
.idea
|
||||||
2
LICENSE
@@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2022 Alex
|
Copyright (c) 2022 Hau Tran
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
7
Makefile
@@ -1,5 +1,8 @@
|
|||||||
dev:
|
dev:
|
||||||
docker-compose -f ./server/docker-compose.yml up
|
docker-compose -f ./docker/docker-compose.dev.yml up --remove-orphans
|
||||||
|
|
||||||
dev-update:
|
dev-update:
|
||||||
docker-compose -f ./server/docker-compose.yml up --build -V
|
docker-compose -f ./docker/docker-compose.dev.yml up --build -V --remove-orphans
|
||||||
|
|
||||||
|
dev-scale:
|
||||||
|
docker-compose -f ./docker/docker-compose.dev.yml up --build -V --scale immich_server=3 --remove-orphans
|
||||||
|
|||||||
13
PR_CHECKLIST.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# Deployment checklist for iOS/Android/Server
|
||||||
|
|
||||||
|
[] Up version in [mobile/pubspec.yml](/mobile/pubspec.yaml)
|
||||||
|
|
||||||
|
[] Up version in [docker/docker-compose.yml](/docker/docker-compose.yml) for `immich_server` service
|
||||||
|
|
||||||
|
[] Up version in [docker/docker-compose.gpu.yml](/docker/docker-compose.gpu.yml) for `immich_server` service
|
||||||
|
|
||||||
|
[] Up version in [server/src/constants/server_version.constant.ts](/server/src/constants/server_version.constant.ts)
|
||||||
|
|
||||||
|
[] Up version in iOS Fastlane [/mobile/ios/fastlane/Fastfile](/mobile/ios/fastlane/Fastfile)
|
||||||
|
|
||||||
|
All of the version should be the same.
|
||||||
93
README.md
@@ -1,8 +1,27 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="design/immich-logo.svg" width="150" title="hover text">
|
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-green.svg?color=3F51B5&style=for-the-badge&label=License&logoColor=000000&labelColor=ececec" alt="License: MIT"></a>
|
||||||
|
<a href="https://github.com/alextran1502/immich"><img src="https://img.shields.io/github/stars/alextran1502/immich.svg?style=for-the-badge&logo=github&color=3F51B5&label=Stars&logoColor=000000&labelColor=ececec" alt="Star on Github"></a>
|
||||||
|
<a href="https://immichci.little-home.net/viewType.html?buildTypeId=Immich_BuildAndroidAndGetArtifact&guest=1">
|
||||||
|
<img src="https://img.shields.io/teamcity/http/immichci.little-home.net/s/Immich_BuildAndroidAndGetArtifact.svg?style=for-the-badge&label=Android&logo=teamcity&logoColor=000000&labelColor=ececec" alt="Android Build"/>
|
||||||
|
</a>
|
||||||
|
<a href="https://immichci.little-home.net/viewType.html?buildTypeId=Immich_BuildAndPublishIOSToTestFlight&guest=1">
|
||||||
|
<img src="https://img.shields.io/teamcity/http/immichci.little-home.net/s/Immich_BuildAndPublishIOSToTestFlight.svg?style=for-the-badge&label=iOS&logo=teamcity&logoColor=000000&labelColor=ececec" alt="iOS Build"/>
|
||||||
|
</a>
|
||||||
|
<a href="https://actions-badge.atrox.dev/alextran1502/immich/goto?ref=main">
|
||||||
|
<img alt="Build Status" src="https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Falextran1502%2Fimmich%2Fbadge%3Fref%3Dmain&style=for-the-badge&label=Server Docker&logo=docker&labelColor=ececec" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img src="design/immich-logo.svg" width="200" title="Immich Logo">
|
||||||
|
</p>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
# IMMICH
|
# Immich
|
||||||
|
|
||||||
Self-hosted photo and video backup solution directly from your mobile phone.
|
Self-hosted photo and video backup solution directly from your mobile phone.
|
||||||
|
|
||||||
@@ -13,11 +32,11 @@ Loading ~4000 images/videos
|
|||||||
## Screenshots
|
## Screenshots
|
||||||
|
|
||||||
<p align="left">
|
<p align="left">
|
||||||
<img src="design/sc1.PNG" width="150" title="Login With Custom URL">
|
<img src="design/nsc1.png" width="150" title="Login With Custom URL">
|
||||||
<img src="design/sc2.PNG" width="150" title="Backup Setting Info">
|
<img src="design/nsc2.png" width="150" title="Backup Setting Info">
|
||||||
<img src="design/sc4.PNG" width="150" title="Home Page">
|
<img src="design/nsc3.png" width="150" title="Multiple seelct">
|
||||||
<img src="design/sc3.PNG" width="150" title="Multiple seelct">
|
<img src="design/nsc6.png" width="150" title="EXIF Info">
|
||||||
<img src="design/sc5.PNG" width="150" title="Multipe select group">
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
# Note
|
# Note
|
||||||
@@ -28,17 +47,21 @@ This project is under heavy development, there will be continous functions, feat
|
|||||||
|
|
||||||
# Features
|
# Features
|
||||||
|
|
||||||
[x] Upload assets(videos/images)
|
- Upload and view assets(videos/images).
|
||||||
|
- Multi-user supported.
|
||||||
[x] View assets
|
- Quick navigation with drag scroll bar.
|
||||||
|
- Auto Backup.
|
||||||
[x] Quick navigation with drag scroll bar
|
- Support HEIC/HEIF Backup.
|
||||||
|
- Extract and display EXIF info.
|
||||||
[x] Auto Backup
|
- Real-time render from multi-device upload event.
|
||||||
|
- Image Tagging/Classification based on ImageNet dataset
|
||||||
[x] Support HEIC/HEIF Backup
|
- Object detection based on COCO SSD.
|
||||||
|
- Search assets based on tags and exif data (lens, make, model, orientation)
|
||||||
[x] Extract and display EXIF info
|
- Upload assets from your local computer/server using [immich cli tools](https://www.npmjs.com/package/immich)
|
||||||
|
- [Optional] Reserve geocoding using Mapbox (Generous free-tier of 100,000 search/month)
|
||||||
|
- Show asset's location information on map (OpenStreetMap).
|
||||||
|
- Show curated places on the search page
|
||||||
|
- Show curated objects on the search page
|
||||||
|
|
||||||
# Development
|
# Development
|
||||||
|
|
||||||
@@ -48,10 +71,11 @@ You can use docker compose for development, there are several services that comp
|
|||||||
2. PostgreSQL
|
2. PostgreSQL
|
||||||
3. Redis
|
3. Redis
|
||||||
4. Nginx
|
4. Nginx
|
||||||
|
5. TensorFlow
|
||||||
|
|
||||||
## Populate .env file
|
## Populate .env file
|
||||||
|
|
||||||
Navigate to `server` directory and run
|
Navigate to `docker` directory and run
|
||||||
|
|
||||||
```
|
```
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
@@ -59,16 +83,14 @@ cp .env.example .env
|
|||||||
|
|
||||||
Then populate the value in there.
|
Then populate the value in there.
|
||||||
|
|
||||||
|
Notice that if set `ENABLE_MAPBOX` to `true`, you will have to provide `MAPBOX_KEY` for the server to run.
|
||||||
|
|
||||||
|
Pay attention to the key `UPLOAD_LOCATION`, this directory must exist and is owned by the user that run the `docker-compose` command below.
|
||||||
|
|
||||||
To start, run
|
To start, run
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker-compose -f ./server/docker-compose.yml up
|
docker-compose -f ./docker/docker-compose.yml up --build -V
|
||||||
```
|
|
||||||
|
|
||||||
To force rebuild node modules after installing new packages
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker-compose -f ./server/docker-compose.yml up --build -V
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The server will be running at `http://your-ip:2283` through `Nginx`
|
The server will be running at `http://your-ip:2283` through `Nginx`
|
||||||
@@ -96,14 +118,19 @@ Download `apk` in release tab and run on your phone. You can follow this guide o
|
|||||||
|
|
||||||
### iOS
|
### iOS
|
||||||
|
|
||||||
- Get a MacOS
|
You can download the app from Apple AppStore [here](https://apps.apple.com/us/app/immich/id1613945652):
|
||||||
- Download and setup Flutter development environment
|
|
||||||
- Navigate to `mobile` folder
|
|
||||||
- Run with release build command for best performance.
|
|
||||||
|
|
||||||
```bash
|
<p align="left">
|
||||||
flutter run --release
|
<img src="design/ios-qr-code.png" width="250" title="Apple App Store">
|
||||||
```
|
<p/>
|
||||||
|
|
||||||
|
# Support
|
||||||
|
|
||||||
|
If you like the app, find it helpful, and want to support me to offset the cost of publishing to AppStores, you can sponsor the project with [**Github Sponsore**](https://github.com/sponsors/alextran1502).
|
||||||
|
|
||||||
|
This is also a meaningful way to give me motivation and encounragment to continue working on the app.
|
||||||
|
|
||||||
|
Cheer! 🎉
|
||||||
|
|
||||||
# Known Issue
|
# Known Issue
|
||||||
|
|
||||||
|
|||||||
BIN
.DS_Store → design/.DS_Store
vendored
|
Before Width: | Height: | Size: 115 KiB After Width: | Height: | Size: 115 KiB |
BIN
design/ios-qr-code.png
Normal file
|
After Width: | Height: | Size: 56 KiB |
BIN
design/nsc1.png
Normal file
|
After Width: | Height: | Size: 176 KiB |
BIN
design/nsc2.png
Normal file
|
After Width: | Height: | Size: 303 KiB |
BIN
design/nsc3.png
Normal file
|
After Width: | Height: | Size: 2.7 MiB |
BIN
design/nsc6.png
Normal file
|
After Width: | Height: | Size: 540 KiB |
BIN
design/sc1.PNG
|
Before Width: | Height: | Size: 260 KiB |
BIN
design/sc3.PNG
|
Before Width: | Height: | Size: 765 KiB |
BIN
design/sc4.PNG
|
Before Width: | Height: | Size: 734 KiB |
BIN
design/sc5.PNG
|
Before Width: | Height: | Size: 583 KiB |
18
docker/.env.example
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# STAGE
|
||||||
|
NODE_ENV=development
|
||||||
|
|
||||||
|
# Database
|
||||||
|
DB_USERNAME=postgres
|
||||||
|
DB_PASSWORD=postgres
|
||||||
|
DB_DATABASE_NAME=
|
||||||
|
|
||||||
|
# Upload File Config
|
||||||
|
UPLOAD_LOCATION=absolute_location_on_your_machine_where_you_want_to_store_the_backup
|
||||||
|
|
||||||
|
# JWT SECRET
|
||||||
|
JWT_SECRET=
|
||||||
|
|
||||||
|
# MAPBOX
|
||||||
|
## ENABLE_MAPBOX is either true of false -> if true, you have to provide MAPBOX_KEY
|
||||||
|
ENABLE_MAPBOX=
|
||||||
|
MAPBOX_KEY=
|
||||||
1
docker/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.env
|
||||||
@@ -1,22 +1,18 @@
|
|||||||
version: '3.8'
|
version: "3.8"
|
||||||
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
server:
|
immich_server:
|
||||||
container_name: immich_server
|
image: immich-server-dev:1.3.2
|
||||||
image: immich-server-dev:1.0.0
|
|
||||||
build:
|
build:
|
||||||
context: .
|
context: ../server
|
||||||
target: development
|
target: development
|
||||||
dockerfile: ./Dockerfile
|
dockerfile: ../server/Dockerfile
|
||||||
command: npm run start:dev
|
command: npm run start:dev
|
||||||
ports:
|
expose:
|
||||||
- "3000:3000"
|
- "3000"
|
||||||
# expose:
|
|
||||||
# - 3000
|
|
||||||
volumes:
|
volumes:
|
||||||
- .:/usr/src/app
|
- ../server:/usr/src/app
|
||||||
- userdata:/usr/src/app/upload
|
- ${UPLOAD_LOCATION}:/usr/src/app/upload
|
||||||
- /usr/src/app/node_modules
|
- /usr/src/app/node_modules
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
@@ -26,11 +22,32 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- immich_network
|
- immich_network
|
||||||
|
|
||||||
|
immich_microservices:
|
||||||
|
image: immich-microservices-dev:1.3.2
|
||||||
|
build:
|
||||||
|
context: ../microservices
|
||||||
|
target: development
|
||||||
|
dockerfile: ../microservices/Dockerfile
|
||||||
|
command: npm run start:dev
|
||||||
|
expose:
|
||||||
|
- "3001"
|
||||||
|
volumes:
|
||||||
|
- ../microservices:/usr/src/app
|
||||||
|
- ${UPLOAD_LOCATION}:/usr/src/app/upload
|
||||||
|
- /usr/src/app/node_modules
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
depends_on:
|
||||||
|
- database
|
||||||
|
networks:
|
||||||
|
- immich_network
|
||||||
|
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
container_name: immich_redis
|
container_name: immich_redis
|
||||||
image: redis:6.2
|
image: redis:6.2
|
||||||
networks:
|
networks:
|
||||||
- immich_network
|
- immich_network
|
||||||
|
|
||||||
database:
|
database:
|
||||||
container_name: immich_postgres
|
container_name: immich_postgres
|
||||||
@@ -47,7 +64,7 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- 5432:5432
|
- 5432:5432
|
||||||
networks:
|
networks:
|
||||||
- immich_network
|
- immich_network
|
||||||
|
|
||||||
nginx:
|
nginx:
|
||||||
container_name: proxy_nginx
|
container_name: proxy_nginx
|
||||||
@@ -62,10 +79,9 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- immich_network
|
- immich_network
|
||||||
depends_on:
|
depends_on:
|
||||||
- server
|
- immich_server
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
immich_network:
|
immich_network:
|
||||||
volumes:
|
volumes:
|
||||||
pgdata:
|
pgdata:
|
||||||
userdata:
|
|
||||||
94
docker/docker-compose.gpu.yml
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
version: "3.8"
|
||||||
|
|
||||||
|
services:
|
||||||
|
immich_server:
|
||||||
|
image: immich-server-dev:1.4.0
|
||||||
|
build:
|
||||||
|
context: ../server
|
||||||
|
target: development
|
||||||
|
dockerfile: ../server/Dockerfile
|
||||||
|
command: npm run start:dev
|
||||||
|
expose:
|
||||||
|
- "3000"
|
||||||
|
volumes:
|
||||||
|
- ../server:/usr/src/app
|
||||||
|
- ${UPLOAD_LOCATION}:/usr/src/app/upload
|
||||||
|
- /usr/src/app/node_modules
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
depends_on:
|
||||||
|
- redis
|
||||||
|
- database
|
||||||
|
networks:
|
||||||
|
- immich_network
|
||||||
|
|
||||||
|
immich_microservices:
|
||||||
|
image: immich-microservices-dev:1.4.0
|
||||||
|
build:
|
||||||
|
context: ../microservices
|
||||||
|
target: development
|
||||||
|
dockerfile: ../microservices/Dockerfile
|
||||||
|
command: npm run start:dev
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
reservations:
|
||||||
|
devices:
|
||||||
|
- driver: nvidia
|
||||||
|
count: 1
|
||||||
|
capabilities: [ gpu ]
|
||||||
|
expose:
|
||||||
|
- "3001"
|
||||||
|
volumes:
|
||||||
|
- ../microservices:/usr/src/app
|
||||||
|
- ${UPLOAD_LOCATION}:/usr/src/app/upload
|
||||||
|
- /usr/src/app/node_modules
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
depends_on:
|
||||||
|
- database
|
||||||
|
- immich_server
|
||||||
|
networks:
|
||||||
|
- immich_network
|
||||||
|
|
||||||
|
redis:
|
||||||
|
container_name: immich_redis
|
||||||
|
image: redis:6.2
|
||||||
|
networks:
|
||||||
|
- immich_network
|
||||||
|
|
||||||
|
database:
|
||||||
|
container_name: immich_postgres
|
||||||
|
image: postgres:14
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
environment:
|
||||||
|
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
||||||
|
POSTGRES_USER: ${DB_USERNAME}
|
||||||
|
POSTGRES_DB: ${DB_DATABASE_NAME}
|
||||||
|
PG_DATA: /var/lib/postgresql/data
|
||||||
|
volumes:
|
||||||
|
- pgdata:/var/lib/postgresql/data
|
||||||
|
ports:
|
||||||
|
- 5432:5432
|
||||||
|
networks:
|
||||||
|
- immich_network
|
||||||
|
|
||||||
|
nginx:
|
||||||
|
container_name: proxy_nginx
|
||||||
|
image: nginx:latest
|
||||||
|
volumes:
|
||||||
|
- ./settings/nginx-conf:/etc/nginx/conf.d
|
||||||
|
ports:
|
||||||
|
- 2283:80
|
||||||
|
- 2284:443
|
||||||
|
logging:
|
||||||
|
driver: none
|
||||||
|
networks:
|
||||||
|
- immich_network
|
||||||
|
depends_on:
|
||||||
|
- immich_server
|
||||||
|
|
||||||
|
networks:
|
||||||
|
immich_network:
|
||||||
|
volumes:
|
||||||
|
pgdata:
|
||||||
108
docker/docker-compose.yml
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
version: "3.8"
|
||||||
|
|
||||||
|
services:
|
||||||
|
immich_server:
|
||||||
|
image: immich-server:1.4.0
|
||||||
|
build:
|
||||||
|
context: ../server
|
||||||
|
target: production
|
||||||
|
dockerfile: ../server/Dockerfile
|
||||||
|
command: npm run start:prod
|
||||||
|
expose:
|
||||||
|
- "3000"
|
||||||
|
volumes:
|
||||||
|
- ../server:/usr/src/app
|
||||||
|
- ${UPLOAD_LOCATION}:/usr/src/app/upload
|
||||||
|
- /usr/src/app/node_modules
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
depends_on:
|
||||||
|
- redis
|
||||||
|
- database
|
||||||
|
networks:
|
||||||
|
- immich_network
|
||||||
|
|
||||||
|
immich_microservices:
|
||||||
|
image: immich-microservices:1.4.0
|
||||||
|
build:
|
||||||
|
context: ../microservices
|
||||||
|
target: production
|
||||||
|
dockerfile: ../microservices/Dockerfile
|
||||||
|
command: npm run start:prod
|
||||||
|
expose:
|
||||||
|
- "3001"
|
||||||
|
volumes:
|
||||||
|
- ../microservices:/usr/src/app
|
||||||
|
- ${UPLOAD_LOCATION}:/usr/src/app/upload
|
||||||
|
- /usr/src/app/node_modules
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
depends_on:
|
||||||
|
- database
|
||||||
|
networks:
|
||||||
|
- immich_network
|
||||||
|
|
||||||
|
|
||||||
|
redis:
|
||||||
|
container_name: immich_redis
|
||||||
|
image: redis:6.2
|
||||||
|
networks:
|
||||||
|
- immich_network
|
||||||
|
|
||||||
|
database:
|
||||||
|
container_name: immich_postgres
|
||||||
|
image: postgres:14
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
environment:
|
||||||
|
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
||||||
|
POSTGRES_USER: ${DB_USERNAME}
|
||||||
|
POSTGRES_DB: ${DB_DATABASE_NAME}
|
||||||
|
PG_DATA: /var/lib/postgresql/data
|
||||||
|
volumes:
|
||||||
|
- pgdata:/var/lib/postgresql/data
|
||||||
|
ports:
|
||||||
|
- 5432:5432
|
||||||
|
networks:
|
||||||
|
- immich_network
|
||||||
|
|
||||||
|
nginx:
|
||||||
|
container_name: proxy_nginx
|
||||||
|
image: nginx:latest
|
||||||
|
volumes:
|
||||||
|
- ./settings/nginx-conf:/etc/nginx/conf.d
|
||||||
|
ports:
|
||||||
|
- 2283:80
|
||||||
|
- 2284:443
|
||||||
|
logging:
|
||||||
|
driver: none
|
||||||
|
networks:
|
||||||
|
- immich_network
|
||||||
|
depends_on:
|
||||||
|
- immich_server
|
||||||
|
|
||||||
|
# immich_tf_fastapi:
|
||||||
|
# container_name: immich_tf_fastapi
|
||||||
|
# image: tensor_flow_fastapi:1.0.0
|
||||||
|
# restart: always
|
||||||
|
# command: uvicorn app.main:app --proxy-headers --host 0.0.0.0 --port 8000 --reload
|
||||||
|
# build:
|
||||||
|
# context: ../machine_learning
|
||||||
|
# target: cpu
|
||||||
|
# dockerfile: ../machine_learning/Dockerfile
|
||||||
|
# volumes:
|
||||||
|
# - ../machine_learning/app:/code/app
|
||||||
|
# - ${UPLOAD_LOCATION}:/code/app/upload
|
||||||
|
# ports:
|
||||||
|
# - 2285:8000
|
||||||
|
# expose:
|
||||||
|
# - "8000"
|
||||||
|
# depends_on:
|
||||||
|
# - database
|
||||||
|
# networks:
|
||||||
|
# - immich_network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
immich_network:
|
||||||
|
volumes:
|
||||||
|
pgdata:
|
||||||
35
docker/settings/nginx-conf/nginx.conf
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
map $http_upgrade $connection_upgrade {
|
||||||
|
default upgrade;
|
||||||
|
'' close;
|
||||||
|
}
|
||||||
|
|
||||||
|
# events {
|
||||||
|
# worker_connections 1000;
|
||||||
|
# }
|
||||||
|
|
||||||
|
server {
|
||||||
|
|
||||||
|
client_max_body_size 50000M;
|
||||||
|
|
||||||
|
listen 80;
|
||||||
|
access_log off;
|
||||||
|
location / {
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_buffer_size 16k;
|
||||||
|
proxy_busy_buffers_size 24k;
|
||||||
|
proxy_buffers 64 4k;
|
||||||
|
proxy_force_ranges on;
|
||||||
|
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
|
||||||
|
proxy_pass http://immich_server:3000;
|
||||||
|
}
|
||||||
|
}
|
||||||
1
machine_learning/.dockerignore
Normal file
@@ -0,0 +1 @@
|
|||||||
|
devenv/
|
||||||
3
machine_learning/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
__pycache__/
|
||||||
|
devenv/
|
||||||
|
app/upload
|
||||||
25
machine_learning/Dockerfile
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
## GPU Build
|
||||||
|
# FROM tensorflow/tensorflow:latest-gpu as gpu
|
||||||
|
|
||||||
|
# WORKDIR /code
|
||||||
|
|
||||||
|
# COPY ./requirements.txt /code/requirements.txt
|
||||||
|
|
||||||
|
# RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
|
||||||
|
|
||||||
|
# COPY ./app /code/app
|
||||||
|
|
||||||
|
|
||||||
|
## CPU BUILD
|
||||||
|
FROM python:3.8 as cpu
|
||||||
|
|
||||||
|
RUN apt-get update
|
||||||
|
RUN apt-get install ffmpeg libsm6 libxext6 -y
|
||||||
|
|
||||||
|
WORKDIR /code
|
||||||
|
|
||||||
|
COPY ./requirements.txt /code/requirements.txt
|
||||||
|
|
||||||
|
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
|
||||||
|
|
||||||
|
COPY ./app /code/app
|
||||||
0
machine_learning/app/__init__.py
Normal file
BIN
machine_learning/app/cars.jpg
Normal file
|
After Width: | Height: | Size: 193 KiB |
0
machine_learning/app/image_classifier/__init__.py
Normal file
37
machine_learning/app/image_classifier/image_classifier.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
from tensorflow.keras.applications import InceptionV3
|
||||||
|
from tensorflow.keras.applications.inception_v3 import preprocess_input, decode_predictions
|
||||||
|
from tensorflow.keras.preprocessing import image
|
||||||
|
import numpy as np
|
||||||
|
from PIL import Image
|
||||||
|
import cv2
|
||||||
|
IMG_SIZE = 299
|
||||||
|
PREDICTION_MODEL = InceptionV3(weights='imagenet')
|
||||||
|
|
||||||
|
|
||||||
|
def classify_image(image_path: str):
|
||||||
|
img_path = f'./app/{image_path}'
|
||||||
|
# img = image.load_img(img_path, target_size=(IMG_SIZE, IMG_SIZE))
|
||||||
|
|
||||||
|
target_image = cv2.imread(img_path, cv2.IMREAD_UNCHANGED)
|
||||||
|
resized_target_image = cv2.resize(target_image, (IMG_SIZE, IMG_SIZE))
|
||||||
|
|
||||||
|
x = image.img_to_array(resized_target_image)
|
||||||
|
x = np.expand_dims(x, axis=0)
|
||||||
|
x = preprocess_input(x)
|
||||||
|
|
||||||
|
preds = PREDICTION_MODEL.predict(x)
|
||||||
|
result = decode_predictions(preds, top=3)[0]
|
||||||
|
payload = []
|
||||||
|
for _, value, _ in result:
|
||||||
|
payload.append(value)
|
||||||
|
|
||||||
|
return payload
|
||||||
|
|
||||||
|
|
||||||
|
def warm_up():
|
||||||
|
img_path = f'./app/test.png'
|
||||||
|
img = image.load_img(img_path, target_size=(IMG_SIZE, IMG_SIZE))
|
||||||
|
x = image.img_to_array(img)
|
||||||
|
x = np.expand_dims(x, axis=0)
|
||||||
|
x = preprocess_input(x)
|
||||||
|
PREDICTION_MODEL.predict(x)
|
||||||
1002
machine_learning/app/imagenet_class_index.json
Normal file
46
machine_learning/app/main.py
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
from pydantic import BaseModel
|
||||||
|
from fastapi import FastAPI
|
||||||
|
|
||||||
|
from .object_detection import object_detection
|
||||||
|
from .image_classifier import image_classifier
|
||||||
|
|
||||||
|
from tf2_yolov4.anchors import YOLOV4_ANCHORS
|
||||||
|
from tf2_yolov4.model import YOLOv4
|
||||||
|
|
||||||
|
|
||||||
|
HEIGHT, WIDTH = (640, 960)
|
||||||
|
|
||||||
|
# Warm up model
|
||||||
|
image_classifier.warm_up()
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
|
||||||
|
class TagImagePayload(BaseModel):
|
||||||
|
thumbnail_path: str
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/tagImage")
|
||||||
|
async def post_root(payload: TagImagePayload):
|
||||||
|
image_path = payload.thumbnail_path
|
||||||
|
|
||||||
|
if image_path[0] == '.':
|
||||||
|
image_path = image_path[2:]
|
||||||
|
|
||||||
|
return image_classifier.classify_image(image_path=image_path)
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/")
|
||||||
|
async def test():
|
||||||
|
|
||||||
|
object_detection.run_detection()
|
||||||
|
# image = tf.io.read_file("./app/cars.jpg")
|
||||||
|
# image = tf.image.decode_image(image)
|
||||||
|
# image = tf.image.resize(image, (HEIGHT, WIDTH))
|
||||||
|
# images = tf.expand_dims(image, axis=0) / 255.0
|
||||||
|
|
||||||
|
# model = YOLOv4(
|
||||||
|
# (HEIGHT, WIDTH, 3),
|
||||||
|
# 80,
|
||||||
|
# YOLOV4_ANCHORS,
|
||||||
|
# "darknet",
|
||||||
|
# )
|
||||||
0
machine_learning/app/object_detection/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
|
||||||
|
def run_detection():
|
||||||
|
print("run detection")
|
||||||
|
Before Width: | Height: | Size: 345 KiB After Width: | Height: | Size: 345 KiB |
8
machine_learning/requirements.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
opencv-python==4.5.5.64
|
||||||
|
fastapi>=0.68.0,<0.69.0
|
||||||
|
pydantic>=1.8.0,<2.0.0
|
||||||
|
uvicorn>=0.15.0,<0.16.0
|
||||||
|
tensorflow==2.8.0
|
||||||
|
numpy==1.22.2
|
||||||
|
pillow==9.0.1
|
||||||
|
tf2_yolov4==0.1.0
|
||||||
4
microservices/.dockerignore
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
node_modules/
|
||||||
|
upload/
|
||||||
|
dist/
|
||||||
|
|
||||||
24
microservices/.eslintrc.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
module.exports = {
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
parserOptions: {
|
||||||
|
project: 'tsconfig.json',
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
plugins: ['@typescript-eslint/eslint-plugin'],
|
||||||
|
extends: [
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
'plugin:prettier/recommended',
|
||||||
|
],
|
||||||
|
root: true,
|
||||||
|
env: {
|
||||||
|
node: true,
|
||||||
|
jest: true,
|
||||||
|
},
|
||||||
|
ignorePatterns: ['.eslintrc.js'],
|
||||||
|
rules: {
|
||||||
|
'@typescript-eslint/interface-name-prefix': 'off',
|
||||||
|
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||||
|
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||||
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
|
},
|
||||||
|
};
|
||||||
35
microservices/.gitignore
vendored
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# compiled output
|
||||||
|
/dist
|
||||||
|
/node_modules
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Tests
|
||||||
|
/coverage
|
||||||
|
/.nyc_output
|
||||||
|
|
||||||
|
# IDEs and editors
|
||||||
|
/.idea
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
.c9/
|
||||||
|
*.launch
|
||||||
|
.settings/
|
||||||
|
*.sublime-workspace
|
||||||
|
|
||||||
|
# IDE - VSCode
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
4
microservices/.prettierrc
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "all"
|
||||||
|
}
|
||||||
43
microservices/Dockerfile
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
##################################
|
||||||
|
# DEVELOPMENT
|
||||||
|
##################################
|
||||||
|
FROM node:16-bullseye-slim AS development
|
||||||
|
|
||||||
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
WORKDIR /usr/src/app
|
||||||
|
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
|
||||||
|
RUN apt-get update
|
||||||
|
RUN apt-get install gcc g++ make cmake python3 python3-pip ffmpeg -y
|
||||||
|
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
#################################
|
||||||
|
# PRODUCTION
|
||||||
|
#################################
|
||||||
|
FROM node:16-bullseye-slim AS production
|
||||||
|
|
||||||
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
|
ARG NODE_ENV=production
|
||||||
|
ENV NODE_ENV=${NODE_ENV}
|
||||||
|
|
||||||
|
WORKDIR /usr/src/app
|
||||||
|
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
|
||||||
|
RUN apt-get update
|
||||||
|
RUN apt-get install gcc g++ make cmake python3 python3-pip ffmpeg -y
|
||||||
|
|
||||||
|
RUN npm install --only=production
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
COPY --from=development /usr/src/app/dist ./dist
|
||||||
|
|
||||||
|
CMD ["node", "dist/main"]
|
||||||
4
microservices/README.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
# Microservices for Immich
|
||||||
|
|
||||||
|
## Image Classifier
|
||||||
4
microservices/nest-cli.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"collection": "@nestjs/schematics",
|
||||||
|
"sourceRoot": "src"
|
||||||
|
}
|
||||||
17323
microservices/package-lock.json
generated
Normal file
83
microservices/package.json
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
{
|
||||||
|
"name": "nest_microservices",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "",
|
||||||
|
"author": "",
|
||||||
|
"private": true,
|
||||||
|
"license": "UNLICENSED",
|
||||||
|
"scripts": {
|
||||||
|
"prebuild": "rimraf dist",
|
||||||
|
"build": "nest build",
|
||||||
|
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
||||||
|
"start": "nest start",
|
||||||
|
"start:dev": "nest start --watch",
|
||||||
|
"start:debug": "nest start --debug --watch",
|
||||||
|
"start:prod": "node dist/main",
|
||||||
|
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
|
||||||
|
"test": "jest",
|
||||||
|
"test:watch": "jest --watch",
|
||||||
|
"test:cov": "jest --coverage",
|
||||||
|
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
|
||||||
|
"test:e2e": "jest --config ./test/jest-e2e.json"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@nestjs/common": "^8.0.0",
|
||||||
|
"@nestjs/core": "^8.0.0",
|
||||||
|
"@nestjs/mapped-types": "^1.0.1",
|
||||||
|
"@nestjs/platform-express": "^8.0.0",
|
||||||
|
"@nestjs/typeorm": "^8.0.3",
|
||||||
|
"@tensorflow-models/coco-ssd": "^2.2.2",
|
||||||
|
"@tensorflow-models/mobilenet": "^2.1.0",
|
||||||
|
"@tensorflow/tfjs": "^3.15.0",
|
||||||
|
"@tensorflow/tfjs-converter": "^3.15.0",
|
||||||
|
"@tensorflow/tfjs-core": "^3.15.0",
|
||||||
|
"@tensorflow/tfjs-node": "^3.15.0",
|
||||||
|
"@tensorflow/tfjs-node-gpu": "^3.15.0",
|
||||||
|
"@trpc/server": "^9.20.3",
|
||||||
|
"pg": "^8.7.3",
|
||||||
|
"reflect-metadata": "^0.1.13",
|
||||||
|
"rimraf": "^3.0.2",
|
||||||
|
"rxjs": "^7.2.0",
|
||||||
|
"typeorm": "^0.2.45"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@nestjs/cli": "^8.2.4",
|
||||||
|
"@nestjs/schematics": "^8.0.0",
|
||||||
|
"@nestjs/testing": "^8.0.0",
|
||||||
|
"@types/express": "^4.17.13",
|
||||||
|
"@types/jest": "27.4.1",
|
||||||
|
"@types/node": "^16.0.0",
|
||||||
|
"@types/supertest": "^2.0.11",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^5.0.0",
|
||||||
|
"@typescript-eslint/parser": "^5.0.0",
|
||||||
|
"eslint": "^8.0.1",
|
||||||
|
"eslint-config-prettier": "^8.3.0",
|
||||||
|
"eslint-plugin-prettier": "^4.0.0",
|
||||||
|
"jest": "^27.2.5",
|
||||||
|
"prettier": "^2.3.2",
|
||||||
|
"source-map-support": "^0.5.20",
|
||||||
|
"supertest": "^6.1.3",
|
||||||
|
"ts-jest": "^27.0.3",
|
||||||
|
"ts-loader": "^9.2.3",
|
||||||
|
"ts-node": "^10.0.0",
|
||||||
|
"tsconfig-paths": "^3.10.1",
|
||||||
|
"typescript": "^4.3.5"
|
||||||
|
},
|
||||||
|
"jest": {
|
||||||
|
"moduleFileExtensions": [
|
||||||
|
"js",
|
||||||
|
"json",
|
||||||
|
"ts"
|
||||||
|
],
|
||||||
|
"rootDir": "src",
|
||||||
|
"testRegex": ".*\\.spec\\.ts$",
|
||||||
|
"transform": {
|
||||||
|
"^.+\\.(t|j)s$": "ts-jest"
|
||||||
|
},
|
||||||
|
"collectCoverageFrom": [
|
||||||
|
"**/*.(t|j)s"
|
||||||
|
],
|
||||||
|
"coverageDirectory": "../coverage",
|
||||||
|
"testEnvironment": "node"
|
||||||
|
}
|
||||||
|
}
|
||||||
16
microservices/src/app.module.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { ImageClassifierModule } from './image-classifier/image-classifier.module';
|
||||||
|
import { databaseConfig } from './config/database.config';
|
||||||
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
|
import { ObjectDetectionModule } from './object-detection/object-detection.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [
|
||||||
|
TypeOrmModule.forRoot(databaseConfig),
|
||||||
|
ImageClassifierModule,
|
||||||
|
ObjectDetectionModule,
|
||||||
|
],
|
||||||
|
controllers: [],
|
||||||
|
providers: [],
|
||||||
|
})
|
||||||
|
export class AppModule {}
|
||||||
11
microservices/src/config/database.config.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
|
||||||
|
|
||||||
|
export const databaseConfig: TypeOrmModuleOptions = {
|
||||||
|
type: 'postgres',
|
||||||
|
host: 'immich_postgres',
|
||||||
|
port: 5432,
|
||||||
|
username: process.env.DB_USERNAME,
|
||||||
|
password: process.env.DB_PASSWORD,
|
||||||
|
database: process.env.DB_DATABASE_NAME,
|
||||||
|
synchronize: false,
|
||||||
|
};
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import { Body, Controller, Post } from '@nestjs/common';
|
||||||
|
import { ImageClassifierService } from './image-classifier.service';
|
||||||
|
|
||||||
|
@Controller('image-classifier')
|
||||||
|
export class ImageClassifierController {
|
||||||
|
constructor(
|
||||||
|
private readonly imageClassifierService: ImageClassifierService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
@Post('/tagImage')
|
||||||
|
async tagImage(@Body('thumbnailPath') thumbnailPath: string) {
|
||||||
|
return await this.imageClassifierService.tagImage(thumbnailPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { ImageClassifierService } from './image-classifier.service';
|
||||||
|
import { ImageClassifierController } from './image-classifier.controller';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
controllers: [ImageClassifierController],
|
||||||
|
providers: [ImageClassifierService],
|
||||||
|
})
|
||||||
|
export class ImageClassifierModule {}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
|
import * as mobilenet from '@tensorflow-models/mobilenet';
|
||||||
|
import * as cocoSsd from '@tensorflow-models/coco-ssd';
|
||||||
|
import * as tf from '@tensorflow/tfjs-node';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ImageClassifierService {
|
||||||
|
private readonly MOBILENET_VERSION = 2;
|
||||||
|
private readonly MOBILENET_ALPHA = 1.0;
|
||||||
|
|
||||||
|
private mobileNetModel: mobilenet.MobileNet;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
Logger.log(
|
||||||
|
`Running Node TensorFlow Version : ${tf.version['tfjs']}`,
|
||||||
|
'ImageClassifier',
|
||||||
|
);
|
||||||
|
mobilenet
|
||||||
|
.load({
|
||||||
|
version: this.MOBILENET_VERSION,
|
||||||
|
alpha: this.MOBILENET_ALPHA,
|
||||||
|
})
|
||||||
|
.then((mobilenetModel) => (this.mobileNetModel = mobilenetModel));
|
||||||
|
}
|
||||||
|
|
||||||
|
async tagImage(thumbnailPath: string) {
|
||||||
|
try {
|
||||||
|
const isExist = fs.existsSync(thumbnailPath);
|
||||||
|
if (isExist) {
|
||||||
|
const tags = [];
|
||||||
|
const image = fs.readFileSync(thumbnailPath);
|
||||||
|
const decodedImage = tf.node.decodeImage(image, 3) as tf.Tensor3D;
|
||||||
|
const predictions = await this.mobileNetModel.classify(decodedImage);
|
||||||
|
|
||||||
|
for (const prediction of predictions) {
|
||||||
|
if (prediction.probability >= 0.1) {
|
||||||
|
tags.push(...prediction.className.split(',').map((e) => e.trim()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tags;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log('Error reading file ', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
microservices/src/main.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { NestFactory } from '@nestjs/core';
|
||||||
|
import { AppModule } from './app.module';
|
||||||
|
|
||||||
|
async function bootstrap() {
|
||||||
|
const app = await NestFactory.create(AppModule);
|
||||||
|
|
||||||
|
await app.listen(3001);
|
||||||
|
}
|
||||||
|
|
||||||
|
bootstrap();
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import { Body, Controller, Post } from '@nestjs/common';
|
||||||
|
import { ObjectDetectionService } from './object-detection.service';
|
||||||
|
|
||||||
|
@Controller('object-detection')
|
||||||
|
export class ObjectDetectionController {
|
||||||
|
constructor(
|
||||||
|
private readonly objectDetectionService: ObjectDetectionService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
@Post('/detectObject')
|
||||||
|
async detectObject(@Body('thumbnailPath') thumbnailPath: string) {
|
||||||
|
return await this.objectDetectionService.detectObject(thumbnailPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { ObjectDetectionService } from './object-detection.service';
|
||||||
|
import { ObjectDetectionController } from './object-detection.controller';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
controllers: [ObjectDetectionController],
|
||||||
|
providers: [ObjectDetectionService],
|
||||||
|
})
|
||||||
|
export class ObjectDetectionModule {}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
|
import * as cocoSsd from '@tensorflow-models/coco-ssd';
|
||||||
|
import * as tf from '@tensorflow/tfjs-node';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ObjectDetectionService {
|
||||||
|
private cocoSsdModel: cocoSsd.ObjectDetection;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
Logger.log(
|
||||||
|
`Running Node TensorFlow Version : ${tf.version['tfjs']}`,
|
||||||
|
'ObjectDetection',
|
||||||
|
);
|
||||||
|
cocoSsd.load().then((model) => (this.cocoSsdModel = model));
|
||||||
|
}
|
||||||
|
async detectObject(thumbnailPath: string) {
|
||||||
|
try {
|
||||||
|
const isExist = fs.existsSync(thumbnailPath);
|
||||||
|
if (isExist) {
|
||||||
|
const tags = new Set();
|
||||||
|
const image = fs.readFileSync(thumbnailPath);
|
||||||
|
const decodedImage = tf.node.decodeImage(image, 3) as tf.Tensor3D;
|
||||||
|
const predictions = await this.cocoSsdModel.detect(decodedImage);
|
||||||
|
|
||||||
|
for (const result of predictions) {
|
||||||
|
if (result.score > 0.5) {
|
||||||
|
tags.add(result.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [...tags];
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log('Error reading file ', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
25
microservices/test/app.e2e-spec.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { INestApplication } from '@nestjs/common';
|
||||||
|
import * as request from 'supertest';
|
||||||
|
import { AppModule } from '../src/app.module';
|
||||||
|
|
||||||
|
// End to End test
|
||||||
|
describe('AppController (e2e)', () => {
|
||||||
|
let app: INestApplication;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const moduleFixture: TestingModule = await Test.createTestingModule({
|
||||||
|
imports: [AppModule],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
app = moduleFixture.createNestApplication();
|
||||||
|
await app.init();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('/ (GET)', () => {
|
||||||
|
return request(app.getHttpServer())
|
||||||
|
.get('/')
|
||||||
|
.expect(200)
|
||||||
|
.expect('Hello World!');
|
||||||
|
});
|
||||||
|
});
|
||||||
9
microservices/test/jest-e2e.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"moduleFileExtensions": ["js", "json", "ts"],
|
||||||
|
"rootDir": ".",
|
||||||
|
"testEnvironment": "node",
|
||||||
|
"testRegex": ".e2e-spec.ts$",
|
||||||
|
"transform": {
|
||||||
|
"^.+\\.(t|j)s$": "ts-jest"
|
||||||
|
}
|
||||||
|
}
|
||||||
4
microservices/tsconfig.build.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
|
||||||
|
}
|
||||||
21
microservices/tsconfig.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "commonjs",
|
||||||
|
"declaration": true,
|
||||||
|
"removeComments": true,
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"target": "es2017",
|
||||||
|
"sourceMap": true,
|
||||||
|
"outDir": "./dist",
|
||||||
|
"baseUrl": "./",
|
||||||
|
"incremental": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strictNullChecks": false,
|
||||||
|
"noImplicitAny": false,
|
||||||
|
"strictBindCallApply": false,
|
||||||
|
"forceConsistentCasingInFileNames": false,
|
||||||
|
"noFallthroughCasesInSwitch": false
|
||||||
|
}
|
||||||
|
}
|
||||||
5
mobile/.gitignore
vendored
@@ -8,6 +8,8 @@
|
|||||||
.buildlog/
|
.buildlog/
|
||||||
.history
|
.history
|
||||||
.svn/
|
.svn/
|
||||||
|
*.ipa
|
||||||
|
*.zip
|
||||||
|
|
||||||
# IntelliJ related
|
# IntelliJ related
|
||||||
*.iml
|
*.iml
|
||||||
@@ -44,3 +46,6 @@ app.*.map.json
|
|||||||
/android/app/debug
|
/android/app/debug
|
||||||
/android/app/profile
|
/android/app/profile
|
||||||
/android/app/release
|
/android/app/release
|
||||||
|
|
||||||
|
# Fastlane
|
||||||
|
ios/fastlane/report.xml
|
||||||
3
mobile/android/Gemfile
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
source "https://rubygems.org"
|
||||||
|
|
||||||
|
gem "fastlane"
|
||||||
218
mobile/android/Gemfile.lock
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
GEM
|
||||||
|
remote: https://rubygems.org/
|
||||||
|
specs:
|
||||||
|
CFPropertyList (3.0.5)
|
||||||
|
rexml
|
||||||
|
addressable (2.8.0)
|
||||||
|
public_suffix (>= 2.0.2, < 5.0)
|
||||||
|
artifactory (3.0.15)
|
||||||
|
atomos (0.1.3)
|
||||||
|
aws-eventstream (1.2.0)
|
||||||
|
aws-partitions (1.566.0)
|
||||||
|
aws-sdk-core (3.130.0)
|
||||||
|
aws-eventstream (~> 1, >= 1.0.2)
|
||||||
|
aws-partitions (~> 1, >= 1.525.0)
|
||||||
|
aws-sigv4 (~> 1.1)
|
||||||
|
jmespath (~> 1.0)
|
||||||
|
aws-sdk-kms (1.55.0)
|
||||||
|
aws-sdk-core (~> 3, >= 3.127.0)
|
||||||
|
aws-sigv4 (~> 1.1)
|
||||||
|
aws-sdk-s3 (1.113.0)
|
||||||
|
aws-sdk-core (~> 3, >= 3.127.0)
|
||||||
|
aws-sdk-kms (~> 1)
|
||||||
|
aws-sigv4 (~> 1.4)
|
||||||
|
aws-sigv4 (1.4.0)
|
||||||
|
aws-eventstream (~> 1, >= 1.0.2)
|
||||||
|
babosa (1.0.4)
|
||||||
|
claide (1.1.0)
|
||||||
|
colored (1.2)
|
||||||
|
colored2 (3.1.2)
|
||||||
|
commander (4.6.0)
|
||||||
|
highline (~> 2.0.0)
|
||||||
|
declarative (0.0.20)
|
||||||
|
digest-crc (0.6.4)
|
||||||
|
rake (>= 12.0.0, < 14.0.0)
|
||||||
|
domain_name (0.5.20190701)
|
||||||
|
unf (>= 0.0.5, < 1.0.0)
|
||||||
|
dotenv (2.7.6)
|
||||||
|
emoji_regex (3.2.3)
|
||||||
|
excon (0.92.0)
|
||||||
|
faraday (1.10.0)
|
||||||
|
faraday-em_http (~> 1.0)
|
||||||
|
faraday-em_synchrony (~> 1.0)
|
||||||
|
faraday-excon (~> 1.1)
|
||||||
|
faraday-httpclient (~> 1.0)
|
||||||
|
faraday-multipart (~> 1.0)
|
||||||
|
faraday-net_http (~> 1.0)
|
||||||
|
faraday-net_http_persistent (~> 1.0)
|
||||||
|
faraday-patron (~> 1.0)
|
||||||
|
faraday-rack (~> 1.0)
|
||||||
|
faraday-retry (~> 1.0)
|
||||||
|
ruby2_keywords (>= 0.0.4)
|
||||||
|
faraday-cookie_jar (0.0.7)
|
||||||
|
faraday (>= 0.8.0)
|
||||||
|
http-cookie (~> 1.0.0)
|
||||||
|
faraday-em_http (1.0.0)
|
||||||
|
faraday-em_synchrony (1.0.0)
|
||||||
|
faraday-excon (1.1.0)
|
||||||
|
faraday-httpclient (1.0.1)
|
||||||
|
faraday-multipart (1.0.3)
|
||||||
|
multipart-post (>= 1.2, < 3)
|
||||||
|
faraday-net_http (1.0.1)
|
||||||
|
faraday-net_http_persistent (1.2.0)
|
||||||
|
faraday-patron (1.0.0)
|
||||||
|
faraday-rack (1.0.0)
|
||||||
|
faraday-retry (1.0.3)
|
||||||
|
faraday_middleware (1.2.0)
|
||||||
|
faraday (~> 1.0)
|
||||||
|
fastimage (2.2.6)
|
||||||
|
fastlane (2.204.3)
|
||||||
|
CFPropertyList (>= 2.3, < 4.0.0)
|
||||||
|
addressable (>= 2.8, < 3.0.0)
|
||||||
|
artifactory (~> 3.0)
|
||||||
|
aws-sdk-s3 (~> 1.0)
|
||||||
|
babosa (>= 1.0.3, < 2.0.0)
|
||||||
|
bundler (>= 1.12.0, < 3.0.0)
|
||||||
|
colored
|
||||||
|
commander (~> 4.6)
|
||||||
|
dotenv (>= 2.1.1, < 3.0.0)
|
||||||
|
emoji_regex (>= 0.1, < 4.0)
|
||||||
|
excon (>= 0.71.0, < 1.0.0)
|
||||||
|
faraday (~> 1.0)
|
||||||
|
faraday-cookie_jar (~> 0.0.6)
|
||||||
|
faraday_middleware (~> 1.0)
|
||||||
|
fastimage (>= 2.1.0, < 3.0.0)
|
||||||
|
gh_inspector (>= 1.1.2, < 2.0.0)
|
||||||
|
google-apis-androidpublisher_v3 (~> 0.3)
|
||||||
|
google-apis-playcustomapp_v1 (~> 0.1)
|
||||||
|
google-cloud-storage (~> 1.31)
|
||||||
|
highline (~> 2.0)
|
||||||
|
json (< 3.0.0)
|
||||||
|
jwt (>= 2.1.0, < 3)
|
||||||
|
mini_magick (>= 4.9.4, < 5.0.0)
|
||||||
|
multipart-post (~> 2.0.0)
|
||||||
|
naturally (~> 2.2)
|
||||||
|
optparse (~> 0.1.1)
|
||||||
|
plist (>= 3.1.0, < 4.0.0)
|
||||||
|
rubyzip (>= 2.0.0, < 3.0.0)
|
||||||
|
security (= 0.1.3)
|
||||||
|
simctl (~> 1.6.3)
|
||||||
|
terminal-notifier (>= 2.0.0, < 3.0.0)
|
||||||
|
terminal-table (>= 1.4.5, < 2.0.0)
|
||||||
|
tty-screen (>= 0.6.3, < 1.0.0)
|
||||||
|
tty-spinner (>= 0.8.0, < 1.0.0)
|
||||||
|
word_wrap (~> 1.0.0)
|
||||||
|
xcodeproj (>= 1.13.0, < 2.0.0)
|
||||||
|
xcpretty (~> 0.3.0)
|
||||||
|
xcpretty-travis-formatter (>= 0.0.3)
|
||||||
|
gh_inspector (1.1.3)
|
||||||
|
google-apis-androidpublisher_v3 (0.16.0)
|
||||||
|
google-apis-core (>= 0.4, < 2.a)
|
||||||
|
google-apis-core (0.4.2)
|
||||||
|
addressable (~> 2.5, >= 2.5.1)
|
||||||
|
googleauth (>= 0.16.2, < 2.a)
|
||||||
|
httpclient (>= 2.8.1, < 3.a)
|
||||||
|
mini_mime (~> 1.0)
|
||||||
|
representable (~> 3.0)
|
||||||
|
retriable (>= 2.0, < 4.a)
|
||||||
|
rexml
|
||||||
|
webrick
|
||||||
|
google-apis-iamcredentials_v1 (0.10.0)
|
||||||
|
google-apis-core (>= 0.4, < 2.a)
|
||||||
|
google-apis-playcustomapp_v1 (0.7.0)
|
||||||
|
google-apis-core (>= 0.4, < 2.a)
|
||||||
|
google-apis-storage_v1 (0.11.0)
|
||||||
|
google-apis-core (>= 0.4, < 2.a)
|
||||||
|
google-cloud-core (1.6.0)
|
||||||
|
google-cloud-env (~> 1.0)
|
||||||
|
google-cloud-errors (~> 1.0)
|
||||||
|
google-cloud-env (1.5.0)
|
||||||
|
faraday (>= 0.17.3, < 2.0)
|
||||||
|
google-cloud-errors (1.2.0)
|
||||||
|
google-cloud-storage (1.36.1)
|
||||||
|
addressable (~> 2.8)
|
||||||
|
digest-crc (~> 0.4)
|
||||||
|
google-apis-iamcredentials_v1 (~> 0.1)
|
||||||
|
google-apis-storage_v1 (~> 0.1)
|
||||||
|
google-cloud-core (~> 1.6)
|
||||||
|
googleauth (>= 0.16.2, < 2.a)
|
||||||
|
mini_mime (~> 1.0)
|
||||||
|
googleauth (1.1.2)
|
||||||
|
faraday (>= 0.17.3, < 3.a)
|
||||||
|
jwt (>= 1.4, < 3.0)
|
||||||
|
memoist (~> 0.16)
|
||||||
|
multi_json (~> 1.11)
|
||||||
|
os (>= 0.9, < 2.0)
|
||||||
|
signet (>= 0.16, < 2.a)
|
||||||
|
highline (2.0.3)
|
||||||
|
http-cookie (1.0.4)
|
||||||
|
domain_name (~> 0.5)
|
||||||
|
httpclient (2.8.3)
|
||||||
|
jmespath (1.6.1)
|
||||||
|
json (2.6.1)
|
||||||
|
jwt (2.3.0)
|
||||||
|
memoist (0.16.2)
|
||||||
|
mini_magick (4.11.0)
|
||||||
|
mini_mime (1.1.2)
|
||||||
|
multi_json (1.15.0)
|
||||||
|
multipart-post (2.0.0)
|
||||||
|
nanaimo (0.3.0)
|
||||||
|
naturally (2.2.1)
|
||||||
|
optparse (0.1.1)
|
||||||
|
os (1.1.4)
|
||||||
|
plist (3.6.0)
|
||||||
|
public_suffix (4.0.6)
|
||||||
|
rake (13.0.6)
|
||||||
|
representable (3.1.1)
|
||||||
|
declarative (< 0.1.0)
|
||||||
|
trailblazer-option (>= 0.1.1, < 0.2.0)
|
||||||
|
uber (< 0.2.0)
|
||||||
|
retriable (3.1.2)
|
||||||
|
rexml (3.2.5)
|
||||||
|
rouge (2.0.7)
|
||||||
|
ruby2_keywords (0.0.5)
|
||||||
|
rubyzip (2.3.2)
|
||||||
|
security (0.1.3)
|
||||||
|
signet (0.16.1)
|
||||||
|
addressable (~> 2.8)
|
||||||
|
faraday (>= 0.17.5, < 3.0)
|
||||||
|
jwt (>= 1.5, < 3.0)
|
||||||
|
multi_json (~> 1.10)
|
||||||
|
simctl (1.6.8)
|
||||||
|
CFPropertyList
|
||||||
|
naturally
|
||||||
|
terminal-notifier (2.0.0)
|
||||||
|
terminal-table (1.8.0)
|
||||||
|
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||||
|
trailblazer-option (0.1.2)
|
||||||
|
tty-cursor (0.7.1)
|
||||||
|
tty-screen (0.8.1)
|
||||||
|
tty-spinner (0.9.3)
|
||||||
|
tty-cursor (~> 0.7)
|
||||||
|
uber (0.1.0)
|
||||||
|
unf (0.1.4)
|
||||||
|
unf_ext
|
||||||
|
unf_ext (0.0.8.1)
|
||||||
|
unicode-display_width (1.8.0)
|
||||||
|
webrick (1.7.0)
|
||||||
|
word_wrap (1.0.0)
|
||||||
|
xcodeproj (1.21.0)
|
||||||
|
CFPropertyList (>= 2.3.3, < 4.0)
|
||||||
|
atomos (~> 0.1.3)
|
||||||
|
claide (>= 1.0.2, < 2.0)
|
||||||
|
colored2 (~> 3.1)
|
||||||
|
nanaimo (~> 0.3.0)
|
||||||
|
rexml (~> 3.2.4)
|
||||||
|
xcpretty (0.3.0)
|
||||||
|
rouge (~> 2.0.7)
|
||||||
|
xcpretty-travis-formatter (1.0.1)
|
||||||
|
xcpretty (~> 0.2, >= 0.0.7)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
x86_64-darwin-21
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
fastlane
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
2.3.7
|
||||||
@@ -25,6 +25,13 @@ apply plugin: 'com.android.application'
|
|||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||||
|
|
||||||
|
def keystoreProperties = new Properties()
|
||||||
|
def keystorePropertiesFile = rootProject.file('key.properties')
|
||||||
|
if (keystorePropertiesFile.exists()) {
|
||||||
|
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion flutter.compileSdkVersion
|
compileSdkVersion flutter.compileSdkVersion
|
||||||
|
|
||||||
@@ -43,18 +50,27 @@ android {
|
|||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||||
applicationId "com.example.immich_mobile"
|
applicationId "app.alextran.immich"
|
||||||
minSdkVersion flutter.minSdkVersion
|
minSdkVersion 20
|
||||||
targetSdkVersion flutter.targetSdkVersion
|
targetSdkVersion flutter.targetSdkVersion
|
||||||
versionCode flutterVersionCode.toInteger()
|
versionCode flutterVersionCode.toInteger()
|
||||||
versionName flutterVersionName
|
versionName flutterVersionName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signingConfigs {
|
||||||
|
release {
|
||||||
|
keyAlias keystoreProperties['keyAlias']
|
||||||
|
keyPassword keystoreProperties['keyPassword']
|
||||||
|
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
|
||||||
|
storePassword keystoreProperties['storePassword']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
// TODO: Add your own signing config for the release build.
|
// TODO: Add your own signing config for the release build.
|
||||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||||
signingConfig signingConfigs.debug
|
signingConfig signingConfigs.release
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="app.alextran.immich">
|
||||||
package="com.example.immich_mobile">
|
<!-- Flutter needs it to communicate with the running application
|
||||||
<!-- Flutter needs it to communicate with the running application
|
|
||||||
to allow setting breakpoints, to provide hot reload, etc.
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
-->
|
-->
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
</manifest>
|
</manifest>
|
||||||
@@ -1,39 +1,23 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="app.alextran.immich">
|
||||||
package="com.example.immich_mobile">
|
<application android:label="Immich" android:name="${applicationName}" android:usesCleartextTraffic="true" android:icon="@mipmap/ic_launcher">
|
||||||
<application
|
<activity android:name=".MainActivity" android:exported="true" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize">
|
||||||
android:label="Immich"
|
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||||
android:name="${applicationName}"
|
|
||||||
android:usesCleartextTraffic="true"
|
|
||||||
android:icon="@mipmap/ic_launcher">
|
|
||||||
<activity
|
|
||||||
android:name=".MainActivity"
|
|
||||||
android:exported="true"
|
|
||||||
android:launchMode="singleTop"
|
|
||||||
android:theme="@style/LaunchTheme"
|
|
||||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
|
||||||
android:hardwareAccelerated="true"
|
|
||||||
android:windowSoftInputMode="adjustResize">
|
|
||||||
<!-- Specifies an Android theme to apply to this Activity as soon as
|
|
||||||
the Android process has started. This theme is visible to the user
|
the Android process has started. This theme is visible to the user
|
||||||
while the Flutter UI initializes. After that, this theme continues
|
while the Flutter UI initializes. After that, this theme continues
|
||||||
to determine the Window background behind the Flutter UI. -->
|
to determine the Window background behind the Flutter UI. -->
|
||||||
<meta-data
|
<meta-data android:name="io.flutter.embedding.android.NormalTheme" android:resource="@style/NormalTheme" />
|
||||||
android:name="io.flutter.embedding.android.NormalTheme"
|
<intent-filter>
|
||||||
android:resource="@style/NormalTheme"
|
<action android:name="android.intent.action.MAIN" />
|
||||||
/>
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
<intent-filter>
|
</intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
|
||||||
<category android:name="android.intent.category.LAUNCHER"/>
|
|
||||||
</intent-filter>
|
|
||||||
|
|
||||||
</activity>
|
|
||||||
<!-- Don't delete the meta-data below.
|
|
||||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
|
||||||
<meta-data
|
|
||||||
android:name="flutterEmbedding"
|
|
||||||
android:value="2"/>
|
|
||||||
|
|
||||||
|
</activity>
|
||||||
</application>
|
<!-- Don't delete the meta-data below.
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||||
</manifest>
|
<meta-data android:name="flutterEmbedding" android:value="2" />
|
||||||
|
|
||||||
|
|
||||||
|
</application>
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||||
|
</manifest>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package app.alextran.immich
|
||||||
|
|
||||||
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
|
|
||||||
|
class MainActivity: FlutterActivity() {
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="app.alextran.immich">
|
||||||
package="com.example.immich_mobile">
|
<!-- Flutter needs it to communicate with the running application
|
||||||
<!-- Flutter needs it to communicate with the running application
|
|
||||||
to allow setting breakpoints, to provide hot reload, etc.
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
-->
|
-->
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
</manifest>
|
</manifest>
|
||||||
2
mobile/android/fastlane/Appfile
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
json_key_file("/Users/alex/Documents/immich-fastlane-googleplaystore-key.json") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one
|
||||||
|
package_name("app.alextran.immich") # e.g. com.krausefx.app
|
||||||
25
mobile/android/fastlane/Fastfile
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# This file contains the fastlane.tools configuration
|
||||||
|
# You can find the documentation at https://docs.fastlane.tools
|
||||||
|
#
|
||||||
|
# For a list of all available actions, check out
|
||||||
|
#
|
||||||
|
# https://docs.fastlane.tools/actions
|
||||||
|
#
|
||||||
|
# For a list of all available plugins, check out
|
||||||
|
#
|
||||||
|
# https://docs.fastlane.tools/plugins/available-plugins
|
||||||
|
#
|
||||||
|
|
||||||
|
# Uncomment the line if you want fastlane to automatically update itself
|
||||||
|
# update_fastlane
|
||||||
|
|
||||||
|
default_platform(:android)
|
||||||
|
|
||||||
|
platform :android do
|
||||||
|
|
||||||
|
desc "Update AAB to PlayStore"
|
||||||
|
lane :beta do
|
||||||
|
upload_to_play_store(track: 'beta', aab: '../build/app/outputs/bundle/release/app-release.aab')
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
32
mobile/android/fastlane/README.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
fastlane documentation
|
||||||
|
----
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
|
||||||
|
Make sure you have the latest version of the Xcode command line tools installed:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
xcode-select --install
|
||||||
|
```
|
||||||
|
|
||||||
|
For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
|
||||||
|
|
||||||
|
# Available Actions
|
||||||
|
|
||||||
|
## Android
|
||||||
|
|
||||||
|
### android beta
|
||||||
|
|
||||||
|
```sh
|
||||||
|
[bundle exec] fastlane android beta
|
||||||
|
```
|
||||||
|
|
||||||
|
Update AAB to PlayStore
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
|
||||||
|
|
||||||
|
More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
|
||||||
|
|
||||||
|
The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
|
||||||
20
mobile/android/fastlane/report.xml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<testsuites>
|
||||||
|
<testsuite name="fastlane.lanes">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000318">
|
||||||
|
|
||||||
|
</testcase>
|
||||||
|
|
||||||
|
|
||||||
|
<testcase classname="fastlane.lanes" name="1: upload_to_play_store" time="111.253169">
|
||||||
|
|
||||||
|
<failure message="/usr/local/Cellar/fastlane/2.204.3/libexec/gems/fastlane-2.204.3/fastlane/lib/fastlane/actions/actions_helper.rb:67:in `execute_action' /usr/local/Cellar/fastlane/2.204.3/libexec/gems/fastlane-2.204.3/fastlane/lib/fastlane/runner.rb:255:in `block in execute_action' /usr/local/Cellar/fastlane/2.204.3/libexec/gems/fastlane-2.204.3/fastlane/lib/fastlane/runner.rb:229:in `chdir' /usr/local/Cellar/fastlane/2.204.3/libexec/gems/fastlane-2.204.3/fastlane/lib/fastlane/runner.rb:229:in `execute_action' /usr/local/Cellar/fastlane/2.204.3/libexec/gems/fastlane-2.204.3/fastlane/lib/fastlane/runner.rb:157:in `trigger_action_by_name' /usr/local/Cellar/fastlane/2.204.3/libexec/gems/fastlane-2.204.3/fastlane/lib/fastlane/fast_file.rb:159:in `method_missing' Fastfile:22:in `block (2 levels) in parsing_binding' /usr/local/Cellar/fastlane/2.204.3/libexec/gems/fastlane-2.204.3/fastlane/lib/fastlane/lane.rb:33:in `call' /usr/local/Cellar/fastlane/2.204.3/libexec/gems/fastlane-2.204.3/fastlane/lib/fastlane/runner.rb:49:in `block in execute' /usr/local/Cellar/fastlane/2.204.3/libexec/gems/fastlane-2.204.3/fastlane/lib/fastlane/runner.rb:45:in `chdir' /usr/local/Cellar/fastlane/2.204.3/libexec/gems/fastlane-2.204.3/fastlane/lib/fastlane/runner.rb:45:in `execute' /usr/local/Cellar/fastlane/2.204.3/libexec/gems/fastlane-2.204.3/fastlane/lib/fastlane/lane_manager.rb:47:in `cruise_lane' /usr/local/Cellar/fastlane/2.204.3/libexec/gems/fastlane-2.204.3/fastlane/lib/fastlane/command_line_handler.rb:36:in `handle' /usr/local/Cellar/fastlane/2.204.3/libexec/gems/fastlane-2.204.3/fastlane/lib/fastlane/commands_generator.rb:109:in `block (2 levels) in run' /usr/local/Cellar/fastlane/2.204.3/libexec/gems/commander-4.6.0/lib/commander/command.rb:187:in `call' /usr/local/Cellar/fastlane/2.204.3/libexec/gems/commander-4.6.0/lib/commander/command.rb:157:in `run' /usr/local/Cellar/fastlane/2.204.3/libexec/gems/commander-4.6.0/lib/commander/runner.rb:444:in `run_active_command' /usr/local/Cellar/fastlane/2.204.3/libexec/gems/fastlane-2.204.3/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb:124:in `run!' /usr/local/Cellar/fastlane/2.204.3/libexec/gems/commander-4.6.0/lib/commander/delegates.rb:18:in `run!' /usr/local/Cellar/fastlane/2.204.3/libexec/gems/fastlane-2.204.3/fastlane/lib/fastlane/commands_generator.rb:353:in `run' /usr/local/Cellar/fastlane/2.204.3/libexec/gems/fastlane-2.204.3/fastlane/lib/fastlane/commands_generator.rb:42:in `start' /usr/local/Cellar/fastlane/2.204.3/libexec/gems/fastlane-2.204.3/fastlane/lib/fastlane/cli_tools_distributor.rb:122:in `take_off' /usr/local/Cellar/fastlane/2.204.3/libexec/gems/fastlane-2.204.3/bin/fastlane:23:in `<top (required)>' /usr/local/Cellar/fastlane/2.204.3/libexec/bin/fastlane:25:in `load' /usr/local/Cellar/fastlane/2.204.3/libexec/bin/fastlane:25:in `<main>' Google Api Error: Invalid request - APK specifies a version code that has already been used." />
|
||||||
|
|
||||||
|
</testcase>
|
||||||
|
|
||||||
|
</testsuite>
|
||||||
|
</testsuites>
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
org.gradle.jvmargs=-Xmx1536M
|
org.gradle.jvmargs=-Xmx1536M
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
3
mobile/android/metadata/en-US/full_description.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
This is a client app for Immich Server and you will need to run/manage the server on your own in order to use the app.
|
||||||
|
|
||||||
|
Github URL: https://github.com/alextran1502/immich
|
||||||
BIN
mobile/android/metadata/en-US/images/featureGraphic.png
Normal file
|
After Width: | Height: | Size: 48 KiB |
BIN
mobile/android/metadata/en-US/images/icon.png
Normal file
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 403 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 74 KiB |
|
After Width: | Height: | Size: 183 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 3.4 MiB |
|
After Width: | Height: | Size: 185 KiB |
|
After Width: | Height: | Size: 1.5 MiB |
|
After Width: | Height: | Size: 4.0 MiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 3.4 MiB |
|
After Width: | Height: | Size: 185 KiB |
|
After Width: | Height: | Size: 1.5 MiB |
|
After Width: | Height: | Size: 4.0 MiB |
1
mobile/android/metadata/en-US/short_description.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Self-hosted photo and video backup solution directly from your mobile phone.
|
||||||
1
mobile/android/metadata/en-US/title.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Immich
|
||||||
0
mobile/android/metadata/en-US/video.txt
Normal file
BIN
mobile/assets/location-pin.png
Normal file
|
After Width: | Height: | Size: 50 KiB |
3
mobile/ios/Gemfile
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
source "https://rubygems.org"
|
||||||
|
|
||||||
|
gem "fastlane"
|
||||||
218
mobile/ios/Gemfile.lock
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
GEM
|
||||||
|
remote: https://rubygems.org/
|
||||||
|
specs:
|
||||||
|
CFPropertyList (3.0.5)
|
||||||
|
rexml
|
||||||
|
addressable (2.8.0)
|
||||||
|
public_suffix (>= 2.0.2, < 5.0)
|
||||||
|
artifactory (3.0.15)
|
||||||
|
atomos (0.1.3)
|
||||||
|
aws-eventstream (1.2.0)
|
||||||
|
aws-partitions (1.566.0)
|
||||||
|
aws-sdk-core (3.129.1)
|
||||||
|
aws-eventstream (~> 1, >= 1.0.2)
|
||||||
|
aws-partitions (~> 1, >= 1.525.0)
|
||||||
|
aws-sigv4 (~> 1.1)
|
||||||
|
jmespath (~> 1.0)
|
||||||
|
aws-sdk-kms (1.55.0)
|
||||||
|
aws-sdk-core (~> 3, >= 3.127.0)
|
||||||
|
aws-sigv4 (~> 1.1)
|
||||||
|
aws-sdk-s3 (1.113.0)
|
||||||
|
aws-sdk-core (~> 3, >= 3.127.0)
|
||||||
|
aws-sdk-kms (~> 1)
|
||||||
|
aws-sigv4 (~> 1.4)
|
||||||
|
aws-sigv4 (1.4.0)
|
||||||
|
aws-eventstream (~> 1, >= 1.0.2)
|
||||||
|
babosa (1.0.4)
|
||||||
|
claide (1.1.0)
|
||||||
|
colored (1.2)
|
||||||
|
colored2 (3.1.2)
|
||||||
|
commander (4.6.0)
|
||||||
|
highline (~> 2.0.0)
|
||||||
|
declarative (0.0.20)
|
||||||
|
digest-crc (0.6.4)
|
||||||
|
rake (>= 12.0.0, < 14.0.0)
|
||||||
|
domain_name (0.5.20190701)
|
||||||
|
unf (>= 0.0.5, < 1.0.0)
|
||||||
|
dotenv (2.7.6)
|
||||||
|
emoji_regex (3.2.3)
|
||||||
|
excon (0.91.0)
|
||||||
|
faraday (1.10.0)
|
||||||
|
faraday-em_http (~> 1.0)
|
||||||
|
faraday-em_synchrony (~> 1.0)
|
||||||
|
faraday-excon (~> 1.1)
|
||||||
|
faraday-httpclient (~> 1.0)
|
||||||
|
faraday-multipart (~> 1.0)
|
||||||
|
faraday-net_http (~> 1.0)
|
||||||
|
faraday-net_http_persistent (~> 1.0)
|
||||||
|
faraday-patron (~> 1.0)
|
||||||
|
faraday-rack (~> 1.0)
|
||||||
|
faraday-retry (~> 1.0)
|
||||||
|
ruby2_keywords (>= 0.0.4)
|
||||||
|
faraday-cookie_jar (0.0.7)
|
||||||
|
faraday (>= 0.8.0)
|
||||||
|
http-cookie (~> 1.0.0)
|
||||||
|
faraday-em_http (1.0.0)
|
||||||
|
faraday-em_synchrony (1.0.0)
|
||||||
|
faraday-excon (1.1.0)
|
||||||
|
faraday-httpclient (1.0.1)
|
||||||
|
faraday-multipart (1.0.3)
|
||||||
|
multipart-post (>= 1.2, < 3)
|
||||||
|
faraday-net_http (1.0.1)
|
||||||
|
faraday-net_http_persistent (1.2.0)
|
||||||
|
faraday-patron (1.0.0)
|
||||||
|
faraday-rack (1.0.0)
|
||||||
|
faraday-retry (1.0.3)
|
||||||
|
faraday_middleware (1.2.0)
|
||||||
|
faraday (~> 1.0)
|
||||||
|
fastimage (2.2.6)
|
||||||
|
fastlane (2.204.3)
|
||||||
|
CFPropertyList (>= 2.3, < 4.0.0)
|
||||||
|
addressable (>= 2.8, < 3.0.0)
|
||||||
|
artifactory (~> 3.0)
|
||||||
|
aws-sdk-s3 (~> 1.0)
|
||||||
|
babosa (>= 1.0.3, < 2.0.0)
|
||||||
|
bundler (>= 1.12.0, < 3.0.0)
|
||||||
|
colored
|
||||||
|
commander (~> 4.6)
|
||||||
|
dotenv (>= 2.1.1, < 3.0.0)
|
||||||
|
emoji_regex (>= 0.1, < 4.0)
|
||||||
|
excon (>= 0.71.0, < 1.0.0)
|
||||||
|
faraday (~> 1.0)
|
||||||
|
faraday-cookie_jar (~> 0.0.6)
|
||||||
|
faraday_middleware (~> 1.0)
|
||||||
|
fastimage (>= 2.1.0, < 3.0.0)
|
||||||
|
gh_inspector (>= 1.1.2, < 2.0.0)
|
||||||
|
google-apis-androidpublisher_v3 (~> 0.3)
|
||||||
|
google-apis-playcustomapp_v1 (~> 0.1)
|
||||||
|
google-cloud-storage (~> 1.31)
|
||||||
|
highline (~> 2.0)
|
||||||
|
json (< 3.0.0)
|
||||||
|
jwt (>= 2.1.0, < 3)
|
||||||
|
mini_magick (>= 4.9.4, < 5.0.0)
|
||||||
|
multipart-post (~> 2.0.0)
|
||||||
|
naturally (~> 2.2)
|
||||||
|
optparse (~> 0.1.1)
|
||||||
|
plist (>= 3.1.0, < 4.0.0)
|
||||||
|
rubyzip (>= 2.0.0, < 3.0.0)
|
||||||
|
security (= 0.1.3)
|
||||||
|
simctl (~> 1.6.3)
|
||||||
|
terminal-notifier (>= 2.0.0, < 3.0.0)
|
||||||
|
terminal-table (>= 1.4.5, < 2.0.0)
|
||||||
|
tty-screen (>= 0.6.3, < 1.0.0)
|
||||||
|
tty-spinner (>= 0.8.0, < 1.0.0)
|
||||||
|
word_wrap (~> 1.0.0)
|
||||||
|
xcodeproj (>= 1.13.0, < 2.0.0)
|
||||||
|
xcpretty (~> 0.3.0)
|
||||||
|
xcpretty-travis-formatter (>= 0.0.3)
|
||||||
|
gh_inspector (1.1.3)
|
||||||
|
google-apis-androidpublisher_v3 (0.16.0)
|
||||||
|
google-apis-core (>= 0.4, < 2.a)
|
||||||
|
google-apis-core (0.4.2)
|
||||||
|
addressable (~> 2.5, >= 2.5.1)
|
||||||
|
googleauth (>= 0.16.2, < 2.a)
|
||||||
|
httpclient (>= 2.8.1, < 3.a)
|
||||||
|
mini_mime (~> 1.0)
|
||||||
|
representable (~> 3.0)
|
||||||
|
retriable (>= 2.0, < 4.a)
|
||||||
|
rexml
|
||||||
|
webrick
|
||||||
|
google-apis-iamcredentials_v1 (0.10.0)
|
||||||
|
google-apis-core (>= 0.4, < 2.a)
|
||||||
|
google-apis-playcustomapp_v1 (0.7.0)
|
||||||
|
google-apis-core (>= 0.4, < 2.a)
|
||||||
|
google-apis-storage_v1 (0.11.0)
|
||||||
|
google-apis-core (>= 0.4, < 2.a)
|
||||||
|
google-cloud-core (1.6.0)
|
||||||
|
google-cloud-env (~> 1.0)
|
||||||
|
google-cloud-errors (~> 1.0)
|
||||||
|
google-cloud-env (1.5.0)
|
||||||
|
faraday (>= 0.17.3, < 2.0)
|
||||||
|
google-cloud-errors (1.2.0)
|
||||||
|
google-cloud-storage (1.36.1)
|
||||||
|
addressable (~> 2.8)
|
||||||
|
digest-crc (~> 0.4)
|
||||||
|
google-apis-iamcredentials_v1 (~> 0.1)
|
||||||
|
google-apis-storage_v1 (~> 0.1)
|
||||||
|
google-cloud-core (~> 1.6)
|
||||||
|
googleauth (>= 0.16.2, < 2.a)
|
||||||
|
mini_mime (~> 1.0)
|
||||||
|
googleauth (1.1.2)
|
||||||
|
faraday (>= 0.17.3, < 3.a)
|
||||||
|
jwt (>= 1.4, < 3.0)
|
||||||
|
memoist (~> 0.16)
|
||||||
|
multi_json (~> 1.11)
|
||||||
|
os (>= 0.9, < 2.0)
|
||||||
|
signet (>= 0.16, < 2.a)
|
||||||
|
highline (2.0.3)
|
||||||
|
http-cookie (1.0.4)
|
||||||
|
domain_name (~> 0.5)
|
||||||
|
httpclient (2.8.3)
|
||||||
|
jmespath (1.6.1)
|
||||||
|
json (2.6.1)
|
||||||
|
jwt (2.3.0)
|
||||||
|
memoist (0.16.2)
|
||||||
|
mini_magick (4.11.0)
|
||||||
|
mini_mime (1.1.2)
|
||||||
|
multi_json (1.15.0)
|
||||||
|
multipart-post (2.0.0)
|
||||||
|
nanaimo (0.3.0)
|
||||||
|
naturally (2.2.1)
|
||||||
|
optparse (0.1.1)
|
||||||
|
os (1.1.4)
|
||||||
|
plist (3.6.0)
|
||||||
|
public_suffix (4.0.6)
|
||||||
|
rake (13.0.6)
|
||||||
|
representable (3.1.1)
|
||||||
|
declarative (< 0.1.0)
|
||||||
|
trailblazer-option (>= 0.1.1, < 0.2.0)
|
||||||
|
uber (< 0.2.0)
|
||||||
|
retriable (3.1.2)
|
||||||
|
rexml (3.2.5)
|
||||||
|
rouge (2.0.7)
|
||||||
|
ruby2_keywords (0.0.5)
|
||||||
|
rubyzip (2.3.2)
|
||||||
|
security (0.1.3)
|
||||||
|
signet (0.16.1)
|
||||||
|
addressable (~> 2.8)
|
||||||
|
faraday (>= 0.17.5, < 3.0)
|
||||||
|
jwt (>= 1.5, < 3.0)
|
||||||
|
multi_json (~> 1.10)
|
||||||
|
simctl (1.6.8)
|
||||||
|
CFPropertyList
|
||||||
|
naturally
|
||||||
|
terminal-notifier (2.0.0)
|
||||||
|
terminal-table (1.8.0)
|
||||||
|
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||||
|
trailblazer-option (0.1.2)
|
||||||
|
tty-cursor (0.7.1)
|
||||||
|
tty-screen (0.8.1)
|
||||||
|
tty-spinner (0.9.3)
|
||||||
|
tty-cursor (~> 0.7)
|
||||||
|
uber (0.1.0)
|
||||||
|
unf (0.1.4)
|
||||||
|
unf_ext
|
||||||
|
unf_ext (0.0.8)
|
||||||
|
unicode-display_width (1.8.0)
|
||||||
|
webrick (1.7.0)
|
||||||
|
word_wrap (1.0.0)
|
||||||
|
xcodeproj (1.21.0)
|
||||||
|
CFPropertyList (>= 2.3.3, < 4.0)
|
||||||
|
atomos (~> 0.1.3)
|
||||||
|
claide (>= 1.0.2, < 2.0)
|
||||||
|
colored2 (~> 3.1)
|
||||||
|
nanaimo (~> 0.3.0)
|
||||||
|
rexml (~> 3.2.4)
|
||||||
|
xcpretty (0.3.0)
|
||||||
|
rouge (~> 2.0.7)
|
||||||
|
xcpretty-travis-formatter (1.0.1)
|
||||||
|
xcpretty (~> 0.2, >= 0.0.7)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
x86_64-darwin-21
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
fastlane
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
2.3.7
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# Uncomment this line to define a global platform for your project
|
# Uncomment this line to define a global platform for your project
|
||||||
# platform :ios, '9.0'
|
platform :ios, '11.0'
|
||||||
|
|
||||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||||
@@ -34,8 +34,19 @@ target 'Runner' do
|
|||||||
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
||||||
end
|
end
|
||||||
|
|
||||||
post_install do |installer|
|
# post_install do |installer|
|
||||||
installer.pods_project.targets.each do |target|
|
# installer.pods_project.targets.each do |target|
|
||||||
flutter_additional_ios_build_settings(target)
|
# flutter_additional_ios_build_settings(target)
|
||||||
end
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
|
post_install do |installer|
|
||||||
|
installer.pods_project.targets.each do |target|
|
||||||
|
flutter_additional_ios_build_settings(target)
|
||||||
|
target.build_configurations.each do |config|
|
||||||
|
config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
|
||||||
|
config.build_settings['ENABLE_BITCODE'] = 'YES'
|
||||||
|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0'
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,18 +1,22 @@
|
|||||||
PODS:
|
PODS:
|
||||||
- device_info_plus (0.0.1):
|
|
||||||
- Flutter
|
|
||||||
- Flutter (1.0.0)
|
- Flutter (1.0.0)
|
||||||
|
- flutter_udid (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- SAMKeychain
|
||||||
- fluttertoast (0.0.2):
|
- fluttertoast (0.0.2):
|
||||||
- Flutter
|
- Flutter
|
||||||
- Toast
|
- Toast
|
||||||
- FMDB (2.7.5):
|
- FMDB (2.7.5):
|
||||||
- FMDB/standard (= 2.7.5)
|
- FMDB/standard (= 2.7.5)
|
||||||
- FMDB/standard (2.7.5)
|
- FMDB/standard (2.7.5)
|
||||||
|
- package_info_plus (0.4.5):
|
||||||
|
- Flutter
|
||||||
- path_provider_ios (0.0.1):
|
- path_provider_ios (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- photo_manager (1.0.0):
|
- photo_manager (1.0.0):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
|
- SAMKeychain (1.5.3)
|
||||||
- sqflite (0.0.2):
|
- sqflite (0.0.2):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FMDB (>= 2.7.5)
|
- FMDB (>= 2.7.5)
|
||||||
@@ -23,9 +27,10 @@ PODS:
|
|||||||
- Flutter
|
- Flutter
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
|
||||||
- Flutter (from `Flutter`)
|
- Flutter (from `Flutter`)
|
||||||
|
- flutter_udid (from `.symlinks/plugins/flutter_udid/ios`)
|
||||||
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
|
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
|
||||||
|
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||||
- path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
|
- path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
|
||||||
- photo_manager (from `.symlinks/plugins/photo_manager/ios`)
|
- photo_manager (from `.symlinks/plugins/photo_manager/ios`)
|
||||||
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
||||||
@@ -35,15 +40,18 @@ DEPENDENCIES:
|
|||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
- FMDB
|
- FMDB
|
||||||
|
- SAMKeychain
|
||||||
- Toast
|
- Toast
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
device_info_plus:
|
|
||||||
:path: ".symlinks/plugins/device_info_plus/ios"
|
|
||||||
Flutter:
|
Flutter:
|
||||||
:path: Flutter
|
:path: Flutter
|
||||||
|
flutter_udid:
|
||||||
|
:path: ".symlinks/plugins/flutter_udid/ios"
|
||||||
fluttertoast:
|
fluttertoast:
|
||||||
:path: ".symlinks/plugins/fluttertoast/ios"
|
:path: ".symlinks/plugins/fluttertoast/ios"
|
||||||
|
package_info_plus:
|
||||||
|
:path: ".symlinks/plugins/package_info_plus/ios"
|
||||||
path_provider_ios:
|
path_provider_ios:
|
||||||
:path: ".symlinks/plugins/path_provider_ios/ios"
|
:path: ".symlinks/plugins/path_provider_ios/ios"
|
||||||
photo_manager:
|
photo_manager:
|
||||||
@@ -56,17 +64,19 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/wakelock/ios"
|
:path: ".symlinks/plugins/wakelock/ios"
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed
|
|
||||||
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
|
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
|
||||||
|
flutter_udid: 0848809dbed4c055175747ae6a45a8b4f6771e1c
|
||||||
fluttertoast: 6122fa75143e992b1d3470f61000f591a798cc58
|
fluttertoast: 6122fa75143e992b1d3470f61000f591a798cc58
|
||||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||||
|
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
|
||||||
path_provider_ios: 7d7ce634493af4477d156294792024ec3485acd5
|
path_provider_ios: 7d7ce634493af4477d156294792024ec3485acd5
|
||||||
photo_manager: 84fa94fbeb82e607333ea9a13c43b58e0903a463
|
photo_manager: 84fa94fbeb82e607333ea9a13c43b58e0903a463
|
||||||
|
SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c
|
||||||
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
|
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
|
||||||
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
|
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
|
||||||
video_player_avfoundation: e489aac24ef5cf7af82702979ed16f2a5ef84cff
|
video_player_avfoundation: e489aac24ef5cf7af82702979ed16f2a5ef84cff
|
||||||
wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f
|
wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f
|
||||||
|
|
||||||
PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
|
PODFILE CHECKSUM: 05c3056158482c567a3e0cdab1351ceeee238a07
|
||||||
|
|
||||||
COCOAPODS: 1.10.1
|
COCOAPODS: 1.11.3
|
||||||
|
|||||||