integrated responder framework
This commit is contained in:
		
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
__pycache__/
 | 
			
		||||
venv/
 | 
			
		||||
.idea/
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										11
									
								
								app_instance.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								app_instance.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
import responder
 | 
			
		||||
 | 
			
		||||
# CORS wasn't demoed in the course, but is required to be used from
 | 
			
		||||
# external apps like movie exploder.
 | 
			
		||||
 | 
			
		||||
cors_params = {
 | 
			
		||||
    'allow_origins': '*',
 | 
			
		||||
    'allow_methods': '*',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
api = responder.API(cors=True, cors_params=cors_params)
 | 
			
		||||
							
								
								
									
										33
									
								
								css/docs.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								css/docs.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
.request {
 | 
			
		||||
    font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    border: 1px solid gray;
 | 
			
		||||
    border-radius: 5px;
 | 
			
		||||
    padding: 10px;
 | 
			
		||||
    font-size: 24px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.get {
 | 
			
		||||
    color: #2b542c;
 | 
			
		||||
    background-color: #beffbd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.post {
 | 
			
		||||
    color: #ae5900;
 | 
			
		||||
    background-color: #ffc79d;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.response_formats span {
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    color: darkred;
 | 
			
		||||
    font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pre {
 | 
			
		||||
    font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ul li {
 | 
			
		||||
    font-size: 18px;
 | 
			
		||||
    margin-bottom: 10px;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										184
									
								
								css/theme.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								css/theme.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,184 @@
 | 
			
		||||
@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);
 | 
			
		||||
 | 
			
		||||
body {
 | 
			
		||||
    font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
 | 
			
		||||
    font-weight: 300;
 | 
			
		||||
    color: black;
 | 
			
		||||
    background: white;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
h1,
 | 
			
		||||
h2,
 | 
			
		||||
h3,
 | 
			
		||||
h4,
 | 
			
		||||
h5,
 | 
			
		||||
h6 {
 | 
			
		||||
    font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
 | 
			
		||||
    font-weight: 300;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
p {
 | 
			
		||||
    font-weight: 300;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.font-normal {
 | 
			
		||||
    font-weight: 400;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.font-semi-bold {
 | 
			
		||||
    font-weight: 600;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.font-bold {
 | 
			
		||||
    font-weight: 700;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.starter-template {
 | 
			
		||||
    margin-top: 25px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.starter-template .content {
 | 
			
		||||
    margin-left: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.starter-template .content h1 {
 | 
			
		||||
    margin-top: 10px;
 | 
			
		||||
    font-size: 60px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.starter-template .content h1 .smaller {
 | 
			
		||||
    font-size: 40px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.starter-template .content .lead {
 | 
			
		||||
    font-size: 25px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.starter-template .links {
 | 
			
		||||
    float: right;
 | 
			
		||||
    right: 0;
 | 
			
		||||
    margin-top: 125px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.starter-template .links ul {
 | 
			
		||||
    display: block;
 | 
			
		||||
    padding: 0;
 | 
			
		||||
    margin: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.starter-template .links ul li {
 | 
			
		||||
    list-style: none;
 | 
			
		||||
    display: inline;
 | 
			
		||||
    margin: 0 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.starter-template .links ul li:first-child {
 | 
			
		||||
    margin-left: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.starter-template .links ul li:last-child {
 | 
			
		||||
    margin-right: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.starter-template .links ul li.current-version {
 | 
			
		||||
    font-weight: 400;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.starter-template .links ul li a, a {
 | 
			
		||||
    text-decoration: underline;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.starter-template .links ul li a:hover, a:hover {
 | 
			
		||||
    text-decoration: underline;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.starter-template .links ul li .icon-muted {
 | 
			
		||||
    margin-right: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.starter-template .copyright {
 | 
			
		||||
    margin-top: 10px;
 | 
			
		||||
    font-size: 0.9em;
 | 
			
		||||
    text-transform: lowercase;
 | 
			
		||||
    float: right;
 | 
			
		||||
    right: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media (max-width: 1199px) {
 | 
			
		||||
    .starter-template .content h1 {
 | 
			
		||||
        font-size: 45px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .starter-template .content h1 .smaller {
 | 
			
		||||
        font-size: 30px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .starter-template .content .lead {
 | 
			
		||||
        font-size: 20px;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media (max-width: 991px) {
 | 
			
		||||
    .starter-template {
 | 
			
		||||
        margin-top: 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .starter-template .logo {
 | 
			
		||||
        margin: 40px auto;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .starter-template .content {
 | 
			
		||||
        margin-left: 0;
 | 
			
		||||
        text-align: center;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .starter-template .content h1 {
 | 
			
		||||
        margin-bottom: 20px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .starter-template .links {
 | 
			
		||||
        float: none;
 | 
			
		||||
        text-align: center;
 | 
			
		||||
        margin-top: 60px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .starter-template .copyright {
 | 
			
		||||
        float: none;
 | 
			
		||||
        text-align: center;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media (max-width: 767px) {
 | 
			
		||||
    .starter-template .content h1 .smaller {
 | 
			
		||||
        font-size: 25px;
 | 
			
		||||
        display: block;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .starter-template .content .lead {
 | 
			
		||||
        font-size: 16px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .starter-template .links {
 | 
			
		||||
        margin-top: 40px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .starter-template .links ul li {
 | 
			
		||||
        display: block;
 | 
			
		||||
        margin: 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .starter-template .links ul li .icon-muted {
 | 
			
		||||
        display: none;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .starter-template .copyright {
 | 
			
		||||
        margin-top: 20px;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.disclaimer {
 | 
			
		||||
    margin-top: 20px;
 | 
			
		||||
    font-style: italic;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								routes.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								routes.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
# noinspection PyUnresolvedReferences
 | 
			
		||||
from app_instance import api
 | 
			
		||||
# noinspection PyUnresolvedReferences
 | 
			
		||||
from views.api_views import *
 | 
			
		||||
# noinspection PyUnresolvedReferences
 | 
			
		||||
from views.home import *
 | 
			
		||||
# noinspection PyUnresolvedReferences
 | 
			
		||||
from views.temp_css import *
 | 
			
		||||
# noinspection PyUnresolvedReferences
 | 
			
		||||
from views.player import *
 | 
			
		||||
 | 
			
		||||
api.add_route("/static", static=True)
 | 
			
		||||
							
								
								
									
										120
									
								
								server.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										120
									
								
								server.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@@ -1,90 +1,48 @@
 | 
			
		||||
import time
 | 
			
		||||
#!/usr/bin/env python3
 | 
			
		||||
 | 
			
		||||
import random
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Karten: 1-13 in Blau, Rot, Gelb, Gruen und 4xZ und 4xN
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def chunks(lst, n):
 | 
			
		||||
    """Yield successive n-sized chunks from lst."""
 | 
			
		||||
    for i in range(0, len(lst), n):
 | 
			
		||||
        yield lst[i:i + n]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Card:
 | 
			
		||||
    def __init__(self, color, value):
 | 
			
		||||
        self.color = color
 | 
			
		||||
        self.value = value
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        sc = self.color if self.color else ' '
 | 
			
		||||
        sv = str(self.value)
 | 
			
		||||
        return sc+' '+sv
 | 
			
		||||
 | 
			
		||||
    def __repr__(self):
 | 
			
		||||
        return str(self)
 | 
			
		||||
 | 
			
		||||
class Player:
 | 
			
		||||
    def __init__(self, name, player_id):
 | 
			
		||||
        self.name = name
 | 
			
		||||
        self.id = player_id
 | 
			
		||||
        self.cards = []
 | 
			
		||||
 | 
			
		||||
    def deal_cards(self, cards):
 | 
			
		||||
        self.cards = cards
 | 
			
		||||
 | 
			
		||||
    def show_cards(self):
 | 
			
		||||
        print(self.cards)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class WizGame:
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.players = []
 | 
			
		||||
        self.card_deck = []
 | 
			
		||||
 | 
			
		||||
    def create_deck(self):
 | 
			
		||||
        for color in ["blue", "red", "green", "yellow"]:
 | 
			
		||||
            for val in range(1,14):
 | 
			
		||||
                self.card_deck.append(Card(color, val))
 | 
			
		||||
        for _ in range(1,5):
 | 
			
		||||
            self.card_deck.append(Card(None, 'Z'))
 | 
			
		||||
        for _ in range(1,5):
 | 
			
		||||
            self.card_deck.append(Card(None, 'N'))
 | 
			
		||||
        print("carddeck:")
 | 
			
		||||
        print(self.card_deck)
 | 
			
		||||
 | 
			
		||||
    def deal_cards(self):
 | 
			
		||||
        random.shuffle(self.card_deck)
 | 
			
		||||
        num_cards = int(len(self.card_deck)/len(self.players))
 | 
			
		||||
        print(num_cards)
 | 
			
		||||
        cs = list(chunks(self.card_deck, num_cards))
 | 
			
		||||
        for i in range(len(self.players)):
 | 
			
		||||
            self.players[i].deal_cards(cs[i])
 | 
			
		||||
            self.players[i].show_cards()
 | 
			
		||||
 | 
			
		||||
    def add_player(self, name: str, player_id):
 | 
			
		||||
        if len(self.players) < 6:
 | 
			
		||||
            self.players.append((Player(name, player_id)))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import socket
 | 
			
		||||
import responder
 | 
			
		||||
from app_instance import api
 | 
			
		||||
from routes import *
 | 
			
		||||
import wiz_game
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
    print("main started")
 | 
			
		||||
    w = WizGame()
 | 
			
		||||
    w.create_deck()
 | 
			
		||||
    w.add_player("p1", 1)
 | 
			
		||||
    w.add_player("p2", 2)
 | 
			
		||||
    w.add_player("p3", 3)
 | 
			
		||||
    w.add_player("p4", 4)
 | 
			
		||||
    w.deal_cards()
 | 
			
		||||
    print("round 2")
 | 
			
		||||
    w.deal_cards()
 | 
			
		||||
    print("round 3")
 | 
			
		||||
    w.deal_cards()
 | 
			
		||||
    print("round 4")
 | 
			
		||||
    w.deal_cards()
 | 
			
		||||
 | 
			
		||||
    random.seed()
 | 
			
		||||
 | 
			
		||||
    wiz_game.the_game.create_deck()
 | 
			
		||||
    wiz_game.the_game.add_player("p1", 1)
 | 
			
		||||
    wiz_game.the_game.add_player("p2", 2)
 | 
			
		||||
    wiz_game.the_game.add_player("p3", 3)
 | 
			
		||||
    wiz_game.the_game.add_player("p4", 4)
 | 
			
		||||
    wiz_game.the_game.deal_cards(4)
 | 
			
		||||
 | 
			
		||||
    api.run(port=19203, address="127.0.0.1")
 | 
			
		||||
    exit(0)
 | 
			
		||||
 | 
			
		||||
#    w.create_deck()
 | 
			
		||||
#    w.add_player("p1", 1)
 | 
			
		||||
#    w.add_player("p2", 2)
 | 
			
		||||
#    w.add_player("p3", 3)
 | 
			
		||||
#    w.add_player("p4", 4)
 | 
			
		||||
#    w.deal_cards(1)
 | 
			
		||||
#    print("round 2")
 | 
			
		||||
#    w.deal_cards(2)
 | 
			
		||||
#    print("round 3")
 | 
			
		||||
#    w.deal_cards(3)
 | 
			
		||||
#    print("round 4")
 | 
			
		||||
#    w.deal_cards(4)
 | 
			
		||||
#    print("round 12")
 | 
			
		||||
#    w.deal_cards(12)
 | 
			
		||||
#    print("round 13")
 | 
			
		||||
#    w.deal_cards(13)
 | 
			
		||||
#    print("round 14")
 | 
			
		||||
#    w.deal_cards(14)
 | 
			
		||||
#    print("round 15")
 | 
			
		||||
#    w.deal_cards(15)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    main()
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										51
									
								
								templates/home/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								templates/home/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
{% extends "/shared/_layout.html" %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
 | 
			
		||||
        <div class="content">
 | 
			
		||||
            <h1><span class="font-semi-bold">Gambling Foo</span> <span class="smaller">A RESTful gaming service</span></h1>
 | 
			
		||||
            <p class="lead">
 | 
			
		||||
                Play a nice game of cards?<br>
 | 
			
		||||
                <br>
 | 
			
		||||
                <strong>Endpoints</strong>
 | 
			
		||||
            <ul>
 | 
			
		||||
                <li>
 | 
			
		||||
                    <strong>Shuffle Card Deck</strong><br>
 | 
			
		||||
                    <a href="/api/shuffle">GET /api/shuffle</a>
 | 
			
		||||
                </li>
 | 
			
		||||
                <li>
 | 
			
		||||
                    <strong>Movies by director</strong><br>
 | 
			
		||||
                    <a href="/api/director/cameron">GET /api/director/{director_name}</a>
 | 
			
		||||
                </li>
 | 
			
		||||
<!--
 | 
			
		||||
                <li>
 | 
			
		||||
                    <strong>Movie by IMDB code</strong><br>
 | 
			
		||||
                    <a href="/api/movie/tt0096754">GET /api/movie/{imdb_number}</a>
 | 
			
		||||
                </li>
 | 
			
		||||
                <li>
 | 
			
		||||
                    <strong>Top 10 Movies (by IMDB score)</strong><br>
 | 
			
		||||
                    <a href="/api/movie/top">GET /api/movie/top</a>
 | 
			
		||||
                </li>
 | 
			
		||||
                <li>
 | 
			
		||||
                    <strong>All genres</strong><br>
 | 
			
		||||
                    <a href="/api/movie/genre/all">GET /api/movie/genre/all</a>
 | 
			
		||||
                </li>
 | 
			
		||||
                <li>
 | 
			
		||||
                    <strong>Top movies for a given genres</strong><br>
 | 
			
		||||
                    <a href="/api/movie/genre/sci-fi">GET /api/movie/genre/{genre}</a>
 | 
			
		||||
                </li>
 | 
			
		||||
-->
 | 
			
		||||
            </ul>
 | 
			
		||||
            </p>
 | 
			
		||||
 | 
			
		||||
            <p class="disclaimer">
 | 
			
		||||
                Spam Bacon Sausage + Spam
 | 
			
		||||
                Spam Spam Spam Spam Spam
 | 
			
		||||
                  Spam Baked Beans Spam
 | 
			
		||||
                  Spam Spam + Spam
 | 
			
		||||
 | 
			
		||||
            </p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{% endblock %}
 | 
			
		||||
							
								
								
									
										50
									
								
								templates/home/player.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								templates/home/player.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
			
		||||
{% extends "/shared/_layout.html" %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
 | 
			
		||||
        <div class="content">
 | 
			
		||||
            <h1><span class="font-semi-bold">Gambling Foo</span> <span class="smaller">A RESTful gaming service</span></h1>
 | 
			
		||||
            <p class="lead">
 | 
			
		||||
                Play a nice game of cards?<br>
 | 
			
		||||
                <br>
 | 
			
		||||
                <strong>Player {{player}} view</strong>
 | 
			
		||||
            <table style="width:100%">
 | 
			
		||||
                <tr>
 | 
			
		||||
                {% for card in cards %}
 | 
			
		||||
                    <li>
 | 
			
		||||
                        <strong>>card {{loop.index}} is: {{card}} </strong><br>
 | 
			
		||||
                    </li>
 | 
			
		||||
                {% endfor %}
 | 
			
		||||
                    
 | 
			
		||||
<!--
 | 
			
		||||
                <li>
 | 
			
		||||
                    <strong>Movie by IMDB code</strong><br>
 | 
			
		||||
                    <a href="/api/movie/tt0096754">GET /api/movie/{imdb_number}</a>
 | 
			
		||||
                </li>
 | 
			
		||||
                <li>
 | 
			
		||||
                    <strong>Top 10 Movies (by IMDB score)</strong><br>
 | 
			
		||||
                    <a href="/api/movie/top">GET /api/movie/top</a>
 | 
			
		||||
                </li>
 | 
			
		||||
                <li>
 | 
			
		||||
                    <strong>All genres</strong><br>
 | 
			
		||||
                    <a href="/api/movie/genre/all">GET /api/movie/genre/all</a>
 | 
			
		||||
                </li>
 | 
			
		||||
                <li>
 | 
			
		||||
                    <strong>Top movies for a given genres</strong><br>
 | 
			
		||||
                    <a href="/api/movie/genre/sci-fi">GET /api/movie/genre/{genre}</a>
 | 
			
		||||
                </li>
 | 
			
		||||
-->
 | 
			
		||||
            </table>
 | 
			
		||||
            </p>
 | 
			
		||||
 | 
			
		||||
            <p class="disclaimer">
 | 
			
		||||
                Spam Bacon Sausage + Spam
 | 
			
		||||
                Spam Spam Spam Spam Spam
 | 
			
		||||
                  Spam Baked Beans Spam
 | 
			
		||||
                  Spam Spam + Spam
 | 
			
		||||
 | 
			
		||||
            </p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{% endblock %}
 | 
			
		||||
							
								
								
									
										64
									
								
								templates/shared/_layout.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								templates/shared/_layout.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html >
 | 
			
		||||
<head>
 | 
			
		||||
    <meta charset="utf-8">
 | 
			
		||||
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
			
		||||
    <meta name="description" content="pyramid web application">
 | 
			
		||||
    <meta name="author" content="Pylons Project">
 | 
			
		||||
 | 
			
		||||
    <title>MovieDB Service</title>
 | 
			
		||||
 | 
			
		||||
    <!-- Bootstrap core CSS -->
 | 
			
		||||
    <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
 | 
			
		||||
 | 
			
		||||
    <!-- Custom styles for this scaffold -->
 | 
			
		||||
    <link href="/css/theme.css" rel="stylesheet">
 | 
			
		||||
    <link href="/css/docs.css" rel="stylesheet">
 | 
			
		||||
 | 
			
		||||
    <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
 | 
			
		||||
    <!--[if lt IE 9]>
 | 
			
		||||
    <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
 | 
			
		||||
    <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
 | 
			
		||||
    <![endif]-->
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body>
 | 
			
		||||
 | 
			
		||||
<div class="starter-template">
 | 
			
		||||
    <div class="container">
 | 
			
		||||
        <div class="row">
 | 
			
		||||
            <div class="col-md-2">
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="col-md-10">
 | 
			
		||||
                <div>{% block content %}{% endblock %}</div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="row">
 | 
			
		||||
            <div class="links">
 | 
			
		||||
                <ul>
 | 
			
		||||
                    <li><i class="glyphicon glyphicon-cog icon-muted"></i><a
 | 
			
		||||
                            href="https://github.com/mikeckennedy/python-jumpstart-course-demos"
 | 
			
		||||
                            target="_blank">Github Project</a></li>
 | 
			
		||||
                    <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="https://twitter.com/talkpython"
 | 
			
		||||
                                                                               target="_blank">Twitter</a>
 | 
			
		||||
                    </li>
 | 
			
		||||
                </ul>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="row">
 | 
			
		||||
            <div class="copyright">
 | 
			
		||||
                Copyright © Talk Python Training
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<!-- Bootstrap core JavaScript
 | 
			
		||||
================================================== -->
 | 
			
		||||
<!-- Placed at the end of the document so the pages load faster -->
 | 
			
		||||
<script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script>
 | 
			
		||||
<script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										39
									
								
								views/api_views.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								views/api_views.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
from responder import Response
 | 
			
		||||
 | 
			
		||||
from app_instance import api
 | 
			
		||||
 | 
			
		||||
response_count_max = 10
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@api.route("/api/search/{keyword}")
 | 
			
		||||
def search_keyword(req, resp, keyword: str):
 | 
			
		||||
    resp.media = {'keyword': keyword, 'hits': "movie_dicts", 'truncated_results': "limited"}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@api.route("/api/director/{director_name}")
 | 
			
		||||
def search_director(_, resp, director_name: str):
 | 
			
		||||
    resp.media = {'keyword': director_name, 'hits': "movies_dicts", 'truncated_results': "limited"}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@api.route("/api/movie/genre/{genre}")
 | 
			
		||||
def movies_by_genre(_, resp: Response, genre: str):
 | 
			
		||||
    resp.media = {'genre': genre, 'hits': "hits_dicts", 'truncated_results': "limited"}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@api.route("/api/movie/{imdb_number}")
 | 
			
		||||
def search_imdb(_, resp, imdb_number: str):
 | 
			
		||||
    resp.media = {'foo': "bar"}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@api.route("/api/movie/top")
 | 
			
		||||
def top_movies(_, resp: Response):
 | 
			
		||||
    resp.media = {'keyword': "keyword", 'hits': "hits_dicts", 'truncated_results': "limited"}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@api.route("/api/movie/genre/all")
 | 
			
		||||
def all_genres(_, resp: Response):
 | 
			
		||||
    resp.media = {"all": "stuff"}
 | 
			
		||||
 | 
			
		||||
@api.route("/api/shuffle")
 | 
			
		||||
def cards_shuffle(_, resp: Response):
 | 
			
		||||
    resp.media = {"shuffled": "done"}
 | 
			
		||||
							
								
								
									
										6
									
								
								views/home.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								views/home.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
from app_instance import api
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@api.route("/")
 | 
			
		||||
def index(req, resp):
 | 
			
		||||
    resp.content = api.template('home/index.html')
 | 
			
		||||
							
								
								
									
										11
									
								
								views/player.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								views/player.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
from app_instance import api
 | 
			
		||||
 | 
			
		||||
from wiz_game import the_game
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@api.route("/player/{player}")
 | 
			
		||||
def index(req, resp, player: str):
 | 
			
		||||
    p = int(player)
 | 
			
		||||
    print(p)
 | 
			
		||||
    print(the_game.players)
 | 
			
		||||
    resp.content = api.template('home/player.html', player=player, cards=the_game.players[p].cards)
 | 
			
		||||
							
								
								
									
										22
									
								
								views/temp_css.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								views/temp_css.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
from app_instance import api
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# This sucks. But at the moment I'm publishing this code / video
 | 
			
		||||
# Responder has developed a bug where it cannot serve static files
 | 
			
		||||
# See https://github.com/kennethreitz/responder/issues/337
 | 
			
		||||
#
 | 
			
		||||
# This is just a work around so you all can enjoy the course.
 | 
			
		||||
 | 
			
		||||
@api.route("/css/{file}")
 | 
			
		||||
def css(req, resp, file):
 | 
			
		||||
    resp.headers['Content-Type'] = 'text/css'
 | 
			
		||||
    full_file = os.path.join(
 | 
			
		||||
        os.path.dirname(__file__),
 | 
			
		||||
        '..',
 | 
			
		||||
        'css',
 | 
			
		||||
        file
 | 
			
		||||
    )
 | 
			
		||||
    with open(full_file, encoding='utf-8') as fin:
 | 
			
		||||
        resp.content = fin.read()
 | 
			
		||||
							
								
								
									
										83
									
								
								wiz_game.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								wiz_game.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,83 @@
 | 
			
		||||
 | 
			
		||||
import random
 | 
			
		||||
 | 
			
		||||
def chunks(lst, n):
 | 
			
		||||
    """Yield successive n-sized chunks from lst."""
 | 
			
		||||
    for i in range(0, len(lst), n):
 | 
			
		||||
        yield lst[i:i + n]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Card:
 | 
			
		||||
    def __init__(self, color, value):
 | 
			
		||||
        self.color = color
 | 
			
		||||
        self.value = value
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        sc = self.color if self.color else ' '
 | 
			
		||||
        sv = str(self.value)
 | 
			
		||||
        return sc+' '+sv
 | 
			
		||||
 | 
			
		||||
    def __repr__(self):
 | 
			
		||||
        return str(self)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Player:
 | 
			
		||||
    def __init__(self, name, player_id):
 | 
			
		||||
        self.name = name
 | 
			
		||||
        self.id = player_id
 | 
			
		||||
        self.cards = []
 | 
			
		||||
 | 
			
		||||
    def set_cards(self, cards):
 | 
			
		||||
        self.cards = cards
 | 
			
		||||
 | 
			
		||||
    def show_cards(self):
 | 
			
		||||
        print(self.cards)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class WizGame:
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.players = []
 | 
			
		||||
        self.card_deck = []
 | 
			
		||||
        self.trump_color = None
 | 
			
		||||
 | 
			
		||||
    def create_deck(self):
 | 
			
		||||
        for color in ["b", "r", "g", "y"]:
 | 
			
		||||
            for val in range(1,14):
 | 
			
		||||
                self.card_deck.append(Card(color, val))
 | 
			
		||||
        for _ in range(1,5):
 | 
			
		||||
            self.card_deck.append(Card(None, 'Z'))
 | 
			
		||||
        for _ in range(1,5):
 | 
			
		||||
            self.card_deck.append(Card(None, 'N'))
 | 
			
		||||
        print("carddeck:")
 | 
			
		||||
        print(self.card_deck)
 | 
			
		||||
 | 
			
		||||
    def set_trump_color(self, card: Card):
 | 
			
		||||
        if card.color:
 | 
			
		||||
            self.trump_color = card.color
 | 
			
		||||
        elif card.value == 'Z':
 | 
			
		||||
            self.trump_color = 'choose'
 | 
			
		||||
        else:
 | 
			
		||||
            self.trump_color = None
 | 
			
		||||
 | 
			
		||||
    def deal_cards(self, cards_per_player):
 | 
			
		||||
        random.shuffle(self.card_deck)
 | 
			
		||||
        cs = list(chunks(self.card_deck, cards_per_player))
 | 
			
		||||
        for idx,p in enumerate(self.players):
 | 
			
		||||
            p.set_cards(cs[idx])
 | 
			
		||||
            p.show_cards()
 | 
			
		||||
        if len(cs) > len(self.players):
 | 
			
		||||
            cc = cs[len(self.players)]
 | 
			
		||||
            c = cc[0]
 | 
			
		||||
            print("trump card: {}".format(c))
 | 
			
		||||
            self.set_trump_color(c)
 | 
			
		||||
        else:
 | 
			
		||||
            self.trump_color = None
 | 
			
		||||
        print("trump color: {}".format(self.trump_color))
 | 
			
		||||
 | 
			
		||||
    def add_player(self, name: str, player_id):
 | 
			
		||||
        if len(self.players) < 6:
 | 
			
		||||
            self.players.append((Player(name, player_id)))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
the_game = WizGame()
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user