Всем привет! 37 | Завтрашнее занятие состоится в физтех-парке в 20.15. Подходить можно к 20.00, обсудить вопросы и другие интересующие вещи. 38 |
39 | 40 |С собой иметь паспорт для прохода в здание.
41 | 42 |
60 | Всем привет! 61 | К сожалению, в будние дни на физтехе найти аудиторию даже в 8 часов вечера - непосильная задача (по крайней мере, со стороны учебного отдела). Поэтому есть две новости: хорошая и плохая. 62 | Хорошая заключается в том, что нас любезно согласился приютить физтех-парк. Поэтому занятия будут проходить там в 8 вечера. 63 | Плохая же новость заключается в том, что впустить нас они смогут только со следующей недели. Поэтому первое занятие состоится через неделю, 3 ноября. 64 | Лекция, которая планировалась быть сегодня, должна была быть посвящена знакомству с системой Ubuntu, разворачиванию ее на виртуальной машине и работе с ней. Кроме этого, планировалось рассказать про git и GitHub (который активно понадобится нам в качестве хостинга на ближайших занятиях). Это должно было быть вводное занятие для знакомства с базовыми инструментами, чтобы не останавливаться на них при знакомстве с технологиями. На все возникающие вопросы будут даны ответы либо на следующем занятии, либо в общем чате telegram (ссылка будет отдельным постом). 65 |
66 | 67 | В связи с этими обстоятельствами, есть два варианта развития событий: 68 |-
69 |
- Просто перенесем лекцию на неделю вперед. 70 |
- Запишем скринкаст по данным темам и выложим его к выходным. Тогда со следующего занятия можно будет начать знакомство с HTML и CSS, таким образом переходя непосредственно к технологиям. 71 |
Веб-программирование на Физтехе 2016-2017
13 |Занятие 3. Знакомство с JavaScript и jQuery
14 |Привет, {{ username }}!
9 |
10 |
11 |
--------------------------------------------------------------------------------
/lections/04/examples/flask/templates/login.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Login
6 |
7 |
8 |
9 | Войдите, пожалуйста
10 |
17 |
18 | {% if error %}
19 | {{ error }}
20 | {% endif %}
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/lections/04/examples/http_server.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include
5 | #include
6 |
7 | using namespace boost::asio;
8 | using boost::system::error_code;
9 |
10 | io_service service;
11 |
12 | std::string handle(const std::string& req)
13 | {
14 | std::stringstream response_body;
15 | response_body << "Test C++ HTTP Server \n"
16 | << "Test page
\n"
17 | << "This is body of the test page...
\n"
18 | << "Request headers
\n"
19 | << "" << req << "
\n"
20 | << "Test C++ Http Server\n";
21 |
22 | std::stringstream response;
23 | response << "HTTP/1.1 200 OK\r\n"
24 | << "Version: HTTP/1.1\r\n"
25 | << "Content-Type: text/html; charset=utf-8\r\n"
26 | << "Content-Length: " << response_body.str().length()
27 | << "\r\n\r\n"
28 | << response_body.str();
29 |
30 | return response.str();
31 | }
32 |
33 | size_t read_complete(char * buff, const error_code & err, size_t bytes) {
34 | if (err) return 0;
35 | for (char* b = buff; b < buff + bytes - 3; ++b) {
36 | if (*b == '\r' && *(b + 1) == '\n'
37 | && *(b + 2) == '\r' && *(b + 3) == '\n') {
38 | return 0;
39 | }
40 | }
41 | return 1;
42 | }
43 |
44 | void handle_connections() {
45 | ip::tcp::acceptor acceptor(service, ip::tcp::endpoint(ip::tcp::v4(), 8001));
46 | char buff[1024];
47 | while (true) {
48 | ip::tcp::socket sock(service);
49 | acceptor.accept(sock);
50 | int bytes = read(sock, buffer(buff),
51 | boost::bind(read_complete, buff, _1, _2));
52 | std::string msg(buff, bytes);
53 | sock.write_some(buffer(handle(msg)));
54 | sock.close();
55 | }
56 | }
57 |
58 | int main()
59 | {
60 | handle_connections();
61 | return 0;
62 | }
63 |
--------------------------------------------------------------------------------
/lections/04/slides/pictures/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/04/slides/pictures/cover.jpg
--------------------------------------------------------------------------------
/lections/05/README.md:
--------------------------------------------------------------------------------
1 | ## SimpleTaskTracker на Flask
2 |
3 | **[Слайды](https://dbeliakov.github.io/mipt-web-2016/lections/05/slides/)**
4 |
5 | **[Скринкаст](https://youtu.be/lh0EKMfHZP0)**
6 |
7 | * [Исходный код SimpleTaskTracker](examples/tasktracker)
8 |
--------------------------------------------------------------------------------
/lections/05/examples/tasktracker/app.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | from flask import Flask, abort, render_template, request, jsonify, session, redirect
4 | from utils import *
5 | from db import *
6 |
7 | app = Flask("SimpleTaskTracker")
8 | template_dir = 'templates'
9 |
10 | @app.route('/', methods=['GET'])
11 | @authorized
12 | def index():
13 | return render_template('index.html')
14 |
15 | @app.route('/login', methods=["GET"])
16 | @not_authorized
17 | def login():
18 | return render_template('login.html')
19 |
20 | @app.route('/api/login', methods=["POST"])
21 | @not_authorized
22 | def api_login():
23 | login = request.form.get('login', None)
24 | password = request.form.get('password', None)
25 | if login is None or password is None:
26 | return jsonify({'status': 'error', 'message': 'Неверные данные для входа'})
27 | user = authorize(login, password)
28 | if user.is_authorized():
29 | session['user_login'] = login
30 | return jsonify({'status': 'ok'})
31 | return jsonify({'status': 'error', 'message': 'Неверные данные для входа'})
32 |
33 | @app.route('/logout', methods=["GET"])
34 | @authorized
35 | def logout():
36 | session.clear()
37 | return redirect('/login')
38 |
39 | @app.route('/api/tasks', methods=["GET"])
40 | @authorized
41 | def api_tasks():
42 | login = session['user_login']
43 | return jsonify({"tasks": get_tasks(login)})
44 |
45 | @app.route('/api/remove_task/', methods=["GET"])
46 | @authorized
47 | def api_remove_task(task_id):
48 | login = session['user_login']
49 | remove_task(login, task_id)
50 | return jsonify({'status': 'ok'})
51 |
52 | @app.route('/api/add_task', methods=["POST"])
53 | @authorized
54 | def api_add_task():
55 | login = session['user_login']
56 | text = request.form.get('text', None)
57 | if text is None:
58 | return jsonify({'status': 'error', 'message': 'Некорректный запрос'})
59 | task_id = add_task(login, text)
60 | return jsonify({'status': 'ok', 'task_id': task_id})
61 |
62 | if __name__ == "__main__":
63 | app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
64 | app.run(port=8001)
65 |
--------------------------------------------------------------------------------
/lections/05/examples/tasktracker/db.py:
--------------------------------------------------------------------------------
1 | import json
2 |
3 | def get_tasks(login):
4 | with open('tasks.json') as f:
5 | tasks = json.load(f)
6 | if not login in tasks:
7 | return []
8 | return tasks[login]
9 |
10 | def add_task(login, text):
11 | with open('tasks.json') as f:
12 | tasks = json.load(f)
13 | if not login in tasks:
14 | tasks[login] = []
15 | task_id = 1
16 | else:
17 | if len(tasks[login]) == 0:
18 | task_id = 1
19 | else:
20 | task_id = tasks[login][-1]["id"] + 1
21 | tasks[login].append({"id": task_id, "text": text})
22 | with open('tasks.json', 'w') as f:
23 | json.dump(tasks, f)
24 | return task_id
25 |
26 | def remove_task(login, id):
27 | with open('tasks.json') as f:
28 | tasks = json.load(f)
29 | if not login in tasks:
30 | return
31 | for i, task in enumerate(tasks[login]):
32 | if task['id'] == id:
33 | del tasks[login][i]
34 | break
35 | with open('tasks.json', 'w') as f:
36 | json.dump(tasks, f)
37 |
--------------------------------------------------------------------------------
/lections/05/examples/tasktracker/db.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/05/examples/tasktracker/db.pyc
--------------------------------------------------------------------------------
/lections/05/examples/tasktracker/static/styles.css:
--------------------------------------------------------------------------------
1 | body {
2 | padding-top: 40px;
3 | padding-bottom: 40px;
4 | }
5 |
6 | .container {
7 | background-color: #eee;
8 | width: 500px;
9 | height: 350px;
10 | position: absolute;
11 | top:0;
12 | bottom: 0;
13 | left: 0;
14 | right: 0;
15 | margin: auto;
16 | border: 1px solid black;
17 | border-radius: 10px;
18 | }
19 |
20 | .container_2 {
21 | background-color: #eee;
22 | width: 500px;
23 | margin: 50px auto;
24 | padding: 20px;
25 | border: 1px solid black;
26 | border-radius: 10px;
27 | }
28 |
29 | .header {
30 | margin-left: auto;
31 | margin-right: auto;
32 | width: 50%;
33 | text-align: center;
34 | border-bottom: 1px solid grey;
35 | }
36 |
37 | .form-signin {
38 | max-width: 330px;
39 | padding: 15px;
40 | margin: 0 auto;
41 | }
42 | .form-signin .form-signin-heading,
43 | .form-signin .checkbox {
44 | margin-bottom: 10px;
45 | }
46 | .form-signin .checkbox {
47 | font-weight: normal;
48 | }
49 | .form-signin .form-control {
50 | position: relative;
51 | height: auto;
52 | -webkit-box-sizing: border-box;
53 | -moz-box-sizing: border-box;
54 | box-sizing: border-box;
55 | padding: 10px;
56 | font-size: 16px;
57 | }
58 | .form-signin .form-control:focus {
59 | z-index: 2;
60 | }
61 | .form-signin input[type="email"] {
62 | margin-bottom: -1px;
63 | border-bottom-right-radius: 0;
64 | border-bottom-left-radius: 0;
65 | }
66 | .form-signin input[type="password"] {
67 | margin-bottom: 10px;
68 | border-top-left-radius: 0;
69 | border-top-right-radius: 0;
70 | }
71 |
--------------------------------------------------------------------------------
/lections/05/examples/tasktracker/tasks.json:
--------------------------------------------------------------------------------
1 | {"admin": []}
--------------------------------------------------------------------------------
/lections/05/examples/tasktracker/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Tasks - SimpleTaskTracker
6 |
10 |
13 |
14 |
15 |
19 |
20 |
21 |
22 | SimpleTaskTracker
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/lections/05/examples/tasktracker/templates/login.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Sign in - SimpleTaskTracker
6 |
10 |
13 |
14 |
15 |
19 |
20 |
21 |
22 | SimpleTaskTracker
23 |
24 |
25 |
26 |
33 |
34 |
35 |
36 |
37 |
38 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/lections/05/examples/tasktracker/users.json:
--------------------------------------------------------------------------------
1 | {
2 | "admin": {
3 | "password": "123"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/lections/05/examples/tasktracker/utils.py:
--------------------------------------------------------------------------------
1 | import json
2 | from flask import redirect, session
3 | from functools import wraps
4 |
5 | with open('users.json') as users_file:
6 | g_users = json.load(users_file)
7 |
8 | class User(object):
9 | def __init__(self, login):
10 | if login is not None and login in g_users:
11 | self.login = login
12 | self.anonymous = False
13 | self.password = g_users[login]["password"]
14 | else:
15 | self.anonymous = True
16 |
17 | def is_anonymous(self):
18 | return self.anonymous
19 |
20 | def is_authorized(self):
21 | return not self.anonymous
22 |
23 |
24 | def authorize(login, password):
25 | user = User(login)
26 | if not user.is_authorized():
27 | return user
28 | if user.password == password:
29 | return user
30 | return User(None)
31 |
32 | def get_user(login):
33 | return User(login)
34 |
35 | def authorized(fn):
36 | @wraps(fn)
37 | def wrapped(*args, **kwargs):
38 | user = get_user(session.get("user_login", None))
39 | if user.is_authorized():
40 | return fn(*args, **kwargs)
41 | else:
42 | return redirect('/login')
43 | return wrapped
44 |
45 | def not_authorized(fn):
46 | @wraps(fn)
47 | def wrapped():
48 | user = get_user(session.get("user_login", ""))
49 | if not user.is_authorized():
50 | return fn()
51 | else:
52 | return redirect('/')
53 | return wrapped
54 |
--------------------------------------------------------------------------------
/lections/05/slides/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Веб-программирование на Физтехе 2016-2017
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Веб-программирование на Физтехе 2016-2017
13 | Занятие 5. SimpleTaskTracker на Flask
14 |
15 |
42 |
45 |
46 |
49 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/lections/05/slides/pictures/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/05/slides/pictures/cover.jpg
--------------------------------------------------------------------------------
/lections/06/README.md:
--------------------------------------------------------------------------------
1 | ## Deployment
2 |
3 | **[Слайды](https://dbeliakov.github.io/mipt-web-2016/lections/06/slides/)**
4 |
5 | **[Скринкаст](https://youtu.be/3U6xAMuz3_4)**
6 |
7 | * [DigitalOcean](https://www.digitalocean.com)
8 | * [GitHub Student Developer Pack](https://education.github.com/pack)
9 | * [Byobu](https://en.wikipedia.org/wiki/Byobu_(software))
10 | * [Byobu shortcuts](https://help.ubuntu.com/community/Byobu)
11 | * [Gunicorn](http://gunicorn.org)
12 | * [Vagrant](https://www.vagrantup.com)
13 | * [VirtualEnv](https://github.com/pypa/virtualenv)
14 |
15 |
--------------------------------------------------------------------------------
/lections/06/slides/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Веб-программирование на Физтехе 2016-2017
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Веб-программирование на Физтехе 2016-2017
13 | Занятие 6. Deployment
14 |
15 |
42 |
57 |
58 |
66 |
67 |
75 |
76 |
85 |
86 |
107 |
108 |
116 |
117 |
123 |
124 |
131 |
132 |
146 |
147 |
154 |
155 |
158 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
--------------------------------------------------------------------------------
/lections/06/slides/pictures/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/06/slides/pictures/cover.jpg
--------------------------------------------------------------------------------
/lections/07/README.md:
--------------------------------------------------------------------------------
1 | ## Базы данных. SQL
2 |
3 | **[Слайды](https://dbeliakov.github.io/mipt-web-2016/lections/07/slides/)**
4 |
5 | **[Код](code)**
6 |
7 | **[Скринкаст](TBD)**
8 |
9 | * [Учебник по SQL](http://www.mysql.ru/docs/gruber/)
10 | * [Интерактивный учебник по SQL](http://www.sql-tutorial.ru)
11 |
12 |
--------------------------------------------------------------------------------
/lections/07/code/create.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE user_types (
2 | id INTEGER PRIMARY KEY AUTOINCREMENT,
3 | name VARCHAR(255)
4 | );
5 |
6 | CREATE TABLE users (
7 | id INTEGER PRIMARY KEY AUTOINCREMENT,
8 | first_name VARCHAR(255),
9 | last_name VARCHAR(255),
10 | active BOOLEAN,
11 | profile INTEGER,
12 | FOREIGN KEY(profile) REFERENCES user_types(id)
13 | );
14 |
15 |
--------------------------------------------------------------------------------
/lections/07/code/fill.sql:
--------------------------------------------------------------------------------
1 | INSERT INTO user_types (name) VALUES ("Student");
2 | INSERT INTO user_types (name) VALUES ("Teacher");
3 |
4 | INSERT INTO users (first_name, last_name, active, profile) VALUES ("Dmitrii", "Beliakov", 1, (SELECT id FROM user_types WHERE name = "Teacher"));
5 | INSERT INTO users (first_name, last_name, active, profile) VALUES ("Kamil", "Talipov", 1, (SELECT id FROM user_types WHERE name = "Teacher"));
6 | INSERT INTO users (first_name, last_name, active, profile) VALUES ("Ivan", "Ivanov", 0, (SELECT id FROM user_types WHERE name = "Student"));
7 | INSERT INTO users (first_name, last_name, active, profile) VALUES ("Petr", "Petrov", 0, (SELECT id FROM user_types WHERE name = "Student"));
8 | INSERT INTO users (first_name, last_name, active, profile) VALUES ("Petr", "Sidorov", 0, (SELECT id FROM user_types WHERE name = "Student"));
9 |
--------------------------------------------------------------------------------
/lections/07/code/select.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | import sqlite3
4 |
5 |
6 | connection = sqlite3.connect("test.db")
7 |
8 |
9 | def selectAllStudents():
10 | query = "SELECT users.first_name, users.last_name FROM users WHERE profile = (SELECT id FROM user_types WHERE name = \"Student\");"
11 | print query
12 | cursor = connection.cursor()
13 | cursor.execute(query)
14 |
15 | rows = cursor.fetchall()
16 |
17 | for row in rows:
18 | print row
19 |
20 | if __name__ == "__main__":
21 | selectAllStudents()
22 |
--------------------------------------------------------------------------------
/lections/07/code/select.sql:
--------------------------------------------------------------------------------
1 | SELECT * FROM users, user_types;
2 |
3 | SELECT user_types.name, users.first_name, users.last_name FROM users, user_types WHERE users.profile = user_types.id;
4 |
5 | SELECT COUNT(*) FROM users WHERE profile = (SELECT id FROM user_types WHERE name = "Student");
6 |
7 | SELECT COUNT(*), active FROM users GROUP BY active;
8 |
9 | SELECT COUNT(*), active FROM users GROUP BY active HAVING COUNT(*) > 2;
10 |
11 | SELECT COUNT(*), user_types.name FROM users, user_types WHERE users.profile = user_types.id GROUP BY user_types.name;
12 |
--------------------------------------------------------------------------------
/lections/07/code/update.sql:
--------------------------------------------------------------------------------
1 | UPDATE users SET profile = (SELECT id FROM user_types WHERE name = "Student") WHERE first_name = "Dmitrii" AND last_name = "Beliakov";
2 |
--------------------------------------------------------------------------------
/lections/07/slides/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Веб-программирование на Физтехе 2016-2017
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Веб-программирование на Физтехе 2016-2017
13 | Занятие 7. Базы данных. SQL
14 |
15 |
42 |
51 |
52 |
88 |
89 |
97 |
98 |
106 |
107 |
117 |
118 |
127 |
128 |
139 |
140 |
148 |
149 |
178 |
179 |
187 |
188 |
195 |
196 |
206 |
207 |
210 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
--------------------------------------------------------------------------------
/lections/07/slides/pictures/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/07/slides/pictures/cover.jpg
--------------------------------------------------------------------------------
/lections/08/README.md:
--------------------------------------------------------------------------------
1 | ## Базы данных. SQL
2 |
3 | **[Слайды](https://dbeliakov.github.io/mipt-web-2016/lections/08/slides/)**
4 |
5 | **[Код](code)**
6 |
7 | **[Скринкаст](TBD)**
8 |
9 | * [Официальный туториал](https://docs.djangoproject.com/en/1.10/intro/tutorial01/)
10 | * [DjangoBook.com](http://djangobook.com)
11 | * [DjBook.ru](http://djbook.ru/rel1.9/)
12 | * Книга Antonio Mele - Django by example
13 | * [Awesome Django](https://github.com/rosarior/awesome-django)
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/.DS_Store
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/db.sqlite3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/db.sqlite3
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/lessons/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/lessons/.DS_Store
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/lessons/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/lessons/__init__.py
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/lessons/__init__.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/lessons/__init__.pyc
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/lessons/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | import lessons.models
3 |
4 | admin.site.register(lessons.models.Lesson)
5 | admin.site.register(lessons.models.Problem)
6 | admin.site.register(lessons.models.Submission)
7 | admin.site.register(lessons.models.Test)
8 |
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/lessons/admin.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/lessons/admin.pyc
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/lessons/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.db import models, migrations
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ]
11 |
12 | operations = [
13 | migrations.CreateModel(
14 | name='Lesson',
15 | fields=[
16 | ('id', models.AutoField(verbose_name='ID', serialize=False, primary_key=True, auto_created=True)),
17 | ('title', models.TextField()),
18 | ('content', models.TextField()),
19 | ],
20 | options={
21 | },
22 | bases=(models.Model,),
23 | ),
24 | migrations.CreateModel(
25 | name='Problem',
26 | fields=[
27 | ('id', models.AutoField(verbose_name='ID', serialize=False, primary_key=True, auto_created=True)),
28 | ('title', models.TextField()),
29 | ('statement', models.TextField()),
30 | ('lesson', models.ForeignKey(to='lessons.Lesson')),
31 | ],
32 | options={
33 | },
34 | bases=(models.Model,),
35 | ),
36 | migrations.CreateModel(
37 | name='Submission',
38 | fields=[
39 | ('id', models.AutoField(verbose_name='ID', serialize=False, primary_key=True, auto_created=True)),
40 | ('code', models.TextField()),
41 | ('status', models.TextField(choices=[('OK', 'OK'), ('ER', 'Error')])),
42 | ('problem', models.ForeignKey(to='lessons.Problem')),
43 | ],
44 | options={
45 | },
46 | bases=(models.Model,),
47 | ),
48 | migrations.CreateModel(
49 | name='Test',
50 | fields=[
51 | ('id', models.AutoField(verbose_name='ID', serialize=False, primary_key=True, auto_created=True)),
52 | ('number', models.IntegerField(unique=True)),
53 | ('input', models.TextField()),
54 | ('answer', models.TextField()),
55 | ('problem', models.ForeignKey(to='lessons.Problem')),
56 | ],
57 | options={
58 | },
59 | bases=(models.Model,),
60 | ),
61 | ]
62 |
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/lessons/migrations/0001_initial.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/lessons/migrations/0001_initial.pyc
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/lessons/migrations/0002_auto_20170226_2056.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.db import models, migrations
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ('lessons', '0001_initial'),
11 | ]
12 |
13 | operations = [
14 | migrations.AddField(
15 | model_name='submission',
16 | name='info',
17 | field=models.TextField(blank=True),
18 | preserve_default=True,
19 | ),
20 | migrations.AlterField(
21 | model_name='submission',
22 | name='status',
23 | field=models.TextField(choices=[('OK', 'Correct'), ('RE', 'Run-time error'), ('WA', 'Wrong answer')]),
24 | preserve_default=True,
25 | ),
26 | ]
27 |
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/lessons/migrations/0002_auto_20170226_2056.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/lessons/migrations/0002_auto_20170226_2056.pyc
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/lessons/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/lessons/migrations/__init__.py
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/lessons/migrations/__init__.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/lessons/migrations/__init__.pyc
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/lessons/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 |
3 |
4 | class Lesson(models.Model):
5 | title = models.TextField()
6 | content = models.TextField()
7 |
8 | def __str__(self):
9 | return self.title
10 |
11 |
12 | class Problem(models.Model):
13 | title = models.TextField()
14 | statement = models.TextField()
15 | lesson = models.ForeignKey(Lesson)
16 |
17 | def __str__(self):
18 | return self.title
19 |
20 |
21 | class Test(models.Model):
22 | number = models.IntegerField(unique=True)
23 | input = models.TextField()
24 | answer = models.TextField()
25 | problem = models.ForeignKey(Problem)
26 |
27 | def __str__(self):
28 | return '{0}: {1}'.format(self.number, self.input)
29 |
30 |
31 | class Submission(models.Model):
32 | OK = 'OK'
33 | RE = 'RE'
34 | WA = 'WA'
35 | STATUSES = (
36 | (OK, 'Correct'),
37 | (RE, 'Run-time error'),
38 | (WA, 'Wrong answer'),
39 | )
40 |
41 | code = models.TextField()
42 | status = models.TextField(choices=STATUSES)
43 | problem = models.ForeignKey(Problem)
44 | info = models.TextField(blank=True)
45 |
46 | def __str__(self):
47 | return '{0} (status): {1}'.format(self.problem, self.status, self.code)
48 |
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/lessons/models.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/lessons/models.pyc
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/lessons/submission_testing.py:
--------------------------------------------------------------------------------
1 | from lessons.models import Submission
2 |
3 |
4 | def is_correst_answer_on_test(function, test):
5 | output = function(*eval(test.input))
6 | return str(output) == test.answer
7 |
8 |
9 | def test_submission(problem, source):
10 | info = ''
11 |
12 | try:
13 | sandbox = {}
14 | exec(source, globals(), sandbox)
15 | function = sandbox['action']
16 | if all(is_correst_answer_on_test(function=function, test=test)
17 | for test in problem.test_set.all()):
18 | status = Submission.OK
19 | else:
20 | status = Submission.WA
21 | except Exception as e:
22 | status = Submission.RE
23 | info = str(e)
24 |
25 | Submission(code=source, status=status, problem=problem, info=info).save()
26 |
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/lessons/submission_testing.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/lessons/submission_testing.pyc
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/lessons/templates/index.html:
--------------------------------------------------------------------------------
1 | Учебник Питона
2 |
3 | Уроки:
4 |
5 | {% for lesson in lessons %}
6 | - {{ lesson.title }}
7 | {% endfor %}
8 |
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/lessons/templates/lesson.html:
--------------------------------------------------------------------------------
1 | Уроки
2 |
3 | Урок {{ lesson.id }}: {{ lesson.title }}
4 |
5 | {{ lesson.content|safe }}
6 |
7 | Задачи:
8 |
9 | {% for problem in lesson.problem_set.all %}
10 | - {{ problem.title }}
11 | {% endfor %}
12 |
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/lessons/templates/problem.html:
--------------------------------------------------------------------------------
1 | Урок {{ problem.lesson.id }}: {{ problem.lesson.title }}
2 |
3 | Задача "{{ problem.title }}"
4 |
5 | {{ problem.statement|safe }}
6 |
7 |
15 |
16 |
17 |
18 | #
19 | Код
20 | Статус
21 | Комментарий
22 |
23 | {% for submission in problem.submission_set.all %}
24 |
25 | {{ submission.id }}
26 | {{ submission.code }}
27 | {{ submission.get_status_display }}
28 | {{ submission.info }}
29 |
30 | {% endfor %}
31 |
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/lessons/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/lessons/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls import url
2 |
3 | from lessons import views
4 |
5 | urlpatterns = [
6 | url(r'^$', views.index, name='index'),
7 | url(r'^lessons/(?P\d+)/$', views.lesson, name='lesson'),
8 | url(r'^problems/(?P\d+)/$', views.problem, name='problem'),
9 | url(r'^send_submission/(?P\d+)/$', views.send_submission, name='send_submission'),
10 | ]
11 |
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/lessons/urls.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/lessons/urls.pyc
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/lessons/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import redirect, render
2 |
3 | from lessons.models import Lesson, Problem
4 | from lessons.submission_testing import test_submission
5 |
6 |
7 | def index(request):
8 | lessons = Lesson.objects.all()
9 | return render(request, 'index.html', {'lessons': lessons})
10 |
11 |
12 | def lesson(request, lesson_id):
13 | lesson = Lesson.objects.get(id=lesson_id)
14 | return render(request, 'lesson.html', {'lesson': lesson})
15 |
16 |
17 | def problem(request, problem_id):
18 | problem = Problem.objects.get(id=problem_id)
19 | tests = problem.test_set.order_by('number')
20 | return render(request, 'problem.html', {'problem': problem, 'tests': tests})
21 |
22 |
23 | def send_submission(request, problem_id):
24 | problem = Problem.objects.get(id=problem_id)
25 | source = request.POST['source']
26 | test_submission(problem, source)
27 | return redirect('problem', problem_id=problem.id)
28 |
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/lessons/views.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/lessons/views.pyc
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import os
3 | import sys
4 |
5 | if __name__ == "__main__":
6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "testingplatform.settings")
7 |
8 | from django.core.management import execute_from_command_line
9 |
10 | execute_from_command_line(sys.argv)
11 |
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/testingplatform/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/testingplatform/__init__.py
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/testingplatform/__init__.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/testingplatform/__init__.pyc
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/testingplatform/settings.py:
--------------------------------------------------------------------------------
1 | """
2 | Django settings for testingplatform project.
3 |
4 | Generated by 'django-admin startproject' using Django 1.10.5.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/1.10/topics/settings/
8 |
9 | For the full list of settings and their values, see
10 | https://docs.djangoproject.com/en/1.10/ref/settings/
11 | """
12 |
13 | import os
14 |
15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
17 |
18 |
19 | # Quick-start development settings - unsuitable for production
20 | # See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/
21 |
22 | # SECURITY WARNING: keep the secret key used in production secret!
23 | SECRET_KEY = 'u4fu9&6vfo8#clac*=7q*ut)ie5#^*_g$isnw3h7v3x))@!rl4'
24 |
25 | # SECURITY WARNING: don't run with debug turned on in production!
26 | DEBUG = True
27 |
28 | ALLOWED_HOSTS = []
29 |
30 |
31 | # Application definition
32 |
33 | INSTALLED_APPS = [
34 | 'django.contrib.admin',
35 | 'django.contrib.auth',
36 | 'django.contrib.contenttypes',
37 | 'django.contrib.sessions',
38 | 'django.contrib.messages',
39 | 'django.contrib.staticfiles',
40 | 'lessons',
41 | ]
42 |
43 | MIDDLEWARE = [
44 | 'django.middleware.security.SecurityMiddleware',
45 | 'django.contrib.sessions.middleware.SessionMiddleware',
46 | 'django.middleware.common.CommonMiddleware',
47 | 'django.middleware.csrf.CsrfViewMiddleware',
48 | 'django.contrib.auth.middleware.AuthenticationMiddleware',
49 | 'django.contrib.messages.middleware.MessageMiddleware',
50 | 'django.middleware.clickjacking.XFrameOptionsMiddleware',
51 | ]
52 |
53 | ROOT_URLCONF = 'testingplatform.urls'
54 |
55 | TEMPLATES = [
56 | {
57 | 'BACKEND': 'django.template.backends.django.DjangoTemplates',
58 | 'DIRS': [],
59 | 'APP_DIRS': True,
60 | 'OPTIONS': {
61 | 'context_processors': [
62 | 'django.template.context_processors.debug',
63 | 'django.template.context_processors.request',
64 | 'django.contrib.auth.context_processors.auth',
65 | 'django.contrib.messages.context_processors.messages',
66 | ],
67 | },
68 | },
69 | ]
70 |
71 | WSGI_APPLICATION = 'testingplatform.wsgi.application'
72 |
73 |
74 | # Database
75 | # https://docs.djangoproject.com/en/1.10/ref/settings/#databases
76 |
77 | DATABASES = {
78 | 'default': {
79 | 'ENGINE': 'django.db.backends.sqlite3',
80 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
81 | }
82 | }
83 |
84 |
85 | # Password validation
86 | # https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
87 |
88 | AUTH_PASSWORD_VALIDATORS = [
89 | {
90 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
91 | },
92 | {
93 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
94 | },
95 | {
96 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
97 | },
98 | {
99 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
100 | },
101 | ]
102 |
103 |
104 | # Internationalization
105 | # https://docs.djangoproject.com/en/1.10/topics/i18n/
106 |
107 | LANGUAGE_CODE = 'en-us'
108 |
109 | TIME_ZONE = 'UTC'
110 |
111 | USE_I18N = True
112 |
113 | USE_L10N = True
114 |
115 | USE_TZ = True
116 |
117 |
118 | # Static files (CSS, JavaScript, Images)
119 | # https://docs.djangoproject.com/en/1.10/howto/static-files/
120 |
121 | STATIC_URL = '/static/'
122 |
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/testingplatform/settings.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/testingplatform/settings.pyc
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/testingplatform/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls import include, url
2 | from django.contrib import admin
3 |
4 | urlpatterns = [
5 | url(r'^', include('lessons.urls')),
6 | url(r'^admin/', include(admin.site.urls)),
7 | ]
8 |
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/testingplatform/urls.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/testingplatform/urls.pyc
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/testingplatform/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for testingplatform project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "testingplatform.settings")
12 |
13 | from django.core.wsgi import get_wsgi_application
14 | application = get_wsgi_application()
15 |
--------------------------------------------------------------------------------
/lections/08/code/testingplatform/testingplatform/wsgi.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/testingplatform/wsgi.pyc
--------------------------------------------------------------------------------
/lections/08/slides/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/slides/.DS_Store
--------------------------------------------------------------------------------
/lections/08/slides/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Веб-программирование на Физтехе 2016-2017
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Веб-программирование на Физтехе 2016-2017
13 | Занятие 8. Введение в Django и Django ORM
14 |
15 |
42 |
43 |
44 |
54 |
55 |
59 |
60 |
73 |
74 |
80 |
81 |
91 |
92 |
95 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/lections/08/slides/pictures/architecture.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/slides/pictures/architecture.jpg
--------------------------------------------------------------------------------
/lections/08/slides/pictures/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/slides/pictures/cover.jpg
--------------------------------------------------------------------------------
/lections/09/README.md:
--------------------------------------------------------------------------------
1 | ## SimpleForum на Django
2 |
3 | **[Код](code)**
4 |
5 | * [Официальный туториал](https://docs.djangoproject.com/en/1.10/intro/tutorial01/)
6 | * [DjangoBook.com](http://djangobook.com)
7 | * [DjBook.ru](http://djbook.ru/rel1.9/)
8 | * Книга Antonio Mele - Django by example
9 | * [Awesome Django](https://github.com/rosarior/awesome-django)
10 |
--------------------------------------------------------------------------------
/lections/09/code/simple_forum/db.sqlite3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/09/code/simple_forum/db.sqlite3
--------------------------------------------------------------------------------
/lections/09/code/simple_forum/forum/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/09/code/simple_forum/forum/__init__.py
--------------------------------------------------------------------------------
/lections/09/code/simple_forum/forum/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | import forum.models
3 |
4 | # Register your models here.
5 |
6 | admin.site.register(forum.models.Category)
7 | admin.site.register(forum.models.Thread)
8 | admin.site.register(forum.models.Message)
9 |
--------------------------------------------------------------------------------
/lections/09/code/simple_forum/forum/apps.py:
--------------------------------------------------------------------------------
1 | from __future__ import unicode_literals
2 |
3 | from django.apps import AppConfig
4 |
5 |
6 | class ForumConfig(AppConfig):
7 | name = 'forum'
8 |
--------------------------------------------------------------------------------
/lections/09/code/simple_forum/forum/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.10.6 on 2017-03-04 16:41
3 | from __future__ import unicode_literals
4 |
5 | from django.conf import settings
6 | from django.db import migrations, models
7 | import django.db.models.deletion
8 |
9 |
10 | class Migration(migrations.Migration):
11 |
12 | initial = True
13 |
14 | dependencies = [
15 | migrations.swappable_dependency(settings.AUTH_USER_MODEL),
16 | ]
17 |
18 | operations = [
19 | migrations.CreateModel(
20 | name='Category',
21 | fields=[
22 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
23 | ('title', models.TextField()),
24 | ('extended_info', models.TextField()),
25 | ('logo', models.ImageField(null=True, upload_to='category_logo/')),
26 | ],
27 | ),
28 | migrations.CreateModel(
29 | name='Message',
30 | fields=[
31 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
32 | ('text', models.TextField()),
33 | ('time', models.DateTimeField(auto_now_add=True)),
34 | ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
35 | ],
36 | ),
37 | migrations.CreateModel(
38 | name='UserProfile',
39 | fields=[
40 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
41 | ('avatar', models.ImageField(null=True, upload_to='avatar/')),
42 | ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
43 | ],
44 | ),
45 | migrations.CreateModel(
46 | name='Thread',
47 | fields=[
48 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
49 | ('title', models.TextField()),
50 | ('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='forum.Category')),
51 | ],
52 | ),
53 | ]
54 |
--------------------------------------------------------------------------------
/lections/09/code/simple_forum/forum/migrations/0002_message_thread.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.10.6 on 2017-03-05 07:39
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 | import django.db.models.deletion
7 |
8 |
9 | class Migration(migrations.Migration):
10 |
11 | dependencies = [
12 | ('forum', '0001_initial'),
13 | ]
14 |
15 | operations = [
16 | migrations.AddField(
17 | model_name='message',
18 | name='thread',
19 | field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='forum.Thread'),
20 | ),
21 | ]
22 |
--------------------------------------------------------------------------------
/lections/09/code/simple_forum/forum/migrations/0003_message_title.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.10.6 on 2017-03-07 18:03
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('forum', '0002_message_thread'),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name='message',
17 | name='title',
18 | field=models.TextField(null=True),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/lections/09/code/simple_forum/forum/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/09/code/simple_forum/forum/migrations/__init__.py
--------------------------------------------------------------------------------
/lections/09/code/simple_forum/forum/models.py:
--------------------------------------------------------------------------------
1 | from __future__ import unicode_literals
2 |
3 | from django.db import models
4 | from django.contrib.auth.models import User
5 |
6 |
7 | class UserProfile(models.Model):
8 | user = models.OneToOneField(User)
9 | avatar = models.ImageField(upload_to='avatar/', null=True)
10 |
11 |
12 | class Category(models.Model):
13 | title = models.TextField()
14 | extended_info = models.TextField()
15 | logo = models.ImageField(upload_to='category_logo/', null=True)
16 |
17 | def __unicode__(self):
18 | return self.title
19 |
20 |
21 | class Thread(models.Model):
22 | title = models.TextField()
23 | category = models.ForeignKey(Category)
24 |
25 | def __unicode__(self):
26 | return self.title
27 |
28 |
29 | class Message(models.Model):
30 | thread = models.ForeignKey(Thread, null=True)
31 | title = models.TextField(null=True)
32 | text = models.TextField()
33 | time = models.DateTimeField(auto_now_add=True)
34 | author = models.ForeignKey(User)
35 |
36 | def as_dict(self):
37 | return {
38 | 'text': self.text,
39 | 'author': str(self.author),
40 | }
41 |
42 | def __unicode__(self):
43 | return self.text
44 |
45 |
--------------------------------------------------------------------------------
/lections/09/code/simple_forum/forum/static/forum/css/navbar.css:
--------------------------------------------------------------------------------
1 | body {
2 | padding-top: 20px;
3 | padding-bottom: 20px;
4 | }
5 |
6 | .navbar {
7 | margin-bottom: 20px;
8 | }
9 |
10 |
--------------------------------------------------------------------------------
/lections/09/code/simple_forum/forum/static/forum/css/thread.css:
--------------------------------------------------------------------------------
1 | .message {
2 | margin-top: 10px;
3 | margin-left: 30px;
4 | }
5 |
6 | .author {
7 | color: red;
8 | }
--------------------------------------------------------------------------------
/lections/09/code/simple_forum/forum/static/forum/js/load_messages.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function() {
2 | function loadMessages() {
3 | $.get('/load_messages', {
4 | 'thread_id': $('#thread_id').val(),
5 | 'page_num': $('#page_num').val()
6 | }).done(function(data) {
7 | data.messages.forEach(function (message) {
8 | var row = $('');
9 | row.append($('
Войдите, пожалуйста
10 | 17 | 18 | {% if error %} 19 |{{ error }}
20 | {% endif %} 21 |Test page
\n" 17 | << "This is body of the test page...
\n" 18 | << "Request headers
\n" 19 | << "" << req << "\n" 20 | << "Test C++ Http Server\n"; 21 | 22 | std::stringstream response; 23 | response << "HTTP/1.1 200 OK\r\n" 24 | << "Version: HTTP/1.1\r\n" 25 | << "Content-Type: text/html; charset=utf-8\r\n" 26 | << "Content-Length: " << response_body.str().length() 27 | << "\r\n\r\n" 28 | << response_body.str(); 29 | 30 | return response.str(); 31 | } 32 | 33 | size_t read_complete(char * buff, const error_code & err, size_t bytes) { 34 | if (err) return 0; 35 | for (char* b = buff; b < buff + bytes - 3; ++b) { 36 | if (*b == '\r' && *(b + 1) == '\n' 37 | && *(b + 2) == '\r' && *(b + 3) == '\n') { 38 | return 0; 39 | } 40 | } 41 | return 1; 42 | } 43 | 44 | void handle_connections() { 45 | ip::tcp::acceptor acceptor(service, ip::tcp::endpoint(ip::tcp::v4(), 8001)); 46 | char buff[1024]; 47 | while (true) { 48 | ip::tcp::socket sock(service); 49 | acceptor.accept(sock); 50 | int bytes = read(sock, buffer(buff), 51 | boost::bind(read_complete, buff, _1, _2)); 52 | std::string msg(buff, bytes); 53 | sock.write_some(buffer(handle(msg))); 54 | sock.close(); 55 | } 56 | } 57 | 58 | int main() 59 | { 60 | handle_connections(); 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /lections/04/slides/pictures/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/04/slides/pictures/cover.jpg -------------------------------------------------------------------------------- /lections/05/README.md: -------------------------------------------------------------------------------- 1 | ## SimpleTaskTracker на Flask 2 | 3 | **[Слайды](https://dbeliakov.github.io/mipt-web-2016/lections/05/slides/)** 4 | 5 | **[Скринкаст](https://youtu.be/lh0EKMfHZP0)** 6 | 7 | * [Исходный код SimpleTaskTracker](examples/tasktracker) 8 | -------------------------------------------------------------------------------- /lections/05/examples/tasktracker/app.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from flask import Flask, abort, render_template, request, jsonify, session, redirect 4 | from utils import * 5 | from db import * 6 | 7 | app = Flask("SimpleTaskTracker") 8 | template_dir = 'templates' 9 | 10 | @app.route('/', methods=['GET']) 11 | @authorized 12 | def index(): 13 | return render_template('index.html') 14 | 15 | @app.route('/login', methods=["GET"]) 16 | @not_authorized 17 | def login(): 18 | return render_template('login.html') 19 | 20 | @app.route('/api/login', methods=["POST"]) 21 | @not_authorized 22 | def api_login(): 23 | login = request.form.get('login', None) 24 | password = request.form.get('password', None) 25 | if login is None or password is None: 26 | return jsonify({'status': 'error', 'message': 'Неверные данные для входа'}) 27 | user = authorize(login, password) 28 | if user.is_authorized(): 29 | session['user_login'] = login 30 | return jsonify({'status': 'ok'}) 31 | return jsonify({'status': 'error', 'message': 'Неверные данные для входа'}) 32 | 33 | @app.route('/logout', methods=["GET"]) 34 | @authorized 35 | def logout(): 36 | session.clear() 37 | return redirect('/login') 38 | 39 | @app.route('/api/tasks', methods=["GET"]) 40 | @authorized 41 | def api_tasks(): 42 | login = session['user_login'] 43 | return jsonify({"tasks": get_tasks(login)}) 44 | 45 | @app.route('/api/remove_task/
SimpleTaskTracker
23 |SimpleTaskTracker
23 |Веб-программирование на Физтехе 2016-2017
13 |Занятие 5. SimpleTaskTracker на Flask
14 |Веб-программирование на Физтехе 2016-2017
13 |Занятие 6. Deployment
14 |Веб-программирование на Физтехе 2016-2017
13 |Занятие 7. Базы данных. SQL
14 |Учебник Питона
2 | 3 | Уроки: 4 |-
5 | {% for lesson in lessons %}
6 |
- {{ lesson.title }} 7 | {% endfor %} 8 |
Урок {{ lesson.id }}: {{ lesson.title }}
4 | 5 | {{ lesson.content|safe }} 6 | 7 | Задачи: 8 |-
9 | {% for problem in lesson.problem_set.all %}
10 |
- {{ problem.title }} 11 | {% endfor %} 12 |
Задача "{{ problem.title }}"
4 | 5 | {{ problem.statement|safe }} 6 | 7 | 15 | 16 |# | 19 |Код | 20 |Статус | 21 |Комментарий | 22 |
---|---|---|---|
{{ submission.id }} | 26 |{{ submission.code }} |
27 | {{ submission.get_status_display }} | 28 |{{ submission.info }} | 29 |
Веб-программирование на Физтехе 2016-2017
13 |Занятие 8. Введение в Django и Django ORM
14 |