Example #1
0
    def get(self):
        """ Attempt to get the initial version of the form from the website. """
        if self.cookies is None:
            get_or_post_a_url(_make_url('Default.aspx', False))
            response = get_or_post_a_url(_make_url('ReportManager.aspx?ReportVisibility=1&ReportCategory=0'))
            self.cookies = {'ASP.NET_SessionId': response.cookies.get('ASP.NET_SessionId')}

        response = get_or_post_a_url(self.start_url, cookies=self.cookies)
        self.form_data = FormData(response.content)
        if self.action_url is None:
            self.action_url = _make_url(self.form_data.action)
        return True
Example #2
0
    def _do_post(self, submit=False):
        """ Submit the form data and update based on response.
            Given how slow the parsing of a 3M HTML page is, try and use the
            X-MicrosoftAjax: Delta=true header to get smaller blocks for processing.
        """
        if self.form_data.action is None:
            self.logger.info("Unable to post due no action URL available. Did you call get()?")
            return None

        action_url = _make_url(self.form_data.action)
        form_hdrs = {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
                     'User-Agent': 'Mozilla',
                     'X-Requested-With': 'XMLHttpRequest',
                     'X-MicrosoftAjax': 'Delta=true',
                     'Referer': unquote(action_url)
                     }
        post_dict = self.form_data.as_post_data(submit=submit)
        post_data = "&".join(["{}={}".format(key, post_dict[key]) for key in post_dict.keys()])

        response = get_or_post_a_url(action_url,
                                     post=True,
                                     cookies=self.cookies,
                                     headers=form_hdrs,
                                     data=post_data)
        return response
Example #3
0
    def get(self):
        """ Attempt to get the initial version of the form from the website. """
        if self.cookies is None:
            get_or_post_a_url(_make_url('Default.aspx', False))
            response = get_or_post_a_url(
                _make_url(
                    'ReportManager.aspx?ReportVisibility=1&ReportCategory=0'))
            self.cookies = {
                'ASP.NET_SessionId': response.cookies.get('ASP.NET_SessionId')
            }

        response = get_or_post_a_url(self.start_url, cookies=self.cookies)
        self.form_data = FormData(response.content)
        if self.action_url is None:
            self.action_url = _make_url(self.form_data.action)
        return True
Example #4
0
    def _do_post(self, submit=False):
        """ Submit the form data and update based on response.
            Given how slow the parsing of a 3M HTML page is, try and use the
            X-MicrosoftAjax: Delta=true header to get smaller blocks for processing.
        """
        if self.form_data.action is None:
            self.logger.info(
                "Unable to post due no action URL available. Did you call get()?"
            )
            return None

        action_url = _make_url(self.form_data.action)
        form_hdrs = {
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
            'User-Agent': 'Mozilla',
            'X-Requested-With': 'XMLHttpRequest',
            'X-MicrosoftAjax': 'Delta=true',
            'Referer': unquote(action_url)
        }
        post_dict = self.form_data.as_post_data(submit=submit)
        post_data = "&".join(
            ["{}={}".format(key, post_dict[key]) for key in post_dict.keys()])

        response = get_or_post_a_url(action_url,
                                     post=True,
                                     cookies=self.cookies,
                                     headers=form_hdrs,
                                     data=post_data)
        return response
Example #5
0
    def get_data(self):
        """ Get the data from the DECC server and parse it into DECC records.

        :returns: True or False
        :rtype: bool
        """
        if self.filename is not None:
            return self._parse_filename()

        if self.available is None:
            self._find_available()
            if self.available is None:
                raise Exception("Unable to get details of available downloads")

        response = get_or_post_a_url(self.available['url'])
        self.raw_data = response.content

        if sys.version_info >= (3, 0):
            csvfile = csv.reader(
                codecs.iterdecode(response.content.splitlines(), 'latin1'))
        else:
            csvfile = csv.reader(response.content.splitlines())

        for row in csvfile:
            self._parse_row(row)
        self.records = sorted(self.records, key=lambda rec: rec.site_name)
        return True
Example #6
0
    def get_data(self):
        """ Get the data from the DECC server and parse it into DECC records.

        :returns: True or False
        :rtype: bool
        """
        if self.filename is not None:
            return self._parse_filename()

        if self.available is None:
            self._find_available()
            if self.available is None:
                raise Exception("Unable to get details of available downloads")

        response = get_or_post_a_url(self.available['url'])
        self.raw_data = response.content

        if sys.version_info >= (3, 0):
            csvfile = csv.reader(codecs.iterdecode(response.content.splitlines(), 'latin1'))
        else:
            csvfile = csv.reader(response.content.splitlines())

        for row in csvfile:
            self._parse_row(row)
        self.records = sorted(self.records, key=lambda rec: rec.site_name)
        return True
