Commit 5ba693c7 authored by Brady James Garvin's avatar Brady James Garvin
Browse files

Initial commit.

parents
.idea
*.pyc
*.pyo
*.apk
from __future__ import print_function
from sys import stderr
from sqlalchemy.exc import SQLAlchemyError
from movies import MovieDatabase, Movie
from kivy.app import App
__app_package__ = 'edu.unl.cse.soft161.movies'
__app__ = 'Movies'
__version__ = '1.0'
__flags__ = ['--bootstrap=sdl2', '--requirements=python2,kivy,sqlalchemy,mysql_connector', '--permission=INTERNET']
class MoviesApp(App):
def __init__(self, **kwargs):
super(MoviesApp, self).__init__(**kwargs)
url = MovieDatabase.construct_mysql_url('localhost', 3306, 'movies', 'root', 'cse')
self.movie_database = MovieDatabase(url)
self.session = self.movie_database.create_session()
@staticmethod
def _create_movie(session, title, budget, gross_revenue):
movie = Movie(title=title, budget=budget, gross_revenue=gross_revenue)
session.add(movie)
session.commit()
def create_movie(self, title, budget, gross_revenue):
try:
budget = int(budget) * 1000000
gross_revenue = int(gross_revenue) * 1000000
except ValueError as exception:
self.root.ids.message.text = 'Formatting error: {exception}'.format(exception=exception)
return
try:
self._create_movie(self.session, title, budget, gross_revenue)
self.root.ids.message.text = 'Movie added!'
except SQLAlchemyError as exception:
self.session.rollback()
self.root.ids.message.text = 'Database error: {exception}'.format(exception=exception)
if __name__ == "__main__":
try:
app = MoviesApp()
app.run()
except SQLAlchemyError as exception:
print('Initial database connection failed!', file=stderr)
print('Cause: {exception}'.format(exception=exception), file=stderr)
exit(1)
ScreenManager:
Screen:
name: 'movie_entry'
BoxLayout:
orientation: 'vertical'
Label:
text: 'Enter a movie:'
font_size: '24sp'
BoxLayout:
orientation: 'horizontal'
Widget:
Label:
text: 'Movie Title:'
size_hint: (1, None)
height: sp(32)
Widget:
TextInput:
id: title
size_hint: (4, None)
height: sp(32)
Widget:
BoxLayout:
orientation: 'horizontal'
Widget:
Label:
text: 'Budget (millions of US dollars):'
size_hint: (1, None)
height: sp(32)
Widget:
TextInput:
id: budget
size_hint: (4, None)
height: sp(32)
Widget:
BoxLayout:
orientation: 'horizontal'
Widget:
Label:
text: 'Gross Revenue (millions of US dollars):'
size_hint: (1, None)
height: sp(32)
Widget:
TextInput:
id: gross_revenue
size_hint: (4, None)
height: sp(32)
Widget:
Widget:
BoxLayout:
orientation: 'horizontal'
Widget:
Button:
text: 'Create'
size_hint: (4, 1)
on_press: app.create_movie(title.text, budget.text, gross_revenue.text)
Widget:
BoxLayout:
orientation: 'horizontal'
Widget:
Label:
id: message
text: ''
size_hint: (None, 1)
size: self.texture_size
Widget:
# All screens are white.
<Screen>:
canvas.before:
Color:
rgba: (1, 1, 1, 1)
Rectangle:
pos: self.pos
size: self.size
# All labels are blue.
<Label>:
color: (0, 0, 0.75, 1)
# All checkboxes are blue.
<CheckBox>:
canvas:
Color:
rgba: (0, 0, 0.75, 1)
Rectangle:
source: 'atlas://data/images/defaulttheme/checkbox{radio}{disabled}{on}'.format(radio=('_radio' if self.group else ''), disabled=('_disabled' if self.disabled else ''), on=('_on' if self.active else '_off'))
size: sp(32), sp(32)
pos: int(self.center_x - sp(16)), int(self.center_y - sp(16))
# All buttons have white text.
<Button>:
color: (1, 1, 1, 1)
from sqlalchemy import create_engine, Column, Integer, String, Date, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship
Persisted = declarative_base()
class Movie(Persisted):
__tablename__ = 'movies'
movie_id = Column(Integer, primary_key=True)
title = Column(String(256), nullable=False)
budget = Column(Integer)
gross_revenue = Column(Integer)
opening_date = Column(Date)
genres = relationship('Genre', uselist=True, secondary='movie_genres')
reviews = relationship('Review', uselist=True, back_populates='movie')
class Review(Persisted):
__tablename__ = 'reviews'
review_id = Column(Integer, primary_key=True)
movie_id = Column(Integer, ForeignKey('movies.movie_id'))
movie = relationship('Movie', back_populates='reviews')
score = Column(Integer)
comments = Column(String(1024))
class Genre(Persisted):
__tablename__ = 'genres'
genre_id = Column(Integer, primary_key=True)
name = Column(String(256), nullable=False)
movies = relationship('Movie', uselist=True, secondary='movie_genres')
class MovieGenre(Persisted):
__tablename__ = 'movie_genres'
movie_id = Column(Integer, ForeignKey('movies.movie_id'), primary_key=True)
genre_id = Column(Integer, ForeignKey('genres.genre_id'), primary_key=True)
votes = Column(Integer)
class MovieDatabase(object):
@staticmethod
def construct_mysql_url(authority, port, database, username, password):
return 'mysql+mysqlconnector://{username}:{password}@{authority}:{port}/{database}' \
.format(authority=authority, port=port, database=database, username=username, password=password)
@staticmethod
def construct_in_memory_url():
return 'sqlite:///'
def __init__(self, url):
self.engine = create_engine(url)
self.Session = sessionmaker()
self.Session.configure(bind=self.engine)
def ensure_tables_exist(self):
Persisted.metadata.create_all(self.engine)
def create_session(self):
return self.Session()
# -*- coding: utf-8; -*-
from __future__ import print_function
from sys import stderr
from datetime import date
from sqlalchemy.exc import SQLAlchemyError
from movies import MovieDatabase, Movie, Genre, Review
def add_starter_data(session):
biography = Genre(name='Biography')
drama = Genre(name='Drama')
history = Genre(name='History')
action = Genre(name='Action')
adventure = Genre(name='Adventure')
sci_fi = Genre(name='SciFi')
session.add(biography)
session.add(drama)
session.add(history)
session.add(action)
session.add(adventure)
session.add(sci_fi)
# Hidden Figures (Biography, Drama, History)
# 2016 October 15
# Budget: $25,000,000
# Gross Revenue: $206,000,000
# Sample review from IMBD:
# "★★★★★★★★★☆ In the opinion of this reviewer, an extraordinary achievement."
hidden_figures = Movie(title='Hidden Figures', budget=25000000, gross_revenue=206000000,
opening_date=date(2016, 10, 15), genres=[biography, drama, history])
session.add(hidden_figures)
extraordinary_achievement = Review(movie=hidden_figures, score=9,
comments='In the opinion of this reviewer, an extraordinary achievement.')
session.add(extraordinary_achievement)
# Rogue One (Action, Adventure, SciFi)
# 2016 December 16
# Budget: $200,000,000
# Gross Revenue: $1,016,000,000
# Sample reviews from IMDB:
# "★★★★★★★★★☆ I feel like the void left in my heart by Episode VII has been filled now."
# "★★★★★☆☆☆☆☆ Ultimately underwhelming."
rogue_one = Movie(title='Rogue One', budget=200000000, gross_revenue=1016000000,
opening_date=date(2016, 12, 16), genres=[action, adventure, sci_fi])
session.add(rogue_one)
void_filled = Review(movie=rogue_one, score=9,
comments='I feel like the void left in my heart by Episode VII has been filled now.')
ultimately_underwhelming = Review(movie=rogue_one, score=5,
comments='Ultimately underwhelming.')
session.add(void_filled)
session.add(ultimately_underwhelming)
def main():
try:
url = MovieDatabase.construct_mysql_url('localhost', 3306, 'movies', 'root', 'cse')
movie_database = MovieDatabase(url)
movie_database.ensure_tables_exist()
print('Tables created.')
session = movie_database.create_session()
add_starter_data(session)
session.commit()
print('Records created.')
except SQLAlchemyError as exception:
print('Database setup failed!', file=stderr)
print('Cause: {exception}'.format(exception=exception), file=stderr)
exit(1)
if __name__ == '__main__':
main()
from unittest import TestCase
from movies import MovieDatabase, Movie
from main import MoviesApp
class TestCreateMovie(TestCase):
def test_create_movie_inserts_movies(self):
url = MovieDatabase.construct_in_memory_url()
movie_database = MovieDatabase(url)
movie_database.ensure_tables_exist()
session = movie_database.create_session()
MoviesApp._create_movie(session, 'Example', 4000000, 290000000)
actual = session.query(Movie).filter(Movie.title == 'Example').first()
self.assertIsNotNone(actual)
def test_create_movie_inserts_one_movie(self):
url = MovieDatabase.construct_in_memory_url()
movie_database = MovieDatabase(url)
movie_database.ensure_tables_exist()
session = movie_database.create_session()
MoviesApp._create_movie(session, 'Example', 4000000, 290000000)
actual = session.query(Movie).filter(Movie.title == 'Example').count()
self.assertEqual(actual, 1)
def test_create_movie_inserts_correct_dollar_figures(self):
url = MovieDatabase.construct_in_memory_url()
movie_database = MovieDatabase(url)
movie_database.ensure_tables_exist()
session = movie_database.create_session()
MoviesApp._create_movie(session, 'Example', 4000000, 290000000)
actual = session.query(Movie).filter(Movie.title == 'Example').first()
self.assertEqual(actual.budget, 4000000)
self.assertEqual(actual.gross_revenue, 290000000)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment