зеркало из https://github.com/mozilla/bedrock.git
Fix bug 1055612: parse open standard rss
Add articles parsed from rss to new homepage Update tweets and open standard rss during deploy
This commit is contained in:
Родитель
37b1b6513c
Коммит
1e2055c25f
|
@ -27,357 +27,37 @@
|
|||
<option value="os-opinion" data-name="Opinion">{{ _('Opinion') }}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="os-container" id="os-live">
|
||||
{% for category in ('live', 'learn', 'innovate', 'engage', 'opinion') %}
|
||||
<div class="os-container" id="os-{{category}}">
|
||||
<ul class="os-headlines">
|
||||
{% for article in categorized_articles.get(category, []) %}
|
||||
<li role="presentation">
|
||||
<a href="http://techcrunch.com/2014/08/30/online-anonymity-will-soon-be-the-only-kind-we-have/" aria-controls="os-live-article-1">
|
||||
<h3>Online Anonymity Will Soon Be The Only Kind We Have</h3>
|
||||
<time>2 hours ago</time>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="http://reason.com/archives/2014/08/31/how-kids-find-online-privacy" aria-controls="os-live-article-2">
|
||||
<h3>How Kids Find Online Privacy</h3>
|
||||
<time>3 days ago</time>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="http://www.washingtonpost.com/business/on-it/at-gsa-an-internet-of-things-experiment/2014/08/30/403c620c-2e10-11e4-994d-202962a9150c_story.html" aria-controls="os-live-article-3">
|
||||
<h3>At GSA, an ‘Internet of Things’ experiment</h3>
|
||||
<time>Aug 16, 2014</time>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="http://www.postcrescent.com/story/money/2014/08/31/group-seeks-ban-drones-protect-privacy/14817525/" aria-controls="os-live-article-4">
|
||||
<h3>Group seeks ban on drones to protect privacy</h3>
|
||||
<time>Aug 2, 2014</time>
|
||||
<a href="#" aria-controls="os-{{category}}-article-{{ loop.index }}">
|
||||
<h3>{{ article.title }}</h3>
|
||||
<time>{{ article.published|datetime }}</time>
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<div class="os-article-container">
|
||||
<article class="os-article" id="os-live-article-1">
|
||||
<h3>Online Anonymity Will Soon Be The Only Kind We Have</h3>
|
||||
{% for article in categorized_articles.get(category, []) %}
|
||||
<article class="os-article" id="os-{{category}}-article-{{ loop.index }}">
|
||||
<h3>{{ article.title }}</h3>
|
||||
<p class="meta">
|
||||
<time>3 days ago</time> <span class="tag">Innovate</span> Written by…
|
||||
<time>{{ article.published|datetime }}</time> <span class="tag">Innovate</span> Written by {{ article.author }}
|
||||
</p>
|
||||
{% if article.image %}
|
||||
<div class="article-img">
|
||||
<img src="http://lorempixel.com/460/296/technics" alt="">
|
||||
<img src="{{ article.image.get_absolute_url() }}" alt="{{ article.image.alt }}">
|
||||
</div>
|
||||
<p>Anonymity: it’s all the rage–Whisper, Secret–and it’s rage-inducing. A Brazilian court has ruled that Secret must be removed from app stores there, and existing installs must be remotely wiped. The UK’s House of Lords has essentially recommended the extinction of online anonymity. <a class="more" href="http://techcrunch.com/2014/08/30/online-anonymity-will-soon-be-the-only-kind-we-have/">Read more</a></p>
|
||||
</article>
|
||||
<article class="os-article" id="os-live-article-2">
|
||||
<h3>How Kids Find Online Privacy</h3>
|
||||
<p class="meta">
|
||||
<time>3 days ago</time> <span class="tag">Innovate</span> Written by…
|
||||
</p>
|
||||
<div class="article-img">
|
||||
<img src="http://lorempixel.com/460/296/people" alt="">
|
||||
</div>
|
||||
<p>Anthropologist danah boyd (uncapitalization hers) is the author of It's Complicated: The Social Lives of Networked Teens (Yale University Press). In May, she told reason three ways kids find privacy online. <a class="more" href="http://reason.com/archives/2014/08/31/how-kids-find-online-privacy">Read more</a></p>
|
||||
</article>
|
||||
<article class="os-article" id="os-live-article-3">
|
||||
<h3>At GSA, an ‘Internet of Things’ experiment</h3>
|
||||
<p class="meta">
|
||||
<time>3 days ago</time> <span class="tag">Innovate</span> Written by…
|
||||
</p>
|
||||
<div class="article-img">
|
||||
<img src="http://lorempixel.com/460/296/cats" alt="">
|
||||
</div>
|
||||
<p>At the General Services Administration in downtown Washington, tiny white sensors pepper the windows, ceiling tiles, heating units, water tanks and fan coolers, almost blending in to the building’s open-plan decor. <a class="more" href="http://www.washingtonpost.com/business/on-it/at-gsa-an-internet-of-things-experiment/2014/08/30/403c620c-2e10-11e4-994d-202962a9150c_story.html">Read more</a></p>
|
||||
</article>
|
||||
<article class="os-article" id="os-live-article-4">
|
||||
<h3>Group seeks ban on drones to protect privacy</h3>
|
||||
<p class="meta">
|
||||
<time>3 days ago</time> <span class="tag">Innovate</span> Written by…
|
||||
</p>
|
||||
<div class="article-img">
|
||||
<img src="http://lorempixel.com/460/296/business" alt="">
|
||||
</div>
|
||||
<p>I few weeks ago I watched “Red,” one of my favorite movies. The action flick stars Bruce Willis, Morgan Freeman and Helen Mirren as ex-CIA agents who are RED — Retired: Extremely Dangerous. The agents unknowingly witnessed war crimes committed decades ago by the now vice president with aspirations for his boss’ job. <a class="more" href="http://www.postcrescent.com/story/money/2014/08/31/group-seeks-ban-drones-protect-privacy/14817525/">Read more</a></p>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
<div class="os-container" id="os-learn">
|
||||
<ul class="os-headlines">
|
||||
<li role="presentation">
|
||||
<a href="http://techcrunch.com/2014/08/30/online-anonymity-will-soon-be-the-only-kind-we-have/" aria-controls="os-live-article-1" aria-controls="os-learn-article-1">
|
||||
<h3>Online Anonymity Will Soon Be The Only Kind We Have</h3>
|
||||
<time>2 hours ago</time>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="http://reason.com/archives/2014/08/31/how-kids-find-online-privacy" aria-controls="os-learn-article-2">
|
||||
<h3>How Kids Find Online Privacy</h3>
|
||||
<time>3 days ago</time>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="http://www.washingtonpost.com/business/on-it/at-gsa-an-internet-of-things-experiment/2014/08/30/403c620c-2e10-11e4-994d-202962a9150c_story.html" aria-controls="os-learn-article-3">
|
||||
<h3>At GSA, an ‘Internet of Things’ experiment</h3>
|
||||
<time>Aug 16, 2014</time>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="http://www.postcrescent.com/story/money/2014/08/31/group-seeks-ban-drones-protect-privacy/14817525/" aria-controls="os-learn-article-4">
|
||||
<h3>Group seeks ban on drones to protect privacy</h3>
|
||||
<time>Aug 2, 2014</time>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="os-article-container">
|
||||
<article class="os-article" id="os-learn-article-1">
|
||||
<h3>Online Anonymity Will Soon Be The Only Kind We Have</h3>
|
||||
<p class="meta">
|
||||
<time>3 days ago</time> <span class="tag">Innovate</span> Written by…
|
||||
</p>
|
||||
<div class="article-img">
|
||||
<img src="http://lorempixel.com/460/296/technics" alt="">
|
||||
</div>
|
||||
<p>Anonymity: it’s all the rage–Whisper, Secret–and it’s rage-inducing. A Brazilian court has ruled that Secret must be removed from app stores there, and existing installs must be remotely wiped. The UK’s House of Lords has essentially recommended the extinction of online anonymity. <a class="more" href="http://techcrunch.com/2014/08/30/online-anonymity-will-soon-be-the-only-kind-we-have/">Read more</a></p>
|
||||
</article>
|
||||
<article class="os-article" id="os-learn-article-2">
|
||||
<h3>How Kids Find Online Privacy</h3>
|
||||
<p class="meta">
|
||||
<time>3 days ago</time> <span class="tag">Innovate</span> Written by…
|
||||
</p>
|
||||
<div class="article-img">
|
||||
<img src="http://lorempixel.com/460/296/people" alt="">
|
||||
</div>
|
||||
<p>Anthropologist danah boyd (uncapitalization hers) is the author of It's Complicated: The Social Lives of Networked Teens (Yale University Press). In May, she told reason three ways kids find privacy online. <a class="more" href="http://reason.com/archives/2014/08/31/how-kids-find-online-privacy">Read more</a></p>
|
||||
</article>
|
||||
<article class="os-article" id="os-learn-article-3">
|
||||
<h3>At GSA, an ‘Internet of Things’ experiment</h3>
|
||||
<p class="meta">
|
||||
<time>3 days ago</time> <span class="tag">Innovate</span> Written by…
|
||||
</p>
|
||||
<div class="article-img">
|
||||
<img src="http://lorempixel.com/460/296/cats" alt="">
|
||||
</div>
|
||||
<p>At the General Services Administration in downtown Washington, tiny white sensors pepper the windows, ceiling tiles, heating units, water tanks and fan coolers, almost blending in to the building’s open-plan decor. <a class="more" href="http://www.washingtonpost.com/business/on-it/at-gsa-an-internet-of-things-experiment/2014/08/30/403c620c-2e10-11e4-994d-202962a9150c_story.html">Read more</a></p>
|
||||
</article>
|
||||
<article class="os-article" id="os-learn-article-4">
|
||||
<h3>Group seeks ban on drones to protect privacy</h3>
|
||||
<p class="meta">
|
||||
<time>3 days ago</time> <span class="tag">Innovate</span> Written by…
|
||||
</p>
|
||||
<div class="article-img">
|
||||
<img src="http://lorempixel.com/460/296/business" alt="">
|
||||
</div>
|
||||
<p>I few weeks ago I watched “Red,” one of my favorite movies. The action flick stars Bruce Willis, Morgan Freeman and Helen Mirren as ex-CIA agents who are RED — Retired: Extremely Dangerous. The agents unknowingly witnessed war crimes committed decades ago by the now vice president with aspirations for his boss’ job. <a class="more" href="http://www.postcrescent.com/story/money/2014/08/31/group-seeks-ban-drones-protect-privacy/14817525/">Read more</a></p>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
<div class="os-container" id="os-innovate">
|
||||
<ul class="os-headlines">
|
||||
<li role="presentation">
|
||||
<a href="http://techcrunch.com/2014/08/30/online-anonymity-will-soon-be-the-only-kind-we-have/" aria-controls="os-live-article-1" aria-controls="os-innovate-article-1">
|
||||
<h3>Online Anonymity Will Soon Be The Only Kind We Have</h3>
|
||||
<time>2 hours ago</time>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="http://reason.com/archives/2014/08/31/how-kids-find-online-privacy" aria-controls="os-innovate-article-2">
|
||||
<h3>How Kids Find Online Privacy</h3>
|
||||
<time>3 days ago</time>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="http://www.washingtonpost.com/business/on-it/at-gsa-an-internet-of-things-experiment/2014/08/30/403c620c-2e10-11e4-994d-202962a9150c_story.html" aria-controls="os-innovate-article-3">
|
||||
<h3>At GSA, an ‘Internet of Things’ experiment</h3>
|
||||
<time>Aug 16, 2014</time>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="http://www.postcrescent.com/story/money/2014/08/31/group-seeks-ban-drones-protect-privacy/14817525/" aria-controls="os-innovate-article-4">
|
||||
<h3>Group seeks ban on drones to protect privacy</h3>
|
||||
<time>Aug 2, 2014</time>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="os-article-container">
|
||||
<article class="os-article" id="os-innovate-article-1">
|
||||
<h3>Online Anonymity Will Soon Be The Only Kind We Have</h3>
|
||||
<p class="meta">
|
||||
<time>3 days ago</time> <span class="tag">Innovate</span> Written by…
|
||||
</p>
|
||||
<div class="article-img">
|
||||
<img src="http://lorempixel.com/460/296/technics" alt="">
|
||||
</div>
|
||||
<p>Anonymity: it’s all the rage–Whisper, Secret–and it’s rage-inducing. A Brazilian court has ruled that Secret must be removed from app stores there, and existing installs must be remotely wiped. The UK’s House of Lords has essentially recommended the extinction of online anonymity. <a class="more" href="http://techcrunch.com/2014/08/30/online-anonymity-will-soon-be-the-only-kind-we-have/">Read more</a></p>
|
||||
</article>
|
||||
<article class="os-article" id="os-innovate-article-2">
|
||||
<h3>How Kids Find Online Privacy</h3>
|
||||
<p class="meta">
|
||||
<time>3 days ago</time> <span class="tag">Innovate</span> Written by…
|
||||
</p>
|
||||
<div class="article-img">
|
||||
<img src="http://lorempixel.com/460/296/people" alt="">
|
||||
</div>
|
||||
<p>Anthropologist danah boyd (uncapitalization hers) is the author of It's Complicated: The Social Lives of Networked Teens (Yale University Press). In May, she told reason three ways kids find privacy online. <a class="more" href="http://reason.com/archives/2014/08/31/how-kids-find-online-privacy">Read more</a></p>
|
||||
</article>
|
||||
<article class="os-article" id="os-innovate-article-3">
|
||||
<h3>At GSA, an ‘Internet of Things’ experiment</h3>
|
||||
<p class="meta">
|
||||
<time>3 days ago</time> <span class="tag">Innovate</span> Written by…
|
||||
</p>
|
||||
<div class="article-img">
|
||||
<img src="http://lorempixel.com/460/296/cats" alt="">
|
||||
</div>
|
||||
<p>At the General Services Administration in downtown Washington, tiny white sensors pepper the windows, ceiling tiles, heating units, water tanks and fan coolers, almost blending in to the building’s open-plan decor. <a class="more" href="http://www.washingtonpost.com/business/on-it/at-gsa-an-internet-of-things-experiment/2014/08/30/403c620c-2e10-11e4-994d-202962a9150c_story.html">Read more</a></p>
|
||||
</article>
|
||||
<article class="os-article" id="os-innovate-article-4">
|
||||
<h3>Group seeks ban on drones to protect privacy</h3>
|
||||
<p class="meta">
|
||||
<time>3 days ago</time> <span class="tag">Innovate</span> Written by…
|
||||
</p>
|
||||
<div class="article-img">
|
||||
<img src="http://lorempixel.com/460/296/business" alt="">
|
||||
</div>
|
||||
<p>I few weeks ago I watched “Red,” one of my favorite movies. The action flick stars Bruce Willis, Morgan Freeman and Helen Mirren as ex-CIA agents who are RED — Retired: Extremely Dangerous. The agents unknowingly witnessed war crimes committed decades ago by the now vice president with aspirations for his boss’ job. <a class="more" href="http://www.postcrescent.com/story/money/2014/08/31/group-seeks-ban-drones-protect-privacy/14817525/">Read more</a></p>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
<div class="os-container" id="os-engage">
|
||||
<ul class="os-headlines">
|
||||
<li role="presentation">
|
||||
<a href="http://techcrunch.com/2014/08/30/online-anonymity-will-soon-be-the-only-kind-we-have/" aria-controls="os-live-article-1" aria-controls="os-engage-article-1">
|
||||
<h3>Online Anonymity Will Soon Be The Only Kind We Have</h3>
|
||||
<time>2 hours ago</time>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="http://reason.com/archives/2014/08/31/how-kids-find-online-privacy" aria-controls="os-engage-article-2">
|
||||
<h3>How Kids Find Online Privacy</h3>
|
||||
<time>3 days ago</time>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="http://www.washingtonpost.com/business/on-it/at-gsa-an-internet-of-things-experiment/2014/08/30/403c620c-2e10-11e4-994d-202962a9150c_story.html" aria-controls="os-engage-article-3">
|
||||
<h3>At GSA, an ‘Internet of Things’ experiment</h3>
|
||||
<time>Aug 16, 2014</time>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="http://www.postcrescent.com/story/money/2014/08/31/group-seeks-ban-drones-protect-privacy/14817525/" aria-controls="os-engage-article-4">
|
||||
<h3>Group seeks ban on drones to protect privacy</h3>
|
||||
<time>Aug 2, 2014</time>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="os-article-container">
|
||||
<article class="os-article" id="os-engage-article-1">
|
||||
<h3>Online Anonymity Will Soon Be The Only Kind We Have</h3>
|
||||
<p class="meta">
|
||||
<time>3 days ago</time> <span class="tag">Innovate</span> Written by…
|
||||
</p>
|
||||
<div class="article-img">
|
||||
<img src="http://lorempixel.com/460/296/technics" alt="">
|
||||
</div>
|
||||
<p>Anonymity: it’s all the rage–Whisper, Secret–and it’s rage-inducing. A Brazilian court has ruled that Secret must be removed from app stores there, and existing installs must be remotely wiped. The UK’s House of Lords has essentially recommended the extinction of online anonymity. <a class="more" href="http://techcrunch.com/2014/08/30/online-anonymity-will-soon-be-the-only-kind-we-have/">Read more</a></p>
|
||||
</article>
|
||||
<article class="os-article" id="os-engage-article-2">
|
||||
<h3>How Kids Find Online Privacy</h3>
|
||||
<p class="meta">
|
||||
<time>3 days ago</time> <span class="tag">Innovate</span> Written by…
|
||||
</p>
|
||||
<div class="article-img">
|
||||
<img src="http://lorempixel.com/460/296/people" alt="">
|
||||
</div>
|
||||
<p>Anthropologist danah boyd (uncapitalization hers) is the author of It's Complicated: The Social Lives of Networked Teens (Yale University Press). In May, she told reason three ways kids find privacy online. <a class="more" href="http://reason.com/archives/2014/08/31/how-kids-find-online-privacy">Read more</a></p>
|
||||
</article>
|
||||
<article class="os-article" id="os-engage-article-3">
|
||||
<h3>At GSA, an ‘Internet of Things’ experiment</h3>
|
||||
<p class="meta">
|
||||
<time>3 days ago</time> <span class="tag">Innovate</span> Written by…
|
||||
</p>
|
||||
<div class="article-img">
|
||||
<img src="http://lorempixel.com/460/296/cats" alt="">
|
||||
</div>
|
||||
<p>At the General Services Administration in downtown Washington, tiny white sensors pepper the windows, ceiling tiles, heating units, water tanks and fan coolers, almost blending in to the building’s open-plan decor. <a class="more" href="http://www.washingtonpost.com/business/on-it/at-gsa-an-internet-of-things-experiment/2014/08/30/403c620c-2e10-11e4-994d-202962a9150c_story.html">Read more</a></p>
|
||||
</article>
|
||||
<article class="os-article" id="os-engage-article-4">
|
||||
<h3>Group seeks ban on drones to protect privacy</h3>
|
||||
<p class="meta">
|
||||
<time>3 days ago</time> <span class="tag">Innovate</span> Written by…
|
||||
</p>
|
||||
<div class="article-img">
|
||||
<img src="http://lorempixel.com/460/296/business" alt="">
|
||||
</div>
|
||||
<p>I few weeks ago I watched “Red,” one of my favorite movies. The action flick stars Bruce Willis, Morgan Freeman and Helen Mirren as ex-CIA agents who are RED — Retired: Extremely Dangerous. The agents unknowingly witnessed war crimes committed decades ago by the now vice president with aspirations for his boss’ job. <a class="more" href="http://www.postcrescent.com/story/money/2014/08/31/group-seeks-ban-drones-protect-privacy/14817525/">Read more</a></p>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
<div class="os-container" id="os-opinion">
|
||||
<ul class="os-headlines">
|
||||
<li role="presentation">
|
||||
<a href="http://techcrunch.com/2014/08/30/online-anonymity-will-soon-be-the-only-kind-we-have/" aria-controls="os-live-article-1" aria-controls="os-opinion-article-1">
|
||||
<h3>Online Anonymity Will Soon Be The Only Kind We Have</h3>
|
||||
<time>2 hours ago</time>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="http://reason.com/archives/2014/08/31/how-kids-find-online-privacy" aria-controls="os-opinion-article-2">
|
||||
<h3>How Kids Find Online Privacy</h3>
|
||||
<time>3 days ago</time>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="http://www.washingtonpost.com/business/on-it/at-gsa-an-internet-of-things-experiment/2014/08/30/403c620c-2e10-11e4-994d-202962a9150c_story.html" aria-controls="os-opinion-article-3">
|
||||
<h3>At GSA, an ‘Internet of Things’ experiment</h3>
|
||||
<time>Aug 16, 2014</time>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="http://www.postcrescent.com/story/money/2014/08/31/group-seeks-ban-drones-protect-privacy/14817525/" aria-controls="os-opinion-article-4">
|
||||
<h3>Group seeks ban on drones to protect privacy</h3>
|
||||
<time>Aug 2, 2014</time>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="os-article-container">
|
||||
<article class="os-article" id="os-opinion-article-1">
|
||||
<h3>Online Anonymity Will Soon Be The Only Kind We Have</h3>
|
||||
<p class="meta">
|
||||
<time>3 days ago</time> <span class="tag">Innovate</span> Written by…
|
||||
</p>
|
||||
<div class="article-img">
|
||||
<img src="http://lorempixel.com/460/296/technics" alt="">
|
||||
</div>
|
||||
<p>Anonymity: it’s all the rage–Whisper, Secret–and it’s rage-inducing. A Brazilian court has ruled that Secret must be removed from app stores there, and existing installs must be remotely wiped. The UK’s House of Lords has essentially recommended the extinction of online anonymity. <a class="more" href="http://techcrunch.com/2014/08/30/online-anonymity-will-soon-be-the-only-kind-we-have/">Read more</a></p>
|
||||
</article>
|
||||
<article class="os-article" id="os-opinion-article-2">
|
||||
<h3>How Kids Find Online Privacy</h3>
|
||||
<p class="meta">
|
||||
<time>3 days ago</time> <span class="tag">Innovate</span> Written by…
|
||||
</p>
|
||||
<div class="article-img">
|
||||
<img src="http://lorempixel.com/460/296/people" alt="">
|
||||
</div>
|
||||
<p>Anthropologist danah boyd (uncapitalization hers) is the author of It's Complicated: The Social Lives of Networked Teens (Yale University Press). In May, she told reason three ways kids find privacy online.</p>
|
||||
<p>1. Social steganography. The most common way teens find privacy is not by restricting access to content, but by restricting access to meaning. They encode what they're posting using in-jokes, song lyrics, pronouns, and references that outsiders won't recognize. <a class="more" href="http://reason.com/archives/2014/08/31/how-kids-find-online-privacy">Read more</a></p>
|
||||
</article>
|
||||
<article class="os-article" id="os-opinion-article-3">
|
||||
<h3>At GSA, an ‘Internet of Things’ experiment</h3>
|
||||
<p class="meta">
|
||||
<time>3 days ago</time> <span class="tag">Innovate</span> Written by…
|
||||
</p>
|
||||
<div class="article-img">
|
||||
<img src="http://lorempixel.com/460/296/cats" alt="">
|
||||
</div>
|
||||
<p>At the General Services Administration in downtown Washington, tiny white sensors pepper the windows, ceiling tiles, heating units, water tanks and fan coolers, almost blending in to the building’s open-plan decor. <a class="more" href="http://www.washingtonpost.com/business/on-it/at-gsa-an-internet-of-things-experiment/2014/08/30/403c620c-2e10-11e4-994d-202962a9150c_story.html">Read more</a></p>
|
||||
</article>
|
||||
<article class="os-article" id="os-opinion-article-4">
|
||||
<h3>Group seeks ban on drones to protect privacy</h3>
|
||||
<p class="meta">
|
||||
<time>3 days ago</time> <span class="tag">Innovate</span> Written by…
|
||||
</p>
|
||||
<div class="article-img">
|
||||
<img src="http://lorempixel.com/460/296/business" alt="">
|
||||
</div>
|
||||
<p>I few weeks ago I watched “Red,” one of my favorite movies. The action flick stars Bruce Willis, Morgan Freeman and Helen Mirren as ex-CIA agents who are RED — Retired: Extremely Dangerous. The agents unknowingly witnessed war crimes committed decades ago by the now vice president with aspirations for his boss’ job. <a class="more" href="http://www.postcrescent.com/story/money/2014/08/31/group-seeks-ban-drones-protect-privacy/14817525/">Read more</a></p>
|
||||
{% endif %}
|
||||
<p>{{ article.summary }}</p>
|
||||
<a class="more" href="{{ article.link }}">Read more</a>
|
||||
</article>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<a class="more-large" href="https://openstandard.mozilla.org/">{{ _('Read more articles') }}</a>
|
||||
</div>
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
{# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/. -#}
|
||||
|
||||
{% if l10n_has_tag('homepage_2015') or settings.DEV %}
|
||||
{% include 'mozorg/home/home-new.html' %}
|
||||
{% else %}
|
||||
{% include 'mozorg/home.html' %}
|
||||
{% endif %}
|
|
@ -1,4 +1,4 @@
|
|||
# -*- coding: utf8 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
@ -137,13 +137,6 @@ class TestHome(TestCase):
|
|||
ctx = resp_mock.call_args[0][2]
|
||||
self.assertEqual(ctx['mobilizer_link'], 'His Dudeness')
|
||||
|
||||
def test_can_post(self, resp_mock):
|
||||
"""Home page must accept post for newsletter signup."""
|
||||
req = self.rf.post('/')
|
||||
self.view(req)
|
||||
# would return 405 before calling render otherwise
|
||||
resp_mock.assert_called_once_with(req, ['mozorg/home/index.html'], ANY)
|
||||
|
||||
|
||||
class TestViews(TestCase):
|
||||
def test_hacks_newsletter_frames_allow(self):
|
||||
|
|
|
@ -8,7 +8,7 @@ from util import page
|
|||
import views
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url('^$', views.HomeTestView.as_view(), name='mozorg.home'),
|
||||
url('^$', views.home, name='mozorg.home'),
|
||||
page('about/manifesto', 'mozorg/about/manifesto.html'),
|
||||
page('about/manifesto/details', 'mozorg/about/manifesto-details.html'),
|
||||
page('about', 'mozorg/about.html'),
|
||||
|
|
|
@ -32,6 +32,7 @@ from bedrock.mozorg.models import TwitterCache
|
|||
from bedrock.mozorg.util import hide_contrib_form
|
||||
from bedrock.mozorg.util import HttpResponseJSON
|
||||
from bedrock.newsletter.forms import NewsletterFooterForm
|
||||
from bedrock.openstandard.utils import categorized_articles
|
||||
|
||||
|
||||
credits_file = CreditsFile('credits')
|
||||
|
@ -326,28 +327,42 @@ class Robots(TemplateView):
|
|||
|
||||
class HomeTestView(l10n_utils.LangFilesMixin, TemplateView):
|
||||
"""Home page view that will use a different template for a QS."""
|
||||
|
||||
template_name = 'mozorg/home/index.html'
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
# required for newsletter form post that is handled in newsletter/helpers.py
|
||||
return self.get(request, *args, **kwargs)
|
||||
template_name = 'mozorg/home.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super(HomeTestView, self).get_context_data(**kwargs)
|
||||
ctx['has_contribute'] = lang_file_is_active('mozorg/contribute')
|
||||
locale = l10n_utils.get_locale(self.request)
|
||||
|
||||
if locale in settings.HOMEPAGE_TWITTER_ACCOUNTS:
|
||||
account = settings.HOMEPAGE_TWITTER_ACCOUNTS[locale]
|
||||
try:
|
||||
ctx['tweets'] = TwitterCache.objects.get(account=account).tweets
|
||||
except (TwitterCache.DoesNotExist, DatabaseError):
|
||||
ctx['tweets'] = []
|
||||
else:
|
||||
ctx['tweets'] = []
|
||||
|
||||
locale = locale if locale in settings.MOBILIZER_LOCALE_LINK else 'en-US'
|
||||
ctx['mobilizer_link'] = settings.MOBILIZER_LOCALE_LINK[locale]
|
||||
|
||||
return ctx
|
||||
|
||||
|
||||
def home_tweets(locale):
|
||||
account = settings.HOMEPAGE_TWITTER_ACCOUNTS.get(locale)
|
||||
if account:
|
||||
try:
|
||||
return TwitterCache.objects.get(account=account).tweets
|
||||
except (TwitterCache.DoesNotExist, DatabaseError):
|
||||
pass # TODO: see if we should catch other errors
|
||||
return []
|
||||
|
||||
|
||||
def new_home(request, locale=None):
|
||||
locale = locale or l10n_utils.get_locale(request)
|
||||
return l10n_utils.render(
|
||||
request, 'mozorg/home/home-new.html', {
|
||||
'has_contribute': lang_file_is_active('mozorg/contribute'),
|
||||
'tweets': home_tweets(locale),
|
||||
'categorized_articles': categorized_articles(),
|
||||
'mobilizer_link': settings.MOBILIZER_LOCALE_LINK.get(
|
||||
locale, settings.MOBILIZER_LOCALE_LINK['en-US'])})
|
||||
|
||||
|
||||
def home(request):
|
||||
locale = l10n_utils.get_locale(request)
|
||||
new_template = 'mozorg/home/home-new.html'
|
||||
if l10n_utils.template_is_active(new_template, locale) or settings.DEV:
|
||||
return new_home(request, locale=locale)
|
||||
else:
|
||||
return HomeTestView.as_view()(request)
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
import cronjobs
|
||||
|
||||
from .utils import delete_old_articles, update_from_category_feeds
|
||||
|
||||
|
||||
@cronjobs.register
|
||||
def update_openstandard():
|
||||
update_from_category_feeds()
|
||||
delete_old_articles()
|
|
@ -0,0 +1,63 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from south.utils import datetime_utils as datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Adding model 'ArticleImage'
|
||||
db.create_table(u'openstandard_articleimage', (
|
||||
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('original', self.gf('django.db.models.fields.CharField')(max_length=2000)),
|
||||
('name', self.gf('django.db.models.fields.CharField')(max_length=2000)),
|
||||
('alt', self.gf('django.db.models.fields.CharField')(max_length=2000, blank=True)),
|
||||
))
|
||||
db.send_create_signal(u'openstandard', ['ArticleImage'])
|
||||
|
||||
# Adding model 'Article'
|
||||
db.create_table(u'openstandard_article', (
|
||||
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('author', self.gf('django.db.models.fields.CharField')(max_length=2000)),
|
||||
('category', self.gf('django.db.models.fields.CharField')(max_length=255)),
|
||||
('image', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['openstandard.ArticleImage'], null=True, blank=True)),
|
||||
('link', self.gf('django.db.models.fields.CharField')(max_length=2000)),
|
||||
('title', self.gf('django.db.models.fields.CharField')(max_length=2000)),
|
||||
('summary', self.gf('django.db.models.fields.CharField')(max_length=2000)),
|
||||
('published', self.gf('django.db.models.fields.DateTimeField')()),
|
||||
))
|
||||
db.send_create_signal(u'openstandard', ['Article'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting model 'ArticleImage'
|
||||
db.delete_table(u'openstandard_articleimage')
|
||||
|
||||
# Deleting model 'Article'
|
||||
db.delete_table(u'openstandard_article')
|
||||
|
||||
|
||||
models = {
|
||||
u'openstandard.article': {
|
||||
'Meta': {'object_name': 'Article'},
|
||||
'author': ('django.db.models.fields.CharField', [], {'max_length': '2000'}),
|
||||
'category': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'image': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['openstandard.ArticleImage']", 'null': 'True', 'blank': 'True'}),
|
||||
'link': ('django.db.models.fields.CharField', [], {'max_length': '2000'}),
|
||||
'published': ('django.db.models.fields.DateTimeField', [], {}),
|
||||
'summary': ('django.db.models.fields.CharField', [], {'max_length': '2000'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '2000'})
|
||||
},
|
||||
u'openstandard.articleimage': {
|
||||
'Meta': {'object_name': 'ArticleImage'},
|
||||
'alt': ('django.db.models.fields.CharField', [], {'max_length': '2000', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '2000'}),
|
||||
'original': ('django.db.models.fields.CharField', [], {'max_length': '2000'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['openstandard']
|
|
@ -0,0 +1,30 @@
|
|||
from django.conf import settings
|
||||
from django.db import models
|
||||
|
||||
|
||||
class ArticleImage(models.Model):
|
||||
original = models.CharField(max_length=2000)
|
||||
name = models.CharField(max_length=2000)
|
||||
alt = models.CharField(max_length=2000, blank=True)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return settings.OPENSTANDARD_IMAGE_URL + self.name
|
||||
|
||||
|
||||
class Article(models.Model):
|
||||
author = models.CharField(max_length=2000)
|
||||
category = models.CharField(max_length=255)
|
||||
image = models.ForeignKey(ArticleImage, blank=True, null=True)
|
||||
link = models.CharField(max_length=2000)
|
||||
title = models.CharField(max_length=2000)
|
||||
summary = models.CharField(max_length=2000)
|
||||
published = models.DateTimeField()
|
||||
|
||||
def __unicode__(self):
|
||||
return self.title
|
||||
|
||||
def get_absolute_url(self):
|
||||
return self.link
|
|
@ -0,0 +1,132 @@
|
|||
from itertools import groupby
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.cache import cache
|
||||
from django.utils import timezone as tz
|
||||
|
||||
import dateutil.parser
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
from feedparser import parse
|
||||
|
||||
from .models import Article, ArticleImage
|
||||
|
||||
|
||||
def copy_image(src):
|
||||
try:
|
||||
response = requests.get(src, stream=True, timeout=10)
|
||||
except:
|
||||
return
|
||||
if response.status_code != 200:
|
||||
return
|
||||
|
||||
name = src.split('/')[-1]
|
||||
with open(settings.OPENSTANDARD_IMAGE_ROOT + name, 'wb') as image_file:
|
||||
for chunk in response.iter_content(1024):
|
||||
image_file.write(chunk)
|
||||
|
||||
return name
|
||||
|
||||
|
||||
def get_or_maybe_create_article_image(soup):
|
||||
image_soup = soup.find('img')
|
||||
if not image_soup:
|
||||
return
|
||||
src = image_soup.attrs.get('src')
|
||||
if not src:
|
||||
return
|
||||
try:
|
||||
return ArticleImage.objects.get(original=src)
|
||||
except ArticleImage.DoesNotExist:
|
||||
name = copy_image(src)
|
||||
if name:
|
||||
return ArticleImage.objects.create(
|
||||
original=src, name=name,
|
||||
alt=image_soup.attrs.get('alt', ''))
|
||||
|
||||
|
||||
def maybe_update(model_instance, data):
|
||||
update_fields = [key for key, value in data.items() if
|
||||
getattr(model_instance, key, None) != value]
|
||||
if update_fields:
|
||||
for field in update_fields:
|
||||
setattr(model_instance, field, data[field])
|
||||
model_instance.save(update_fields=update_fields)
|
||||
|
||||
|
||||
def parse_datetime(text, use_tz=settings.USE_TZ, timezone=settings.TIME_ZONE):
|
||||
try:
|
||||
parsed = dateutil.parser.parse(text)
|
||||
except:
|
||||
return
|
||||
else:
|
||||
if use_tz and tz.is_naive(parsed):
|
||||
return tz.make_aware(parsed, tz.get_current_timezone())
|
||||
elif not use_tz and tz.is_aware(parsed):
|
||||
return tz.make_naive(parsed, tz.get_current_timezone())
|
||||
return parsed
|
||||
|
||||
|
||||
def get_validated_article_data(entry, category, use_tz=settings.USE_TZ):
|
||||
for key in ('author', 'link', 'title', 'summary', 'published'):
|
||||
if not entry.get(key):
|
||||
return
|
||||
try:
|
||||
soup = BeautifulSoup(entry['summary'])
|
||||
except:
|
||||
return
|
||||
published = parse_datetime(entry['published'])
|
||||
if published:
|
||||
return {
|
||||
'author': entry['author'],
|
||||
'category': category,
|
||||
'image': get_or_maybe_create_article_image(soup),
|
||||
'link': entry['link'],
|
||||
'title': entry['title'],
|
||||
'summary': soup.get_text(),
|
||||
'published': published}
|
||||
|
||||
|
||||
def create_or_maybe_update_article(entry, category):
|
||||
article_data = get_validated_article_data(entry, category)
|
||||
if not article_data:
|
||||
return
|
||||
try:
|
||||
article = Article.objects.get(link=article_data['link'])
|
||||
except:
|
||||
return Article.objects.create(**article_data)
|
||||
else:
|
||||
return maybe_update(article, article_data)
|
||||
|
||||
|
||||
def update_from_category_feeds():
|
||||
for category, feed_url in settings.OPENSTANDARD_CATEGORY_FEEDS:
|
||||
try:
|
||||
parsed_feed = parse(feed_url)
|
||||
except:
|
||||
continue
|
||||
for entry in parsed_feed.get('entries', []):
|
||||
create_or_maybe_update_article(entry, category)
|
||||
|
||||
|
||||
def categorized_articles(
|
||||
cache_key='openstandard_articles', cache_timeout=None,
|
||||
force_cache_refresh=False, per_category_limit=4):
|
||||
|
||||
if not force_cache_refresh:
|
||||
cached = cache.get(cache_key)
|
||||
if cached:
|
||||
return cached
|
||||
|
||||
# This is faster than the equivalent SQL for a small table size,
|
||||
# which we will ensure with a cron job running delete_old_articles
|
||||
categorized = dict((category, list(articles)[:per_category_limit])
|
||||
for category, articles in
|
||||
groupby(Article.objects.select_related(),
|
||||
lambda a: a.category))
|
||||
cache.set(cache_key, categorized, cache_timeout)
|
||||
return categorized
|
||||
|
||||
|
||||
def delete_old_articles():
|
||||
'TODO'
|
|
@ -897,6 +897,7 @@ INSTALLED_APPS = get_apps(exclude=(
|
|||
'%s.legal' % PROJECT_MODULE,
|
||||
'%s.mozorg' % PROJECT_MODULE,
|
||||
'%s.newsletter' % PROJECT_MODULE,
|
||||
'%s.openstandard' % PROJECT_MODULE,
|
||||
'%s.persona' % PROJECT_MODULE,
|
||||
'%s.press' % PROJECT_MODULE,
|
||||
'%s.privacy' % PROJECT_MODULE,
|
||||
|
@ -1098,6 +1099,16 @@ HOMEPAGE_TWITTER_ACCOUNTS = {
|
|||
'pt-BR': 'firefoxbrasil',
|
||||
}
|
||||
|
||||
OPENSTANDARD_CATEGORY_FEEDS = (
|
||||
('live', 'https://openstandard.mozilla.org/category/live/feed/'),
|
||||
('learn', 'https://openstandard.mozilla.org/category/learn/feed/'),
|
||||
('innovate', 'https://openstandard.mozilla.org/category/innovate/feed/'),
|
||||
('engage', 'https://openstandard.mozilla.org/category/engage/feed/'),
|
||||
('opinion', 'https://openstandard.mozilla.org/category/opinion/feed/'),
|
||||
)
|
||||
OPENSTANDARD_IMAGE_ROOT = MEDIA_ROOT + '/img/openstandard/'
|
||||
OPENSTANDARD_IMAGE_URL = MEDIA_URL + 'img/openstandard/'
|
||||
|
||||
# Mapbox token for spaces and communities pages
|
||||
MAPBOX_TOKEN = 'examples.map-i86nkdio'
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
"""
|
||||
Deployment for Bedrock on www-demo1.allizom.org.
|
||||
Deployment for Bedrock on www-demo5.allizom.org.
|
||||
|
||||
Requires commander (https://github.com/oremj/commander) which is installed on
|
||||
the systems that need it.
|
||||
|
|
|
@ -121,11 +121,18 @@ def pre_update(ctx, ref=settings.UPDATE_REF):
|
|||
commands['update_info']()
|
||||
|
||||
|
||||
@task
|
||||
def cronjobs(ctx):
|
||||
management_cmd(ctx, 'cron update_tweets')
|
||||
management_cmd(ctx, 'cron update_openstandard')
|
||||
|
||||
|
||||
@task
|
||||
def update(ctx):
|
||||
commands['database']()
|
||||
commands['update_assets']()
|
||||
commands['update_locales']()
|
||||
commands['cronjobs']()
|
||||
commands['update_revision_file']()
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
# Ignore everything in this directory
|
||||
*
|
||||
# Except this file
|
||||
!.gitignore
|
Загрузка…
Ссылка в новой задаче