Example #1
0
 def test_str(self):
     group1 = self.reload(self.group1, 'en')
     self.assertEqual(
         force_text(group1),
         self.data['group1']['en']['name'],
     )
     group1 = self.reload(self.group1, 'de')
     self.assertEqual(
         force_text(group1),
         self.data['group1']['de']['name'],
     )
Example #2
0
 def test_str(self):
     group1 = self.reload(self.group1, 'en')
     self.assertEqual(
         force_text(group1),
         self.data['group1']['en']['name'],
     )
     group1 = self.reload(self.group1, 'de')
     self.assertEqual(
         force_text(group1),
         self.data['group1']['de']['name'],
     )
Example #3
0
    def test_add_people_list_plugin_api(self):
        """
        We add a person to the People Plugin and look her up
        """
        name = 'Donald'
        Person.objects.create(name=name)
        plugin = api.add_plugin(self.placeholder, PeoplePlugin, self.language)
        plugin.people = Person.objects.all()
        self.assertEqual(force_text(plugin), force_text(plugin.pk))
        self.page.publish(self.language)

        url = self.page.get_absolute_url()
        response = self.client.get(url, follow=True)
        self.assertContains(response, name)
Example #4
0
    def test_add_people_list_plugin_api(self):
        """
        We add a person to the People Plugin and look her up
        """
        name = 'Donald'
        Person.objects.create(name=name)
        plugin = api.add_plugin(self.placeholder, PeoplePlugin, self.language)
        plugin.people = Person.objects.all()
        self.assertEqual(force_text(plugin), force_text(plugin.pk))
        self.page.publish(self.language)

        url = self.page.get_absolute_url()
        response = self.client.get(url)
        self.assertContains(response, name)
Example #5
0
def csspath(input_file, version_str=None):
    """
    :type   input_file: File 

    :returns: File   
    """

    input_str = force_text(input_file.read())
    cur = 0
    output = StringIO()
    matches = _CSS_URL_MATCH.finditer(input_str)

    for match in matches:
        url = match.group('url')
        if url is None:
            url = match.group('url1')
            start, end = match.span('url1')
        else:
            start, end = match.span('url')

        output.write(input_str[cur:start])
        output.write(
            _transform_url(url, version_str=version_str).encode('utf8'))
        cur = end

    output.write(input_str[cur:])
    output.seek(0)

    return File(output)
Example #6
0
def csspath(input_file, version_str=None):
    """
    :type   input_file: File 

    :returns: File   
    """

    input_str = force_text(input_file.read())
    cur = 0
    output = StringIO()
    matches = _CSS_URL_MATCH.finditer(input_str)
    
    for match in matches:
        url = match.group('url')
        if url is None:
            url = match.group('url1')
            start, end = match.span('url1')
        else:    
            start, end = match.span('url')

        output.write(input_str[cur:start])
        output.write(_transform_url(url, version_str=version_str).encode('utf8'))
        cur = end
        
    output.write(input_str[cur:])
    output.seek(0)

    return File(output)
Example #7
0
def get_header_name(name):
    """
    Returns "HTTP_HEADER_NAME" for "header-name" or "Header-Name", etc.
    Won't add "HTTP_" to input that already has it or for CONTENT_TYPE or
    CONTENT_LENGTH.
    """
    uc_name = re.sub(r"\W+", "_", force_text(name)).upper()
    if uc_name in ["CONTENT_LENGTH", "CONTENT_TYPE"] or uc_name.startswith("HTTP_"):
        return uc_name
    return "HTTP_{0}".format(uc_name)
Example #8
0
 def test_normal_ordering(self):
     """
     Ensure that events are ordered oldest-first, which is the default
     for app-configs.
     """
     page_url = self.page.get_absolute_url()
     response = force_text(self.client.get(page_url).render())
     # NOTE: This list should be ordered in the events natural order
     for e in range(0, len(self.oldest_first) - 1):
         self.assertLess(response.find(self.oldest_first[e].title),
                         response.find(self.oldest_first[e + 1].title))
Example #9
0
def get_header_name(name):
    """
    Returns "HTTP_HEADER_NAME" for "header-name" or "Header-Name", etc.
    Won't add "HTTP_" to input that already has it or for CONTENT_TYPE or
    CONTENT_LENGTH.
    """
    uc_name = re.sub(r'\W+', '_', force_text(name)).upper()
    if (uc_name in ['CONTENT_LENGTH', 'CONTENT_TYPE']
            or uc_name.startswith('HTTP_')):
        return uc_name
    return 'HTTP_{0}'.format(uc_name)
Example #10
0
def get_header_name(name):
    """
    Returns "HTTP_HEADER_NAME" for "header-name" or "Header-Name", etc.
    Won't add "HTTP_" to input that already has it or for CONTENT_TYPE or
    CONTENT_LENGTH.
    """
    uc_name = re.sub(r'\W+', '_', force_text(name)).upper()
    if (uc_name in ['CONTENT_LENGTH', 'CONTENT_TYPE'] or
            uc_name.startswith('HTTP_')):
        return uc_name
    return 'HTTP_{0}'.format(uc_name)
Example #11
0
 def id(self):
     """
     To construct an unique ID for each wizard, we start with the module and
     class name for uniqueness, we hash it because a wizard's ID is displayed
     in the form's markup, and we'd rather not expose code paths there.
     """
     if not self._hash_cache:
         full_path = force_text(".".join(
             [self.__module__, self.__class__.__name__])).encode('utf-8')
         hash = hashlib.sha1()
         hash.update(full_path)
         self._hash_cache = hash.hexdigest()
     return self._hash_cache
Example #12
0
 def test_latest_first_ordering(self):
     """
     Ensure that events are ordered latest-first when app is configured
     to do so.
     """
     page_url = self.page.get_absolute_url()
     response = force_text(self.client.get(page_url).render())
     latest_first = reversed(self.oldest_first)
     self.app_config.latest_first = True
     # NOTE: This list should be ordered in the events natural order
     for e in range(0, len([latest_first]) - 1):
         self.assertLess(response.find(latest_first[e].title),
                         response.find(latest_first[e + 1].title))
Example #13
0
    def test_authors_plugin(self):
        author1, author2 = self.create_person(), self.create_person()
        # Published, author1 articles in our current namespace
        author1_articles = []
        for _ in range(3):
            article = self.create_article(author=author1)
            author1_articles.append(article)

        # Published, author2 articles in our current namespace
        other_articles = []
        for _ in range(5):
            article = self.create_article(author=author2)
            other_articles.append(article)

        # Unpublished, author1 articles in our current namespace
        for _ in range(7):
            article = self.create_article(
                author=author1,
                is_published=False
            )
            other_articles.append(article)

        # Published, author1 articles in a different namespace
        other_articles.append(self.create_article(
            author=author1,
            app_config=self.another_app_config
        ))

        # REQUIRED DUE TO USE OF RAW QUERIES
        time.sleep(1)

        response = self.client.get(self.plugin_page.get_absolute_url())
        response_content = force_text(response.content)
        pattern = '<p>\s*<a href="{url}">\s*</a>\s*</p>'
        pattern += '\s*<p>{num}</p>'
        author1_pattern = pattern.format(
            num=3,
            url=reverse(
                '{0}:article-list-by-author'.format(self.app_config.namespace),
                args=[author1.slug]
            )
        )
        author2_pattern = pattern.format(
            num=5,
            url=reverse(
                '{0}:article-list-by-author'.format(self.app_config.namespace),
                args=[author2.slug]
            )
        )
        self.assertRegexpMatches(response_content, author1_pattern)
        self.assertRegexpMatches(response_content, author2_pattern)
    def test_authors_plugin(self):
        author1, author2 = self.create_person(), self.create_person()
        # Published, author1 articles in our current namespace
        author1_articles = []
        for _ in range(3):
            article = self.create_article(author=author1)
            author1_articles.append(article)

        # Published, author2 articles in our current namespace
        other_articles = []
        for _ in range(5):
            article = self.create_article(author=author2)
            other_articles.append(article)

        # Unpublished, author1 articles in our current namespace
        for _ in range(7):
            article = self.create_article(
                author=author1,
                is_published=False
            )
            other_articles.append(article)

        # Published, author1 articles in a different namespace
        other_articles.append(self.create_article(
            author=author1,
            app_config=self.another_app_config
        ))

        # REQUIRED DUE TO USE OF RAW QUERIES
        time.sleep(1)

        response = self.client.get(self.plugin_page.get_absolute_url())
        response_content = force_text(response.content)
        pattern = '<p class="author"><a href="{url}"></a>'
        pattern += '</p>\s*<p[^>]*></p>\s*<p class="badge">{num}</p>'
        author1_pattern = pattern.format(
            num=3,
            url=reverse(
                '{0}:article-list-by-author'.format(self.app_config.namespace),
                args=[author1.slug]
            )
        )
        author2_pattern = pattern.format(
            num=5,
            url=reverse(
                '{0}:article-list-by-author'.format(self.app_config.namespace),
                args=[author2.slug]
            )
        )
        self.assertRegexpMatches(response_content, author1_pattern)
        self.assertRegexpMatches(response_content, author2_pattern)
Example #15
0
def get_timezone_name():
    """
    This returns a cross-platform compatible timezone name suitable for
    embedding into cache-keys. Its inclusion into cache-keys enables, but does
    not guarantee by itself, that dates are display correctly for the client's
    timezone. In order to complete this the project should use middleware or
    some other mechanism to affect's Django's get_current_timezone_name().
    """
    # The datetime module doesn't restrict the output of tzname().
    # Windows is known to use non-standard, locale-dependant names.
    # User-defined tzinfo classes may return absolutely anything.
    # Hence this paranoid conversion to create a valid cache key.
    tz_name = force_text(get_current_timezone_name(), errors='ignore')
    return tz_name.encode('ascii', 'ignore').decode('ascii').replace(' ', '_')
Example #16
0
 def id(self):
     """
     To construct an unique ID for each wizard, we start with the module and
     class name for uniqueness, we hash it because a wizard's ID is displayed
     in the form's markup, and we'd rather not expose code paths there.
     """
     if not self._hash_cache:
         full_path = force_text(
                 ".".join([self.__module__, self.__class__.__name__])
             ).encode('utf-8')
         hash = hashlib.sha1()
         hash.update(full_path)
         self._hash_cache = hash.hexdigest()
     return self._hash_cache
Example #17
0
    def test_authors_plugin(self):
        author1, author2 = self.create_person(), self.create_person()
        # Published, author1 articles in our current namespace
        author1_articles = []
        for _ in range(3):
            article = self.create_article(author=author1)
            author1_articles.append(article)

        # Published, author2 articles in our current namespace
        other_articles = []
        for _ in range(5):
            article = self.create_article(author=author2)
            other_articles.append(article)

        # Unpublished, author1 articles in our current namespace
        for _ in range(7):
            article = self.create_article(
                author=author1,
                is_published=False
            )
            other_articles.append(article)

        # Published, author1 articles in a different namespace
        other_articles.append(self.create_article(
            author=author1,
            app_config=self.another_app_config
        ))

        # REQUIRED DUE TO USE OF RAW QUERIES
        time.sleep(1)

        response = self.client.get(self.plugin_page.get_absolute_url())
        response_content = force_text(response.content)
        # This pattern tries to accommodate all the templates from all the
        # versions of this package.
        pattern = '<a href="{url}">\s*</a>'
        author1_pattern = pattern.format(
            url=reverse(
                '{0}:article-list-by-author'.format(self.app_config.namespace),
                args=[author1.slug]
            )
        )
        author2_pattern = pattern.format(
            url=reverse(
                '{0}:article-list-by-author'.format(self.app_config.namespace),
                args=[author2.slug]
            )
        )
        self.assertRegexpMatches(response_content, author1_pattern)
        self.assertRegexpMatches(response_content, author2_pattern)