Example #7
0
    def get_data(self, **params):
        """ Get data from the Elexon servers and attempt to parse it into a series of
            dicts each representing a record. Parameters are passed as a dict.
            Multiple sets of data are created in the multi member, single sets in items.
        """
        if self.report is None:
            raise Exception(
                "ElexonAPI objects require the report be set before use.")
        if self.apikey is None:
            raise Exception(
                "An API key is required to use the Elexon API accessor functionality"
            )

        url = make_elexon_url(self.report, self.version)
        params.update({'APIKey': self.apikey, 'ServiceType': 'xml'})
        req = get_or_post_a_url(url, params=params)
        #        print(req.content)
        xml = parse_response_as_xml(req)
        http = xml.xpath('/response/responseMetadata/httpCode')
        response_code = int(http[0].text)
        if response_code == 204:
            print("No content returned, but no error reported.")
            return True
        elif response_code != 200:
            print("No data returned. Error reported.")
            err = xml.xpath('/response/responseMetadata/description')
            print(err[0].text)
            return False

        if self.MULTI_RESULTS is None:
            for item in xml.xpath('/response/responseBody/responseList/item'):
                item_dict = map_xml_to_dict(item, self.XML_MAPPING)

                if 'activeflag' in item_dict:
                    item_dict['activeflag'] = item_dict['activeflag'] == 'Y'
                if 'settlementperiod' in item_dict:
                    item_dict['settlementperiod'] = int(
                        item_dict['settlementperiod'])

                self.post_item_cleanup(item_dict)
                self.items.append(item_dict)
        else:
            for result_set in self.MULTI_RESULTS:
                self.multi[result_set[0]] = []
                for item in xml.xpath(result_set[1]):
                    item_dict = map_xml_to_dict(item, self.XML_MAPPING)
                    if 'activeFlags' in item_dict:
                        item_dict['activeflag'] = item_dict[
                            'activeflag'] == 'Y'
                    if 'settlementperiod' in item_dict:
                        item_dict['settlementperiod'] = int(
                            item_dict['settlementperiod'])

                    self.post_item_cleanup(item_dict)
                    #                    print(item_dict)
                    self.multi[result_set[0]].append(item_dict)

        return True
Example #8
0
    def get_data(self):
        """ Get data from the BM Reports website. Try 3 times.
        """
        resp = get_or_post_a_url(self.URL, params=self.PARAMS)
        self.xml = parse_response_as_xml(resp)
        if self.xml is None:
            return

        for section in ['INST', 'HH', 'LAST24H']:
            self.sections.append(GenerationPeriod(self.xml.xpath(section)[0]))
Example #9
0
    def get_data(self):
        """ Get data from the BM Reports website. Try 3 times.
        """
        resp = get_or_post_a_url(self.URL, params=self.PARAMS)
        self.xml = parse_response_as_xml(resp)
        if self.xml is None:
            return

        for section in ['INST', 'HH', 'LAST24H']:
            self.sections.append(GenerationPeriod(self.xml.xpath(section)[0]))
Example #10
0
    def get_prices(self):
        """
        Get the recent prices.

        :return: True or False
        :rtype: bool
        """
        resp = get_or_post_a_url(self.URL)
        self._parse_content(resp.content)
        return True
Example #11
0
    def get_prices(self):
        """
        Get the recent prices.

        :return: True or False
        :rtype: bool
        """
        resp = get_or_post_a_url(self.URL)
        self._parse_content(resp.content)
        return True
Example #12
0
    def get_data(self, **params):
        """ Get data from the Elexon servers and attempt to parse it into a series of
            dicts each representing a record. Parameters are passed as a dict.
            Multiple sets of data are created in the multi member, single sets in items.
        """
        if self.report is None:
            raise Exception("ElexonAPI objects require the report be set before use.")
        if self.apikey is None:
            raise Exception("An API key is required to use the Elexon API accessor functionality")

        url = make_elexon_url(self.report, self.version)
        params.update({'APIKey': self.apikey, 'ServiceType': 'xml'})
        req = get_or_post_a_url(url, params=params)
