Skip to content
This repository was archived by the owner on Mar 6, 2025. It is now read-only.

Commit 0a5a308

Browse files
author
Dan Bright
committed
Initial commit of frontend component in new repo
Initial commit of frontend component in new repo after repo reorganisation.
1 parent e7d5a7c commit 0a5a308

34 files changed

+3128
-0
lines changed

.gitignore

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
.babelrc
2+
build/
3+
assets/bundles/
4+
node_modules/
5+
tests/
6+
.eslintcache
7+
*swp
8+
package-lock.json
9+
devel/
10+
nvm/
11+
.env.production
12+
.env.dev

README.md

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Simple Photo Management - Frontend Client Component
2+
3+
## About
4+
5+
This is a demo/prototype of simple application built on web technologies to IPTC tag, search & image optimise digital photo libraries.
6+
7+
It has web frontend client that connects to a RESTful API backend. Data is stored in either a SQLite, mySQL or PostgreSQL (recommended) database.
8+
9+
The web client is built with React.js and the server backend is written in Python 3.7 using the Django framework.
10+
11+
**Important: Before scanning an image directory, please ensure you have backed up your data. This is a prototype and should be used with that in mind. Please do not put your only copy of digital photos at risk!**
12+
13+
## Support & project status
14+
15+
A one-off installation service for this app is available. Please contact spm@uplandsdynamic.com for further details.
16+
17+
The GPL licensed version of this project offered here is *not guaranteed* to be regularly maintained. It is made available here for demo/prototype purposes only, and should not be used in production (i.e. a "live" working environment) unless the administrator regularly patches project dependencies (i.e. PYPI & npm packages) with upstream security updates as and when released by vendors.
18+
19+
## Key technologies
20+
21+
Python 3.7, Django, Django-rest-framework, Javascript (ReactJS), HTML5, CSS3
22+
23+
## Key features
24+
25+
- Recursively scan directories for digital image files
26+
- Add, remove & edit IPTC meta keyword tags from digital images via a web interface
27+
- Easily select previously used IPTC meta keyword tags and add to digital images
28+
- Automatically create a range of smaller (optimised) versions of each larger image (e.g. .jpg from a .tiff)
29+
- Optimised versions named using a hash of the origin image file, to prevent duplication (note, the hash includes metadata, so if an identical looking image has had a change in metadata it is deemed 'different'.)
30+
- Display & download optimised & resized versions of large images in the web interface
31+
- Database IPTC tags associated with each image
32+
- Search for & display digital images containing single IPTC tags or a combination of multiple tags
33+
- Search and replace IPTC tags over all scanned image directories
34+
- Restrict access to specific tags for specific usernames
35+
- Switch between `light` and `dark` modes (by setting an environment variable)
36+
37+
## Live Demo
38+
39+
There is a live demo available here:
40+
41+
https://frontend.spm.webapps.uplandsdynamic.com
42+
43+
Login credentials are:
44+
45+
- Username: riker
46+
- Password: z4Xd\*7byV\$xw
47+
48+
## Screenshots
49+
50+
![Screenshot 1](./meta/img/screenshot_01.png?raw=true)
51+
52+
## Usage Instructions
53+
54+
- Navigate to the web client url - e.g. `http://your_domain.tld` **Note: When starting a newly built or pulled container for the first time, the web client may take several minutes (depending on your server's resources) to create a fresh build. You will get a `502 Bad Gateway` error whilst the NPM build is occurring. Please be patient and try refreshing the page in a few moments.**
55+
56+
- Login to the web client using the superuser credentials you'd previously supplied.
57+
- Click on the `+` button to scan the photo_directory for new original photos. By default, this action:
58+
- Recursively scans for digital images (.jpg, .tiff, .png)
59+
- Reads any IPTC keyword tags and adds them to the database.
60+
- The digital images are processed, with a range of image sizes automatically generated.
61+
- Give it a few seconds and click the green refresh button (far left of the toolbar, beneath the page numbers). Images with no pre-existing IPTC keyword tags should be displayed (if any).
62+
- To display images that do have tags, try typing a phrase into the search bar:
63+
- To search for tags containing a specifically defined phrase, enclose the phrase between quotation marks, e.g. "a phrase tag"
64+
- To search for images that contain a combination of multiple tags, separate search words or phrases with either a space, or a forward slash `/`.
65+
- Clicking the button with the `tag` icon re-scans all images in photo_directory, adds any newly discovered images and recopies all IPTC keyword tags to the database. To simply add new images without re-copying the tags, use the `+` button instead.
66+
- Clicking the button with the `broom` icon cleans the database of references to any processed images that no longer exist in the `media` directories or the origin image `photo_directory`.
67+
- Clicking the button with the `slashed 'T'` icon removes all tags from the database which are not currently attached to any image (tag pruning). Note, this *does not* remove tags from an image, but simply cleans database records of unused tags.
68+
- Clicking the button with the `swap` icon (left & right arrows) switches to `search & replace` mode, which allows replacement of an IPTC tag in all images with another:
69+
- Simply enter the term to search for in the upper `Search` field, the replacement tag in the `Replace` field, then click on the red button to `search & replace`.
70+
- To remove a tag from all images *without replacing it with an alternative*, type a dash character (also known as minus or tack) "`-`" into the `Replace` field. Then click on the red button to delete that tag from every image in the database.
71+
- Add new tags to an image in one of two ways. These actions both write the new tag(s) to the metadata of the **ORIGINAL IMAGE** and to the database.:
72+
- By entering them in the input field, in the `Action` column. Separate multiple tags with a `/`.
73+
- By selecting from the list of previously used tags, that appears below the input field after you've begun to enter your tag. As you continue to type, this list resolves to display tags containing a sequence of characters that match your input.
74+
- Processed images may be operated on in the following ways:
75+
- Clicking on a thumbnail image opens a larger resolution copy of that processed image. This may then be downloaded, via the toolbar appearing at the top of the image viewer. Note, this is __not__ the *original* image, but rather a higher resolution version of the processed image.
76+
- The thumbnail images themselves have a mini-toolbar of buttons beneath them:
77+
- `Anticlockwise arrow` rotates the processed images (thumbnail and the generated larger versions up to 1080px wide) anticlockwise.
78+
- `Clockwise arrow` rotates the processed images (thumbnail and the generated larger versions up to 1080px wide) clockwise.
79+
- `Refresh symbol` reprocesses that image record. Processed images (thumbnail and larger versions up to 1080px wide) are generated and tags coped to them from the original image. This is useful if, for example, a processed image has been accidentally deleted, or corrupted for some reason.
80+
- Occasionally, the user may encounter errors during tag writing, due to problematical or corrupted preexisting metadata. In that case, a `mod_lock` flag is set in the database and the metadata of the original image is no longer allowed to be modified by the system until this flag has been removed. Clicking on the `red button with a crossed 'T' & padlock icon` will bulk remove *ALL* metadata from *ALL* original images that have the `mod_lock` flag set. Once the problematical metadata on an image has been deleted, the `mod_lock` flag is removed. Instigating this function should obviously be done with caution.
81+
- To restrict access to specific tags for specific usernames, log in to the Django admin dashboard (typically found at `http://your_api_domain.tld/admin`). After logging in, navigate to the `SPM_APP > Photo Tag` page. Once there, you may select tags and assign them to specific usernames.
82+
Note: the users would need to have already been created - however they should have *no* administrative privileges, nor be assigned to the `administrators` group, since there would otherwise be no point in providing access to specific tags, because users in the `administrators` group have read/write permissions on all records in any case. Non-administrator usernames have access to *only those tags which have been assigned to those usernames*.
83+
84+
## Installation (on Linux systems)
85+
86+
__Below are basic steps to install and run a demonstration of the app on an Linux Ubuntu 20.04 server. They do not provide for a secure installation, such as would be required if the app was publicly available. Steps should be taken to security harden the environment if using in production.__
87+
88+
### Brief installation instructions
89+
90+
- Clone repository to an app source directory of your choice, e.g. `git clone https://github.com/Aninstance/simple-photo-management-frontend.git`.
91+
- Make web root directory, e.g. `mkdir -p /var/www/html/spm-frontend`.
92+
- Move into the cloned directory and install the required node packages. Ensure a current version of NPM is installed and active on your system - it's recommended to install NVM (Node Version Manager) - which allows multiple node versions to be installed - to avoid changing a pre-installed version that may be required by other software or packages on your system.
93+
- Install npx on your system if not already installed, e.g.: `npm install -g npx`.
94+
- Change to the cloned app's directory, e.g.: `cd simple-photo-management-frontend;`.
95+
- Install the packages by running `npm install`.
96+
- Configure the app environment by coping the `.env.production_DEFAULT` file to `.env.production` and editing according to your requirements.
97+
- Build the app, e.g.: `npm run build:production`.
98+
- Copy the built app into its web directory, e.g. `cp -a build/. /var/www/html/spm-frontend/;` `cp -a /var/www/html/spm-frontend/static. /var/www/html/spm-frontend/;`.
99+
- Recursively change ownership of the `spm-frontend` directory to your web server user.
100+
- Configure your web server to serve the app from your web directory (this is straight forward, but outwith the scope of this document. If you need further help, please check your web server's documentation).
101+
102+
### Update Instructions
103+
104+
- Ensure you backup a copy of changes to your environment configuration - make a copy of your `.env.production` file *outside* of your cloned directory.
105+
- From the build directory, run `git pull`.
106+
- Run the commands `rm -rf node_modules` and `npm install --legacy-peer-deps` and `npm run build:production`.
107+
- Once the app has been built, copy to the web directory: `cp -a build/. /var/www/html/ssm-frontend/;` `cp -a /var/www/html/ssm-frontend/static/. /var/www/html/ssm-frontend/;`.
108+
- Recursively change ownership of the `ssm-frontend` directory to your web server user.
109+
- Restart your web server.
110+
111+
Note: The above guide is not definitive and is intended for users who know their way around Ubuntu server and Django.
112+
113+
*Users would need to arrange database backups and to secure the application appropriately when used in a production environment.*
114+
115+
## Development Roadmap
116+
117+
- ~~Automated display of tag suggestions (based on real-time character matching & most used) when adding IPTC tags to an image~~ [Complete]
118+
- Enhancement of `clean` to facilitate deletion of processed image files & thumbnails (rather just database entries) when origin image no longer exists
119+
- Tag suggestions based on facial recognition
120+
- Expose switching between `light` and `dark` modes on the UI rather than requiring setting of environment variable
121+
- ~~Remove tags from the used-tag list if no longer used for any images~~ [Complete]
122+
- ~~Add ability to delete tags after search (currently limited to replace with an alternative tag)~~ [Complete]
123+
124+
## Authors
125+
126+
- Dan Bright (Uplands Dynamic), dan@uplandsdynamic.com

react/.env.production_DEFAULT

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
REACT_APP_ROUTE = 'https://mydomain.tld'
2+
REACT_APP_API_ROUTE = 'https://mydomain.tld/api'
3+
REACT_APP_API_DATA_ROUTE = 'https://mydomain.tld/api/v2'
4+
REACT_APP_ORG_NAME = 'My Organisation Name'
5+
REACT_APP_SHORT_ORG_NAME = 'Org Name'
6+
REACT_APP_COPYRIGHT = 'Application developed by Uplands Dynamic, apps@uplandsdynamic.com'
7+
REACT_APP_FOOTER = 'My app footer'
8+
REACT_APP_NAME_TITLE = 'Simple Photo Management'
9+
REACT_APP_ROWS_PER_TABLE = 25
10+
REACT_APP_PAGER_MAIN_SIZE = 5
11+
REACT_APP_PAGER_END_SIZE = 3
12+
REACT_APP_VERSION = '0.6.8-beta'
13+
REACT_APP_THEME = 'DARK'

react/package.json

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{
2+
"author": "Dan Bright, productions@aninstance.com",
3+
"license": "GPLv3",
4+
"name": "simple-photo-management-react-frontend",
5+
"version": "1.0.8-beta",
6+
"private": true,
7+
"description": "React frontend for Django REST Simple Photo Management application",
8+
"main": "index.js",
9+
"dependencies": {
10+
"@fortawesome/fontawesome-svg-core": "*",
11+
"@fortawesome/free-brands-svg-icons": "*",
12+
"@fortawesome/free-regular-svg-icons": "*",
13+
"@fortawesome/free-solid-svg-icons": "*",
14+
"@fortawesome/react-fontawesome": "*",
15+
"acorn": "*",
16+
"axios": "*",
17+
"bootstrap": "*",
18+
"env-cmd": "*",
19+
"jquery": "*",
20+
"js-cookie": "*",
21+
"lodash.clonedeep": "*",
22+
"moment": "*",
23+
"moment-timezone": "*",
24+
"popper.js": "*",
25+
"react": "*",
26+
"react-app-polyfill": "*",
27+
"react-dom": "*",
28+
"react-markdown": "*",
29+
"react-modal": "*",
30+
"react-modal-image": "*",
31+
"react-router-dom": "*",
32+
"react-scripts": "*",
33+
"to": "*"
34+
},
35+
"scripts": {
36+
"analyze": "source-map-explorer build/static/js/main.*",
37+
"start": "HTTPS=false BROWSER=none react-scripts start",
38+
"build:dev": "env-cmd -f .env.dev react-scripts build",
39+
"build:production": "env-cmd -f .env.production react-scripts build",
40+
"test": "react-scripts test",
41+
"test:once": "CI=true react-scripts test",
42+
"test:debug": "react-scripts --inspect-brk test --runInBand",
43+
"eject": "react-scripts eject",
44+
"preinstall": "npx npm-force-resolutions"
45+
},
46+
"browserslist": [
47+
">0.2%",
48+
"not dead",
49+
"not ie <= 11",
50+
"not op_mini all"
51+
],
52+
"devDependencies": {
53+
"eslint-plugin-react": "^7.23.2"
54+
},
55+
"resolutions": {
56+
"minimist": "^1.2.5"
57+
}
58+
}

react/public/.htaccess

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Options -MultiViews
2+
RewriteEngine On
3+
RewriteCond %{REQUEST_FILENAME} !-f
4+
RewriteRule ^ index.html [QSA,L]

react/public/index.html

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="description" content="Simple Photo Management">
6+
<link rel="shortcut icon" href="%PUBLIC_URL%/favicons/favicon.ico">
7+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
8+
<meta name="theme-color" content="#000000">
9+
<!--
10+
manifest.json provides metadata used when your web app is added to the
11+
homescreen on Android. See https://developers.google.com/web/fundamentals/web-app-manifest/
12+
-->
13+
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
14+
<!--
15+
Notice the use of %PUBLIC_URL% in the tags above.
16+
It will be replaced with the URL of the `public` folder during the build.
17+
Only files inside the `public` folder can be referenced from the HTML.
18+
19+
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
20+
work correctly both with client-side routing and a non-root public URL.
21+
-->
22+
<title>Simple Photo Management</title>
23+
</head>
24+
<body>
25+
<noscript>
26+
You need to enable JavaScript to run this app.
27+
</noscript>
28+
<div id="root"></div>
29+
</body>
30+
</html>

react/public/manifest.json

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"short_name": "Simple Photo Management",
3+
"name": "Simple Photo Management App, by www.aninstance.com",
4+
"icons": [
5+
{
6+
"src": "favicon.ico",
7+
"sizes": "64x64 32x32 24x24 16x16",
8+
"type": "image/x-icon"
9+
}
10+
],
11+
"start_url": ".",
12+
"display": "standalone",
13+
"theme_color": "#000000",
14+
"background_color": "#000000"
15+
}

0 commit comments

Comments
 (0)