Example #18
0
def get_timezone_name():
    """
    This returns a cross-platform compatible timezone name suitable for
    embedding into cache-keys. Its inclusion into cache-keys enables, but does
    not guarantee by itself, that dates are display correctly for the client's
    timezone. In order to complete this the project should use middleware or
    some other mechanism to affect's Django's get_current_timezone_name().
    """
    # The datetime module doesn't restrict the output of tzname().
    # Windows is known to use non-standard, locale-dependant names.
    # User-defined tzinfo classes may return absolutely anything.
    # Hence this paranoid conversion to create a valid cache key.
    tz_name = force_text(get_current_timezone_name(), errors='ignore')
    return tz_name.encode('ascii', 'ignore').decode('ascii').replace(' ', '_')
Example #19
0
    def get_vcard(self, request=None):
        vcard = Vcard()
        function = self.safe_translation_getter('function')

        safe_name = self.safe_translation_getter('name',
                                                 default="Person: {0}".format(
                                                     self.pk))
        vcard.add_line('FN', safe_name)
        vcard.add_line('N', [None, safe_name, None, None, None])

        if hasattr(self.profile, "visual") and self.profile.visual:
            ext = self.profile.visual.extension.upper()
            try:
                with open(self.visual.path, 'rb') as f:
                    data = force_text(base64.b64encode(f.read()))
                    vcard.add_line('PHOTO', data, TYPE=ext, ENCODING='b')
            except IOError:
                if request:
                    url = urlparse.urljoin(request.build_absolute_uri(),
                                           self.profile.visual.url),
                    vcard.add_line('PHOTO', url, TYPE=ext)

        fields = [(
            "EMAIL",
            "email",
        ), ('TITLE', "function"), ('TEL', "phone", 'WORK'),
                  ('TEL', "mobile", 'CELL'), ('TEL', "fax", 'FAX'),
                  ('URL', "website")]

        for field in fields:
            if hasattr(self.profile, field[1]) and getattr(
                    self.profile, field[1]):
                if len(field) > 2:
                    vcard.add_line(field[0],
                                   getattr(self.profile, field[1]),
                                   TYPE=field[2])
                else:
                    vcard.add_line(field[0], getattr(self.profile, field[1]))

        if self.primary_group:
            group_name = self.primary_group.safe_translation_getter(
                'name', default="Group: {0}".format(self.primary_group.pk))
            if group_name:
                vcard.add_line('ORG', group_name)
            self.primary_group.get_vcard(vcard)
        return str(vcard)
Example #20
0
    def get_vary_cache_on(self, request):
        """
        Returns a list of VARY headers.
        """
        def inner_plugin_iterator(lang):
            """See note in get_cache_expiration.inner_plugin_iterator()."""
            if hasattr(self, '_all_plugins_cache'):
                for instance in self._all_plugins_cache:
                    plugin = instance.get_plugin_class_instance()
                    yield instance, plugin
            else:
                for plugin_item in self.get_plugins(lang):
                    yield plugin_item.get_plugin_instance()

        if not self.cache_placeholder or not get_cms_setting('PLUGIN_CACHE'):
            return []

        vary_list = set()
        language = get_language_from_request(request, self.page)
        for instance, plugin in inner_plugin_iterator(language):
            if not instance:
                continue
            vary_on = plugin.get_vary_cache_on(request, instance, self)
            if not vary_on:
                # None, or an empty iterable
                continue
            if isinstance(vary_on, six.string_types):
                if vary_on.lower() not in vary_list:
                    vary_list.add(vary_on.lower())
            else:
                try:
                    for vary_on_item in iter(vary_on):
                        if vary_on_item.lower() not in vary_list:
                            vary_list.add(vary_on_item.lower())
                except TypeError:
                    warnings.warn(
                        'Plugin %(plugin_class)s (%(pk)d) returned '
                        'unexpected value %(value)s for '
                        'get_vary_cache_on(), ignoring.' % {
                            'plugin_class': plugin.__class__.__name__,
                            'pk': instance.pk,
                            'value': force_text(vary_on),
                        })

        return sorted(list(vary_list))
Example #21
0
    def get_vary_cache_on(self, request):
        """
        Returns a list of VARY headers.
        """
        def inner_plugin_iterator(lang):
            """See note in get_cache_expiration.inner_plugin_iterator()."""
            if hasattr(self, '_all_plugins_cache'):
                for instance in self._all_plugins_cache:
                    plugin = instance.get_plugin_class_instance()
                    yield instance, plugin
            else:
                for plugin_item in self.get_plugins(lang):
                    yield plugin_item.get_plugin_instance()

        if not self.cache_placeholder or not get_cms_setting('PLUGIN_CACHE'):
            return []

        vary_list = set()
        language = get_language_from_request(request, self.page)
        for instance, plugin in inner_plugin_iterator(language):
            if not instance:
                continue
            vary_on = plugin.get_vary_cache_on(request, instance, self)
            if not vary_on:
                # None, or an empty iterable
                continue
            if isinstance(vary_on, six.string_types):
                if vary_on.lower() not in vary_list:
                    vary_list.add(vary_on.lower())
            else:
                try:
                    for vary_on_item in iter(vary_on):
                        if vary_on_item.lower() not in vary_list:
                            vary_list.add(vary_on_item.lower())
                except TypeError:
                    warnings.warn(
                        'Plugin %(plugin_class)s (%(pk)d) returned '
                        'unexpected value %(value)s for '
                        'get_vary_cache_on(), ignoring.' % {
                            'plugin_class': plugin.__class__.__name__,
                            'pk': instance.pk,
                            'value': force_text(vary_on),
                        })

        return sorted(list(vary_list))
