Note that this project has been moved to the organization Dev-digitalgarda
This is the php backend of the project "Webfoto".
The "Webfoto" project's purpose is to put some cameras, that take a photo every a certain amount of time, in some hotels, so that a web component can show the timeline of the view of that hotel in the hotel's website.
The php backend is the code that periodically handles and organizes the images sent by the cameras, making them homogeneous, and that furnishes the APIs to the webcomponent. It is a PHP code that can be used by any server that can run PHP.
For the cronjob part:
- It parses the
.env
file - It reads the
settings.json
file - Then it does the next steps for each of the albums that it finds in the
settings.json
- If a table for the photos of for the album is missing in the db, it creates it
- Then it retrieves all the images in the input folder of the album
- It analyzes them and, in base of the configurations, removes the ones that are not needed
- It then adds a good name to the kept photos and moves them to the output folder of the album, by adding also a tuple to the database for each photo
- If it is written in the settings, it sends via ftp the last image of the album
- It then checks if there are images that, depending on the configurations, are too days old, and removes them
- It then checks if, depending on the configuration, there were not input images for a certain amount of time and, if this is the case, it sends an email alert
For the api part:
endpoint | description |
---|---|
/api/albums/:name/images | It returns all the ISO timestamps of all the images of this album, sorted in ascending order, as a json array. The param :name is exactly the one used in the webcomponent that shows this album and that is in the settings.json |
/api/albums/:name/images | It redirects to the last image of this album, which is statically served. The param :name is exactly the one used in the webcomponent that shows this album and that is in the settings.json |
The configuration is done both with a .env
file with environment variables and with a settings.json
file.
There is in this repo a .env.example
file with an example of .env
file.
The variables are the ones in the table below:
Variable | Required | Default | Description |
---|---|---|---|
DB_HOST | ✔️ | undefined | The host of the mysql database |
DB_PORT | ✔️ | undefined | The port of the mysql database |
DB_DATABASE | ✔️ | undefined | The name of the mysql database |
DB_USER | ✔️ | undefined | The user of the mysql database |
DB_PASSWORD | ✔️ | undefined | The password of the mysql database |
DB_CHARSET | ✅ | utf8mb4 | The charsed used by the mysql database |
EMAIL_AUTH_TYPE | ✅ | undefined | It can be CREDENTIALS or GOOGLE and specifies the way the user is authenticated to send emails in case of an alert |
EMAIL_HOST | ✅ | undefined | The smtp host of the email |
EMAIL_USERNAME | ✅ | undefined | The email username |
EMAIL_PASSWORD | ✅ | undefined | The email password, used in case of CREDENTIALS auth |
EMAIL_GOOGLE_CLIENT_ID | ✅ | undefined | The email google client id, used in case of GOOGLE auth |
EMAIL_GOOGLE_CLIENT_SECRET | ✅ | undefined | The email google client secret token, used in case of GOOGLE auth |
EMAIL_GOOGLE_REFRESH_TOKEN | ✅ | undefined | The email google refresh token, used in case of GOOGLE auth |
EMAIL_RECIPIENT | ✅ | undefined | The email address of the recipient of the alert email |
EMAIL_RECIPIENT_TEXT | ✅ | undefined | The name of the email recipient of the alert email |
EMAIL_SUBJECT | ✅ | undefined | The subject of the email alert. Note that {{ALBUM}} is substituted with the album name |
EMAIL_BODY | ✅ | undefined | The body of the email alert. Note that {{ALBUM}} is substituted with the album name |
ALERT_THRESHOLD_HOURS | ✅ | undefined | After how many hours without images will an email alert be sent |
SETTINGS_PATH | ✅ | ./settings.json | The path of the settings json file |
KEEP_LAST_DAYS | ✔️ | undefined | How many days of photos will be kept (Note that older photos will be deleted). |
OUTPUT_FOTOS_PATH | ✔️ | undefined | The path where the handled photos will be saved (Note that there will be a subfolder with the album's name). |
OUTPUT_FOTOS_URL | ✔️ | undefined | The path that statically serves the photos (the root folder). It is used bye the last-image api endpoint. |
ADD_CORS | ✅ | true | If in the api endpoint a cors-allow-anywhere will be added. |
It is an array defining each album (which represents an hotel). Note that there is a settings.example.json
file in this repo.
The properties are:
Variable | Type | Required | Description |
---|---|---|---|
name | string | ✔️ | The name of the album, which will be used also in the database |
inputPath | string | ✔️ | The path to the directory were the camera saves the album photos |
driver | string | ✔️ | The type of driver used to parse the input folder (for instance dahua or hikvision ) |
keepEverySeconds | number | ✔️ | Which is the minimum gap in seconds of two subsequent photos that are kept |
ftp.host | string | ✅ | The ftp host where the last images will be sent |
ftp.user | string | ✅ | The ftp user where the last images will be sent |
ftp.port | number | ✅ | The ftp port where the last images will be sent |
ftp.password | string | ✅ | The ftp password where the last images will be sent |
ftp.destination | string | ✅ | The ftp path where the last images will be sent |
Note: ftp
is a nested object.
The database is mysql or mariadb (neither the implementation nor the configuration change).
The database contains two tables:
- images: It contains the saved images
- alerts: It contains information about alerts
The image table:
Column | Type | Description |
---|---|---|
id | integer | The incremental id of the tuple |
name | text | The name of the album |
path | text | The path where the image is saved, relative to the outputs subfolder |
timestamp | datetime | The datetime of the image |
The alerts table:
Column | Type | Description |
---|---|---|
id | integer | The incremental id of the tuple |
name | text | The name of the album |
timestamp | datetime | The timestamp when the last time an alert was sent for this album. It is used to avoid send more than an email alert a day |
Because Rector is used to downgrade the php code to legacy php code versions, ideally, the last version of php can be used for this code. At the time this text was written, the latest version was php 8.
For the dependencies, composer was used. All the code is well modularized and organized in namespaces with classes.
- Download the last generated code from the releases
- Add a
.env
and asettings.json
file, by looking at the analogue example files and at this readme - Execute
composer install
- Serve the php code and note that you are responsible to call the
cronjob.php
periodically
The deploy is actually automatically handled through a github action.
The github action:
- Starts an ubuntu docker container
- Adds php and composer
- Installs the dependencies
- Uses rector to downgrade the php version
- Compresses the code
- Gets the composer.json version
- Pulishes a new release with that version and with the compressed backend
Every automatic deploy creates a new release. In that release, there is attached a compressed (.tar.gz) file containing the generated code.
Whoever will contribute and work on this code:
- Should install locally php, composer and a mysql-like db
- Clone the project and checkout on the dev branch
- Change the code
- Add the submodule with
composer run pull-core
- Test locally the changes with
composer start
- Push the code on dev
- Only when you want a new release to be published, you should update the version in composer.json and merge the dev branch into main