Skip to content

Commit

Permalink
Merge branch 'master' of github.com:park-python/course
Browse files Browse the repository at this point in the history
  • Loading branch information
zhebrak committed Dec 13, 2016
2 parents 5284dfe + 449d6db commit a026bef
Show file tree
Hide file tree
Showing 26 changed files with 493 additions and 34 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -95,3 +95,6 @@ ENV/

# Rope project settings
.ropeproject

lectures/09_Web_Development/project/env
lectures/09_Web_Development/project/music/sqlite3.db
34 changes: 0 additions & 34 deletions lectures/09_Web_Development/12_web_development.ipynb

This file was deleted.

Empty file.
20 changes: 20 additions & 0 deletions lectures/09_Web_Development/project/music/core/admin.py
@@ -0,0 +1,20 @@
from django.contrib import admin

from .models import Artist, Genre, Ruble

# Register your models here.


@admin.register(Artist)
class ArtistAdmin(admin.ModelAdmin):
pass


@admin.register(Genre)
class GenreAdmin(admin.ModelAdmin):
pass


@admin.register(Ruble)
class RubleAdmin(admin.ModelAdmin):
pass
5 changes: 5 additions & 0 deletions lectures/09_Web_Development/project/music/core/apps.py
@@ -0,0 +1,5 @@
from django.apps import AppConfig


class CoreConfig(AppConfig):
name = 'core'
@@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.3 on 2016-11-22 17:00
from __future__ import unicode_literals

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

initial = True

dependencies = [
]

operations = [
migrations.CreateModel(
name='Artist',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)),
],
),
migrations.CreateModel(
name='Genre',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=255)),
],
),
migrations.CreateModel(
name='Ruble',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('nominal', models.IntegerField(default=1)),
('artist', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='core.Artist')),
],
),
migrations.AddField(
model_name='artist',
name='genres',
field=models.ManyToManyField(blank=True, null=True, to='core.Genre'),
),
]
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.3 on 2016-12-05 06:27
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('core', '0001_initial'),
]

operations = [
migrations.AddField(
model_name='artist',
name='avatar',
field=models.CharField(blank=True, max_length=255, null=True),
),
]
Empty file.
48 changes: 48 additions & 0 deletions lectures/09_Web_Development/project/music/core/models.py
@@ -0,0 +1,48 @@
from django.db import models
import cent


class Genre(models.Model):
title = models.CharField(max_length=255)

def __str__(self):
return self.title


class Artist(models.Model):
name = models.CharField(max_length=255)
avatar = models.CharField(max_length=255, blank=True, null=True)
genres = models.ManyToManyField(Genre, blank=True, null=True)

def calculate_capital(self):
capital = self.ruble_set.aggregate(nominal=models.Sum("nominal"))
return capital.get('nominal') or 0

def __str__(self):
return self.name


class Ruble(models.Model):
nominal = models.IntegerField(default=1)
artist = models.ForeignKey(Artist, blank=True, null=True)

def __str__(self):
return "{} ({})".format(self.nominal, self.artist.name)

def push_capital(self):
client = cent.Client("http://localhost:9000", "secret", timeout=1)
try:
client.publish("updates", {
"artist": self.artist.id,
"capital": self.artist.calculate_capital()
})
except cent.CentException:
pass

def delete(self, **kwargs):
super(Ruble, self).delete(**kwargs)
self.push_capital()

def save(self, **kwargs):
super(Ruble, self).save(**kwargs)
self.push_capital()
@@ -0,0 +1,77 @@
*, *:before, *:after {
box-sizing: border-box;
}

body, html {
margin: 0;
padding: 0;
background-color: #2C1B35;
}

.table {
display: table;
width: 100%;
position: absolute;
height: 100%;
}

.table-cell {
display: table-cell;
vertical-align: middle;
}

.leader {
list-style-type: none;
padding: 0;
margin: 0 auto;
width: 420px;
height: 390px;
}

