<commit_before>"""
This module provides a wrapper around the Helioviewer API.
"""
from __future__ import absolute_import

#pylint: disable=E1101,F0401,W0231
__author__ = ["<NAME>"]
__email__ = "<EMAIL>"

import os
import json
import urllib
import urllib2
import sunpy
from sunpy.time import parse_time

class HelioviewerClient:
    """Helioviewer.org Client"""
    def __init__(self, url="http://helioviewer.org/api/"):
        self._api = url

    def get_data_sources(self, **kwargs):
        """Returns a structured list of datasources available at Helioviewer.org"""
        params = {"action": "getDataSources"}
        params.update(kwargs)
        
        return self._get_json(params)    
    
    def get_closest_image(self, date, **kwargs):
        """Finds the closest image available for the specified source and date.
        
        For more information on what types of requests are available and the
        expected usage for the response, consult the Helioviewer API documenation:
            http://helioviewer.org/api
        
        Parameters
        ----------
        date : datetime, string
            A string or datetime object for the desired date of the image
        observatory : string
            (Optional) Observatory name
        instrument : string
            (Optional) instrument name
        detector : string
            (Optional) detector name
        measurement : string
            (Optional) measurement name
        sourceId : int
            (Optional) data source id
            
        Returns
        -------
        out : dict
            A dictionary containing metainformation for the closest image matched
            
        Examples
        --------
        >>> from sunpy.net import helioviewer
        >>> client = helioviewer.HelioviewerClient()
        >>> metadata = client.get_closest_image('2012/01/01', sourceId=11)
        >>> print(metadata['date'])
        """
        params = {
            "action": "getClosestImage",
            "date": self._format_date(date)
        }
        params.update(kwargs)
        
        response = self._get_json(params)
        
        # Cast date string to DateTime
        response['date'] = sunpy.time.parse_time(response['date'])
        
        return response
    
    def get_jp2_image(self, date, directory=None, **kwargs):
        """
        Downloads the JPEG 2000 that most closely matches the specified time and 
        data source.
        
        The data source may be specified either using it's sourceId from the
        get_data_sources query, or a combination of observatory, instrument,
        detector and measurement. 
        
        Parameters
        ----------
        date : datetime, string
            A string or datetime object for the desired date of the image
        directory : string
            Directory to download JPEG 2000 image to.
        observatory : string
            (Optional) Observatory name
        instrument : string
            (Optional) instrument name
        detector : string
            (Optional) detector name
        measurement : string
            (Optional) measurement name
        sourceId : int
            (Optional) data source id
        jpip : bool
            (Optional) Returns a JPIP URI if set to True
            
        Returns
        -------
        out : Returns a map representation of the requested image or a URI if
        "jpip" parameter is set to True.
        
        Examples
        --------
        >>> from sunpy.net import helioviewer
        >>> client = helioviewer.HelioviewerClient()
        >>> aia = client.get_jp2_image('2012/07/03 14:30:00', observatory='SDO', instrument='AIA', detector='AIA', measurement='171')
        >>> aia.show()
        >>>
        >>> data_sources = client.get_data_sources()
        >>> lasco = client.get_jp2_image('2012/07/03 14:30:00', sourceId=data_sources['SOHO']['LASCO']['C2']['white-light']['sourceId'])
        """
        params = {
            "action": "getJP2Image",
            "date": self._format_date(date)
        }
        params.update(kwargs)
        
        # JPIP URL response
        if 'jpip' in kwargs:
            return self._get_json(params)
    
        filepath = self._get_file(params, directory)
    
        return sunpy.make_map(filepath)
    
    def _get_json(self, params):
        """Returns a JSON result as a string"""
        response = self._request(params).read()
        return json.loads(response)
    
    def _get_file(self, params, directory=None):
        """Downloads a file and return the filepath to that file"""
        # Query Helioviewer.org
        response = self._request(params)
        
        # JPEG 2000 image response
        if directory is None:
            directory = sunpy.config.get('downloads', 'download_dir')
        
        filename = response.info()['Content-Disposition'][22:-1]
        filepath = os.path.join(directory, filename)
        
        f = open(filepath, 'wb')
        f.write(response.read())
        f.close()
        
        return filepath
    
    def _request(self, params):
        """Sends an API request and returns the result
        
        Parameters<commit_msg>Added takeScreenshot API request to helioviewer module<commit_after>"""