Example #22
0
    def test_tags_plugin(self):
        # Published, tag1-tagged articles in our current namespace
        self.create_tagged_articles(3, tags=['tag1'])['tag1']
        other_articles = self.create_tagged_articles(5, tags=['tag2'])['tag2']
        # Some tag1, but unpublished articles
        other_articles += self.create_tagged_articles(
            7, tags=['tag1'], is_published=False)['tag1']
        # Some tag1 articles in another namespace
        other_articles += self.create_tagged_articles(
            1, tags=['tag1'], app_config=self.another_app_config)['tag1']

        # REQUIRED DUE TO USE OF RAW QUERIES
        time.sleep(1)

        response = self.client.get(self.plugin_page.get_absolute_url())
        response_content = force_text(response.content)
        self.assertRegexpMatches(response_content, 'tag1\s*<span[^>]*>3</span>')
        self.assertRegexpMatches(response_content, 'tag2\s*<span[^>]*>5</span>')
    def test_tags_plugin(self):
        # Published, tag1-tagged articles in our current namespace
        self.create_tagged_articles(3, tags=['tag1'])['tag1']
        other_articles = self.create_tagged_articles(5, tags=['tag2'])['tag2']
        # Some tag1, but unpublished articles
        other_articles += self.create_tagged_articles(
            7, tags=['tag1'], is_published=False)['tag1']
        # Some tag1 articles in another namespace
        other_articles += self.create_tagged_articles(
            1, tags=['tag1'], app_config=self.another_app_config)['tag1']

        # REQUIRED DUE TO USE OF RAW QUERIES
        time.sleep(1)

        response = self.client.get(self.plugin_page.get_absolute_url())
        response_content = force_text(response.content)
        self.assertRegexpMatches(response_content, 'tag1\s*<span[^>]*>3</span>')
        self.assertRegexpMatches(response_content, 'tag2\s*<span[^>]*>5</span>')
Example #24
0
    def all_translations(self, obj):
        """
        Adds a property to the list_display that lists all translations with
        links directly to their change forms. Includes CSS to style the links
        to looks like tags with color indicating current language, active and
        inactive translations.

        A similar capability is in HVAD, and now there is this for
        Parler-based projects.
        """
        available = list(obj.get_available_languages())
        current = get_current_language()
        langs = []
        for code, lang_name in settings.LANGUAGES:
            classes = [
                "lang-code",
            ]
            title = force_text(lang_name)
            if code == current:
                classes += [
                    "current",
                ]
            if code in available:
                classes += [
                    "active",
                ]
                title += " (translated)"
            else:
                title += " (untranslated)"
            change_form_url = admin_reverse(
                '{app_label}_{model_name}_change'.format(
                    app_label=obj._meta.app_label.lower(),
                    model_name=obj.__class__.__name__.lower(),
                ),
                args=(obj.id, ))
            link = ('<a class="{classes}" href="{url}?language={code}" ' +
                    'title="{title}">  {code}  </a> ').format(
                        classes=' '.join(classes),
                        url=change_form_url,
                        code=code,
                        title=title,
                    )
            langs.append(link)
        return ''.join(langs)
Example #25
0
def parse(obj):
    if isinstance(obj, type(Enum)):
        return OrderedDict({
            item.name: item.value
            for item in obj
        })
    elif isinstance(obj, Enum):
        return obj.value
    elif isinstance(obj, dict):
        return OrderedDict({
            parse(key): parse(value)
            for key, value in obj.items()
        })
    elif isinstance(obj, (list, tuple)):
        return [parse(item) for item in obj]
    elif isinstance(obj, Promise):
        return force_text(obj)
    else:
        return obj
Example #26
0
def all_distinct_files(context, version):
    """Only display a file once even if it's been uploaded
    for several platforms."""
    # hashes_to_file will group files per hash:
    # {<file.hash>: [<file>, 'Windows / Mac OS X']}
    hashes_to_file = {}
    for file_ in version.all_files:
        display_name = force_text(amo.PLATFORMS[file_.platform].name)
        if file_.hash in hashes_to_file:
            hashes_to_file[file_.hash][1] += ' / ' + display_name
        else:
            hashes_to_file[file_.hash] = [file_, display_name]
    return new_context(dict(
        # We don't need the hashes in the template.
        distinct_files=hashes_to_file.values(),
        amo=context.get('amo'),
        addon=context.get('addon'),
        show_diff=context.get('show_diff'),
        version=version))
Example #27
0
def all_distinct_files(context, version):
    """Only display a file once even if it's been uploaded
    for several platforms."""
    # hashes_to_file will group files per hash:
    # {<file.hash>: [<file>, 'Windows / Mac OS X']}
    hashes_to_file = {}
    for file_ in version.all_files:
        display_name = force_text(amo.PLATFORMS[file_.platform].name)
        if file_.hash in hashes_to_file:
            hashes_to_file[file_.hash][1] += ' / ' + display_name
        else:
            hashes_to_file[file_.hash] = [file_, display_name]
    return new_context(
        dict(
            # We don't need the hashes in the template.
            distinct_files=hashes_to_file.values(),
            amo=context.get('amo'),
            addon=context.get('addon'),
            show_diff=context.get('show_diff'),
            version=version))
