mirror of
https://github.com/rembo10/headphones.git
synced 2026-07-21 00:14:02 +01:00
Merged prowl notifications from Calimerorulez
This commit is contained in:
@@ -321,6 +321,14 @@
|
|||||||
<br><br>
|
<br><br>
|
||||||
<h3>Log Directory:</h3><input type="text" name="log_dir" value="${config['log_dir']}" size="50">
|
<h3>Log Directory:</h3><input type="text" name="log_dir" value="${config['log_dir']}" size="50">
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<h2>Prowl Notification:</h2>
|
||||||
|
<br>
|
||||||
|
<h3><input type="checkbox" name="prowl_enabled" value="1" ${config['prowl_enabled']} />Enabled?</h3><br>
|
||||||
|
<h3>API key:</h3><input type="text" name="prowl_keys" value="${config['prowl_keys']}" size="50"><br><br>
|
||||||
|
<h3><input type="checkbox" name="prowl_onsnatch" value="1" ${config['prowl_onsnatch']} />Notify on snatch?</h3><br>
|
||||||
|
<h3>Priority (-2,-1,0,1 or 2):</h3><input type="text" name="prowl_priority" value="${config['prowl_priority']}" size="2">
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
@@ -454,4 +462,4 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</%def>
|
</%def>
|
||||||
|
|||||||
+17
-1
@@ -130,6 +130,10 @@ ENCODEROUTPUTFORMAT = None
|
|||||||
ENCODERQUALITY = None
|
ENCODERQUALITY = None
|
||||||
ENCODERVBRCBR = None
|
ENCODERVBRCBR = None
|
||||||
ENCODERLOSSLESS = False
|
ENCODERLOSSLESS = False
|
||||||
|
PROWL_ENABLED = True
|
||||||
|
PROWL_PRIORITY = 1
|
||||||
|
PROWL_KEYS = None
|
||||||
|
PROWL_ONSNATCH = True
|
||||||
|
|
||||||
def CheckSection(sec):
|
def CheckSection(sec):
|
||||||
""" Check if INI section exists, if not create it """
|
""" Check if INI section exists, if not create it """
|
||||||
@@ -191,7 +195,7 @@ def initialize():
|
|||||||
NZBMATRIX, NZBMATRIX_USERNAME, NZBMATRIX_APIKEY, NEWZNAB, NEWZNAB_HOST, NEWZNAB_APIKEY, \
|
NZBMATRIX, NZBMATRIX_USERNAME, NZBMATRIX_APIKEY, NEWZNAB, NEWZNAB_HOST, NEWZNAB_APIKEY, \
|
||||||
NZBSORG, NZBSORG_UID, NZBSORG_HASH, NEWZBIN, NEWZBIN_UID, NEWZBIN_PASSWORD, LASTFM_USERNAME, INTERFACE, FOLDER_PERMISSIONS, \
|
NZBSORG, NZBSORG_UID, NZBSORG_HASH, NEWZBIN, NEWZBIN_UID, NEWZBIN_PASSWORD, LASTFM_USERNAME, INTERFACE, FOLDER_PERMISSIONS, \
|
||||||
ENCODERFOLDER, ENCODER, BITRATE, SAMPLINGFREQUENCY, ENCODE, ADVANCEDENCODER, ENCODEROUTPUTFORMAT, ENCODERQUALITY, ENCODERVBRCBR, \
|
ENCODERFOLDER, ENCODER, BITRATE, SAMPLINGFREQUENCY, ENCODE, ADVANCEDENCODER, ENCODEROUTPUTFORMAT, ENCODERQUALITY, ENCODERVBRCBR, \
|
||||||
ENCODERLOSSLESS
|
ENCODERLOSSLESS, PROWL_ENABLED, PROWL_PRIORITY, PROWL_KEYS, PROWL_ONSNATCH
|
||||||
|
|
||||||
if __INITIALIZED__:
|
if __INITIALIZED__:
|
||||||
return False
|
return False
|
||||||
@@ -203,6 +207,7 @@ def initialize():
|
|||||||
CheckSection('Newznab')
|
CheckSection('Newznab')
|
||||||
CheckSection('NZBsorg')
|
CheckSection('NZBsorg')
|
||||||
CheckSection('Newzbin')
|
CheckSection('Newzbin')
|
||||||
|
CheckSection('Prowl')
|
||||||
|
|
||||||
# Set global variables based on config file or use defaults
|
# Set global variables based on config file or use defaults
|
||||||
try:
|
try:
|
||||||
@@ -290,6 +295,11 @@ def initialize():
|
|||||||
ENCODERQUALITY = check_setting_int(CFG, 'General', 'encoderquality', 2)
|
ENCODERQUALITY = check_setting_int(CFG, 'General', 'encoderquality', 2)
|
||||||
ENCODERVBRCBR = check_setting_str(CFG, 'General', 'encodervbrcbr', 'cbr')
|
ENCODERVBRCBR = check_setting_str(CFG, 'General', 'encodervbrcbr', 'cbr')
|
||||||
ENCODERLOSSLESS = bool(check_setting_int(CFG, 'General', 'encoderlossless', 1))
|
ENCODERLOSSLESS = bool(check_setting_int(CFG, 'General', 'encoderlossless', 1))
|
||||||
|
|
||||||
|
PROWL_ENABLED = bool(check_setting_int(CFG, 'Prowl', 'prowl_enabled', 0))
|
||||||
|
PROWL_KEYS = check_setting_str(CFG, 'Prowl', 'prowl_keys', '')
|
||||||
|
PROWL_ONSNATCH = bool(check_setting_int(CFG, 'Prowl', 'prowl_onsnatch', 0))
|
||||||
|
PROWL_PRIORITY = check_setting_int(CFG, 'Prowl', 'prowl_priority', 0)
|
||||||
|
|
||||||
if not LOG_DIR:
|
if not LOG_DIR:
|
||||||
LOG_DIR = os.path.join(DATA_DIR, 'logs')
|
LOG_DIR = os.path.join(DATA_DIR, 'logs')
|
||||||
@@ -471,6 +481,12 @@ def config_write():
|
|||||||
new_config['Newzbin']['newzbin_uid'] = NEWZBIN_UID
|
new_config['Newzbin']['newzbin_uid'] = NEWZBIN_UID
|
||||||
new_config['Newzbin']['newzbin_password'] = NEWZBIN_PASSWORD
|
new_config['Newzbin']['newzbin_password'] = NEWZBIN_PASSWORD
|
||||||
|
|
||||||
|
new_config['Prowl'] = {}
|
||||||
|
new_config['Prowl']['prowl_enabled'] = int(PROWL_ENABLED)
|
||||||
|
new_config['Prowl']['prowl_keys'] = PROWL_KEYS
|
||||||
|
new_config['Prowl']['prowl_onsnatch'] = int(PROWL_ONSNATCH)
|
||||||
|
new_config['Prowl']['prowl_priority'] = int(PROWL_PRIORITY)
|
||||||
|
|
||||||
new_config['General']['lastfm_username'] = LASTFM_USERNAME
|
new_config['General']['lastfm_username'] = LASTFM_USERNAME
|
||||||
new_config['General']['interface'] = INTERFACE
|
new_config['General']['interface'] = INTERFACE
|
||||||
new_config['General']['folder_permissions'] = FOLDER_PERMISSIONS
|
new_config['General']['folder_permissions'] = FOLDER_PERMISSIONS
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import os
|
|||||||
import time
|
import time
|
||||||
import encode
|
import encode
|
||||||
import urllib, shutil, re
|
import urllib, shutil, re
|
||||||
|
from headphones import prowl
|
||||||
|
from headphones.prowl import PROWL
|
||||||
import lib.beets as beets
|
import lib.beets as beets
|
||||||
from lib.beets import autotag
|
from lib.beets import autotag
|
||||||
from lib.beets.mediafile import MediaFile
|
from lib.beets.mediafile import MediaFile
|
||||||
@@ -254,6 +256,13 @@ def doPostProcessing(albumid, albumpath, release, tracks, downloaded_track_list)
|
|||||||
updateHave(albumpath)
|
updateHave(albumpath)
|
||||||
|
|
||||||
logger.info('Post-processing for %s - %s complete' % (release['ArtistName'], release['AlbumTitle']))
|
logger.info('Post-processing for %s - %s complete' % (release['ArtistName'], release['AlbumTitle']))
|
||||||
|
if headphones.PROWL_ONSNATCH:
|
||||||
|
pushmessage = release['ArtistName'] + ' - ' + release['AlbumTitle']
|
||||||
|
logger.info(u"Prowl request")
|
||||||
|
prowl = PROWL()
|
||||||
|
prowl.notify(pushmessage,"Download and Postprocessing completed")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def embedAlbumArt(artwork, downloaded_track_list):
|
def embedAlbumArt(artwork, downloaded_track_list):
|
||||||
logger.info('Embedding album art')
|
logger.info('Embedding album art')
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
from headphones import logger
|
||||||
|
import base64
|
||||||
|
import cherrypy
|
||||||
|
import urllib
|
||||||
|
import urllib2
|
||||||
|
import headphones
|
||||||
|
from httplib import HTTPSConnection
|
||||||
|
from urllib import urlencode
|
||||||
|
|
||||||
|
class PROWL:
|
||||||
|
|
||||||
|
keys = []
|
||||||
|
priority = []
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.enabled = headphones.PROWL_ENABLED
|
||||||
|
self.keys = headphones.PROWL_KEYS
|
||||||
|
self.priority = headphones.PROWL_PRIORITY
|
||||||
|
pass
|
||||||
|
|
||||||
|
def conf(self, options):
|
||||||
|
return cherrypy.config['config'].get('Prowl', options)
|
||||||
|
|
||||||
|
def notify(self, message, event):
|
||||||
|
if not headphones.PROWL_ENABLED:
|
||||||
|
return
|
||||||
|
|
||||||
|
http_handler = HTTPSConnection("api.prowlapp.com")
|
||||||
|
|
||||||
|
data = {'apikey': headphones.PROWL_KEYS,
|
||||||
|
'application': 'Headphones',
|
||||||
|
'event': event,
|
||||||
|
'description': message.encode("utf-8"),
|
||||||
|
'priority': headphones.PROWL_PRIORITY }
|
||||||
|
|
||||||
|
http_handler.request("POST",
|
||||||
|
"/publicapi/add",
|
||||||
|
headers = {'Content-type': "application/x-www-form-urlencoded"},
|
||||||
|
body = urlencode(data))
|
||||||
|
response = http_handler.getresponse()
|
||||||
|
request_status = response.status
|
||||||
|
|
||||||
|
if request_status == 200:
|
||||||
|
logger.info(u"Prowl notifications sent.")
|
||||||
|
return True
|
||||||
|
elif request_status == 401:
|
||||||
|
logger.info(u"Prowl auth failed: %s" % response.reason)
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
logger.info(u"Prowl notification failed.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def updateLibrary(self):
|
||||||
|
#For uniformity reasons not removed
|
||||||
|
return
|
||||||
|
|
||||||
|
def test(self, keys, priority):
|
||||||
|
|
||||||
|
self.enabled = True
|
||||||
|
self.keys = keys
|
||||||
|
self.priority = priority
|
||||||
|
|
||||||
|
self.notify('ZOMG Lazors Pewpewpew!', 'Test Message')
|
||||||
+7
-1
@@ -25,7 +25,8 @@ import urllib2, cookielib
|
|||||||
|
|
||||||
from headphones.common import USER_AGENT
|
from headphones.common import USER_AGENT
|
||||||
from headphones import logger
|
from headphones import logger
|
||||||
|
from headphones import prowl
|
||||||
|
from headphones.prowl import PROWL
|
||||||
|
|
||||||
def sendNZB(nzb):
|
def sendNZB(nzb):
|
||||||
|
|
||||||
@@ -116,6 +117,11 @@ def sendNZB(nzb):
|
|||||||
|
|
||||||
if sabText == "ok":
|
if sabText == "ok":
|
||||||
logger.info(u"NZB sent to SAB successfully")
|
logger.info(u"NZB sent to SAB successfully")
|
||||||
|
if headphones.PROWL_ONSNATCH:
|
||||||
|
logger.info(u"Prowl request")
|
||||||
|
prowl = PROWL()
|
||||||
|
prowl.notify(nzb.name,"Download started")
|
||||||
|
|
||||||
return True
|
return True
|
||||||
elif sabText == "Missing authentication":
|
elif sabText == "Missing authentication":
|
||||||
logger.info(u"Incorrect username/password sent to SAB, NZB not sent")
|
logger.info(u"Incorrect username/password sent to SAB, NZB not sent")
|
||||||
|
|||||||
@@ -495,9 +495,9 @@ def verifyresult(title, artistterm, term):
|
|||||||
if token == 'Various' or token == 'Artists' or token == 'VA':
|
if token == 'Various' or token == 'Artists' or token == 'VA':
|
||||||
continue
|
continue
|
||||||
if not re.search('(?:\W|^)+' + token + '(?:\W|$)+', title, re.IGNORECASE | re.UNICODE):
|
if not re.search('(?:\W|^)+' + token + '(?:\W|$)+', title, re.IGNORECASE | re.UNICODE):
|
||||||
if not re.search('(?:\W|^)+' + token.replace("'","") + '(?:\W|$)+', title, re.IGNORECASE | re.UNICODE):
|
if not re.search('(?:\W|^)+' + token.replace("'","") + '(?:\W|$)+', title, re.IGNORECASE | re.UNICODE):
|
||||||
logger.info("Removed from results: " + title + " (missing tokens: " + token + " and " + token.replace("'","") + ")")
|
logger.info("Removed from results: " + title + " (missing tokens: " + token + " and " + token.replace("'","") + ")")
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def getresultNZB(result):
|
def getresultNZB(result):
|
||||||
|
|||||||
+16
-1
@@ -355,6 +355,21 @@ configform = form = '''
|
|||||||
<p><b>Log Directory</b>:<br><input type="text" name="log_dir" value="%s" size="60">
|
<p><b>Log Directory</b>:<br><input type="text" name="log_dir" value="%s" size="60">
|
||||||
</p>
|
</p>
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<b>Prowl Notification:</b>
|
||||||
|
<p>
|
||||||
|
<input type="checkbox" name="prowl_enabled" value="1" %s />Enabled?
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<i class="smalltext">API key:</i>
|
||||||
|
<input type="text" name="prowl_keys" value="%s" size="50">
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<input type="checkbox" name="prowl_onsnatch" value="1" %s />Notify on snatch?</p>
|
||||||
|
<p><b>Priority (-2,-1,0,1 or 2):</b><input type="text" name="prowl_priority" value="%s" size="5">
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
@@ -422,4 +437,4 @@ def displayAlbums(ArtistID, Type=None):
|
|||||||
i = i+1
|
i = i+1
|
||||||
page.append('</table><br />')
|
page.append('</table><br />')
|
||||||
|
|
||||||
return ''.join(page)
|
return ''.join(page)
|
||||||
|
|||||||
+11
-2
@@ -378,7 +378,11 @@ class WebInterface(object):
|
|||||||
"samplingfrequency": headphones.SAMPLINGFREQUENCY,
|
"samplingfrequency": headphones.SAMPLINGFREQUENCY,
|
||||||
"encodervbrcbr": headphones.ENCODERVBRCBR,
|
"encodervbrcbr": headphones.ENCODERVBRCBR,
|
||||||
"encoderquality": headphones.ENCODERQUALITY,
|
"encoderquality": headphones.ENCODERQUALITY,
|
||||||
"encoderlossless": checked(headphones.ENCODERLOSSLESS)
|
"encoderlossless": checked(headphones.ENCODERLOSSLESS),
|
||||||
|
"prowl_enabled": checked(headphones.PROWL_ENABLED),
|
||||||
|
"prowl_onsnatch": checked(headphones.PROWL_ONSNATCH),
|
||||||
|
"prowl_keys": headphones.PROWL_KEYS,
|
||||||
|
"prowl_priority": headphones.PROWL_PRIORITY
|
||||||
}
|
}
|
||||||
return serve_template(templatename="config.html", title="Settings", config=config)
|
return serve_template(templatename="config.html", title="Settings", config=config)
|
||||||
config.exposed = True
|
config.exposed = True
|
||||||
@@ -390,7 +394,8 @@ class WebInterface(object):
|
|||||||
nzbsorg=0, nzbsorg_uid=None, nzbsorg_hash=None, newzbin=0, newzbin_uid=None, newzbin_password=None, preferred_quality=0, preferred_bitrate=None, detect_bitrate=0, move_files=0,
|
nzbsorg=0, nzbsorg_uid=None, nzbsorg_hash=None, newzbin=0, newzbin_uid=None, newzbin_password=None, preferred_quality=0, preferred_bitrate=None, detect_bitrate=0, move_files=0,
|
||||||
torrentblackhole_dir=None, download_torrent_dir=None, numberofseeders=10, use_isohunt=0, use_kat=0, use_mininova=0,
|
torrentblackhole_dir=None, download_torrent_dir=None, numberofseeders=10, use_isohunt=0, use_kat=0, use_mininova=0,
|
||||||
rename_files=0, correct_metadata=0, cleanup_files=0, add_album_art=0, embed_album_art=0, embed_lyrics=0, destination_dir=None, folder_format=None, file_format=None, include_extras=0, interface=None, log_dir=None,
|
rename_files=0, correct_metadata=0, cleanup_files=0, add_album_art=0, embed_album_art=0, embed_lyrics=0, destination_dir=None, folder_format=None, file_format=None, include_extras=0, interface=None, log_dir=None,
|
||||||
encode=0, encoder=None, bitrate=None, samplingfrequency=None, encoderfolder=None, advancedencoder=None, encoderoutputformat=None, encodervbrcbr=None, encoderquality=None, encoderlossless=0):
|
encode=0, encoder=None, bitrate=None, samplingfrequency=None, encoderfolder=None, advancedencoder=None, encoderoutputformat=None, encodervbrcbr=None, encoderquality=None, encoderlossless=0,
|
||||||
|
prowl_enabled=0, prowl_onsnatch=0, prowl_keys=None, prowl_priority=0):
|
||||||
|
|
||||||
headphones.HTTP_HOST = http_host
|
headphones.HTTP_HOST = http_host
|
||||||
headphones.HTTP_PORT = http_port
|
headphones.HTTP_PORT = http_port
|
||||||
@@ -450,6 +455,10 @@ class WebInterface(object):
|
|||||||
headphones.ENCODERVBRCBR = encodervbrcbr
|
headphones.ENCODERVBRCBR = encodervbrcbr
|
||||||
headphones.ENCODERQUALITY = int(encoderquality)
|
headphones.ENCODERQUALITY = int(encoderquality)
|
||||||
headphones.ENCODERLOSSLESS = encoderlossless
|
headphones.ENCODERLOSSLESS = encoderlossless
|
||||||
|
headphones.PROWL_ENABLED = prowl_enabled
|
||||||
|
headphones.PROWL_ONSNATCH = prowl_onsnatch
|
||||||
|
headphones.PROWL_KEYS = prowl_keys
|
||||||
|
headphones.PROWL_PRIORITY = prowl_priority
|
||||||
|
|
||||||
headphones.config_write()
|
headphones.config_write()
|
||||||
|
|
||||||
|
|||||||
Executable
+1215
File diff suppressed because it is too large
Load Diff
Executable
+110
@@ -0,0 +1,110 @@
|
|||||||
|
"""
|
||||||
|
iri2uri
|
||||||
|
|
||||||
|
Converts an IRI to a URI.
|
||||||
|
|
||||||
|
"""
|
||||||
|
__author__ = "Joe Gregorio (joe@bitworking.org)"
|
||||||
|
__copyright__ = "Copyright 2006, Joe Gregorio"
|
||||||
|
__contributors__ = []
|
||||||
|
__version__ = "1.0.0"
|
||||||
|
__license__ = "MIT"
|
||||||
|
__history__ = """
|
||||||
|
"""
|
||||||
|
|
||||||
|
import urlparse
|
||||||
|
|
||||||
|
|
||||||
|
# Convert an IRI to a URI following the rules in RFC 3987
|
||||||
|
#
|
||||||
|
# The characters we need to enocde and escape are defined in the spec:
|
||||||
|
#
|
||||||
|
# iprivate = %xE000-F8FF / %xF0000-FFFFD / %x100000-10FFFD
|
||||||
|
# ucschar = %xA0-D7FF / %xF900-FDCF / %xFDF0-FFEF
|
||||||
|
# / %x10000-1FFFD / %x20000-2FFFD / %x30000-3FFFD
|
||||||
|
# / %x40000-4FFFD / %x50000-5FFFD / %x60000-6FFFD
|
||||||
|
# / %x70000-7FFFD / %x80000-8FFFD / %x90000-9FFFD
|
||||||
|
# / %xA0000-AFFFD / %xB0000-BFFFD / %xC0000-CFFFD
|
||||||
|
# / %xD0000-DFFFD / %xE1000-EFFFD
|
||||||
|
|
||||||
|
escape_range = [
|
||||||
|
(0xA0, 0xD7FF ),
|
||||||
|
(0xE000, 0xF8FF ),
|
||||||
|
(0xF900, 0xFDCF ),
|
||||||
|
(0xFDF0, 0xFFEF),
|
||||||
|
(0x10000, 0x1FFFD ),
|
||||||
|
(0x20000, 0x2FFFD ),
|
||||||
|
(0x30000, 0x3FFFD),
|
||||||
|
(0x40000, 0x4FFFD ),
|
||||||
|
(0x50000, 0x5FFFD ),
|
||||||
|
(0x60000, 0x6FFFD),
|
||||||
|
(0x70000, 0x7FFFD ),
|
||||||
|
(0x80000, 0x8FFFD ),
|
||||||
|
(0x90000, 0x9FFFD),
|
||||||
|
(0xA0000, 0xAFFFD ),
|
||||||
|
(0xB0000, 0xBFFFD ),
|
||||||
|
(0xC0000, 0xCFFFD),
|
||||||
|
(0xD0000, 0xDFFFD ),
|
||||||
|
(0xE1000, 0xEFFFD),
|
||||||
|
(0xF0000, 0xFFFFD ),
|
||||||
|
(0x100000, 0x10FFFD)
|
||||||
|
]
|
||||||
|
|
||||||
|
def encode(c):
|
||||||
|
retval = c
|
||||||
|
i = ord(c)
|
||||||
|
for low, high in escape_range:
|
||||||
|
if i < low:
|
||||||
|
break
|
||||||
|
if i >= low and i <= high:
|
||||||
|
retval = "".join(["%%%2X" % ord(o) for o in c.encode('utf-8')])
|
||||||
|
break
|
||||||
|
return retval
|
||||||
|
|
||||||
|
|
||||||
|
def iri2uri(uri):
|
||||||
|
"""Convert an IRI to a URI. Note that IRIs must be
|
||||||
|
passed in a unicode strings. That is, do not utf-8 encode
|
||||||
|
the IRI before passing it into the function."""
|
||||||
|
if isinstance(uri ,unicode):
|
||||||
|
(scheme, authority, path, query, fragment) = urlparse.urlsplit(uri)
|
||||||
|
authority = authority.encode('idna')
|
||||||
|
# For each character in 'ucschar' or 'iprivate'
|
||||||
|
# 1. encode as utf-8
|
||||||
|
# 2. then %-encode each octet of that utf-8
|
||||||
|
uri = urlparse.urlunsplit((scheme, authority, path, query, fragment))
|
||||||
|
uri = "".join([encode(c) for c in uri])
|
||||||
|
return uri
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class Test(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_uris(self):
|
||||||
|
"""Test that URIs are invariant under the transformation."""
|
||||||
|
invariant = [
|
||||||
|
u"ftp://ftp.is.co.za/rfc/rfc1808.txt",
|
||||||
|
u"http://www.ietf.org/rfc/rfc2396.txt",
|
||||||
|
u"ldap://[2001:db8::7]/c=GB?objectClass?one",
|
||||||
|
u"mailto:John.Doe@example.com",
|
||||||
|
u"news:comp.infosystems.www.servers.unix",
|
||||||
|
u"tel:+1-816-555-1212",
|
||||||
|
u"telnet://192.0.2.16:80/",
|
||||||
|
u"urn:oasis:names:specification:docbook:dtd:xml:4.1.2" ]
|
||||||
|
for uri in invariant:
|
||||||
|
self.assertEqual(uri, iri2uri(uri))
|
||||||
|
|
||||||
|
def test_iri(self):
|
||||||
|
""" Test that the right type of escaping is done for each part of the URI."""
|
||||||
|
self.assertEqual("http://xn--o3h.com/%E2%98%84", iri2uri(u"http://\N{COMET}.com/\N{COMET}"))
|
||||||
|
self.assertEqual("http://bitworking.org/?fred=%E2%98%84", iri2uri(u"http://bitworking.org/?fred=\N{COMET}"))
|
||||||
|
self.assertEqual("http://bitworking.org/#%E2%98%84", iri2uri(u"http://bitworking.org/#\N{COMET}"))
|
||||||
|
self.assertEqual("#%E2%98%84", iri2uri(u"#\N{COMET}"))
|
||||||
|
self.assertEqual("/fred?bar=%E2%98%9A#%E2%98%84", iri2uri(u"/fred?bar=\N{BLACK LEFT POINTING INDEX}#\N{COMET}"))
|
||||||
|
self.assertEqual("/fred?bar=%E2%98%9A#%E2%98%84", iri2uri(iri2uri(u"/fred?bar=\N{BLACK LEFT POINTING INDEX}#\N{COMET}")))
|
||||||
|
self.assertNotEqual("/fred?bar=%E2%98%9A#%E2%98%84", iri2uri(u"/fred?bar=\N{BLACK LEFT POINTING INDEX}#\N{COMET}".encode('utf-8')))
|
||||||
|
|
||||||
|
unittest.main()
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user