-
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
massive refactoring; all tests pass now on python 2.7.10
- Loading branch information
Showing
6 changed files
with
677 additions
and
694 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,7 +36,6 @@ | |
from lib.NNTPIOStream import NNTP_DEFAULT_ENCODING | ||
|
||
from lib.SocketBase import SocketBase | ||
from lib.SocketBase import ConnectionType | ||
from lib.SocketBase import SocketException | ||
from lib.SocketBase import SignalCaughtException | ||
from lib.Utils import mkdir | ||
|
@@ -88,7 +87,7 @@ | |
|
||
# Group Response (when we switch to a group) | ||
NNTP_GROUP_RESPONSE_RE = re.compile( | ||
r'(?P<count>[0-9]+)\s+(?P<low>[0-9]+)\s+' + \ | ||
r'(?P<count>[0-9]+)\s+(?P<low>[0-9]+)\s+' + | ||
r'(?P<high>[0-9]+)\s+(?P<name>.*[^\s]*[^.])(\.|\s)*$', | ||
) | ||
|
||
|
@@ -132,14 +131,15 @@ | |
# query fails | ||
NNTP_XOVER_RETRIES = 5 | ||
|
||
#RAW_TEXT_MESSAGE = re.compile( | ||
# r'^message-id:\s*<?([^>]+)>?\s*$', | ||
#) | ||
# RAW_TEXT_MESSAGE = re.compile( | ||
# r'^message-id:\s*<?([^>]+)>?\s*$', | ||
# ) | ||
|
||
# Used with BytesIO seek(). These variables | ||
# are part of python v2.7 but included here for python v2.6 | ||
# support too. | ||
|
||
|
||
class NNTPConnection(SocketBase): | ||
""" | ||
NNTPConnection is a class that wraps and eases the comunication | ||
|
@@ -229,10 +229,10 @@ def __init__(self, username=None, password=None, secure=False, | |
|
||
# get connection mode | ||
if secure: | ||
kwargs['mode'] = ConnectionType.SECURE_CONNECT | ||
kwargs['secure'] = True | ||
self.protocol = 'nntps' | ||
else: | ||
kwargs['mode'] = ConnectionType.CONNECT | ||
kwargs['secure'] = False | ||
self.protocol = 'nntp' | ||
|
||
# Default Filters | ||
|
@@ -274,24 +274,24 @@ def __init__(self, username=None, password=None, secure=False, | |
if self._iostream not in NNTP_SUPPORTED_IO_STREAMS: | ||
# Default | ||
self._iostream = NNTPIOStream.RFC3977_GZIP | ||
logger.warning('An unknown iostream was specified; ' + \ | ||
logger.warning('An unknown iostream was specified; ' + | ||
"using default: '%s'." % self._iostream) | ||
|
||
except (TypeError, ValueError): | ||
# Default | ||
self._iostream = NNTPIOStream.RFC3977_GZIP | ||
logger.warning('A malformed iostream was specified; ' + \ | ||
logger.warning('A malformed iostream was specified; ' + | ||
"using default: '%s'." % self._iostream) | ||
|
||
elif iostream: | ||
# Default | ||
logger.warning('An invalid iostream was specified; ' + \ | ||
logger.warning('An invalid iostream was specified; ' + | ||
"using default: '%s'." % self._iostream) | ||
self._iostream = NNTPIOStream.RFC3977_GZIP | ||
|
||
else: # iostream is None (0, or False) | ||
# used RFC3977 Standards but without Compresssion | ||
logger.info('An invalid iostream was specified; ' + \ | ||
logger.info('An invalid iostream was specified; ' + | ||
"using default: '%s'." % self._iostream) | ||
self._iostream = NNTPIOStream.RFC3977 | ||
|
||
|
@@ -369,14 +369,6 @@ def __init__(self, username=None, password=None, secure=False, | |
# Used to cache group list responses | ||
self._grouplist = None | ||
|
||
|
||
def __del__(self): | ||
""" | ||
Handle Deconstruction | ||
""" | ||
self.close() | ||
|
||
|
||
def append(self, connection, *args, **kwargs): | ||
""" | ||
Add a backup NNTP Server (Block Account) which is only | ||
|
@@ -390,7 +382,6 @@ def append(self, connection, *args, **kwargs): | |
self._backups.append(connection) | ||
return True | ||
|
||
|
||
def connect(self, *args, **kwargs): | ||
""" | ||
Establishes a connection to an NNTP Server | ||
|
@@ -405,7 +396,6 @@ def connect(self, *args, **kwargs): | |
# call _connect() | ||
return self._connect(*args, **kwargs) | ||
|
||
|
||
def _connect(self, *args, **kwargs): | ||
""" | ||
_connect() performs the actual connection with little | ||
|
@@ -476,7 +466,6 @@ def _connect(self, *args, **kwargs): | |
|
||
return True | ||
|
||
|
||
def post(self, payload): | ||
""" | ||
Allows posting content to a NNTP Server | ||
|
@@ -493,8 +482,7 @@ def post(self, payload): | |
return response | ||
|
||
# The server | ||
#header=('From: %s' % [email protected] | ||
|
||
# header=('From: %s' % [email protected] | ||
|
||
# STUB: TODO | ||
# payload should be a class that takes all the required | ||
|
@@ -504,7 +492,6 @@ def post(self, payload): | |
# contents and closing it afterwards. | ||
return NNTPResponse(239, 'Article transferred OK') | ||
|
||
|
||
def group(self, name): | ||
""" | ||
Changes to a specific group | ||
|
@@ -559,7 +546,6 @@ def group(self, name): | |
logger.warning('Bad Group: %s' % name) | ||
return (None, None, None, self.group_name) | ||
|
||
|
||
def groups(self, filters=None, lazy=True): | ||
""" | ||
Retrieves a list of groups from the server and returns them in an easy | ||
|
@@ -616,16 +602,16 @@ def groups(self, filters=None, lazy=True): | |
|
||
elif isinstance(filter, basestring): | ||
try: | ||
filter =r'^.*%s.*$' % re.escape(filter) | ||
_filters.append(re.compile( | ||
filter, flags=re.IGNORECASE), | ||
filter = r'^.*%s.*$' % re.escape(filter) | ||
_filters.append( | ||
re.compile(filter, flags=re.IGNORECASE), | ||
) | ||
logger.debug('Compiled group regex "%s"' % filter) | ||
|
||
except: | ||
logger.error( | ||
'Invalid group regular expression: "%s"' % filter, | ||
) | ||
'Invalid group regular expression: "%s"' % filter, | ||
) | ||
else: | ||
logger.error( | ||
'Ignored group expression: "%s"' % filter, | ||
|
@@ -674,14 +660,12 @@ def groups(self, filters=None, lazy=True): | |
)) | ||
return self._grouplist | ||
|
||
|
||
def tell(self): | ||
""" | ||
Returns the current index | ||
""" | ||
return self.group_index | ||
|
||
|
||
def seek_by_date(self, refdate, group=None): | ||
""" | ||
Similar to the seek() function in the sense it changes the | ||
|
@@ -740,7 +724,6 @@ def seek_by_date(self, refdate, group=None): | |
logger.info('Matched index: %d' % (self.group_index)) | ||
return self.group_index | ||
|
||
|
||
def _seek_by_date(self, refdate, head=None, tail=None): | ||
""" | ||
|
@@ -788,13 +771,13 @@ def _seek_by_date(self, refdate, head=None, tail=None): | |
if response is None: | ||
# Nothing Retrieved | ||
return -1 | ||
#if response.code != 423: | ||
# if response.code != 423: | ||
# # 423 means there were no more items to fetch | ||
# # this is a common error that even this class produces | ||
# # and therefore we do not need to create a verbose | ||
# # message from it. | ||
# logger.error('NNTP Server responded %s' % response) | ||
#return -1 | ||
# return -1 | ||
|
||
# Deal with our response | ||
if len(response): | ||
|
@@ -807,12 +790,12 @@ def _seek_by_date(self, refdate, head=None, tail=None): | |
# dict() | ||
_refkeys = response.keys() | ||
|
||
#logger.debug('total=%d, left=%s, right=%s, ref=%s' % ( | ||
# logger.debug('total=%d, left=%s, right=%s, ref=%s' % ( | ||
# end-start, | ||
# _refkeys[0], | ||
# _refkeys[-1], | ||
# _refdate, | ||
#)) | ||
# )) | ||
|
||
# | ||
# Decisions | ||
|
@@ -876,7 +859,6 @@ def _seek_by_date(self, refdate, head=None, tail=None): | |
# direction; we need to | ||
return -1 | ||
|
||
|
||
def seek(self, index, whence=None): | ||
""" | ||
Sets a default nntp index | ||
|
@@ -951,7 +933,8 @@ def prev(self, count=50000): | |
return response | ||
|
||
|
||
def xover(self, group=None, start=None, end=None, sort=XoverGrouping.BY_POSTER_TIME): | ||
def xover(self, group=None, start=None, end=None, | ||
sort=XoverGrouping.BY_POSTER_TIME): | ||
""" | ||
xover | ||
Returns a NNTPRequest object | ||
|
@@ -1678,12 +1661,15 @@ def _recv(self, decoders=None, timeout=None): | |
# when retrieving server-side listings; it's best to | ||
# just alert the end user and move along | ||
logger.warning( | ||
'_recv() %d byte(s) ZLIB decompression failure.' % ( | ||
bytes, | ||
)) | ||
'_recv() %d byte(s) ZLIB decompression failure.' \ | ||
% (bytes), | ||
) | ||
# Convert our response to that of an response Fetch | ||
# Error | ||
return NNTPResponse(NNTPResponseCode.FETCH_ERROR, 'Fetch Error') | ||
return NNTPResponse( | ||
NNTPResponseCode.FETCH_ERROR, | ||
'Fetch Error', | ||
) | ||
else: | ||
# No compression | ||
self._data.write(self._buffer.read(tail_ptr-head_ptr)) | ||
|
@@ -1848,7 +1834,7 @@ def close(self): | |
if self.connected: | ||
try: | ||
# Prevent Recursion by calling parent send() | ||
super(NNTPConnection, self).send('QUIT') | ||
super(NNTPConnection, self).send('QUIT' + EOL) | ||
except: | ||
pass | ||
|
||
|
@@ -1891,6 +1877,11 @@ def _hard_reset(self, wait=True): | |
self.close() | ||
self.connect() | ||
|
||
def __del__(self): | ||
""" | ||
Handle Deconstruction | ||
""" | ||
self.close() | ||
|
||
def __str__(self): | ||
return '%s://%s@%s:%d' % ( | ||
|
@@ -1901,7 +1892,6 @@ def __unicode__(self): | |
return u'%s://%s@%s:%d' % ( | ||
self.protocol, self.username, self.host, self.port) | ||
|
||
|
||
def __repr__(self): | ||
""" | ||
Return a printable object | ||
|
@@ -1913,4 +1903,3 @@ def __repr__(self): | |
self.host, | ||
self.port, | ||
) | ||
|
Oops, something went wrong.