Changeset 210

Show
Ignore:
Timestamp:
08/01/05 16:12:05 (3 years ago)
Author:
zool
Message:

moved openseason to nodel; fixing user login handling in nodedb; bbox tweaks from wirelesscommons

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • bbox/bbox/__init__.py

    Revision 198 Revision 210
    1# bbox - an RSS / RDF aggregator 1# bbox - an RSS / RDF aggregator 
    2# Jo Walsh - Dec 2004 - Mar 2005 2# Jo Walsh - Dec 2004 - Mar 2005 
    3 3 
    4# This code owes heavily to the approach and source in Edd Dumbill's  4# This code owes heavily to the approach and source in Edd Dumbill's  
    5# IBM Developerworks article on aggregating RSS with contexts: 5# IBM Developerworks article on aggregating RSS with contexts: 
    6# http://www-106.ibm.com/developerworks/xml/library/x-rdfprov.html 6# http://www-106.ibm.com/developerworks/xml/library/x-rdfprov.html 
    7 7 
    8# It uses Mark Pilgrim's feedparser, at http://feedparser.org/ 8# It uses Mark Pilgrim's feedparser, at http://feedparser.org/ 
    9# This software has 2000 tests. The code is included in this package. 9# This software has 2000 tests. The code is included in this package. 
    10 10 
    11# It uses the 'rdfobj', an object interface to the python interface 11# It uses the 'rdfobj', an object interface to the python interface 
    12# to the redland rdf toolkit. This is also included. 12# to the redland rdf toolkit. This is also included. 
    13# redland is at http://www.redland.opensource.ac.uk/ 13# redland is at http://www.redland.opensource.ac.uk/ 
    14  14  
    15import feedparser 15import feedparser 
    16import time, datetime 16import time, datetime 
    17import rdfobj 17import rdfobj 
    18import RDF 18import RDF 
    19from politehttp import polite_request 19from politehttp import polite_request 
    20import bbox.config 20import bbox.config 
    21import os 21import os 
    22from warnings import warn 22from warnings import warn 
    23 23 
    24class BBox: 24class BBox: 
    25 25 
    26    def __init__(self,spatialStore=None,verbose=None,always_visit=None,db=None): 26    def __init__(self,spatialStore=None,verbose=None,always_visit=None,db=None): 
    27     27     
    28        """We initialise a bbox by passing a database to it. If wishing to use an optional spatial index, a spatialStore object must be supplied. setting verbose to a true value turns on BBox's stream of consciousness.""" 28        """We initialise a bbox by passing a database to it. If wishing to use an optional spatial index, a spatialStore object must be supplied. setting verbose to a true value turns on BBox's stream of consciousness.""" 
    29 29 
    30        self.spatialStore = spatialStore 30        self.spatialStore = spatialStore 
    31        self._verbose = verbose 31        self._verbose = verbose 
    32        self._visit_true = always_visit 32        self._visit_true = always_visit 
    33         33         
    34        os.chdir(bbox.config.store) 34        os.chdir(bbox.config.store) 
    35        if db is None: 35        if db is None: 
    36            db = bbox.config.db 36            db = bbox.config.db 
    37        self.model = rdfobj.Model(db,db='hash') 37        self.model = rdfobj.Model(db,db='hash') 
    38        self.model.load(bbox.config.boot) 38        self.model.load(bbox.config.boot) 
    39        from rdfobj import fbox 39        from rdfobj import fbox 
    40        fbox = rdfobj.fbox 40        fbox = rdfobj.fbox 
    41        counter = self.model.fetch(fbox.Visit_Count) 41        counter = self.model.fetch(fbox.Visit_Count) 
    42        c = counter[fbox.count] 42        c = counter[fbox.count] 
    43        if c is None: c = 0 43        if c is None: c = 0 
    44        c = int(str(c))+1 44        c = int(str(c))+1 
    45        counter[fbox.count] = str(c) 45        counter[fbox.count] = str(c) 
    46         46         
    47        if counter is None: 47        if counter is None: 
    48            v = self.model.create(fbox.Visit_Count, uri=fbox.Visit_Count) 48            v = self.model.create(fbox.Visit_Count, uri=fbox.Visit_Count) 
    49            v[fbox.count] = 0 49            v[fbox.count] = 0 
    50             50             
    51 51 
    52    def mention(self,thought): 52    def mention(self,thought): 
    53        """If BBox is constructed with verbose=1, prints to STDOUT (currently) a record of what it's up to.""" 53        """If BBox is constructed with verbose=1, prints to STDOUT (currently) a record of what it's up to.""" 
    54        if self._verbose: 54        if self._verbose: 
    55            print(thought) 55            print(thought) 
    56             56             
    57    def read_subscriptions(self): 57    def read_subscriptions(self): 
    58        """read_subscriptions() picks up the latest RSS feed updates. """ 58        """read_subscriptions() picks up the latest RSS feed updates. """ 
    59        self.mention("checking subscriptions.")  59        self.mention("checking subscriptions.")  
    60        subs = self.subscriptions() 60        subs = self.subscriptions() 
    61        from rdfobj import fbox 61        from rdfobj import fbox 
    62        fbox = rdfobj.fbox 62        fbox = rdfobj.fbox 
    63        for s in subs: 63        for s in subs: 
    64            self.mention("reading "+str(s[fbox.channel])) 64            self.mention("reading "+str(s[fbox.channel])) 
    65            format = s[fbox.format].uri() 65            format = s[fbox.format].uri() 
    66            c = s[fbox.channel] 66            c = s[fbox.channel] 
    67 67 
    68            # see if we're actually due a visit 68            # see if we're actually due a visit 
    69            due = self.visit_scheduled(s) 69            due = self.visit_scheduled(s) 
    70            if due is None:  70            if due is None:  
    71                print "nothing due to look at!" 71                print "nothing due to look at!" 
    72                subs.next() 72                subs.next() 
    73            else: 73            else: 
    74                if format == fbox.rss: 74                if format == fbox.rss: 
    75                    self.read_rss(c.uri(),subscription=s) 75                    self.read_rss(c.uri(),subscription=s) 
    76                elif format == fbox.rdf: 76                elif format == fbox.rdf: 
    77                    self.read_rdf(s[fbox.channel].uri(),subscription=s) 77                    self.read_rdf(s[fbox.channel].uri(),subscription=s) 
    78             78             
    79    def read_rss(self,uri,context=None,subscription=None): 79    def read_rss(self,uri,context=None,subscription=None): 
    80        """Read updates from an RSS feed.""" 80        """Read updates from an RSS feed.""" 
    81 81 
    82        #if subscription is None: subscription = {} 82        #if subscription is None: subscription = {} 
    83        rss = rdfobj.rss 83        rss = rdfobj.rss 
    84        dc = rdfobj.dc 84        dc = rdfobj.dc 
    85        ical = rdfobj.ical 85        ical = rdfobj.ical 
      86        fbox = rdfobj.fbox 
    86 87 
    87        result = self.politely_get_uri(uri,subscription=subscription)  88        result = self.politely_get_uri(uri,subscription=subscription)  
    88 89 
    89        channel = self.model.fetch(uri)          90        channel = self.model.fetch(uri)          
    90        """If we got a feed object back from the request, then create a 91        """If we got a feed object back from the request, then create a 
    91        context for this visit to the feed, and store the entries that we 92        context for this visit to the feed, and store the entries that we 
    92        collected from it.""" 93        collected from it.""" 
    93        if self._visit_true: 94        if self._visit_true: 
    94            warn('visiting') 95            warn('visiting') 
    95             96             
    96        elif result['status'] != 200:  97        elif result['status'] != 200:  
    97            return 98            return 
    98 99 
    99        feed = feedparser.parse(result['data']) 100        feed = feedparser.parse(result['data']) 
    100        if feed.has_key('feed'): 101        if feed.has_key('feed'): 
    101            context = self.visit(uri) 102            context = self.visit(uri) 
    102            # existence of exact duplicates? 103            # existence of exact duplicates? 
    103            items = [] 104             
    104            for e in feed.entries: 105            for e in feed.entries: 
    105                item = self.model.create( rss.item, uri=str(e.link), context = context ) 106                item = self.model.create( rss.item, uri=str(e.link), context = context ) 
    106                warn(item.uri()) 107                 
    107                if e.has_key('summary'): item[rss.description] = str(e.summary) 108                if e.has_key('summary'): item[rss.description] = str(e.summary) 
    108 109 
    109                if e.has_key('content'): item[rss.description] = str(e.content) 110                if e.has_key('content'): item[rss.description] = str(e.content) 
      111 
      112                if e.has_key('title'): item[rss.title] = str(e.title) 
      113 
      114                item[fbox.channel] = channel 
      115                 
    110                # d.entries[0].modified_parsed is common 116                # d.entries[0].modified_parsed is common 
    111                 117                 
    112                time_tuple = None 118                time_tuple = None 
    113                if e.has_key('modified_parsed'): 119                if e.has_key('modified_parsed'): 
    114                    time_tuple = e.modified_parsed 120                    time_tuple = e.modified_parsed 
    115                elif e.has_key('created_parsed'): 121                elif e.has_key('created_parsed'): 
    116                    time_tuple = e.created_parsed 122                    time_tuple = e.created_parsed 
    117                 123                 
    118                # item[ical.datetime] = some process with time_tuple and strftime 124                # item[ical.datetime] = some process with time_tuple and strftime 
    119                # d = datetime.datetime(time_tuple) 125                # d = datetime.datetime(time_tuple) 
    120                # ical_date = ical_datetime.datetime_to_string(d) 126                # ical_date = ical_datetime.datetime_to_string(d) 
    121                # print ical_date 127                # print ical_date 
    122                # item[ical.datetime] = ical_date 128                # item[ical.datetime] = ical_date 
    123                # not much use without a timestamp 129                # not much use without a timestamp 
      130         
    124                if time_tuple is None: 131                if time_tuple is None: 
    125                    continue 132                    continue 
    126                ical_enough = time.strftime("%Y%m%dT%H%M%SZ",time_tuple) 133                ical_enough = time.strftime("%Y%m%dT%H%M%SZ",time_tuple) 
    127                item[ical.datetime] = ical_enough 134                item[ical.datetime] = ical_enough 
    128                items.append(item) 135                 
    129                   
    130            its = channel[rss.items]       
    131            if its is not None:   
    132                for i in its:       
    133                    items.append(i)   
    134                
    135                channel[rss.items] = items   
    136                   
    137    136    
    138    def read_rdf(self,uri,subscription=None):    137    def read_rdf(self,uri,subscription=None):    
    139        """Read updates from an RDF url.""" 138        """Read updates from an RDF url.""" 
    140        result = self.politely_get_uri(uri,subscription=subscription) 139        result = self.politely_get_uri(uri,subscription=subscription) 
    141        if result['status'] == 200: 140        if result['status'] == 200: 
    142            self.model.load(uri) 141            self.model.load(uri) 
    143 142 
    144    def politely_get_uri(self,uri,subscription=None): 143    def politely_get_uri(self,uri,subscription=None): 
    145        """Request a copy of the document at a url, first checking that it has changed since what we record as last-modified and the last etag that we have for it.""" 144        """Request a copy of the document at a url, first checking that it has changed since what we record as last-modified and the last etag that we have for it.""" 
    146         145         
    147        # we should deal with etag/last-mod politely here too @@TODO 146        # we should deal with etag/last-mod politely here too @@TODO 
    148        #visit = self.visit(uri) 147        #visit = self.visit(uri) 
    149        result = None 148        result = None 
    150        fbox = rdfobj.fbox 149        fbox = rdfobj.fbox 
    151 150 
    152        if self._visit_true is not None: 151        if self._visit_true is not None: 
    153            result = polite_request(str(uri))       152            result = polite_request(str(uri))       
    154        elif subscription[fbox.last_etag] is not None: 153        elif subscription[fbox.last_etag] is not None: 
    155            result = polite_request(str(uri),etag=str(subscription[fbox.last_etag])) 154            result = polite_request(str(uri),etag=str(subscription[fbox.last_etag])) 
    156        elif subscription[fbox.last_modified] is not None: 155        elif subscription[fbox.last_modified] is not None: 
    157            result = polite_request(str(uri),last_modified=str(subscription[fbox.last_modified])) 156            result = polite_request(str(uri),last_modified=str(subscription[fbox.last_modified])) 
    158        else: result = polite_request(str(uri)) 157        else: result = polite_request(str(uri)) 
    159 158 
    160        self.mention("received response: "+str(result['status'])) 159        self.mention("received response: "+str(result['status'])) 
    161            160            
    162        # look to the postgis index  161        # look to the postgis index  
    163        """Take actions about other kinds of HTTP statuses.(TODO)""" 162        """Take actions about other kinds of HTTP statuses.(TODO)""" 
    164        # handling different HTTP statuses. 163        # handling different HTTP statuses. 
    165        subscription[fbox.http_status] = str(result['status']) 164        subscription[fbox.http_status] = str(result['status']) 
    166        subscription[fbox.last_etag] = result['etag'] 165        subscription[fbox.last_etag] = result['etag'] 
    167        subscription[fbox.last_modified] = result['lastmodified']        166        subscription[fbox.last_modified] = result['lastmodified']        
    168        subscription[fbox.last_visited] = time.strftime("%Y%m%dT%H%M%SZ")  167        subscription[fbox.last_visited] = time.strftime("%Y%m%dT%H%M%SZ")  
    169        return result 168        return result 
    170 169 
    171    def subscriptions(self): 170    def subscriptions(self): 
    172        """Returns a list (Iterator type) of the URLs at which 171        """Returns a list (Iterator type) of the URLs at which 
    173        there is a feed that we are subscribed to (fbox:Feed type)""" 172        there is a feed that we are subscribed to (fbox:Feed type)""" 
    174        from rdfobj import fbox, rdf 173        from rdfobj import fbox, rdf 
    175        fbox = rdfobj.fbox 174        fbox = rdfobj.fbox 
    176        rdf = rdfobj.rdf 175        rdf = rdfobj.rdf 
    177        subs = self.model.search(rdf.type,fbox.Feed) 176        subs = self.model.search(rdf.type,fbox.Feed) 
    178        return subs 177        return subs 
    179 178 
    180    def subscription(self,uri): 179    def subscription(self,uri): 
    181        """Given a uri, returns the rdfobj which is the subscription it represents.""" 180        """Given a uri, returns the rdfobj which is the subscription it represents.""" 
    182        obj = self.model.fetch(uri) 181        obj = self.model.fetch(uri) 
    183        return obj 182        return obj 
    184 183 
    185    def items(self,uri,since=None,until=None): 184    def items(self,uri,since=None,until=None): 
    186        """Get items from a feed, optionally filtering by date. (not completely implemented)""" 185        """Get items from a feed, optionally filtering by date. (not completely implemented)""" 
    187        from rdfobj import fbox, dc, rss 186        from rdfobj import fbox, dc, rss 
    188        rss = fbox.rss 187        rss = fbox.rss 
    189        dc = fbox.dc 188        dc = fbox.dc 
    190        fbox = rdfobj.fbox 189        fbox = rdfobj.fbox 
    191        s = self.subscription(uri) 190        s = self.subscription(uri) 
    192        c = s[fbox.channel] 191        c = s[fbox.channel] 
    193        out = []  192        out = []  
    194        if since is not None: 193        if since is not None: 
    195            for i in c[rss.items]: 194            for i in c[rss.items]: 
    196                warn(i[dc.date]) 195                warn(i[dc.date]) 
    197                if i[dc.date] > since: 196                if i[dc.date] > since: 
    198                    out.append(i) 197                    out.append(i) 
    199 198 
    200        return c.rss_items 199        return c.rss_items 
    201   200   
    202    def subscribe(self,feed=None,format=None,interval=None): 201    def subscribe(self,feed=None,format=None,interval=None): 
    203        """subscribe() creates a subscription to a uri. format is either 'rss' or 'rdf'. RDF is assumed if none is specified. Interval is the maximum interval in minutes that a feed should be checked at. It sends polite HTTP requests so don't worry about setting it to a bit more often than you might need. A value in minutes - defaults to 100 minutes.""" 202        """subscribe() creates a subscription to a uri. format is either 'rss' or 'rdf'. RDF is assumed if none is specified. Interval is the maximum interval in minutes that a feed should be checked at. It sends polite HTTP requests so don't worry about setting it to a bit more often than you might need. A value in minutes - defaults to 100 minutes.""" 
    204        from rdfobj import fbox 203        from rdfobj import fbox 
    205        fbox = rdfobj.fbox       204        fbox = rdfobj.fbox       
    206        if feed is None: return 205        if feed is None: return 
    207 206 
    208        f = self.model.search(fbox.channel,feed) 207        f = self.model.search(fbox.channel,feed) 
    209        found = None 208        found = None 
    210        for n in f: 209        for n in f: 
    211            found = 1     210            found = 1     
    212        if found is not None: 211        if found is not None: 
    213            return 212            return 
    214 213 
    215        self.mention("subscribing to "+str(feed)) 214        self.mention("subscribing to "+str(feed)) 
    216 215 
    217        if format is None:  216        if format is None:  
    218            format = fbox.rdf 217            format = fbox.rdf 
    219        elif format == 'rss': 218        elif format == 'rss': 
    220            format = fbox.rss 219            format = fbox.rss 
    221        elif format == 'rdf': 220        elif format == 'rdf': 
    222            format = fbox.rdf 221            format = fbox.rdf 
    223 222 
    224        if interval is None: interval = str(100) 223        if interval is None: interval = str(100) 
    225 224 
    226        ff = self.model.create( fbox.Feed, uri=None ) 225        ff = self.model.create( fbox.Feed, uri=None ) 
    227        ff[fbox.channel] = str(feed) 226        ff[fbox.channel] = str(feed) 
    228        ff[fbox.format] = str(format) 227        ff[fbox.format] = str(format) 
    229        ff[fbox.interval] = interval 228        ff[fbox.interval] = interval 
    230 229 
    231        return ff 230        return ff 
    232 231 
    233    def update(self): 232    def update(self): 
    234        """Causes all the subscribed URLs to be visited for updates.""" 233        """Causes all the subscribed URLs to be visited for updates.""" 
    235        subs = self.subscriptions() 234        subs = self.subscriptions() 
    236        from rdfobj import fbox 235        from rdfobj import fbox 
    237        fbox = rdfobj.fbox 236        fbox = rdfobj.fbox 
    238        while not subs.end(): 237        while not subs.end(): 
    239            s = subs.current() 238            s = subs.current() 
    240            self.visit(s[fbox.channel]) 239            self.visit(s[fbox.channel]) 
    241            subs.next() 240            subs.next() 
    242 241 
    243    def visit(self,uri=None): 242    def visit(self,uri=None): 
    244        """Creates an anonymous object which records a visit that we 243        """Creates an anonymous object which records a visit that we 
    245        paid to a feed, including a counter of times visited. This object is 244        paid to a feed, including a counter of times visited. This object is 
    246        used as a Redland context for all the information collected from a feed 245        used as a Redland context for all the information collected from a feed 
    247        during this visit.""" 246        during this visit.""" 
    248        # redland had problems serialising models with bnode context uris  247        # redland had problems serialising models with bnode context uris  
    249        count = self.counter() 248        count = self.counter() 
    250        from rdfobj import fbox 249        from rdfobj import fbox 
    251        fbox = rdfobj.fbox 250        fbox = rdfobj.fbox 
    252        visit_uri = str(fbox.visit)+'/'+str(count) 251        visit_uri = str(fbox.visit)+'/'+str(count) 
    253        visit = self.model.create( fbox.Visit , visit_uri) 252        visit = self.model.create( fbox.Visit , visit_uri) 
    254 253 
    255        visit[fbox.source] = uri 254        visit[fbox.source] = uri 
    256        t = time.strftime("%Y%m%dT%H%M%SZ") 255        t = time.strftime("%Y%m%dT%H%M%SZ") 
    257        visit[fbox.timestamp] = t 256        visit[fbox.timestamp] = t 
    258        return RDF.Node(RDF.Uri(str(visit.uri()))) 257        return RDF.Node(RDF.Uri(str(visit.uri()))) 
    259 258 
    260    def user(self,token=None,nick=None,mbox=None): 259    def user(self,token=None,nick=None,mbox=None): 
    261        """Passed either a user's login token, mbox and name, resolved to mutual exclusion in that order, and returns any corresponding user / foaf:Person object. No security - handle this yourself elsewhere!""" 260        """Passed either a user's login token, mbox and name, resolved to mutual exclusion in that order, and returns any corresponding user / foaf:Person object. No security - handle this yourself elsewhere!""" 
    262        from rdfobj import foaf 261        from rdfobj import foaf 
    263        foaf = rdfobj.foaf 262        foaf = rdfobj.foaf 
    264        if token is not None: 263        if token is not None: 
    265            users = self.model.search(foaf.auth_token,token) 264            users = self.model.search(foaf.auth_token,token) 
    266            for u in users: 265            for u in users: 
    267                return u[foaf.alias] 266                return u[foaf.alias] 
    268        if mbox is not None: 267        if mbox is not None: 
    269            users = self.model.search(foaf.mbox,mbox) 268            users = self.model.search(foaf.mbox,mbox) 
    270            for u in users: 269            for u in users: 
    271                return u 270                return u 
    272        if nick is not None: 271        if nick is not None: 
    273            o = [] 272            o = [] 
    274            users = self.model.search(foaf.name,nick) 273            users = self.model.search(foaf.name,nick) 
    275            for u in users: 274            for u in users: 
    276                o.append(u) 275                o.append(u) 
    277            users = self.model.search(foaf.givenName,nick) 276            users = self.model.search(foaf.givenName,nick) 
    278            for u in users: o.append(u) 277            for u in users: o.append(u) 
    279            return o 278            return o 
    280 279 
    281    def add_user(self,nick=None,mbox=None,password=None): 280    def add_user(self,nick=None,mbox=None,password=None): 
    282        """ Create a new user foaf:Person""" 281        """ Create a new user foaf:Person""" 
    283        store = self.store 282        store = self.store 
    284        from rdfobj import foaf, wlan 283        from rdfobj import foaf, wlan 
    285        foaf = rdfobj.foaf 284        foaf = rdfobj.foaf 
    286        wlan = rdfobj.wlan 285        wlan = rdfobj.wlan 
    287 286 
    288        obj = self.model.create(foaf.Person,uri=uri) 287        obj = self.model.create(foaf.Person,uri=uri) 
    289        obj[foaf.mbox] = mbox 288        obj[foaf.mbox] = mbox 
    290        obj[foaf.nick] = nick 289        obj[foaf.nick] = nick 
    291        if page is not None: obj[foaf.homepage] = page 290        if page is not None: obj[foaf.homepage] = page 
    292        self.obj = obj 291        self.obj = obj 
    293 292 
    294        """ Create a kind of shadow user where we store the password and the logged-in token, so they won't get serialised accidentally along with the user. """ 293        """ Create a kind of shadow user where we store the password and the logged-in token, so they won't get serialised accidentally along with the user. """ 
    295 294 
    296        auth = store.create(foaf.AuthedPerson) 295        auth = store.create(foaf.AuthedPerson) 
    297        auth[foaf.password] = password 296        auth[foaf.password] = password 
    298        auth[foaf.nick] = nick 297        auth[foaf.nick] = nick 
    299        auth[foaf.alias] = obj 298        auth[foaf.alias] = obj 
    300 299 
    301        token = self.auth_token() 300        token = self.auth_token() 
    302        auth[foaf.auth_token] = token 301        auth[foaf.auth_token] = token 
    303        self.model.sync() 302        self.model.sync() 
    304        return token 303        return token 
    305 304 
    306    def auth_token(self): 305    def auth_token(self): 
    307        """Generate a random auth token.""" 306        """Generate a random auth token.""" 
    308        x = '' 307        x = '' 
    309        for  n in range(0, 6): 308        for  n in range(0, 6): 
    310            x = x + chr(65 + random.randint(0, 26)) 309            x = x + chr(65 + random.randint(0, 26)) 
    311        return x         310        return x         
    312         311         
    313    def visit_scheduled(self,sub): 312    def visit_scheduled(self,sub): 
    314        """Compare the last visited time, if that's applicable, to the interval between events (rather than a schedule? perhaps we'll have to re-think this later."""    313        """Compare the last visited time, if that's applicable, to the interval between events (rather than a schedule? perhaps we'll have to re-think this later."""    
    315        if self._visit_true is not None: 314        if self._visit_true is not None: 
    316            return 1 315            return 1 
    317        from rdfobj import fbox 316        from rdfobj import fbox 
    318        fbox = rdfobj.fbox 317        fbox = rdfobj.fbox 
    319        last = sub[fbox.last_visited] 318        last = sub[fbox.last_visited] 
    320        if last is None: 319        if last is None: 
    321            return 1 320            return 1 
    322        t = time.time() 321        t = time.time() 
    323        # convert last time simply from ical to epoch? 322        # convert last time simply from ical to epoch? 
    324 323 
    325        return 1 324        return 1 
    326        since = t - float(str(last)) 325        since = t - float(str(last)) 
    327         326         
    328        interval = sub[fbox.interval] 327        interval = sub[fbox.interval] 
    329        if interval is None: 328        if interval is None: 
    330            sub[fbox.interval] = str(100) 329            sub[fbox.interval] = str(100) 
    331            interval = sub[fbox.interval] 330            interval = sub[fbox.interval] 
    332        secs = int(str(interval))*60 331        secs = int(str(interval))*60 
    333        if since >= secs: 332        if since >= secs: 
    334            return 1 333            return 1 
    335        return None 334        return None 
    336                 335                 
    337    def counter(self): 336    def counter(self): 
    338        """Update the counter that's used to generate visit context URIs.""" 337        """Update the counter that's used to generate visit context URIs.""" 
    339        from rdfobj import fbox 338        from rdfobj import fbox 
    340        fbox = rdfobj.fbox 339        fbox = rdfobj.fbox 
    341        counter = self.model.fetch(fbox.Visit_Count) 340        counter = self.model.fetch(fbox.Visit_Count) 
    342        c = counter[fbox.count] 341        c = counter[fbox.count] 
    343        c = int(str(c))+1 342        c = int(str(c))+1 
    344        counter[fbox.count] = str(c) 343        counter[fbox.count] = str(c) 
    345        return c 344        return c 
    346 345 
    347 346 
    348if __name__ == "__main__": 347if __name__ == "__main__": 
    349    bbox = BBox(visit_true = 1) 348    bbox = BBox(visit_true = 1) 
    350    bbox.subscribe(feed='http://frot.org/wirelesslondon/bbox.rdf',format=fbox.rss) 349    bbox.subscribe(feed='http://frot.org/wirelesslondon/bbox.rdf',format=fbox.rss) 
    351    bbox.subscribe(feed='http://frot.org/devlog/index.rss',format=fbox.rss) 350    bbox.subscribe(feed='http://frot.org/devlog/index.rss',format=fbox.rss) 
    352    bbox.subscribe(feed='http://zooleika.org.uk/bio/foaf.rdf',format=fbox.rdf) 351    bbox.subscribe(feed='http://zooleika.org.uk/bio/foaf.rdf',format=fbox.rdf) 
    353    bbox.read_subscriptions() 352    bbox.read_subscriptions() 
  • bbox/bbox/config.py

    Revision 103 Revision 210
    1boot='file:/home/jo/consumotronic/bbox/boot.rdf' 1boot='file:/home/wirelesslondon/lib/consumotronic/bbox/boot.rdf' 
    2store = '/home/jo/bbox/store/' 2store = '/home/wirelesslondon/store/' 
    3db = 'bbox' 3db = 'bbox' 
    4spatialdb = 'bbox4spatialdb = 'wirelesslondon
    5utm_zone = '31' 5utm_zone = '31' 
    6srid = '32631' 6srid = '32631' 
  • docs/docs.css

    Revision 51 Revision 210
    1body { 1body { 
    2    background-image:url(bbox_small.png); 2    background-image:url(bbox_small.png); 
    3    background-repeat:no-repeat; 3    background-repeat:no-repeat; 
    4    font-family: Arial,Helvetica,Sans; 4    font-family: Arial,Helvetica,Sans; 
    5    font-size: 90%; 5    font-size: 90%; 
    6    margin-left:132px; 6    margin-left:132px; 
    7    margin-top: 20px; 7    margin-top: 20px; 
      8    width: 600px; 
      9} 
      10a:link { 
      11    color: #9dc146; 
      12} 
      13a:visited { 
      14    color: #487f2f; 
    8} 15} 
    9.note { 16.note { 
    10    border-width:1; 17    border-width:1; 
    11    border-style:solid; 18    border-style:solid; 
    12    padding: 5px; 19    padding: 5px; 
    13} 20} 
    14ul { 21ul { 
    15    list-style: square; 22    list-style: square; 
    16} 23} 
    17ul.internal { 24ul.internal { 
    18    list-style: none; 25    list-style: none; 
    19} 26} 
      27 
      28span.caption {  
      29    background: #ccffcc; 
      30    font-family:"Comic Sans MS"; 
      31} 
  • freemap/osm.map

    Revision 104 Revision 210
    1map 1map 
    2    extent -1973283.56 5434082.43 1542684.32 8155631.45 2    extent -1973283.56 5434082.43 1542684.32 8155631.45 
    3    size         600 480         3    size         600 480         
    4    imagetype   jpeg 4    imagetype   jpeg 
    5    shapepath   "/home/wirelesslondon/etc/mapdata/"     5    shapepath   "/home/wirelesslondon/etc/mapdata/"     
    6    fontset     "fonts.txt" 6    fontset     "fonts.txt" 
    7    imagecolor 128 128 128 7    imagecolor 128 128 128 
    8    projection  "proj=utm" "zone=31" end 8    projection  "proj=utm" "zone=31" end 
    9    #projection "proj=latlong" end 9    #projection "proj=latlong" end 
    10    web 10    web 
    11        template    "wl.html" 11        template    "wl.html" 
    12        imagepath   "/home/wirelesslondon/docs/tmp/" 12        imagepath   "/home/wirelesslondon/docs/tmp/" 
    13        imageurl    "/tmp/" 13        imageurl    "/tmp/" 
    14 14 
    15        metadata 15        metadata 
    16            "wfs_title" "london free map - data from openstreetmap.org" 16            "wfs_title" "london free map - data from openstreetmap.org" 
    17            "wfs_onlineresource" "http://map.wirelesslondon.info/map/wfs.cgi?service=WFS" 17            "wfs_onlineresource" "http://map.wirelesslondon.info/map/wfs.cgi?service=WFS" 
    18            "wfs_srs" "EPSG:32631" 18            "wfs_srs" "EPSG:32631" 
    19        end 19        end 
    20 20 
    21    end 21    end 
    22 22 
    23    symbol 23    symbol 
    24        name    "solid" 24        name    "solid" 
    25        type    ellipse 25        type    ellipse 
    26        points  1 1 end 26        points  1 1 end 
    27        filled  true     27        filled  true     
    28    end 28    end 
    29     29     
    30    symbol 30    symbol 
    31        name "dashed"  31        name "dashed"  
    32        type ellipse  32        type ellipse  
    33        filled true  33        filled true  
    34        points 1 1 end 34        points 1 1 end 
    35        style 3 3 end  35        style 3 3 end  
    36    end 36    end 
    37 37 
    38 38 
    39    SYMBOL 39    SYMBOL 
    40       NAME "ppoint" 40       NAME "ppoint" 
    41       TYPE TRUETYPE 41       TYPE TRUETYPE 
    42       FONT webdings 42       FONT webdings 
    43       FILLED true 43       FILLED true 
    44       ANTIALIAS true 44       ANTIALIAS true 
    45       CHARACTER "" 45       CHARACTER "" 
    46    END 46    END 
    47        layer 47        layer 
    48      name "landsat7" 48      name "landsat7" 
    49      type raster 49      type raster 
    50      group satellite 50      group satellite 
    51      status default 51      status default 
    52      connection "http://wms.jpl.nasa.gov/wms.cgi?" 52      connection "http://wms.jpl.nasa.gov/wms.cgi?" 
    53      projection "init=epsg:4326" end 53      projection "init=epsg:4326" end 
    54      connectiontype wms 54      connectiontype wms 
    55      METADATA 55      METADATA 
    56        "wms_srs"             "EPSG:4326" 56        "wms_srs"             "EPSG:4326" 
    57        "wms_name"            "global_mosaic" 57        "wms_name"            "global_mosaic" 
    58        "wms_server_version"  "1.1.0" 58        "wms_server_version"  "1.1.0" 
    59        "wms_format"          "image/png" 59        "wms_format"          "image/png" 
    60        "wms_style"           "visual" 60        "wms_style"           "visual" 
    61      END 61      END 
    62    END 62    END 
    63 63 
    64    layer 64    layer 
    65        name    "landsat" 65        name    "landsat" 
    66        projection "proj=utm" "zone=31" end 66        projection "proj=utm" "zone=31" end 
    67        status  default  67        status  default  
    68        data    "london.tif" 68        data    "london.tif" 
    69        type    raster 69        type    raster 
    70    end 70    end 
    71 71 
    72    #layer 72    #layer 
    73#       name    "nodes" 73#       name    "nodes" 
    74#       projection "proj=utm" "zone=31" end 74#       projection "proj=utm" "zone=31" end 
    75#       status default   75#       status default   
    76# 76# 
    77#       connectiontype  postgis 77#       connectiontype  postgis 
    78#       connection      dbname=wirelesslondon 78#       connection      dbname=wirelesslondon 
    79#       data            "geom from nodes" 79#       data            "geom from nodes" 
    80#       filter          "rdf_type = 'http://xmlns.com/2003/wireless/Node'" 80#       filter          "rdf_type = 'http://xmlns.com/2003/wireless/Node'" 
    81#       type            point 81#       type            point 
    82# 82# 
    83#       labelitem       "name" 83#       labelitem       "name" 
    84#       class 84#       class 
    85#           template "[node]" 85#           template "[node]" 
    86#           color   128 255 128  86#           color   128 255 128  
    87#           outlinecolor 32 32 32 87#           outlinecolor 32 32 32 
    88#           symbol  "solid" 88#           symbol  "solid" 
    89#           size    8 89#           size    8 
    90#           label 90#           label 
    91 #               color 128 255 128  91 #               color 128 255 128  
    92#                outlinecolor 32 32 32 92#                outlinecolor 32 32 32 
    93#               position ur 93#               position ur 
    94#               angle auto 94#               angle auto 
    95#               antialias true 95#               antialias true 
    96#               type truetype 96#               type truetype 
    97#               font Arial_Bold  97#               font Arial_Bold  
    98#               size 10 98#               size 10 
    99#           end 99#           end 
    100#       end 100#       end 
    101#       tolerance 50 101#       tolerance 50 
    102 #   end 102 #   end 
    103# 103# 
    104 104 
    105 105 
    106    layer  106    layer  
    107        name "nearbies" 107        name "nearbies" 
    108        projection "proj=utm" "zone=31" end 108        projection "proj=utm" "zone=31" end 
    109        status  on 109        status  on 
    110 110 
    111        connectiontype  postgis 111        connectiontype  postgis 
    112        connection      dbname=wirelesslondon 112        connection      dbname=wirelesslondon 
    113        data            "geom from nodes" 113        data            "geom from nodes" 
    114        filter          "rdf_type = 'http://xmlns.com/wordnet/1.6/Message'" 114        filter          "rdf_type = 'http://xmlns.com/wordnet/1.6/Message'" 
    115        type            point 115        type            point 
    116 116 
    117        labelitem       "name" 117        labelitem       "name" 
    118        class 118        class 
    119            color   255 128 0 119            color   255 128 0 
    120            outlinecolor 32 32 32 120            outlinecolor 32 32 32 
    121            symbol  "solid" 121            symbol  "solid" 
    122            size    8 122            size    8 
    123            label 123            label 
    124                color 255 128 0 124                color 255 128 0 
    125                outlinecolor 32 32 32 125                outlinecolor 32 32 32 
    126                position ur 126                position ur 
    127                angle auto 127                angle auto 
    128                antialias true 128                antialias true 
    129                type truetype 129                type truetype 
    130                font Arial_Bold 130                font Arial_Bold 
    131                size 10 131                size 10 
    132            end 132            end 
    133        end 133        end 
    134    end 134    end 
    135     135     
    136         layer 136         layer 
    137        name    "a_road" 137        name    "a_road" 
    138        metadata 138        metadata 
    139            "wfs_title" "roads" 139            "wfs_title" "roads" 
    140        end 140        end 
    141        dump TRUE # needed for wfs to work 141        dump TRUE # needed for wfs to work 
    142        projection "proj=utm" "zone=31" end 142        projection "proj=utm" "zone=31" end 
    143        #projection "proj=latlong" end 143        #projection "proj=latlong" end 
    144        status  default 144        status  default 
    145 145 
    146        connectiontype  postgis 146        connectiontype  postgis 
    147        connection      dbname=wirelesslondon 147        connection      dbname=wirelesslondon 
    148        data            "geom from roadseg" 148        data            "geom from roadseg" 
    149        type            line