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'], )
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)
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)
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)
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)
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)
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))
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)
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
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))
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)
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(' ', '_')
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
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)
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)
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))
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 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 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
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))
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))
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)
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)
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)
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)
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
def test_app_config_get_app_title(self): with override('en'): self.assertEquals('Things', force_text(self.app_config.get_app_title()))
def __str__(self): return force_text(self.driver)
def __repr__(self): return 'Wizard: "{0}"'.format(force_text(self.title))
def __str__(self): return force_text(self.title)
def _verbose(string): return force_text(string).capitalize()
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)
def default(self, obj): if isinstance(obj, Promise): return force_text(obj) return super(LazyEncoder, self).default(obj)
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
def get_platform_display(self): return force_text(amo.PLATFORMS[self.platform].name)
def convert_to_js_str(val): val = force_text(val).replace('\'', '\\\'') return u"'%s'" % val
def test_str(self): name = 'Person Str' person = Person.objects.create(name=name) self.assertEqual(force_text(person), name)
def default(self, o): if isinstance(o, Promise): return force_text(o) else: return super(LazyEncoder, self).default(o)