Example #28
0
    def test_authors_plugin(self):
        author1, author2 = self.create_person(), self.create_person()
        # Published, author1 dashboards in our current namespace
        author1_dashboards = []
        for _ in range(3):
            dashboard = self.create_dashboard(author=author1)
            author1_dashboards.append(dashboard)

        # Published, author2 dashboards in our current namespace
        other_dashboards = []
        for _ in range(5):
            dashboard = self.create_dashboard(author=author2)
            other_dashboards.append(dashboard)

        # Unpublished, author1 dashboards in our current namespace
        for _ in range(7):
            dashboard = self.create_dashboard(author=author1,
                                              is_published=False)
            other_dashboards.append(dashboard)

        # Published, author1 dashboards in a different namespace
        other_dashboards.append(
            self.create_dashboard(author=author1,
                                  app_config=self.another_app_config))

        # REQUIRED DUE TO USE OF RAW QUERIES
        time.sleep(1)

        response = self.client.get(self.plugin_page.get_absolute_url())
        response_content = force_text(response.content)
        # This pattern tries to accommodate all the templates from all the
        # versions of this package.
        pattern = '<a href="{url}">\s*</a>'
        author1_pattern = pattern.format(url=reverse(
            '{0}:dashboard-list-by-author'.format(self.app_config.namespace),
            args=[author1.slug]))
        author2_pattern = pattern.format(url=reverse(
            '{0}:dashboard-list-by-author'.format(self.app_config.namespace),
            args=[author2.slug]))
        self.assertRegexpMatches(response_content, author1_pattern)
        self.assertRegexpMatches(response_content, author2_pattern)
Example #29
0
    def test_categories_plugin(self):
        # Published, category1 dashboards in our current namespace
        cat1_dashboards = []
        for _ in range(3):
            dashboard = self.create_dashboard()
            dashboard.categories.add(self.category1)
            cat1_dashboards.append(dashboard)

        # Published category2 dashboards in our namespace
        other_dashboards = []
        for _ in range(5):
            dashboard = self.create_dashboard()
            dashboard.categories.add(self.category2)
            other_dashboards.append(dashboard)

        # Some tag1, but unpublished dashboards
        for _ in range(7):
            dashboard = self.create_dashboard(is_published=False)
            dashboard.categories.add(self.category1)
            other_dashboards.append(dashboard)

        # Some tag1 dashboards in another namespace
        for _ in range(1):
            dashboard = self.create_dashboard(
                app_config=self.another_app_config)
            dashboard.categories.add(self.category1)
            other_dashboards.append(dashboard)

        # REQUIRED DUE TO USE OF RAW QUERIES
        time.sleep(1)

        response = self.client.get(self.plugin_page.get_absolute_url())
        response_content = force_text(response.content)
        # We use two different patterns in alternation because different
        # versions of dashboards_app have different templates
        pattern = '<span[^>]*>{num}</span>\s*<a href=[^>]*>{name}</a>'
        pattern += '|<a href=[^>]*>{name}</a>\s*<span[^>]*>{num}</span>'
        needle1 = pattern.format(num=3, name=self.category1.name)
        needle2 = pattern.format(num=5, name=self.category2.name)
        self.assertRegexpMatches(response_content, needle1)
        self.assertRegexpMatches(response_content, needle2)
Example #30
0
    def test_categories_plugin(self):
        # Published, category1 articles in our current namespace
        cat1_articles = []
        for _ in range(3):
            article = self.create_article()
            article.categories.add(self.category1)
            cat1_articles.append(article)

        # Published category2 articles in our namespace
        other_articles = []
        for _ in range(5):
            article = self.create_article()
            article.categories.add(self.category2)
            other_articles.append(article)

        # Some tag1, but unpublished articles
        for _ in range(7):
            article = self.create_article(is_published=False)
            article.categories.add(self.category1)
            other_articles.append(article)

        # Some tag1 articles in another namespace
        for _ in range(1):
            article = self.create_article(app_config=self.another_app_config)
            article.categories.add(self.category1)
            other_articles.append(article)

        # REQUIRED DUE TO USE OF RAW QUERIES
        time.sleep(1)

        response = self.client.get(self.plugin_page.get_absolute_url())
        response_content = force_text(response.content)
        # We use two different patterns in alternation because different
        # versions of newsblog have different templates
        pattern = '<span[^>]*>{num}</span>\s*<a href=[^>]*>{name}</a>'
        pattern += '|<a href=[^>]*>{name}</a>\s*<span[^>]*>{num}</span>'
        needle1 = pattern.format(num=3, name=self.category1.name)
        needle2 = pattern.format(num=5, name=self.category2.name)
        self.assertRegexpMatches(response_content, needle1)
        self.assertRegexpMatches(response_content, needle2)
    def all_translations(self, obj):
        """
        Adds a property to the list_display that lists all translations with
        links directly to their change forms. Includes CSS to style the links
        to looks like tags with color indicating current language, active and
        inactive translations.

        A similar capability is in HVAD, and now there is this for
        Parler-based projects.
        """
        available = list(obj.get_available_languages())
        current = get_current_language()
        langs = []
        for code, lang_name in settings.LANGUAGES:
            classes = ["lang-code", ]
            title = force_text(lang_name)
            if code == current:
                classes += ["current", ]
            if code in available:
                classes += ["active", ]
                title += " (translated)"
            else:
                title += " (untranslated)"
            change_form_url = admin_reverse(
                '{app_label}_{model_name}_change'.format(
                    app_label=obj._meta.app_label.lower(),
                    model_name=obj.__class__.__name__.lower(),
                ), args=(obj.id, )
            )
            link = ('<a class="{classes}" href="{url}?language={code}" ' +
                'title="{title}">{code}</a>').format(
                classes=' '.join(classes),
                url=change_form_url,
                code=code,
                title=title,
            )
            langs.append(link)
        return ''.join(langs)
 def test_archive_plugin(self):
     dates = [
         datetime.datetime(2014, 11, 15, 12, 0, 0, 0, pytz.UTC),
         datetime.datetime(2014, 11, 16, 12, 0, 0, 0, pytz.UTC),
         datetime.datetime(2015, 1, 15, 12, 0, 0, 0, pytz.UTC),
         datetime.datetime(2015, 1, 15, 12, 0, 0, 0, pytz.UTC),
         datetime.datetime(2015, 1, 15, 12, 0, 0, 0, pytz.UTC),
         datetime.datetime(2015, 2, 15, 12, 0, 0, 0, pytz.UTC),
     ]
     articles = []
     for d in dates:
         article = self.create_article(publishing_date=d)
         articles.append(article)
     response = self.client.get(self.plugin_page.get_absolute_url())
     response_content = force_text(response.content)
     needle = '<a href="/en/page/{year}/{month}/"[^>]*>'
     '[^<]*<span class="badge">{num}</span>'
     month1 = needle.format(year=2014, month=11, num=2)
     month2 = needle.format(year=2015, month=2, num=1)
     month3 = needle.format(year=2015, month=1, num=3)
     self.assertRegexpMatches(response_content, month1)
     self.assertRegexpMatches(response_content, month2)
     self.assertRegexpMatches(response_content, month3)
