Ejemplo n.º 1
0
 def testAvailableThemes(self):
     """ Check that the ThemeController says we have the themes we expect to have. """
     
     tc = ThemeController()
     names_ref = ['barebones', 'circles', 'floaty', 'fruitsalad']
     names_tc = tc.get_theme_names()
     self.assertEqual(set(names_ref), set(names_tc))
Ejemplo n.º 2
0
def landing(request):
    context = {}
    tc = ThemeController()
    context['theme_name'] = tc.get_current_theme()
    context['last_customization_name'] = Tag.getTag('prev_theme_customization',
                                                    default='None')
    return render_to_response('themes/landing.html', request, context)
Ejemplo n.º 3
0
    def testAvailableThemes(self):
        """ Check that the ThemeController says we have the themes we expect to have. """

        tc = ThemeController()
        names_ref = ['barebones', 'circles', 'floaty', 'fruitsalad']
        names_tc = tc.get_theme_names()
        self.assertEqual(set(names_ref), set(names_tc))
Ejemplo n.º 4
0
    def testAvailableThemes(self):
        """ Check that the ThemeController says we have the themes we expect to have. """

        tc = ThemeController()
        names_ref = ['generic1', 'generic2', 'chicago', 'mit']
        names_tc = tc.get_theme_names()
        self.assertEqual(set(names_ref), set(names_tc))
Ejemplo n.º 5
0
def landing(request):
    if settings.LOCAL_THEME:
        raise ESPError(THEME_ERROR_STRING, log=False)
    context = {}
    tc = ThemeController()
    context['theme_name'] = tc.get_current_theme()
    context['last_customization_name'] = tc.get_current_customization()
    return render_to_response('themes/landing.html', request, context)
Ejemplo n.º 6
0
 def load_from_tag(cls, theme_name=None, just_selected=False):
     data = json.loads(Tag.getTag('theme_template_control', default='{}'))
     if theme_name is None:
         tc = ThemeController()
         theme_name = tc.get_current_theme()
     data['theme'] = theme_name
     form_temp = cls(initial=data)
     data = form_temp.recover_from_serialization(data)
     data['just_selected'] = just_selected
     form = cls(initial=data)
     return form
Ejemplo n.º 7
0
 def load_from_tag(cls, theme_name=None, just_selected=False):
     data = json.loads(Tag.getTag('theme_template_control', default='{}'))
     if theme_name is None:
         tc = ThemeController()
         theme_name = tc.get_current_theme()
     data['theme'] = theme_name
     form_temp = cls(initial=data)
     data = form_temp.recover_from_serialization(data)
     data['just_selected'] = just_selected
     form = cls(initial=data)
     return form
Ejemplo n.º 8
0
def get_nav_category(path):
    tc = ThemeController()
    settings = tc.get_template_settings()
                #   Search for current nav category based on request path
    first_level = ''.join(path.lstrip('/').split('/')[:1])
    for category in settings['nav_structure']:
        if category['header_link'].lstrip('/').startswith(first_level):
            return category
    #   Search failed - use default nav category
    default_nav_category = 'learn'
    for category in settings['nav_structure']:
        if category['header_link'].lstrip('/').startswith(default_nav_category):
            return category
Ejemplo n.º 9
0
def get_nav_category(path):
    tc = ThemeController()
    settings = tc.get_template_settings()
    #   Search for current nav category based on request path
    first_level = ''.join(path.lstrip('/').split('/')[:1])
    for category in settings['nav_structure']:
        if category['header_link'].lstrip('/').startswith(first_level):
            return category
    #   Search failed - use default nav category
    default_nav_category = 'learn'
    for category in settings['nav_structure']:
        if category['header_link'].lstrip('/').startswith(
                default_nav_category):
            return category
