Beispiel #1
0
 def setUp(self):
     self.config = testutil.get_config()
     self.vfs = VFS_Real(self.config)
     self.selector = "/testfile.html"
     self.protocol = testutil.get_testing_protocol(self.selector,
                                                   config=self.config)
     self.stat_result = self.vfs.stat(self.selector)
Beispiel #2
0
    def setUp(self):
        self.config = testutil.get_config()
        self.vfs = VFS_Real(self.config)
        self.selector = "/testdata.zip"
        self.protocol = testutil.get_testing_protocol(self.selector,
                                                      config=self.config)
        self.stat_result = self.vfs.stat(self.selector)

        self.config.set("handlers.ZIP.ZIPHandler", "enabled", "true")
Beispiel #3
0
    def setUp(self):
        self.config = testutil.get_config()
        self.vfs = VFS_Real(self.config)
        self.selector = "/testfile.txt.gz"
        self.protocol = testutil.get_testing_protocol(self.selector, config=self.config)
        self.stat_result = self.vfs.stat(self.selector)

        self.config.set(
            "handlers.file.CompressedFileHandler", "decompressors", "{'gzip' : 'zcat'}"
        )
Beispiel #4
0
    def setUp(self):
        self.config = testutil.get_config()
        self.vfs = VFS_Real(self.config)
        self.selector = "/talsample.html.tal"
        self.protocol = testutil.get_testing_protocol(self.selector,
                                                      config=self.config)
        self.stat_result = self.vfs.stat(self.selector)

        # Initialize the custom mimetypes encoding map
        initialization.init_logger(self.config, "")
        initialization.init_mimetypes(self.config)
Beispiel #5
0
    def setUp(self):
        self.config = testutil.get_config()
        self.vfs = VFS_Real(self.config)
        self.selector = "/"
        self.protocol = testutil.get_testing_protocol(self.selector,
                                                      config=self.config)
        self.stat_result = self.vfs.stat(self.selector)

        # Make sure there's no directory cache file from a previous test run
        cachefile = self.config.get("handlers.dir.DirHandler", "cachefile")
        try:
            os.remove(self.vfs.getfspath(self.selector) + "/" + cachefile)
        except OSError:
            pass
Beispiel #6
0
class TestCompressedFileHandler(unittest.TestCase):
    def setUp(self):
        self.config = testutil.get_config()
        self.vfs = VFS_Real(self.config)
        self.selector = "/testfile.txt.gz"
        self.protocol = testutil.get_testing_protocol(self.selector, config=self.config)
        self.stat_result = self.vfs.stat(self.selector)

        self.config.set(
            "handlers.file.CompressedFileHandler", "decompressors", "{'gzip' : 'zcat'}"
        )

    def test_compressed_file_handler(self):
        handler = CompressedFileHandler(
            self.selector, "", self.protocol, self.config, self.stat_result, self.vfs
        )

        self.assertTrue(handler.canhandlerequest())
        self.assertFalse(handler.isdir())

        entry = handler.getentry()
        self.assertEqual(entry.mimetype, "text/plain")
        self.assertEqual(entry.type, "0")

        with tempfile.TemporaryFile("rb") as wfile:
            handler.write(wfile)
            wfile.seek(0)
            data = wfile.read()

        self.assertEqual(data, b"Test\n")
Beispiel #7
0
 def setUp(self):
     self.config = testutil.get_config()
     self.vfs = VFS_Real(self.config)
     self.selector = "URL:http://gopher.quux.org/"
     self.protocol = testutil.get_testing_protocol(self.selector,
                                                   config=self.config)
     self.stat_result = None
Beispiel #8
0
 def setUp(self):
     self.config = testutil.get_config()
     self.vfs = VFS_Real(self.config)
     self.selector = "/0/README"
     self.protocol = testutil.get_testing_protocol(self.selector,
                                                   config=self.config)
     self.stat_result = None
Beispiel #9
0
 def setUp(self):
     self.config = configparser.ConfigParser()
     self.config.add_section("pygopherd")
     self.config.set("pygopherd", "root", os.path.abspath("testdata"))
     self.real = VFS_Real(self.config)
     self.z = VFSZip(self.config, self.real, "/testdata.zip")
     self.z2 = VFSZip(self.config, self.real, "/testdata2.zip")
     self.zs = VFSZip(self.config, self.real, "/symlinktest.zip")
