summaryrefslogtreecommitdiff
path: root/examples/film.py
blob: fd4157c4de0242997f0c3859f3e5b9cac0e61c16 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/usr/bin/env python
"""

film.py: a simple tool to manage your movies review
Simon Rozet, http://atonie.org/

    - manage directors and writers
    - manage actors
    - handle non IMDB uri
    - markdown support in comment

Requires download and import of Python imdb library from
https://imdbpy.github.io/ - (warning: installation
will trigger automatic installation of several other packages)

--
Usage:
    film.py whoami "John Doe <john@doe.org>"
        Initialize the store and set your name and email.
    film.py whoami
        Tell you who you are
    film.py http://www.imdb.com/title/tt0105236/
        Review the movie "Reservoir Dogs"
"""
import datetime
import os
import sys
import re
import time

try:
    import imdb
except ImportError:
    imdb = None

from rdflib import BNode, ConjunctiveGraph, URIRef, Literal, Namespace, RDF
from rdflib.namespace import FOAF, DC
from builtins import input

storefn = os.path.expanduser("~/movies.n3")
# storefn = '/home/simon/codes/film.dev/movies.n3'
storeuri = "file://" + storefn
title = "Movies viewed by %s"

r_who = re.compile(
    "^(.*?) <([a-z0-9_-]+(\.[a-z0-9_-]+)*@[a-z0-9_-]+(\.[a-z0-9_-]+)+)>$"
)

IMDB = Namespace("http://www.csd.abdn.ac.uk/~ggrimnes/dev/imdb/IMDB#")
REV = Namespace("http://purl.org/stuff/rev#")


class Store:
    def __init__(self):
        self.graph = ConjunctiveGraph()
        if os.path.exists(storefn):
            self.graph.load(storeuri, format="n3")
        self.graph.bind("dc", DC)
        self.graph.bind("foaf", FOAF)
        self.graph.bind("imdb", IMDB)
        self.graph.bind("rev", "http://purl.org/stuff/rev#")

    def save(self):
        self.graph.serialize(storeuri, format="n3")

    def who(self, who=None):
        if who is not None:
            name, email = (r_who.match(who).group(1), r_who.match(who).group(2))
            self.graph.add((URIRef(storeuri), DC["title"], Literal(title % name)))
            self.graph.add((URIRef(storeuri + "#author"), RDF.type, FOAF["Person"]))
            self.graph.add((URIRef(storeuri + "#author"), FOAF["name"], Literal(name)))
            self.graph.add((URIRef(storeuri + "#author"), FOAF["mbox"], Literal(email)))
            self.save()
        else:
            return self.graph.objects(URIRef(storeuri + "#author"), FOAF["name"])

    def new_movie(self, movie):
        movieuri = URIRef("http://www.imdb.com/title/tt%s/" % movie.movieID)
        self.graph.add((movieuri, RDF.type, IMDB["Movie"]))
        self.graph.add((movieuri, DC["title"], Literal(movie["title"])))
        self.graph.add((movieuri, IMDB["year"], Literal(int(movie["year"]))))
        self.save()

    def new_review(self, movie, date, rating, comment=None):
        review = BNode()  # @@ humanize the identifier (something like #rev-$date)
        movieuri = URIRef("http://www.imdb.com/title/tt%s/" % movie.movieID)
        self.graph.add(
            (movieuri, REV["hasReview"], URIRef("%s#%s" % (storeuri, review)))
        )
        self.graph.add((review, RDF.type, REV["Review"]))
        self.graph.add((review, DC["date"], Literal(date)))
        self.graph.add((review, REV["maxRating"], Literal(5)))
        self.graph.add((review, REV["minRating"], Literal(0)))
        self.graph.add((review, REV["reviewer"], URIRef(storeuri + "#author")))
        self.graph.add((review, REV["rating"], Literal(rating)))
        if comment is not None:
            self.graph.add((review, REV["text"], Literal(comment)))
        self.save()

    def movie_is_in(self, uri):
        return (URIRef(uri), RDF.type, IMDB["Movie"]) in self.graph


def help():
    print(__doc__.split("--")[1])


def main(argv=None):
    if not argv:
        argv = sys.argv
    s = Store()
    if argv[1] in ("help", "--help", "h", "-h"):
        help()
    elif argv[1] == "whoami":
        if os.path.exists(storefn):
            print(list(s.who())[0])
        else:
            s.who(argv[2])
    elif argv[1].startswith("http://www.imdb.com/title/tt"):
        if s.movie_is_in(argv[1]):
            raise
        else:
            i = imdb.IMDb()
            movie = i.get_movie(argv[1][len("http://www.imdb.com/title/tt") : -1])
            print("%s (%s)" % (movie["title"].encode("utf-8"), movie["year"]))
            for director in movie["director"]:
                print("directed by: %s" % director["name"].encode("utf-8"))
            for writer in movie["writer"]:
                print("written by: %s" % writer["name"].encode("utf-8"))
            s.new_movie(movie)
            rating = None
            while not rating or (rating > 5 or rating <= 0):
                try:
                    rating = int(input("Rating (on five): "))
                except ValueError:
                    rating = None
            date = None
            while not date:
                try:
                    i = input("Review date (YYYY-MM-DD): ")
                    date = datetime.datetime(*time.strptime(i, "%Y-%m-%d")[:6])
                except:
                    date = None
            comment = input("Comment: ")
            s.new_review(movie, date, rating, comment)
    else:
        help()


if __name__ == "__main__":
    if not imdb:
        raise Exception(
            'This example requires the IMDB library! Install with "pip install imdbpy"'
        )
    main()