Exemplo n.º 1
0
 def action_edit(self):
     if not self.section.path_params or len(self.section.path_params) != 1:
         raise Exception('NotFound')
     message = ''
     theme = self.get_theme(self.section.path_params[0])
     if self.section.handler.request.get('submit'):
         new_namespace = self.section.handler.request.get('namespace')
         if not new_namespace:
             message = '<div class="status error">Namespace is required</div>'
         elif new_namespace != theme.namespace and new_namespace in self.theme_namespaces:
             message = '<div class="status error">%s is already a custom theme namespace</div>' % new_namespace
         elif new_namespace != theme.namespace and is_local_theme_namespace(
                 new_namespace):
             message = '<div class="status error">"%s" is a local theme namespace</div>' % new_namespace
         elif new_namespace != theme.namespace:
             for t in theme.body_template_names:
                 section.rename_theme_namespace_template(
                     theme.namespace + '/' + t, new_namespace + '/' + t)
             self.theme_namespaces[self.theme_namespaces.index(
                 theme.namespace)] = new_namespace
             self.update()
             theme.namespace = new_namespace
             theme.put()
             cache.flush_all(
             )  # Flush all cached resources for this theme which is important for sections where it is active
             raise Exception('Redirect', self.section.action_redirect_path)
         else:
             raise Exception('Redirect', self.section.action_redirect_path)
     f = form(self.section, self.section.full_path)
     f.add_control(
         control(self.section, 'text', 'namespace', theme.namespace))
     f.add_control(control(self.section, 'submit', 'submit', 'Submit'))
     return '%s<h2>Edit namespace</h2>%s' % (message, unicode(f))
Exemplo n.º 2
0
 def action_edit(self):
     if not self.section.path_params or len(self.section.path_params) != 1:
         raise Exception('NotFound')
     message = ''
     theme = self.get_theme(self.section.path_params[0])
     if self.section.handler.request.get('submit'):
         new_namespace = self.section.handler.request.get('namespace')
         if not new_namespace:
             message = '<div class="status error">Namespace is required</div>'
         elif new_namespace != theme.namespace and new_namespace in self.theme_namespaces:
             message = '<div class="status error">%s is already a custom theme namespace</div>' % new_namespace
         elif new_namespace != theme.namespace and is_local_theme_namespace(new_namespace):
             message = '<div class="status error">"%s" is a local theme namespace</div>' % new_namespace
         elif new_namespace != theme.namespace:
             for t in theme.body_template_names:
                 section.rename_theme_namespace_template(theme.namespace + '/' + t, new_namespace + '/' + t)
             self.theme_namespaces[self.theme_namespaces.index(theme.namespace)] = new_namespace
             self.update()
             theme.namespace = new_namespace
             theme.put()
             cache.flush_all() # Flush all cached resources for this theme which is important for sections where it is active
             raise Exception('Redirect', self.section.action_redirect_path)
         else:
             raise Exception('Redirect', self.section.action_redirect_path)
     f = form(self.section, self.section.full_path)
     f.add_control(control(self.section, 'text', 'namespace', theme.namespace))
     f.add_control(control(self.section, 'submit', 'submit', 'Submit'))
     return '%s<h2>Edit namespace</h2>%s' % (message, unicode(f))
Exemplo n.º 3
0
 def import_compressed_theme_data(self, data):
     compressed = zipfile.ZipFile(StringIO(data), 'r')
     paths = compressed.namelist()
     namespaces = []
     main_dir = None
     for nl in paths:
         if nl.count('/') == 2:
             main_dir, nl, _ = nl.split('/')
             namespaces.append(nl)
     if not namespaces:
         raise Exception('No namespaces indentified')
     else:
         messages = []
         for namespace in namespaces:
             i = 2
             suffix = ''
             while is_local_theme_namespace(namespace + suffix):
                 suffix = ' ' + str(i)
                 i += 1
             while namespace + suffix in self.theme_namespaces:
                 suffix = ' ' + str(i)
                 i += 1
             calculated_namespace = namespace + suffix
             theme = Theme(namespace=calculated_namespace)
             for p in paths:
                 if p.startswith(main_dir + '/' + namespace + '/templates/') and p.endswith('.body'):
                     filename = p.split(main_dir + '/' + namespace + '/templates/')[1][:-5]
                     theme.body_template_names.append(filename)
                     theme.body_template_contents.append(validated_body_template(zipfile.ZipFile.read(compressed, p)))
                 elif p.startswith(main_dir + '/' + namespace + '/css/') and p.endswith('.css'):
                     filename = p.split(main_dir + '/' + namespace + '/css/')[1]
                     theme.css_filenames.append(filename)
                     theme.css_contents.append(zipfile.ZipFile.read(compressed, p))
                 elif p.startswith(main_dir + '/' + namespace + '/js/') and p.endswith('.js'):
                     filename = p.split(main_dir + '/' + namespace + '/js/')[1]
                     theme.js_filenames.append(filename)
                     theme.js_contents.append(zipfile.ZipFile.read(compressed, p))
                 elif p.startswith(main_dir + '/' + namespace + '/images/') and p != main_dir + '/' + namespace + '/images/':
                     filename = p.split(main_dir + '/' + namespace + '/images/')[1]
                     content_type, _ = mimetypes.guess_type(filename)
                     data = zipfile.ZipFile.read(compressed, p)
                     handle = files.blobstore.create(mime_type=content_type, _blobinfo_uploaded_filename=filename)
                     with files.open(handle, 'a') as f: f.write(data)
                     files.finalize(handle)
                     key = files.blobstore.get_blob_key(handle)
                     theme.image_filenames.append(filename)
                     theme.image_keys.append(key)
             key = theme.put()
             self.theme_keys.append(key)
             self.theme_namespaces.append(calculated_namespace)
             self.update()
             if messages: raise Exception(messages)
Exemplo n.º 4
0
 def import_compressed_theme_data(self, data):
     compressed = zipfile.ZipFile(StringIO(data), 'r')
     paths = compressed.namelist()
     namespaces = []
     main_dir = None
     for nl in paths:
         if nl.count('/') == 2:
             main_dir, nl, _ = nl.split('/')
             namespaces.append(nl)
     if not namespaces:
         raise Exception('No namespaces indentified')
     else:
         messages = []
         for namespace in namespaces:
             i = 2
             suffix = ''
             while is_local_theme_namespace(namespace + suffix):
                 suffix = ' ' + str(i)
                 i += 1
             while namespace + suffix in self.theme_namespaces:
                 suffix = ' ' + str(i)
                 i += 1
             calculated_namespace = namespace + suffix
             theme = Theme(namespace=calculated_namespace)
             for p in paths:
                 if p.startswith(main_dir + '/' + namespace + '/templates/') and p.endswith('.body'):
                     filename = p.split(main_dir + '/' + namespace + '/templates/')[1][:-5]
                     theme.body_template_names.append(filename)
                     theme.body_template_contents.append(validated_body_template(db.Text(zipfile.ZipFile.read(compressed, p))))
                 elif p.startswith(main_dir + '/' + namespace + '/css/') and p.endswith('.css'):
                     filename = p.split(main_dir + '/' + namespace + '/css/')[1]
                     theme.css_filenames.append(filename)
                     theme.css_contents.append(db.Text(zipfile.ZipFile.read(compressed, p)))
                 elif p.startswith(main_dir + '/' + namespace + '/js/') and p.endswith('.js'):
                     filename = p.split(main_dir + '/' + namespace + '/js/')[1]
                     theme.js_filenames.append(filename)
                     theme.js_contents.append(db.Text(zipfile.ZipFile.read(compressed, p)))
                 elif p.startswith(main_dir + '/' + namespace + '/images/') and p != main_dir + '/' + namespace + '/images/':
                     filename = p.split(main_dir + '/' + namespace + '/images/')[1]
                     content_type, _ = mimetypes.guess_type(filename)
                     data = db.Blob(zipfile.ZipFile.read(compressed, p))
                     key = File(filename=filename, data=data, content_type=content_type, section_path=self.section.path).put()
                     theme.image_filenames.append(filename)
                     theme.image_keys.append(str(key))
             key = theme.put()
             self.theme_keys.append(str(key))
             self.theme_namespaces.append(calculated_namespace)
             self.update()
             if messages: raise Exception(messages)
Exemplo n.º 5
0
 def action_add(self):
     message = ''
     if self.section.handler.request.get('submit'):
         namespace = self.section.handler.request.get('namespace').replace('/', '')
         if not namespace:
             message = '<div class="status error">Namespace is required</div>'
         elif namespace in self.theme_namespaces:
             message = '<div class="status error">Namespace "%s" already exists</div>' % namespace
         elif is_local_theme_namespace(namespace):
             message = '<div class="status error">Namespace "%s" is already a local theme namespace</div>' % namespace
         else:
             key = Theme(namespace=namespace).put()
             self.theme_keys.append(key)
             self.theme_namespaces.append(namespace)
             self.update()
             raise Exception('Redirect', self.section.action_redirect_path)
     f = form(self.section, self.section.full_path)
     f.add_control(control(self.section, 'text', 'namespace', '', 'Namespace'))
     f.add_control(control(self.section, 'submit', 'submit', 'Submit'))
     return '%s<h2>Add theme</h2>%s' % (message, unicode(f))
Exemplo n.º 6
0
 def action_add(self):
     message = ''
     if self.section.handler.request.get('submit'):
         namespace = self.section.handler.request.get('namespace').replace(
             '/', '')
         if not namespace:
             message = '<div class="status error">Namespace is required</div>'
         elif namespace in self.theme_namespaces:
             message = '<div class="status error">Namespace "%s" already exists</div>' % namespace
         elif is_local_theme_namespace(namespace):
             message = '<div class="status error">Namespace "%s" is already a local theme namespace</div>' % namespace
         else:
             key = Theme(namespace=namespace).put()
             self.theme_keys.append(key)
             self.theme_namespaces.append(namespace)
             self.update()
             raise Exception('Redirect', self.section.action_redirect_path)
     f = form(self.section, self.section.full_path)
     f.add_control(
         control(self.section, 'text', 'namespace', '', 'Namespace'))
     f.add_control(control(self.section, 'submit', 'submit', 'Submit'))
     return '%s<h2>Add theme</h2>%s' % (message, unicode(f))
Exemplo n.º 7
0
    def get(self, path):     
        try:
            path = path.strip('/')
            path, extension = os.path.splitext(path)

            contents = cache.get(path + extension)
            last_modified = cache.get(CACHE_LAST_MODIFIED_PREPEND + path + extension)

            if not contents:
                contents = ''

                ''' YUI '''
                yui_parts = '' if path.find('___yui___') < 0 else path[path.find('___yui___'):].replace('___yui___', '', 1)
                yui_parts = yui_parts if yui_parts.find('___') < 0 else yui_parts[:yui_parts.find('___')]
                rest_parts = path.replace('___yui___', '', 1).replace(yui_parts, '', 1).replace('___local___', '', 1)
                if '___theme___' in rest_parts:
                    local_parts, theme_parts = rest_parts.split('___theme___')
                else:
                    local_parts, theme_parts = rest_parts, None
                if yui_parts:
                    yui_version = '3.7.2/build/'
                    yui_absolute = 'http://yui.yahooapis.com/combo?'
                    yui_parts = yui_parts.split('__')
                    yui_parts = [(yui_version + x.replace('_', '/') + '-min' + extension) for x in yui_parts]
                    result = urlfetch.fetch(yui_absolute + '&'.join(yui_parts))
                    if result.status_code == 200:
                        contents += result.content
                    else:
                        raise Exception('NotFound')

                ''' Local '''
                filenames = [(x + extension) for x in local_parts.split('_')]
                if len(filenames) != len(utils.unique_list(filenames)):
                    raise Exception('NotFound')
                files = utils.file_search(filenames)
                if extension == '.css':
                    contents += (''.join([parse_content(open(f, 'r').read(), True) for f in files]))
                else:
                    contents += (''.join([parse_content(open(f, 'r').read()) for f in files]))

                ''' Theme '''
                if theme_parts:
                    theme_namespace, theme_parts = theme_parts.split('___')
                    filenames = [(x + extension) for x in theme_parts.split('_')]
                    if len(filenames) != len(utils.unique_list(filenames)):
                        raise Exception('NotFound')
                    elif is_local_theme_namespace(theme_namespace):
                        if extension == '.css':
                            contents += (''.join([parse_content(open('./themes/' + theme_namespace + '/' + extension.strip('.') + '/' + f, 'r').read(), True, theme_namespace) for f in filenames]))
                        else:
                            contents += (''.join([parse_content(open('./themes/' + theme_namespace + '/' + extension.strip('.') + '/' + f, 'r').read(), False, theme_namespace) for f in filenames]))
                    else:
                        t = get_custom_theme(theme_namespace)
                        for f in filenames:
                            if extension == '.css':
                                index = t.css_filenames.index(f)
                                contents += parse_content(t.css_contents[index], True, theme_namespace)
                            elif extension == '.js':
                                index = t.js_filenames.index(f)
                                contents += parse_content(t.js_contents[index], False, theme_namespace)

                cache.set(path + extension, contents)
                last_modified = datetime.utcnow()
                cache.set(CACHE_LAST_MODIFIED_PREPEND + path + extension, last_modified)

            if not contents.strip(): raise Exception('NotFound')

            if not last_modified:
                last_modified = datetime.utcnow()
                cache.set(CACHE_LAST_MODIFIED_PREPEND + path + extension, last_modified)

            content_type = 'application/javascript' if extension == '.js' else 'text/css'
            response = webapp2.Response(template.get(contents.strip()), content_type=content_type)
            response.headers['Connection'] = 'Keep-Alive'
            response.headers['Date'] = datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S GMT")
            response.headers['Last-Modified'] = last_modified.strftime("%a, %d %b %Y %H:%M:%S GMT")
            response.headers['Expires'] = (last_modified + timedelta(8)).strftime("%a, %d %b %Y %H:%M:%S GMT")
            response.cache_control.no_cache = None
            response.cache_control.public = True
            response.cache_control.max_age = 604800000 # One week
            return response
        except Exception as inst:
            message = ''
            if configuration.debug_mode():
                message = '<div class="status error">' + unicode(inst) + '<br><br>' + traceback.format_exc().replace('\n', '<br><br>') + '</div>'
            response = webapp2.Response(template.get('<html><head><title>404 Not Found</title></head><body><h1>404 Not Found</h1>Document or file requested by the client was not found.%s</body></html>' % message))
            response.set_status(404)
            return response