Beispiel #10
0
 def setUp(self):
     self.config = testutil.get_config()
     self.vfs = VFS_Real(self.config)
     # The "hello" will be sent as an additional script argument. Multiple
     # query arguments can be provided using " " as the separator.
     self.selector = "/pygopherd/cgitest.sh?hello"
     self.protocol = testutil.get_testing_protocol(self.selector,
                                                   config=self.config)
     self.stat_result = None
Beispiel #11
0
    def handleeaext(self, selector, vfs):
        """Handle getting extended attributes from the filesystem."""
        global eaexts
        if eaexts == None:
            eaexts = eval(self.config.get("GopherEntry", "eaexts"))
        if vfs == None:
            from pygopherd.handlers.base import VFS_Real
            vfs = VFS_Real(self.config)

        for extension, blockname in eaexts.items():
            if self.ea.has_key(blockname):
                continue
            try:
                rfile = vfs.open(selector + extension, "rt")
                self.setea(blockname, "\n".join(
                           [x.rstrip() for x in rfile.readlines(20480)]))
            except IOError:
                pass
Beispiel #12
0
class TestDirHandler(unittest.TestCase):
    def setUp(self):
        self.config = testutil.get_config()
        self.vfs = VFS_Real(self.config)
        self.selector = "/"
        self.protocol = testutil.get_testing_protocol(self.selector,
                                                      config=self.config)
        self.stat_result = self.vfs.stat(self.selector)

        # Make sure there's no directory cache file from a previous test run
        cachefile = self.config.get("handlers.dir.DirHandler", "cachefile")
        try:
            os.remove(self.vfs.getfspath(self.selector) + "/" + cachefile)
        except OSError:
            pass

    def test_dir_handler(self):
        handler = DirHandler(self.selector, "", self.protocol, self.config,
                             self.stat_result, self.vfs)

        self.assertTrue(handler.canhandlerequest())
        self.assertTrue(handler.isdir())

        handler.prepare()
        self.assertFalse(handler.fromcache)

        entry = handler.getentry()
        self.assertEqual(entry.mimetype, "application/gopher-menu")
        self.assertEqual(entry.type, "1")

        entries = handler.getdirlist()
        self.assertTrue(entries)

        # Create a second handler to test that it will load from the cached
        # file that the first handler should have created
        handler = DirHandler(self.selector, "", self.protocol, self.config,
                             self.stat_result, self.vfs)

        handler.prepare()
        self.assertTrue(handler.fromcache)

        cached_entries = handler.getdirlist()
        for a, b in zip(entries, cached_entries):
            self.assertEqual(a.selector, b.selector)
Beispiel #13
0
    def handleeaext(self, selector, vfs):
        """Handle getting extended attributes from the filesystem."""
        global eaexts
        if eaexts == None:
            eaexts = eval(self.config.get("GopherEntry", "eaexts"))
        if vfs == None:
            from pygopherd.handlers.base import VFS_Real
            vfs = VFS_Real(self.config)

        for extension, blockname in eaexts.items():
            if self.ea.has_key(blockname):
                continue
            try:
                rfile = vfs.open(selector + extension, "rt")
                self.setea(
                    blockname,
                    "\n".join([x.rstrip() for x in rfile.readlines(20480)]))
            except IOError:
                pass
Beispiel #14
0
def getHandler(selector,
               searchrequest,
               protocol,
               config,
               handlerlist=None,
               vfs=None):
    """Called without handlerlist specified, uses the default as listed
    in config."""
    global handlers, rootpath

    if vfs == None:
        from pygopherd.handlers.base import VFS_Real
        vfs = VFS_Real(config)

    if not handlers:
        handlers = eval(config.get("handlers.HandlerMultiplexer", "handlers"))
        rootpath = config.get("pygopherd", "root")
    if handlerlist == None:
        handlerlist = handlers

    # TODO: assert that our absolute path is within the absolute
    # path of the site root.

    #if not os.path.abspath(rootpath + '/' + selector). \
    #   startswith(os.path.abspath(rootpath)):
    #    raise GopherExceptions.FileNotFound, \
    #          [selector, "Requested document is outside the server root",
    #           protocol]

    statresult = None
    try:
        statresult = vfs.stat(selector)
    except OSError:
        pass
    for handler in handlerlist:
        htry = handler(selector, searchrequest, protocol, config, statresult,
                       vfs)
        if htry.isrequestforme():
            return htry.gethandler()

    raise GopherExceptions.FileNotFound(
        [selector, "no handler found", protocol])
Beispiel #15
0
class TestUMNDirHandler(unittest.TestCase):
    def setUp(self):
        self.config = testutil.get_config()
        self.vfs = VFS_Real(self.config)
        self.selector = "/"
        self.protocol = testutil.get_testing_protocol(self.selector,
                                                      config=self.config)
        self.stat_result = self.vfs.stat(self.selector)

        # Make sure there's no directory cache file from a previous test run
        cachefile = self.config.get("handlers.dir.DirHandler", "cachefile")
        try:
            os.remove(self.vfs.getfspath(self.selector) + "/" + cachefile)
        except OSError:
            pass

    def test_dir_handler(self):
        handler = UMNDirHandler(self.selector, "", self.protocol, self.config,
                                self.stat_result, self.vfs)

        self.assertTrue(handler.canhandlerequest())
        self.assertTrue(handler.isdir())

        handler.prepare()
        self.assertFalse(handler.fromcache)

        entry = handler.getentry()
        self.assertEqual(entry.mimetype, "application/gopher-menu")
        self.assertEqual(entry.type, "1")

        entries = handler.getdirlist()
        self.assertTrue(entries)

        # First entry should be the special link file
        self.assertEqual(entries[0].name, "Cheese Ball Recipes")
        self.assertEqual(entries[0].host, "zippy.micro.umn.edu")
        self.assertEqual(entries[0].port, 150)

        # Second entry should be the special cap file
        self.assertEqual(entries[2].name, "New Long Cool Name")
        self.assertEqual(entries[2].selector, "/zzz.txt")
Beispiel #16
0
class TestMBoxHandler(unittest.TestCase):
    def setUp(self):
        self.config = testutil.get_config()
        self.vfs = VFS_Real(self.config)
        self.selector = "/python-dev.mbox"
        self.protocol = testutil.get_testing_protocol(self.selector, config=self.config)
        self.stat_result = self.vfs.stat(self.selector)

    def test_mbox_folder_handler(self):
        handler = MBoxFolderHandler(
            self.selector, "", self.protocol, self.config, self.stat_result, self.vfs
        )
        handler.prepare()

        self.assertTrue(handler.canhandlerequest())
        self.assertTrue(handler.isdir())

        entry = handler.getentry()
        self.assertEqual(entry.mimetype, "application/gopher-menu")
        self.assertEqual(entry.type, "1")

        messages = handler.getdirlist()
        self.assertTrue(len(messages), 6)
        self.assertEqual(messages[0].selector, "/python-dev.mbox|/MBOX-MESSAGE/1")
        self.assertEqual(messages[0].name, "[Python-Dev] Pickling w/ low overhead")

    def test_mbox_message_handler(self):
        """
        Load the third message from the mbox.
        """
        handler = MBoxMessageHandler(
            "/python-dev.mbox|/MBOX-MESSAGE/3",
            "",
            self.protocol,
            self.config,
            self.stat_result,
            self.vfs,
        )
        handler.prepare()

        self.assertTrue(handler.canhandlerequest())
        self.assertFalse(handler.isdir())

        entry = handler.getentry()
        self.assertEqual(entry.mimetype, "text/plain")
        self.assertEqual(entry.name, "Re: [Python-Dev] Buffer interface in abstract.c?")
        self.assertEqual(entry.type, "0")

        wfile = io.BytesIO()
        handler.write(wfile)
        email_text = wfile.getvalue()
        assert email_text.startswith(b"From: Greg Stein <*****@*****.**>")
