From fdd22877615fd8b2b5674acee32a217383f676f7 Mon Sep 17 00:00:00 2001 From: Andrey Anokhin Date: Sat, 17 Aug 2019 13:04:58 +0300 Subject: [PATCH 001/176] Basic structure of flask-app --- app/__init__.py | 15 +++++++++++++++ app/forms.py | 1 + app/models.py | 4 ++++ app/routes.py | 9 +++++++++ app/templates/index.html | 1 + app/tests.py | 1 + config.py | 13 +++++++++++++ eriwan_podcast.py | 2 ++ 8 files changed, 46 insertions(+) create mode 100644 app/__init__.py create mode 100644 app/forms.py create mode 100644 app/models.py create mode 100644 app/routes.py create mode 100644 app/templates/index.html create mode 100644 app/tests.py create mode 100644 config.py create mode 100644 eriwan_podcast.py diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 0000000..2b7660c --- /dev/null +++ b/app/__init__.py @@ -0,0 +1,15 @@ +# Creates the application object as an instance of class Flask + + +from flask import Flask +from config import Config + +app = Flask(__name__) + +# using Config class from ./config.py +app.config.from_object(Config) + +# The routes module is imported at the bottom and not at the top of the script +# as it is always done. The bottom import is a workaround to circular imports, +# a common problem with Flask applications. +from app import routes, models diff --git a/app/forms.py b/app/forms.py new file mode 100644 index 0000000..8dd6df3 --- /dev/null +++ b/app/forms.py @@ -0,0 +1 @@ +# Here will be Flask Web Forms diff --git a/app/models.py b/app/models.py new file mode 100644 index 0000000..3cb39d5 --- /dev/null +++ b/app/models.py @@ -0,0 +1,4 @@ +# Here will be Classes with model definitions + +# from app import app, db +# Here will be db models diff --git a/app/routes.py b/app/routes.py new file mode 100644 index 0000000..4ee1448 --- /dev/null +++ b/app/routes.py @@ -0,0 +1,9 @@ +# View functions +from flask import render_template +from app import app + + +@app.route('/') +def index(): + feed_blank = 'Podcast Main page: RSS feed' + return render_template('index.html', feed_blank=feed_blank) diff --git a/app/templates/index.html b/app/templates/index.html new file mode 100644 index 0000000..7789fb0 --- /dev/null +++ b/app/templates/index.html @@ -0,0 +1 @@ +{{ feed_blank }} \ No newline at end of file diff --git a/app/tests.py b/app/tests.py new file mode 100644 index 0000000..74813ec --- /dev/null +++ b/app/tests.py @@ -0,0 +1 @@ +# Here will be tests diff --git a/config.py b/config.py new file mode 100644 index 0000000..183a890 --- /dev/null +++ b/config.py @@ -0,0 +1,13 @@ +# Config Classes + +import os +basedir = os.path.abspath(os.path.dirname(__file__)) + + +class Config(object): + SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess' + SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \ + 'sqlite:///' + os.path.join(basedir, 'app.db') + SQLALCHEMY_TRACK_MODIFICATIONS = False + + ADMINS = ['your-email@example.com'] diff --git a/eriwan_podcast.py b/eriwan_podcast.py new file mode 100644 index 0000000..2741a3e --- /dev/null +++ b/eriwan_podcast.py @@ -0,0 +1,2 @@ +# The top-level that defines the Flask application instance +from app import app From ccf2e869c9cb52cd2ed6340870f71b0d8e41b2a7 Mon Sep 17 00:00:00 2001 From: Andrey Anokhin Date: Sat, 17 Aug 2019 13:09:59 +0300 Subject: [PATCH 002/176] Create requirements.txt and add flask to it. --- requirements.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..7e10602 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +flask From c23b4b24e9967c171e41e175f72e89f97a59c072 Mon Sep 17 00:00:00 2001 From: Andrey Anokhin Date: Sat, 17 Aug 2019 13:21:49 +0300 Subject: [PATCH 003/176] how to run --- HOW TO RUN FLASK APP.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 HOW TO RUN FLASK APP.md diff --git a/HOW TO RUN FLASK APP.md b/HOW TO RUN FLASK APP.md new file mode 100644 index 0000000..a425cfc --- /dev/null +++ b/HOW TO RUN FLASK APP.md @@ -0,0 +1,6 @@ +# HOW TO RUN FLASK APP +```sh +export FLASK_APP=eriwan_podcast.py +export FLASK_DEBUG=1 +flask run +``` From b0866e72aa72fa515bd69fce3262508ee327f56c Mon Sep 17 00:00:00 2001 From: Mo1far <38346000+Mo1far@users.noreply.github.com> Date: Sat, 17 Aug 2019 13:32:07 +0300 Subject: [PATCH 004/176] Update config.py changed SEKRET_KEY to a more complex version --- config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.py b/config.py index 183a890..25c57a4 100644 --- a/config.py +++ b/config.py @@ -5,7 +5,7 @@ class Config(object): - SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess' + SECRET_KEY = os.environ.get('SECRET_KEY') or 'Wo7GhuD2OWIv' SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \ 'sqlite:///' + os.path.join(basedir, 'app.db') SQLALCHEMY_TRACK_MODIFICATIONS = False From 94533bb0abbc67e949da6066732e542156cc7c3b Mon Sep 17 00:00:00 2001 From: Alexander Shustrov Date: Sat, 17 Aug 2019 13:46:42 +0300 Subject: [PATCH 005/176] added idea settings into gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 6f667ed..7018eb4 100644 --- a/.gitignore +++ b/.gitignore @@ -105,3 +105,6 @@ venv.bak/ # direnv .envrc + +# ideas +.vscode From ffad299c682118381bce953e6b97dd71e6d05b2c Mon Sep 17 00:00:00 2001 From: AlexeyRadchenko Date: Sat, 17 Aug 2019 16:27:52 +0500 Subject: [PATCH 006/176] add flask-wtf in requirements --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 7e10602..519d308 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ flask +flask-wtf==0.14.2 \ No newline at end of file From fc50c9d5a3cb696c69835cceaf1ad7140e168f49 Mon Sep 17 00:00:00 2001 From: AlexeyRadchenko Date: Sat, 17 Aug 2019 16:31:07 +0500 Subject: [PATCH 007/176] create podcast upload form class --- app/forms.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/forms.py b/app/forms.py index 8dd6df3..5628584 100644 --- a/app/forms.py +++ b/app/forms.py @@ -1 +1,9 @@ -# Here will be Flask Web Forms +from flask_wtf import FlaskForm +from flask_wtf.file import FileField, FileAllowed, FileRequired + + +class FileUploadForm(FlaskForm): + file = FileField('Podcast file', validators=[ + FileRequired(), + FileAllowed(['mp3'], "Wrong format! Only mp3 format audio files") + ]) From 402b696e7d882012f0bfa64495f27ffb5606dade Mon Sep 17 00:00:00 2001 From: Andrey Anokhin Date: Sat, 17 Aug 2019 14:50:03 +0300 Subject: [PATCH 008/176] add custom error pages --- app/__init__.py | 2 +- app/errors.py | 16 ++++++++++++++++ app/routes.py | 2 +- app/templates/404.html | 6 ++++++ app/templates/500.html | 6 ++++++ app/templates/base.html | 4 ++++ app/templates/index.html | 7 ++++++- 7 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 app/errors.py create mode 100644 app/templates/404.html create mode 100644 app/templates/500.html create mode 100644 app/templates/base.html diff --git a/app/__init__.py b/app/__init__.py index 2b7660c..75ca279 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -12,4 +12,4 @@ # The routes module is imported at the bottom and not at the top of the script # as it is always done. The bottom import is a workaround to circular imports, # a common problem with Flask applications. -from app import routes, models +from app import routes, models, errors diff --git a/app/errors.py b/app/errors.py new file mode 100644 index 0000000..256c34f --- /dev/null +++ b/app/errors.py @@ -0,0 +1,16 @@ +# Handle route and server exceptions +# TODO: uncomment db, when it will be create +from flask import render_template +from app import app +# from app db + + +@app.errorhandler(404) +def not_found_error(error): + return render_template('404.html'), 404 + + +@app.errorhandler(500) +def internal_error(error): + # db.session.rollback() + return render_template('500.html'), 500 diff --git a/app/routes.py b/app/routes.py index 4ee1448..16f7cda 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,5 +1,5 @@ # View functions -from flask import render_template +from flask import render_template, url_for from app import app diff --git a/app/templates/404.html b/app/templates/404.html new file mode 100644 index 0000000..b9877fc --- /dev/null +++ b/app/templates/404.html @@ -0,0 +1,6 @@ +{% extends "base.html" %} + +{% block app_content %} +

