From 7146fcd2fcf95e24b64086bda9c808e9af65f1a5 Mon Sep 17 00:00:00 2001
From: Dmitry Belyaev <b4tm4n@mail.ru>
Date: Fri, 3 Jul 2020 13:29:57 +0300
Subject: [PATCH] checkpoint

---
 .gitignore                                    |  23 +--
 .idea/.gitignore                              |   3 +
 .idea/helloworld_web.iml                      |  10 ++
 .../inspectionProfiles/profiles_settings.xml  |   6 +
 .idea/misc.xml                                |   7 +
 .idea/modules.xml                             |   8 ++
 .idea/vcs.xml                                 |   6 +
 forms.py                                      |  10 ++
 main.py                                       | 134 ++++++++++++++++++
 models.py                                     |   0
 requirements.txt                              |   4 +
 templates/contact.html                        |  29 ++++
 templates/index.html                          |  10 ++
 templates/login.html                          |  28 ++++
 14 files changed, 268 insertions(+), 10 deletions(-)
 create mode 100644 .idea/.gitignore
 create mode 100644 .idea/helloworld_web.iml
 create mode 100644 .idea/inspectionProfiles/profiles_settings.xml
 create mode 100644 .idea/misc.xml
 create mode 100644 .idea/modules.xml
 create mode 100644 .idea/vcs.xml
 create mode 100644 forms.py
 create mode 100644 main.py
 create mode 100644 models.py
 create mode 100644 templates/contact.html
 create mode 100644 templates/index.html
 create mode 100644 templates/login.html

diff --git a/.gitignore b/.gitignore
index 9618f13..bba54d9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,10 +1,13 @@
-
-# ide
-.vscode/
-
-# virtualenv
-venv/
-
-# cache
-*.pyc
-__pycache__/
+
+# ide
+.vscode/
+
+# virtualenv
+venv/
+
+# cache
+*.pyc
+__pycache__/
+
+# db
+*.sqlite
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..eaf91e2
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/helloworld_web.iml b/.idea/helloworld_web.iml
new file mode 100644
index 0000000..858c4d5
--- /dev/null
+++ b/.idea/helloworld_web.iml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="PYTHON_MODULE" version="4">
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/venv" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+<component name="InspectionProjectProfileManager">
+  <settings>
+    <option name="USE_PROJECT_PROFILE" value="false" />
+    <version value="1.0" />
+  </settings>
+</component>
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..a7a472d
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8 (venv)" project-jdk-type="Python SDK" />
+  <component name="PyCharmProfessionalAdvertiser">
+    <option name="shown" value="true" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..cfa12a9
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/helloworld_web.iml" filepath="$PROJECT_DIR$/.idea/helloworld_web.iml" />
+    </modules>
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..9661ac7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/forms.py b/forms.py
new file mode 100644
index 0000000..89d8675
--- /dev/null
+++ b/forms.py
@@ -0,0 +1,10 @@
+from flask_wtf import FlaskForm
+from wtforms import StringField, SubmitField, TextAreaField
+from wtforms.validators import DataRequired, Email
+
+
+class ContactForm(FlaskForm):
+    name = StringField("Name: ", validators=[DataRequired()])
+    email = StringField("Email: ", validators=[Email()])
+    message = TextAreaField("Message", validators=[DataRequired()])
+    submit = SubmitField("Submit")
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..ff35016
--- /dev/null
+++ b/main.py
@@ -0,0 +1,134 @@
+import flask
+from flask import Flask, request, current_app, url_for, render_template, flash, redirect
+from flask_script import Manager, Shell
+from jinja2 import Template
+from flask_sqlalchemy import SQLAlchemy
+from datetime import datetime
+
+from forms import ContactForm
+
+app = Flask(__name__)
+app.debug = True
+app.config['SECRET_KEY'] = '0d6e368e-bd0c-11ea-921d-9342d47f60ca'
+app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
+app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:///db.sqlite"
+manager = Manager(app)
+db = SQLAlchemy(app)
+
+
+class Category(db.Model):
+    __tablename__ = 'categories'
+    id = db.Column(db.Integer(), primary_key=True)
+    name = db.Column(db.String(255), nullable=False)
+    slug = db.Column(db.String(255), nullable=False)
+    created_on = db.Column(db.DateTime(), default=datetime.utcnow)
+    posts = db.relationship('Post', backref='category')
+
+    def __repr__(self):
+        return "<{}:{}>".format(id, self.name)
+
+
+class Post(db.Model):
+    __tablename__ = 'posts'
+    id = db.Column(db.Integer(), primary_key=True)
+    title = db.Column(db.String(255), nullable=False)
+    slug = db.Column(db.String(255), nullable=False)
+    content = db.Column(db.Text(), nullable=False)
+    created_on = db.Column(db.DateTime(), default=datetime.utcnow)
+    updated_on = db.Column(db.DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)
+    category_id = db.Column(db.Integer(), db.ForeignKey('categories.id'))
+
+    def __repr__(self):
+        return "<{}:{}>".format(self.id, self.title[:10])
+
+
+post_tags = db.Table('post_tags',
+                     db.Column('post_id', db.Integer, db.ForeignKey('posts.id')),
+                     db.Column('tag_id', db.Integer, db.ForeignKey('tags.id'))
+                     )
+
+
+class Tag(db.Model):
+    __tablename__ = 'tags'
+    id = db.Column(db.Integer(), primary_key=True)
+    name = db.Column(db.String(255), nullable=False)
+    slug = db.Column(db.String(255), nullable=False)
+    created_on = db.Column(db.DateTime(), default=datetime.utcnow)
+    posts = db.relationship('Post', secondary=post_tags, backref='tags')
+
+    def __repr__(self):
+        return "<{}:{}>".format(id, self.name)
+
+
+class Feedback(db.Model):
+    __tablename__ = 'feedbacks'
+    id = db.Column(db.Integer(), primary_key=True)
+    name = db.Column(db.String(1000), nullable=False)
+    email = db.Column(db.String(100), nullable=False)
+    message = db.Column(db.Text(), nullable=False)
+    created_on = db.Column(db.DateTime(), default=datetime.utcnow)
+
+    def __repr__(self):
+        return "<{}:{}>".format(self.id, self.name)
+
+
+@manager.command
+def faker():
+    print("Команда для добавления поддельных данных в таблицы")
+
+
+@app.route('/')
+def index():
+    return render_template('index.html')
+
+
+@app.route('/login/', methods=['post', 'get'])
+def login():
+    username = ''
+    password = ''
+    message = ''
+    if request.method == 'POST':
+        username = request.form.get('username')  # запрос к данным формы
+        password = request.form.get('password')
+
+    if username == 'root' and password == 'pass':
+        message = "Correct username and password"
+    else:
+        message = "Wrong username or password"
+
+    return render_template('login.html', message=message)
+
+
+@app.route('/contact/', methods=['get', 'post'])
+def contact():
+    form = ContactForm()
+    if form.validate_on_submit():
+        name = form.name.data
+        email = form.email.data
+        message = form.message.data
+        print(name)
+        print(email)
+        print(message)
+        # здесь логика базы данных
+        feedback = Feedback(name=name, email=email, message=message)
+        db.session.add(feedback)
+        db.session.commit()
+
+        print("\nData received. Now redirecting ...")
+        flash("Message Received", "success")
+        return redirect(url_for('contact'))
+
+    return render_template('contact.html', form=form)
+
+
+def shell_context():
+    import os, sys
+    return {'app': app, 'os': os, 'sys': sys, 'flask': flask, 'request': request, 'current_app': current_app,
+            'url_for': url_for, 'Template': Template, 'db': db}
+
+
+manager.add_command("shell", Shell(make_context=shell_context))
+
+if __name__ == "__main__":
+    db.init_app(app)
+    manager.run()
diff --git a/models.py b/models.py
new file mode 100644
index 0000000..e69de29
diff --git a/requirements.txt b/requirements.txt
index e77b3cc..bc18baf 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1,6 @@
 Flask==1.1.2
 Flask-WTF==0.14.3
