diff --git a/.gitignore b/.gitignore index 6f2c7bf..3b346be 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,9 @@ local/ share/ lib64 +uploads/ +thumbnails/ + config.toml __pycache__/ photos.db \ No newline at end of file diff --git a/app.py b/app.py index 407abb2..50b7279 100644 --- a/app.py +++ b/app.py @@ -74,7 +74,7 @@ scheduler.add_job(generate_all_thumbnails, 'date', run_date=datetime.now()) # R @app.route('/') def index(): - return render_template('index.html') + return render_template('index.html', accent_color=config['appearance']['accent_color']) @app.route('/api/images') def get_images(): @@ -116,7 +116,7 @@ def admin(): photos = db_session.query(Photo).order_by(Photo.date_taken.desc()).all() db_session.close() - return render_template('admin.html', photos=photos) + return render_template('admin.html', photos=photos, accent_color=config['appearance']['accent_color']) @app.route('/admin/login', methods=['GET', 'POST']) def admin_login(): @@ -126,7 +126,7 @@ def admin_login(): return redirect(url_for('admin')) else: flash('Invalid password') - return render_template('admin_login.html') + return render_template('admin_login.html', accent_color=config['appearance']['accent_color']) @app.route('/admin/upload', methods=['POST']) def admin_upload(): @@ -183,7 +183,7 @@ def admin_upload(): orientation=int(exif.get('Orientation', 1)), width=width, height=height, - highlight_color=get_highlight_color(THUMBNAIL_FOLDER + f"{os.path.splitext(filename)[0]}/256_{filename}") + highlight_color=get_highlight_color(THUMBNAIL_FOLDER + f"/{os.path.splitext(filename)[0]}/256_{filename}") ) db_session.add(new_photo) db_session.commit() diff --git a/config.py b/config.py index b929a5b..0c5b9a7 100644 --- a/config.py +++ b/config.py @@ -14,6 +14,9 @@ def load_or_create_config(): 'directories': { 'upload': 'uploads', 'thumbnail': 'thumbnails' + }, + 'appearance': { + 'accent_color': '{{ accent_color }}' } } with open(CONFIG_FILE, 'w') as f: diff --git a/templates/admin.html b/templates/admin.html index ae11af1..f54bde2 100644 --- a/templates/admin.html +++ b/templates/admin.html @@ -3,56 +3,146 @@ <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Admin Interface</title> + <title>Admin Interface - Tanishq Dubey Photography</title> + <link rel="preconnect" href="https://fonts.googleapis.com"> + <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> + <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Mono:wght@100..900&display=swap" rel="stylesheet"> <style> + body { + margin: 0; + padding: 0; + font-family: 'Noto Sans Mono', monospace; + background-color: #f0f0f0; + } + .container { + max-width: 1200px; + margin: 0 auto; + padding: 2rem; + } + h1 { + color: {{ accent_color }}; + margin-bottom: 1.5rem; + } + .upload-form { + background-color: #ffffff; + padding: 1rem; + border-radius: 8px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + margin-bottom: 2rem; + } + input[type="file"] { + margin-right: 1rem; + } + input[type="submit"] { + background-color: {{ accent_color }}; + color: white; + border: none; + padding: 0.5rem 1rem; + border-radius: 4px; + cursor: pointer; + font-family: inherit; + font-weight: bold; + } + input[type="submit"]:hover { + background-color: {{ accent_color }}e0; /* Slightly darker version of the accent color */ + } table { - border-collapse: collapse; width: 100%; + border-collapse: collapse; + background-color: #ffffff; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } th, td { - border: 1px solid #ddd; - padding: 8px; + padding: 0.75rem; text-align: left; + border-bottom: 1px solid #e0e0e0; } th { - background-color: #f2f2f2; + background-color: #f5f5f5; + font-weight: bold; + color: #333; + } + tr:hover { + background-color: #f9f9f9; + } + .thumbnail { + max-width: 100px; + max-height: 100px; + object-fit: cover; + } + .flash-messages { + margin-bottom: 1rem; + } + .flash-messages p { + background-color: #4CAF50; + color: white; + padding: 0.5rem; + border-radius: 4px; + } + .logout { + text-align: right; + margin-bottom: 1rem; + } + .logout a { + color: {{ accent_color }}; + text-decoration: none; + } + .logout a:hover { + text-decoration: underline; } </style> </head> <body> - <h1>Admin Interface</h1> - {% with messages = get_flashed_messages() %} - {% if messages %} - <ul> - {% for message in messages %} - <li>{{ message }}</li> + <div class="container"> + <div class="logout"> + <a href="{{ url_for('admin_logout') }}">Logout</a> + </div> + <h1>Admin Interface</h1> + {% with messages = get_flashed_messages() %} + {% if messages %} + <div class="flash-messages"> + {% for message in messages %} + <p>{{ message }}</p> + {% endfor %} + </div> + {% endif %} + {% endwith %} + <div class="upload-form"> + <h2>Upload New Image</h2> + <form action="{{ url_for('admin_upload') }}" method="POST" enctype="multipart/form-data"> + <input type="file" name="file" accept=".jpg,.jpeg,.png,.gif" required> + <input type="submit" value="Upload"> + </form> + </div> + <h2>Uploaded Images</h2> + <table> + <thead> + <tr> + <th>Thumbnail</th> + <th>Filename</th> + <th>Date Taken</th> + <th>Focal Length</th> + <th>Aperture</th> + <th>Shutter Speed</th> + <th>ISO</th> + <th>Dimensions</th> + </tr> + </thead> + <tbody> + {% for photo in photos %} + <tr> + <td><img src="{{ url_for('serve_thumbnail', filename=photo.thumbnail_filename) }}" alt="Thumbnail" class="thumbnail"></td> + <td>{{ photo.input_filename }}</td> + <td>{{ photo.date_taken.strftime('%Y-%m-%d %H:%M:%S') }}</td> + <td>{{ photo.focal_length }}</td> + <td>{{ photo.aperture }}</td> + <td>{{ photo.shutter_speed }}</td> + <td>{{ photo.iso }}</td> + <td>{{ photo.width }}x{{ photo.height }}</td> + </tr> {% endfor %} - </ul> - {% endif %} - {% endwith %} - <h2>Upload New Image</h2> - <form action="{{ url_for('admin_upload') }}" method="POST" enctype="multipart/form-data"> - <input type="file" name="file" accept=".jpg,.jpeg,.png,.gif" required> - <input type="submit" value="Upload"> - </form> - <h2>Uploaded Images</h2> - <table> - <tr> - <th>ID</th> - <th>Thumbnail</th> - <th>Filename</th> - <th>Date Taken</th> - <th>Technical Info</th> - </tr> - {% for photo in photos %} - <tr> - <td>{{ photo.id }}</td> - <td><img src="{{ url_for('static', filename='thumbnails/' + photo.thumbnail_filename) }}" alt="Thumbnail" width="100"></td> - <td>{{ photo.input_filename }}</td> - <td>{{ photo.date_taken.strftime('%Y-%m-%d %H:%M:%S') }}</td> - <td>{{ photo.focal_length }}mm f/{{ photo.aperture }} {{ photo.shutter_speed }}s ISO{{ photo.iso }}</td> - </tr> - {% endfor %} - </table> + </tbody> + </table> + </div> </body> </html> diff --git a/templates/admin_login.html b/templates/admin_login.html index fca4dac..a41adb8 100644 --- a/templates/admin_login.html +++ b/templates/admin_login.html @@ -3,22 +3,75 @@ <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Admin Login</title> + <title>Admin Login - Tanishq Dubey Photography</title> + <link rel="preconnect" href="https://fonts.googleapis.com"> + <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> + <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Mono:wght@100..900&display=swap" rel="stylesheet"> + <style> + body { + margin: 0; + padding: 0; + font-family: 'Noto Sans Mono', monospace; + background-color: #f0f0f0; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + } + .login-container { + background-color: #ffffff; + padding: 2rem; + border-radius: 8px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + text-align: center; + } + h1 { + color: {{ accent_color }}; + margin-bottom: 1.5rem; + } + input[type="password"] { + width: 100%; + padding: 0.5rem; + margin-bottom: 1rem; + border: 1px solid #ccc; + border-radius: 4px; + font-family: inherit; + } + input[type="submit"] { + background-color: {{ accent_color }}; + color: white; + border: none; + padding: 0.5rem 1rem; + border-radius: 4px; + cursor: pointer; + font-family: inherit; + font-weight: bold; + } + input[type="submit"]:hover { + background-color: #e55c00; + } + .flash-messages { + margin-bottom: 1rem; + color: #ff0000; + } + </style> </head> <body> - <h1>Admin Login</h1> - {% with messages = get_flashed_messages() %} - {% if messages %} - <ul> - {% for message in messages %} - <li>{{ message }}</li> - {% endfor %} - </ul> - {% endif %} - {% endwith %} - <form method="POST"> - <input type="password" name="password" required> - <input type="submit" value="Login"> - </form> + <div class="login-container"> + <h1>Admin Login</h1> + {% with messages = get_flashed_messages() %} + {% if messages %} + <div class="flash-messages"> + {% for message in messages %} + <p>{{ message }}</p> + {% endfor %} + </div> + {% endif %} + {% endwith %} + <form method="POST"> + <input type="password" name="password" required placeholder="Enter password"> + <input type="submit" value="Login"> + </form> + </div> </body> </html> diff --git a/templates/index.html b/templates/index.html index e4642d9..fda2ef6 100644 --- a/templates/index.html +++ b/templates/index.html @@ -55,13 +55,13 @@ position: absolute; bottom: 4rem; font-size: 1rem; - padding-right: 10px; - color: #ff6600; - padding: 2px 5px; + right: 1rem; + text-align: right; + color: #ec5a11; font-family: "Noto Sans Mono", monospace; font-size: 0.7rem; opacity: 0; - text-shadow: 0 0 2px #ff6600; + text-shadow: 0 0 2px #ec5a11; transition: opacity 0.3s ease; } @@ -121,7 +121,7 @@ } .sidebar-nav a { text-decoration: none; - color: #ff6600; + color: {{ accent_color }}; } @@ -149,12 +149,6 @@ height: auto; } } - - @media (min-width: 769px) and (max-width: 1024px) { - .grid-container { - grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); - } - } </style> </head> <body>