Ejemplo n.º 10
0
 def testEditor(self):
     """ Check that the theme editor backend functionality is working. """
     
     """
     TODO:
     -   Check that theme specific properties show up on the form
     -   Check load, save, delete modes as well as test
     """
     
     #   Log in as administrator and load the theme editor
     self.client.login(username=self.admin.username, password='******')
     response = self.client.get('/themes/customize/')
     self.assertEqual(response.status_code, 200)
     
     #   Check that the "advanced" properties for all themes show up in the form
     #   (using ThemeController directly for theme switching, since testSelector()
     #   covers the Web interface)
     tc = ThemeController()
     theme_names = tc.get_theme_names()
     for theme_name in theme_names:
         variables_filename = os.path.join(settings.MEDIA_ROOT, 'esp', 'themes', 'theme_data', theme_name, 'variables.less')
         if os.path.exists(variables_filename):
             tc.clear_theme()
             tc.load_theme(theme_name)
             response = self.client.get('/themes/customize/')
             self.assertEqual(response.status_code, 200)
             variables = re.findall(r'@(\S+):\s+?(\S+);', open(variables_filename).read())
             for (varname, value) in variables:
                 self.assertTrue(len(re.findall(r'<input.*?name="%s".*?value="%s".*?>', response.content, flags=re.I)) > 0)
     
     #   Test that we can change a parameter and the right value appears in the stylesheet
     def verify_linkcolor(color_str):
         css_filename = os.path.join(settings.MEDIA_ROOT, 'styles', themes_settings.COMPILED_CSS_FILE)
         regexp = r'\n\s*?a\s*?{.*?color:\s*?%s;.*?}' % color_str
         self.assertTrue(len(re.findall(regexp, open(css_filename).read(), flags=(re.DOTALL | re.I))) == 1)
         
     color_str1 = '#%06X' % random.randint(0, 1 << 24)
     config_dict = {'apply': True, 'linkColor': color_str1}
     response = self.client.post('/themes/customize/', config_dict)
     self.assertEqual(response.status_code, 200)
     verify_linkcolor(color_str1)
     
     #   Test that we can save this setting, change it and re-load
     config_dict = {'save': True, 'linkColor': color_str1, 'saveThemeName': 'save_test'}
     response = self.client.post('/themes/customize/', config_dict)
     self.assertEqual(response.status_code, 200)
     
     color_str2 = '#%06X' % random.randint(0, 1 << 24)
     config_dict = {'apply': True, 'linkColor': color_str2}
     response = self.client.post('/themes/customize/', config_dict)
     self.assertEqual(response.status_code, 200)
     verify_linkcolor(color_str2)
     
     config_dict = {'load': True, 'loadThemeName': 'save_test'}
     response = self.client.post('/themes/customize/', config_dict)
     self.assertEqual(response.status_code, 200)
     verify_linkcolor(color_str1)
     
     #   We're done.  Log out.
     self.client.logout()
Ejemplo n.º 11
0
def extract_theme(url):
    #   Get the appropriate color scheme out of the Tag that controls nav structure
    #   (specific to MIT theme)
    tab_index = 0
    tc = ThemeController()
    settings = tc.get_template_settings()
    max_chars_matched = 0
    for category in settings['nav_structure']:
        num_chars_matched = count_matching_chars(url, category['header_link'])
        if num_chars_matched > max_chars_matched:
            max_chars_matched = num_chars_matched
            tab_index = 0
        i = 1
        for item in category['links']:
            num_chars_matched = count_matching_chars(url, item['link'])
            if num_chars_matched > max_chars_matched:
                max_chars_matched = num_chars_matched
                tab_index = i
            i += 1
    return 'tabcolor%d' % tab_index
Ejemplo n.º 12
0
def extract_theme(url):
    #   Get the appropriate color scheme out of the Tag that controls nav structure
    #   (specific to MIT theme)
    tab_index = 0
    tc = ThemeController()
    settings = tc.get_template_settings()
    max_chars_matched = 0
    for category in settings['nav_structure']:
        num_chars_matched = count_matching_chars(url, category['header_link'])
        if num_chars_matched > max_chars_matched:
            max_chars_matched = num_chars_matched
            tab_index = 0
        i = 1
        for item in category['links']:
            num_chars_matched = count_matching_chars(url, item['link'])
            if num_chars_matched > max_chars_matched:
                max_chars_matched = num_chars_matched
                tab_index = i
            i += 1
    return 'tabcolor%d' % tab_index
Ejemplo n.º 13
0
def extract_theme(str):
    #   Get the appropriate color scheme out of the Tag that controls nav structure
    #   (specific to MIT theme)
    tab_index = 0
    tc = ThemeController()
    settings = tc.get_template_settings()
    for category in settings['nav_structure']:
        if category['header_link'][:5] == str[:5]:
            i = 1
            for item in category['links']:
                if str == item['link']:
                    tab_index = i
                    break
                path_current = os.path.dirname(str)
                path_tab = os.path.dirname(item['link'])
                if len(path_current) > len(
                        path_tab) and path_current.startswith(path_tab):
                    tab_index = i
                    break
                i += 1
    return 'tabcolor%d' % tab_index
