Upload 5 files
Browse files- app.py +57 -0
- movie_controller.py +41 -0
- movie_dao.py +15 -0
- movie_model.py +15 -0
- movies.csv +31 -0
app.py
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from flask import Flask, render_template, jsonify, request
|
| 2 |
+
from movie_controller import MovieController
|
| 3 |
+
|
| 4 |
+
app = Flask(__name__)
|
| 5 |
+
controller = MovieController()
|
| 6 |
+
|
| 7 |
+
@app.route('/')
|
| 8 |
+
def index():
|
| 9 |
+
return render_template('index.html')
|
| 10 |
+
|
| 11 |
+
@app.route('/api/movies')
|
| 12 |
+
def get_movies():
|
| 13 |
+
movies = controller.get_all_movies()
|
| 14 |
+
return jsonify([movie.__dict__ for movie in movies])
|
| 15 |
+
|
| 16 |
+
@app.route('/api/highest-rated')
|
| 17 |
+
def get_highest_rated():
|
| 18 |
+
movie = controller.get_highest_rated_movie()
|
| 19 |
+
return jsonify(movie.__dict__)
|
| 20 |
+
|
| 21 |
+
@app.route('/api/highest-grossing')
|
| 22 |
+
def get_highest_grossing():
|
| 23 |
+
movie = controller.get_highest_grossing_movie()
|
| 24 |
+
return jsonify(movie.__dict__)
|
| 25 |
+
|
| 26 |
+
@app.route('/api/movies-by-year')
|
| 27 |
+
def get_movies_by_year():
|
| 28 |
+
movies = controller.get_movies_sorted_by_year()
|
| 29 |
+
return jsonify([movie.__dict__ for movie in movies])
|
| 30 |
+
|
| 31 |
+
@app.route('/api/genres')
|
| 32 |
+
def get_genres():
|
| 33 |
+
genres = controller.get_all_genres()
|
| 34 |
+
return jsonify(genres)
|
| 35 |
+
|
| 36 |
+
@app.route('/api/languages')
|
| 37 |
+
def get_languages():
|
| 38 |
+
languages = controller.get_all_languages()
|
| 39 |
+
return jsonify(languages)
|
| 40 |
+
|
| 41 |
+
@app.route('/api/movies/filter')
|
| 42 |
+
def filter_movies():
|
| 43 |
+
genre = request.args.get('genre', '')
|
| 44 |
+
year = request.args.get('year', '')
|
| 45 |
+
language = request.args.get('language', '')
|
| 46 |
+
movies = controller.filter_movies(genre, year, language)
|
| 47 |
+
return jsonify([movie.__dict__ for movie in movies])
|
| 48 |
+
|
| 49 |
+
@app.route('/api/movies/sort')
|
| 50 |
+
def sort_movies():
|
| 51 |
+
sort_by = request.args.get('sort_by', 'year')
|
| 52 |
+
order = request.args.get('order', 'desc')
|
| 53 |
+
movies = controller.sort_movies(sort_by, order)
|
| 54 |
+
return jsonify([movie.__dict__ for movie in movies])
|
| 55 |
+
|
| 56 |
+
if __name__ == '__main__':
|
| 57 |
+
app.run(debug=True)
|
movie_controller.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from movie_dao import MovieDao
|
| 2 |
+
|
| 3 |
+
class MovieController:
|
| 4 |
+
def __init__(self):
|
| 5 |
+
self.__movie_data = MovieDao.load()
|
| 6 |
+
|
| 7 |
+
def get_all_movies(self):
|
| 8 |
+
return self.__movie_data
|
| 9 |
+
|
| 10 |
+
def get_highest_rated_movie(self):
|
| 11 |
+
return max(self.__movie_data, key=lambda movie: movie.rating)
|
| 12 |
+
|
| 13 |
+
def get_highest_grossing_movie(self):
|
| 14 |
+
return max(self.__movie_data, key=lambda movie: movie.box_office)
|
| 15 |
+
|
| 16 |
+
def get_movies_sorted_by_year(self):
|
| 17 |
+
return sorted(self.__movie_data, key=lambda movie: movie.year, reverse=True)
|
| 18 |
+
|
| 19 |
+
def get_all_genres(self):
|
| 20 |
+
return sorted(set(movie.genre for movie in self.__movie_data))
|
| 21 |
+
|
| 22 |
+
def get_all_languages(self):
|
| 23 |
+
return sorted(set(movie.language for movie in self.__movie_data))
|
| 24 |
+
|
| 25 |
+
def search_movies(self, query):
|
| 26 |
+
query = query.lower()
|
| 27 |
+
return [movie for movie in self.__movie_data if query in movie.title.lower() or query in movie.director.lower()]
|
| 28 |
+
|
| 29 |
+
def filter_movies(self, genre=None, year=None, language=None):
|
| 30 |
+
filtered = self.__movie_data
|
| 31 |
+
if genre:
|
| 32 |
+
filtered = [movie for movie in filtered if movie.genre == genre]
|
| 33 |
+
if year:
|
| 34 |
+
filtered = [movie for movie in filtered if movie.year == int(year)]
|
| 35 |
+
if language:
|
| 36 |
+
filtered = [movie for movie in filtered if movie.language == language]
|
| 37 |
+
return filtered
|
| 38 |
+
|
| 39 |
+
def sort_movies(self, sort_by='year', order='desc'):
|
| 40 |
+
reverse = order.lower() == 'desc'
|
| 41 |
+
return sorted(self.__movie_data, key=lambda movie: getattr(movie, sort_by), reverse=reverse)
|
movie_dao.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import csv
|
| 2 |
+
from movie_model import MovieModel
|
| 3 |
+
|
| 4 |
+
class MovieDao:
|
| 5 |
+
__movie_data = []
|
| 6 |
+
__FILE_NAME = "movies.csv"
|
| 7 |
+
|
| 8 |
+
@classmethod
|
| 9 |
+
def load(cls):
|
| 10 |
+
with open(cls.__FILE_NAME, encoding="utf-8") as csvfile:
|
| 11 |
+
for row in csv.reader(csvfile):
|
| 12 |
+
if row[0] != 'id': # Skip header
|
| 13 |
+
movie = MovieModel(*row)
|
| 14 |
+
cls.__movie_data.append(movie)
|
| 15 |
+
return cls.__movie_data
|
movie_model.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class MovieModel:
|
| 2 |
+
def __init__(self, id, title, year, director, genre, rating, duration, box_office, budget, language):
|
| 3 |
+
self.id = id
|
| 4 |
+
self.title = title
|
| 5 |
+
self.year = year
|
| 6 |
+
self.director = director
|
| 7 |
+
self.genre = genre
|
| 8 |
+
self.rating = float(rating)
|
| 9 |
+
self.duration = int(duration)
|
| 10 |
+
self.box_office = float(box_office)
|
| 11 |
+
self.budget = float(budget)
|
| 12 |
+
self.language = language
|
| 13 |
+
|
| 14 |
+
def __str__(self):
|
| 15 |
+
return f"{self.title} ({self.year}) directed by {self.director}, {self.genre}, Rating: {self.rating}"
|
movies.csv
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
id,title,year,director,genre,rating,duration,box_office,budget,language
|
| 2 |
+
1,肖申克的救赎,1994,弗兰克·德拉邦特,剧情,9.3,142,58.3,25,英语
|
| 3 |
+
2,霸王别姬,1993,陈凯歌,剧情,9.6,171,5.2,9,中文
|
| 4 |
+
3,阿甘正传,1994,罗伯特·泽米吉斯,剧情,9.5,142,677.9,55,英语
|
| 5 |
+
4,这个杀手不太冷,1994,吕克·贝松,犯罪,9.4,110,46.1,16,英语
|
| 6 |
+
5,美丽人生,1997,罗伯托·贝尼尼,剧情,9.5,116,229.2,20,意大利语
|
| 7 |
+
6,泰坦尼克号,1997,詹姆斯·卡梅隆,爱情,9.4,194,2201.6,200,英语
|
| 8 |
+
7,千与千寻,2001,宫崎骏,动画,9.4,125,355.5,19,日语
|
| 9 |
+
8,辛德勒的名单,1993,史蒂文·斯皮尔伯格,历史,9.5,195,321.2,22,英语
|
| 10 |
+
9,盗梦空间,2010,克里斯托弗·诺兰,科幻,9.3,148,836.8,160,英语
|
| 11 |
+
10,让子弹飞,2010,姜文,喜剧,9.0,132,67.5,12,中文
|
| 12 |
+
11,怦然心动,2010,罗伯·莱纳,爱情,9.1,90,16.2,15,英语
|
| 13 |
+
12,疯狂动物城,2016,拜伦·霍华德,动画,9.2,108,1023.8,150,英语
|
| 14 |
+
13,大话西游之大圣娶亲,1995,刘镇伟,喜剧,9.2,95,0.5,5,中文
|
| 15 |
+
14,熔炉,2011,黄东赫,剧情,9.3,125,30.9,2.2,韩语
|
| 16 |
+
15,控方证人,1957,比利·怀德,悬疑,9.6,116,8.2,3,英语
|
| 17 |
+
16,教父,1972,弗朗西斯·福特·科波拉,犯罪,9.3,175,245.1,6,英语
|
| 18 |
+
17,当幸福来敲门,2006,加布里尔·穆奇诺,剧情,9.1,117,307.1,55,英语
|
| 19 |
+
18,触不可及,2011,奥利维·那卡什,喜剧,9.2,112,426.6,9.5,法语
|
| 20 |
+
19,穿条纹睡衣的男孩,2008,马克·赫尔曼,剧情,9.1,94,40.4,12.5,英语
|
| 21 |
+
20,三傻大闹宝莱坞,2009,拉吉库马尔·希拉尼,喜剧,9.2,170,90.3,8.5,印地语
|
| 22 |
+
21,哪吒之魔童降世,2019,饺子,动画,8.4,110,742.6,30,中文
|
| 23 |
+
22,头号玩家,2018,史蒂文·斯皮尔伯格,科幻,8.7,140,582.9,175,英语
|
| 24 |
+
23,寻梦环游记,2017,李·昂克里奇,动画,9.0,105,807.1,175,英语
|
| 25 |
+
24,我不是药神,2018,文牧野,剧情,9.0,117,31.0,10,中文
|
| 26 |
+
25,飞越疯人院,1975,米洛斯·福尔曼,剧情,9.1,133,112.0,3,英语
|
| 27 |
+
26,你的名字。,2016,新海诚,动画,8.9,106,357.9,3.4,日语
|
| 28 |
+
27,流浪地球,2019,郭帆,科幻,7.9,125,700.0,50,中文
|
| 29 |
+
28,无间道,2002,刘伟强/麦兆辉,犯罪,9.2,101,7.1,6.5,中文
|
| 30 |
+
29,绿皮书,2018,彼得·法雷里,剧情,8.9,130,321.8,23,英语
|
| 31 |
+
30,海上钢琴师,1998,朱塞佩·托纳多雷,剧情,9.3,165,4.5,9,英语
|