Exemplo n.º 8
0
 def import_compressed_theme_data(self, data):
     compressed = zipfile.ZipFile(StringIO(data), 'r')
     paths = compressed.namelist()
     namespaces = []
     main_dir = None
     for nl in paths:
         if nl.count('/') == 2:
             main_dir, nl, _ = nl.split('/')
             namespaces.append(nl)
     if not namespaces:
         raise Exception('No namespaces indentified')
     else:
         messages = []
         for namespace in namespaces:
             i = 2
             suffix = ''
             while is_local_theme_namespace(namespace + suffix):
                 suffix = ' ' + str(i)
                 i += 1
             while namespace + suffix in self.theme_namespaces:
                 suffix = ' ' + str(i)
                 i += 1
             calculated_namespace = namespace + suffix
             theme = Theme(namespace=calculated_namespace)
             for p in paths:
                 if p.startswith(main_dir + '/' + namespace +
                                 '/templates/') and p.endswith('.body'):
                     filename = p.split(main_dir + '/' + namespace +
                                        '/templates/')[1][:-5]
                     theme.body_template_names.append(filename)
                     theme.body_template_contents.append(
                         validated_body_template(
                             zipfile.ZipFile.read(compressed, p)))
                 elif p.startswith(main_dir + '/' + namespace +
                                   '/css/') and p.endswith('.css'):
                     filename = p.split(main_dir + '/' + namespace +
                                        '/css/')[1]
                     theme.css_filenames.append(filename)
                     theme.css_contents.append(
                         zipfile.ZipFile.read(compressed, p))
                 elif p.startswith(main_dir + '/' + namespace +
                                   '/js/') and p.endswith('.js'):
                     filename = p.split(main_dir + '/' + namespace +
                                        '/js/')[1]
                     theme.js_filenames.append(filename)
                     theme.js_contents.append(
                         zipfile.ZipFile.read(compressed, p))
                 elif p.startswith(
                         main_dir + '/' + namespace + '/images/'
                 ) and p != main_dir + '/' + namespace + '/images/':
                     filename = p.split(main_dir + '/' + namespace +
                                        '/images/')[1]
                     content_type, _ = mimetypes.guess_type(filename)
                     data = zipfile.ZipFile.read(compressed, p)
                     handle = files.blobstore.create(
                         mime_type=content_type,
                         _blobinfo_uploaded_filename=filename)
                     with files.open(handle, 'a') as f:
                         f.write(data)
                     files.finalize(handle)
                     key = files.blobstore.get_blob_key(handle)
                     theme.image_filenames.append(filename)
                     theme.image_keys.append(key)
             key = theme.put()
             self.theme_keys.append(key)
             self.theme_namespaces.append(calculated_namespace)
             self.update()
             if messages: raise Exception(messages)