Example #33
0
 def test_archive_plugin(self):
     dates = [
         datetime.datetime(2014, 11, 15, 12, 0, 0, 0, pytz.UTC),
         datetime.datetime(2014, 11, 16, 12, 0, 0, 0, pytz.UTC),
         datetime.datetime(2015, 1, 15, 12, 0, 0, 0, pytz.UTC),
         datetime.datetime(2015, 1, 15, 12, 0, 0, 0, pytz.UTC),
         datetime.datetime(2015, 1, 15, 12, 0, 0, 0, pytz.UTC),
         datetime.datetime(2015, 2, 15, 12, 0, 0, 0, pytz.UTC),
     ]
     articles = []
     for d in dates:
         article = self.create_article(publishing_date=d)
         articles.append(article)
     response = self.client.get(self.plugin_page.get_absolute_url())
     response_content = force_text(response.content)
     needle = '<a href="/en/page/{year}/{month}/"[^>]*>'
     '[^<]*<span class="badge">{num}</span>'
     month1 = needle.format(year=2014, month=11, num=2)
     month2 = needle.format(year=2015, month=2, num=1)
     month3 = needle.format(year=2015, month=1, num=3)
     self.assertRegexpMatches(response_content, month1)
     self.assertRegexpMatches(response_content, month2)
     self.assertRegexpMatches(response_content, month3)
Example #34
0
    def test_categories_plugin(self):
        # Published, category1 articles in our current namespace
        cat1_articles = []
        for _ in range(3):
            article = self.create_article()
            article.categories.add(self.category1)
            cat1_articles.append(article)

        # Published category2 articles in our namespace
        other_articles = []
        for _ in range(5):
            article = self.create_article()
            article.categories.add(self.category2)
            other_articles.append(article)

        # Some tag1, but unpublished articles
        for _ in range(7):
            article = self.create_article(is_published=False)
            article.categories.add(self.category1)
            other_articles.append(article)

        # Some tag1 articles in another namespace
        for _ in range(1):
            article = self.create_article(app_config=self.another_app_config)
            article.categories.add(self.category1)
            other_articles.append(article)

        # REQUIRED DUE TO USE OF RAW QUERIES
        time.sleep(1)

        response = self.client.get(self.plugin_page.get_absolute_url())
        response_content = force_text(response.content)
        pattern = '<span[^>]*>{num}</span>\s*<a href=[^>]*>{name}</a>'
        needle1 = pattern.format(num=3, name=self.category1.name)
        needle2 = pattern.format(num=5, name=self.category2.name)
        self.assertRegexpMatches(response_content, needle1)
        self.assertRegexpMatches(response_content, needle2)
Example #35
0
    def get_vcard(self, request=None):
        vcard = Vcard()
        function = self.safe_translation_getter('function')

        safe_name = self.safe_translation_getter(
            'name', default="Person: {0}".format(self.pk))
        vcard.add_line('FN', safe_name)
        vcard.add_line('N', [None, safe_name, None, None, None])

        if self.visual:
            ext = self.visual.extension.upper()
            try:
                with open(self.visual.path, 'rb') as f:
                    data = force_text(base64.b64encode(f.read()))
                    vcard.add_line('PHOTO', data, TYPE=ext, ENCODING='b')
            except IOError:
                if request:
                    url = urlparse.urljoin(request.build_absolute_uri(),
                                           self.visual.url),
                    vcard.add_line('PHOTO', url, TYPE=ext)

        if self.email:
            vcard.add_line('EMAIL', self.email)

        if function:
            vcard.add_line('TITLE', self.function)

        if self.phone:
            vcard.add_line('TEL', self.phone, TYPE='WORK')
        if self.mobile:
            vcard.add_line('TEL', self.mobile, TYPE='CELL')

        if self.fax:
            vcard.add_line('TEL', self.fax, TYPE='FAX')
        if self.website:
            vcard.add_line('URL', self.website)

        if self.primary_group:
            group_name = self.primary_group.safe_translation_getter(
                'name', default="Group: {0}".format(self.primary_group.pk))
            if group_name:
                vcard.add_line('ORG', group_name)
            if (self.primary_group.address or self.primary_group.city or
                    self.primary_group.postal_code):
                vcard.add_line('ADR', (
                    None, None,
                    self.primary_group.address,
                    self.primary_group.city,
                    None,
                    self.primary_group.postal_code,
                    None,
                ), TYPE='WORK')

            if self.primary_group.phone:
                vcard.add_line('TEL', self.primary_group.phone, TYPE='WORK')
            if self.primary_group.fax:
                vcard.add_line('TEL', self.primary_group.fax, TYPE='FAX')
            if self.primary_group.website:
                vcard.add_line('URL', self.primary_group.website)

        if six.PY2:
            vcard = unicode(vcard)

        return vcard
