Compare commits

..

No commits in common. "cdf6f9fcfdd268c25cd8fd156368402a077721ca" and "82d6f6003f8a21d1d3b13829bfe809a0c8a97e78" have entirely different histories.

35 changed files with 64 additions and 108 deletions

View File

@ -5,8 +5,9 @@
!app
!migrations
!tests
!.flaskenv
!boot.sh
!config.py
!docker-nopaque-entrypoint.sh
!nopaque.py
!requirements.txt
!wsgi.py

1
.flaskenv Normal file
View File

@ -0,0 +1 @@
FLASK_APP=nopaque.py

View File

@ -46,7 +46,7 @@ COPY docker-nopaque-entrypoint.sh /usr/local/bin/
COPY --chown=nopaque:nopaque app app
COPY --chown=nopaque:nopaque migrations migrations
COPY --chown=nopaque:nopaque tests tests
COPY --chown=nopaque:nopaque boot.sh config.py wsgi.py requirements.txt ./
COPY --chown=nopaque:nopaque .flaskenv boot.sh config.py nopaque.py requirements.txt ./
RUN mkdir logs

View File

@ -33,9 +33,6 @@ scheduler = APScheduler()
socketio = SocketIO()
# TODO: Create export for lemmatized corpora
def create_app(config: Config = Config) -> Flask:
''' Creates an initialized Flask (WSGI Application) object. '''
app = Flask(__name__)

View File

@ -1,6 +1,6 @@
from flask import abort, request
from app.decorators import content_negotiation
from app import db
from app.decorators import content_negotiation
from app.models import User
from . import bp

View File

@ -9,12 +9,12 @@ from app.users.settings.forms import (
UpdateAccountInformationForm,
UpdateProfileInformationForm
)
from . import bp
from .forms import UpdateUserForm
from app.users.utils import (
user_endpoint_arguments_constructor as user_eac,
user_dynamic_list_constructor as user_dlc
)
from . import bp
from .forms import UpdateUserForm
@bp.route('')

View File

@ -5,8 +5,8 @@ from flask import abort, Blueprint
from werkzeug.exceptions import InternalServerError
from app import db, hashids
from app.models import Job, JobInput, JobStatus, TesseractOCRPipelineModel
from .auth import auth_error_responses, token_auth
from .schemas import EmptySchema, JobSchema, SpaCyNLPPipelineJobSchema, TesseractOCRPipelineJobSchema, TesseractOCRPipelineModelSchema
from .auth import auth_error_responses, token_auth
bp = Blueprint('jobs', __name__)

View File

@ -3,11 +3,11 @@ from apifairy import authenticate, body, response
from apifairy.decorators import other_responses
from flask import abort, Blueprint
from werkzeug.exceptions import InternalServerError
from app.email import create_message, send
from app import db
from app.email import create_message, send
from app.models import User
from .auth import auth_error_responses, token_auth
from .schemas import EmptySchema, UserSchema
from .auth import auth_error_responses, token_auth
bp = Blueprint('users', __name__)

View File

@ -4,7 +4,7 @@ from threading import Thread
from app import db
from app.decorators import content_negotiation, permission_required
from app.models import SpaCyNLPPipelineModel
from . import bp
from .. import bp
@bp.route('/spacy-nlp-pipeline-models/<hashid:spacy_nlp_pipeline_model_id>', methods=['DELETE'])

View File

@ -8,7 +8,9 @@ from .forms import (
CreateSpaCyNLPPipelineModelForm,
UpdateSpaCyNLPPipelineModelForm
)
from .utils import spacy_nlp_pipeline_model_dlc
from .utils import (
spacy_nlp_pipeline_model_dlc as spacy_nlp_pipeline_model_dlc
)
@bp.route('/spacy-nlp-pipeline-models')

View File

@ -8,7 +8,9 @@ from .forms import (
CreateTesseractOCRPipelineModelForm,
UpdateTesseractOCRPipelineModelForm
)
from .utils import tesseract_ocr_pipeline_model_dlc
from .utils import (
tesseract_ocr_pipeline_model_dlc as tesseract_ocr_pipeline_model_dlc
)
@bp.route('/tesseract-ocr-pipeline-models')

View File

@ -1,11 +1,11 @@
from datetime import datetime
from flask import current_app
from app import db
from app.models import User, Corpus, CorpusFile
from datetime import datetime
from pathlib import Path
from typing import Dict, List
import json
import shutil
from app import db
from app.models import User, Corpus, CorpusFile
class SandpaperConverter:

View File

@ -1,7 +1,7 @@
from flask import current_app
from flask import abort, current_app
from threading import Thread
from app.decorators import content_negotiation
from app import db
from app.decorators import content_negotiation
from app.models import CorpusFile
from ..decorators import corpus_follower_permission_required
from . import bp

View File

@ -1,5 +1,6 @@
from flask import request, url_for
from app.models import CorpusFile
from ..utils import corpus_endpoint_arguments_constructor as corpus_eac
def corpus_file_dynamic_list_constructor():

View File

@ -0,0 +1,2 @@
from .container_column import ContainerColumn
from .int_enum_column import IntEnumColumn

View File

@ -0,0 +1,21 @@
import json
from app import db
class ContainerColumn(db.TypeDecorator):
impl = db.String
def __init__(self, container_type, *args, **kwargs):
super().__init__(*args, **kwargs)
self.container_type = container_type
def process_bind_param(self, value, dialect):
if isinstance(value, self.container_type):
return json.dumps(value)
elif isinstance(value, str) and isinstance(json.loads(value), self.container_type):
return value
else:
return TypeError()
def process_result_value(self, value, dialect):
return json.loads(value)

View File