Exemplo n.º 9
0
    def get(self, path):
        try:
            path = path.strip('/')
            path, extension = os.path.splitext(path)

            contents = cache.get(path + extension)
            last_modified = cache.get(CACHE_LAST_MODIFIED_PREPEND + path +
                                      extension)

            if not contents:
                contents = ''
                ''' YUI '''
                yui_parts = '' if path.find('___yui___') < 0 else path[
                    path.find('___yui___'):].replace('___yui___', '', 1)
                yui_parts = yui_parts if yui_parts.find(
                    '___') < 0 else yui_parts[:yui_parts.find('___')]
                rest_parts = path.replace('___yui___', '', 1).replace(
                    yui_parts, '', 1).replace('___local___', '', 1)
                if '___theme___' in rest_parts:
                    local_parts, theme_parts = rest_parts.split('___theme___')
                else:
                    local_parts, theme_parts = rest_parts, None
                if yui_parts:
                    yui_version = '3.7.2/build/'
                    yui_absolute = 'http://yui.yahooapis.com/combo?'
                    yui_parts = yui_parts.split('__')
                    yui_parts = [(yui_version + x.replace('_', '/') + '-min' +
                                  extension) for x in yui_parts]
                    result = urlfetch.fetch(yui_absolute + '&'.join(yui_parts))
                    if result.status_code == 200:
                        contents += result.content
                    else:
                        raise Exception('NotFound')
                ''' Local '''
                filenames = [(x + extension) for x in local_parts.split('_')]
                if len(filenames) != len(utils.unique_list(filenames)):
                    raise Exception('NotFound')
                files = utils.file_search(filenames)
                if extension == '.css':
                    contents += (''.join([
                        parse_content(open(f, 'r').read(), True) for f in files
                    ]))
                else:
                    contents += (''.join(
                        [parse_content(open(f, 'r').read()) for f in files]))
                ''' Theme '''
                if theme_parts:
                    theme_namespace, theme_parts = theme_parts.split('___')
                    filenames = [(x + extension)
                                 for x in theme_parts.split('_')]
                    if len(filenames) != len(utils.unique_list(filenames)):
                        raise Exception('NotFound')
                    elif is_local_theme_namespace(theme_namespace):
                        if extension == '.css':
                            contents += (''.join([
                                parse_content(
                                    open(
                                        './themes/' + theme_namespace + '/' +
                                        extension.strip('.') + '/' + f,
                                        'r').read(), True, theme_namespace)
                                for f in filenames
                            ]))
                        else:
                            contents += (''.join([
                                parse_content(
                                    open(
                                        './themes/' + theme_namespace + '/' +
                                        extension.strip('.') + '/' + f,
                                        'r').read(), False, theme_namespace)
                                for f in filenames
                            ]))
                    else:
                        t = get_custom_theme(theme_namespace)
                        for f in filenames:
                            if extension == '.css':
                                index = t.css_filenames.index(f)
                                contents += parse_content(
                                    t.css_contents[index], True,
                                    theme_namespace)
                            elif extension == '.js':
                                index = t.js_filenames.index(f)
                                contents += parse_content(
                                    t.js_contents[index], False,
                                    theme_namespace)

                cache.set(path + extension, contents)
                last_modified = datetime.utcnow()
                cache.set(CACHE_LAST_MODIFIED_PREPEND + path + extension,
                          last_modified)

            if not contents.strip(): raise Exception('NotFound')

            if not last_modified:
                last_modified = datetime.utcnow()
                cache.set(CACHE_LAST_MODIFIED_PREPEND + path + extension,
                          last_modified)

            content_type = 'application/javascript' if extension == '.js' else 'text/css'
            response = webapp2.Response(template.get(contents.strip()),
                                        content_type=content_type)
            response.headers['Connection'] = 'Keep-Alive'
            response.headers['Date'] = datetime.utcnow().strftime(
                "%a, %d %b %Y %H:%M:%S GMT")
            response.headers['Last-Modified'] = last_modified.strftime(
                "%a, %d %b %Y %H:%M:%S GMT")
            response.headers['Expires'] = (
                last_modified +
                timedelta(8)).strftime("%a, %d %b %Y %H:%M:%S GMT")
            response.cache_control.no_cache = None
            response.cache_control.public = True
            response.cache_control.max_age = 604800000  # One week
            return response
        except Exception as inst:
            message = ''
            if configuration.debug_mode():
                message = '<div class="status error">' + unicode(
                    inst) + '<br><br>' + traceback.format_exc().replace(
                        '\n', '<br><br>') + '</div>'
            response = webapp2.Response(
                template.get(
                    '<html><head><title>404 Not Found</title></head><body><h1>404 Not Found</h1>Document or file requested by the client was not found.%s</body></html>'
                    % message))
            response.set_status(404)
            return response