Beispiel #17
0
def getHandler(selector, searchrequest, protocol, config, handlerlist = None,
               vfs = None):
    """Called without handlerlist specified, uses the default as listed
    in config."""
    global handlers, rootpath

    if vfs == None:
        from pygopherd.handlers.base import VFS_Real
        vfs = VFS_Real(config)

    if not handlers:
        handlers = eval(config.get("handlers.HandlerMultiplexer",
                                   "handlers"))
        rootpath = config.get("pygopherd", "root")
    if handlerlist == None:
        handlerlist = handlers

    # SECURITY: assert that our absolute path is within the absolute
    # path of the site root.

    #if not os.path.abspath(rootpath + '/' + selector). \
    #   startswith(os.path.abspath(rootpath)):
    #    raise GopherExceptions.FileNotFound, \
    #          [selector, "Requested document is outside the server root",
    #           protocol]

    statresult = None
    try:
        statresult = vfs.stat(selector)
    except OSError:
        pass
    for handler in handlerlist:
        htry = handler(selector, searchrequest, protocol, config, statresult,
                       vfs)
        if htry.isrequestforme():
            return htry.gethandler()
    
    raise GopherExceptions.FileNotFound, \
          [selector, "no handler found", protocol]
Beispiel #18
0
class TestZipHandler(unittest.TestCase):
    def setUp(self):
        self.config = testutil.get_config()
        self.vfs = VFS_Real(self.config)
        self.selector = "/testdata.zip"
        self.protocol = testutil.get_testing_protocol(self.selector,
                                                      config=self.config)
        self.stat_result = self.vfs.stat(self.selector)

        self.config.set("handlers.ZIP.ZIPHandler", "enabled", "true")

    def test_zip_handler_directory(self):
        handler = ZIPHandler(self.selector, "", self.protocol, self.config,
                             self.stat_result, self.vfs)
        self.assertTrue(handler.canhandlerequest())

        handler.prepare()
        self.assertTrue(handler.isdir())

        entry = handler.getentry()
        self.assertEqual(entry.selector, "/testdata.zip")
        self.assertEqual(entry.name, "testdata.zip")
        self.assertEqual(entry.mimetype, "application/gopher-menu")

        entries = handler.getdirlist()
        self.assertEqual(len(entries), 8)

        self.assertEqual(entries[0].selector, "/testdata.zip/README")
        self.assertEqual(entries[0].name, "README")
        self.assertEqual(entries[0].mimetype, "text/plain")

    def test_zip_handler_file(self):
        self.selector = "/testdata.zip/README"

        handler = ZIPHandler(self.selector, "", self.protocol, self.config,
                             None, self.vfs)
        self.assertTrue(handler.canhandlerequest())

        handler.prepare()
        self.assertFalse(handler.isdir())

        entry = handler.getentry()
        self.assertEqual(entry.selector, "/testdata.zip/README")
        self.assertEqual(entry.name, "README")
        self.assertEqual(entry.mimetype, "text/plain")

        wfile = io.BytesIO()
        handler.write(wfile)
        data = wfile.getvalue()
        assert data.startswith(
            b"This directory contains data for the unit tests.")
Beispiel #19
0
class TestFileHandler(unittest.TestCase):
    def setUp(self):
        self.config = testutil.get_config()
        self.vfs = VFS_Real(self.config)
        self.selector = "/testfile.txt"
        self.protocol = testutil.get_testing_protocol(self.selector, config=self.config)
        self.stat_result = self.vfs.stat(self.selector)

    def test_file_handler(self):
        handler = FileHandler(
            self.selector, "", self.protocol, self.config, self.stat_result, self.vfs
        )

        self.assertTrue(handler.canhandlerequest())
        self.assertFalse(handler.isdir())

        entry = handler.getentry()
        self.assertEqual(entry.mimetype, "text/plain")
        self.assertEqual(entry.type, "0")

        wfile = io.BytesIO()
        handler.write(wfile)
        data = wfile.getvalue().decode()
        self.assertEqual(data, "Test\n")

    @unittest.skipUnless(
        testutil.supports_non_utf8_filenames(),
        reason="Filesystem does not support non-utf8 filenames.",
    )
    def test_file_handler_non_utf8(self):
        self.selector = b"/\xAE.txt".decode(errors="surrogateescape")

        handler = FileHandler(
            self.selector, "", self.protocol, self.config, self.stat_result, self.vfs
        )

        self.assertTrue(handler.canhandlerequest())
        self.assertFalse(handler.isdir())

        entry = handler.getentry()
        self.assertEqual(entry.mimetype, "text/plain")
        self.assertEqual(entry.type, "0")

        wfile = io.BytesIO()
        handler.write(wfile)
        data = wfile.getvalue()
        self.assertEqual(data, b"Hello, \xAE!")
Beispiel #20
0
class TestHTMLHandler(unittest.TestCase):
    def setUp(self):
        self.config = testutil.get_config()
        self.vfs = VFS_Real(self.config)
        self.selector = "/testfile.html"
        self.protocol = testutil.get_testing_protocol(self.selector,
                                                      config=self.config)
        self.stat_result = self.vfs.stat(self.selector)

    def test_html_handler(self):
        handler = HTMLFileTitleHandler("/testfile.html", "", self.protocol,
                                       self.config, self.stat_result, self.vfs)

        self.assertTrue(handler.canhandlerequest())

        entry = handler.getentry()
        self.assertEqual(entry.name, "<Gopher Rocks>")
def getHandler(
    selector: str,
    searchrequest: str,
    protocol: BaseGopherProtocol,
    config: configparser.ConfigParser,
    handlerlist: typing.Optional[typing.List[BaseHandler]] = None,
    vfs: typing.Optional[VFS_Real] = None,
):
    """Called without handlerlist specified, uses the default as listed
    in config."""
    global handlers, rootpath
    init_default_handlers(config)

    if vfs is None:
        vfs = VFS_Real(config)

    if handlerlist is None:
        handlerlist = handlers

    typing.cast(handlers, typing.List[BaseHandler])
    typing.cast(rootpath, str)

    # SECURITY: assert that our absolute path is within the absolute
    # path of the site root.

    # if not os.path.abspath(rootpath + '/' + selector). \
    #   startswith(os.path.abspath(rootpath)):
    #    raise GopherExceptions.FileNotFound, \
    #          [selector, "Requested document is outside the server root",
    #           protocol]

    statresult = None
    try:
        statresult = vfs.stat(selector)
    except OSError:
        pass
    for handler in handlerlist:
        htry = handler(selector, searchrequest, protocol, config, statresult,
                       vfs)
        if htry.isrequestforme():
            return htry.gethandler()

    raise GopherExceptions.FileNotFound(selector, "no handler found", protocol)
Beispiel #22
0
class TestPYGHandler(unittest.TestCase):
    def setUp(self):
        self.config = testutil.get_config()
        self.vfs = VFS_Real(self.config)
        self.selector = "/testfile.pyg"
        self.protocol = testutil.get_testing_protocol(self.selector,
                                                      config=self.config)
        self.stat_result = self.vfs.stat("/testfile.pyg")

    def test_pyg_handler(self):
        handler = PYGHandler(self.selector, "", self.protocol, self.config,
                             self.stat_result, self.vfs)

        self.assertTrue(handler.canhandlerequest())
        self.assertFalse(handler.isdir())

        entry = handler.getentry()
        self.assertEqual(entry.selector, "/testfile.pyg")

        wfile = io.BytesIO()
        handler.write(wfile)
        self.assertEqual(wfile.getvalue(), b"hello world!")