Page Not Found

+

Back

+{% endblock %} diff --git a/app/templates/500.html b/app/templates/500.html new file mode 100644 index 0000000..c1490d0 --- /dev/null +++ b/app/templates/500.html @@ -0,0 +1,6 @@ +{% extends "base.html" %} + +{% block app_content %} +

An unexpected error has occurred'

+

'Back'}}

+{% endblock %} diff --git a/app/templates/base.html b/app/templates/base.html new file mode 100644 index 0000000..2bfcb4b --- /dev/null +++ b/app/templates/base.html @@ -0,0 +1,4 @@ + + +{% block app_content %} +{% endblock %} \ No newline at end of file diff --git a/app/templates/index.html b/app/templates/index.html index 7789fb0..5fede4d 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -1 +1,6 @@ -{{ feed_blank }} \ No newline at end of file + +{% extends "base.html" %} + +{% block app_content %} +

{{ feed_blank }}

+{% endblock %} From a6548857124d6b19e9557ec583dab95717f8e901 Mon Sep 17 00:00:00 2001 From: Aleksander Date: Sat, 17 Aug 2019 14:53:05 +0300 Subject: [PATCH 009/176] created models and database settings --- HOW TO RUN FLASK APP.md | 5 ++ app.db | Bin 0 -> 32768 bytes app/__init__.py | 8 +++ app/models.py | 73 +++++++++++++++++++- config.py | 2 + migrations/README | 1 + migrations/alembic.ini | 45 +++++++++++++ migrations/env.py | 96 +++++++++++++++++++++++++++ migrations/script.py.mako | 24 +++++++ migrations/versions/6301de4834d1_.py | 55 +++++++++++++++ requirements.txt | 7 +- 11 files changed, 312 insertions(+), 4 deletions(-) create mode 100644 app.db create mode 100644 migrations/README create mode 100644 migrations/alembic.ini create mode 100644 migrations/env.py create mode 100644 migrations/script.py.mako create mode 100644 migrations/versions/6301de4834d1_.py diff --git a/HOW TO RUN FLASK APP.md b/HOW TO RUN FLASK APP.md index a425cfc..6e0ea33 100644 --- a/HOW TO RUN FLASK APP.md +++ b/HOW TO RUN FLASK APP.md @@ -2,5 +2,10 @@ ```sh export FLASK_APP=eriwan_podcast.py export FLASK_DEBUG=1 + +flask db init +flask db migrate +flask db upgrade + flask run ``` diff --git a/app.db b/app.db new file mode 100644 index 0000000000000000000000000000000000000000..db697ed4f2b3d83d7c9e044580c6a55bc2e31f25 GIT binary patch literal 32768 zcmeI&OHUI)0KoBG9xbhwdTDy#G8bYuAn5}LAu(F&0u5y=OHnv&7P^L&KCllZ@dSP# z&wc>Ek4I0&nWcqpqulh+{5PHMygT!oX_LwJ@Sx)NJn^pGX}Ud8(4J_zuDujO)3m4z zb21FCh>Xk(6Y{Q)#QzqJYAe~zMDnK=ee_F9CX(OgQ;F}1#^bLt$%Oy{2q1s}0tg_0 z00RG2;Cdw*O{Y@&&5NFU+VI}DFM=>vvdv=66t&`3#S|)6Wa2TuF3MKT+%auoRcpdJ zs#KOmJf@1Bo_Ey~HS<_zj}-O0UdOp_rfR>o%lk$9MC_R-BIDN$mA75B&GL?=@-l-a zhOo_T(>AS=c_>s~P&sZ~Z$_f&g$4a)FBq_Q>37?8Z*Yr-hCRr9VB{^g>4`T*yR=)h zGx@bO;~x+H?QA6dETw<;TXpZszjA`Psy8(db&m`taAcJaj!dcj$~+e16-Ct=hzy$= z)=VV*G^Mvg9eYjJZ>TD>5A_<PRJ9Ikc2Rz>#8?l`<;9r@O<<%yIo9V>k@Ufmt_5q}{m_u7c*pJcZufvQ-dS!e zV_N>q1ZVq%jOfW9ntX8~fB*srAbr;#Cg>0_wt!@-n>$$j` z7w7*8SzM-p00IagfB*srAb' + + def set_password(self, password): + self.password_hash = generate_password_hash(password) + + def check_password(self, password): + return check_password_hash(self.password_hash, password) + + +class Episode(db.Model): + id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String(255), nullable=False) + user_id = db.Column(db.Integer, db.ForeignKey('user.id')) + + def __repr__(self): + return f', name: {self.name}' + + def get_file_path(self): + ''' + Return wrapped in jingles file path + ''' + static_path = os.path.join(app.config.STATIC_ROOT, 'episodes') + file_path = f'{static_path}/{self.id}.mp3' + if os.path.exists(file_path): + return file_path + + # todo: add to celery task + def generate_wrapped_file(self, upload_file): + ''' + Generate file with name of episode prefix from upload_file + ''' + pass + + +class Joke(db.Model): + id = db.Column(db.Integer, primary_key=True) + joke_text = db.Column(db.Text, nullable=False) + user_id = db.Column(db.Integer, db.ForeignKey('user.id')) + + def __repr__(self): + return f', name: {self.name}' + + def get_file_path(self): + ''' + Return wrapped in jingles file path + ''' + static_path = os.path.join(app.config.get('STATIC_ROOT'), 'jokes') + file_path = f'{static_path}/{self.id}.mp3' + if os.path.exists(file_path): + return file_path + + # todo: add to celery task + def generate_wrapped_file(self, upload_file): + ''' + Generate wrapped in jingles file from upload_file + ''' + pass diff --git a/config.py b/config.py index 25c57a4..94849ca 100644 --- a/config.py +++ b/config.py @@ -11,3 +11,5 @@ class Config(object): SQLALCHEMY_TRACK_MODIFICATIONS = False ADMINS = ['your-email@example.com'] + + STATIC_ROOT = '/static/' diff --git a/migrations/README b/migrations/README new file mode 100644 index 0000000..98e4f9c --- /dev/null +++ b/migrations/README @@ -0,0 +1 @@ +Generic single-database configuration. \ No newline at end of file diff --git a/migrations/alembic.ini b/migrations/alembic.ini new file mode 100644 index 0000000..f8ed480 --- /dev/null +++ b/migrations/alembic.ini @@ -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 diff --git a/migrations/env.py b/migrations/env.py new file mode 100644 index 0000000..79b8174 --- /dev/null +++ b/migrations/env.py @@ -0,0 +1,96 @@ +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 +config.set_main_option( + 'sqlalchemy.url', current_app.config.get( + 'SQLALCHEMY_DATABASE_URI').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() diff --git a/migrations/script.py.mako b/migrations/script.py.mako new file mode 100644 index 0000000..2c01563 --- /dev/null +++ b/migrations/script.py.mako @@ -0,0 +1,24 @@ +"""${message} + +Revision ID: ${up_revision} +Revises: ${down_revision | comma,n} +Create Date: ${create_date} + +""" +from alembic import op +import sqlalchemy as sa +${imports if imports else ""} + +# revision identifiers, used by Alembic. +revision = ${repr(up_revision)} +down_revision = ${repr(down_revision)} +branch_labels = ${repr(branch_labels)} +depends_on = ${repr(depends_on)} + + +def upgrade(): + ${upgrades if upgrades else "pass"} + + +def downgrade(): + ${downgrades if downgrades else "pass"} diff --git a/migrations/versions/6301de4834d1_.py b/migrations/versions/6301de4834d1_.py new file mode 100644 index 0000000..e87730e --- /dev/null +++ b/migrations/versions/6301de4834d1_.py @@ -0,0 +1,55 @@ +"""empty message + +Revision ID: 6301de4834d1 +Revises: +Create Date: 2019-08-17 15:06:22.058512 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '6301de4834d1' +down_revision = None +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('user', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('username', sa.String(length=64), nullable=False), + sa.Column('email', sa.String(length=120), nullable=False), + sa.Column('password_hash', sa.String(length=128), nullable=False), + sa.Column('is_admin', sa.Boolean(), nullable=False), + sa.PrimaryKeyConstraint('id') + ) + op.create_index(op.f('ix_user_email'), 'user', ['email'], unique=True) + op.create_index(op.f('ix_user_username'), 'user', ['username'], unique=True) + op.create_table('episode', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('name', sa.String(length=255), nullable=False), + sa.Column('user_id', sa.Integer(), nullable=True), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('joke', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('joke_text', sa.Text(), nullable=False), + sa.Column('user_id', sa.Integer(), nullable=True), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), + sa.PrimaryKeyConstraint('id') + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('joke') + op.drop_table('episode') + op.drop_index(op.f('ix_user_username'), table_name='user') + op.drop_index(op.f('ix_user_email'), table_name='user') + op.drop_table('user') + # ### end Alembic commands ### diff --git a/requirements.txt b/requirements.txt index 7e10602..dfe16f3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,6 @@ -flask +# core +Flask ~= 1.1.1 + +# database +Flask-SQLAlchemy ~= 2.4.0 +flask-migrate ~= 2.5.2 From f4188354bc2c801fb7df9e8e108a153663f97a0d Mon Sep 17 00:00:00 2001 From: AlexeyRadchenko Date: Sat, 17 Aug 2019 17:07:45 +0500 Subject: [PATCH 010/176] add upload route --- app/routes.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/routes.py b/app/routes.py index 4ee1448..1b7642f 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,9 +1,18 @@ # View functions from flask import render_template from app import app +from .forms import FileUploadForm @app.route('/') def index(): feed_blank = 'Podcast Main page: RSS feed' return render_template('index.html', feed_blank=feed_blank) + + +@app.route('/upload-podcast/', methods=['POST']) +def upload_file(): + form = FileUploadForm(request.form) + if form.validate(): + pass + return render_template('index.html', form=form) From 4462f5e19e74848c374e9ce22c504aeae6e46cda Mon Sep 17 00:00:00 2001 From: Turkova Maria Date: Sat, 17 Aug 2019 15:11:11 +0300 Subject: [PATCH 011/176] added *.mp3 --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 6f667ed..07ff005 100644 --- a/.gitignore +++ b/.gitignore @@ -105,3 +105,7 @@ venv.bak/ # direnv .envrc + + +# files: +*.mp3 From 2848c9b1a247ce0251f2ee0b312f0ea1c52072f6 Mon Sep 17 00:00:00 2001 From: Turkova Maria Date: Sat, 17 Aug 2019 15:11:53 +0300 Subject: [PATCH 012/176] gTTS speech synthesis version added --- gTTS_speech_synthesis.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 gTTS_speech_synthesis.py diff --git a/gTTS_speech_synthesis.py b/gTTS_speech_synthesis.py new file mode 100644 index 0000000..373d998 --- /dev/null +++ b/gTTS_speech_synthesis.py @@ -0,0 +1,16 @@ +from gtts import gTTS + +def text_to_speech(text): + """ + takes text, makes Russian speech + """ + tts = gTTS(text=text, lang='ru') + file_name = "hello1.mp3" + tts.save(file_name) + + return file + +if __name__ == "__main__": + #text = "Армянская семья так любила извиняться, что взяла фамилию Сорян." + text = "Рыла свинья белорыла, тупорыла; полдвора рылом изрыла, вырыла, подрыла" + print(text_to_speech(text)) From a2a62bb7aa45a8301e0bef38d33fe30cb26c357d Mon Sep 17 00:00:00 2001 From: Aleksander Date: Sat, 17 Aug 2019 15:12:35 +0300 Subject: [PATCH 013/176] fix config get --- app/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models.py b/app/models.py index 4ad3b34..f944446 100644 --- a/app/models.py +++ b/app/models.py @@ -33,7 +33,7 @@ def get_file_path(self): ''' Return wrapped in jingles file path ''' - static_path = os.path.join(app.config.STATIC_ROOT, 'episodes') + static_path = os.path.join(app.config.get('STATIC_ROOT'), 'episodes') file_path = f'{static_path}/{self.id}.mp3' if os.path.exists(file_path): return file_path From a2011fd15a246dd136b4458f1bb7d7f67c588609 Mon Sep 17 00:00:00 2001 From: Andrey Anokhin Date: Sat, 17 Aug 2019 15:15:55 +0300 Subject: [PATCH 014/176] change block app_content to content --- app/templates/404.html | 2 +- app/templates/500.html | 2 +- app/templates/base.html | 2 +- app/templates/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/templates/404.html b/app/templates/404.html index b9877fc..4be3669 100644 --- a/app/templates/404.html +++ b/app/templates/404.html @@ -1,6 +1,6 @@ {% extends "base.html" %} -{% block app_content %} +{% block content %}

