Skip to content

Commit a77f9eb

Browse files
committed
fix webdev dir
1 parent 07fadae commit a77f9eb

File tree

2,190 files changed

+357559
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

2,190 files changed

+357559
-0
lines changed

3_webdev/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
config.*

3_webdev/README.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Netflix Matrimony - 'Tinder' for Netflix 🍿
2+
#### 5 Python Projects in 5 Days - Day 3: Web Development
3+
4+
A Flask app that generates random movie recommendations, with details listed for each title, that a user can swipe through and watch with the click of a button.
5+
6+
![app demo](/3_webdev/demo.gif)
7+
8+
**📸YouTube Tutorial: [https://youtu.be/HZHOhf8EXXc](https://youtu.be/HZHOhf8EXXc)**
9+
10+
## Inspiration
11+
Since I now have a lot more free time on my hands, I’ve been perusing Netflix more than usual. Despite their vast library, I can never find something to watch, and I don't think I'm alone. So, I wanted to make something that generates *completely* random recommendations, but still gives the user *some* information about the title before they watch. So, if someone is stuck in a movie rut, this app can help them branch out and try something new! 🎞
12+
13+
## Installation
14+
1. Install Flask
15+
16+
```$ pip install flask```
17+
2. (Option) Install virtualenv to manage dependencies (only needed for Python 2 uesrs):
18+
19+
```$ pip install virtualenv # only needed for Python 2```
20+
21+
3. Obtain an API Key for OMDB, and add to a `config.py` file using the following format:
22+
23+
```
24+
api_key = "YOUR_KEY"
25+
```
26+
If you are ever adding your own code to GitHub, make sure this `config.py` file is listed under a `.gitignore` file so it doesn't accidently get published to GitHub!
27+
28+
4. Download the CSV linked in [this Kaggle dataset](https://www.kaggle.com/shivamb/netflix-shows) and name the file `catalog.csv`. This will store the bulk of our data.
29+
30+
31+
## Usage
32+
#### To launch the app:
33+
$ python main.py
34+
35+
Once the Flask app is running, navigate to the `localhost` link provided:
36+
37+
<code> * Running on <b>http://127.0.0.1:5000/</b> (Press CTRL+C to quit)</code>
38+
39+
40+
## Thanks
41+
42+
* [Open Movie Database](http://www.omdbapi.com/) - Movie data API to fetch movie poster links and IMDB scores
43+
* [Kaggle Netflix Dataset](https://www.kaggle.com/shivamb/netflix-shows) - Comprehensive dataset with many Netflix movies/tv shows and their metadata
44+
45+
## Learn More
46+
47+
* [Flask Starter Guide](https://www.freecodecamp.org/news/how-to-build-a-web-application-using-flask-and-deploy-it-to-the-cloud-3551c985e492/) - A great starter guide on how to learn Flask
48+
* [Flask Tutorial](https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world) - A more in-depth tutorial on Flask
49+
* [About .gitignore and config giles](https://medium.com/black-tech-diva/hide-your-api-keys-7635e181a06c) - A step-by-step guide on how to hide your API keys
50+
51+
## License
52+
53+
This project is licensed under the MIT License - see the [LICENSE.md](https://github.com/harshibar/5-python-projects/blob/master/LICENSE) file for details.
1.3 KB
Binary file not shown.

3_webdev/app.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
runtime: python27
2+
api_version: 1
3+
threadsafe: true
4+
5+
handlers:
6+
- url: /static
7+
static_dir: static
8+
- url: /.*
9+
script: main.app
10+
11+
libraries:
12+
- name: ssl
13+
version: latest
14+
15+

3_webdev/appengine_config.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from google.appengine.ext import vendor
2+
3+
# Add any libraries installed in the "lib" folder.
4+
vendor.add('lib')

3_webdev/catalog.csv

Lines changed: 6237 additions & 0 deletions
Large diffs are not rendered by default.

3_webdev/demo.gif

461 KB
Loading

3_webdev/main.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
from flask import Flask, render_template
2+
import csv
3+
import random
4+
import requests
5+
import config
6+
7+
app = Flask(__name__)
8+
9+
10+
@app.route("/")
11+
def home():
12+
# randomly select a movie
13+
with open('catalog.csv') as f:
14+
reader = csv.reader(f)
15+
row = random.choice(list(reader))
16+
17+
movie = {
18+
'id': row[0],
19+
'category': row[1],
20+
'title': row[2],
21+
'director': row[3],
22+
'cast': row[4],
23+
'country': row[5],
24+
'date_added': row[6],
25+
'release_year': row[7],
26+
'maturity': row[8],
27+
'duration': row[9],
28+
'genre': row[10],
29+
'description': row[11],
30+
# default poster just so we see something
31+
'image': 'https://live.staticflickr.com/4422/36193190861_93b15edb32_z.jpg',
32+
'imdb': 'Not Available'
33+
}
34+
35+
# fetch cover image
36+
# call OMDB database
37+
url = f"http://www.omdbapi.com/?t={movie['title']}/&apikey={config.api_key}"
38+
# get back the response
39+
response = requests.request("GET", url)
40+
# parse result into JSON and look for matching data if available
41+
movie_data = response.json()
42+
if 'Poster' in movie_data:
43+
movie['image'] = movie_data['Poster']
44+
if 'imdbRating' in movie_data:
45+
movie['imdb'] = movie_data['imdbRating']
46+
# send all this data to the home.html template
47+
return render_template("home.html", movie=movie)
48+
49+
@app.route("/about")
50+
def about():
51+
return render_template("about.html")
52+
53+
if __name__ == "__main__":
54+
app.run(debug=True)

3_webdev/requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Flask
2+
Werkzeug

3_webdev/static/css/about.css

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
p {
2+
font-size: 18px;
3+
line-height: 40px;
4+
text-align: center;
5+
}
6+
7+
h1 {
8+
text-align: center;
9+
}
10+
11+
body {
12+
font-family: 'Open Sans', sans-serif;
13+
}

3_webdev/static/css/home.css

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
body {
2+
font-family: 'Open Sans', sans-serif;
3+
}
4+
5+
.movie-card {
6+
/* Add shadows to create the "card" effect */
7+
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
8+
transition: 0.3s;
9+
width:40%;
10+
min-width: 300px;
11+
border-radius: 5px;
12+
}
13+
14+
p {
15+
color: rgb(140,140,140);
16+
margin-bottom: 6px !important;
17+
}
18+
19+
.marker {
20+
margin-bottom: 1px !important;
21+
}
22+
23+
/* Add rounded corners to the top left and the top right corner of the image */
24+
img {
25+
border-radius: 5px 5px 0 0;
26+
margin-top: 10px;
27+
max-height: 400px;
28+
}
29+
30+
hr {
31+
margin:10px 0 !important;
32+
}
33+
34+
/* On mouse-over, add a deeper shadow */
35+
.card:hover {
36+
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
37+
}
38+
39+
.text {
40+
text-align: justify !important;
41+
padding: 0 0 0 0 !important;
42+
width: 100% !important;
43+
}
44+
45+
span {
46+
font-weight: 500;
47+
}
48+
49+
.container {
50+
padding: 2px 16px;
51+
text-align: center;
52+
}
53+
.container > div {
54+
display: inline-block;
55+
padding: 0 10px;
56+
vertical-align: middle;
57+
}
58+
.container:after {
59+
content: " ";
60+
display: inline-block;
61+
width: 100%;
62+
}
63+
64+
.button {
65+
width: 50px;
66+
height: 50px;
67+
background-color: blue;
68+
border-radius: 50%;
69+
color: white;
70+
border: none;
71+
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.2);
72+
transition: 0.3s;
73+
}
74+
75+
.downvote {
76+
background-image: linear-gradient(rgb(249,54,96), rgb(252, 93, 67))
77+
}
78+
79+
.heart {
80+
background-image: linear-gradient(rgb(37,225,143), rgb(76, 236, 202))
81+
}
82+
83+
.watch {
84+
margin-top: 10px;
85+
width: auto !important;
86+
height: 36px !important;
87+
border-radius: 6px !important;
88+
font-size: 16px !important;
89+
background-image: linear-gradient(rgb(45,156,255), rgb(29, 194, 255))
90+
}

3_webdev/static/css/template.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
body {
2+
font-family: 'Open Sans', sans-serif;
3+
}
4+
5+
.logo {
6+
background-color: #0D122B;
7+
padding: 10px;
8+
color: white;
9+
}

3_webdev/static/images/favicon.ico

152 KB
Binary file not shown.

3_webdev/static/images/favicon.png

28 KB
Loading
167 KB
Loading

3_webdev/templates/about.html

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<!DOCTYPE html>
2+
<html lang="en" dir="ltr">
3+
<head>
4+
<meta charset="utf-8">
5+
<title>About</title>
6+
<link rel="shortcut icon" href="{{ url_for('static', filename='images/favicon.ico') }}">
7+
<link rel="stylesheet" href="{{ url_for('static', filename='css/about.css') }}">
8+
9+
<script src="https://use.fontawesome.com/3fa36ae73c.js"></script>
10+
11+
</head>
12+
<body>
13+
{% extends "template.html" %}
14+
{% block content %}
15+
16+
<div class="container">
17+
<h1> Hey! </h1>
18+
<p> This app was created with 💜 by <a href="https://youtube.com/c/harshibar" target="_blank">harshibar</a> in one day.</p>
19+
<p> Feel free to try it out to Netflix and ~chill~ while in quarantine.</p>
20+
<p> Or, if you want to make this crappy code better, go ahead!</p>
21+
<p> Here is the code on <i class="fa fa-github" aria-hidden="true"></i>
22+
</p>
23+
</div>
24+
25+
{% endblock %}
26+
</body>
27+
</html>

3_webdev/templates/home.html

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<!DOCTYPE html>
2+
<html lang="en" dir="ltr">
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Netflix Matrimony</title>
6+
<link rel="shortcut icon" href="{{ url_for('static', filename='images/favicon.ico') }}">
7+
8+
<link rel="stylesheet" href="{{ url_for('static', filename='css/home.css') }}">
9+
10+
<script src="https://use.fontawesome.com/3fa36ae73c.js"></script>
11+
</head>
12+
<body>
13+
{% extends "template.html" %}
14+
{% block content %}
15+
<div class="container master">
16+
<div>
17+
<a href="{{ url_for('home') }}">
18+
<button class="button downvote">
19+
<i class="fa fa-times fa-3x"></i>
20+
</button>
21+
</a>
22+
</div>
23+
24+
<div class="movie-card">
25+
<img src={{movie.image}} alt="movie">
26+
<div class="text">
27+
<h4><b>{{movie.title}}</b></h4>
28+
<p class="marker"> <i class="fa fa-imdb" aria-hidden="true"></i> {{movie.imdb}}/10</p>
29+
<p class="marker"><i class="fa fa-calendar" aria-hidden="true"></i> {{movie.release_year}}</p>
30+
<p class="marker"> <i class="fa fa-film" aria-hidden="true"></i> {{movie.genre}}</p>
31+
<p class="marker"> <i class="fa fa-clock-o" aria-hidden="true"></i> {{movie.duration}} </p>
32+
<p class="marker"> <i class="fa fa-globe" aria-hidden="true"></i> {{movie.country}}</p>
33+
<hr>
34+
<p>{{movie.description}}</p>
35+
</div>
36+
</div>
37+
38+
<div>
39+
<a href="{{ url_for('home') }}">
40+
<button class="button heart">
41+
<i class="fa fa-heart fa-2x"></i>
42+
</button>
43+
</a>
44+
</div>
45+
</div>
46+
47+
<div class="container">
48+
<div>
49+
<button class="button watch" onclick="window.open('https://www.netflix.com/watch/{{movie.id}}', '_blank')"target='0'>
50+
Watch Now!
51+
<i class="fa fa-star"></i>
52+
</button>
53+
</div>
54+
</div>
55+
56+
{% endblock %}
57+
</body>
58+
</html>

3_webdev/templates/template.html

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<!DOCTYPE html>
2+
<html lang="en" dir="ltr">
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Flask Parent Template</title>
6+
7+
<link rel="shortcut icon" href="{{ url_for('static', filename='images/favicon.ico') }}">
8+
<link rel="stylesheet" href="{{ url_for('static', filename='css/template.css') }}">
9+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
10+
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
11+
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.no-icons.min.css" rel="stylesheet">
12+
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
13+
14+
</head>
15+
<body>
16+
<header>
17+
<div class="container">
18+
<nav class="navbar navbar-expand-lg navbar-light bg-light">
19+
<a class="navbar-brand" href="/">Netflix Matrimony</a>
20+
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup"
21+
aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
22+
<span class="navbar-toggler-icon"></span>
23+
</button>
24+
<div id="navbarNavAltMarkup">
25+
<div class="navbar-nav">
26+
<a class="nav-item nav-link active" href="/">Home <span class="sr-only">(current)</span></a>
27+
<a class="nav-item nav-link" href="/about">About</a>
28+
</div>
29+
</div>
30+
</nav>
31+
</div>
32+
</header>
33+
34+
{% block content %}
35+
{% endblock %}
36+
37+
</body>
38+
</html>

0 commit comments

Comments
 (0)