Beispiel #23
0
class TestTALHandler(unittest.TestCase):
    def setUp(self):
        self.config = testutil.get_config()
        self.vfs = VFS_Real(self.config)
        self.selector = "/talsample.html.tal"
        self.protocol = testutil.get_testing_protocol(self.selector,
                                                      config=self.config)
        self.stat_result = self.vfs.stat(self.selector)

        # Initialize the custom mimetypes encoding map
        initialization.init_logger(self.config, "")
        initialization.init_mimetypes(self.config)

    def test_tal_available(self):
        self.assertTrue(talavailable)

    def test_tal_handler(self):
        handler = TALFileHandler(self.selector, "", self.protocol, self.config,
                                 self.stat_result, self.vfs)

        self.assertTrue(handler.canhandlerequest())

        entry = handler.getentry()
        self.assertEqual(entry.mimetype, "text/html")
        self.assertEqual(entry.type, "h")

        wfile = io.BytesIO()
        handler.write(wfile)
        rendered_data = wfile.getvalue().decode()

        expected_data = TEST_TEMPLATE.format(
            selector=handler.selector,
            handler=html.escape(str(handler)),
            protocol=html.escape(str(self.protocol)),
            vfs=html.escape(str(self.vfs)),
        )

        self.assertEqual(rendered_data.strip(), expected_data.strip())
Beispiel #24
0
class TestBuckGophermapHandler(unittest.TestCase):
    def setUp(self):
        self.config = testutil.get_config()
        self.vfs = VFS_Real(self.config)
        self.selector = "/bucktooth"
        self.protocol = testutil.get_testing_protocol(self.selector,
                                                      config=self.config)
        self.stat_result = self.vfs.stat(self.selector)

    def test_buck_gophermap_handler(self):
        handler = BuckGophermapHandler(self.selector, "", self.protocol,
                                       self.config, self.stat_result, self.vfs)

        self.assertTrue(handler.canhandlerequest())
        self.assertTrue(handler.isdir())

        handler.prepare()
        entry = handler.getentry()
        self.assertEqual(entry.mimetype, "application/gopher-menu")
        self.assertEqual(entry.type, "1")

        entries = handler.getdirlist()
        self.assertTrue(entries)

        expected = [
            ("i", "hello world", "fake", "(NULL)", 0),
            ("1", "filename", "/bucktooth/filename", None, None),
            ("1", "filename", "/bucktooth/README", None, None),
            ("1", "filename", "/bucktooth/selector", "hostname", None),
            ("1", "filename", "/bucktooth/selector", "hostname", 69),
        ]
        for i, entry in enumerate(entries):
            self.assertEqual(entry.type, expected[i][0])
            self.assertEqual(entry.name, expected[i][1])
            self.assertEqual(entry.selector, expected[i][2])
            self.assertEqual(entry.host, expected[i][3])
            self.assertEqual(entry.port, expected[i][4])
Beispiel #25
0
    def handleeaext(self, selector: str, vfs: Optional[VFS_Real]) -> None:
        """Handle getting extended attributes from the filesystem."""
        global eaexts
        if eaexts is None:
            eaexts = eval(self.config.get("GopherEntry", "eaexts"))
        if vfs is None:
            from pygopherd.handlers.base import VFS_Real

            vfs = VFS_Real(self.config)

        for extension, blockname in list(eaexts.items()):
            if blockname in self.ea:
                continue
            try:
                with vfs.open(selector + extension,
                              "r",
                              errors="surrogateescape") as rfile:
                    self.setea(
                        blockname,
                        "\n".join([x.rstrip()
                                   for x in rfile.readlines(20480)]),
                    )
            except IOError:
                pass