.leader li {
background-color: #fff;
border-radius: 5px;
height: 100px;
margin-bottom: 10px;
overflow: hidden;
box-shadow: 0 5px 5px rgba(0, 0, 0, 0.1);
}

.leader li .list_num {
float: left;
line-height: 40px;
font-size: 18px;
color: rgba(0, 0, 0, 0.65);
margin: 15px;
font-weight: bold;
width: 20px;
text-align: right;
margin-left: 10px;
}

.leader li h2 {
display: block;
margin: 0;
font-size: 18px;
line-height: 40px;
font-weight: 300;
margin-top: 15px;
padding-right: 20px;
}

.leader li h2 .number {
float: right;
font-weight: bold;
color: rgba(0, 0, 0, 0.65);
-webkit-transition: color 0.3s;
transition: color 0.3s;
}

.leader li img {
width: 80px;
height: 80px;
float: left;
margin: 15px 20px;
margin-left: 0;
border-radius: 100%;
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

Large diffs are not rendered by default.

@@ -0,0 +1,35 @@
$(function () {
var centrifuge = new Centrifuge({
"url": "http://localhost:9000/connection/websocket",
"insecure": true
});
centrifuge.subscribe("updates", function(message) {
handleUpdate(message);
});
centrifuge.connect();
});

function handleUpdate(message) {
console.log(message);
var artistID = message.data.artist;
var capital = message.data.capital;
var artist = $("#artist"+artistID);
var num = artist.find(".number");
num.text(capital);
sort();
}

function sort() {
var leaderBoard = $('#leaderboard');
var artists = leaderBoard.find('li');

artists.sort(function (a, b) {
var numA = parseInt($(a).find('.number').text());
var numB = parseInt($(b).find('.number').text());
return (numA < numB) ? 1 : (numA > numB) ? -1 : 0;
}).appendTo(leaderBoard);

artists.each(function(index, elem) {
$(elem).find(".list_num").text(index+1);
});
}

Large diffs are not rendered by default.

@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="/static/core/css/core.css">
<script type="text/javascript" src="/static/core/js/jquery.min.js"></script>
<script type="text/javascript" src="/static/core/js/centrifuge.min.js"></script>
<script type="text/javascript" src="/static/core/js/core.js"></script>
</head>
<body>
<div class="table">
<div class="table-cell">
<ul class="leader" id="leaderboard">
{% for artist in artists %}
<li id="artist{{ artist.pk }}">
<span class="list_num">
{{ forloop.counter }}
</span>
<img src="{{ artist.avatar }}" />
<h2>
{{ artist.name }}<span class="number">{% firstof artist.capital "0" %}</span>
</h2>
</li>
{% endfor %}
</ul>
</div>
</div>
</body>
</html>
3 changes: 3 additions & 0 deletions lectures/09_Web_Development/project/music/core/tests.py
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
16 changes: 16 additions & 0 deletions lectures/09_Web_Development/project/music/core/views.py
@@ -0,0 +1,16 @@
from django.shortcuts import render_to_response
from core.models import Artist
from django.db.models import Sum


def leaderboard_index(request):

artists = Artist.objects.annotate(
capital=Sum("ruble__nominal")
).order_by('-capital')

context = {
"artists": artists
}

return render_to_response("index.html", context=context)
22 changes: 22 additions & 0 deletions lectures/09_Web_Development/project/music/manage.py
@@ -0,0 +1,22 @@
#!/usr/bin/env python
import os
import sys

if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "music.settings")
try:
from django.core.management import execute_from_command_line
except ImportError:
# The above import may fail for some other reason. Ensure that the
# issue is really that Django is missing to avoid masking other
# exceptions on Python 2.
try:
import django
except ImportError:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
)
raise
execute_from_command_line(sys.argv)
Empty file.

0 comments on commit a026bef

Please sign in to comment.