Commit 6895fa63 authored by Ana Guerrero López's avatar Ana Guerrero López

Import Upstream version 3.4

parent 7c5df7e6
#!/usr/bin/env python
"""
characters4local.py script.
This script creates some files to manage characters' information
for the 'local' data access system.
Copyright 2007 Davide Alberani <da@erlug.linux.it>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
import sys, os, anydbm
from array import array
from struct import pack
HELP = """characters4local.py usage:
%s /directory/with/local/files/
# NOTE: you need read and write access to the specified directory.
See README.currentRole for more information.
""" % sys.argv[0]
if len(sys.argv) != 2:
print 'Specify the target directory!'
print HELP
sys.exit(1)
DATA_DIR = sys.argv[1]
def _buildChrIntsList(length):
"""Auxiliary table for fast conversion from 3-bytes strings to integers."""
chi = []
for j in xrange(length):
chi.append({})
for count in xrange(256):
val = count << j*8L
if val <= sys.maxint: val = int(val)
chi[j][chr(count)] = val
return chi
_chr_ints = _buildChrIntsList(3)
def toDec(v):
""""Convert string v to integer."""
value = 0
for i in xrange(len(v)):
value |= _chr_ints[i][v[i]]
return value
def toBin3(v):
"""Return a string (little-endian) from a numeric value."""
return '%s%s%s' % (chr(v & 255), chr((v >> 8) & 255), chr((v >> 16) & 255))
# Dictionary used to store characters information in the
# format: {'characterName': (characterID, (personID, movieID, ...))}
CACHE_CID = {}
def doCast(dataF, roleCount=0):
"""Read the dataF file and populate the CACHE_CID dictionary."""
print 'Start reading file %s.' % dataF
fptr = open(dataF, 'rb')
fread = fptr.read
while True:
piddata = fread(3)
if len(piddata) != 3:
break
# The personID we're managing.
personID = toDec(piddata)
filmCount = toDec(fread(3))
# Number of movies with and without attributes.
noWith = (filmCount >> 12) & 4095
noWithout = filmCount & 4095
for i in xrange(noWith + noWithout):
movieID = toDec(fread(3))
if i < noWith:
# Eat 'attributeID'.
fread(3)
length = ord(fread(1))
if length > 0:
curRole = fread(length)
noterixd = curRole.rfind('(')
if noterixd != -1:
# Don't strip notes, if they are not associated to
# the last character.
if curRole.rfind('/') < noterixd:
curRole = curRole[:noterixd]
for role in curRole.split('/'):
role = role.strip()
if not role:
continue
if role in CACHE_CID:
CACHE_CID[role][1].extend((personID, movieID))
else:
CACHE_CID[role] = (roleCount,
array('I', (personID, movieID)))
roleCount += 1
if roleCount % 100000 == 0:
print '* So far, %d characters were read.' % \
roleCount
# Eat 'position'
fread(1)
##if roleCount > 70000: break
fptr.close()
print 'File %s closed.' % dataF
return roleCount
def writeData(d, directory):
"""Write d data into file in the specified directory."""
# Open files.
print 'Start writing data to directory %s.' % directory
char2id = anydbm.open(os.path.join(directory, 'character2id.index'), 'n')
findex = open(os.path.join(directory, 'characters.index'), 'wb')
fdata = open(os.path.join(directory, 'characters.data'), 'wb')
fdatawrite = fdata.write
fdatawritelines = fdata.writelines
fdatatell = fdata.tell
fkey = open(os.path.join(directory, 'characters.key'), 'wb')
# Auxiliary list used to store offsets in the fdata file.
offsetList = []
offsetListappend = offsetList.append
dpopitem = d.popitem
dpop = d.pop
print 'Writing characters.key file...',
sys.stdout.flush()
fkey.writelines('%s|%x\n' % (name, d[name][0]) for name in sorted(d))
fkey.close()
print 'DONE!'
print 'Converting received dictionary...',
sys.stdout.flush()
# Convert the received dictionary in another format, simpler/faster
# to process. It's faster and requires less memory than a
# sorted(d.iteritems(), key=operator.itemgetter(1)) call.
d2 = {}
while True:
try:
name, (charID, items) = dpopitem()
except KeyError:
break
d2[charID] = (name, items)
# Probably this won't free-up any memory space, but...
d = {}
print 'DONE!'
count = 1
d2pop = d2.pop
print 'Start writing data (this may take a while).'
for charID in sorted(d2):
name, items = d2pop(charID)
offsetListappend(fdatatell())
charIDBin = toBin3(charID)
# Map character names to characterIDs.
char2id[name] = charIDBin
fdatawritelines((charIDBin, # characterID: superfluous,
# but useful for run-time checks.
pack('<H', len(name)), # Length of the name (2-bytes).
name, # Name of the character.
toBin3(len(items)))) # Number of 3-bytes-long items to
# read; 24-bits, because some
# characters (like "Himself")
# appear in many movies.
fdatawritelines(toBin3(x) for x in items)
if count % 100000 == 0:
print '* So far, %d characters were written.' % count
count += 1
fdata.close()
char2id.close()
print 'Writing the characters.index file...',
sys.stdout.flush()
findex.writelines(pack('<L', x) for x in offsetList)
findex.close()
print 'DONE!'
print 'Dump to directory %s complete.' % directory
# Read actors.data.
lastRC = doCast(DATA_DIR + 'actors.data')
# Read actresses.data.
doCast(DATA_DIR + 'actresses.data', roleCount=lastRC)
# Write output files.
writeData(CACHE_CID, DATA_DIR)
......@@ -7,22 +7,6 @@ Usage: get_character "characterID"
Show some info about the character with the given imdbID (e.g. '0000001'
for "Jesse James".
"""
# Parameters to initialize the IMDb class.
IMDB_PARAMS = {
# The used access system. 'web' means that you're retrieving data
# from the IMDb web server.
'accessSystem': 'web'
#'accessSystem': 'mobile'
# XXX: if you've a local installation of the IMDb database,
# comment the above line and uncomment the following two.
#'accessSystem': 'local',
#'dbDirectory': '/usr/local/imdb' # or, in a Windows environment:
#'dbDirectory': 'D:/imdb-20060107'
# XXX: parameters for a SQL installation.
#'accessSystem': 'sql',
#'uri': 'mysql://userName:yourPassword@localhost/dbName'
}
import sys
......@@ -41,7 +25,7 @@ if len(sys.argv) != 2:
imdbID = sys.argv[1]
i = imdb.IMDb(**IMDB_PARAMS)
i = imdb.IMDb()
out_encoding = sys.stdout.encoding or sys.getdefaultencoding()
......
......@@ -6,22 +6,6 @@ Usage: get_first_character "character name"
Search for the given name and print the best matching result.
"""
# Parameters to initialize the IMDb class.
IMDB_PARAMS = {
# The used access system. 'web' means that you're retrieving data
# from the IMDb web server.
'accessSystem': 'web'
#'accessSystem': 'mobile'
# XXX: if you've a local installation of the IMDb database,
# comment the above line and uncomment the following two.
#'accessSystem': 'local',
#'dbDirectory': '/usr/local/imdb' # or, in a Windows environment:
#'dbDirectory': 'D:/imdb-20060107'
# XXX: parameters for a SQL installation.
#'accessSystem': 'sql',
#'uri': 'mysql://userName:yourPassword@localhost/dbName'
}
import sys
......@@ -41,7 +25,7 @@ if len(sys.argv) != 2:
name = sys.argv[1]
i = imdb.IMDb(**IMDB_PARAMS)
i = imdb.IMDb()
in_encoding = sys.stdin.encoding or sys.getdefaultencoding()
out_encoding = sys.stdout.encoding or sys.getdefaultencoding()
......
......@@ -6,22 +6,6 @@ Usage: get_first_movie "movie title"
Search for the given title and print the best matching result.
"""
# Parameters to initialize the IMDb class.
IMDB_PARAMS = {
# The used access system. 'web' means that you're retrieving data
# from the IMDb web server.
'accessSystem': 'web'
#'accessSystem': 'mobile'
# XXX: if you've a local installation of the IMDb database,
# comment the above line and uncomment the following two.
#'accessSystem': 'local',
#'dbDirectory': '/usr/local/imdb' # or, in a Windows environment:
#'dbDirectory': 'D:/imdb-20060107'
# XXX: parameters for a SQL installation.
#'accessSystem': 'sql',
#'uri': 'mysql://userName:yourPassword@localhost/dbName'
}
import sys
......@@ -41,7 +25,7 @@ if len(sys.argv) != 2:
title = sys.argv[1]
i = imdb.IMDb(**IMDB_PARAMS)
i = imdb.IMDb()
in_encoding = sys.stdin.encoding or sys.getdefaultencoding()
out_encoding = sys.stdout.encoding or sys.getdefaultencoding()
......
......@@ -6,22 +6,6 @@ Usage: get_first_person "person name"
Search for the given name and print the best matching result.
"""
# Parameters to initialize the IMDb class.
IMDB_PARAMS = {
# The used access system. 'web' means that you're retrieving data
# from the IMDb web server.
'accessSystem': 'web'
#'accessSystem': 'mobile'
# XXX: if you've a local installation of the IMDb database,
# comment the above line and uncomment the following two.
#'accessSystem': 'local',
#'dbDirectory': '/usr/local/imdb' # or, in a Windows environment:
#'dbDirectory': 'D:/imdb-20060107'
# XXX: parameters for a SQL installation.
#'accessSystem': 'sql',
#'uri': 'mysql://userName:yourPassword@localhost/dbName'
}
import sys
......@@ -41,7 +25,7 @@ if len(sys.argv) != 2:
name = sys.argv[1]
i = imdb.IMDb(**IMDB_PARAMS)
i = imdb.IMDb()
in_encoding = sys.stdin.encoding or sys.getdefaultencoding()
out_encoding = sys.stdout.encoding or sys.getdefaultencoding()
......
......@@ -7,22 +7,6 @@ Usage: get_movie "imdbID"
Show some info about the movie with the given imdbID (e.g. '0133093'
for "The Matrix".
"""
# Parameters to initialize the IMDb class.
IMDB_PARAMS = {
# The used access system. 'web' means that you're retrieving data
# from the IMDb web server.
'accessSystem': 'web'
#'accessSystem': 'mobile'
# XXX: if you've a local installation of the IMDb database,
# comment the above line and uncomment the following two.
#'accessSystem': 'local',
#'dbDirectory': '/usr/local/imdb' # or, in a Windows environment:
#'dbDirectory': 'D:/imdb-20060107'
# XXX: parameters for a SQL installation.
#'accessSystem': 'sql',
#'uri': 'mysql://userName:yourPassword@localhost/dbName'
}
import sys
......@@ -41,7 +25,7 @@ if len(sys.argv) != 2:
imdbID = sys.argv[1]
i = imdb.IMDb(**IMDB_PARAMS)
i = imdb.IMDb()
out_encoding = sys.stdout.encoding or sys.getdefaultencoding()
......
......@@ -7,22 +7,6 @@ Usage: get_person "personID"
Show some info about the person with the given imdbID (e.g. '0000210'
for "Julia Roberts".
"""
# Parameters to initialize the IMDb class.
IMDB_PARAMS = {
# The used access system. 'web' means that you're retrieving data
# from the IMDb web server.
'accessSystem': 'web'
#'accessSystem': 'mobile'
# XXX: if you've a local installation of the IMDb database,
# comment the above line and uncomment the following two.
#'accessSystem': 'local',
#'dbDirectory': '/usr/local/imdb' # or, in a Windows environment:
#'dbDirectory': 'D:/imdb-20060107'
# XXX: parameters for a SQL installation.
#'accessSystem': 'sql',
#'uri': 'mysql://userName:yourPassword@localhost/dbName'
}
import sys
......@@ -41,7 +25,7 @@ if len(sys.argv) != 2:
imdbID = sys.argv[1]
i = imdb.IMDb(**IMDB_PARAMS)
i = imdb.IMDb()
out_encoding = sys.stdout.encoding or sys.getdefaultencoding()
......
......@@ -272,7 +272,7 @@ def title_soundex(title):
title = ', '.join(ts[:-1])
return soundex(title)
def name_soundexes(name):
def name_soundexes(name, character=False):
"""Return three soundex codes for the given name; the name is assumed
to be in the 'surname, name' format, without the imdbIndex indication,
as the one in the analyze_name(name)['name'] value.
......@@ -289,8 +289,11 @@ def name_soundexes(name):
name_normal = normalizeName(name)
s2 = soundex(name_normal)
if s1 == s2: s2 = None
namesplit = name.split(', ')
s3 = soundex(namesplit[0])
if not character:
namesplit = name.split(', ')
s3 = soundex(namesplit[0])
else:
s3 = soundex(name.split(' ')[-1])
if s3 and s3 in (s1, s2): s3 = None
return (s1, s2, s3)
......@@ -721,6 +724,58 @@ class PersonsCache(_BaseCache):
CURS.executemany(self.sqlstr, self.converter(l))
class CharactersCache(_BaseCache):
"""Manage the characters list."""
counter = counter()
def __init__(self, *args, **kwds):
_BaseCache.__init__(self, *args, **kwds)
self._table_name = tableName(CharName)
self._id_for_custom_q = 'CHARACTERS'
self.sqlstr, self.converter = createSQLstr(CharName, ['id', 'name',
'imdbIndex', 'namePcodeNf', 'surnamePcode'])
def populate(self):
print ' * POPULATING CharactersCache...'
nameTbl = tableName(CharName)
personidCol = colName(CharName, 'id')
nameCol = colName(CharName, 'name')
imdbindexCol = colName(CharName, 'imdbIndex')
CURS.execute('SELECT %s, %s, %s FROM %s;' % (personidCol, nameCol,
imdbindexCol, nameTbl))
_oldcacheValues = CharName.sqlmeta.cacheValues
CharName.sqlmeta.cacheValues = False
for x in fetchsome(CURS, self.flushEvery):
nd = {'name': unicode(x[1], 'utf_8')}
if x[2]: nd['imdbIndex'] = x[2]
name = build_name(nd, canonical=1)
dict.__setitem__(self, name, x[0])
self.counter = counter(CharName.select().count() + 1)
CharName.sqlmeta.cacheValues = _oldcacheValues
def _toDB(self, quiet=0):
if not quiet:
print ' * FLUSHING CharactersCache...'
sys.stdout.flush()
l = []
lapp = l.append
tmpDictiter = self._tmpDict.iteritems
for k, v in tmpDictiter():
try:
t = analyze_name(k)
except IMDbParserError:
if k and k.strip():
print 'WARNING CharactersCache._toDB() invalid name:', _(k)
continue
tget = t.get
name = tget('name')
namePcodeCf, namePcodeNf, surnamePcode = name_soundexes(name,
character=True)
lapp((v, name, tget('imdbIndex'),
namePcodeCf, surnamePcode))
CURS.executemany(self.sqlstr, self.converter(l))
class SQLData(dict):
"""Variable set of information, to be stored from time to time
to the SQL database."""
......@@ -894,7 +949,7 @@ def doCast(fp, roleid, rolename):
name = ''
roleidVal = RawValue('roleID', roleid)
sqldata = SQLData(table=CastInfo, cols=['personID', 'movieID',
'personRole', 'note', 'nrOrder', roleidVal])
'personRoleID', 'note', 'nrOrder', roleidVal])
if rolename == 'miscellaneous crew': sqldata.flushEvery = 10000
for line in fp:
if line and line[0] != '\t':
......@@ -941,7 +996,13 @@ def doCast(fp, roleid, rolename):
except ValueError:
pass
movieid = CACHE_MID.addUnique(title)
sqldata.add((pid, movieid, role, note, order))
if role is not None:
roles = role.split('/')
for role in roles:
cid = CACHE_CID.addUnique(role)
sqldata.add((pid, movieid, cid, note, order))
else:
sqldata.add((pid, movieid, None, note, order))
if count % 10000 == 0:
print 'SCANNING %s:' % rolename,
print _(name)
......@@ -965,9 +1026,15 @@ def castLists():
try:
f = SourceFile(fname, start=CAST_START, stop=CAST_STOP)
except IOError:
if rolename == 'actress':
CACHE_CID.flush()
CACHE_CID.clear()
continue
doCast(f, roleid, rolename)
f.close()
if rolename == 'actress':
CACHE_CID.flush()
CACHE_CID.clear()
t('castLists(%s)' % rolename)
......@@ -1262,7 +1329,7 @@ def nmmvFiles(fp, funct, fname):
guestid = RoleType.select(RoleType.q.role == 'guest')[0].id
roleid = str(guestid)
guestdata = SQLData(table=CastInfo,
cols=['personID', 'movieID', 'personRole', 'note',
cols=['personID', 'movieID', 'personRoleID', 'note',
RawValue('roleID', roleid)], flushEvery=10000)
akanamesdata = SQLData(table=AkaName, cols=['personID', 'name',
'imdbIndex', 'namePcodeCf', 'namePcodeNf', 'surnamePcode'])
......@@ -1525,6 +1592,7 @@ def completeCast():
# global instances
CACHE_MID = MoviesCache()
CACHE_PID = PersonsCache()
CACHE_CID = CharactersCache()
def _cmpfunc(x, y):
......@@ -1769,6 +1837,8 @@ def run():
CACHE_MID.clear()
CACHE_PID.flush()
CACHE_PID.clear()
CACHE_CID.flush()
CACHE_CID.clear()
t('fushing caches...')
print 'TOTAL TIME TO INSERT DATA: %d minutes, %d seconds' % \
......@@ -1802,6 +1872,8 @@ def _kdb_handler(signum, frame):
except IntegrityError: pass
try: CACHE_PID.flush()
except IntegrityError: pass
try: CACHE_CID.flush()
except IntegrityError: pass
print 'DONE! (in %d minutes, %d seconds)' % \
divmod(int(time.time())-BEGIN_TIME, 60)
sys.exit()
......
......@@ -6,22 +6,6 @@ Usage: search_character "character name"
Search for the given name and print the results.
"""
# Parameters to initialize the IMDb class.
IMDB_PARAMS = {
# The used access system. 'web' means that you're retrieving data
# from the IMDb web server.
'accessSystem': 'web'
#'accessSystem': 'mobile'
# XXX: if you've a local installation of the IMDb database,
# comment the above line and uncomment the following two.
#'accessSystem': 'local',
#'dbDirectory': '/usr/local/imdb' # or, in a Windows environment:
#'dbDirectory': 'D:/imdb-20060107'
# XXX: parameters for a SQL installation.
#'accessSystem': 'sql',
#'uri': 'mysql://userName:yourPassword@localhost/dbName'
}
import sys
......@@ -41,7 +25,7 @@ if len(sys.argv) != 2:
name = sys.argv[1]
i = imdb.IMDb(**IMDB_PARAMS)
i = imdb.IMDb()
in_encoding = sys.stdin.encoding or sys.getdefaultencoding()
out_encoding = sys.stdout.encoding or sys.getdefaultencoding()
......
......@@ -6,22 +6,6 @@ Usage: search_movie "movie title"
Search for the given title and print the results.
"""
# Parameters to initialize the IMDb class.
IMDB_PARAMS = {
# The used access system. 'web' means that you're retrieving data
# from the IMDb web server.
'accessSystem': 'web'
#'accessSystem': 'mobile'
# XXX: if you've a local installation of the IMDb database,
# comment the above line and uncomment the following two.
#'accessSystem': 'local',
#'dbDirectory': '/usr/local/imdb' # or, in a Windows environment:
#'dbDirectory': 'D:/imdb-20060107'
# XXX: parameters for a SQL installation.
#'accessSystem': 'sql',
#'uri': 'mysql://userName:yourPassword@localhost/dbName'
}
import sys
......@@ -41,7 +25,7 @@ if len(sys.argv) != 2:
title = sys.argv[1]
i = imdb.IMDb(**IMDB_PARAMS)
i = imdb.IMDb()
in_encoding = sys.stdin.encoding or sys.getdefaultencoding()
out_encoding = sys.stdout.encoding or sys.getdefaultencoding()
......
......@@ -6,22 +6,6 @@ Usage: search_person "person name"
Search for the given name and print the results.
"""
# Parameters to initialize the IMDb class.
IMDB_PARAMS = {
# The used access system. 'web' means that you're retrieving data
# from the IMDb web server.
'accessSystem': 'web'
#'accessSystem': 'mobile'
# XXX: if you've a local installation of the IMDb database,
# comment the above line and uncomment the following two.
#'accessSystem': 'local',
#'dbDirectory': '/usr/local/imdb' # or, in a Windows environment:
#'dbDirectory': 'D:/imdb-20060107'
# XXX: parameters for a SQL installation.
#'accessSystem': 'sql',
#'uri': 'mysql://userName:yourPassword@localhost/dbName'
}
import sys
......@@ -41,7 +25,7 @@ if len(sys.argv) != 2:
name = sys.argv[1]
i = imdb.IMDb(**IMDB_PARAMS)
i = imdb.IMDb()
in_encoding = sys.stdin.encoding or sys.getdefaultencoding()
out_encoding = sys.stdout.encoding or sys.getdefaultencoding()
......
Changelog for IMDbPY
====================
* What's the new in release 3.4 "Flatliners" (16 Dec 2007)
[general]
- *** NOTE FOR PACKAGERS *** in the docs directory there is the
"imdbpy.cfg" configuration file, which should be installed in /etc
or equivalent directory; the setup.py script _doesn't_ manage its
installation.
- introduced a global configuration file to set IMDbPY's parameters.
- supported characters using "sql" and "local" data access systems.
- fixed a bug retrieving characterID from a character's name.
[http]
- fixed a bug in "release dates" parser.
- fixed bugs in "episodes" parser.
- fixed bugs reading "series years".
- stricter definition for ParserBase._re_imdbIDmatch regular expression.
[mobile]
- fixed bugs reading "series years".
- fixed bugs reading characters' filmography.
[sql]
- support for characters.
[local]
- support for characters.
- introduced the characters4local.py script.
* What's the new in release 3.3 "Heroes" (18 Nov 2007)
[general]
- first support for character pages; only for "http" and "mobile", so far.
......
......@@ -5,8 +5,9 @@
Since version 3.3, IMDbPY supports the character pages of the IMDb
database; this required some substantial changes to how actors'
and acresses' roles were handled.
So far, only the "http", "httpThin" and "mobile" data access systems
can manage the character pages.
Starting with release 3.4, "local" and "sql" data access systems
are supported, too - but they work a bit differently from "http"
and "mobile". See "MOBILE AND LOCAL" below.
The currentRole instance attribute can be found in every instance
of Person, Movie and Character classes, even if actually the Character
......@@ -49,6 +50,23 @@ will return a good-old-unicode string, like expected in the previous
version of IMDbPY.
MOBILE AND LOCAL
================
Fetching data from the web, only characters with an active page
on the web site will have their characterID; we don't have these
information accessing "sql" and "local", so _every_ character
will have an associated characterID.
This way, every character with the same name will share the same ID.
For "local", to activate support for characters, you have to
run the characters4local.py script, specifying the directory
with the local files (you need write access to this directory:
some new files will be created).
Probably the script will require 150/200MB of free space,
about 500MB of RAM memory and about 1 hour to complete.
GOODIES
=======
......@@ -78,7 +96,7 @@ E.g.:
myPrint = imdb.helpers.makeObject2Txt(personTxt='<if personID><a href=/person/%(personID)s></if personID>%(long imdb name)s<if personID></a></if personID><if currentRole> ... %(currentRole)s<if notes> %(notes)s</if notes></if currentRole>'
Another useful argumento is 'applyToValues': if set to a function,
Another useful argument is 'applyToValues': if set to a function,
it will be applied to every value before the substitution; it can
be useful to format strings for html output.
......@@ -8,6 +8,8 @@ file.
Obviously you can still prefer to use the 'local' data access
system if you're already using the moviedb program.
NOTE: see README.currentRole for information about character support.
Select a mirror of the "The Plain Text Data Files" from
the http://www.imdb.com/interfaces.html page and download
......
......@@ -76,6 +76,14 @@ you can access movie data through the e-mail interface, etc. etc.
| 'htmlThin'| information are gathered; useful
| | for systems with limited bandwidth.
NOTE ON THE 'DEFAULT' ACCESS SYSTEM: since release 3.4, the 'imdbpy.cfg'
configuration file is available, so that you can set a system-wide (or
user-wide) default. The file is commented with indication of the location
where it can be put, and how to modify it.
Obviously, if no imdbpy.cfg file is found (or is not readable or it can't
be parsed), 'http' is still considered the default.
The imdb_access object has seven main methods: search_movie(title),
get_movie(movieID), search_person(name), get_person(personID),