Ejemplo n.º 14
0
def confirm_overwrite(request, current_theme=None, differences=None, orig_view=None):
    """ Display a form asking the user which local modified files
        they would like to keep, and which they would like to overwrite
        with the ones from the theme data.  """

    if settings.LOCAL_THEME:
        raise ESPError(THEME_ERROR_STRING, log=False)

    context = {}
    tc = ThemeController()

    if current_theme is None:
        current_theme = request.POST.get('theme', '')

    if request.method == 'POST' and request.POST.get('confirm_overwrite', '0') == '1':
        files_to_keep = []
        diffs_current = tc.check_local_modifications(current_theme)

        #   Build a list of filenames that we are not supposed to overwrite.
        for entry in diffs_current:
            post_key = 'overwrite_%s' % entry['filename_hash']
            post_val = request.POST.get(post_key, None)
            if post_val is not None:
                if post_val != 'overwrite':
                    files_to_keep.append(entry['filename'])

        #   Continue with the original view (typically the theme selector).
        view_func = selector
        if request.POST.get('orig_view', '') == 'recompile':
            view_func = recompile
        return view_func(request, keep_files=files_to_keep)

    #   Display the form asking the user which files to keep/overwrite.
    if differences is None:
        differences = tc.check_local_modifications(current_theme)

    context['theme_name'] = current_theme
    context['differences'] = differences
    context['orig_view'] = orig_view
    return render_to_response('themes/confirm_overwrite.html', request, context)
Ejemplo n.º 15
0
    def testEditor(self):
        """ Check that the theme editor backend functionality is working. """

        """
        TODO:
        -   Check that theme specific properties show up on the form
        -   Check load, save, delete modes as well as test
        """

        #   Log in as administrator and load the theme editor
        self.client.login(username=self.admin.username, password='******')
        response = self.client.get('/themes/customize/')
        self.assertEqual(response.status_code, 200)

        #   Check that the "advanced" properties for all themes show up in the form
        #   (using ThemeController directly for theme switching, since testSelector()
        #   covers the Web interface)
        tc = ThemeController()
        theme_names = tc.get_theme_names()
        for theme_name in theme_names:
            variables_filename = os.path.join(settings.MEDIA_ROOT, 'esp', 'themes', 'theme_data', theme_name, 'variables.less')
            if os.path.exists(variables_filename):
                tc.clear_theme()
                tc.load_theme(theme_name)
                response = self.client.get('/themes/customize/')
                self.assertEqual(response.status_code, 200)
                variables = re.findall(r'@(\S+):\s+?(\S+);', open(variables_filename).read())
                for (varname, value) in variables:
                    self.assertTrue(len(re.findall(r'<input.*?name="%s".*?value="%s".*?>', response.content, flags=re.I)) > 0)

        #   Test that we can change a parameter and the right value appears in the stylesheet
        def verify_linkcolor(color_str):
            css_filename = os.path.join(settings.MEDIA_ROOT, 'styles', themes_settings.COMPILED_CSS_FILE)
            regexp = r'\n\s*?a\s*?{.*?color:\s*?%s;.*?}' % color_str
            self.assertTrue(len(re.findall(regexp, open(css_filename).read(), flags=(re.DOTALL | re.I))) == 1)

        color_str1 = '#%06X' % random.randint(0, 1 << 24)
        config_dict = {'apply': True, 'linkColor': color_str1}
        response = self.client.post('/themes/customize/', config_dict)
        self.assertEqual(response.status_code, 200)
        verify_linkcolor(color_str1)

        #   Test that we can save this setting, change it and re-load
        config_dict = {'save': True, 'linkColor': color_str1, 'saveThemeName': 'save_test'}
        response = self.client.post('/themes/customize/', config_dict)
        self.assertEqual(response.status_code, 200)

        color_str2 = '#%06X' % random.randint(0, 1 << 24)
        config_dict = {'apply': True, 'linkColor': color_str2}
        response = self.client.post('/themes/customize/', config_dict)
        self.assertEqual(response.status_code, 200)
        verify_linkcolor(color_str2)

        config_dict = {'load': True, 'loadThemeName': 'save_test'}
        response = self.client.post('/themes/customize/', config_dict)
        self.assertEqual(response.status_code, 200)
        verify_linkcolor(color_str1)

        #   We're done.  Log out.
        self.client.logout()
