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',
1269
1275
def _end_expirationdate(self):
1270
1276
self._save('expired_parsed', _parse_date(self.pop('expired')))
1278
# geospatial location, or "where", from georss.org
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
1287
def _save_where(self, geometry):
1288
context = self._getContext()
1289
context.setdefault('where', {})
1290
context['where'] = FeedParserDict(geometry)
1292
def _end_georss_point(self):
1293
geometry = _parse_georss_point(self.pop('geometry'))
1294
self._save_where(geometry)
1296
def _end_georss_line(self):
1297
geometry = _parse_georss_line(self.pop('geometry'))
1298
self._save_where(geometry)
1300
def _end_georss_polygon(self):
1301
this = self.pop('geometry')
1302
geometry = _parse_georss_polygon(this)
1303
self._save_where(geometry)
1305
def _end_georss_box(self):
1306
geometry = _parse_georss_box(self.pop('geometry'))
1307
self._save_where(geometry)
1309
def _start_where(self, attrsD):
1310
self.push('where', 0)
1311
_start_georss_where = _start_where
1313
def _start_gml_point(self, attrsD):
1314
self.ingeometry = 'point'
1315
self.push('geometry', 0)
1317
def _start_gml_linestring(self, attrsD):
1318
self.ingeometry = 'linestring'
1319
self.push('geometry', 0)
1321
def _start_gml_polygon(self, attrsD):
1322
self.push('geometry', 0)
1324
def _start_gml_exterior(self, attrsD):
1325
self.push('geometry', 0)
1327
def _start_gml_linearring(self, attrsD):
1328
self.ingeometry = 'polygon'
1329
self.push('geometry', 0)
1331
def _start_gml_pos(self, attrsD):
1334
def _end_gml_pos(self):
1335
this = self.pop('pos')
1336
geometry = _parse_georss_point(this)
1337
self._save_where(geometry)
1339
def _start_gml_poslist(self, attrsD):
1342
def _end_gml_poslist(self):
1343
geometry = _parse_poslist(self.pop('pos'), self.ingeometry)
1344
self._save_where(geometry)
1346
def _end_geom(self):
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
1355
def _end_where(self):
1357
_end_georss_where = _end_where
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
3338
3427
return version, data, dict(replacement and safe_pattern.findall(replacement))
3429
# GeoRSS geometry parsers. Each return a dict with 'type' and 'coordinates'
3430
# keys, or None in the case of a parsing error
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'],)}
3439
raise ValueError, "unsupported geometry type: %s" % geom_type
3441
# Point coordinates are a 2-tuple (lon, lat)
3442
def _parse_georss_point(value):
3444
lat, lon = value.replace(',', ' ').split()
3445
return {'type': 'Point', 'coordinates': (float(lon), float(lat))}
3446
except Exception, e:
3448
sys.stderr.write('_parse_georss_point raised %s\n' % (handler.__name__, repr(e)))
3452
# Line coordinates are a tuple of 2-tuples ((lon0, lat0), ... (lonN, latN))
3453
def _parse_georss_line(value):
3455
latlons = value.replace(',', ' ').split()
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:
3464
sys.stderr.write('_parse_georss_line raised %s\n' % repr(e))
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):
3473
latlons = value.replace(',', ' ').split()
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:
3482
sys.stderr.write('_parse_georss_polygon raised %s\n' % repr(e))
3486
# Box coordinates are a 2-tuple of 2-tuples ((lon_ll, lat_ll), (lon_ur, lat_ur))
3487
def _parse_georss_box(value):
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:
3493
sys.stderr.write('_parse_georss_box raised %s\n' % repr(e))
3497
# end geospatial parsers
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()