Skip to content

Commit

Permalink
added: sounds function & imtegrated klang project
Browse files Browse the repository at this point in the history
  • Loading branch information
Khoa N committed Nov 15, 2020
1 parent 24d3397 commit 869e95e
Show file tree
Hide file tree
Showing 21 changed files with 327 additions and 23 deletions.
11 changes: 9 additions & 2 deletions app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
from flask import Flask, jsonify
from flask import Flask, jsonify, send_from_directory
from flask_sqlalchemy import SQLAlchemy
from flask_restx import Api

from flask_login import LoginManager, current_user
from flask_migrate import Migrate

from app.klang.config import KlangConfig

db = SQLAlchemy()
login_manager = LoginManager()

migrate = Migrate()

klang_config = KlangConfig()

Expand All @@ -31,6 +32,7 @@ def create_app(env=None):

register_routes(api, app)
db.init_app(app)
migrate.init_app(app, db)
login_manager.init_app(app)

from .auth import auth as auth_blueprint
Expand All @@ -41,4 +43,9 @@ def create_app(env=None):
def health():
return jsonify("healthy")

## server for public assets
@app.route('/public/<path:path>')
def public(path):
return send_from_directory('public', path)

return app
42 changes: 35 additions & 7 deletions app/klang/controller.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
from datetime import datetime
from typing import List

from flask import session
from flask import session, request, abort
from flask_accepts.decorators.decorators import responds
from flask_restx import Namespace, Resource
from flask_restx import Namespace, Resource, reqparse
from flask import request, current_app

from .service import ConllService
from flask_login import current_user, login_required
import requests

api = Namespace("Klang", description="Single namespace, single entity") # noqa


@api.route("/conlls")
class ConllServiceResource(Resource):
"ConllService"

def get(self) :
def get(self):
# check if the user is logged in
if not current_user.is_authenticated:
return current_app.login_manager.unauthorized()
return ConllService.get_all()


Expand All @@ -22,11 +29,32 @@ class ConllNameServiceResource(Resource):
"ConllService"

def get(self, conll_name):

# check if the user is logged in
if not current_user.is_authenticated:
return current_app.login_manager.unauthorized()
conll_string = ConllService.get_by_name(conll_name)
sentences_string = ConllService.seperate_conll_sentences(conll_string)
sentences_audio_token = []
is_admin = request.args.get('is_admin')
users = ConllService.get_users_list(is_admin)
response = {}

for sentence_string in sentences_string:
audio_tokens = ConllService.sentence_to_audio_tokens(sentence_string)
sentences_audio_token.append(audio_tokens)
return sentences_audio_token
audio_tokens = ConllService.sentence_to_audio_tokens(
sentence_string)
sentences_audio_token.append(audio_tokens)
response['original'] = sentences_audio_token
for user in users:
transcription = ConllService.get_transcription(
user, conll_name, sentences_audio_token)
response[user] = transcription

return response

def post(self, conll_name):
data = request.get_json()
transcription = data['transcription']
if not transcription:
abort(400)
ConllService.save_transcription(conll_name, transcription)
return {'transcription': transcription}
5 changes: 0 additions & 5 deletions app/klang/data_test/John_Doe/John_Doe.intervals.conll

This file was deleted.

16 changes: 16 additions & 0 deletions app/klang/model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from sqlalchemy import BLOB, Boolean, Column, Integer, String, Boolean, TEXT
from sqlalchemy.ext.declarative import DeclarativeMeta
from sqlalchemy_utils import ChoiceType

from app import db # noqa

class Transcription(db.Model):
__tablename__ = "Klang"
# id = models.AutoField(primary_key = True)
# user = models.CharField(max_length = 100)
# mp3 = models.CharField(max_length = 100)
# transcription = models.TextField()
id = Column(Integer, primary_key=True)
user = Column(String(100), unique=True, nullable=False)
mp3 = Column(String(100), unique=True, nullable=False)
transcription = Column(TEXT)
64 changes: 55 additions & 9 deletions app/klang/service.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import os
import re
from typing import List
from sqlalchemy import exc
import sys
import json
from flask import abort

from app import klang_config
from app import klang_config, db
from .model import Transcription
from app.user.model import User
from flask_login import current_user

