def import_posts(self): category = self.get_category() self.write_out(self.style.STEP("- Importing entries\n")) for post in self.blogger_manager.get_posts(self.blogger_blog_id, self.blogger_limit): creation_date = convert_blogger_timestamp(post.published.text) status = DRAFT if is_draft(post) else PUBLISHED title = post.title.text or "" content = post.content.text or "" excerpt = self.auto_excerpt and Truncator(strip_tags(smart_unicode(content))).words(50) or "" slug = slugify(post.title.text or get_post_id(post))[:255] try: entry = Entry.objects.get(creation_date=creation_date, slug=slug) output = self.style.NOTICE("> Skipped %s (already migrated)\n" % entry) except Entry.DoesNotExist: entry = Entry( status=status, title=title, content=content, creation_date=creation_date, slug=slug, excerpt=excerpt ) entry.tags = ",".join([slugify(cat.term) for cat in post.category]) entry.last_update = convert_blogger_timestamp(post.updated.text) entry.save() entry.sites.add(self.SITE) entry.categories.add(category) entry.authors.add(self.default_author) try: self.import_comments(entry, post) except gdata_service.RequestError: # comments not available for this post pass entry.comment_count = entry.comments.count() entry.save(force_update=True) output = self.style.ITEM("> Migrated %s + %s comments\n" % (entry.title, entry.comment_count)) self.write_out(output)
def import_from_rss(rss_as_bytes): rss = objectify.fromstring(rss_as_bytes) current_site = Site.objects.get_current() for item in rss.channel.item: blob = unicode(item['{%s}encoded' % item.nsmap['content']]) category, _ = Category.objects.get_or_create( slug=my_slugify(unicode(item.category.text)), title=unicode(item.category.text) ) entry = Entry() cms_content = Content() cms_content.save() process_html_blob(blob, cms_content) entry.content_ptr = cms_content entry.title = unicode(item.title.text) entry.creation_date = parse_rss_date(unicode(item.pubDate)) entry.slug = my_slugify(entry.title) entry.save() entry.sites.add(current_site) entry.categories.add(category) link = unicode(item.link.text) _url_cache[link] = entry.get_absolute_url() _url_cache[re.sub("^https", "http", link)] = entry.get_absolute_url() add_redirect(link, entry.get_absolute_url())
def import_posts(self): category = self.get_category() self.write_out(self.style.STEP('- Importing entries\n')) for post in self.blogger_manager.get_posts(self.blogger_blog_id, self.blogger_limit): creation_date = convert_blogger_timestamp(post.published.text) status = DRAFT if is_draft(post) else PUBLISHED title = post.title.text or '' content = post.content.text or '' excerpt = self.auto_excerpt and Truncator( strip_tags(content)).words(50) or '' slug = slugify(post.title.text or get_post_id(post))[:255] try: entry = Entry.objects.get(creation_date=creation_date, slug=slug) output = self.style.NOTICE( '> Skipped %s (already migrated)\n' % entry) except Entry.DoesNotExist: entry = Entry(status=status, title=title, content=content, creation_date=creation_date, slug=slug, excerpt=excerpt) if self.default_author: entry.author = self.default_author entry.tags = ','.join( [slugify(cat.term) for cat in post.category]) entry.last_update = convert_blogger_timestamp( post.updated.text) entry.save() entry.sites.add(self.SITE) entry.categories.add(category) entry.authors.add(self.default_author) try: self.import_comments(entry, post) except gdata_service.RequestError: # comments not available for this post pass entry.comment_count = entry.comments.count() entry.save(force_update=True) output = self.style.ITEM('> Migrated %s + %s comments\n' % (entry.title, entry.comment_count)) self.write_out(output)
def save(self, *args, **kwargs): if self.pk is None: # or if there is no entry? What is a good check? # take action on first save # NB! Try to make sure that the slug is unique so we can have separate links to separate messages entry = Entry( title=self.create_entry_title(), content=self.create_entry_content(), status=HIDDEN, ) entry.save() entry.slug = self.create_entry_slug() + '-' + str(entry.pk) entry.sites.add(Site.objects.get(pk=settings.SITE_ID)) entry.authorized_users.add(self.user) entry.content_template += '.%s' % (self.__class__.__name__.lower()) entry.detail_template += '.%s' % (self.__class__.__name__.lower()) entry.save() # Should we perhaps save somewhere this Site.objects.get(pk=settings.SITE_ID) so we don't have to query it every time? Though, I guess, it is not such a big deal here, as we are rarely saving things that have associated blog posts. We are not generating blog posts (entries) every second... self.entry = entry else: if self.entry is None: pass # QUESTION. Should we still post? Better late than never? Though, with transactions, we'd never get here. super(PrivatelyPublishedModelMixin, self).save(*args, **kwargs)
def import_posts(self): category = self.get_category() self.write_out(self.style.STEP('- Importing entries\n')) for post in self.blogger_manager.get_posts(self.blogger_blog_id): creation_date = convert_blogger_timestamp(post.published.text) status = DRAFT if is_draft(post) else PUBLISHED title = post.title.text or '' content = post.content.text or '' slug = slugify(post.title.text or get_post_id(post))[:255] try: entry = Entry.objects.get(creation_date=creation_date, slug=slug) output = self.style.NOTICE('> Skipped %s (already migrated)\n' % entry) except Entry.DoesNotExist: entry = Entry(status=status, title=title, content=content, creation_date=creation_date, slug=slug) if self.default_author: entry.author = self.default_author entry.tags = ','.join([slugify(cat.term) for cat in post.category]) entry.last_update = convert_blogger_timestamp( post.updated.text) entry.save() entry.sites.add(self.SITE) entry.categories.add(category) entry.authors.add(self.default_author) try: self.import_comments(entry, post) except gdata_service.RequestError: # comments not available for this post pass output = self.style.ITEM('> Migrated %s + %s comments\n' % (entry.title, len(Comment.objects.for_model(entry)))) self.write_out(output)
def import_entries(self, feed_entries): """Import entries""" for feed_entry in feed_entries: self.write_out('> %s... ' % feed_entry.title) if feed_entry.get('publised_parsed'): creation_date = datetime(*feed_entry.published_parsed[:6]) if settings.USE_TZ: creation_date = timezone.make_aware( creation_date, timezone.utc) else: creation_date = timezone.now() slug = slugify(feed_entry.title)[:255] if Entry.objects.filter(creation_date__year=creation_date.year, creation_date__month=creation_date.month, creation_date__day=creation_date.day, slug=slug): self.write_out(self.style.NOTICE( 'SKIPPED (already imported)\n')) continue categories = self.import_categories(feed_entry) entry_dict = {'title': feed_entry.title[:255], 'content': feed_entry.description, 'excerpt': feed_entry.get('summary'), 'status': PUBLISHED, 'creation_date': creation_date, 'start_publication': creation_date, 'last_update': timezone.now(), 'slug': slug} if not entry_dict['excerpt'] and self.auto_excerpt: entry_dict['excerpt'] = Truncator( strip_tags(feed_entry.description)).words(50) if self.tags: entry_dict['tags'] = self.import_tags(categories) entry = Entry(**entry_dict) entry.save() entry.categories.add(*categories) entry.sites.add(self.SITE) if self.image_enclosure: for enclosure in feed_entry.enclosures: if 'image' in enclosure.get('type') \ and enclosure.get('href'): img_tmp = NamedTemporaryFile(delete=True) img_tmp.write(urlopen(enclosure['href']).read()) img_tmp.flush() entry.image.save(os.path.basename(enclosure['href']), File(img_tmp)) break if self.default_author: entry.authors.add(self.default_author) elif feed_entry.get('author_detail'): try: author = Author.objects.create_user( slugify(feed_entry.author_detail.get('name')), feed_entry.author_detail.get('email', '')) except IntegrityError: author = Author.objects.get( username=slugify(feed_entry.author_detail.get('name'))) entry.authors.add(author) self.write_out(self.style.ITEM('OK\n'))
def test_restricted_access(self): client = Client() user_g = create_test_user("Guido van Rossum", "*****@*****.**", "3jh3j") user_h = create_test_user("Hilda von Varden", "*****@*****.**", "777777777") # must specify slug. Otherwise get_aboslute_url is broken and will get NoReverseMatch. entry = Entry(title="Django's wonderful permalink decorator 12321", slug="django", status=PUBLISHED, start_publication=datetime.datetime( 2011, 8, 15, 8, 15, 12, 0, pytz.UTC)) private_entry_g = Entry( title="Secret communication of Guido with space travellers", slug="secret-never-see", status=HIDDEN) private_entry_h = Entry( title="Hilda spent her vacation in New Zealand", slug="-k-a-n-g-a-r-o-o-", status=HIDDEN) ### NB! ### This will fail with an in-memory sqlite3 database, but works fine with an on-disk sqlite3 database. With in-memory database it fails with 'no such table zinnia_category'. If we omit status-PUBLISHED, it works just fine. This is really weird, because the code in a previous test manually queries the database (as sqlite3) and confirms that various Zinnia tables exist, including 'zinnia_category'. Perhaps, Zinnia has some extra functionality when saving PUBLISHED entries, and it does something that breaks with an in-memory database... entry.save() private_entry_g.save() private_entry_h.save() # Adding the respective users as authorized. We can only do it after first saving the models. private_entry_g.authorized_users.add(user_g) private_entry_g.save() private_entry_h.authorized_users.add(user_h) private_entry_h.save() # Logging in user_g client.login(username='******', password='******') # Now, we did not set the site for the new entries (see django.contrib.sites). # Thus, we do not expect them to show up when we follow a direct link. # By the way, they still shows up in the dashboard; this is probably a Zinnia issue. self.assertEqual(client.get(entry.get_absolute_url()).status_code, 404) self.assertEqual( client.get(private_entry_g.get_absolute_url()).status_code, 404) self.assertEqual( client.get(private_entry_h.get_absolute_url()).status_code, 404) # django.contrib.sites # Adding the current site to the Entry. # Otherwise it will not be displayed in the detailed view. # For some weird reason it is still displayed in the dashboard (that is, zinnia archive of entries). Created an issue for Zinnia on github... self.site = Site.objects.get(pk=settings.SITE_ID) entry.sites.add(self.site) entry.save() private_entry_g.sites.add(self.site) private_entry_g.save() private_entry_h.sites.add(self.site) private_entry_h.save() # Test a direct link to the entries. We should see the public entry and the private entry by one of the users self.assertContains(client.get(entry.get_absolute_url()), 'wonderful permalink decorator 12321', status_code=200) # self.assertContains(client.get(private_entry_g.get_absolute_url()), 'Secret communication of Guido with', status_code=200) # self.assertEquals(client.get(private_entry_h.get_absolute_url()).status_code, 404) # Also, there should be no link to the hidden entry from the detail view of other entries! self.assertNotContains(client.get(entry.get_absolute_url()), private_entry_h.get_absolute_url()) self.assertNotContains(client.get(private_entry_g.get_absolute_url()), private_entry_h.get_absolute_url()) # Test the dashboard response_dash = client.get(reverse('dashboard'), follow=True) self.assertContains(response_dash, 'wonderful permalink decorator 12321', status_code=200) self.assertContains(response_dash, 'Secret communication of Guido with', status_code=200) self.assertNotContains(response_dash, 'spent her vacation', status_code=200) # The dashboard should contain links "Continue Reading" to the visible posts self.assertContains(response_dash, entry.get_absolute_url()) # self.assertContains(response_dash, private_entry_g.get_absolute_url()) # self.assertNotContains(response_dash, private_entry_h.get_absolute_url()) client.logout() # LOG OUT. # Still try a direct link to a public entry! But the private one should return 404. self.assertContains(client.get(entry.get_absolute_url()), 'wonderful permalink decorator 12321', status_code=200) self.assertEquals( client.get(private_entry_g.get_absolute_url()).status_code, 404) self.assertEquals( client.get(private_entry_h.get_absolute_url()).status_code, 404) # Since we are logged out, the public entry cannot show links to either hidden entry self.assertNotContains(client.get(entry.get_absolute_url()), private_entry_g.get_absolute_url()) self.assertNotContains(client.get(entry.get_absolute_url()), private_entry_h.get_absolute_url()) # Now logging in user_h client.login(username="******", password="******") # Test a direct link to the entries. We should see the public entry and the private entry by the other user self.assertContains(client.get(entry.get_absolute_url()), 'wonderful permalink decorator 12321', status_code=200) self.assertEquals( client.get(private_entry_g.get_absolute_url()).status_code, 404) self.assertContains(client.get(private_entry_h.get_absolute_url()), 'Hilda spent her vacation in New Zealand', status_code=200) # Also, there should be no link to the hidden entry from the detail view of other entries! # self.assertNotContains(client.get(entry.get_absolute_url()), private_entry_g.get_absolute_url()) # self.assertNotContains(client.get(private_entry_h.get_absolute_url()), private_entry_g.get_absolute_url()) # Test the dashboard response_dash = client.get(reverse('dashboard'), follow=True) self.assertContains(response_dash, 'wonderful permalink decorator 12321', status_code=200) self.assertNotContains(response_dash, 'Secret communication of Guido with', status_code=200) self.assertContains(response_dash, 'spent her vacation', status_code=200) # The dashboard should contain links "Continue Reading" to the visible posts self.assertContains(response_dash, entry.get_absolute_url()) # self.assertNotContains(response_dash, private_entry_g.get_absolute_url()) # self.assertContains(response_dash, private_entry_h.get_absolute_url()) client.logout()
def import_entries(self, feed_entries): """ Import entries. """ for feed_entry in feed_entries: self.write_out('> %s... ' % feed_entry.title) if feed_entry.get('published_parsed'): creation_date = datetime(*feed_entry.published_parsed[:6]) if settings.USE_TZ: creation_date = timezone.make_aware( creation_date, timezone.utc) else: creation_date = timezone.now() slug = slugify(feed_entry.title)[:255] if Entry.objects.filter(creation_date__year=creation_date.year, creation_date__month=creation_date.month, creation_date__day=creation_date.day, slug=slug): self.write_out( self.style.NOTICE('SKIPPED (already imported)\n')) continue categories = self.import_categories(feed_entry) entry_dict = { 'title': feed_entry.title[:255], 'content': feed_entry.description, 'excerpt': strip_tags(feed_entry.get('summary')), 'status': PUBLISHED, 'creation_date': creation_date, 'start_publication': creation_date, 'last_update': timezone.now(), 'slug': slug } if not entry_dict['excerpt'] and self.auto_excerpt: entry_dict['excerpt'] = Truncator( strip_tags(feed_entry.description)).words(50) if self.tags: entry_dict['tags'] = self.import_tags(categories) entry = Entry(**entry_dict) entry.save() entry.categories.add(*categories) entry.sites.add(self.SITE) if self.image_enclosure: for enclosure in feed_entry.enclosures: if ('image' in enclosure.get('type') and enclosure.get('href')): img_tmp = NamedTemporaryFile(delete=True) img_tmp.write(urlopen(enclosure['href']).read()) img_tmp.flush() entry.image.save(os.path.basename(enclosure['href']), File(img_tmp)) break if self.default_author: entry.authors.add(self.default_author) elif feed_entry.get('author_detail'): try: author = Author.objects.create_user( slugify(feed_entry.author_detail.get('name')), feed_entry.author_detail.get('email', '')) except IntegrityError: author = Author.objects.get( username=slugify(feed_entry.author_detail.get('name'))) entry.authors.add(author) self.write_out(self.style.ITEM('OK\n'))