diff --git a/README.md b/README.md index 324ed05..0a56802 100644 --- a/README.md +++ b/README.md @@ -65,3 +65,14 @@ an Openshift Origin cluster. GALLERY_S3_BUCKET_ID = $s3BucketID GALLERY_S3_SECRET_KEY = $s3SecretKey ``` + +## Local Development +Below are instructions for running gallery locally. It assumes that you have already forked and cloned this repository onto your local machine. + +1. Change the line in `__init__.py` that sets the config file from `config.env.py` to `localconfig.env.py`. + +2. Get gallery dev secrets from an RTP and fill in `localconfig.env.py`. *DO NOT COMMIT THESE TO GIT* + +3. Run `pip install -r requirements.txt` + +4. Run `python3 wsgi.py` \ No newline at end of file diff --git a/gallery/__init__.py b/gallery/__init__.py index 8ea5fcc..18b737a 100644 --- a/gallery/__init__.py +++ b/gallery/__init__.py @@ -25,6 +25,7 @@ from flask import send_from_directory from flask import abort from flask_sqlalchemy import SQLAlchemy +from sqlalchemy import or_ from sqlalchemy.sql import func as sql_func from sqlalchemy.orm import load_only from flask_pyoidc.flask_pyoidc import OIDCAuthentication @@ -213,7 +214,7 @@ def upload_file(auth_dict: Optional[Dict[str, Any]] = None): upload_status['error'] = errors upload_status['success'] = success - refresh_thumbnail() + refresh_default_thumbnails() # actually redirect to URL # change from FORM post to AJAX maybe? return jsonify(upload_status) @@ -311,7 +312,7 @@ def api_mkdir( @app.cli.command() def refresh_thumbnails(): click.echo("Refreshing thumbnails") - refresh_thumbnail() + refresh_default_thumbnails() @app.cli.command() @@ -386,24 +387,25 @@ def add_file(file_name: str, path: str, dir_id: str, description: str, owner: st return file_model -def refresh_thumbnail(): - def refresh_thumbnail_helper(dir_model: Directory) -> str: - dir_children = [d for d in Directory.query.filter(Directory.parent == dir_model.id).all()] - file_children = [f for f in File.query.filter(File.parent == dir_model.id).all()] - for file in file_children: - if file.thumbnail_uuid != DEFAULT_THUMBNAIL_NAME: - return file.thumbnail_uuid - for d in dir_children: - if d.thumbnail_uuid != DEFAULT_THUMBNAIL_NAME: - return d.thumbnail_uuid - # WE HAVE TO GO DEEPER (inception noise) - for d in dir_children: - # TODO: Switch to iterative tree walk using a queue to avoid - # recursion issues with super large directory structures - return refresh_thumbnail_helper(d) - # No thumbnail found - return DEFAULT_THUMBNAIL_NAME - +def refresh_directory_thumbnail(dir_model: Directory) -> str: + dir_children = [d for d in Directory.query.filter(Directory.parent == dir_model.id).all()] + file_children = [f for f in File.query.filter(File.parent == dir_model.id).all()] + for file in file_children: + if file.thumbnail_uuid != DEFAULT_THUMBNAIL_NAME and not file.hidden: + return file.thumbnail_uuid + for d in dir_children: + if d.thumbnail_uuid != DEFAULT_THUMBNAIL_NAME: + return d.thumbnail_uuid + # WE HAVE TO GO DEEPER (inception noise) + for d in dir_children: + # TODO: Switch to iterative tree walk using a queue to avoid + # recursion issues with super large directory structures + return refresh_directory_thumbnail(d) + # No thumbnail found + return DEFAULT_THUMBNAIL_NAME + + +def refresh_default_thumbnails(): missing_thumbnails = File.query.filter(File.thumbnail_uuid == DEFAULT_THUMBNAIL_NAME).all() for file_model in missing_thumbnails: dir_path = get_full_dir_path(file_model.parent) @@ -416,7 +418,7 @@ def refresh_thumbnail_helper(dir_model: Directory) -> str: missing_thumbnails = Directory.query.filter(Directory.thumbnail_uuid == DEFAULT_THUMBNAIL_NAME).all() for dir_model in missing_thumbnails: - dir_model.thumbnail_uuid = refresh_thumbnail_helper(dir_model) + dir_model.thumbnail_uuid = refresh_directory_thumbnail(dir_model) db.session.flush() db.session.commit() db.session.refresh(dir_model) @@ -476,6 +478,13 @@ def hide_file(file_id: int, auth_dict: Optional[Dict[str, Any]] = None): return "Permission denied", 403 file_model.hidden = True + + # Remove image from thumbnails + dirs = Directory.query.filter(or_(Directory.thumbnail_uuid == file_model.thumbnail_uuid, \ + Directory.thumbnail_uuid == file_model.thumbnail_uuid[:-4])) + for d in dirs: + d.thumbnail_uuid = refresh_directory_thumbnail(d) + db.session.flush() db.session.commit() @@ -497,6 +506,12 @@ def show_file(file_id: int, auth_dict: Optional[Dict[str, Any]] = None): return "Permission denied", 403 file_model.hidden = False + + # Add image as directory thumbnail + parent_model = Directory.query.filter(Directory.id == file_model.parent).first() + if parent_model.thumbnail_uuid == DEFAULT_THUMBNAIL_NAME: + parent_model.thumbnail_uuid = refresh_directory_thumbnail(parent_model) + db.session.flush() db.session.commit() diff --git a/gallery/static/js/gallery.js b/gallery/static/js/gallery.js index b4b44a4..9bcbb79 100644 --- a/gallery/static/js/gallery.js +++ b/gallery/static/js/gallery.js @@ -252,7 +252,7 @@ function hideFile() { function showFile() { $('#show').modal('show'); - $('#show button[id^="hide"]').click(function(e) { + $('#show button[id^="show"]').click(function(e) { e.preventDefault(); var this_id = $('#show button[id^="show"]').attr('id').substr($('#show button[id^="show"]').attr('id').indexOf("-") + 1); $.ajax({ diff --git a/localconfig.env.py b/localconfig.env.py new file mode 100644 index 0000000..8cf7bfc --- /dev/null +++ b/localconfig.env.py @@ -0,0 +1,29 @@ +import os + +# Flask config +DEBUG=False +IP=os.environ.get('GALLERY_IP', 'localhost') +PORT=os.environ.get('GALLERY_PORT', '6969') +SERVER_NAME = os.environ.get('GALLERY_SERVER_NAME', 'localhost:6969') +SECRET_KEY = os.environ.get('GALLERY_SECRET_KEY', '') + +# LDAP config +LDAP_URL=os.environ.get('GALLERY_LDAP_URL', 'ldaps://ldap.csh.rit.edu:636') +LDAP_BIND_DN=os.environ.get('GALLERY_LDAP_BIND_DN', '') +LDAP_BIND_PW=os.environ.get('GALLERY_LDAP_BIND_PW', '') +LDAP_USER_OU=os.environ.get('GALLERY_LDAP_USER_OU', 'ou=Users,dc=csh,dc=rit,dc=edu') + +# OpenID Connect SSO config +OIDC_ISSUER = os.environ.get('GALLERY_OIDC_ISSUER', 'https://sso.csh.rit.edu/auth/realms/csh') +OIDC_CLIENT_ID = os.environ.get('GALLERY_OIDC_CLIENT_ID', 'gallery-dev') +OIDC_CLIENT_SECRET = os.environ.get('GALLERY_OIDC_CLIENT_SECRET', '') + +SQLALCHEMY_DATABASE_URI = os.environ.get( + 'GALLERY_DATABASE_URI', + 'postgresql://gallery:undergrowth7803824=exhibitionist@postgres.csh.rit.edu/gallery-dev') +SQLALCHEMY_TRACK_MODIFICATIONS = False + +S3_URI = os.environ.get('GALLERY_S3_URI', 'https://s3.csh.rit.edu') +S3_ACCESS_ID = os.environ.get('GALLERY_S3_ACCESS_ID','') +S3_SECRET_KEY = os.environ.get('GALLERY_S3_SECRET_KEY','') +S3_BUCKET_ID = os.environ.get('GALLERY_S3_BUCKET_ID','gallery-dev') diff --git a/requirements.txt b/requirements.txt index de06ac5..aae44a7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ Flask==1.0.2 Flask-pyoidc==2.0.0 -csh_ldap==2.1.1 +csh_ldap~=2.2.0 addict==2.2.0 flask_sqlalchemy==2.3.2 flask_migrate==2.3.1