/venus

To download this project, use:
bzr branch http://golem.ph.utexas.edu/~distler/code/venus/

« back to all changes in this revision

Viewing changes to planet/vendor/feedparser.py

  • Committer: Sam Ruby
  • Date: 2008-08-11 12:17:17 UTC
  • mfrom: (86.1.1 venus)
  • Revision ID: rubys@intertwingly.net-20080811121717-9bpq6zq0tg267oz5
Add test case

Show diffs side-by-side

added added

removed removed

397
397
                  'http://freshmeat.net/rss/fm/':                         'fm',
398
398
                  'http://xmlns.com/foaf/0.1/':                           'foaf',
399
399
                  'http://www.w3.org/2003/01/geo/wgs84_pos#':             'geo',
 
400
                  'http://www.georss.org/georss':                         'georss',
 
401
                  'http://www.opengis.net/gml':                           'gml',
400
402
                  'http://postneo.com/icbm/':                             'icbm',
401
403
                  'http://purl.org/rss/1.0/modules/image/':               'image',
402
404
                  'http://www.itunes.com/DTDs/PodCast-1.0.dtd':           'itunes',
456
458
        self.incontributor = 0
457
459
        self.inpublisher = 0
458
460
        self.insource = 0
 
461
        
 
462
        # georss
 
463
        self.ingeometry = 0
 
464
        
459
465
        self.sourcedata = FeedParserDict()
460
466
        self.contentparams = FeedParserDict()
461
467
        self._summaryKey = None
1269
1275
    def _end_expirationdate(self):
1270
1276
        self._save('expired_parsed', _parse_date(self.pop('expired')))
1271
1277
 
 
1278
    # geospatial location, or "where", from georss.org
 
1279
 
 
1280
    def _start_georssgeom(self, attrsD):
 
1281
        self.push('geometry', 0)
 
1282
    _start_georss_point = _start_georssgeom
 
1283
    _start_georss_line = _start_georssgeom
 
1284
    _start_georss_polygon = _start_georssgeom
 
1285
    _start_georss_box = _start_georssgeom
 
1286
 
 
1287
    def _save_where(self, geometry):
 
1288
        context = self._getContext()
 
1289
        context.setdefault('where', {})
 
1290
        context['where'] = FeedParserDict(geometry)
 
1291
 
 
1292
    def _end_georss_point(self):
 
1293
        geometry = _parse_georss_point(self.pop('geometry'))
 
1294
        self._save_where(geometry)
 
1295
 
 
1296
    def _end_georss_line(self):
 
1297
        geometry = _parse_georss_line(self.pop('geometry'))
 
1298
        self._save_where(geometry)
 
1299
    
 
1300
    def _end_georss_polygon(self):
 
1301
        this = self.pop('geometry')
 
1302
        geometry = _parse_georss_polygon(this)
 
1303
        self._save_where(geometry)
 
1304
 
 
1305
    def _end_georss_box(self):
 
1306
        geometry = _parse_georss_box(self.pop('geometry'))
 
1307
        self._save_where(geometry)
 
1308
 
 
1309
    def _start_where(self, attrsD):
 
1310
        self.push('where', 0)
 
1311
    _start_georss_where = _start_where
 
1312
 
 
1313
    def _start_gml_point(self, attrsD):
 
1314
        self.ingeometry = 'point'
 
1315
        self.push('geometry', 0)
 
1316
 
 
1317
    def _start_gml_linestring(self, attrsD):
 
1318
        self.ingeometry = 'linestring'
 
1319
        self.push('geometry', 0)
 
1320
 
 
1321
    def _start_gml_polygon(self, attrsD):
 
1322
        self.push('geometry', 0)
 
1323
 
 
1324
    def _start_gml_exterior(self, attrsD):
 
1325
        self.push('geometry', 0)
 
1326
 
 
1327
    def _start_gml_linearring(self, attrsD):
 
1328
        self.ingeometry = 'polygon'
 
1329
        self.push('geometry', 0)
 
1330
 
 
1331
    def _start_gml_pos(self, attrsD):
 
1332
        self.push('pos', 0)
 
1333
 
 
1334
    def _end_gml_pos(self):
 
1335
        this = self.pop('pos')
 
1336
        geometry = _parse_georss_point(this)
 
1337
        self._save_where(geometry)
 
1338
 
 
1339
    def _start_gml_poslist(self, attrsD):
 
1340
        self.push('pos', 0)
 
1341
 
 
1342
    def _end_gml_poslist(self):
 
1343
        geometry = _parse_poslist(self.pop('pos'), self.ingeometry)
 
1344
        self._save_where(geometry)
 
1345
 
 
1346
    def _end_geom(self):
 
1347
        self.ingeometry = 0
 