Ejemplo n.º 16
0
def render_to_response(template,
                       request,
                       context,
                       prog=None,
                       auto_per_program_templates=True,
                       mimetype=None,
                       use_request_context=True):
    from esp.web.views.navBar import makeNavBar

    if isinstance(template, (basestring, )):
        template = [template]

    if isinstance(prog, (list, tuple)) and auto_per_program_templates:
        template = [_per_program_template_name(prog[0], t)
                    for t in template] + template

    section = request.path.split('/')[1]
    tc = ThemeController()
    context['theme'] = tc.get_template_settings()
    context['settings'] = settings

    # create nav bar list
    if not context.has_key('navbar_list'):
        category = None
        if context.has_key('nav_category'):
            category = context['nav_category']
        context['navbar_list'] = makeNavBar(section, category)

    if not use_request_context:
        context['request'] = request
        response = django.shortcuts.render_to_response(template,
                                                       context,
                                                       mimetype=mimetype)
        return response
    else:
        return render_response(request, template, context, mimetype=mimetype)
Ejemplo n.º 17
0
def render_to_response(template, request, context, content_type=None, use_request_context=True):
    from esp.web.views.navBar import makeNavBar

    if isinstance(template, (basestring,)):
        template = [ template ]

    section = request.path.split('/')[1]
    tc = ThemeController()
    context['theme'] = tc.get_template_settings()
    context['settings'] = settings

    # create nav bar list
    if not 'navbar_list' in context:
        category = None
        if 'nav_category' in context:
            category = context['nav_category']
        context['navbar_list'] = makeNavBar(section, category, path=request.path[1:])

    if not use_request_context:
        context['request'] = request
        response = django.shortcuts.render_to_response(template, context, content_type=content_type)
        return response
    else:
        return render_response(request, template, context, content_type=content_type)
Ejemplo n.º 18
0
def recompile(request, keep_files=None):
    if settings.LOCAL_THEME:
        raise ESPError(THEME_ERROR_STRING, log=False)

    tc = ThemeController()

    #   Check for differences between the theme's files and those in the working copy.
    #   If there are differences, require a confirmation from the user for each file.
    theme_name = tc.get_current_theme()
    differences = tc.check_local_modifications(theme_name)
    if len(differences) > 0 and keep_files is None:
        return confirm_overwrite(request, current_theme=theme_name, differences=differences, orig_view='recompile')

    tc.recompile_theme(keep_files=keep_files)
    return HttpResponseRedirect('/themes/')
Ejemplo n.º 19
0
def landing(request):
    context = {}
    tc = ThemeController()
    context['theme_name'] = tc.get_current_theme()
    context['last_customization_name'] = tc.get_current_customization()
    return render_to_response('themes/landing.html', request, context)
Ejemplo n.º 20
0
 def save_to_tag(self):
     tc = ThemeController()
     data = self.prepare_for_serialization(self.cleaned_data.copy())
     tc.set_template_settings(data)
Ejemplo n.º 21
0
def selector(request, keep_files=None):
    if settings.LOCAL_THEME:
        raise ESPError(THEME_ERROR_STRING, log=False)

    context = {}
    tc = ThemeController()

    if request.method == 'POST' and 'action' in request.POST:
        if request.POST['action'] == 'select':
            theme_name = request.POST['theme'].replace(' (current)', '')

            #   Check for differences between the theme's files and those in the working copy.
            #   If there are differences, require a confirmation from the user for each file.
            differences = tc.check_local_modifications(theme_name)
            if len(differences) > 0 and keep_files is None:
                return confirm_overwrite(request, current_theme=theme_name, differences=differences, orig_view='selector')

            #   Display configuration form if one is provided for the selected theme
            if tc.get_config_form_class(theme_name) is not None:
                return configure(request, current_theme=theme_name, force_display=True, keep_files=keep_files)

            tc.save_customizations('%s-last' % tc.get_current_theme())
            backup_info = tc.clear_theme(keep_files=keep_files)
            tc.load_theme(theme_name, backup_info=backup_info)
        elif request.POST['action'] == 'clear':
            tc.save_customizations('%s-last' % tc.get_current_theme())
            tc.clear_theme()

    context['theme_name'] = tc.get_current_theme()
    context['themes'] = tc.get_theme_names()
    return render_to_response('themes/selector.html', request, context)