Beispiel #26
0
    def populatefromfs(self, fspath, statval = None, vfs = None):
        """Fills in self with data gleaned from the filesystem.

        The argument fspath specifies where in the filesystem it will search.
        statval, if present, will be used instead of calling stat() itself
        so as to cut down on the number of system calls.

        The overall idea of this function is to set only those values that
        are not already set and to do so only if a definitive answer for
        them can be obtained from the operating system.  The rest of this
        information describes the details of how it does this.

        If populatefromfs has already been called or self.populated is true,
        this function will note the fspath and the return without modifying
        anything else.

        If either gethost() or getport() return anything other than None,
        the same thing will happen.

        If there is no statval and os.stat returns an error, again,
        the same thing will happen.

        Assuming these tests pass, then:

        self.gopherpsupport will be set to true for any file or directory.

        The remaining values will be set only if they are not set already:

        For both files and directories, the creation and modification times
        will be noted, the name will be set to the filename (as returned
        by os.path.basename on the selector).

        For directories only, the type will be set to 1 and the mimetype to
        application/gopher-menu.  Gopher+ protocols may wish to
        indicate application/gopher+-menu is available as well, but that
        is outside the scope of this function.

        For files only, the size will be noted.  An attempt will be made
        to ascertain a mimetype and an encoding.  If only a mimetype is
        found, it will be noted in self.mimetype.  If both a mimetype
        and an encoding is found, self.mimetype will be
        application/octet-stream, self.encoding will note the encoding,
        and self.encodedmimetype will note the type of the encoded data.
        If no mimetype can be found, it will be set to the default
        from the config file.  If no gopher0 type character is already present,
        self.guesstype() will be called to set it."""
        
        self.fspath = fspath
        if vfs == None:
            from pygopherd.handlers.base import VFS_Real
            vfs = VFS_Real(self.config)

        if self.populated:
            return

        # Just let the stat catch the OSError rather than testing
        # for existance here.  Help cut down on the number of syscalls.

        if not (self.gethost() == None and self.getport() == None):
            return

        if not statval:
            try:
                statval = vfs.stat(self.fspath)
            except OSError:
                return
        
        self.populated = 1
        self.gopherpsupport = 1         # Indicate gopher+ support for locals.

        # All this "or" stuff means that we only modify it if it's not already
        # set.

        self.ctime = self.ctime or statval[9]
        self.mtime = self.mtime or statval[8]
        self.name = self.name or os.path.basename(self.selector)

        if stat.S_ISDIR(statval[0]):
            self.type = self.type or '1'
            self.mimetype = self.mimetype or 'application/gopher-menu'
            self.handleeaext(self.fspath + '/', vfs) # Add the / so we get /.abs
            return

        self.handleeaext(self.fspath, vfs)

        self.size = self.size or statval[6]

        mimetype, encoding = mimetypes.guess_type(self.selector, strict = 0)

        if encoding:
            self.mimetype = self.mimetype or 'application/octet-stream'
            self.encoding = self.encoding or encoding
            self.encodedmimetype = self.encodedmimetype or mimetype
        else:
            self.mimetype = self.mimetype or mimetype

        # Did we get no mime type at all?  Fall back to a default.

        if not self.mimetype:
            self.mimetype = self.config.get("GopherEntry", "defaultmimetype")

        self.type = self.type or self.guesstype()
Beispiel #27
0
 def populatefromvfs(self, vfs: VFS_Real, selector: str) -> None:
     self.populatefromfs(selector, statval=vfs.stat(selector), vfs=vfs)
Beispiel #28
0
    def populatefromfs(self, fspath, statval=None, vfs=None):
        """Fills in self with data gleaned from the filesystem.

        The argument fspath specifies where in the filesystem it will search.
        statval, if present, will be used instead of calling stat() itself
        so as to cut down on the number of system calls.

        The overall idea of this function is to set only those values that
        are not already set and to do so only if a definitive answer for
        them can be obtained from the operating system.  The rest of this
        information describes the details of how it does this.

        If populatefromfs has already been called or self.populated is true,
        this function will note the fspath and the return without modifying
        anything else.

        If either gethost() or getport() return anything other than None,
        the same thing will happen.

        If there is no statval and os.stat returns an error, again,
        the same thing will happen.

        Assuming these tests pass, then:

        self.gopherpsupport will be set to true for any file or directory.

        The remaining values will be set only if they are not set already:

        For both files and directories, the creation and modification times
        will be noted, the name will be set to the filename (as returned
        by os.path.basename on the selector).

        For directories only, the type will be set to 1 and the mimetype to
        application/gopher-menu.  Gopher+ protocols may wish to
        indicate application/gopher+-menu is available as well, but that
        is outside the scope of this function.

        For files only, the size will be noted.  An attempt will be made
        to ascertain a mimetype and an encoding.  If only a mimetype is
        found, it will be noted in self.mimetype.  If both a mimetype
        and an encoding is found, self.mimetype will be
        application/octet-stream, self.encoding will note the encoding,
        and self.encodedmimetype will note the type of the encoded data.
        If no mimetype can be found, it will be set to the default
        from the config file.  If no gopher0 type character is already present,
        self.guesstype() will be called to set it."""

        self.fspath = fspath
        if vfs == None:
            from pygopherd.handlers.base import VFS_Real
            vfs = VFS_Real(self.config)

        if self.populated:
            return

        # Just let the stat catch the OSError rather than testing
        # for existance here.  Help cut down on the number of syscalls.

        if not (self.gethost() == None and self.getport() == None):
            return

        if not statval:
            try:
                statval = vfs.stat(self.fspath)
            except OSError:
                return

        self.populated = 1
        self.gopherpsupport = 1  # Indicate gopher+ support for locals.

        # All this "or" stuff means that we only modify it if it's not already
        # set.

        self.ctime = self.ctime or statval[9]
        self.mtime = self.mtime or statval[8]
        self.name = self.name or os.path.basename(self.selector)

        if stat.S_ISDIR(statval[0]):
            self.type = self.type or '1'
            self.mimetype = self.mimetype or 'application/gopher-menu'
            self.handleeaext(self.fspath + '/',
                             vfs)  # Add the / so we get /.abs
            return

        self.handleeaext(self.fspath, vfs)

        self.size = self.size or statval[6]

        mimetype, encoding = mimetypes.guess_type(self.selector, strict=0)

        if encoding:
            self.mimetype = self.mimetype or 'application/octet-stream'
            self.encoding = self.encoding or encoding
            self.encodedmimetype = self.encodedmimetype or mimetype
        else:
            self.mimetype = self.mimetype or mimetype

        # Did we get no mime type at all?  Fall back to a default.

        if not self.mimetype:
            self.mimetype = self.config.get("GopherEntry", "defaultmimetype")

        self.type = self.type or self.guesstype()