Page Not Found

Back

{% endblock %} diff --git a/app/templates/500.html b/app/templates/500.html index c1490d0..f99f3f1 100644 --- a/app/templates/500.html +++ b/app/templates/500.html @@ -1,6 +1,6 @@ {% extends "base.html" %} -{% block app_content %} +{% block content %}

An unexpected error has occurred'

'Back'}}

{% endblock %} diff --git a/app/templates/base.html b/app/templates/base.html index 2bfcb4b..d385b23 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -1,4 +1,4 @@ -{% block app_content %} +{% block content %} {% endblock %} \ No newline at end of file diff --git a/app/templates/index.html b/app/templates/index.html index 5fede4d..276ba7f 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -1,6 +1,6 @@ {% extends "base.html" %} -{% block app_content %} +{% block content %}

{{ feed_blank }}

{% endblock %} From f33375ae339aff242e0c986acfb708c402419c54 Mon Sep 17 00:00:00 2001 From: Molfar Date: Sat, 17 Aug 2019 15:20:12 +0300 Subject: [PATCH 015/176] added base template --- app/templates/main.html | 49 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 app/templates/main.html diff --git a/app/templates/main.html b/app/templates/main.html new file mode 100644 index 0000000..ee73717 --- /dev/null +++ b/app/templates/main.html @@ -0,0 +1,49 @@ + + + + + {% if title %} + {{ title }} - Eriwan + {% else %} + Eriwan + {% endif %} + + {% block js %} + + {% endblock %} + + +{% block menu %} + +{% endblock %} + +
+
+
+{% with messages = get_flashed_messages() %} + {% if messages %} +
    + {% for message in messages %} + + {% endfor %} +