align_begin_and_end_regex = re.compile(
r"^\d+\t(.+?)\t.*AlignBegin=(\d+).*AlignEnd=(\d+)"
Expand Down Expand Up @@ -46,22 +53,15 @@ def seperate_conll_sentences(conll_string: str) -> List[str]:

@staticmethod
def sentence_to_audio_tokens(sentence_string: str):
# audio_tokens = {}
audio_tokens = []
for line in sentence_string.split("\n"):
if line:
if not line.startswith("#"):
m = align_begin_and_end_regex.search(line)
# audio_token = {
# "token": m.group(1),
# "alignBegin": int(m.group(2)),
# "alignEnd": int(m.group(3)),
# }
audio_token = [m.group(1), m.group(2), m.group(3)]
audio_tokens.append(audio_token)
# audio_tokens[int(line.split("\t")[0])] = audio_token

print(audio_tokens)

return audio_tokens

@staticmethod
Expand All @@ -73,3 +73,49 @@ def process_sentences_audio_token(conll_name: str):
audio_tokens = ConllService.sentence_to_audio_tokens(sentence_string)
sentences_audio_token.append(audio_tokens)
return sentences_audio_token

@staticmethod
def get_transcription(user_name, conll_name, original_trans):
trans = []
try:
record = Transcription.query.filter_by(
user = user_name,
mp3 = conll_name).one()
trans = json.loads(record.transcription)
pass
except exc.SQLAlchemyError:
for line in original_trans:
trans.append([word[0] for word in line])
pass
return trans

@staticmethod
def get_users_list(is_admin):
users = []
if is_admin == 'true':
users = [x.username for x in User.query.all()]
else:
users = [current_user.username]
return users

@staticmethod
def save_transcription(conll_name, transcription):
user_name = current_user.username
try:
Transcription.query.filter_by(
user = user_name,
mp3 = conll_name
).delete(synchronize_session = False)
trans_str = json.dumps(transcription)
print(transcription)
record = Transcription(
user = user_name,
mp3 = conll_name,
transcription = trans_str)
db.session.add(record)
db.session.commit()
pass
except:
print(sys.exc_info()[0])
abort(400)
pass
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added app/public/favicon.ico
Binary file not shown.
Binary file added app/public/icons/favicon-128x128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/public/icons/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/public/icons/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/public/icons/favicon-96x96.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
from app import create_app, db
from commands.seed_command import SeedCommand


from dotenv import load_dotenv
load_dotenv(dotenv_path=".flaskenv", verbose=True)
from sqlalchemy import MetaData, Table, Column, Integer, String

env = os.getenv("FLASK_ENV") or "test"
print(f"Active environment: * {env} *")
Expand Down
1 change: 1 addition & 0 deletions migrations/README
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Generic single-database configuration.
45 changes: 45 additions & 0 deletions migrations/alembic.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# A generic, single database configuration.

[alembic]
# template used to generate migration files
# file_template = %%(rev)s_%%(slug)s

# set to 'true' to run the environment during
# the 'revision' command, regardless of autogenerate
# revision_environment = false


# Logging configuration
[loggers]
keys = root,sqlalchemy,alembic

[handlers]
keys = console

[formatters]
keys = generic

[logger_root]
level = WARN
handlers = console
qualname =

[logger_sqlalchemy]
level = WARN
handlers =
qualname = sqlalchemy.engine

[logger_alembic]
level = INFO
handlers =
qualname = alembic

[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic

[formatter_generic]
format = %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S
97 changes: 97 additions & 0 deletions migrations/env.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
from __future__ import with_statement

import logging
from logging.config import fileConfig

from sqlalchemy import engine_from_config
from sqlalchemy import pool

from alembic import context

# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config

# Interpret the config file for Python logging.
# This line sets up loggers basically.
fileConfig(config.config_file_name)
logger = logging.getLogger('alembic.env')

# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
from flask import current_app
print(current_app.extensions['migrate'])
config.set_main_option(
'sqlalchemy.url',
str(current_app.extensions['migrate'].db.engine.url).replace('%', '%%'))
target_metadata = current_app.extensions['migrate'].db.metadata

# other values from the config, defined by the needs of env.py,
# can be acquired:
# my_important_option = config.get_main_option("my_important_option")
# ... etc.


def run_migrations_offline():
"""Run migrations in 'offline' mode.
This configures the context with just a URL
and not an Engine, though an Engine is acceptable
here as well. By skipping the Engine creation
we don't even need a DBAPI to be available.
Calls to context.execute() here emit the given string to the
script output.
"""
url = config.get_main_option("sqlalchemy.url")
context.configure(
url=url, target_metadata=target_metadata, literal_binds=True
)

with context.begin_transaction():
context.run_migrations()


def run_migrations_online():
"""Run migrations in 'online' mode.
In this scenario we need to create an Engine
and associate a connection with the context.
"""

# this callback is used to prevent an auto-migration from being generated
# when there are no changes to the schema
# reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html
def process_revision_directives(context, revision, directives):
if getattr(config.cmd_opts, 'autogenerate', False):
script = directives[0]
if script.upgrade_ops.is_empty():
directives[:] = []
logger.info('No changes in schema detected.')

connectable = engine_from_config(
config.get_section(config.config_ini_section),
prefix='sqlalchemy.',
poolclass=pool.NullPool,
)

with connectable.connect() as connection:
context.configure(
connection=connection,
target_metadata=target_metadata,
process_revision_directives=process_revision_directives,
**current_app.extensions['migrate'].configure_args
)

with context.begin_transaction():
context.run_migrations()


if context.is_offline_mode():
run_migrations_offline()
else:
run_migrations_online()
Loading

0 comments on commit 869e95e

Please sign in to comment.