#        print(req.content)
        xml = parse_response_as_xml(req)
        http = xml.xpath('/response/responseMetadata/httpCode')
        response_code = int(http[0].text)
        if response_code == 204:
            print("No content returned, but no error reported.")
            return True
        elif response_code != 200:
            print("No data returned. Error reported.")
            err = xml.xpath('/response/responseMetadata/description')
            print(err[0].text)
            return False

        if self.MULTI_RESULTS is None:
            for item in xml.xpath('/response/responseBody/responseList/item'):
                item_dict = map_xml_to_dict(item, self.XML_MAPPING)

                if 'activeflag' in item_dict:
                   item_dict['activeflag'] = item_dict['activeflag'] == 'Y'
                if 'settlementperiod' in item_dict:
                    item_dict['settlementperiod'] = int(item_dict['settlementperiod'])

                self.post_item_cleanup(item_dict)
                self.items.append(item_dict)
        else:
            for result_set in self.MULTI_RESULTS:
                self.multi[result_set[0]] = []
                for item in xml.xpath(result_set[1]):
                    item_dict = map_xml_to_dict(item, self.XML_MAPPING)
                    if 'activeFlags' in item_dict:
                       item_dict['activeflag'] = item_dict['activeflag'] == 'Y'
                    if 'settlementperiod' in item_dict:
                        item_dict['settlementperiod'] = int(item_dict['settlementperiod'])

                    self.post_item_cleanup(item_dict)
#                    print(item_dict)
                    self.multi[result_set[0]].append(item_dict)

        return True
Example #13
0
 def _find_available(self):
     """
     Get the URL and period for the currently available download.
     """
     response = get_or_post_a_url(self.URL)
     document = html5lib.parse(response.content,
                               treebuilder="lxml",
                               namespaceHTMLElements=False)
     titles = document.xpath('.//h2[@class="title"]')
     period = None
     for tit in titles:
         if len(tit.getchildren()) == 0:
             period = tit.text.split(':')[1].strip()
     links = document.xpath('.//span[@class="download"]/a')
     self.available = {'period': period,
                       'url': self.BASE_URL + links[0].get('href')}
Example #14
0
 def _find_available(self):
     """
     Get the URL and period for the currently available download.
     """
     response = get_or_post_a_url(self.URL)
     document = html5lib.parse(response.content,
                               treebuilder="lxml",
                               namespaceHTMLElements=False)
     titles = document.xpath('.//h2[@class="title"]')
     period = None
     for tit in titles:
         if len(tit.getchildren()) == 0:
             period = tit.text.split(':')[1].strip()
     links = document.xpath('.//span[@class="download"]/a')
     self.available = {
         'period': period,
         'url': self.BASE_URL + links[0].get('href')
     }
Example #15
0
    def get_data(self):
        """ Get the data from the remote server. """
        data = {'element': 'SYSPRICE', 'dT': self.dtt.strftime("%Y-%m-%d")}
        resp = get_or_post_a_url(self.URL, params=data)
        self.xml = parse_response_as_xml(resp)
        if self.xml is None:
            return False

        for elm in self.xml.xpath('.//ELEMENT'):
            data = {}
            for elm2 in elm.getchildren():
                if elm2.tag == 'SP':
                    data['period'] = int(elm2.text)
                elif elm2.tag == 'SD':
                    data['date'] = datetime.strptime(elm2.text, "%Y-%m-%d")
                else:
                    data[elm2.tag.lower()] = elm2.text
            self.prices.append(data)
        return len(self.prices) > 0
Example #16
0
    def get_data(self):
        """ Get the data from the remote server. """
        data = {'element': 'SYSPRICE',
                'dT': self.dtt.strftime("%Y-%m-%d")}
        resp = get_or_post_a_url(self.URL, params=data)
        self.xml = parse_response_as_xml(resp)
        if self.xml is None:
            return False

        for elm in self.xml.xpath('.//ELEMENT'):
            data = {}
            for elm2 in elm.getchildren():
                if elm2.tag == 'SP':
                    data['period'] = int(elm2.text)
                elif elm2.tag == 'SD':
                    data['date'] = datetime.strptime(elm2.text, "%Y-%m-%d")
                else:
                    data[elm2.tag.lower()] = elm2.text
            self.prices.append(data)
        return len(self.prices) > 0
Example #17
0
    def get_data(self, **params):
        if self.report is None:
            raise Exception("ElexonAPI objects require the report be set before use.")
        if self.apikey is None:
            raise Exception("An API key is required to use the Elexon API accessor functionality")

        url = make_elexon_url(self.report, self.version)
        params.update({'APIKey': self.apikey, 'ServiceType': 'xml'})
        req = get_or_post_a_url(url, params=params)
        xml = parse_response_as_xml(req)
        http = xml.xpath('/response/responseMetadata/httpCode')
        if int(http[0].text) != 200:
            return False

        for item in xml.xpath('/response/responseBody/responseList/item'):
            item_dict = map_children_to_dict(item, self.XML_MAPPING)
            self.post_item_cleanup(item_dict)
            self.items.append(item_dict)

        return True