Example #36
0
 def test_app_config_get_app_title(self):
     with override('en'):
         self.assertEquals('Things',
                           force_text(self.app_config.get_app_title()))
Example #37
0
 def __str__(self):
     return force_text(self.driver)
Example #38
0
 def __repr__(self):
     return 'Wizard: "{0}"'.format(force_text(self.title))
Example #39
0
 def __repr__(self):
     return 'Wizard: "{0}"'.format(force_text(self.title))
Example #40
0
 def __str__(self):
     return force_text(self.title)
 def _verbose(string):
     return force_text(string).capitalize()
Example #42
0
    def get_vcard(self, request=None):
        vcard = Vcard()
        person_translation = self.translations.model.objects.get(
            master_id=self.id, language_code='en')
        function = person_translation.function

        safe_name = person_translation.name
        vcard.add_line('FN', safe_name)
        vcard.add_line('N', [None, safe_name, None, None, None])

        if self.visual:
            ext = self.visual.extension.upper()
            try:
                with open(self.visual.path, 'rb') as f:
                    data = force_text(base64.b64encode(f.read()))
                    vcard.add_line('PHOTO', data, TYPE=ext, ENCODING='b')
            except IOError:
                if request:
                    url = urlparse.urljoin(request.build_absolute_uri(),
                                           self.visual.url),
                    vcard.add_line('PHOTO', url, TYPE=ext)

        if self.email:
            vcard.add_line('EMAIL', self.email)

        if function:
            vcard.add_line('TITLE', function)

        if self.phone:
            vcard.add_line('TEL', self.phone, TYPE='WORK')
        if self.mobile:
            vcard.add_line('TEL', self.mobile, TYPE='CELL')

        if self.fax:
            vcard.add_line('TEL', self.fax, TYPE='FAX')
        if self.website:
            vcard.add_line('URL', self.website)

        # if self.primary_group:
        #     group_name = self.primary_group.safe_translation_getter(
        #         'name', default="Group: {0}".format(self.primary_group.pk))
        #     if group_name:
        #         vcard.add_line('ORG', group_name)
        #     if (self.primary_group.address or self.primary_group.city or
        #             self.primary_group.postal_code):
        #         vcard.add_line('ADR', (
        #             None, None,
        #             self.primary_group.address,
        #             self.primary_group.city,
        #             None,
        #             self.primary_group.postal_code,
        #             None,
        #         ), TYPE='WORK')
        #
        #     if self.primary_group.phone:
        #         vcard.add_line('TEL', self.primary_group.phone, TYPE='WORK')
        #     if self.primary_group.fax:
        #         vcard.add_line('TEL', self.primary_group.fax, TYPE='FAX')
        #     if self.primary_group.website:
        #         vcard.add_line('URL', self.primary_group.website)

        return str(vcard)
Example #43
0
 def test_app_config_get_app_title(self):
     with override('en'):
         self.assertEquals('Things',
                           force_text(self.app_config.get_app_title()))
Example #44
0
 def default(self, obj):
     if isinstance(obj, Promise):
         return force_text(obj)
     return super(LazyEncoder, self).default(obj)
Example #45
0
    def get_cache_expiration(self, request, response_timestamp):
        """
        Returns the number of seconds (from «response_timestamp») that this
        placeholder can be cached. This is derived from the plugins it contains.

        This method must return: EXPIRE_NOW <= int <= MAX_EXPIRATION_IN_SECONDS

        :type request: HTTPRequest
        :type response_timestamp: datetime
        :rtype: int
        """
        min_ttl = MAX_EXPIRATION_TTL

        if not self.cache_placeholder or not get_cms_setting('PLUGIN_CACHE'):
            # This placeholder has a plugin with an effective
            # `cache = False` setting or the developer has explicitly
            # disabled the PLUGIN_CACHE, so, no point in continuing.
            return EXPIRE_NOW

        def inner_plugin_iterator(lang):
            """
            The placeholder will have a cache of all the concrete plugins it
            uses already, but just in case it doesn't, we have a code-path to
            generate them anew.

            This is made extra private as an inner function to avoid any other
            process stealing our yields.
            """
            if hasattr(self, '_all_plugins_cache'):
                for instance in self._all_plugins_cache:
                    plugin = instance.get_plugin_class_instance()
                    yield instance, plugin
            else:
                for plugin_item in self.get_plugins(lang):
                    yield plugin_item.get_plugin_instance()

        language = get_language_from_request(request, self.page)
        for instance, plugin in inner_plugin_iterator(language):
            plugin_expiration = plugin.get_cache_expiration(
                request, instance, self)

            # The plugin_expiration should only ever be either: None, a TZ-
            # aware datetime, a timedelta, or an integer.
            if plugin_expiration is None:
                # Do not consider plugins that return None
                continue
            if isinstance(plugin_expiration, (datetime, timedelta)):
                if isinstance(plugin_expiration, datetime):
                    # We need to convert this to a TTL against the
                    # response timestamp.
                    try:
                        delta = plugin_expiration - response_timestamp
                    except TypeError:
                        # Attempting to take the difference of a naive datetime
                        # and a TZ-aware one results in a TypeError. Ignore
                        # this plugin.
                        warnings.warn(
                            'Plugin %(plugin_class)s (%(pk)d) returned a naive '
                            'datetime : %(value)s for get_cache_expiration(), '
                            'ignoring.' % {
                                'plugin_class': plugin.__class__.__name__,
                                'pk': instance.pk,
                                'value': force_text(plugin_expiration),
                            })
                        continue
                else:
                    # Its already a timedelta instance...
                    delta = plugin_expiration
                ttl = int(delta.total_seconds() + 0.5)
            else:  # must be an int-like value
                try:
                    ttl = int(plugin_expiration)
                except ValueError:
                    # Looks like it was not very int-ish. Ignore this plugin.
                    warnings.warn(
                        'Plugin %(plugin_class)s (%(pk)d) returned '
                        'unexpected value %(value)s for '
                        'get_cache_expiration(), ignoring.' % {
                            'plugin_class': plugin.__class__.__name__,
                            'pk': instance.pk,
                            'value': force_text(plugin_expiration),
                        })
                    continue

            min_ttl = min(ttl, min_ttl)
            if min_ttl <= 0:
                # No point in continuing, we've already hit the minimum
                # possible expiration TTL
                return EXPIRE_NOW

        return min_ttl
