#!/usr/bin/env python
#
# Copyright 2011 Jonathan LeBlanc
#
# 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.
#

import re
import urllib
import urllib2

'''
' Class: Błąd publikacji
' Description: Niestandardowa klasa błedu dla wyjątków publikacji
'''
class PublishError(Exception):
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr(self.value)

'''
' Class: Wydawca
' Description: Umożliwia publikowanie aktualizacji dla kanałów
'''
class Publisher:
    regex_url = re.compile('^https?://')    # prosty mechanizm weryfikacji adresu URL
    
    # Konstruktor zapisujący hub dla danego wydawcy
    def __init__(self, hub):
        if self.regex_url.match(hub): self.hub = hub
        else: raise PublishError('Nieprawidłowy adres URL huba')
    
    # Wysyła żądanie do huba i aktualizuje kanały
    def publish(self, feeds):
        # Ustawia tryb w ramach łańcucha żądania POST
        post_string = 'hub.mode=publish'
        
        # Dodaje poszczególne kanały w formie adresów URL w łańcuchu POST (dodaje tylko prawidłowe adresy URL)
        for feed in feeds:
            if self.regex_url.match(feed):
                post_string += '&hub.url=%s' % (urllib.quote(feed))
            else:
                raise PublishError('Nieprawidłowy adres URL kanału: %s' % (feed))
            
        try:
            # Wysyła żądanie do huba
            file = urllib2.urlopen(self.hub, post_string)
            return True
        except (IOError, urllib2.HTTPError), e:
            # Przetwarza odpowiedź HTTP (kody 2xx oznaczają prawidłową odpowiedź serwera)
            if hasattr(e, 'code') and str(e.code)[0] == '2':
                return True
                
            # Przetwarza błędy
            error = ''
            if hasattr(e, 'read'):
                error = e.read()
            raise PublishError('%s, Odpowiedź: "%s"' % (e, error))    