Example #18
0
    def get_data(self):
        """ Get the report data and update.

        :returns: True or False
        :rtype: bool
        """
        self.data = []
        params = {
            'param5': self.date.strftime("%Y-%m-%d"),
            'param6': self.period,
            'element': self.type,
            'param1': self.unitid,
            'param2': self.unittype,
            'param3': self.leadparty,
            'param4': self.ngcunitname,
        }

        if self.historic:
            resp = get_or_post_a_url('http://www.bmreports.com/bsp/additional/soapfunctions.php?',
                                     params=params)
            return self._process(resp)
        return False
Example #19
0
    def submit(self):
        """ Submit the form data and update based on response.
            Given how slow the parsing of a 3M HTML page is, try and use the
            X-MicrosoftAjax: Delta=true header to get smaller blocks for processing.
        """
        is_set, upd = self.form_data.set_value_by_label('Page Size', '25')
        if is_set is False:
            return False
        response = self._do_post(True)
        if response is None:
            return False
        if self.form_data.update(response.content) is False:
            self.logger.warning("Submit failed :-(")
            return False

        if self.form_data.export_url is None:
            self.logger.warning("Unable to find the export url. Cannot continue.")
            return False

        export_url = _make_url(self.form_data.export_url) + 'XML'
        response = get_or_post_a_url(export_url, cookies=self.cookies)
        self.raw_data = response.content
        return True
Example #20
0
    def get_data(self):
        """ Get the report data and update.

        :returns: True or False
        :rtype: bool
        """
        self.data = []
        params = {
            'param5': self.date.strftime("%Y-%m-%d"),
            'param6': self.period,
            'element': self.type,
            'param1': self.unitid,
            'param2': self.unittype,
            'param3': self.leadparty,
            'param4': self.ngcunitname,
        }

        if self.historic:
            resp = get_or_post_a_url(
                'http://www.bmreports.com/bsp/additional/soapfunctions.php?',
                params=params)
            return self._process(resp)
        return False
Example #21
0
    def get_list(self):
        """ Download and update the unit list.

        :rtype: bool
        """
        self.units = []
        resp = get_or_post_a_url(self.XLS_URL)
        self.raw_data = resp.content

        tmp_f = NamedTemporaryFile(delete=False)
        with open(tmp_f.name, 'wb') as fhh:
            fhh.write(resp.content)

        wbb = xlrd.open_workbook(tmp_f.name)
        sht = wbb.sheet_by_name(self.SHEET_NAME)

        for rownum in range(1, sht.nrows):
            self._extract_row_data(wbb, sht, rownum)

        try:
            os.unlink(tmp_f.name)
        except Exception:
            pass
        return True
Example #22
0
    def submit(self):
        """ Submit the form data and update based on response.
            Given how slow the parsing of a 3M HTML page is, try and use the
            X-MicrosoftAjax: Delta=true header to get smaller blocks for processing.
        """
        is_set, upd = self.form_data.set_value_by_label('Page Size', '25')
        if is_set is False:
            return False
        response = self._do_post(True)
        if response is None:
            return False
        if self.form_data.update(response.content) is False:
            self.logger.warning("Submit failed :-(")
            return False

        if self.form_data.export_url is None:
            self.logger.warning(
                "Unable to find the export url. Cannot continue.")
            return False

        export_url = _make_url(self.form_data.export_url) + 'XML'
        response = get_or_post_a_url(export_url, cookies=self.cookies)
        self.raw_data = response.content
        return True
Example #23
0
    def get_list(self):
        """ Download and update the unit list.

        :rtype: bool
        """
        self.units = []
        resp = get_or_post_a_url(self.XLS_URL)
        self.raw_data = resp.content

        tmp_f = NamedTemporaryFile(delete=False)
        with open(tmp_f.name, 'wb') as fhh:
            fhh.write(resp.content)

        wbb = xlrd.open_workbook(tmp_f.name)
        sht = wbb.sheet_by_name(self.SHEET_NAME)

        for rownum in range(1, sht.nrows):
            self._extract_row_data(wbb, sht, rownum)

        try:
            os.unlink(tmp_f.name)
        except Exception:
            pass
        return True