<commit_before>#!/usr/bin/python
#
# NNTP protocol handling

import sys, os, re, codecs

import settings, group

logger = settings.get_logger('pnntprss.nntp')

# RFC977: commands with parameters must separate the parameters from
# each other and from the command by one or more space or tab
# characters.
separator_re = re.compile(r'\s+')

class NNTPServer:
    """An object representing the server side of an NNTP connection."""
    
    def __init__(self, input, output):
        self.finished = False
        self.current_group = None
        self.current_article_number = None
        
        # reopen input with universal line ending support
        self.input = os.fdopen(input.fileno(), "rU", 0)
        self.output = codecs.getwriter("utf-8")(output)

    def debug_in(self, l):
        logger.debug("< " + l)

    def debug_out(self, l):
        logger.debug("> " + l)

    def readlines(self):
        """A generator yielding the lines sent by the NNTP client."""
        # avoid using file as iterator, since it implies buffering
        while True:
            l = self.input.readline()
            if not l:
                break
            
            # remove trailing newline
            if l[-1] == '\n':
                l = l[0:-1]

            logger.debug("< " + l)
            yield l

    def writeline(self, l):
        """Write a line to the NNTP client."""
        self.debug_out(l)
        self.output.write(l)
        self.output.write('\r\n')
        self.output.flush()

    def write(self, data):
        """Write some data to the NNTP client."""
        lines = data.split("\r\n")
        for l in lines[:-1]:
            self.debug_out(l)

        if lines[-1]:
            self.debug_out(lines[-1])
            
        self.output.write(data)
        self.output.flush()

    def process_commands(self):
        """Process NNTP commands comming from the client, until it
        terminates the connection."""
        self.writeline('201 server ready - no posting allowed')
        
        for l in self.readlines():
            tokens = separator_re.split(l)
            if not tokens:
                self.writeline('501 command syntax error')
    
            m = getattr(self, 'do_' + tokens[0].upper(), None)
            if m:
                m(tokens[1:])
            else:
                self.writeline('500 command not recognized')

            if self.finished:
                break

    # each do_* method handles the corresponding NNTP command.

    def do_MODE(self, params):<commit_msg>Don't report ECONNRESET in the nntp server<commit_after>#!/usr/bin/python
#
# NNTP protocol handling

import sys, os, re, codecs, errno

import settings, group

logger = settings.get_logger('pnntprss.nntp')

# RFC977: commands with parameters must separate the parameters from
# each other and from the command by one or more space or tab
# characters.
separator_re = re.compile(r'\s+')

class NNTPServer:
    """An object representing the server side of an NNTP connection."""
    
    def __init__(self, input, output):
        self.finished = False
        self.current_group = None
        self.current_article_number = None
        
        # reopen input with universal line ending support
        self.input = os.fdopen(input.fileno(), "rU", 0)
        self.output = codecs.getwriter("utf-8")(output)

    def debug_in(self, l):
        logger.debug("< " + l)

    def debug_out(self, l):
        logger.debug("> " + l)

    def readlines(self):
        """A generator yielding the lines sent by the NNTP client."""
        # avoid using file as iterator, since it implies buffering
        while True:
            l = self.input.readline()
            if not l:
                break
            
            # remove trailing newline
            if l[-1] == '\n':
                l = l[0:-1]

            logger.debug("< " + l)
            yield l

    def writeline(self, l):
        """Write a line to the NNTP client."""
        self.debug_out(l)
        self.output.write(l)
        self.output.write('\r\n')
        self.output.flush()

    def write(self, data):
        """Write some data to the NNTP client."""
        lines = data.split("\r\n")
        for l in lines[:-1]:
            self.debug_out(l)

        if lines[-1]:
            self.debug_out(lines[-1])
            
        self.output.write(data)
        self.output.flush()

    def process_commands(self):
        """Process NNTP commands comming from the client, until it
        terminates the connection."""
        self.writeline('201 server ready - no posting allowed')

        try:
            for l in self.readlines():
                tokens = separator_re.split(l)
                if not tokens:
                    self.writeline('501 command syntax error')

                m = getattr(self, 'do_' + tokens[0].upper(), None)
                if m:
                    m(tokens[1:])
                else:
                    self.writeline('500 command not recognized')

                if self.finished:
                    break
        except IOError as e:
            # Swallow the exception when the connection is dropped
            # with outstanding data:
            if e.errno != errno.ECONNRESET:
                raise

    # each do_* method handles the corresponding NNTP command.

    def do_MODE(self, params):
{'fraction_non_alphanumeric': 0.10642270351008215, 'fraction_numerical': 0.008215085884988798, 'mean_word_length': 1.794470526864893, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1926579', 'n_tokens_mistral': 1555, 'n_tokens_neox': 1484, 'n_words': 468}