This module provides a wrapper around the Helioviewer API.
"""
from __future__ import absolute_import

#pylint: disable=E1101,F0401,W0231
__author__ = ["<NAME>"]
__email__ = "<EMAIL>"

import os
import json
import urllib
import urllib2
import sunpy
from sunpy.time import parse_time

class HelioviewerClient:
    """Helioviewer.org Client"""
    def __init__(self, url="http://helioviewer.org/api/"):
        self._api = url

    def get_data_sources(self, **kwargs):
        """Returns a structured list of datasources available at Helioviewer.org"""
        params = {"action": "getDataSources"}
        params.update(kwargs)
        
        return self._get_json(params)    
    
    def get_closest_image(self, date, **kwargs):
        """Finds the closest image available for the specified source and date.
        
        For more information on what types of requests are available and the
        expected usage for the response, consult the Helioviewer API documenation:
            http://helioviewer.org/api
        
        Parameters
        ----------
        date : datetime, string
            A string or datetime object for the desired date of the image
        observatory : string
            (Optional) Observatory name
        instrument : string
            (Optional) instrument name
        detector : string
            (Optional) detector name
        measurement : string
            (Optional) measurement name
        sourceId : int
            (Optional) data source id
            
        Returns
        -------
        out : dict
            A dictionary containing metainformation for the closest image matched
            
        Examples
        --------
        >>> from sunpy.net import helioviewer
        >>> client = helioviewer.HelioviewerClient()
        >>> metadata = client.get_closest_image('2012/01/01', sourceId=11)
        >>> print(metadata['date'])
        """
        params = {
            "action": "getClosestImage",
            "date": self._format_date(date)
        }
        params.update(kwargs)
        
        response = self._get_json(params)
        
        # Cast date string to DateTime
        response['date'] = sunpy.time.parse_time(response['date'])
        
        return response
    
    def get_jp2_image(self, date, directory=None, **kwargs):
        """
        Downloads the JPEG 2000 that most closely matches the specified time and 
        data source.
        
        The data source may be specified either using it's sourceId from the
        get_data_sources query, or a combination of observatory, instrument,
        detector and measurement. 
        
        Parameters
        ----------
        date : datetime, string
            A string or datetime object for the desired date of the image
        directory : string
            (Optional) Directory to download JPEG 2000 image to.
        observatory : string
            (Optional) Observatory name
        instrument : string
            (Optional) instrument name
        detector : string
            (Optional) detector name
        measurement : string
            (Optional) measurement name
        sourceId : int
            (Optional) data source id
        jpip : bool
            (Optional) Returns a JPIP URI if set to True
            
        Returns
        -------
        out : Returns a map representation of the requested image or a URI if
        "jpip" parameter is set to True.
        
        Examples
        --------
        >>> from sunpy.net import helioviewer
        >>> client = helioviewer.HelioviewerClient()
        >>> aia = client.get_jp2_image('2012/07/03 14:30:00', observatory='SDO', instrument='AIA', detector='AIA', measurement='171')
        >>> aia.show()
        >>>
        >>> data_sources = client.get_data_sources()
        >>> lasco = client.get_jp2_image('2012/07/03 14:30:00', sourceId=data_sources['SOHO']['LASCO']['C2']['white-light']['sourceId'])
        """
        params = {
            "action": "getJP2Image",
            "date": self._format_date(date)
        }
        params.update(kwargs)
        
        # JPIP URL response
        if 'jpip' in kwargs:
            return self._get_json(params)
    
        filepath = self._get_file(params, directory)
    
        return sunpy.make_map(filepath)
    
    def take_screenshot(self, date, image_scale, layers, directory=None, 
                        **kwargs):
        """Creates a screenshot using the Helioviewer.org API and saves
        the image to the hard disk.
        
        Returns a single image containing all layers/image types requested. 
        If an image is not available for the date requested the closest 
        available image is returned. The region to be included in the 
        screenshot may be specified using either the top-left and bottom-right 
        coordinates in arc-seconds, or a center point in arc-seconds and a 
        width and height in pixels. See the Helioviewer.org API Coordinates 
        Appendix for more infomration about working with coordinates in 
        Helioviewer.org.

        Parameters
        ----------
        date : datetime, string
            A string or datetime object for the desired date of the image
        image_scale : float
            The zoom scale of the image. Default scales that can be used are 
            0.6, 1.2, 2.4, and so on, increasing or decreasing by a factor 
            of 2. The full-res scale of an AIA image is 0.6.
        layers : string
            Each layer string is comma-separated with these values, e.g.:
            "[sourceId,visible,opacity]" or "[obs,inst,det,meas,visible,opacity]"
            Mulitple layer string are by commas: "[layer1],[layer2],[layer3]"
        directory : string
            (Optional)  Directory to download JPEG 2000 image to.
        x1 : float
            (Optional) The offset of the image's left boundary from the center 
            of the sun, in arcseconds.        
        y1 : float
            (Optional) The offset of the image's top boundary from the center 
            of the sun, in arcseconds.
        x2 : float
            (Optional) The offset of the image's right boundary from the 
            center of the sun, in arcseconds.
        y2 : float
            (Optional) The offset of the image's bottom boundary from the 
            center of the sun, in arcseconds.
        x0 : float
            (Optional) The horizontal offset from the center of the Sun.
        y0 : float
            (Optional) The vertical offset from the center of the Sun.
        width : int
            (Optional) Width of the screenshot in pixels (Maximum: 1920).
        height : int
            (Optional) Height of the screenshot in pixels (Maximum: 1200).
        watermark
            (Optional) Whether or not the include the timestamps and the 
            Helioviewer.org logo in the screenshot (Default=True).
            
        Returns
        -------
        out : string
            filepath to the screenshot
            
        Examples
        --------
        >>> from sunpy.net.helioviewer import HelioviewerClient
        >>> hv = HelioviewerClient()
        >>> hv.take_screenshot('2012/07/16 10:08:00', 2.4, "[SDO,AIA,AIA,171,1,100]", x0=0, y0=0, width=1024, height=1024)
        '/home/user/sunpy/data/2012_07_16_10_08_00_AIA_171.png
        >>> hv.take_screenshot('2012/07/16 10:08:00', 4.8, "[SDO,AIA,AIA,171,1,100],[SOHO,LASCO,C2,white-light,1,100]", x1=-2800, x2=2800, y1=-2800, y2=2800, directory='~/Desktop')
        '/home/user/Desktop/2012_07_16_10_08_00_AIA_171__LASCO_C2.png'        
        """
        params = {
            "action": "takeScreenshot",
            "date": self._format_date(date),
            "imageScale": image_scale,
            "layers": layers,
            "display": True
        }
        params.update(kwargs)
        
        return self._get_file(params, directory)
        
    
    def _get_json(self, params):
        """Returns a JSON result as a string"""
        response = self._request(params).read()
        return json.loads(response)
    
    def _get_file(self, params, directory=None):
        """Downloads a file and return the filepath to that file"""
        # Query Helioviewer.org
        response = self._request(params)
        
        # JPEG 2000 image response
        if directory is None:
            directory = sunpy.config.get('downloads', 'download_dir')
        else:
            directory = os.path.abspath(os.path.expanduser(directory))

        # Get filename
        content = response.info()['Content-Disposition']
        filename = content[content.find('filename=') + 10: -1]
        filepath = os.path.join(directory, filename)
        
        f = open(filepath, 'wb')
        f.write(response.read())
        f.close()
        
        return filepath
    
    def _request(self, params):
        """Sends an API request and returns the result
        
        Parameters
{'fraction_non_alphanumeric': 0.09243050206568168, 'fraction_numerical': 0.02072683985715286, 'mean_word_length': 1.9152888344560115, 'pattern_counts': {'":': 15, '<': 7, '<?xml version=': 0, '>': 85, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 11, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2939950', 'n_tokens_mistral': 3970, 'n_tokens_neox': 3755, 'n_words': 1204}