#!/usr/bin/python
# -*- coding: utf-8 -*-
#author: Ludolph Neethling
#repository: http://ludo.za.net/TMDb.html
#license: LGPLv2 http://www.gnu.org/licenses/lgpl.html

'''
.. module:: TMDb
    :platform: Unix, Windows
    :description: Yet another themoviedb.org python api wrapper. I had a look at
        the other two python modules and realized they did not implement the
        Movie.browse method and also there was no real documentation. So another
        python api was born.

        This module is heavily influenced by the work done by dbr/Ben and
        globald and I just want to thank them for sharing their code.

        Note at the moment this module only allows you to GET data from the API
        and not POST data to the api.

.. moduleauthor:: Ludolph Neethling <ludolph@openhazel.co.za>
'''

__author__ = "Ludolph Neethling"
__version__ = "0.20101025 Alpha"

import sys
import urllib
import urllib2

class TMDbBaseError(Exception):
    pass

class TMDbHttpError(TMDbBaseError):
    pass

class TMDb(object):
    '''TMDb allows you to query themoviedb.org api. Do not use this class
    directly but rather one of its subclasses like Movie'''

    def __init__(self, server = 'http://api.themoviedb.org',
                 api_key = '6311f82d52014265d765d39802aafaa7', view='xml',
                 lang='en'):
        '''Initialize all the needed attributes'''
        self.lang = lang
        self.view = view
        self.server = server
        self.api_key = api_key
        self.version = '2.1'

    def url_base_builder(self, section, method):
        '''Builds the base(without parameters) url'''
        return self.server + '/' + self.version + '/' + section + '.' \
            + method + '/' + self.lang + '/' + self.view + '/' + self.api_key

    def url_parameter_builder(self, section, method, parameters):
        '''Builds just the parameters for a url'''
        method = (section + '.' + method).lower()
        # todo: need to move this checks into a list on the class
        url = '/' if method != 'movie.browse' else '?'
        if method == 'movie.browse':
            for key, value in parameters.items():
                url += key + '=' + urllib.quote(value.encode("utf-8")) + '&'
        else:
            for key, value in parameters.items():
                url += urllib.quote(value.encode("utf-8")) + '/'
        url = url[:-1] if url != '//' else ''
        return url

    def __getattr__(self, name):
        '''Creates a attribute to our api method the first time it gets
        called'''
        def meta_api_method(*arguments, **keywords):
            # todo: a little bit hacky but i need the arguments in the keywords
            # so you might get dummy Movie.browse parameters.
            for i, argument in enumerate(arguments):
                keywords[str(i)] = argument
            return self._api_method(name, keywords)
        setattr(self, name, meta_api_method)
        return self.__getattribute__(name)

    def _api_method(*arguments):
        '''Calls the api using the passed arguments received from the meta
        class'''
        self = arguments[0]
        section = type(self).__name__
        if section == 'TMDb':
            raise TMDbBaseError('Can not use the TMDb Base Class')
        method = arguments[1]
        parameters = arguments[2]
        url = self.url_base_builder(section, method)
        url += self.url_parameter_builder(section, method, parameters)
        return self._grab_url(url)

    def _grab_url(self, url):
        '''Retrieves and returns the content at the url'''
        try:
            urlhandle = urllib2.urlopen(url)
        except IOError, errormsg:
            raise TMDbHttpError('%s returned "%s"' % (url, errormsg))
        if urlhandle.code >= 400:
            raise TMDbHttpError('HTTP status code for %s was %d'
                % (url, urlhandle.code))
        return urlhandle.read()

class Auth(TMDb):
    '''Auth allows you to query all the methods in the Auth section
    of themoviedb.org api'''
    pass

class Media(TMDb):
    '''Media allows you to query all the methods in the Media section
    of themoviedb.org api'''
    pass

class Movie(TMDb):
    '''Movie allows you to query all the methods in the movie section
    of themoviedb.org api'''
    pass

class Person(TMDb):
    '''Person allows you to query all the methods in the Person section
    of themoviedb.org api'''
    pass


class Person(TMDb):
    '''Person allows you to query all the methods in the Person section
    of themoviedb.org api'''
    pass

class Genres(TMDb):
    '''Genres allows you to query all the methods in the Genres section
    of themoviedb.org api'''
    pass

def main():
    '''Main will read the arguments passed to the script and query the
    api. Where the first argument must be the Section(eg. Movie) the second
    must be the method name(eg. Search) and the last must be the parameters.

    Because the parameters gets passed directly to the api you can send more
    then one(eg. "order=asc&order_by=title")'''
    if len(sys.argv) != 4:
        print 'Usage: tmdb.py <Section> <Method> "<Parameters>"'
        sys.exit(1)
    section = type(sys.argv[1], (TMDb,), {})()
    method = section.__getattr__(sys.argv[2])
    print method(sys.argv[3])

if __name__ == '__main__':
    main()