Example #46
0
 def _verbose(string):
     return force_text(string).capitalize()
Example #47
0
 def get_platform_display(self):
     return force_text(amo.PLATFORMS[self.platform].name)
Example #48
0
def convert_to_js_str(val):
    val = force_text(val).replace('\'', '\\\'')
    return u"'%s'" % val
Example #49
0
 def get_platform_display(self):
     return force_text(amo.PLATFORMS[self.platform].name)
Example #50
0
    def get_cache_expiration(self, request, response_timestamp):
        """
        Returns the number of seconds (from «response_timestamp») that this
        placeholder can be cached. This is derived from the plugins it contains.

        This method must return: EXPIRE_NOW <= int <= MAX_EXPIRATION_IN_SECONDS

        :type request: HTTPRequest
        :type response_timestamp: datetime
        :rtype: int
        """
        min_ttl = MAX_EXPIRATION_TTL

        if not self.cache_placeholder or not get_cms_setting('PLUGIN_CACHE'):
            # This placeholder has a plugin with an effective
            # `cache = False` setting or the developer has explicitly
            # disabled the PLUGIN_CACHE, so, no point in continuing.
            return EXPIRE_NOW

        def inner_plugin_iterator(lang):
            """
            The placeholder will have a cache of all the concrete plugins it
            uses already, but just in case it doesn't, we have a code-path to
            generate them anew.

            This is made extra private as an inner function to avoid any other
            process stealing our yields.
            """
            if hasattr(self, '_all_plugins_cache'):
                for instance in self._all_plugins_cache:
                    plugin = instance.get_plugin_class_instance()
                    yield instance, plugin
            else:
                for plugin_item in self.get_plugins(lang):
                    yield plugin_item.get_plugin_instance()

        language = get_language_from_request(request, self.page)
        for instance, plugin in inner_plugin_iterator(language):
            plugin_expiration = plugin.get_cache_expiration(
                request, instance, self)

            # The plugin_expiration should only ever be either: None, a TZ-
            # aware datetime, a timedelta, or an integer.
            if plugin_expiration is None:
                # Do not consider plugins that return None
                continue
            if isinstance(plugin_expiration, (datetime, timedelta)):
                if isinstance(plugin_expiration, datetime):
                    # We need to convert this to a TTL against the
                    # response timestamp.
                    try:
                        delta = plugin_expiration - response_timestamp
                    except TypeError:
                        # Attempting to take the difference of a naive datetime
                        # and a TZ-aware one results in a TypeError. Ignore
                        # this plugin.
                        warnings.warn(
                            'Plugin %(plugin_class)s (%(pk)d) returned a naive '
                            'datetime : %(value)s for get_cache_expiration(), '
                            'ignoring.' % {
                                'plugin_class': plugin.__class__.__name__,
                                'pk': instance.pk,
                                'value': force_text(plugin_expiration),
                            })
                        continue
                else:
                    # Its already a timedelta instance...
                    delta = plugin_expiration
                ttl = int(delta.total_seconds() + 0.5)
            else:  # must be an int-like value
                try:
                    ttl = int(plugin_expiration)
                except ValueError:
                    # Looks like it was not very int-ish. Ignore this plugin.
                    warnings.warn(
                        'Plugin %(plugin_class)s (%(pk)d) returned '
                        'unexpected value %(value)s for '
                        'get_cache_expiration(), ignoring.' % {
                            'plugin_class': plugin.__class__.__name__,
                            'pk': instance.pk,
                            'value': force_text(plugin_expiration),
                        })
                    continue

            min_ttl = min(ttl, min_ttl)
            if min_ttl <= 0:
                # No point in continuing, we've already hit the minimum
                # possible expiration TTL
                return EXPIRE_NOW

        return min_ttl
Example #51
0
def convert_to_js_str(val):
    val = force_text(val).replace('\'', '\\\'')
    return u"'%s'" % val
Example #52
0
 def test_str(self):
     name = 'Person Str'
     person = Person.objects.create(name=name)
     self.assertEqual(force_text(person), name)
Example #53
0
 def test_str(self):
     name = 'Person Str'
     person = Person.objects.create(name=name)
     self.assertEqual(force_text(person), name)
Example #54
0
 def default(self, o):
     if isinstance(o, Promise):
         return force_text(o)
     else:
         return super(LazyEncoder, self).default(o)