# -*- coding: utf-8 -*-
# Copyright 2012 Julien Sobrier
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

""" Version 1.12.1

Python module for Browshot (http://www.browshot.com/), a web service to create website screenshots.

Browshot (http://www.browshot.com/) is a web service to easily make screenshots of web pages in any screen size, as any device: iPhone, iPad, Android, Nook, PC, etc. Browshot has full Flash, JavaScript, CSS, & HTML5 support.

The latest API version is detailed at http://browshot.com/api/documentation. browshot.py follows the API documentation very closely: the function names are similar to the URLs used (screenshot/create becomes screenshot_create(), instance/list becomes instance_list(), etc.), the request arguments are exactly the same, etc.

The library version matches closely the API version it handles: browshot.py 1.0.0 is the first release for the API 1.0, browshot.py 1.1.1 is the second release for the API 1.1, etc.

browshot.py can handle most the API updates within the same major version, e.g. browshot.py 1.0.0 should be compatible with the API 1.1 or 1.2. """


import urllib
from urllib2 import Request, urlopen, URLError, HTTPError
import simplejson


class BrowshotClient(object):
    def __init__(self, key='', base='https://api.browshot.com/api/v1/', debug=0):
        """ Create a new WebService::Browshot object. You must pass your API key (go to you Dashboard to find your API key, https://browshot.com/dashboard).

        Arguments:
            key:  API key.
            base: Base URL for all API requests. You should use the default base provided by the library. Be careful if you decide to use HTTP instead of HTTPS as your API key could be sniffed and your account could be used without your consent.
            debug: Set to 1 to print debug output to the standard output. 0 (disabled) by default.
        """
        self.key = key
        self.base = base
        self.debug = debug

    def api_version(self):
        """ Return the API version handled by the library. Note that this library can usually handle new arguments in requests without requiring an update. """
        return '1.12'

    def simple(self, url='', parameters={}):
        """ Retrieve a screenshot in one function.

            Note: by default, screenshots are cached for 24 hours. You can tune this valu with the cache=X parameter.

            Arguments:
            See http://browshot.com/api/documentation#simple for the full list of possible arguments.
                url (Required): URL of the screenshot

            Returns {'code': <code>, 'png': <content>}
                <code>: 200 if successful
                <content>: PNG file
        """
        parameters.update({'url': url})
        uri = self.make_url('simple', parameters)
        if self.debug:
            print uri

        try:
            response = urlopen(uri)

            return {'code': 200, 'png': response.read()}
        except HTTPError, e:
            return {'code': e.code, 'png': ''}
        except Exception, e:
            return {'code': 400, 'png': ''}



    def simple_file(self, url='', file='', parameters={}):
        """ Retrieve a screenshot, or a thumbnail, and save it to a fil in one functione.

        Note: by default, screenshots are cached for 24 hours. You can tune this valu with the cache=X parameter.

        Returns {'code': <code>, 'file': <file path}
                <code>: 200 if successful
                <file path>: local file where the screenshot was saved, empty string it if failed

        Arguments:
        See http://browshot.com/api/documentation#simple for the full list of possible arguments.
            url (Required): URL of the screenshot
            file (Required): local file to store the screenshot
         """
        data = self.simple(url, parameters);
        if len(data['png']) > 0:
            image = open(file, mode='wb')
            image.write(data['png'])
            image.close();
            return {'code': data['code'], 'file': file}

        return {'code': data['code'], 'file': ''}


    def instance_list(self):
        """ Return the list of instances as a dictionary. See http://browshot.com/api/documentation#instance_list for the response format. """
        return self.return_reply('instance/list')


    def instance_info(self, id=0):
        """ Return the details of an instance. See http://browshot.com/api/documentation#instance_info for the response format.

            Arguments:
                id (Required): Instance ID
         """
        return self.return_reply('instance/info', { 'id': id })

    def instance_create(self,parameters={}):
        """ Create a private instance. See http://browshot.com/api/documentation#instance_create for the response format.

            Arguments:
                See http://browshot.com/api/documentation#instance_create for the full list of possible arguments.
         """
        return self.return_reply('instance/create', parameters)


    def browser_list(self):
        """ Return the list of browsers as a hash reference. See http://browshot.com/api/documentation#browser_list for the response format. """
        return self.return_reply('browser/list')

    def browser_info(self, id=0):
        """ Return the details of a browser. See L<http://browshot.com/api/documentation#browser_info> for the response format.

            Arguments:
                id (Required: Browser ID
        """
        return self.return_reply('browser/info', { 'id': id })

    def browser_create(self,parameters={}):
        """ Create a custom browser. See http://browshot.com/api/documentation#browser_create for the response format.

            Arguments:
                See http://browshot.com/api/documentation#browser_create for the full list of possible arguments.
         """
        return self.return_reply('browser/create', parameters)

    def screenshot_create(self, url='', parameters={}):
        """ Request a screenshot. See http://browshot.com/api/documentation#screenshot_create for the response format.

            Note: by default, screenshots are cached for 24 hours. You can tune this valu with the cache=X parameter.

            Arguments:
            See http://browshot.com/api/documentation#screenshot_create for the full list of possible arguments.
                url(Required): URL of the website to create a screenshot of.
        """
        parameters.update({'url': url})
        return self.return_reply('screenshot/create', parameters)

    def screenshot_info(self, id=0, parameters={}):
        """ Get information about a screenshot requested previously. See http://browshot.com/api/documentation#screenshot_info for the response format.

            Arguments:
                id (Required): Screenshot ID.
        """
        parameters.update({'id': id})
        return self.return_reply('screenshot/info', parameters)

    def screenshot_list(self, parameters={}):
        """ Get details about screenshot requested. See http://browshot.com/api/documentation#screenshot_list for the response format. """
        return self.return_reply('screenshot/list', parameters)

    def screenshot_host(self, id=0, parameters={}):
        """ Host a screenshot or a thumbnail. See L<http://browshot.com/api/documentation#screenshot_host> for the response format.

            Arguments:
            See http://browshot.com/api/documentation#screenshot_host for the full list of possible arguments.
                id (Required): screenshot ID
        """
        parameters.update({'id': id})
        return self.return_reply('screenshot/host', parameters)

    def screenshot_share(self, id=0, parameters={}):
        """ Share a screenshot. See L<http://browshot.com/api/documentation#screenshot_share> for the response format.

            Arguments:
            See http://browshot.com/api/documentation#screenshot_share for the full list of possible arguments.
                id (Required): screenshot ID
        """
        parameters.update({'id': id})
        return self.return_reply('screenshot/share', parameters)

    def screenshot_search(self, url='', parameters={}):
        """ Get details about screenshots requested. See L<http://browshot.com/api/documentation#screenshot_search> for the response format.

            Arguments:
            See http://browshot.com/api/documentation#screenshot_search for the full list of possible arguments.
                url (Required): URL string to match
        """
        parameters.update({'url': url})
        return self.return_reply('screenshot/search', parameters)

    def screenshot_delete(self, id=0, parameters={}):
        """ Deleet details of a screenshot. See L<http://browshot.com/api/documentation#screenshot_delete> for the response format.

            Arguments:
            See http://browshot.com/api/documentation#screenshot_delete for the full list of possible arguments.
                id (Required): screenshot ID
        """
        parameters.update({'id': id})
        return self.return_reply('screenshot/delete', parameters)

    def screenshot_thumbnail(self, id=0, parameters={}):
        """ Retrieve the screenshot, or a thumbnail. See L<http://browshot.com/api/documentation#screenshot_thumbnail> for the response format.

            Arguments:
            See http://browshot.com/api/documentation#screenshot_thumbnail for the full list of possible arguments.
                id (Required): screenshot ID. You will get the full image if no other argument is specified.
        """
        parameters.update({'id': id})
        url = self.make_url('screenshot/thumbnail', parameters)
        response = urllib.urlopen(url)
        return response.read()

    def screenshot_thumbnail_file(self, url='', id=0, parameters={}):
        """ Retrieve the screenshot, or a thumbnail, and save it to a file. See http://browshot.com/api/documentation#screenshot_thumbnail for the response format.

        Returns the file name if successful.

        Arguments:
        See http://browshot.com/api/documentation#screenshot_thumbnail for the full list of possible arguments.
            id (Required): screenshot ID. You will get the full image if no other argument is specified.
            file (Required): local file to store the screenshot
         """
        content = self.screenshot_thumbnail(id, parameters);

        image = open(file, mode='wb')
        image.write(content)
        image.close();

        return file

    def account_info(self, parameters={}):
        """ Get details about the user account. See http://browshot.com/api/documentation#account_info for the response format. """
        return self.return_reply('account/info', parameters)


    def make_url(self, action='', parameters={}):
        url = self.base + action + '?key=' + urllib.quote_plus(self.key)

        for key, value in parameters.items():
            url += '&' + urllib.quote_plus(key) + '=' + urllib.quote_plus(str(value))

        if self.debug:
            print url

        return url

    def return_reply(self, action='', parameters={}):
        try:
            url    = self.make_url(action, parameters)

            response = urllib.urlopen(url)
            json = response.read()

            json_decode = simplejson.loads(json)
            return json_decode
        except Exception, e:
            raise e