Ejemplo n.º 22
0
    def testSelector(self):
        """ Check that theme selector functionality is working. """
        
        self.client.login(username=self.admin.username, password='******')

        #   Get a ThemeController for identifying available themes. 
        tc = ThemeController()
        
        #   Get the home page (this is a fresh site) and make sure it has a link to the theme landing.
        response = self.client.get('/')
        self.assertTrue(len(re.findall(r'<a href="/themes.*?Configure site appearance.*?</a>', response.content, flags=re.DOTALL)) == 1)
        
        #   Go to the themes landing page and theme selector, make sure neither errors out.
        response = self.client.get('/themes/')
        self.assertEqual(response.status_code, 200)
        response = self.client.get('/themes/select/')
        self.assertEqual(response.status_code, 200)
        
        #   Test each theme that is available.
        for theme_name in tc.get_theme_names():
        
            #   print 'Testing theme: %s' % theme_name
        
            #   Delete the theme_compiled.css file so we force a new one to be generated.
            css_filename = os.path.join(settings.MEDIA_ROOT, 'styles', themes_settings.COMPILED_CSS_FILE)
            if os.path.exists(css_filename):
                os.remove(css_filename)
        
            #   POST to the theme selector with our choice of theme
            response = self.client.post('/themes/select/', {'action': 'select', 'theme': theme_name})
            self.assertEqual(response.status_code, 200)
            
            #   Supply more settings if the theme asks for them.
            if '<form id="theme_setup_form"' in response.content:
                field_matches = re.findall(r'<(input type="\S+"|textarea).*?name="(\S+)".*?>', response.content, flags=re.DOTALL)
                settings_dict = {
                    'theme': theme_name,
                    'just_selected': 'True',
                    'nav_structure': '[{"header": "header", "header_link": "/header_link/", "links": [{"link": "link1", "text": "text1"}]}]',
                }
                for entry in field_matches:
                    if entry[1] not in settings_dict:
                        #   Supply value = key if we do not already know what to say
                        settings_dict[entry[1]] = entry[1]
                
                #   If theme setup succeeded, we will be redirected to the landing page.
                response = self.client.post('/themes/setup/', settings_dict, follow=True)
                self.assertTrue(('http://testserver/themes/', 302) in response.redirect_chain)
                
            #   Check that the CSS stylesheet has been included in the page.
            self.assertTrue('/media/styles/theme_compiled.css' in response.content)
            
            #   Check that the CSS stylesheet has been compiled.
            self.assertTrue(os.path.exists(css_filename))
            self.assertTrue(len(open(css_filename).read()) > 1000)  #   Hacky way to check that content is substantial
            """
            #   The following code would validate the CSS syntax, but cssutils doesn't seem to
            #   support the fancy CSS techniques used by Bootstrap and LESS.
            parser = cssutils.CSSParser(raiseExceptions=True)
            parser.parseFile(css_filename)
            """
            
            #   Check that the template override is marked with the theme name.
            self.assertTrue(('{%% comment %%} Theme: %s {%% endcomment %%}' % theme_name) in response.content)
        
        #   Test that the theme can be cleared and the home page reverts.
        response = self.client.post('/themes/select/', {'action': 'clear'})
        response = self.client.get('/')
        self.assertTrue(len(re.findall(r'<a href="/themes.*?Configure site appearance.*?</a>', response.content, flags=re.DOTALL)) == 1)
        
        self.client.logout()
