Esempio n. 1
0
def run_tests():
    """Test MovieCollection class."""

    # Test empty MovieCollection (defaults)
    print("Test empty MovieCollection:")
    movie_collection = MovieCollection()
    print(movie_collection)
    assert not movie_collection.movies  # an empty list is considered False

    # Test loading movies
    print("Test loading movies:")
    movie_collection.load_movies('movies.csv')
    print(movie_collection)
    assert movie_collection.movies  # assuming CSV file is non-empty, non-empty list is considered True

    # Test adding a new Movie with values
    print("Test adding new movie:")
    movie_collection.add_movie(Movie("Amazing Grace", 2006, "Drama", False))
    print(movie_collection)

    # Test sorting movies
    print("Test sorting - year:")
    movie_collection.sort("year")
    print(movie_collection)

    print("Test sorting - title:")
    movie_collection.sort("title")
    print(movie_collection)

    print("Test sorting - category:")
    movie_collection.sort("category")
    print(movie_collection)

    print("Test sorting - watched:")
    movie_collection.sort("is_watched")
    print(movie_collection)

    print("Test getting number of watched movies:")
    print(movie_collection.get_number_of_watched_movies())

    print("Test getting number of unwatched movies:")
    print(movie_collection.get_number_of_unwatched_movies())

    print("Test saving movies (check file):")
    movie_collection.save_movies("movies.csv")
Esempio n. 2
0
class MoviesToWatchApp(App):
    """MoviesToWatchApp is a Kivy App for keeping track of movies from a file """
    bottom_status_text = StringProperty()
    top_status_text = StringProperty()

    def __init__(self, **kwargs):
        """Construct main app."""
        super().__init__(**kwargs)
        self.movie_collection = MovieCollection()
        self.movie_collection.load_movies("movies.csv")
        self.sorted_by = "category"

    def build(self):
        """
        Build the Kivy GUI.
        :return: reference to the root Kivy widget
        """
        self.title = "Movies To Watch 2.0 - by Jonache Hilton"
        self.root = Builder.load_file('app.kv')
        self.sort_movies(self.sorted_by)
        return self.root

    def create_widgets(self):
        """
        Create buttons from list of Movie objects and add them to the GUI.
        :return: None
        """
        self.clear_movie_widgets()
        self.top_status_text = "To watch: {}. Watched: {}".format(
            self.movie_collection.get_number_of_unwatched_movies(),
            self.movie_collection.get_number_of_watched_movies())
        for movie in self.movie_collection.movies:
            # Create a button for each Movie object, specifying the text
            temp_button = Button(text=str(movie))
            temp_button.bind(on_release=self.press_movie)
            # Store a reference to the movie object in the button object
            temp_button.movie = movie
            self.root.ids.movie_box.add_widget(temp_button)
            if movie.is_watched:
                temp_button.background_color = GREEN_COLOUR
            else:
                temp_button.background_color = RED_COLOUR

    def press_movie(self, instance):
        """
        Handle pressing movie buttons, changing watched status of a Movie and updating display.
        :param instance: the Kivy button instance
        :return: None
        """
        # Each button is given its own ".movie" object reference, to get it directly
        movie = instance.movie
        if movie.is_watched:
            movie.unwatch()
            watched_string = "You need to watch"
        else:
            movie.watch()
            watched_string = "You have watched"
        # Update button text
        instance.text = str(movie)
        self.sort_movies(self.sorted_by)
        self.bottom_status_text = "{} {}".format(watched_string, movie.title)

    def press_add_movie(self):
        """
        Handle pressing add movie button, adding Movie object to list and updating display.
        :return: None
        """
        # Check if any errors occur before continuing
        is_valid_input = self.check_text_input_errors()
        if is_valid_input:
            movie_to_add = Movie(self.root.ids.title_input.text,
                                 int(self.root.ids.year_input.text),
                                 self.root.ids.category_input.text.title(),
                                 False)
            self.movie_collection.add_movie(movie_to_add)
            self.clear_fields()
            self.sort_movies(self.sorted_by)
            self.clear_bottom_status_text()

    def check_text_input_errors(self):
        """Check text inputs for a range of errors and returns True if no errors have occurred."""
        try:
            # Check if any of the text inputs are blank
            if self.root.ids.title_input.text == "" or self.root.ids.year_input.text == "" or \
                    self.root.ids.category_input.text == "":
                self.bottom_status_text = "All fields must be completed"
                return False

            elif int(self.root.ids.year_input.text) < 0:
                self.bottom_status_text = "Year must be >= 0"
                return False

            elif self.root.ids.category_input.text.title() not in [
                    "Action", "Comedy", "Documentary", "Drama", "Fantasy",
                    "Thriller"
            ]:
                self.bottom_status_text = "The category must be one of the following: Action, Comedy, Documentary," \
                                          " Drama, Fantasy, Thriller"
                return False
        except ValueError:
            self.bottom_status_text = "Please enter a valid number"
        else:
            return True

    def sort_movies(self, sorted_by):
        """
        Sort the movie widgets based on the sorted_by parameter.
        :param sorted_by: the selected sorting method from the GUI spinner
        :return: None
        """
        self.sorted_by = sorted_by.lower()
        # Convert "watched" to "is_watched" as "watched" is not a valid for attrgetter
        if self.sorted_by == "watched":
            self.sorted_by = "is_watched"
        self.movie_collection.sort(self.sorted_by)
        self.create_widgets()

    def clear_fields(self):
        """
        Clear the text input fields.
        :return: None
        """
        self.root.ids.title_input.text = ""
        self.root.ids.category_input.text = ""
        self.root.ids.year_input.text = ""

    def clear_movie_widgets(self):
        """
        Clear all of the widgets that are children of the "movie_box" layout widget.
        :return: None
        """
        self.root.ids.movie_box.clear_widgets()

    def clear_bottom_status_text(self):
        """
        Clear the bottom status text.
        :return: None
        """
        self.bottom_status_text = ""

    def on_stop(self):
        """
        Save movies back to file when GUI is closed.
        :return: None
        """
        self.movie_collection.save_movies("movies.csv")