NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

atom.py (8445B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\werkzeug\contrib\atom.py
      2 from datetime import datetime
      3 from werkzeug.utils import escape
      4 from werkzeug.wrappers import BaseResponse
      5 XHTML_NAMESPACE = 'http://www.w3.org/1999/xhtml'
      6 
      7 def _make_text_block(name, content, content_type = None):
      8     if content_type == 'xhtml':
      9         return u'<%s type="xhtml"><div xmlns="%s">%s</div></%s>\n' % (name,
     10          XHTML_NAMESPACE,
     11          content,
     12          name)
     13     if not content_type:
     14         return u'<%s>%s</%s>\n' % (name, escape(content), name)
     15     return u'<%s type="%s">%s</%s>\n' % (name,
     16      content_type,
     17      escape(content),
     18      name)
     19 
     20 
     21 def format_iso8601(obj):
     22     return obj.strftime('%Y-%m-%dT%H:%M:%SZ')
     23 
     24 
     25 class AtomFeed(object):
     26     default_generator = ('Werkzeug', None, None)
     27 
     28     def __init__(self, title = None, entries = None, **kwargs):
     29         self.title = title
     30         self.title_type = kwargs.get('title_type', 'text')
     31         self.url = kwargs.get('url')
     32         self.feed_url = kwargs.get('feed_url', self.url)
     33         self.id = kwargs.get('id', self.feed_url)
     34         self.updated = kwargs.get('updated')
     35         self.author = kwargs.get('author', ())
     36         self.icon = kwargs.get('icon')
     37         self.logo = kwargs.get('logo')
     38         self.rights = kwargs.get('rights')
     39         self.rights_type = kwargs.get('rights_type')
     40         self.subtitle = kwargs.get('subtitle')
     41         self.subtitle_type = kwargs.get('subtitle_type', 'text')
     42         self.generator = kwargs.get('generator')
     43         if self.generator is None:
     44             self.generator = self.default_generator
     45         self.links = kwargs.get('links', [])
     46         self.entries = entries and list(entries) or []
     47         if not hasattr(self.author, '__iter__') or isinstance(self.author, (basestring, dict)):
     48             self.author = [self.author]
     49         for i, author in enumerate(self.author):
     50             if not isinstance(author, dict):
     51                 self.author[i] = {'name': author}
     52 
     53         if not self.title:
     54             raise ValueError('title is required')
     55         if not self.id:
     56             raise ValueError('id is required')
     57         for author in self.author:
     58             if 'name' not in author:
     59                 raise TypeError('author must contain at least a name')
     60 
     61     def add(self, *args, **kwargs):
     62         if len(args) == 1 and not kwargs and isinstance(args[0], FeedEntry):
     63             self.entries.append(args[0])
     64         else:
     65             kwargs['feed_url'] = self.feed_url
     66             self.entries.append(FeedEntry(*args, **kwargs))
     67 
     68     def __repr__(self):
     69         return '<%s %r (%d entries)>' % (self.__class__.__name__, self.title, len(self.entries))
     70 
     71     def generate(self):
     72         if not self.author:
     73             if False in map(lambda e: bool(e.author), self.entries):
     74                 self.author = ({'name': u'unbekannter Autor'},)
     75         if not self.updated:
     76             dates = sorted([ entry.updated for entry in self.entries ])
     77             self.updated = dates and dates[-1] or datetime.utcnow()
     78         yield u'<?xml version="1.0" encoding="utf-8"?>\n'
     79         yield u'<feed xmlns="http://www.w3.org/2005/Atom">\n'
     80         yield '  ' + _make_text_block('title', self.title, self.title_type)
     81         yield u'  <id>%s</id>\n' % escape(self.id)
     82         yield u'  <updated>%s</updated>\n' % format_iso8601(self.updated)
     83         if self.url:
     84             yield u'  <link href="%s" />\n' % escape(self.url, True)
     85         if self.feed_url:
     86             yield u'  <link href="%s" rel="self" />\n' % escape(self.feed_url, True)
     87         for link in self.links:
     88             yield u'  <link %s/>\n' % ''.join(('%s="%s" ' % (k, escape(link[k], True)) for k in link))
     89 
     90         for author in self.author:
     91             yield u'  <author>\n'
     92             yield u'    <name>%s</name>\n' % escape(author['name'])
     93             if 'uri' in author:
     94                 yield u'    <uri>%s</uri>\n' % escape(author['uri'])
     95             if 'email' in author:
     96                 yield '    <email>%s</email>\n' % escape(author['email'])
     97             yield '  </author>\n'
     98 
     99         if self.subtitle:
    100             yield '  ' + _make_text_block('subtitle', self.subtitle, self.subtitle_type)
    101         if self.icon:
    102             yield u'  <icon>%s</icon>\n' % escape(self.icon)
    103         if self.logo:
    104             yield u'  <logo>%s</logo>\n' % escape(self.logo)
    105         if self.rights:
    106             yield '  ' + _make_text_block('rights', self.rights, self.rights_type)
    107         generator_name, generator_url, generator_version = self.generator
    108         if generator_name or generator_url or generator_version:
    109             tmp = [u'  <generator']
    110             if generator_url:
    111                 tmp.append(u' uri="%s"' % escape(generator_url, True))
    112             if generator_version:
    113                 tmp.append(u' version="%s"' % escape(generator_version, True))
    114             tmp.append(u'>%s</generator>\n' % escape(generator_name))
    115             yield u''.join(tmp)
    116         for entry in self.entries:
    117             for line in entry.generate():
    118                 yield u'  ' + line
    119 
    120         yield u'</feed>\n'
    121 
    122     def to_string(self):
    123         return u''.join(self.generate())
    124 
    125     def get_response(self):
    126         return BaseResponse(self.to_string(), mimetype='application/atom+xml')
    127 
    128     def __call__(self, environ, start_response):
    129         return self.get_response()(environ, start_response)
    130 
    131     def __unicode__(self):
    132         return self.to_string()
    133 
    134     def __str__(self):
    135         return self.to_string().encode('utf-8')
    136 
    137 
    138 class FeedEntry(object):
    139 
    140     def __init__(self, title = None, content = None, feed_url = None, **kwargs):
    141         self.title = title
    142         self.title_type = kwargs.get('title_type', 'text')
    143         self.content = content
    144         self.content_type = kwargs.get('content_type', 'html')
    145         self.url = kwargs.get('url')
    146         self.id = kwargs.get('id', self.url)
    147         self.updated = kwargs.get('updated')
    148         self.summary = kwargs.get('summary')
    149         self.summary_type = kwargs.get('summary_type', 'html')
    150         self.author = kwargs.get('author')
    151         self.published = kwargs.get('published')
    152         self.rights = kwargs.get('rights')
    153         self.links = kwargs.get('links', [])
    154         self.xml_base = kwargs.get('xml_base', feed_url)
    155         if not hasattr(self.author, '__iter__') or isinstance(self.author, (basestring, dict)):
    156             self.author = [self.author]
    157         for i, author in enumerate(self.author):
    158             if not isinstance(author, dict):
    159                 self.author[i] = {'name': author}
    160 
    161         if not self.title:
    162             raise ValueError('title is required')
    163         if not self.id:
    164             raise ValueError('id is required')
    165         if not self.updated:
    166             raise ValueError('updated is required')
    167 
    168     def __repr__(self):
    169         return '<%s %r>' % (self.__class__.__name__, self.title)
    170 
    171     def generate(self):
    172         base = ''
    173         if self.xml_base:
    174             base = ' xml:base="%s"' % escape(self.xml_base, True)
    175         yield u'<entry%s>\n' % base
    176         yield u'  ' + _make_text_block('title', self.title, self.title_type)
    177         yield u'  <id>%s</id>\n' % escape(self.id)
    178         yield u'  <updated>%s</updated>\n' % format_iso8601(self.updated)
    179         if self.published:
    180             yield u'  <published>%s</published>\n' % format_iso8601(self.published)
    181         if self.url:
    182             yield u'  <link href="%s" />\n' % escape(self.url)
    183         for author in self.author:
    184             yield u'  <author>\n'
    185             yield u'    <name>%s</name>\n' % escape(author['name'])
    186             if 'uri' in author:
    187                 yield u'    <uri>%s</uri>\n' % escape(author['uri'])
    188             if 'email' in author:
    189                 yield u'    <email>%s</email>\n' % escape(author['email'])
    190             yield u'  </author>\n'
    191 
    192         for link in self.links:
    193             yield u'  <link %s/>\n' % ''.join(('%s="%s" ' % (k, escape(link[k], True)) for k in link))
    194 
    195         if self.summary:
    196             yield u'  ' + _make_text_block('summary', self.summary, self.summary_type)
    197         if self.content:
    198             yield u'  ' + _make_text_block('content', self.content, self.content_type)
    199         yield u'</entry>\n'
    200 
    201     def to_string(self):
    202         return u''.join(self.generate())
    203 
    204     def __unicode__(self):
    205         return self.to_string()
    206 
    207     def __str__(self):
    208         return self.to_string().encode('utf-8')