removed unused files
This commit is contained in:
-52
@@ -1,52 +0,0 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from dotenv import load_dotenv
|
||||
|
||||
from src.web import app
|
||||
|
||||
# prepare optional local setup
|
||||
env_path = Path(__file__).parent.parent / 'local.env'
|
||||
load_dotenv(env_path)
|
||||
|
||||
# ensure env vars set
|
||||
necesasary_var_list = {
|
||||
'MONGO_HOST',
|
||||
'MONGO_DB',
|
||||
'MONGO_COLLECTION',
|
||||
'MONGO_USER',
|
||||
'MONGO_PASSWORD',
|
||||
'DASH_AUTH_USERNAME',
|
||||
'DASH_AUTH_PASSWORD',
|
||||
}
|
||||
for env_var in necesasary_var_list:
|
||||
# ensure env var set
|
||||
assert (
|
||||
env_var in os.environ
|
||||
), (
|
||||
f"environment variable not set: {env_var}"
|
||||
)
|
||||
|
||||
# setup logging stream handler
|
||||
fmt = (
|
||||
'%(asctime)s | '
|
||||
'%(levelname)s | '
|
||||
'%(filename)s | '
|
||||
'%(funcName)s | '
|
||||
'%(message)s'
|
||||
)
|
||||
datefmt = '%Y-%m-%d %H:%M:%S'
|
||||
logging.basicConfig(format=fmt, datefmt=datefmt, level=logging.INFO)
|
||||
|
||||
logging.info('initialized app')
|
||||
server = app.server
|
||||
|
||||
if __name__ == '__main__':
|
||||
# prepare local env vars
|
||||
os.environ['MONGO_HOST'] = 'localhost'
|
||||
# run app
|
||||
app.run(debug=True)
|
||||
logging.info('started app')
|
||||
@@ -1 +0,0 @@
|
||||
from .classes import VisualSyntaxModelOutput
|
||||
@@ -1,89 +0,0 @@
|
||||
from pydantic import BaseModel, ValidationError
|
||||
from typing import List
|
||||
import random
|
||||
|
||||
|
||||
class OptionNotSetException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class ModelOutput(BaseModel):
|
||||
|
||||
@classmethod
|
||||
def classname(cls) -> str:
|
||||
"""Return classname."""
|
||||
return cls.__name__
|
||||
|
||||
@classmethod
|
||||
def list_fields(cls) -> List[str]:
|
||||
"""List options that are stored as attributes."""
|
||||
return list(cls.model_fields.keys())
|
||||
|
||||
@classmethod
|
||||
def from_random(cls):
|
||||
"""Instantiate with random numbers."""
|
||||
kwargs = {field: random.random() for field in cls.list_fields()}
|
||||
return cls(**kwargs)
|
||||
|
||||
@classmethod
|
||||
def from_choice(cls, option: str):
|
||||
"""Instantiate from choice."""
|
||||
if option is None:
|
||||
raise ValidationError()
|
||||
assert isinstance(option, str), "option is not a string"
|
||||
allowed_options_list = cls.list_fields()
|
||||
assert option in allowed_options_list, \
|
||||
f"{option} is not among allowed fields {allowed_options_list}"
|
||||
kwargs = {field: 0 for field in cls.list_fields()}
|
||||
kwargs[option] = 1
|
||||
return cls(**kwargs)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
model_dict = self.model_dump()
|
||||
model_repr_str = f"{self.classname()}("
|
||||
model_repr_str += ", ".join([
|
||||
f"{field}={value:.3f}"
|
||||
for field, value
|
||||
in model_dict.items()
|
||||
])
|
||||
model_repr_str += ")"
|
||||
return model_repr_str
|
||||
|
||||
def highest_score_field(self) -> str:
|
||||
"""Return name of field with highest score."""
|
||||
model_dict = self.model_dump()
|
||||
return max(model_dict, key=lambda k: model_dict[k])
|
||||
|
||||
def highest_score_value(self) -> float:
|
||||
"""Return value of field with highest score."""
|
||||
model_dict = self.model_dump()
|
||||
return max(model_dict.values())
|
||||
|
||||
|
||||
class VisualSyntaxModelOutput(ModelOutput):
|
||||
non_transactional_action: float
|
||||
non_transactional_reaction: float
|
||||
unidirectional_transactional_action: float
|
||||
unidirectional_transactional_reaction: float
|
||||
bidirectional_transactional_action: float
|
||||
bidirectional_transactional_reaction: float
|
||||
conversion: float
|
||||
speech_process: float
|
||||
classification_overt_taxonomy: float
|
||||
analytical_exhaustive: float
|
||||
analytical_disarranged: float
|
||||
analytical_temporal: float
|
||||
analytical_distributed: float
|
||||
analytical_topological: float
|
||||
analytical_exploded: float
|
||||
analytical_inclusive: float
|
||||
symbolic_suggestive: float
|
||||
symbolic_attributive: float
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
m = VisualSyntaxModelOutput.from_random()
|
||||
print(m)
|
||||
print(repr(m))
|
||||
print(m.highest_score_field())
|
||||
print(m.highest_score_value())
|
||||
@@ -1,20 +0,0 @@
|
||||
CLASS_NAMES = [
|
||||
"non transactional action",
|
||||
"non transactional reaction",
|
||||
"unidirectional transactional action",
|
||||
"unidirectional transactional reaction",
|
||||
"bidirectional transactional action",
|
||||
"bidirectional transactional reaction",
|
||||
"conversion",
|
||||
"speech process",
|
||||
"classification overt taxonomy",
|
||||
"analytical exhaustive",
|
||||
"analytical disarranged",
|
||||
"analytical temporal",
|
||||
"analytical distributed",
|
||||
"anaytical topological",
|
||||
"analytical exploded",
|
||||
"analytical inclusive",
|
||||
"symbolic suggestive",
|
||||
"symbolic attributive"
|
||||
]
|
||||
@@ -1,9 +0,0 @@
|
||||
from .classes import (
|
||||
ContactModelOutput,
|
||||
AngleModelOutput,
|
||||
PointOfViewModelOutput,
|
||||
DistanceModelOutput,
|
||||
ModalityLightingModelOutput,
|
||||
ModalityColorModelOutput,
|
||||
ModalityDepthModelOutput
|
||||
)
|
||||
@@ -1,137 +0,0 @@
|
||||
from pydantic import BaseModel, ValidationError
|
||||
from typing import List
|
||||
import random
|
||||
|
||||
|
||||
class ModelOutput(BaseModel):
|
||||
|
||||
@classmethod
|
||||
def classname(cls) -> str:
|
||||
"""Return classname."""
|
||||
return cls.__name__
|
||||
|
||||
@classmethod
|
||||
def list_fields(cls) -> List[str]:
|
||||
"""List options that are stored as attributes."""
|
||||
return list(cls.model_fields.keys())
|
||||
|
||||
@classmethod
|
||||
def from_random(cls):
|
||||
"""Instantiate with random numbers."""
|
||||
kwargs = {field: random.random() for field in cls.list_fields()}
|
||||
return cls(**kwargs)
|
||||
|
||||
@classmethod
|
||||
def from_choice(cls, option: str):
|
||||
"""Instantiate from choice."""
|
||||
if option is None:
|
||||
raise ValidationError()
|
||||
assert isinstance(option, str)
|
||||
allowed_options_list = cls.list_fields()
|
||||
assert option in allowed_options_list, \
|
||||
f"{option} is not among allowed fields {allowed_options_list}"
|
||||
kwargs = {field: 0 for field in cls.list_fields()}
|
||||
kwargs[option] = 1
|
||||
return cls(**kwargs)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
model_dict = self.model_dump()
|
||||
model_repr_str = f"{self.classname()}("
|
||||
model_repr_str += ", ".join([
|
||||
f"{field}={value:.3f}"
|
||||
for field, value
|
||||
in model_dict.items()
|
||||
])
|
||||
model_repr_str += ")"
|
||||
return model_repr_str
|
||||
|
||||
def highest_score_field(self) -> str:
|
||||
"""Return name of field with highest score."""
|
||||
model_dict = self.model_dump()
|
||||
return max(model_dict, key=lambda k: model_dict[k])
|
||||
|
||||
def highest_score_value(self) -> float:
|
||||
"""Return value of field with highest score."""
|
||||
model_dict = self.model_dump()
|
||||
return max(model_dict.values())
|
||||
|
||||
|
||||
class ContactModelOutput(ModelOutput):
|
||||
offer: float
|
||||
demand: float
|
||||
|
||||
|
||||
class AngleModelOutput(ModelOutput):
|
||||
high: float
|
||||
eye_level: float
|
||||
low: float
|
||||
|
||||
|
||||
class PointOfViewModelOutput(ModelOutput):
|
||||
frontal: float
|
||||
oblique: float
|
||||
|
||||
|
||||
class DistanceModelOutput(ModelOutput):
|
||||
long: float
|
||||
medium: float
|
||||
close: float
|
||||
|
||||
|
||||
class ModalityLightingModelOutput(ModelOutput):
|
||||
high: float
|
||||
medium: float
|
||||
low: float
|
||||
|
||||
|
||||
class ModalityColorModelOutput(ModelOutput):
|
||||
high: float
|
||||
medium: float
|
||||
low: float
|
||||
|
||||
|
||||
class ModalityDepthModelOutput(ModelOutput):
|
||||
high: float
|
||||
medium: float
|
||||
low: float
|
||||
|
||||
|
||||
# class InterpersonalModelOutput(BaseModel):
|
||||
# contact: ContactModelOutput
|
||||
# angle: AngleModelOutput
|
||||
# point_of_view: PointOfViewModelOutput
|
||||
# distance: DistanceModelOutput
|
||||
# modality_lighting: ModalityLightingModelOutput
|
||||
# modality_color: ModalityColorModelOutput
|
||||
# modality_depth: ModalityDepthModelOutput
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
m = ContactModelOutput.from_random()
|
||||
print(repr(m))
|
||||
print(m.highest_score_field())
|
||||
print(m.highest_score_value())
|
||||
m = AngleModelOutput.from_random()
|
||||
print(repr(m))
|
||||
print(m.highest_score_field())
|
||||
print(m.highest_score_value())
|
||||
m = PointOfViewModelOutput.from_random()
|
||||
print(repr(m))
|
||||
print(m.highest_score_field())
|
||||
print(m.highest_score_value())
|
||||
m = DistanceModelOutput.from_random()
|
||||
print(repr(m))
|
||||
print(m.highest_score_field())
|
||||
print(m.highest_score_value())
|
||||
m = ModalityLightingModelOutput.from_random()
|
||||
print(repr(m))
|
||||
print(m.highest_score_field())
|
||||
print(m.highest_score_value())
|
||||
m = ModalityColorModelOutput.from_random()
|
||||
print(repr(m))
|
||||
print(m.highest_score_field())
|
||||
print(m.highest_score_value())
|
||||
m = ModalityDepthModelOutput.from_random()
|
||||
print(repr(m))
|
||||
print(m.highest_score_field())
|
||||
print(m.highest_score_value())
|
||||
@@ -1,36 +0,0 @@
|
||||
|
||||
model_labels = {
|
||||
"contact": [
|
||||
"offer",
|
||||
"demand"
|
||||
],
|
||||
"angle": [
|
||||
"high",
|
||||
"eye-level",
|
||||
"low"
|
||||
],
|
||||
"point-of-view": [
|
||||
"frontal",
|
||||
"oblique"
|
||||
],
|
||||
"distance": [
|
||||
"long",
|
||||
"medium",
|
||||
"close"
|
||||
],
|
||||
"modality lighting": [
|
||||
"high",
|
||||
"medium",
|
||||
"low"
|
||||
],
|
||||
"modality color": [
|
||||
"high",
|
||||
"medium",
|
||||
"low"
|
||||
],
|
||||
"modality depth": [
|
||||
"high",
|
||||
"medium",
|
||||
"low"
|
||||
]
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
from .classes import (
|
||||
InformationValueModelOutput,
|
||||
FramingModelOutput,
|
||||
SalienceModelOutput
|
||||
)
|
||||
@@ -1,92 +0,0 @@
|
||||
from pydantic import BaseModel, ValidationError
|
||||
from typing import List
|
||||
import random
|
||||
|
||||
|
||||
class ModelOutput(BaseModel):
|
||||
|
||||
@classmethod
|
||||
def classname(cls) -> str:
|
||||
"""Return classname."""
|
||||
return cls.__name__
|
||||
|
||||
@classmethod
|
||||
def list_fields(cls) -> List[str]:
|
||||
"""List options that are stored as attributes."""
|
||||
return list(cls.model_fields.keys())
|
||||
|
||||
@classmethod
|
||||
def from_random(cls):
|
||||
"""Instantiate with random numbers."""
|
||||
kwargs = {field: random.random() for field in cls.list_fields()}
|
||||
return cls(**kwargs)
|
||||
|
||||
@classmethod
|
||||
def from_choice(cls, option: str):
|
||||
"""Instantiate from choice."""
|
||||
if option is None:
|
||||
raise ValidationError()
|
||||
assert isinstance(option, str)
|
||||
allowed_options_list = cls.list_fields()
|
||||
assert option in allowed_options_list, \
|
||||
f"{option} is not among allowed fields {allowed_options_list}"
|
||||
kwargs = {field: 0 for field in cls.list_fields()}
|
||||
kwargs[option] = 1
|
||||
return cls(**kwargs)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
model_dict = self.model_dump()
|
||||
model_repr_str = f"{self.classname()}("
|
||||
model_repr_str += ", ".join([
|
||||
f"{field}={value:.3f}"
|
||||
for field, value
|
||||
in model_dict.items()
|
||||
])
|
||||
model_repr_str += ")"
|
||||
return model_repr_str
|
||||
|
||||
def highest_score_field(self) -> str:
|
||||
"""Return name of field with highest score."""
|
||||
model_dict = self.model_dump()
|
||||
return max(model_dict, key=lambda k: model_dict[k])
|
||||
|
||||
def highest_score_value(self) -> float:
|
||||
"""Return value of field with highest score."""
|
||||
model_dict = self.model_dump()
|
||||
return max(model_dict.values())
|
||||
|
||||
|
||||
class InformationValueModelOutput(ModelOutput):
|
||||
given_new: float
|
||||
ideal_real: float
|
||||
central_marginal: float
|
||||
|
||||
|
||||
class FramingModelOutput(ModelOutput):
|
||||
frame_lines: float
|
||||
empty_space: float
|
||||
colour_contrast: float
|
||||
form_contrast: float
|
||||
|
||||
|
||||
class SalienceModelOutput(ModelOutput):
|
||||
size: float
|
||||
colour: float
|
||||
tone: float
|
||||
form: float
|
||||
positioning: float
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
m = InformationValueModelOutput.from_random()
|
||||
print(repr(m))
|
||||
print(m.highest_score_field())
|
||||
print(m.highest_score_value())
|
||||
m = FramingModelOutput.from_random()
|
||||
print(repr(m))
|
||||
print(m.highest_score_field())
|
||||
print(m.highest_score_value())
|
||||
m = SalienceModelOutput.from_random()
|
||||
print(repr(m))
|
||||
print(m.highest_score_field())
|
||||
print(m.highest_score_value())
|
||||
@@ -1,21 +0,0 @@
|
||||
|
||||
model_labels = {
|
||||
"information value": [
|
||||
"given-new",
|
||||
"ideal-real",
|
||||
"central-marginal"
|
||||
],
|
||||
"framing": [
|
||||
"frame lines",
|
||||
"empty space",
|
||||
"colour contrast",
|
||||
"form contrast"
|
||||
],
|
||||
"salience": [
|
||||
"size",
|
||||
"colour",
|
||||
"tone",
|
||||
"form",
|
||||
"positioning"
|
||||
]
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from src.web.app import app
|
||||
from src.web.app import server
|
||||
-247
@@ -1,247 +0,0 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
||||
import dash_bootstrap_components as dbc
|
||||
from dash import ALL
|
||||
from dash import Dash
|
||||
from dash import Input
|
||||
from dash import Output
|
||||
from dash import State
|
||||
from dash_auth import BasicAuth
|
||||
from pydantic import ValidationError
|
||||
|
||||
from .layout import app_layout
|
||||
from core.database import connect
|
||||
from core.database import count_documents
|
||||
from core.database import get_visual_communication
|
||||
from core.database import NoDocumentFoundException
|
||||
from core.database import upsert_annotation
|
||||
from core.database import upsert_visual_communication
|
||||
from core.database import VisualCommunication
|
||||
from core.dto import ModelData
|
||||
|
||||
# setup app
|
||||
app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
|
||||
app.title = 'visual critical discourse analysis'.title()
|
||||
app.layout = app_layout
|
||||
server = app.server
|
||||
|
||||
# setup authentication
|
||||
AUTH_DICT = {
|
||||
os.getenv('DASH_AUTH_USERNAME'): os.getenv('DASH_AUTH_PASSWORD'),
|
||||
}
|
||||
BasicAuth(app, AUTH_DICT)
|
||||
|
||||
# connect to database
|
||||
collection, db, client = connect()
|
||||
|
||||
|
||||
# define callbacks
|
||||
@app.callback(
|
||||
Output('alert-element', 'is_open'),
|
||||
Output('alert-element', 'children'),
|
||||
Input('alert-message', 'data'),
|
||||
)
|
||||
def show_alert(
|
||||
msg: str | None,
|
||||
):
|
||||
if msg is None or msg == '':
|
||||
return False, ''
|
||||
logging.info(f'updated alert message: {msg}')
|
||||
return True, msg
|
||||
|
||||
|
||||
@app.callback(
|
||||
Output('success-element', 'is_open'),
|
||||
Output('success-element', 'children'),
|
||||
Input('success-message', 'data'),
|
||||
)
|
||||
def show_success(
|
||||
msg: str | None,
|
||||
):
|
||||
if msg is None or msg == '':
|
||||
return False, ''
|
||||
logging.info(f"updated success message: {msg}")
|
||||
return True, msg
|
||||
|
||||
|
||||
@app.callback(
|
||||
Output('progress-bar', 'value'),
|
||||
Output('progress-bar', 'max'),
|
||||
Output('progress-bar', 'label'),
|
||||
Input('next-button', 'n_clicks'),
|
||||
Input('upload-data', 'filename'),
|
||||
)
|
||||
def update_progress_bar(
|
||||
n_clicks: int,
|
||||
filename_list: list[str] | None,
|
||||
):
|
||||
logging.info('began updating progress bar')
|
||||
global collection
|
||||
# get values from database
|
||||
num_total = count_documents(
|
||||
collection=collection,
|
||||
only_with_annotation=False,
|
||||
)
|
||||
num_handled = count_documents(
|
||||
collection=collection,
|
||||
only_with_annotation=True,
|
||||
)
|
||||
limit = int(num_total/20)
|
||||
label_str = f"{num_handled}/{num_total}" if num_handled >= limit else ''
|
||||
return num_handled, num_total, label_str
|
||||
|
||||
|
||||
@app.callback(
|
||||
Output('success-message', 'data', allow_duplicate=True),
|
||||
Output('alert-message', 'data', allow_duplicate=True),
|
||||
Input('upload-data', 'contents'),
|
||||
State('upload-data', 'filename'),
|
||||
prevent_initial_call=True,
|
||||
)
|
||||
def upload_images(
|
||||
content_list: list[str] | None,
|
||||
filename_list: list[str] | None,
|
||||
):
|
||||
logging.info('began uploading images')
|
||||
global collection
|
||||
# stop early if possible
|
||||
if content_list is None or filename_list is None:
|
||||
logging.warning('content_list is None -> nothing to upload')
|
||||
return None, 'nothing selected to upload'.title()
|
||||
# build list of visual communication
|
||||
visual_communication_list = []
|
||||
for content, filename in zip(content_list, filename_list):
|
||||
try:
|
||||
image = VisualCommunication.decode_image(content)
|
||||
vis_com = VisualCommunication(
|
||||
name=filename,
|
||||
image=image,
|
||||
)
|
||||
except Exception as exc:
|
||||
logging.warning(
|
||||
(
|
||||
'failed creating VisualCommunication object '
|
||||
f"from file {filename}"
|
||||
),
|
||||
exc,
|
||||
)
|
||||
else:
|
||||
visual_communication_list.append(vis_com)
|
||||
# upsert documents
|
||||
success = upsert_visual_communication(
|
||||
collection=collection,
|
||||
visual_communication_list=visual_communication_list,
|
||||
)
|
||||
if success:
|
||||
logging.info(f"succesfully uploaded {len(filename_list)} images")
|
||||
return 'successfully uploaded images'.title(), None
|
||||
logging.warning('failed inserting images into database')
|
||||
return None, 'failed uploading images'.title()
|
||||
|
||||
|
||||
@app.callback(
|
||||
Output('alert-message', 'data', allow_duplicate=True),
|
||||
Output('vis-com-name', 'data'),
|
||||
Output('image-container', 'src'),
|
||||
Output({'type': 'annotation', 'index': ALL}, 'value'),
|
||||
Input('next-button', 'n_clicks'),
|
||||
State('vis-com-name', 'data'),
|
||||
State('image-container', 'src'),
|
||||
State({'type': 'annotation', 'index': ALL}, 'id'),
|
||||
State({'type': 'annotation', 'index': ALL}, 'value'),
|
||||
prevent_initial_call=True,
|
||||
)
|
||||
def cycle_visual_communication_data(
|
||||
n_clicks: int,
|
||||
vis_com_name: str,
|
||||
image_src: str,
|
||||
annotation_keys: list,
|
||||
annotation_values: list,
|
||||
):
|
||||
logging.info('began cycling visual communication data')
|
||||
global collection
|
||||
# prepare default response
|
||||
response = [
|
||||
'',
|
||||
vis_com_name,
|
||||
image_src,
|
||||
annotation_values,
|
||||
]
|
||||
# check if next-button clicked
|
||||
if n_clicks == 0:
|
||||
logging.info('stopping early: next-button has not yet been clicked')
|
||||
return response
|
||||
# check if visual communication name is set
|
||||
if len(vis_com_name) > 0:
|
||||
logging.info('saving annotations to database: %s', vis_com_name)
|
||||
try:
|
||||
# extract option keys
|
||||
annotation_keys = [
|
||||
elem['index']
|
||||
for elem in annotation_keys
|
||||
]
|
||||
# ensure all options are set
|
||||
logging.info(annotation_keys)
|
||||
for option, value in zip(annotation_keys, annotation_values):
|
||||
if value is None:
|
||||
raise ValueError(f"{option} is not set")
|
||||
# prepare data to save
|
||||
annotation_keys = [
|
||||
elem.replace(' ', '_')
|
||||
for elem
|
||||
in annotation_keys
|
||||
]
|
||||
annotation_values = [
|
||||
elem.replace(' ', '_').lower()
|
||||
for elem
|
||||
in annotation_values
|
||||
]
|
||||
annotation_map = {
|
||||
key: value
|
||||
for key, value
|
||||
in zip(annotation_keys, annotation_values)
|
||||
}
|
||||
# instantiate ModelOutputs object
|
||||
annotations = ModelData.from_annotations(**annotation_map)
|
||||
# save data to database
|
||||
upsert_annotation(
|
||||
collection=collection,
|
||||
vis_com_name=vis_com_name,
|
||||
annotations=annotations,
|
||||
)
|
||||
except (ValueError, ValidationError) as exc:
|
||||
msg = f"failed saving annotation: {exc}"
|
||||
logging.warning(msg)
|
||||
response[0] = msg
|
||||
return tuple(response)
|
||||
# get new visual communication
|
||||
logging.info('trying to get new visual communication')
|
||||
try:
|
||||
# get data
|
||||
vis_com = get_visual_communication(
|
||||
collection=collection,
|
||||
with_annotation=False,
|
||||
)
|
||||
# set variables
|
||||
vis_com_name = vis_com.name
|
||||
image_src = vis_com.webencoded_image()
|
||||
if vis_com.prediction is not None:
|
||||
# TODO: update to use optional predictions
|
||||
pass
|
||||
else:
|
||||
# reset annotations
|
||||
annotation_values = [None for elem in annotation_values]
|
||||
except NoDocumentFoundException:
|
||||
msg = 'no unannotated data in database'
|
||||
logging.warning(msg)
|
||||
response[0] = msg
|
||||
return tuple(response)
|
||||
else:
|
||||
response[1] = vis_com_name
|
||||
response[2] = image_src
|
||||
response[3] = annotation_values
|
||||
logging.info('finished getting visual communication: %s', vis_com_name)
|
||||
return tuple(response)
|
||||
@@ -1 +0,0 @@
|
||||
from .layout import app_layout
|
||||
@@ -1,23 +0,0 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import dash_bootstrap_components as dbc
|
||||
from dash import html
|
||||
|
||||
|
||||
alerts_element = html.Div(
|
||||
children=[
|
||||
dbc.Alert(
|
||||
children='',
|
||||
id='alert-element',
|
||||
dismissable=True,
|
||||
fade=False,
|
||||
is_open=False,
|
||||
),
|
||||
dbc.Alert(
|
||||
children='',
|
||||
id='success-element',
|
||||
is_open=False,
|
||||
duration=1000,
|
||||
),
|
||||
],
|
||||
)
|
||||
@@ -1,18 +0,0 @@
|
||||
import dash_mantine_components as dmc
|
||||
|
||||
from .image import image_element
|
||||
from .inputs import inputs_element
|
||||
|
||||
|
||||
body_element = dmc.Container(
|
||||
fluid=True,
|
||||
children=[
|
||||
dmc.Grid(
|
||||
grow=True,
|
||||
children=[
|
||||
dmc.Col([image_element], span=5),
|
||||
dmc.Col([inputs_element], span=7)
|
||||
],
|
||||
)
|
||||
],
|
||||
)
|
||||
@@ -1,62 +0,0 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import dash_bootstrap_components as dbc
|
||||
import dash_mantine_components as dmc
|
||||
from dash import dcc
|
||||
from dash import html
|
||||
|
||||
title_element = dmc.Center(
|
||||
children=[
|
||||
html.H2(
|
||||
children=[
|
||||
'Visual Critical Discourse Analysis Tool',
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
progress_bar_element = dbc.Progress(
|
||||
id='progress-bar',
|
||||
max=100,
|
||||
value=0,
|
||||
color='lime',
|
||||
label='',
|
||||
style={
|
||||
'width': '400px',
|
||||
},
|
||||
)
|
||||
|
||||
upload_button_element = dcc.Upload(
|
||||
children=[
|
||||
dmc.Button(
|
||||
'upload images'.title(),
|
||||
id='upload-button',
|
||||
color='lime',
|
||||
n_clicks=0,
|
||||
variant='outline',
|
||||
radius='sm',
|
||||
size='md',
|
||||
),
|
||||
],
|
||||
multiple=True,
|
||||
id='upload-data',
|
||||
accept='image/png,image/jpeg,image/jpg',
|
||||
)
|
||||
|
||||
header_element = dmc.Header(
|
||||
height=80,
|
||||
children=[
|
||||
dmc.Group(
|
||||
children=[
|
||||
title_element,
|
||||
progress_bar_element,
|
||||
upload_button_element,
|
||||
],
|
||||
position='apart',
|
||||
style={
|
||||
'margin': '10px',
|
||||
'padding': '10px',
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
@@ -1,21 +0,0 @@
|
||||
import dash_mantine_components as dmc
|
||||
from dash import html
|
||||
from pathlib import Path
|
||||
from base64 import b64encode
|
||||
|
||||
# read init img
|
||||
init_img_path = Path(__file__).parent / "init_img.png"
|
||||
with open(init_img_path.absolute(), "rb") as fh:
|
||||
init_img_enc = b64encode(fh.read()).decode("utf-8")
|
||||
# generate init img string
|
||||
init_img_src = f"data:image/png;base64, {init_img_enc}"
|
||||
|
||||
image_element = dmc.Center(
|
||||
html.Img(
|
||||
style={
|
||||
"width": "100%",
|
||||
},
|
||||
id="image-container",
|
||||
src=init_img_src
|
||||
)
|
||||
)
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 9.3 KiB |
@@ -1,23 +0,0 @@
|
||||
import dash_mantine_components as dmc
|
||||
|
||||
from .labels import labels_element
|
||||
|
||||
next_button = dmc.Button(
|
||||
"next".title(),
|
||||
id="next-button",
|
||||
n_clicks=0,
|
||||
fullWidth=True,
|
||||
color="lime",
|
||||
radius="sm",
|
||||
size="md",
|
||||
style={
|
||||
"height": "50px"
|
||||
}
|
||||
)
|
||||
|
||||
inputs_element = dmc.SimpleGrid(
|
||||
children=[
|
||||
labels_element,
|
||||
next_button
|
||||
]
|
||||
)
|
||||
@@ -1,113 +0,0 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import dash_mantine_components as dmc
|
||||
from dash import dcc
|
||||
from dash import html
|
||||
|
||||
from core.dto import AngleData
|
||||
from core.dto import ContactData
|
||||
from core.dto import DistanceData
|
||||
from core.dto import FramingData
|
||||
from core.dto import InformationValueData
|
||||
from core.dto import ModalityColorData
|
||||
from core.dto import ModalityDepthData
|
||||
from core.dto import ModalityLightingData
|
||||
from core.dto import PointOfViewData
|
||||
from core.dto import SalienceData
|
||||
from core.dto import VisualSyntaxData
|
||||
|
||||
|
||||
def generate_visual_syntax_options_map():
|
||||
"""Generate map of titles and options for visual syntax labels."""
|
||||
options_map = {}
|
||||
# add experiential labels
|
||||
options_map['visual syntax'] = VisualSyntaxData.list_fields()
|
||||
return options_map
|
||||
|
||||
|
||||
def generate_interpersonal_options_map():
|
||||
"""Generate map of titles and options for interpersonal labels."""
|
||||
options_map = {}
|
||||
# add interpersonal labels
|
||||
options_map['contact'] = ContactData.list_fields()
|
||||
options_map['angle'] = AngleData.list_fields()
|
||||
options_map['point of view'] = PointOfViewData.list_fields()
|
||||
options_map['distance'] = DistanceData.list_fields()
|
||||
options_map['modality lighting'] = ModalityLightingData.list_fields()
|
||||
options_map['modality color'] = ModalityColorData.list_fields()
|
||||
options_map['modality depth'] = ModalityDepthData.list_fields()
|
||||
return options_map
|
||||
|
||||
|
||||
def generate_textual_options_map():
|
||||
"""Generate map of titles and options for textual labels."""
|
||||
options_map = {}
|
||||
# add textual labels
|
||||
options_map['information value'] = InformationValueData.list_fields()
|
||||
options_map['framing'] = FramingData.list_fields()
|
||||
options_map['salience'] = SalienceData.list_fields()
|
||||
return options_map
|
||||
|
||||
|
||||
# prepare experiential container
|
||||
experiential_map = generate_visual_syntax_options_map()
|
||||
experiential_container = dmc.Col(
|
||||
children=[
|
||||
html.H4('experiential'.title()),
|
||||
], span=5,
|
||||
)
|
||||
for title, options in experiential_map.items():
|
||||
id_dict = {'type': 'annotation', 'index': title.replace('_', '-')}
|
||||
experiential_container.children.append(
|
||||
dmc.Container([
|
||||
html.B(title.title()),
|
||||
dcc.RadioItems(
|
||||
options=[text.replace('_', ' ') for text in options],
|
||||
id=id_dict,
|
||||
),
|
||||
]),
|
||||
)
|
||||
# prepare interpersonal container
|
||||
interpersonal_map = generate_interpersonal_options_map()
|
||||
interpersonal_container = dmc.Col(
|
||||
children=[
|
||||
html.H4('interpersonal'.title()),
|
||||
], span=3,
|
||||
)
|
||||
for title, options in interpersonal_map.items():
|
||||
id_dict = {'type': 'annotation', 'index': title.replace('_', '-')}
|
||||
interpersonal_container.children.append(
|
||||
dmc.Container([
|
||||
html.B(title.title()),
|
||||
dcc.RadioItems(
|
||||
options=[text.replace('_', ' ') for text in options],
|
||||
id=id_dict,
|
||||
),
|
||||
]),
|
||||
)
|
||||
# prepare textual container
|
||||
textual_map = generate_textual_options_map()
|
||||
textual_container = dmc.Col(
|
||||
children=[
|
||||
html.H4('textual'.title()),
|
||||
], span=4,
|
||||
)
|
||||
for title, options in textual_map.items():
|
||||
id_dict = {'type': 'annotation', 'index': title.replace('_', '-')}
|
||||
textual_container.children.append(
|
||||
dmc.Container([
|
||||
html.B(title.title()),
|
||||
dcc.RadioItems(
|
||||
options=[text.replace('_', ' ') for text in options],
|
||||
id=id_dict,
|
||||
),
|
||||
]),
|
||||
)
|
||||
|
||||
labels_element = dmc.Grid(
|
||||
children=[
|
||||
experiential_container,
|
||||
interpersonal_container,
|
||||
textual_container,
|
||||
],
|
||||
)
|
||||
@@ -1,34 +0,0 @@
|
||||
import dash_mantine_components as dmc
|
||||
|
||||
from .stores import stores_element
|
||||
from .alerts import alerts_element
|
||||
from .header import header_element
|
||||
from .body import body_element
|
||||
|
||||
|
||||
app_layout = dmc.MantineProvider(
|
||||
theme={
|
||||
"fontFamily": '"Inter", sans-serif',
|
||||
"components": {
|
||||
"NavLink": {
|
||||
"styles": {
|
||||
"label": {
|
||||
"color": "#c2c7d0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
children=[
|
||||
stores_element,
|
||||
alerts_element,
|
||||
dmc.Container(
|
||||
children=[
|
||||
header_element,
|
||||
body_element,
|
||||
],
|
||||
fluid=True
|
||||
),
|
||||
|
||||
]
|
||||
)
|
||||
@@ -1,13 +0,0 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dash import dcc
|
||||
from dash import html
|
||||
|
||||
|
||||
stores_element = html.Div(
|
||||
children=[
|
||||
dcc.Store(id='alert-message', data=''),
|
||||
dcc.Store(id='success-message', data=''),
|
||||
dcc.Store(id='vis-com-name', data=''),
|
||||
],
|
||||
)
|
||||
Reference in New Issue
Block a user