Beispiel #1
0
 def make_from_rss_feed_data(rssFeedData):
     rssFeed = Kotoba(rssFeedData)
     rssItems = rssFeed.get("item")
     rssFeeds = Feeds()
     for item in rssItems:
         title = item.get('title').data()
         link = item.get('link').data()
         description = item.get('description').data()
         comments = item.get('comments').data()
         publishedDate = item.get('pubDate').data()
         rssFeeds.append(RSSFeed(title, link, description, comments, publishedDate))
     rssFeeds.sort()
     rssFeeds.reverse()
     return rssFeeds
Beispiel #2
0
def setup(configuration_filename=None, use_tori_custom_error_page=False, support_unicode=True, enable_compression=False, auto_config=False, additional_config=None):
    """
    Set up the environment
    
    `configuration_filename` is the name of the configuration file in XML. By
    default, it is null and instruct the system to use the default settings.
    
    `use_tori_custome_error_page` is a flag to tell whether the application
    process should use the nicer custom error page. Please note that enabling
    this feature will slightly decrease performance. This is a known issue
    for CherryPy 3.1+.
    
    `support_unicode` is a flag to tell whether the application process should
    support unicode. Please note that enabling this feature will slightly decrease performance.
    
    `enable_compression` is a flag to tell whether the application process
    should compress the output. Please note that enabling this feature will
    decrease performance and possibly mess up JavaScript. This feature is
    disabled by default when the X/HTML document contains **pre** elements.
    Use with caution.
    
    `auto_config` is a flag to tell whether the application process
    should create a configuration file (named by `configuration_filename`)
    automatically if not existed. When the function detect that the configuration
    file doesn't exist, with this flag enabled, it will create the configuration
    file with the default configuration. Then, it will terminated the process.
    This gives the developers an opportunity to config the settings before proceeding.
    
    `additional_config` is a configuration dictionary for CherryPy 3.1+. It is
    for adding some additional configuration directly to CherryPy which is the
    underlying framework. Please note that this will override any configuration
    from the configuration file.
    """
    
    global mode
    global base_uri
    global base_path
    global path
    global error_template
    global static_routing
    global settings
    global template
    global debug
    
    # Initialization
    __base_config_key = 'tools.static'
    mode = 'local'
    port = 8080
    base_uri = ''
    base_path = ''
    path = {}
    error_template = None
    static_routing = {}
    default_config = {
        'global': {
            'server.thread_pool':       10,
            'server.socket_queue_size': 10,
            'server.socket_host':       '0.0.0.0',
            'server.socket_port':       port,
            'tools.decode.encoding':    'utf-8',
            'tools.encode.encoding':    'utf-8',
            'tools.decode.on':          support_unicode,
            'tools.encode.on':          support_unicode,
            'tools.gzip.on':            enable_compression,
            'log.screen':               False                          # Disable trackback information
        }
    }
    
    if use_tori_custom_error_page:
        # Use the custom error response from Tori
        default_config['global']['error_page.default'] = DefaultErrorPage.response
    
    settings = {}
    standard_config = """<?xml version="1.0" encoding="UTF-8"?>
    <webconfig>
        <mode>local</mode>
        <rendering>mako</rendering>
        <base_path>
            <static>static</static>
            <template>template</template>
            <session>memory</session>
        </base_path>
        <!--
        <port>8080</port>
        -->
        <base_uri>/</base_uri>
        <static_routing>
        <!--
            <file link="favicon.ico" ref="favicon.ico" />
            <dir link="image" ref="image" />
            <dir link="css" ref="css" />
            <dir link="js" ref="js" />
        -->
        </static_routing>
        <settings>
            <option name="debug">false</option>
            <option name="text_minification">false</option>
            <option name="no_cache">true</option>
        </settings>
    </webconfig>
    """
    
    # Get the reference to the calling function
    f = sys._getframe(1)
    c = f.f_code
    reference_to_caller = c.co_filename
    
    # Base path
    base_path = os.path.abspath(os.path.dirname(os.path.abspath(reference_to_caller)))
    
    # Get the location of the given the configuration files
    target_destination = configuration_filename
    if not re.search('^/', configuration_filename):
        target_destination = "%s/%s" % (base_path, configuration_filename)
    
    try:
        # Load the configuration files
        xmldoc = Kotoba()
        xmldoc.read(target_destination)
    except:
        if auto_config:
            fs.write(target_destination, standard_config, "w")
            xmldoc = Kotoba(target_destination)
        else:
            raise WebFrameworkException("Error while reading configuration from %s" % target_destination)
    
    try:
        # Get operational mode
        xml_on_mode = xmldoc.get("mode")
        if len(xml_on_mode) > 0:
            mode = xml_on_mode.data()
    except:
        raise WebFrameworkException("Error while determining the running mode")
    
    try:
        # Get operational port. This will be ignored in GAE mode
        xml_on_port = xmldoc.get("port")
        if len(xml_on_port) > 0:
            port = base.convertToInteger(xml_on_port.data())
            default_config['global']['server.socket_port'] = port
    except:
        raise WebFrameworkException("Error while determining the running port")
    
    try:
        # Store the basic paths in the memory. Make the directory for the destination if necessary.
        path_indices = xmldoc.get('base_path *')
        for path_index in path_indices:
            pathName = path_index.name
            path[pathName] = os.path.join(base_path, path_index.data())
            make_directory_if_not_existed(path[pathName])
    except:
        raise WebFrameworkException("Error while setting up the directories")
    
    try:
        # Get application settings
        xml_on_settings = xmldoc.get("settings option")
        if xml_on_settings:
            for option in xml_on_settings:
                option_data = option.data()
                
                option_data_as_floating_number = base.convertToFloatingNumber(option_data)
                option_data_as_integer = base.convertToInteger(option_data)
                option_data_as_boolean = base.convertToBoolean(option_data)
                
                if re.match("^\d+(\.\d+)?$", option_data):
                    if option_data_as_floating_number is not None:
                        # the option data is integer-convertible.
                        option_data = option_data_as_floating_number
                    elif option_data_as_integer is not None:
                        # the option data is integer-convertible.
                        option_data = option_data_as_integer
                elif option_data_as_boolean is not None:
                    # the option data is boolean-convertible.
                    option_data = option_data_as_boolean
                
                settings[option.attrs['name']] = option_data
        
        # Recognized options by framework (with the default value)
        recognized_options = {
            'debug': True,
            'no_cache': True,
            'direct_rendering': True,
            'text_minification': False
        }
        
        for recognized_option, default_option in recognized_options.iteritems():
            if recognized_option not in settings:
                settings[recognized_option] = default_option
        
        if 'debug' in settings:
            debug = settings['debug']
    except:
        raise WebFrameworkException("Error while reading anonymous settings for this application")
    
    try:
        # Get the base URI
        base_uri = xmldoc.get('base_uri').data()
        base_uri = base_uri.strip()
        base_uri = re.sub("^/", "", base_uri)
        base_uri = re.sub("/$", "", base_uri)
        
        static_routing[base_uri + '/'] = {
            'tools.caching.on':             True,
            'tools.caching.cache_class':    cherrypy.lib.caching.MemoryCache,
            'tools.caching.delay':          259200, # 3 days
            'tools.caching.maxobjsize':     26214400, # 25 MB
            'tools.caching.maxsize':        104857600, # 100 MB
            'tools.sessions.on':            True,
            'tools.sessions.timeout':       10,
            'tools.sessions.storage_type':  'file',
            'tools.sessions.storage_path':  path['session']
        }
        
        default_config['global']['tools.staticdir.root'] = path['static']
        default_config['global']['tools.staticfile.root'] = path['static']
        
        if settings['no_cache']:
            doc_root_settings = static_routing[base_uri + '/']
            doc_root_settings['tools.caching.on'] = False
        
        if mode == ServiceMode.GAE:
            doc_root_settings = static_routing[base_uri + '/']
            doc_root_settings['tools.caching.on'] = False
            del doc_root_settings['tools.sessions.storage_type']
            del doc_root_settings['tools.sessions.storage_path']
        
        xmldocOnstatic_routing = xmldoc.get('static_routing file, static_routing dir')
        
        for referenceSetting in xmldocOnstatic_routing:
            __type = referenceSetting.name
            __ref = referenceSetting.attrs['ref']
            __link = referenceSetting.attrs['link']
            __cBaseKey = "%s%s" % (__base_config_key, __type)
            __cKeyFlag = "%s.on" % (__cBaseKey)
            __cKeyPath = "%s.%s" % (__cBaseKey, __type)
            
            if __type == 'file' and __ref is not None:
                __cKeyPath += 'name'
                #__ref = os.path.join(path['static'], __ref)
            
            if __type == 'dir':
                make_directory_if_not_existed(os.path.join(path['static'], __ref))
            
            static_routing[base_uri + '/' + __link] = {
                str(__cKeyFlag): True,
                str(__cKeyPath): __ref
            }
        
        items_in_static = fs.browse(path['static'])
        for item_type in items_in_static:
            for item in items_in_static[item_type]:
                if item[0] == ".": continue
                __type = item_type == "files" and "file" or "dir"
                __ref = item
                __link = item
                
                __route_address = '%s/%s' % (base_uri, __link)
                if __route_address in static_routing:
                    continue
                
                __cBaseKey = "%s%s" % (__base_config_key, __type)
                __cKeyFlag = "%s.on" % (__cBaseKey)
                __cKeyPath = "%s.%s" % (__cBaseKey, __type)
                
                if __type == 'file' and __ref is not None:
                    __cKeyPath += 'name'
                
                if __type == 'dir':
                    make_directory_if_not_existed(os.path.join(path['static'], __ref))
                
                static_routing[__route_address] = {
                    str(__cKeyFlag): True,
                    str(__cKeyPath): __ref
                }
    
    except:
        raise WebFrameworkException("Error while setting up routing")
    
    try:
        # Determine the template system
        xml_on_rendering = xmldoc.get("rendering")
        if xml_on_rendering:
            template['use'] = xml_on_rendering.data()
        else:
            template['use'] = 'mako'
        
        if template['use'] == 'tenjin':
            enable_caching = not settings['no_cache']
            if enable_caching:
                enable_caching = MemoryCacheStorage()
            template['tenjin']['engine'] = Engine(
                path=[path['template']],
                cache = enable_caching
            )
        else:
            template_filesystem_checks = settings['no_cache']
            if mode == ServiceMode.GAE:
                template['mako']['engine'] = TemplateLookup(
                    directories = [path['template']],
                    filesystem_checks=template_filesystem_checks,
                    **template['mako']['options']
                )
            else:
                template['mako']['engine'] = TemplateLookup(
                    directories = [path['template']],
                    module_directory=os.path.join(path['session'], 'cache', 'template'), # disable for GAE apps
                    filesystem_checks=template_filesystem_checks,
                    **template['mako']['options']
                )
            template['mako']['get'] = template['mako']['engine'].get_template
    except:
        raise WebFrameworkException("Error while setting up the template system")
    
    try:
        # Add custom error pages
        xml_on_error_template = xmldoc.get('error_template')
        if xml_on_error_template:
            error_template = xml_on_error_template.data()
            error_template = fs.read(os.path.join(path['template'], error_template))
    except:
        raise WebFrameworkException("Error while setting up a custom error error page.")
    
    
    cherrypy.config.update(default_config)
    
    if additional_config is not None:
        cherrypy.config.update(additional_config)