File: ResourceInformation.py

package info (click to toggle)
forg 0.5.1-7.1
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 532 kB
  • ctags: 738
  • sloc: python: 5,407; xml: 85; makefile: 63
file content (176 lines) | stat: -rw-r--r-- 6,539 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# ResourceInformation.py
# $Id: ResourceInformation.py,v 1.6 2001/07/05 17:16:53 s2mdalle Exp $
# Written by David Allen <mda@idatar.com>
# Released under the terms of the GNU General Public License
#
# When dealing with a Gopher+ server, information about a document can be
# fetched by sending the request:
# some_locator\t!\r\n
#
# This module handles the parsing and storing of that information.
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
############################################################################

from string import *
from Tkinter import *
import Pmw
import os
import re
import ContentFrame
from gopher         import *
import GopherResource
import GopherResponse

class ResourceInformation:
    verbose = None
    def __init__(self, data=None):
        self.blockdict = {}

        self.data = data
        
        if self.data != None:
            self.setData(self.data)

        return None
    def __str__(self):
        return self.toString()
    def toString(self):
        def fn(key, obj=self):
            return "%s:\n%s\n" % (upper(key), obj.getBlock(key))
        
        return join(map(fn, self.getBlockNames()), "") + "\n"
    
    def setData(self, data):
        self.data = data
        self.data = re.sub("\r\n", "\n", self.data)

        lastindex = -1
        blocks = []

        try:
            while 1:
                # This will throw ValueError if not found.
                newindex = index(self.data, "\n+",
                                 (lastindex + 1), len(self.data))
                blocks.append(self.data[lastindex+1:newindex])
                lastindex = newindex
        except ValueError:  # When no more "\n+" are found.
            # The remaining block is what's left...
            blocks.append(self.data[lastindex+1:len(self.data)])

        # What we're going to do is hash each data block in by its block
        # 'title'.  This way, when we're done hashing all of the data, we
        # can just go through and pick out what we want.  So this type of
        # data:
        # +ADMIN:
        #  Grendel The Evil <grendel@nowhere.com>
        #  Some more admin information
        # Gets hashed in like this essentially:
        # hash['admin'] = "Grendel The Evil <grendel@nowhere.com>\n..."
        self.blockdict = {}

        # We now have a list of blocks.
        for block in blocks:
            lines = split(block, "\n")
            blocklabel = lines[0]

            front = find(blocklabel, "+")   # This defines the start of a block
            back  = find(blocklabel, ":")   # This may not be present

            if front != -1:
                if back == -1:
                    back = len(blocklabel)  # End of string if not present

                # Get the name, which is like this: "+ADMIN:" => 'ADMIN'
                blockname = blocklabel[front+1:back]
                key = lower(blockname) # Lowercase so it hashes nicely.  :)
                
                # strip the leading space.  This is because in gopher+
                # when it responds to info queries, each response line that
                # isn't a block header is indented by one space.
                data = re.sub("\n ", "\n", join(lines[1:], "\n"))

                # Get the first space in the data.
                if self.verbose:
                    print "Data is %s" % data

                # Watch out for the case when data is ''.  This could be in
                # particular if the server sends us a size packet like this:
                # +-1\r\n
                # Which would have a '' data segment.
                if data != '' and data[0] == ' ':
                    data = data[1:]

                # Assign it into the hash.
                if self.verbose:
                    print "Assigned data to key %s" % key

                if data != '' and not data is None:
                    # No sense in assigning nothing into a key.  The getBlock()
                    # handles when there is no data and returns ''
                    self.blockdict[key] = data
            else:
                print "BLOCK ERROR: cannot find blockname in %s" % blocklabel

        if self.verbose:
            k = self.blockdict.keys()
            print "Available block titles are:\n%s" % join(k, "\n")

        print "Keys are ", self.blockdict.keys()
        return self

    # Simple accessors/mutators.
    # Sure, I could just monkey around with the data in an object from outside,
    # but in some cultures, people are executed for such offenses against the
    # OOP paradigm.  :)
    def setBlock(self, blockname, blockval):
        self.blockdict[lower(blockname)] = blockval
        return self.getBlock(lower(blockname))
    def setInfo(self, newinfo):
        self.blockdict['info'] = newinfo
        return self.getInfo()
    def setAdmin(self, newadmin):
        self.blockdict['admin'] = newadmin
        return self.getAdmin()
    def setViews(self, newviews):
        self.blockdict['views'] = newviews
        return self.getViews()
    def setAbstract(self, newabstract):
        self.blockdict['abstract'] = newabstract
        return self.getAbstract()
    def getAbstract(self):
        return self.blockdict['abstract']
    def getViews(self):
        return self.blockdict['views']
    def getInfo(self):
        return self.blockdict['info']
    def getAdmin(self):
        return self.blockdict['admin']
    def getBlockNames(self):
        return self.blockdict.keys()
    def getBlock(self, blockname):
        try:
            return self.blockdict[lower(blockname)]
        except KeyError:
            return ''

class GUIResourceInformation(Pmw.TextDialog):
    def __init__(self, resource_info_object):
        Pmw.TextDialog.__init__(self, title="Resource Information")
        self.insert('end', resource_info_object.toString())
        return None