Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Unified Diff: third_party/twisted_8_1/twisted/news/nntp.py

Issue 12261012: Remove third_party/twisted_8_1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/twisted_8_1/twisted/news/news.py ('k') | third_party/twisted_8_1/twisted/news/tap.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/twisted_8_1/twisted/news/nntp.py
diff --git a/third_party/twisted_8_1/twisted/news/nntp.py b/third_party/twisted_8_1/twisted/news/nntp.py
deleted file mode 100644
index 2e9861e5c7ca6c38786e7ba9336f8e1aff26a4c2..0000000000000000000000000000000000000000
--- a/third_party/twisted_8_1/twisted/news/nntp.py
+++ /dev/null
@@ -1,1069 +0,0 @@
-# -*- test-case-name: twisted.news.test.test_nntp -*-
-# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-NNTP protocol support.
-
-Maintainer: U{Jp Calderone<mailto:exarkun@twistedmatrix.com>}
-
-The following protocol commands are currently understood::
-
- LIST LISTGROUP XOVER XHDR
- POST GROUP ARTICLE STAT HEAD
- BODY NEXT MODE STREAM MODE READER SLAVE
- LAST QUIT HELP IHAVE XPATH
- XINDEX XROVER TAKETHIS CHECK
-
-The following protocol commands require implementation::
-
- NEWNEWS
- XGTITLE XPAT
- XTHREAD AUTHINFO NEWGROUPS
-
-
-Other desired features:
-
- - A real backend
- - More robust client input handling
- - A control protocol
-"""
-
-import time
-import types
-
-try:
- import cStringIO as StringIO
-except:
- import StringIO
-
-from twisted.protocols import basic
-from twisted.python import log
-
-def parseRange(text):
- articles = text.split('-')
- if len(articles) == 1:
- try:
- a = int(articles[0])
- return a, a
- except ValueError, e:
- return None, None
- elif len(articles) == 2:
- try:
- if len(articles[0]):
- l = int(articles[0])
- else:
- l = None
- if len(articles[1]):
- h = int(articles[1])
- else:
- h = None
- except ValueError, e:
- return None, None
- return l, h
-
-
-def extractCode(line):
- line = line.split(' ', 1)
- if len(line) != 2:
- return None
- try:
- return int(line[0]), line[1]
- except ValueError:
- return None
-
-
-class NNTPError(Exception):
- def __init__(self, string):
- self.string = string
-
- def __str__(self):
- return 'NNTPError: %s' % self.string
-
-
-class NNTPClient(basic.LineReceiver):
- MAX_COMMAND_LENGTH = 510
-
- def __init__(self):
- self.currentGroup = None
-
- self._state = []
- self._error = []
- self._inputBuffers = []
- self._responseCodes = []
- self._responseHandlers = []
-
- self._postText = []
-
- self._newState(self._statePassive, None, self._headerInitial)
-
-
- def gotAllGroups(self, groups):
- "Override for notification when fetchGroups() action is completed"
-
-
- def getAllGroupsFailed(self, error):
- "Override for notification when fetchGroups() action fails"
-
-
- def gotOverview(self, overview):
- "Override for notification when fetchOverview() action is completed"
-
-
- def getOverviewFailed(self, error):
- "Override for notification when fetchOverview() action fails"
-
-
- def gotSubscriptions(self, subscriptions):
- "Override for notification when fetchSubscriptions() action is completed"
-
-
- def getSubscriptionsFailed(self, error):
- "Override for notification when fetchSubscriptions() action fails"
-
-
- def gotGroup(self, group):
- "Override for notification when fetchGroup() action is completed"
-
-
- def getGroupFailed(self, error):
- "Override for notification when fetchGroup() action fails"
-
-
- def gotArticle(self, article):
- "Override for notification when fetchArticle() action is completed"
-
-
- def getArticleFailed(self, error):
- "Override for notification when fetchArticle() action fails"
-
-
- def gotHead(self, head):
- "Override for notification when fetchHead() action is completed"
-
-
- def getHeadFailed(self, error):
- "Override for notification when fetchHead() action fails"
-
-
- def gotBody(self, info):
- "Override for notification when fetchBody() action is completed"
-
-
- def getBodyFailed(self, body):
- "Override for notification when fetchBody() action fails"
-
-
- def postedOk(self):
- "Override for notification when postArticle() action is successful"
-
-
- def postFailed(self, error):
- "Override for notification when postArticle() action fails"
-
-
- def gotXHeader(self, headers):
- "Override for notification when getXHeader() action is successful"
-
-
- def getXHeaderFailed(self, error):
- "Override for notification when getXHeader() action fails"
-
-
- def gotNewNews(self, news):
- "Override for notification when getNewNews() action is successful"
-
-
- def getNewNewsFailed(self, error):
- "Override for notification when getNewNews() action fails"
-
-
- def gotNewGroups(self, groups):
- "Override for notification when getNewGroups() action is successful"
-
-
- def getNewGroupsFailed(self, error):
- "Override for notification when getNewGroups() action fails"
-
-
- def setStreamSuccess(self):
- "Override for notification when setStream() action is successful"
-
-
- def setStreamFailed(self, error):
- "Override for notification when setStream() action fails"
-
-
- def fetchGroups(self):
- """
- Request a list of all news groups from the server. gotAllGroups()
- is called on success, getGroupsFailed() on failure
- """
- self.sendLine('LIST')
- self._newState(self._stateList, self.getAllGroupsFailed)
-
-
- def fetchOverview(self):
- """
- Request the overview format from the server. gotOverview() is called
- on success, getOverviewFailed() on failure
- """
- self.sendLine('LIST OVERVIEW.FMT')
- self._newState(self._stateOverview, self.getOverviewFailed)
-
-
- def fetchSubscriptions(self):
- """
- Request a list of the groups it is recommended a new user subscribe to.
- gotSubscriptions() is called on success, getSubscriptionsFailed() on
- failure
- """
- self.sendLine('LIST SUBSCRIPTIONS')
- self._newState(self._stateSubscriptions, self.getSubscriptionsFailed)
-
-
- def fetchGroup(self, group):
- """
- Get group information for the specified group from the server. gotGroup()
- is called on success, getGroupFailed() on failure.
- """
- self.sendLine('GROUP %s' % (group,))
- self._newState(None, self.getGroupFailed, self._headerGroup)
-
-
- def fetchHead(self, index = ''):
- """
- Get the header for the specified article (or the currently selected
- article if index is '') from the server. gotHead() is called on
- success, getHeadFailed() on failure
- """
- self.sendLine('HEAD %s' % (index,))
- self._newState(self._stateHead, self.getHeadFailed)
-
-
- def fetchBody(self, index = ''):
- """
- Get the body for the specified article (or the currently selected
- article if index is '') from the server. gotBody() is called on
- success, getBodyFailed() on failure
- """
- self.sendLine('BODY %s' % (index,))
- self._newState(self._stateBody, self.getBodyFailed)
-
-
- def fetchArticle(self, index = ''):
- """
- Get the complete article with the specified index (or the currently
- selected article if index is '') or Message-ID from the server.
- gotArticle() is called on success, getArticleFailed() on failure.
- """
- self.sendLine('ARTICLE %s' % (index,))
- self._newState(self._stateArticle, self.getArticleFailed)
-
-
- def postArticle(self, text):
- """
- Attempt to post an article with the specified text to the server. 'text'
- must consist of both head and body data, as specified by RFC 850. If the
- article is posted successfully, postedOk() is called, otherwise postFailed()
- is called.
- """
- self.sendLine('POST')
- self._newState(None, self.postFailed, self._headerPost)
- self._postText.append(text)
-
-
- def fetchNewNews(self, groups, date, distributions = ''):
- """
- Get the Message-IDs for all new news posted to any of the given
- groups since the specified date - in seconds since the epoch, GMT -
- optionally restricted to the given distributions. gotNewNews() is
- called on success, getNewNewsFailed() on failure.
-
- One invocation of this function may result in multiple invocations
- of gotNewNews()/getNewNewsFailed().
- """
- date, timeStr = time.strftime('%y%m%d %H%M%S', time.gmtime(date)).split()
- line = 'NEWNEWS %%s %s %s %s' % (date, timeStr, distributions)
- groupPart = ''
- while len(groups) and len(line) + len(groupPart) + len(groups[-1]) + 1 < NNTPClient.MAX_COMMAND_LENGTH:
- group = groups.pop()
- groupPart = groupPart + ',' + group
-
- self.sendLine(line % (groupPart,))
- self._newState(self._stateNewNews, self.getNewNewsFailed)
-
- if len(groups):
- self.fetchNewNews(groups, date, distributions)
-
-
- def fetchNewGroups(self, date, distributions):
- """
- Get the names of all new groups created/added to the server since
- the specified date - in seconds since the ecpoh, GMT - optionally
- restricted to the given distributions. gotNewGroups() is called
- on success, getNewGroupsFailed() on failure.
- """
- date, timeStr = time.strftime('%y%m%d %H%M%S', time.gmtime(date)).split()
- self.sendLine('NEWGROUPS %s %s %s' % (date, timeStr, distributions))
- self._newState(self._stateNewGroups, self.getNewGroupsFailed)
-
-
- def fetchXHeader(self, header, low = None, high = None, id = None):
- """
- Request a specific header from the server for an article or range
- of articles. If 'id' is not None, a header for only the article
- with that Message-ID will be requested. If both low and high are
- None, a header for the currently selected article will be selected;
- If both low and high are zero-length strings, headers for all articles
- in the currently selected group will be requested; Otherwise, high
- and low will be used as bounds - if one is None the first or last
- article index will be substituted, as appropriate.
- """
- if id is not None:
- r = header + ' <%s>' % (id,)
- elif low is high is None:
- r = header
- elif high is None:
- r = header + ' %d-' % (low,)
- elif low is None:
- r = header + ' -%d' % (high,)
- else:
- r = header + ' %d-%d' % (low, high)
- self.sendLine('XHDR ' + r)
- self._newState(self._stateXHDR, self.getXHeaderFailed)
-
-
- def setStream(self):
- """
- Set the mode to STREAM, suspending the normal "lock-step" mode of
- communications. setStreamSuccess() is called on success,
- setStreamFailed() on failure.
- """
- self.sendLine('MODE STREAM')
- self._newState(None, self.setStreamFailed, self._headerMode)
-
-
- def quit(self):
- self.sendLine('QUIT')
- self.transport.loseConnection()
-
-
- def _newState(self, method, error, responseHandler = None):
- self._inputBuffers.append([])
- self._responseCodes.append(None)
- self._state.append(method)
- self._error.append(error)
- self._responseHandlers.append(responseHandler)
-
-
- def _endState(self):
- buf = self._inputBuffers[0]
- del self._responseCodes[0]
- del self._inputBuffers[0]
- del self._state[0]
- del self._error[0]
- del self._responseHandlers[0]
- return buf
-
-
- def _newLine(self, line, check = 1):
- if check and line and line[0] == '.':
- line = line[1:]
- self._inputBuffers[0].append(line)
-
-
- def _setResponseCode(self, code):
- self._responseCodes[0] = code
-
-
- def _getResponseCode(self):
- return self._responseCodes[0]
-
-
- def lineReceived(self, line):
- if not len(self._state):
- self._statePassive(line)
- elif self._getResponseCode() is None:
- code = extractCode(line)
- if code is None or not (200 <= code[0] < 400): # An error!
- self._error[0](line)
- self._endState()
- else:
- self._setResponseCode(code)
- if self._responseHandlers[0]:
- self._responseHandlers[0](code)
- else:
- self._state[0](line)
-
-
- def _statePassive(self, line):
- log.msg('Server said: %s' % line)
-
-
- def _passiveError(self, error):
- log.err('Passive Error: %s' % (error,))
-
-
- def _headerInitial(self, (code, message)):
- if code == 200:
- self.canPost = 1
- else:
- self.canPost = 0
- self._endState()
-
-
- def _stateList(self, line):
- if line != '.':
- data = filter(None, line.strip().split())
- self._newLine((data[0], int(data[1]), int(data[2]), data[3]), 0)
- else:
- self.gotAllGroups(self._endState())
-
-
- def _stateOverview(self, line):
- if line != '.':
- self._newLine(filter(None, line.strip().split()), 0)
- else:
- self.gotOverview(self._endState())
-
-
- def _stateSubscriptions(self, line):
- if line != '.':
- self._newLine(line.strip(), 0)
- else:
- self.gotSubscriptions(self._endState())
-
-
- def _headerGroup(self, (code, line)):
- self.gotGroup(tuple(line.split()))
- self._endState()
-
-
- def _stateArticle(self, line):
- if line != '.':
- if line.startswith('.'):
- line = line[1:]
- self._newLine(line, 0)
- else:
- self.gotArticle('\n'.join(self._endState())+'\n')
-
-
- def _stateHead(self, line):
- if line != '.':
- self._newLine(line, 0)
- else:
- self.gotHead('\n'.join(self._endState()))
-
-
- def _stateBody(self, line):
- if line != '.':
- if line.startswith('.'):
- line = line[1:]
- self._newLine(line, 0)
- else:
- self.gotBody('\n'.join(self._endState())+'\n')
-
-
- def _headerPost(self, (code, message)):
- if code == 340:
- self.transport.write(self._postText[0].replace('\n', '\r\n').replace('\r\n.', '\r\n..'))
- if self._postText[0][-1:] != '\n':
- self.sendLine('')
- self.sendLine('.')
- del self._postText[0]
- self._newState(None, self.postFailed, self._headerPosted)
- else:
- self.postFailed('%d %s' % (code, message))
- self._endState()
-
-
- def _headerPosted(self, (code, message)):
- if code == 240:
- self.postedOk()
- else:
- self.postFailed('%d %s' % (code, message))
- self._endState()
-
-
- def _stateXHDR(self, line):
- if line != '.':
- self._newLine(line.split(), 0)
- else:
- self._gotXHeader(self._endState())
-
-
- def _stateNewNews(self, line):
- if line != '.':
- self._newLine(line, 0)
- else:
- self.gotNewNews(self._endState())
-
-
- def _stateNewGroups(self, line):
- if line != '.':
- self._newLine(line, 0)
- else:
- self.gotNewGroups(self._endState())
-
-
- def _headerMode(self, (code, message)):
- if code == 203:
- self.setStreamSuccess()
- else:
- self.setStreamFailed((code, message))
- self._endState()
-
-
-class NNTPServer(basic.LineReceiver):
- COMMANDS = [
- 'LIST', 'GROUP', 'ARTICLE', 'STAT', 'MODE', 'LISTGROUP', 'XOVER',
- 'XHDR', 'HEAD', 'BODY', 'NEXT', 'LAST', 'POST', 'QUIT', 'IHAVE',
- 'HELP', 'SLAVE', 'XPATH', 'XINDEX', 'XROVER', 'TAKETHIS', 'CHECK'
- ]
-
- def __init__(self):
- self.servingSlave = 0
-
-
- def connectionMade(self):
- self.inputHandler = None
- self.currentGroup = None
- self.currentIndex = None
- self.sendLine('200 server ready - posting allowed')
-
- def lineReceived(self, line):
- if self.inputHandler is not None:
- self.inputHandler(line)
- else:
- parts = line.strip().split()
- if len(parts):
- cmd, parts = parts[0].upper(), parts[1:]
- if cmd in NNTPServer.COMMANDS:
- func = getattr(self, 'do_%s' % cmd)
- try:
- func(*parts)
- except TypeError:
- self.sendLine('501 command syntax error')
- log.msg("501 command syntax error")
- log.msg("command was", line)
- log.deferr()
- except:
- self.sendLine('503 program fault - command not performed')
- log.msg("503 program fault")
- log.msg("command was", line)
- log.deferr()
- else:
- self.sendLine('500 command not recognized')
-
-
- def do_LIST(self, subcmd = '', *dummy):
- subcmd = subcmd.strip().lower()
- if subcmd == 'newsgroups':
- # XXX - this could use a real implementation, eh?
- self.sendLine('215 Descriptions in form "group description"')
- self.sendLine('.')
- elif subcmd == 'overview.fmt':
- defer = self.factory.backend.overviewRequest()
- defer.addCallbacks(self._gotOverview, self._errOverview)
- log.msg('overview')
- elif subcmd == 'subscriptions':
- defer = self.factory.backend.subscriptionRequest()
- defer.addCallbacks(self._gotSubscription, self._errSubscription)
- log.msg('subscriptions')
- elif subcmd == '':
- defer = self.factory.backend.listRequest()
- defer.addCallbacks(self._gotList, self._errList)
- else:
- self.sendLine('500 command not recognized')
-
-
- def _gotList(self, list):
- self.sendLine('215 newsgroups in form "group high low flags"')
- for i in list:
- self.sendLine('%s %d %d %s' % tuple(i))
- self.sendLine('.')
-
-
- def _errList(self, failure):
- print 'LIST failed: ', failure
- self.sendLine('503 program fault - command not performed')
-
-
- def _gotSubscription(self, parts):
- self.sendLine('215 information follows')
- for i in parts:
- self.sendLine(i)
- self.sendLine('.')
-
-
- def _errSubscription(self, failure):
- print 'SUBSCRIPTIONS failed: ', failure
- self.sendLine('503 program fault - comand not performed')
-
-
- def _gotOverview(self, parts):
- self.sendLine('215 Order of fields in overview database.')
- for i in parts:
- self.sendLine(i + ':')
- self.sendLine('.')
-
-
- def _errOverview(self, failure):
- print 'LIST OVERVIEW.FMT failed: ', failure
- self.sendLine('503 program fault - command not performed')
-
-
- def do_LISTGROUP(self, group = None):
- group = group or self.currentGroup
- if group is None:
- self.sendLine('412 Not currently in newsgroup')
- else:
- defer = self.factory.backend.listGroupRequest(group)
- defer.addCallbacks(self._gotListGroup, self._errListGroup)
-
-
- def _gotListGroup(self, (group, articles)):
- self.currentGroup = group
- if len(articles):
- self.currentIndex = int(articles[0])
- else:
- self.currentIndex = None
-
- self.sendLine('211 list of article numbers follow')
- for i in articles:
- self.sendLine(str(i))
- self.sendLine('.')
-
-
- def _errListGroup(self, failure):
- print 'LISTGROUP failed: ', failure
- self.sendLine('502 no permission')
-
-
- def do_XOVER(self, range):
- if self.currentGroup is None:
- self.sendLine('412 No news group currently selected')
- else:
- l, h = parseRange(range)
- defer = self.factory.backend.xoverRequest(self.currentGroup, l, h)
- defer.addCallbacks(self._gotXOver, self._errXOver)
-
-
- def _gotXOver(self, parts):
- self.sendLine('224 Overview information follows')
- for i in parts:
- self.sendLine('\t'.join(map(str, i)))
- self.sendLine('.')
-
-
- def _errXOver(self, failure):
- print 'XOVER failed: ', failure
- self.sendLine('420 No article(s) selected')
-
-
- def xhdrWork(self, header, range):
- if self.currentGroup is None:
- self.sendLine('412 No news group currently selected')
- else:
- if range is None:
- if self.currentIndex is None:
- self.sendLine('420 No current article selected')
- return
- else:
- l = h = self.currentIndex
- else:
- # FIXME: articles may be a message-id
- l, h = parseRange(range)
-
- if l is h is None:
- self.sendLine('430 no such article')
- else:
- return self.factory.backend.xhdrRequest(self.currentGroup, l, h, header)
-
-
- def do_XHDR(self, header, range = None):
- d = self.xhdrWork(header, range)
- if d:
- d.addCallbacks(self._gotXHDR, self._errXHDR)
-
-
- def _gotXHDR(self, parts):
- self.sendLine('221 Header follows')
- for i in parts:
- self.sendLine('%d %s' % i)
- self.sendLine('.')
-
- def _errXHDR(self, failure):
- print 'XHDR failed: ', failure
- self.sendLine('502 no permission')
-
-
- def do_XROVER(self, header, range = None):
- d = self.xhdrWork(header, range)
- if d:
- d.addCallbacks(self._gotXROVER, self._errXROVER)
-
-
- def _gotXROVER(self, parts):
- self.sendLine('224 Overview information follows')
- for i in parts:
- self.sendLine('%d %s' % i)
- self.sendLine('.')
-
-
- def _errXROVER(self, failure):
- print 'XROVER failed: ',
- self._errXHDR(failure)
-
-
- def do_POST(self):
- self.inputHandler = self._doingPost
- self.message = ''
- self.sendLine('340 send article to be posted. End with <CR-LF>.<CR-LF>')
-
-
- def _doingPost(self, line):
- if line == '.':
- self.inputHandler = None
- group, article = self.currentGroup, self.message
- self.message = ''
-
- defer = self.factory.backend.postRequest(article)
- defer.addCallbacks(self._gotPost, self._errPost)
- else:
- self.message = self.message + line + '\r\n'
-
-
- def _gotPost(self, parts):
- self.sendLine('240 article posted ok')
-
-
- def _errPost(self, failure):
- print 'POST failed: ', failure
- self.sendLine('441 posting failed')
-
-
- def do_CHECK(self, id):
- d = self.factory.backend.articleExistsRequest(id)
- d.addCallbacks(self._gotCheck, self._errCheck)
-
-
- def _gotCheck(self, result):
- if result:
- self.sendLine("438 already have it, please don't send it to me")
- else:
- self.sendLine('238 no such article found, please send it to me')
-
-
- def _errCheck(self, failure):
- print 'CHECK failed: ', failure
- self.sendLine('431 try sending it again later')
-
-
- def do_TAKETHIS(self, id):
- self.inputHandler = self._doingTakeThis
- self.message = ''
-
-
- def _doingTakeThis(self, line):
- if line == '.':
- self.inputHandler = None
- article = self.message
- self.message = ''
- d = self.factory.backend.postRequest(article)
- d.addCallbacks(self._didTakeThis, self._errTakeThis)
- else:
- self.message = self.message + line + '\r\n'
-
-
- def _didTakeThis(self, result):
- self.sendLine('239 article transferred ok')
-
-
- def _errTakeThis(self, failure):
- print 'TAKETHIS failed: ', failure
- self.sendLine('439 article transfer failed')
-
-
- def do_GROUP(self, group):
- defer = self.factory.backend.groupRequest(group)
- defer.addCallbacks(self._gotGroup, self._errGroup)
-
-
- def _gotGroup(self, (name, num, high, low, flags)):
- self.currentGroup = name
- self.currentIndex = low
- self.sendLine('211 %d %d %d %s group selected' % (num, low, high, name))
-
-
- def _errGroup(self, failure):
- print 'GROUP failed: ', failure
- self.sendLine('411 no such group')
-
-
- def articleWork(self, article, cmd, func):
- if self.currentGroup is None:
- self.sendLine('412 no newsgroup has been selected')
- else:
- if not article:
- if self.currentIndex is None:
- self.sendLine('420 no current article has been selected')
- else:
- article = self.currentIndex
- else:
- if article[0] == '<':
- return func(self.currentGroup, index = None, id = article)
- else:
- try:
- article = int(article)
- return func(self.currentGroup, article)
- except ValueError, e:
- self.sendLine('501 command syntax error')
-
-
- def do_ARTICLE(self, article = None):
- defer = self.articleWork(article, 'ARTICLE', self.factory.backend.articleRequest)
- if defer:
- defer.addCallbacks(self._gotArticle, self._errArticle)
-
-
- def _gotArticle(self, (index, id, article)):
- if isinstance(article, types.StringType):
- import warnings
- warnings.warn(
- "Returning the article as a string from `articleRequest' "
- "is deprecated. Return a file-like object instead."
- )
- article = StringIO.StringIO(article)
- self.currentIndex = index
- self.sendLine('220 %d %s article' % (index, id))
- s = basic.FileSender()
- d = s.beginFileTransfer(article, self.transport)
- d.addCallback(self.finishedFileTransfer)
-
- ##
- ## Helper for FileSender
- ##
- def finishedFileTransfer(self, lastsent):
- if lastsent != '\n':
- line = '\r\n.'
- else:
- line = '.'
- self.sendLine(line)
- ##
-
- def _errArticle(self, failure):
- print 'ARTICLE failed: ', failure
- self.sendLine('423 bad article number')
-
-
- def do_STAT(self, article = None):
- defer = self.articleWork(article, 'STAT', self.factory.backend.articleRequest)
- if defer:
- defer.addCallbacks(self._gotStat, self._errStat)
-
-
- def _gotStat(self, (index, id, article)):
- self.currentIndex = index
- self.sendLine('223 %d %s article retreived - request text separately' % (index, id))
-
-
- def _errStat(self, failure):
- print 'STAT failed: ', failure
- self.sendLine('423 bad article number')
-
-
- def do_HEAD(self, article = None):
- defer = self.articleWork(article, 'HEAD', self.factory.backend.headRequest)
- if defer:
- defer.addCallbacks(self._gotHead, self._errHead)
-
-
- def _gotHead(self, (index, id, head)):
- self.currentIndex = index
- self.sendLine('221 %d %s article retrieved' % (index, id))
- self.transport.write(head + '\r\n')
- self.sendLine('.')
-
-
- def _errHead(self, failure):
- print 'HEAD failed: ', failure
- self.sendLine('423 no such article number in this group')
-
-
- def do_BODY(self, article):
- defer = self.articleWork(article, 'BODY', self.factory.backend.bodyRequest)
- if defer:
- defer.addCallbacks(self._gotBody, self._errBody)
-
-
- def _gotBody(self, (index, id, body)):
- if isinstance(body, types.StringType):
- import warnings
- warnings.warn(
- "Returning the article as a string from `articleRequest' "
- "is deprecated. Return a file-like object instead."
- )
- body = StringIO.StringIO(body)
- self.currentIndex = index
- self.sendLine('221 %d %s article retrieved' % (index, id))
- self.lastsent = ''
- s = basic.FileSender()
- d = s.beginFileTransfer(body, self.transport)
- d.addCallback(self.finishedFileTransfer)
-
- def _errBody(self, failure):
- print 'BODY failed: ', failure
- self.sendLine('423 no such article number in this group')
-
-
- # NEXT and LAST are just STATs that increment currentIndex first.
- # Accordingly, use the STAT callbacks.
- def do_NEXT(self):
- i = self.currentIndex + 1
- defer = self.factory.backend.articleRequest(self.currentGroup, i)
- defer.addCallbacks(self._gotStat, self._errStat)
-
-
- def do_LAST(self):
- i = self.currentIndex - 1
- defer = self.factory.backend.articleRequest(self.currentGroup, i)
- defer.addCallbacks(self._gotStat, self._errStat)
-
-
- def do_MODE(self, cmd):
- cmd = cmd.strip().upper()
- if cmd == 'READER':
- self.servingSlave = 0
- self.sendLine('200 Hello, you can post')
- elif cmd == 'STREAM':
- self.sendLine('500 Command not understood')
- else:
- # This is not a mistake
- self.sendLine('500 Command not understood')
-
-
- def do_QUIT(self):
- self.sendLine('205 goodbye')
- self.transport.loseConnection()
-
-
- def do_HELP(self):
- self.sendLine('100 help text follows')
- self.sendLine('Read the RFC.')
- self.sendLine('.')
-
-
- def do_SLAVE(self):
- self.sendLine('202 slave status noted')
- self.servingeSlave = 1
-
-
- def do_XPATH(self, article):
- # XPATH is a silly thing to have. No client has the right to ask
- # for this piece of information from me, and so that is what I'll
- # tell them.
- self.sendLine('502 access restriction or permission denied')
-
-
- def do_XINDEX(self, article):
- # XINDEX is another silly command. The RFC suggests it be relegated
- # to the history books, and who am I to disagree?
- self.sendLine('502 access restriction or permission denied')
-
-
- def do_XROVER(self, range = None):
- self.do_XHDR(self, 'References', range)
-
-
- def do_IHAVE(self, id):
- self.factory.backend.articleExistsRequest(id).addCallback(self._foundArticle)
-
-
- def _foundArticle(self, result):
- if result:
- self.sendLine('437 article rejected - do not try again')
- else:
- self.sendLine('335 send article to be transferred. End with <CR-LF>.<CR-LF>')
- self.inputHandler = self._handleIHAVE
- self.message = ''
-
-
- def _handleIHAVE(self, line):
- if line == '.':
- self.inputHandler = None
- self.factory.backend.postRequest(
- self.message
- ).addCallbacks(self._gotIHAVE, self._errIHAVE)
-
- self.message = ''
- else:
- self.message = self.message + line + '\r\n'
-
-
- def _gotIHAVE(self, result):
- self.sendLine('235 article transferred ok')
-
-
- def _errIHAVE(self, failure):
- print 'IHAVE failed: ', failure
- self.sendLine('436 transfer failed - try again later')
-
-
-class UsenetClientProtocol(NNTPClient):
- """
- A client that connects to an NNTP server and asks for articles new
- since a certain time.
- """
-
- def __init__(self, groups, date, storage):
- """
- Fetch all new articles from the given groups since the
- given date and dump them into the given storage. groups
- is a list of group names. date is an integer or floating
- point representing seconds since the epoch (GMT). storage is
- any object that implements the NewsStorage interface.
- """
- NNTPClient.__init__(self)
- self.groups, self.date, self.storage = groups, date, storage
-
-
- def connectionMade(self):
- NNTPClient.connectionMade(self)
- log.msg("Initiating update with remote host: " + str(self.transport.getPeer()))
- self.setStream()
- self.fetchNewNews(self.groups, self.date, '')
-
-
- def articleExists(self, exists, article):
- if exists:
- self.fetchArticle(article)
- else:
- self.count = self.count - 1
- self.disregard = self.disregard + 1
-
-
- def gotNewNews(self, news):
- self.disregard = 0
- self.count = len(news)
- log.msg("Transfering " + str(self.count) + " articles from remote host: " + str(self.transport.getPeer()))
- for i in news:
- self.storage.articleExistsRequest(i).addCallback(self.articleExists, i)
-
-
- def getNewNewsFailed(self, reason):
- log.msg("Updated failed (" + reason + ") with remote host: " + str(self.transport.getPeer()))
- self.quit()
-
-
- def gotArticle(self, article):
- self.storage.postRequest(article)
- self.count = self.count - 1
- if not self.count:
- log.msg("Completed update with remote host: " + str(self.transport.getPeer()))
- if self.disregard:
- log.msg("Disregarded %d articles." % (self.disregard,))
- self.factory.updateChecks(self.transport.getPeer())
- self.quit()
« no previous file with comments | « third_party/twisted_8_1/twisted/news/news.py ('k') | third_party/twisted_8_1/twisted/news/tap.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698