Ejemplo n.º 23
0
def editor(request):
    if settings.LOCAL_THEME:
        raise ESPError(THEME_ERROR_STRING, log=False)

    tc = ThemeController()

    if request.method == 'POST':
        #   Handle form submission
        vars = None
        palette = None

        if 'save' in request.POST:
            if request.POST['saveThemeName'] == '':
                theme_name = tc.get_current_customization()
                if theme_name == 'None':
                    #   Generate a temporary theme name
                    random_slug  = ''.join(random.choice(string.lowercase) for i in range(4))
                    theme_name = 'theme-%s-%s' % (datetime.now().strftime('%Y%m%d'), random_slug)
            else:
                theme_name = request.POST['saveThemeName']
            vars = request.POST.dict()
            palette = request.POST.getlist('palette')
            tc.save_customizations(theme_name, vars=vars, palette=palette)
            tc.set_current_customization(theme_name)
        elif 'load' in request.POST:
            (vars, palette) = tc.load_customizations(request.POST['loadThemeName'])
        elif 'delete' in request.POST:
            tc.delete_customizations(request.POST['loadThemeName'])
        elif 'apply' in request.POST:
            vars = request.POST.dict()
            palette = request.POST.getlist('palette')

        #   Re-generate the CSS for the current theme given the supplied settings
        if vars:
            tc.customize_theme(vars)
        if palette:
            tc.set_palette(palette)

    #   Get current theme and customization settings
    current_theme = tc.get_current_theme()
    context = tc.find_less_variables(flat=True)
    context.update(tc.get_current_params())
    context['palette'] = tc.get_palette()

    #   Get list of available customizations
    context['available_themes'] = tc.get_customization_names()
    context['last_used_setting'] = tc.get_current_customization()

    #   Load a bunch of preset fonts
    context['sans_fonts'] = sorted(themes_settings.sans_serif_fonts.iteritems())

    #   Load the theme-specific options
    adv_vars = tc.find_less_variables(current_theme, theme_only=True)
    context['adv_vars'] = {}
    for filename in adv_vars:
        category_name = os.path.basename(filename)[:-5]
        category_vars = []
        keys = adv_vars[filename].keys()
        keys.sort()
        for key in keys:
            #   Detect type of variable based on default value
            initial_val = adv_vars[filename][key]
            if key in context:
                initial_val = context[key]
            if initial_val.startswith('#'):
                category_vars.append((key, 'color', initial_val))
            elif 'color' in key:
                #   This is a nontrivial color value.  However, we only allow overriding
                #   these variables with specific colors.
                category_vars.append((key, 'color', ''))
            elif initial_val.endswith('px') or initial_val.endswith('em'):
                category_vars.append((key, 'length', initial_val))
            else:
                category_vars.append((key, 'text', initial_val))
        context['adv_vars'][category_name] = category_vars

    return render_to_response('themes/editor.html', request, context)
Ejemplo n.º 24
0
def configure(request, current_theme=None, force_display=False, keep_files=None):
    if settings.LOCAL_THEME:
        raise ESPError(THEME_ERROR_STRING, log=False)

    context = {}
    tc = ThemeController()
    if current_theme is None:
        current_theme = request.POST.get('theme', None) or tc.get_current_theme()
    context['theme_name'] = current_theme

    form_class = tc.get_config_form_class(current_theme)
    if form_class is None:
        form = None
        return render_to_response('themes/configure_form.html', request, context)

    if request.method == 'POST' and not force_display:
        form = form_class(request.POST.copy())

        if form.is_valid():
            #   Done; save results and go back to landing page.
            if form.cleaned_data['theme'] != tc.get_current_theme():
                tc.save_customizations('%s-last' % tc.get_current_theme())

            if form.cleaned_data['just_selected']:
                #   Detect which files (in the active media directories) are being preserved,
                #   and use this information when reloading the theme.
                keep_files = request.POST.getlist('keep_files', [])
                backup_info = tc.clear_theme(keep_files=keep_files)
                tc.load_theme(form.cleaned_data['theme'], backup_info=backup_info)

            form.save_to_tag()
            return HttpResponseRedirect('/themes/')
    else:
        form = form_class.load_from_tag(theme_name=current_theme, just_selected=force_display)

    context['form'] = form
    context['keep_files'] = keep_files
    context['confirm_overwrite'] = request.POST.get('confirm_overwrite', '0')

    return render_to_response('themes/configure_form.html', request, context)
Ejemplo n.º 25
0
def configure(request, current_theme=None, force_display=False):
    context = {}
    tc = ThemeController()
    if current_theme is None:
        current_theme = request.POST.get('theme',
                                         None) or tc.get_current_theme()
    context['theme_name'] = current_theme

    form_class = tc.get_config_form_class(current_theme)
    if form_class is None:
        form = None
        return render_to_response('themes/configure_form.html', request,
                                  context)

    if request.method == 'POST' and not force_display:
        form = form_class(request.POST.copy())

        if form.is_valid():
            #   Done; save results and go back to landing page.
            if form.cleaned_data['theme'] != tc.get_current_theme():
                tc.save_customizations('%s-last' % tc.get_current_theme())
            if form.cleaned_data['just_selected']:
                tc.clear_theme()
                tc.load_theme(form.cleaned_data['theme'])
            form.save_to_tag()
            return HttpResponseRedirect('/themes/')
    else:
        form = form_class.load_from_tag(theme_name=current_theme,
                                        just_selected=force_display)

    context['form'] = form

    return render_to_response('themes/configure_form.html', request, context)