1348
        self.pop('geometry')
 
1349
    _end_gml_point = _end_geom
 
1350
    _end_gml_linestring = _end_geom
 
1351
    _end_gml_linearring = _end_geom
 
1352
    _end_gml_exterior = _end_geom
 
1353
    _end_gml_polygon = _end_geom
 
1354
 
 
1355
    def _end_where(self):
 
1356
        self.pop('where')
 
1357
    _end_georss_where = _end_where
 
1358
 
 
1359
    # end geospatial
 
1360
 
1272
1361
    def _start_cc_license(self, attrsD):
1273
1362
        context = self._getContext()
1274
1363
        value = self._getAttribute(attrsD, 'rdf:resource')
3336
3425
    data = doctype_pattern.sub(replacement, head) + data
3337
3426
 
3338
3427
    return version, data, dict(replacement and safe_pattern.findall(replacement))
3339
 
    
 
3428
 
 
3429
# GeoRSS geometry parsers. Each return a dict with 'type' and 'coordinates'
 
3430
# keys, or None in the case of a parsing error
 
3431
 
 
3432
def _parse_poslist(value, geom_type):
 
3433
    if geom_type == 'linestring':
 
3434
        return _parse_georss_line(value)
 
3435
    elif geom_type == 'polygon':
 
3436
        ring = _parse_georss_line(value)
 
3437
        return {'type': 'Polygon', 'coordinates': (ring['coordinates'],)}
 
3438
    else:
 
3439
        raise ValueError, "unsupported geometry type: %s" % geom_type
 
3440
 
 
3441
# Point coordinates are a 2-tuple (lon, lat)
 
3442
def _parse_georss_point(value):
 
3443
    try:
 
3444
        lat, lon = value.replace(',', ' ').split()
 
3445
        return {'type': 'Point', 'coordinates': (float(lon), float(lat))}
 
3446
    except Exception, e:
 
3447
        if _debug:
 
3448
            sys.stderr.write('_parse_georss_point raised %s\n' % (handler.__name__, repr(e)))
 
3449
        pass
 
3450
    return None
 
3451
 
 
3452
# Line coordinates are a tuple of 2-tuples ((lon0, lat0), ... (lonN, latN))
 
3453
def _parse_georss_line(value):
 
3454
    try:
 
3455
        latlons = value.replace(',', ' ').split()
 
3456
        coords = []
 
3457
        for i in range(0, len(latlons), 2):
 
3458
            lat = float(latlons[i])
 
3459
            lon = float(latlons[i+1])
 
3460
            coords.append((lon, lat))
 
3461
        return {'type': 'LineString', 'coordinates': tuple(coords)}
 
3462
    except Exception, e:
 
3463
        if _debug:
 
3464
            sys.stderr.write('_parse_georss_line raised %s\n' % repr(e))
 
3465
        pass
 
3466
    return None
 
3467
 
 
3468
# Polygon coordinates are a tuple of closed LineString tuples. The first item
 
3469
# in the tuple is the exterior ring. Subsequent items are interior rings, but
 
3470
# georss:polygon elements usually have no interior rings.
 
3471
def _parse_georss_polygon(value):
 
3472
    try:
 
3473
        latlons = value.replace(',', ' ').split()
 
3474
        coords = []
 
3475
        for i in range(0, len(latlons), 2):
 
3476
            lat = float(latlons[i])
 
3477
            lon = float(latlons[i+1])
 
3478
            coords.append((lon, lat))
 
3479
        return {'type': 'Polygon', 'coordinates': (tuple(coords),)}
 
3480
    except Exception, e:
 
3481
        if _debug:
 
3482
            sys.stderr.write('_parse_georss_polygon raised %s\n' % repr(e))
 
3483
        pass
 
3484
    return None
 
3485
 
 
3486
# Box coordinates are a 2-tuple of 2-tuples ((lon_ll, lat_ll), (lon_ur, lat_ur))
 
3487
def _parse_georss_box(value):
 
3488
    try:
 
3489
        vals = [float(x) for x in value.replace(',', ' ').split()]
 
3490
        return {'type': 'Box', 'coordinates': ((vals[1], vals[0]), (vals[3], vals[2]))}
 
3491
    except Exception, e:
 
3492
        if _debug:
 
3493
            sys.stderr.write('_parse_georss_box raised %s\n' % repr(e))
 
3494
        pass
 
3495
    return None
 
3496
 
 
3497
# end geospatial parsers
 
3498
 
3340
3499
def parse(url_file_stream_or_string, etag=None, modified=None, agent=None, referrer=None, handlers=[]):
3341
3500
    '''Parse a feed from a URL, file, stream, or string'''
3342
3501
    result = FeedParserDict()