@ -1,26 +1,6 @@
import json
from app import db
class ContainerColumn(db.TypeDecorator):
impl = db.String
def __init__(self, container_type, *args, **kwargs):
super().__init__(*args, **kwargs)
self.container_type = container_type
def process_bind_param(self, value, dialect):
if isinstance(value, self.container_type):
return json.dumps(value)
elif isinstance(value, str) and isinstance(json.loads(value), self.container_type):
return value
else:
return TypeError()
def process_result_value(self, value, dialect):
return json.loads(value)
class IntEnumColumn(db.TypeDecorator):
impl = db.Integer

View File

@ -1 +0,0 @@

View File

@ -1,2 +0,0 @@
from .types import ContainerColumn
from .types import IntEnumColumn

View File

@ -9,7 +9,7 @@ import shutil
import xml.etree.ElementTree as ET
from app import db
from app.converters.vrt import normalize_vrt_file
from app.extensions.sqlalchemy import IntEnumColumn
from app.ext.flask_sqlalchemy import IntEnumColumn
from .corpus_follower_association import CorpusFollowerAssociation

View File

@ -7,7 +7,7 @@ from typing import Union
from pathlib import Path
import shutil
from app import db
from app.extensions.sqlalchemy import ContainerColumn, IntEnumColumn
from app.ext.flask_sqlalchemy import ContainerColumn, IntEnumColumn
class JobStatus(IntEnum):

View File

@ -5,7 +5,7 @@ from pathlib import Path
import requests
import yaml
from app import db
from app.extensions.sqlalchemy import ContainerColumn
from app.ext.flask_sqlalchemy import ContainerColumn
from .file_mixin import FileMixin
from .user import User

View File

@ -5,7 +5,7 @@ from pathlib import Path
import requests
import yaml
from app import db
from app.extensions.sqlalchemy import ContainerColumn
from app.ext.flask_sqlalchemy import ContainerColumn
from .file_mixin import FileMixin
from .user import User

View File

@ -12,7 +12,7 @@ import re
import secrets
import shutil
from app import db, hashids
from app.extensions.sqlalchemy import IntEnumColumn
from app.ext.flask_sqlalchemy import IntEnumColumn
from .corpus import Corpus
from .corpus_follower_association import CorpusFollowerAssociation
from .corpus_follower_role import CorpusFollowerRole

View File

@ -1,57 +0,0 @@
export class BaseForm {
constructor(formElement) {
this.element = formElement;
this.element.addEventListener('submit', (event) => {
event.preventDefault();
this.submit();
});
console.log("UsernamePostFormInitialized");
}
submit() {
let errorTextElements = this.element
.querySelectorAll('.supporting-text[data-supporting-text-type="error"]');
for (let errorTextElement of errorTextElements) {errorTextElement.remove();}
const body = new FormData(this.element);
const headers = {
'Accept': 'application/json',
'Content-Type': 'application/json'
};
const method = this.element.method;
const fetchPromise = new Promise((resolve, reject) => {
fetch(this.element.action, {body: body, headers: headers, method: method})
.then((response) => {
if (!response.ok) {
console.log("reject", response);
reject(response);
return;
}
console.log("resolve", response);
resolve(response);
});
});
fetchPromise
.then(
(response) => {console.log("Hello from resolve handler");return response.json();},
(response) => {
console.log("Hello from reject handler 1/2");
response.json()
.then((errors) => {
console.log("Hello from reject handler 2/2");
for (let [name, messages] of Object.entries(errors)) {
console.log(name, messages);
const inputFieldElement = this.element[name].closest('.input-field');
for (let message of messages) {
const messageHTML = `<span class="supporting-text" data-supporting-text-type="error">${message}</span>`;
inputFieldElement.insertAdjacentHTML('beforeend', messageHTML);
}
}
});
}
);
}
};

View File

@ -1,3 +1,4 @@
from flask_login import current_user
from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileRequired
from wtforms import (
@ -16,7 +17,7 @@ from wtforms.validators import (
Regexp
)
from app.models import User, UserSettingJobStatusMailNotificationLevel
from app.extensions.wtforms.validators import FileSize
from app.wtforms.validators import FileSize
class UpdateAccountInformationForm(FlaskForm):

View File

@ -24,7 +24,7 @@ if [[ "${#}" == "0" ]]; then
sleep 5
done
fi
python3 wsgi.py
python3 nopaque.py
elif [[ "${1}" == "flask" ]]; then
flask ${@:2}
elif [[ "${1}" == "--help" || "${1}" == "-h" ]]; then

View File

@ -1,3 +1,5 @@
version: "3.5"
# The docker-compose.yml file is not meant to be modified itself.
# Instead use the following files for configurations:
# - .env: Environment variables for the docker-compose.yml file.

View File

@ -1,3 +1,5 @@
version: "3.5"
services:
nopaque:
environment:
@ -11,6 +13,6 @@ services:
- "./config.py:/home/nopaque/config.py"
- "./docker-entrypoint.sh:/usr/local/bin/docker-entrypoint.sh"
- "./migrations:/home/nopaque/migrations"
- "./nopaque.py:/home/nopaque/nopaque.py"
- "./requirements.txt:/home/nopaque/requirements.txt"
- "./tests:/home/nopaque/tests"
- "./wsgi.py:/home/nopaque/wsgi.py"

View File

@ -1,3 +1,5 @@
version: "3.5"
services:
nopaque:
environment:

View File

@ -1,3 +1,5 @@
version: "3.5"
networks:
traefik:
external: true

View File

View File

@ -15,7 +15,7 @@ Flask-Marshmallow==0.14.0
Flask-Menu==0.7.2
Flask-Migrate
Flask-Paranoid
Flask-SocketIO==5.3.6
Flask-SocketIO
Flask-SQLAlchemy==2.5.1
Flask-WTF
hiredis