Ejemplo n.º 26
0
    def testSelector(self):
        """ Check that theme selector functionality is working. """

        self.client.login(username=self.admin.username, password='******')

        #   Get a ThemeController for identifying available themes.
        tc = ThemeController()

        #   Get the home page (this is a fresh site) and make sure it has a link to the theme landing.
        response = self.client.get('/')
        self.assertTrue(len(re.findall(r'<a href="/themes.*?Configure site appearance.*?</a>', response.content, flags=re.DOTALL)) == 1)

        #   Go to the themes landing page and theme selector, make sure neither errors out.
        response = self.client.get('/themes/')
        self.assertEqual(response.status_code, 200)
        response = self.client.get('/themes/select/')
        self.assertEqual(response.status_code, 200)

        # Move the existing images dir out of the way, so we don't conflict
        # with it (either what the user has there, or between themes).
        # TODO(benkraft): Do the same for styles and scripts, although in
        # practice conflicts there are less likely.
        # TODO(benkraft): This is a super hacky way to do things!  Instead we
        # should be doing all these tests in some sort of tmpdir to avoid
        # touching anything of the user's.
        images_dir = os.path.join(settings.MEDIA_ROOT, 'images', 'theme')
        # Really we should use a tempdir, but on vagrant it may be on a
        # different file system, which causes problems, so we do a hackier
        # thing instead.
        images_backup_dir = os.path.join(settings.MEDIA_ROOT, 'images',
                                         'theme_backup_for_tests')
        if os.path.exists(images_dir):
            os.rename(images_dir, images_backup_dir)

        try:
            #   Test each theme that is available.
            for theme_name in tc.get_theme_names():
                #   Delete the theme_compiled.css file so we force a new one to be generated.
                css_filename = os.path.join(settings.MEDIA_ROOT, 'styles', themes_settings.COMPILED_CSS_FILE)
                if os.path.exists(css_filename):
                    os.remove(css_filename)
                # Clobber any stray theme images dir, to avoid conflicts.
                # Note that we've already backed up any one the user had
                # created, above.
                if os.path.exists(images_dir):
                    shutil.rmtree(images_dir)

                # Make sure there won't be any conflicts between this theme and
                # existing files -- since they would cause harder-to-understand
                # errors later on.
                self.assertFalse(tc.check_local_modifications(theme_name))

                #   POST to the theme selector with our choice of theme
                response = self.client.post('/themes/select/', {'action': 'select', 'theme': theme_name})
                self.assertEqual(response.status_code, 200)

                #   Supply more settings if the theme asks for them.
                if '<form id="theme_setup_form"' in response.content:
                    field_matches = re.findall(r'<(input id="\S+"|textarea).*?name="(\S+)".*?>', response.content, flags=re.DOTALL)
                    #   This is the union of all the theme configuration settings that
                    #   have a non-trivial form (e.g. key = value fails validation).
                    settings_dict = {
                        'theme': theme_name,
                        'just_selected': 'True',
                        'front_page_style': 'bubblesfront.html',
                        'facebook_link': 'http://somehost.net',
                        'nav_structure': '[{"header": "header", "header_link": "/header_link/", "links": [{"link": "link1", "text": "text1"}]}]',
                    }
                    for entry in field_matches:
                        if entry[1] not in settings_dict:
                            #   Supply value = key if we do not already know what to say
                            settings_dict[entry[1]] = entry[1]

                    #   If theme setup succeeded, we will be redirected to the landing page.
                    response = self.client.post('/themes/setup/', settings_dict, follow=True)
                    self.assertTrue(('http://testserver/themes/', 302) in response.redirect_chain)

                #   Check that the CSS stylesheet has been included in the page.
                self.assertTrue('/media/styles/theme_compiled.css' in response.content)

                #   Check that the CSS stylesheet has been compiled.
                self.assertTrue(os.path.exists(css_filename))
                self.assertTrue(len(open(css_filename).read()) > 1000)  #   Hacky way to check that content is substantial

                #   Check that the template override is marked with the theme name.
                self.assertTrue(('<!-- Theme: %s -->' % theme_name) in response.content)

            #   Test that the theme can be cleared and the home page reverts.
            response = self.client.post('/themes/select/', {'action': 'clear'})
            response = self.client.get('/')
            self.assertTrue(len(re.findall(r'<a href="/themes.*?Configure site appearance.*?</a>', response.content, flags=re.DOTALL)) == 1)

            self.client.logout()

        finally:
            # Restore the backed up images dir.
            if os.path.exists(images_dir):
                shutil.rmtree(images_dir)
            if os.path.exists(images_backup_dir):
                os.rename(images_backup_dir, images_dir)
