def generic_story( self, header=None, body=None, postscriptum=None, story_type='new story type', section='new section'): new_section, new = Section.objects.get_or_create(title=section) new_story_type, new = StoryType.objects.get_or_create(name=story_type, section=new_section) header = header or ''' @tit: A New Story ''' body = body or ''' @mt: Pitchfork Schlitz fixie hoodie Gastropub YOLO small batch kitsch. Fingerstache direct trade messenger bag, freegan 3 wolf moon squid Truffaut. Distillery vinyl, Bushwick vegan deep v street art roof party normcore. Direct trade craft beer banh mi selvage. Neutra lo-fi drinking vinegar, cold-pressed selvage Kickstarter Schlitz literally distillery food. @mt: Truck vegan meditation farm-to-table authentic. @txt:Crucifix beard cred, hoodie ennui sustainable blog before they sold out small batch squid biodiesel. Tote bag XOXO Wes Anderson 3 wolf moon. Marfa vegan health goth Neutra drinking vinegar. @mt:Fingerstache quinoa High Life Put a bird on it PBR&B four loko master cleanse Shoreditch single-origin coffee DIY sriracha. Lomo normcore food truck put a bird on it Bushwick Schlitz ugh Brooklyn McSweeney's fashion axe. Farm-to-table Tonx banjo, gluten-free leggings master cleanse kogi keytar normcore pour-over tofu sartorial. ''' postscriptum = postscriptum or ''' @bl:foto:Bob cameraguy; text: Liza Writer Genious ''' bodytext = '{}\n{}\n{}'.format(header, body, postscriptum) bodytext = re.sub(r'\s*\n\s*', '\n', bodytext) new_story = Story(bodytext_markup=bodytext, story_type=new_story_type) new_story.save() return new_story
def test_find_inlines(self): text = re.sub( r'\s*\n\s*', '\n', """ @tit: lol @txt: no chance @image: < 1 3 50 sdlkfjslkfjalkjdf slkdfj sldkfj aa allslsdkf @mt: oh no! @box: 3 @quote: > 1 @image: 44 444 4 """, ).strip() story = Story(bodytext_markup=text) image_placeholders = story.find_inline_placeholders(element_class=StoryImage) self.assertEqual(len(image_placeholders), 2) self.assertEqual(image_placeholders[1]['indexes'], [44, 444, 4]) self.assertEqual(image_placeholders[0]['flags'][0], '<') pullquote_placeholders = story.find_inline_placeholders(element_class=Pullquote) self.assertEqual(len(pullquote_placeholders), 1) self.assertEqual(pullquote_placeholders[0]['indexes'], [1]) self.assertEqual(pullquote_placeholders[0]['flags'], ['>'])
def another_hope(): story = Story( title='Another Hope', kicker='Episode IV', lede=""" It is a period of civil war. Rebel spaceships, striking from a hidden base, have won their first victory against the evil Galactic Empire. """, bodytext_markup=""" @txt:During the battle, Rebel spies managed to steal secret plans to the Empire's ultimate weapon, the DEATH STAR, an armored space station with enough power to destroy an entire planet. @txt:Pursued by the Empire's sinister agents, Princess Leia races home aboard her starship, custodian of the stolen plans that can save her people and restore freedom to the galaxy.... """ ) story.save() Byline.create('text: George Lucas, film director', story) return story
def test_new_story(news): """It's possible to create an empty story""" empty_story = Story(story_type=news) empty_story.save() assert empty_story.id is not None html = empty_story.get_html() assert len(html) > 0
def another_hope(): story = Story(title='Another Hope', kicker='Episode IV', lede=""" It is a period of civil war. Rebel spaceships, striking from a hidden base, have won their first victory against the evil Galactic Empire. """, bodytext_markup=""" @txt:During the battle, Rebel spies managed to steal secret plans to the Empire's ultimate weapon, the DEATH STAR, an armored space station with enough power to destroy an entire planet. @txt:Pursued by the Empire's sinister agents, Princess Leia races home aboard her starship, custodian of the stolen plans that can save her people and restore freedom to the galaxy.... """) story.save() Byline.create('text: George Lucas, film director', story) return story
def generic_story(self, header=None, body=None, postscriptum=None, story_type='new story type', section='new section'): new_section, new = Section.objects.get_or_create(title=section) new_story_type, new = StoryType.objects.get_or_create( name=story_type, section=new_section) header = header or ''' @tit: A New Story ''' body = body or ''' @mt: Pitchfork Schlitz fixie hoodie Gastropub YOLO small batch kitsch. Fingerstache direct trade messenger bag, freegan 3 wolf moon squid Truffaut. Distillery vinyl, Bushwick vegan deep v street art roof party normcore. Direct trade craft beer banh mi selvage. Neutra lo-fi drinking vinegar, cold-pressed selvage Kickstarter Schlitz literally distillery food. @mt: Truck vegan meditation farm-to-table authentic. @txt:Crucifix beard cred, hoodie ennui sustainable blog before they sold out small batch squid biodiesel. Tote bag XOXO Wes Anderson 3 wolf moon. Marfa vegan health goth Neutra drinking vinegar. @mt:Fingerstache quinoa High Life Put a bird on it PBR&B four loko master cleanse Shoreditch single-origin coffee DIY sriracha. Lomo normcore food truck put a bird on it Bushwick Schlitz ugh Brooklyn McSweeney's fashion axe. Farm-to-table Tonx banjo, gluten-free leggings master cleanse kogi keytar normcore pour-over tofu sartorial. ''' postscriptum = postscriptum or ''' @bl:foto:Bob cameraguy; text: Liza Writer Genious ''' bodytext = '{}\n{}\n{}'.format(header, body, postscriptum) bodytext = re.sub(r'\s*\n\s*', '\n', bodytext) new_story = Story(bodytext_markup=bodytext, story_type=new_story_type) new_story.save() return new_story
def test_find_inlines(self): text = re.sub( r'\s*\n\s*', '\n', """ @tit: lol @txt: no chance @image: < 1 3 50 sdlkfjslkfjalkjdf slkdfj sldkfj aa allslsdkf @mt: oh no! @box: 3 @quote: > 1 @image: 44 444 4 """, ).strip() story = Story(bodytext_markup=text) image_placeholders = story.find_inline_placeholders( element_class=StoryImage) self.assertEqual(len(image_placeholders), 2) self.assertEqual(image_placeholders[1]['indexes'], [44, 444, 4]) self.assertEqual(image_placeholders[0]['flags'][0], '<') pullquote_placeholders = story.find_inline_placeholders( element_class=Pullquote) self.assertEqual(len(pullquote_placeholders), 1) self.assertEqual(pullquote_placeholders[0]['indexes'], [1]) self.assertEqual(pullquote_placeholders[0]['flags'], ['>'])
def react_frontpage_view(request, section=None, story=None, slug=None): """Main view for server side rendered content""" is_IE = 'Trident' in request.META.get('HTTP_USER_AGENT', '') cache_key = f'cached_page_{story or request.path}{"IE" if is_IE else ""}' if request.user.is_anonymous and not settings.DEBUG: if story: Story.register_visit_in_cache(story) response, path = cache.get(cache_key, (None, None)) if response: if path != request.path: return redirect(path) logger.debug(f'{cache_key} {request}') return response issues = any(request.path.startswith(word) for word in ('/utg', '/pdf')) redux_actions = get_redux_actions(request, story, issues) ssr_context = express.react_server_side_render( actions=redux_actions, url=request.build_absolute_uri(), path=request.path, ) if ssr_context.get('error'): logger.debug(json.dumps(ssr_context, indent=2)) try: pathname = ssr_context['state']['location']['pathname'] if pathname != request.path: return redirect(pathname) except KeyError: pass status_code = ssr_context.pop('HTTPStatus', 200) if status_code == 404 and request.path[-1] != '/': return redirect(request.path + '/') response = render( request, template_name='universitas-server-side-render.html', context={ 'ssr': ssr_context, 'IE': is_IE }, status=status_code, ) if request.user.is_anonymous and status_code == 200: timeout = 120 if request.path != '/': timeout *= 60 cache.set(cache_key, (response, request.path), timeout) return response
def react_frontpage_view(request, section=None, story=None, slug=None): """Main view for server side rendered content""" is_IE = 'Trident' in request.META.get('HTTP_USER_AGENT', '') cache_key = f'cached_page_{story or request.path}{"IE" if is_IE else ""}' if request.user.is_anonymous and not settings.DEBUG: if story: Story.register_visit_in_cache(story) response, path = cache.get(cache_key, (None, None)) if response: if path != request.path: return redirect(path) logger.debug(f'{cache_key} {request}') return response issues = any(request.path.startswith(word) for word in ('/utg', '/pdf')) redux_actions = get_redux_actions(request, story, issues) ssr_context = express.react_server_side_render( actions=redux_actions, url=request.build_absolute_uri(), path=request.path, ) if ssr_context.get('error'): logger.debug(json.dumps(ssr_context, indent=2)) try: pathname = ssr_context['state']['location']['pathname'] if pathname != request.path: return redirect(pathname) except KeyError: pass status_code = ssr_context.pop('HTTPStatus', 200) if status_code == 404 and request.path[-1] != '/': return redirect(request.path + '/') response = render( request, template_name='universitas-server-side-render.html', context={'ssr': ssr_context, 'IE': is_IE}, status=status_code, ) if request.user.is_anonymous and status_code == 200: timeout = 120 if request.path != '/': timeout *= 60 cache.set(cache_key, (response, request.path), timeout) return response
def _importer_prodsak(prodsak_id, replace_existing=False, autocrop=False, import_images=True): """ Create a Story with images from a prodsak object in the prodsys database. """ # Check if this story has been imported already. exists = Story.objects.filter(prodsak_id=prodsak_id) if exists: if replace_existing: exists.delete() else: return # Create a new Story. xtags, status, json, prodsak = _get_xtags_from_prodsys(prodsak_id) story_type = _get_story_type(prodsak.mappe) new_story = Story( prodsak_id=prodsak_id, bodytext_markup=xtags, story_type=story_type, publication_status=status, legacy_prodsys_source=json, ) new_story.save() logger.debug('story saved: {} {}'.format(new_story, new_story.pk)) # Import images from prodsys to the new Story. if import_images: _importer_bilder_fra_prodsys(prodsak, new_story, autocrop) new_story.full_clean() new_story.save(new=True)
def _importer_prodsak( prodsak_id, replace_existing=False, autocrop=False, import_images=True): """ Create a Story with images from a prodsak object in the prodsys database. """ # Check if this story has been imported already. exists = Story.objects.filter(prodsak_id=prodsak_id) if exists: if replace_existing: exists.delete() else: return # Create a new Story. xtags, status, json, prodsak = _get_xtags_from_prodsys(prodsak_id) story_type = _get_story_type(prodsak.mappe) new_story = Story( prodsak_id=prodsak_id, bodytext_markup=xtags, story_type=story_type, publication_status=status, legacy_prodsys_source=json, ) new_story.save() logger.debug('story saved: {} {}'.format(new_story, new_story.pk)) # Import images from prodsys to the new Story. if import_images: _importer_bilder_fra_prodsys(prodsak, new_story, autocrop) new_story.full_clean() new_story.save(new=True)
def fake_story(): photo_by = random_contributor() text_by = random_contributor() markup = '{}\n@bl: text: {}\n@bl: photo:{}'.format(fake_story_content(), text_by, photo_by) story = Story( story_type=random_storytype(), bodytext_markup=markup, publication_status=Story.STATUS_PUBLISHED, publication_date=timezone.now(), ) story.save() numphotos = random.choice([0, 1, 1, 3, 5]) for _ in range(numphotos): fake_story_image(story, photo_by) story.refresh_from_db() story.full_clean() story.frontpagestory_set.all().delete() story.save(new=True) return story
def fake_story(): photo_by = random_contributor() text_by = random_contributor() markup = '{}\n@bl: text: {}\n@bl: photo:{}'.format( fake_story_content(), text_by, photo_by ) story = Story( story_type=random_storytype(), bodytext_markup=markup, publication_status=Story.STATUS_PUBLISHED, publication_date=timezone.now(), ) story.save() numphotos = random.choice([0, 1, 1, 3, 5]) for _ in range(numphotos): fake_story_image(story, photo_by) story.refresh_from_db() story.full_clean() story.frontpagestory_set.all().delete() story.save() return story
def test_create_story_from_xtags(news): source = """ @tit:Hello World! @ing:A test story for you @txt:This story will rock the world! """ new_story = Story( story_type=news, bodytext_markup=source, ) tag_count = BlockTag.objects.count() assert tag_count == 20 new_story.clean() new_story.save() assert new_story.title == 'Hello World!' assert new_story.lede == 'A test story for you' assert 'bodytext' in new_story.get_html()
def _importer_websak(websak): """ Import a single story from legacy website. """ global count count += 1 # check if story exists try: old_story = Story.objects.get(id=websak.id_sak) logger.warn('{:>5} story already exists: {} {}'.format( count, old_story, old_story.pk)) return old_story except Story.DoesNotExist: pass # check whether this story has a parent story try: new_websak = Sak.objects.get(undersak=websak.pk) logger.warn('{:>5} Has parent: {} {}'.format(count, new_websak.pk, websak.pk)) return _importer_websak(new_websak) except Sak.DoesNotExist: pass except Sak.MultipleObjectsReturned: if websak.pk == 0: pass new_story = Story( id=websak.id_sak, publication_date=_make_aware(websak.dato), story_type=_get_story_type(websak.mappe), legacy_html_source=serializers.serialize('json', (websak, )), hit_count=websak.lesninger, ) try: prodsak_id = int(websak.filnavn) # No integer prodsak_id means that this article does not exist in prodsys. except (TypeError, ValueError): prodsak_id = None new_story.prodsak_id = prodsak_id try: # import this story from prodsys prodsak = _get_xtags_from_prodsys(prodsak_id=prodsak_id, status_in=[ Prodsak.READY_FOR_WEB, Prodsak.PUBLISHED_ON_WEB, Prodsak.ARCHIVED, ]) except Prodsak.DoesNotExist: # couldn't find the story in prodsys pass else: new_story.bodytext_markup = prodsak[0] new_story.publication_status = prodsak[1] new_story.prodsys_json = prodsak[2] if new_story.publication_status != Story.STATUS_PUBLISHED: # prodsys story cannot be used for import. # It was not found, never existed, or is malformed. # create xtags from the legacy website story instead. new_story.bodytext_markup = _websak_til_xtags(websak) new_story.publication_status = Story.STATUS_PUBLISHED if websak.undersak: try: undersak = Sak.objects.get(pk=websak.undersak) xtags = _websak_til_xtags(undersak).replace( '@tit:', '@undersaktit:') new_story.bodytext_markup += '\n' + xtags logger.debug('undersak: {} len:{}'.format( websak.undersak, len(xtags))) except Sak.DoesNotExist: # Dangling reference in database. pass new_story.save() new_story.clean() new_story.save() logger.debug('{:>5} story saved: {} {}'.format(count, new_story, new_story.pk)) return new_story
def _importer_websak(websak): """ Import a single story from legacy website. """ global count count += 1 # check if story exists try: old_story = Story.objects.get(id=websak.id_sak) logger.warn( '{:>5} story already exists: {} {}'.format( count, old_story, old_story.pk)) return old_story except Story.DoesNotExist: pass # check whether this story has a parent story try: new_websak = Sak.objects.get(undersak=websak.pk) logger.warn( '{:>5} Has parent: {} {}'.format( count, new_websak.pk, websak.pk)) return _importer_websak(new_websak) except Sak.DoesNotExist: pass except Sak.MultipleObjectsReturned: if websak.pk == 0: pass new_story = Story( id=websak.id_sak, publication_date=_make_aware(websak.dato), story_type=_get_story_type(websak.mappe), legacy_html_source=serializers.serialize('json', (websak,)), hit_count=websak.lesninger, ) try: prodsak_id = int(websak.filnavn) # No integer prodsak_id means that this article does not exist in prodsys. except (TypeError, ValueError): prodsak_id = None new_story.prodsak_id = prodsak_id try: # import this story from prodsys prodsak = _get_xtags_from_prodsys( prodsak_id=prodsak_id, status_in=[ Prodsak.READY_FOR_WEB, Prodsak.PUBLISHED_ON_WEB, Prodsak.ARCHIVED, ]) except Prodsak.DoesNotExist: # couldn't find the story in prodsys pass else: new_story.bodytext_markup = prodsak[0] new_story.publication_status = prodsak[1] new_story.prodsys_json = prodsak[2] if new_story.publication_status != Story.STATUS_PUBLISHED: # prodsys story cannot be used for import. # It was not found, never existed, or is malformed. # create xtags from the legacy website story instead. new_story.bodytext_markup = _websak_til_xtags(websak) new_story.publication_status = Story.STATUS_PUBLISHED if websak.undersak: try: undersak = Sak.objects.get(pk=websak.undersak) xtags = _websak_til_xtags(undersak).replace( '@tit:', '@undersaktit:') new_story.bodytext_markup += '\n' + xtags logger.debug( 'undersak: {} len:{}'.format( websak.undersak, len(xtags))) except Sak.DoesNotExist: # Dangling reference in database. pass new_story.save() new_story.clean() new_story.save() logger.debug( '{:>5} story saved: {} {}'.format( count, new_story, new_story.pk)) return new_story