+Flask-Script==2.0.6
+email_validator==1.1.1
+Flask_SQLAlchemy==2.4.3
+SQLAlchemy==1.3.18
diff --git a/templates/contact.html b/templates/contact.html
new file mode 100644
index 0000000..4569f49
--- /dev/null
+++ b/templates/contact.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Contact</title>
+</head>
+<body>
+
+{% for category, message in  get_flashed_messages(with_categories=true) %}
+<spam class="{{ category }}">{{ message }}</spam>
+{% endfor %}
+
+<form action="" method="post">
+
+    {{ form.csrf_token() }}
+
+    {% for field in form if field.name != "csrf_token" %}
+	<p>{{ field.label() }}</p>
+	<p>{{ field }}
+	    {% for error in field.errors %}
+		{{ error }}
+	    {% endfor %}
+	</p>
+    {% endfor %}
+
+</form>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/templates/index.html b/templates/index.html
new file mode 100644
index 0000000..4a33eb5
--- /dev/null
+++ b/templates/index.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <title>Hello</title>
+</head>
+<body>
+  <h2>Hello{% if name %},&nbsp;<p>{{ name }}</p>{% endif %}</h2>
+</body>
+</html>
\ No newline at end of file
diff --git a/templates/login.html b/templates/login.html
new file mode 100644
index 0000000..aa94936
--- /dev/null
+++ b/templates/login.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Login</title>
+</head>
+<body>
+
+    {% if message %}
+        <p>{{ message }}</p>
+    {% endif %}
+
+    <form action="" method="post">
+        <p>
+	    <label for="username">Username</label>
+	    <input type="text" name="username">
+	</p>
+	<p>
+	    <label for="password">Password</label>
+	    <input type="password" name="password">
+	</p>
+	<p>
+	    <input type="submit">
+	</p>
+    </form>
+
+</body>
+</html>
\ No newline at end of file