Ejemplo n.º 27
0
def recompile(request):
    tc = ThemeController()
    tc.recompile_theme()
    return HttpResponseRedirect('/themes/')
Ejemplo n.º 28
0
def selector(request):
    context = {}
    tc = ThemeController()

    if request.method == 'POST' and 'action' in request.POST:
        if request.POST['action'] == 'select':
            theme_name = request.POST['theme'].replace(' (current)', '')

            #   Display configuration form if one is provided for the selected theme
            if tc.get_config_form_class(theme_name) is not None:
                return configure(request,
                                 current_theme=theme_name,
                                 force_display=True)

            tc.save_customizations('%s-last' % tc.get_current_theme())
            tc.clear_theme()
            tc.load_theme(theme_name)
        elif request.POST['action'] == 'clear':
            tc.save_customizations('%s-last' % tc.get_current_theme())
            tc.clear_theme()

    context['theme_name'] = tc.get_current_theme()
    context['themes'] = tc.get_theme_names()
    return render_to_response('themes/selector.html', request, context)
Ejemplo n.º 29
0
    def testSelector(self):
        """ Check that theme selector functionality is working. """

        self.client.login(username=self.admin.username, password='******')

        #   Get a ThemeController for identifying available themes.
        tc = ThemeController()

        #   Get the home page (this is a fresh site) and make sure it has a link to the theme landing.
        response = self.client.get('/')
        self.assertTrue(len(re.findall(r'<a href="/themes.*?Configure site appearance.*?</a>', response.content, flags=re.DOTALL)) == 1)

        #   Go to the themes landing page and theme selector, make sure neither errors out.
        response = self.client.get('/themes/')
        self.assertEqual(response.status_code, 200)
        response = self.client.get('/themes/select/')
        self.assertEqual(response.status_code, 200)

        #   Test each theme that is available.
        for theme_name in tc.get_theme_names():
            #   Delete the theme_compiled.css file so we force a new one to be generated.
            css_filename = os.path.join(settings.MEDIA_ROOT, 'styles', themes_settings.COMPILED_CSS_FILE)
            if os.path.exists(css_filename):
                os.remove(css_filename)

            #   POST to the theme selector with our choice of theme
            response = self.client.post('/themes/select/', {'action': 'select', 'theme': theme_name})
            self.assertEqual(response.status_code, 200)

            #   Supply more settings if the theme asks for them.
            if '<form id="theme_setup_form"' in response.content:
                field_matches = re.findall(r'<(input id="\S+"|textarea).*?name="(\S+)".*?>', response.content, flags=re.DOTALL)
                #   This is the union of all the theme configuration settings that
                #   have a non-trivial form (e.g. key = value fails validation).
                settings_dict = {
                    'theme': theme_name,
                    'just_selected': 'True',
                    'front_page_style': 'bubblesfront.html',
                    'facebook_link': 'http://somehost.net',
                    'nav_structure': '[{"header": "header", "header_link": "/header_link/", "links": [{"link": "link1", "text": "text1"}]}]',
                }
                for entry in field_matches:
                    if entry[1] not in settings_dict:
                        #   Supply value = key if we do not already know what to say
                        settings_dict[entry[1]] = entry[1]

                #   If theme setup succeeded, we will be redirected to the landing page.
                response = self.client.post('/themes/setup/', settings_dict, follow=True)
                self.assertTrue(('http://testserver/themes/', 302) in response.redirect_chain)

            #   Check that the CSS stylesheet has been included in the page.
            self.assertTrue('/media/styles/theme_compiled.css' in response.content)

            #   Check that the CSS stylesheet has been compiled.
            self.assertTrue(os.path.exists(css_filename))
            self.assertTrue(len(open(css_filename).read()) > 1000)  #   Hacky way to check that content is substantial

            #   Check that the template override is marked with the theme name.
            self.assertTrue(('<!-- Theme: %s -->' % theme_name) in response.content)

        #   Test that the theme can be cleared and the home page reverts.
        response = self.client.post('/themes/select/', {'action': 'clear'})
        response = self.client.get('/')
        self.assertTrue(len(re.findall(r'<a href="/themes.*?Configure site appearance.*?</a>', response.content, flags=re.DOTALL)) == 1)

        self.client.logout()
Ejemplo n.º 30
0
 def save_to_tag(self):
     tc = ThemeController()
     data = self.prepare_for_serialization(self.cleaned_data.copy())
     tc.set_template_settings(data)