+ {% endif %} +{% endwith %} +{% block content %} + +{% endblock %} +{% block footer %} + +{% endblock %} + + \ No newline at end of file From 24a9ae594ab3f060263e4ecdc1471f92f4c8b008 Mon Sep 17 00:00:00 2001 From: Alexander Shustrov Date: Sat, 17 Aug 2019 15:38:26 +0300 Subject: [PATCH 016/176] Edited file methods --- app/models.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/models.py b/app/models.py index f944446..afe8f99 100644 --- a/app/models.py +++ b/app/models.py @@ -41,7 +41,7 @@ def get_file_path(self): # todo: add to celery task def generate_wrapped_file(self, upload_file): ''' - Generate file with name of episode prefix from upload_file + Return generate file with name of episode prefix from upload_file ''' pass @@ -63,9 +63,15 @@ def get_file_path(self): if os.path.exists(file_path): return file_path + def generate_base_file(self): + ''' + Return generate base audio file from joke_text + ''' + pass + # todo: add to celery task def generate_wrapped_file(self, upload_file): ''' - Generate wrapped in jingles file from upload_file + Return generate wrapped in jingles file from upload_file ''' pass From 3ee0ecec873cc8f17c2b2f31f0df58cf2fcbfd10 Mon Sep 17 00:00:00 2001 From: Turkova Maria Date: Sat, 17 Aug 2019 15:44:01 +0300 Subject: [PATCH 017/176] added yandex_tokens.py --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 07ff005..bfee24e 100644 --- a/.gitignore +++ b/.gitignore @@ -93,6 +93,7 @@ venv.bak/ # Spyder project settings .spyderproject .spyproject +yandex_tokens.py # Rope project settings .ropeproject @@ -107,5 +108,5 @@ venv.bak/ .envrc -# files: +# audio files: *.mp3 From b84cedafb6ec18e5f6deb9f2327bb5ffe169e256 Mon Sep 17 00:00:00 2001 From: Turkova Maria Date: Sat, 17 Aug 2019 15:44:27 +0300 Subject: [PATCH 018/176] yandex speech synthesis start of work --- yandex_speech_synthesis.py | 39 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 yandex_speech_synthesis.py diff --git a/yandex_speech_synthesis.py b/yandex_speech_synthesis.py new file mode 100644 index 0000000..fe1e18a --- /dev/null +++ b/yandex_speech_synthesis.py @@ -0,0 +1,39 @@ +import argparse +import requests +from yandex_tokens import FOLDER_ID, IAM_TOKEN + +def synthesize(folder_id, iam_token, text): + url = 'https://tts.api.cloud.yandex.net/speech/v1/tts:synthesize' + headers = { + 'Authorization': 'Bearer ' + iam_token, + } + + data = { + 'text': text, + 'lang': 'en-US', + 'folderId': folder_id, + 'format': 'lpcm', + 'sampleRateHertz': 48000, + } + + with requests.post(url, headers=headers, data=data, stream=True) as resp: + if resp.status_code != 200: + raise RuntimeError("Invalid response received: code: %d, message: %s" % (resp.status_code, resp.text)) + + for chunk in resp.iter_content(chunk_size=None): + yield chunk + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + + parser.add_argument("--IAM_TOKEN", required=True, help="IAM token") + parser.add_argument("--FOLDER_ID", required=True, help="Folder id") + parser.add_argument("--text", required=True, help="Text for synthesize") + parser.add_argument("--output", required=True, help="Output file name") + args = parser.parse_args() + + with open(args.output, "wb") as f: + for audio_content in synthesize(args.folder_id, args.token, args.text): + f.write(audio_content) From ac265eea91ed71bb9a0219532a5faa70086195b0 Mon Sep 17 00:00:00 2001 From: Turkova Maria Date: Sat, 17 Aug 2019 15:55:50 +0300 Subject: [PATCH 019/176] added logging --- eriwan_podcast.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/eriwan_podcast.py b/eriwan_podcast.py index 2741a3e..8df3d94 100644 --- a/eriwan_podcast.py +++ b/eriwan_podcast.py @@ -1,2 +1,10 @@ # The top-level that defines the Flask application instance +import logging + from app import app + +logging.basicConfig( + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', + level=logging.INFO, + filename="eriwan_podcast.log" + ) From df4c6ab702a9d8b2eb054ae041eb5a1184e37073 Mon Sep 17 00:00:00 2001 From: Mo1far <38346000+Mo1far@users.noreply.github.com> Date: Sat, 17 Aug 2019 15:57:03 +0300 Subject: [PATCH 020/176] Update main.html --- app/templates/main.html | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/templates/main.html b/app/templates/main.html index ee73717..0b5fa56 100644 --- a/app/templates/main.html +++ b/app/templates/main.html @@ -14,9 +14,6 @@ {% endblock %} -{% block menu %} - -{% endblock %}