Skip to content
This repository was archived by the owner on Jan 25, 2020. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions app/audio_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,29 @@ def text_to_speech(text):
"""
takes text, makes Russian speech, saved into temporary mp3 file
"""
temporary_file = tempfile.NamedTemporaryFile(suffix=".mp3", delete=False)
temporary_file = tempfile.NamedTemporaryFile(suffix=".mp3")
tts = gTTS(text=text, lang='ru')
tts.save(temporary_file.name)

return temporary_file.name
return temporary_file


def concatenate_audios(path_list, out_path):
def concatenate_audios(file_list, out_path):
"""
Concatenate audios into one file
:param out_path: path for saving mp3 file
:param path_list: audio path list
:param out_path: path for saving mp3 file or file itself
:param file_list: audio path list
:return:
"""

res = AudioSegment.empty()
for audio_path in path_list:
for audio_path in file_list:
res += AudioSegment.from_mp3(audio_path)
res.export(out_path, format='mp3')


def prepend_intro_text_and_save(audio_file, intro_text, output_path):
intro_audio = AudioSegment.from_mp3(text_to_speech(intro_text))
base_audio = AudioSegment.from_mp3(audio_file)
result = intro_audio + base_audio
result.export(output_path, format='mp3')
34 changes: 26 additions & 8 deletions app/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
from app.models import User


def validate_username_does_not_exist(username):
user = User.query.filter_by(username=username.data).first()
if user:
raise ValidationError('Это имя пользователя уже занято. Пожалуйста \
выберите другое.')


class RegistrationForm(FlaskForm):
username = StringField(
'Имя пользователя',
Expand Down Expand Up @@ -35,10 +42,7 @@ class RegistrationForm(FlaskForm):

@staticmethod
def validate_username(self, username):
user = User.query.filter_by(username=username.data).first()
if user:
raise ValidationError('Это имя пользователя уже занято. Пожалуйста \
выберите другое.')
validate_username_does_not_exist(username)

@staticmethod
def validate_email(self, email):
Expand Down Expand Up @@ -71,13 +75,26 @@ class EditJokeForm(FlaskForm):
submit = SubmitField("Редактировать")


class EditUserProfileForm(FlaskForm):
class EditUserNameForm(FlaskForm):
username = StringField(
'Имя пользователя',
render_kw={"placeholder": "Новое имя пользователя"},
validators=[
DataRequired(),
Length(min=2, max=64)])
password = PasswordField(
'Пароль',
validators=[
DataRequired(),
Length(min=3, max=25)])
submit = SubmitField('Редактировать имя')

@staticmethod
def validate_username(self, username):
validate_username_does_not_exist(username)


class EditUserPasswordForm(FlaskForm):
old_password = PasswordField(
'Старый пароль',
validators=[
Expand All @@ -94,12 +111,13 @@ class EditUserProfileForm(FlaskForm):
DataRequired(),
Length(min=3, max=25),
EqualTo('password')])
submit = SubmitField('Редактировать')
submit = SubmitField('Редактировать пароль')


class EpisodeUploadForm(FlaskForm):
file = FileField('Upload podcast', validators=[
title = StringField('Имя подкаста', validators=[DataRequired()])
file = FileField('Аудиофайл', validators=[
FileRequired(),
FileAllowed(['mp3'], "Wrong format! Only mp3 format audio files")
])
title = StringField('Имя подкаста', validators=[DataRequired()])
submit = SubmitField('Загрузить подкаст')
63 changes: 34 additions & 29 deletions app/models.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import os
from pathlib import Path

import sqlalchemy
from flask import url_for
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import UserMixin

from app import app, db, login_manager
from .audio_utils import concatenate_audios, text_to_speech


class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), index=True,
unique=True, nullable=False)
email = db.Column(db.String(120), index=True, unique=True, nullable=False)
username = db.Column(db.String(64), index=True, unique=True, nullable=False)
email = db.Column(db.String(120), index=True, nullable=False)
password_hash = db.Column(db.String(128), nullable=False)
is_admin = db.Column(db.Boolean, default=False, nullable=False)

Expand Down Expand Up @@ -39,31 +40,17 @@ def __repr__(self):
return f'<Episode id: {self.id}>, name: {self.name}'

def get_file_path(self):
'''
Return wrapped in jingles file path
'''
media_path = os.path.join(app.config.get('MEDIA_ROOT'), 'episodes')
file_path = f'{media_path}/{self.id}.mp3'
file_path = os.path.join(app.config.get('MEDIA_ROOT'), 'episodes', f'{self.id}.mp3')
if os.path.exists(file_path):
return file_path

# todo: add to celery task
def generate_wrapped_file(self, episode_path):
"""
Concatenate an episode name mp3 file and an episode mp3 file
:param episode_path: path to episode mp3
"""
media_path = os.path.join(app.config.get('MEDIA_ROOT'), 'episodes')
if not os.path.exists(media_path):
os.makedirs(media_path)
temp_path = text_to_speech(self.name)
concatenate_audios([temp_path, episode_path],
f'{media_path}/{self.id}.mp3')

def get_link(self):
static = app.config.get('STATIC_ROOT') + f'{self.id}.mp3'
host = app.config.get('HOST', 'localhost:5000')
return f'http://{host}/{Path(static).as_posix()}'
return f"http://{host}{url_for('episodes', path=f'{self.id}.mp3')}"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is happening here? why do we have a mix of quotes and why are we building URLs by concatenating strings? 



def get_all_episodes():
return Episode.query.all()


class Joke(db.Model):
Expand All @@ -84,8 +71,7 @@ def get_file_path(self):
Return wrapped in jingles file path
'''

media_path = os.path.join(app.config.get('MEDIA_ROOT'), 'jokes')
file_path = f'{media_path}/{self.id}.mp3'
file_path = os.path.join(app.config.get('MEDIA_ROOT'), 'jokes', f'{self.id}.mp3')
if os.path.exists(file_path):
return file_path

Expand All @@ -98,8 +84,27 @@ def generate_wrapped_file(self):
if not os.path.exists(media_path):
os.makedirs(media_path)

file_path = text_to_speech(self.joke_text)
joke_audio_file = text_to_speech(self.joke_text)
concatenate_audios([self.jingle_file_path(),
file_path,
joke_audio_file,
self.jingle_file_path()],
f'{media_path}/{self.id}.mp3')
os.path.join(media_path, f'{self.id}.mp3'))

def get_link(self):
host = app.config.get('HOST', 'localhost:5000')
return f"http://{host}{url_for('jokes', path=f'{self.id}.mp3')}"


def get_random_jokes_from_db(number=1):
return Joke.query.order_by(sqlalchemy.func.random()).limit(number)


def check_database_schema_existence():
try:
test_user_id = 1
User.query.get(test_user_id)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it an appropriate test for the existence of the schema? 

except sqlalchemy.exc.OperationalError:
db.create_all()


check_database_schema_existence()
Loading