Beispiel #29
0
 def setUp(self):
     self.config = testutil.get_config()
     self.vfs = VFS_Real(self.config)
     self.selector = "/python-dev.mbox"
     self.protocol = testutil.get_testing_protocol(self.selector, config=self.config)
     self.stat_result = self.vfs.stat(self.selector)
Beispiel #30
0
class TestMaildirHandler(unittest.TestCase):
    """
    The maildir test data was generated from a mailbox file using this script:

    http://batleth.sapienti-sat.org/projects/mb2md/

    Important Note: The python implementation uses os.listdir() under the
    hood to iterate over the mail files in the directory. The order of
    files returned is deterministic but is *not* sorted by filename. This
    means that mail files in the generated gopher directory listing may
    appear out of order from their "true" ordering in the mail archive.
    It also makes writing this test a pain in the ass.
    """

    def setUp(self):
        self.config = testutil.get_config()
        self.vfs = VFS_Real(self.config)
        self.selector = "/python-dev"
        self.protocol = testutil.get_testing_protocol(self.selector, config=self.config)
        self.stat_result = self.vfs.stat(self.selector)

    def test_maildir_folder_handler(self):
        handler = MaildirFolderHandler(
            self.selector, "", self.protocol, self.config, self.stat_result, self.vfs
        )
        handler.prepare()

        self.assertTrue(handler.canhandlerequest())
        self.assertTrue(handler.isdir())

        entry = handler.getentry()
        self.assertEqual(entry.mimetype, "application/gopher-menu")
        self.assertEqual(entry.type, "1")

        messages = handler.getdirlist()
        self.assertTrue(len(messages), 6)
        self.assertEqual(messages[0].selector, "/python-dev|/MAILDIR-MESSAGE/1")
        self.assertIn("[Python-Dev]", messages[0].name)

    def test_maildir_message_handler(self):
        """
        Load the third message from the maildir.
        """
        handler = MaildirMessageHandler(
            "/python-dev|/MAILDIR-MESSAGE/3",
            "",
            self.protocol,
            self.config,
            self.stat_result,
            self.vfs,
        )
        handler.prepare()

        self.assertTrue(handler.canhandlerequest())
        self.assertFalse(handler.isdir())

        entry = handler.getentry()
        self.assertEqual(entry.mimetype, "text/plain")
        self.assertEqual(entry.type, "0")

        wfile = io.BytesIO()
        handler.write(wfile)
        email_text = wfile.getvalue()
        assert email_text.startswith(b"From:")