Skip to content

Commit

Permalink
Merge 590ddbb into 8ea23d1
Browse files Browse the repository at this point in the history
  • Loading branch information
rodfersou committed May 9, 2016
2 parents 8ea23d1 + 590ddbb commit eaaa2cb
Show file tree
Hide file tree
Showing 18 changed files with 298 additions and 17 deletions.
5 changes: 5 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ Changelog
1.1b2 (unreleased)
------------------

- Micro-updates are now traversable;
this allows to share them as separate pieces of content (closes `#19`_).
[rodfersou, hvelarde]

- Use POST as request method on form used to edit micro-updates.
[hvelarde]

Expand Down Expand Up @@ -109,3 +113,4 @@ Changelog
.. _`#7`: https://github.com/collective/collective.liveblog/issues/7
.. _`#10`: https://github.com/collective/collective.liveblog/issues/10
.. _`#14`: https://github.com/collective/collective.liveblog/issues/14
.. _`#19`: https://github.com/collective/collective.liveblog/issues/19
7 changes: 6 additions & 1 deletion src/collective/liveblog/browser/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@ class BaseView:

"""Base view with helper methods for Liveblog."""

@property
@view.memoize
def is_anonymous(self):
return api.user.is_anonymous()

@property
@view.memoize
def show_byline(self):
"""Return True if user is allowed to view 'about' information."""
site_props = api.portal.get_tool('portal_properties').site_properties
allow_view = site_props.getProperty('allowAnonymousViewAbout', True)
return not api.user.is_anonymous() or allow_view
return not self.is_anonymous or allow_view
9 changes: 9 additions & 0 deletions src/collective/liveblog/browser/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@
layer="collective.liveblog.interfaces.IBrowserLayer"
/>

<browser:page
for="collective.liveblog.interfaces.ILiveblog"
name="microupdate"
class="collective.liveblog.browser.microupdates.MicroUpdateView"
permission="zope2.View"
layer="collective.liveblog.interfaces.IBrowserLayer"
template="templates/microupdate.pt"
/>

<browser:page
for="collective.liveblog.interfaces.ILiveblog"
name="view"
Expand Down
7 changes: 5 additions & 2 deletions src/collective/liveblog/browser/header.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,8 @@ class Header(ViewletBase):
"""A viewlet to include a header in the Liveblog."""

def available(self):
"""Return True if an image has been defined."""
return self.context.image is not None
"""Check if the viewlet must be displayed; that is, if an image
is been used and the context is not a micro-update.
"""
is_microupdate = self.request['PARENTS'][0].__name__ == 'microupdate'
return self.context.image is not None and not is_microupdate
30 changes: 30 additions & 0 deletions src/collective/liveblog/browser/microupdates.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,44 @@
from collective.liveblog import _
from collective.liveblog.adapters import IMicroUpdateContainer
from collective.liveblog.adapters import MicroUpdate
from collective.liveblog.browser.base import BaseView
from datetime import datetime
from plone import api
from Products.Five.browser import BrowserView
from time import time
from zExceptions import NotFound
from zope.event import notify
from zope.lifecycleevent import ObjectModifiedEvent


class MicroUpdateView(BrowserView, BaseView):

"""Default view for a Liveblog's micro-update."""

def __init__(self, context, request):
# do not allow accessing the view without a timestamp
if len(request.path) == 0:
request.RESPONSE.setStatus(400)
super(MicroUpdateView, self).__init__(context, request)

def __call__(self):
# return an empty page on Bad Request
if self.request.RESPONSE.getStatus() == 400:
return ''
return self.index()

def publishTraverse(self, request, timestamp):
"""Get the selected micro-update."""
microupdates = self.context.get_microupdates()
update = [u for u in microupdates if u['timestamp'] == timestamp]
assert len(update) in (0, 1)
if len(update) == 0:
raise NotFound

self.update = update[0]
return self


class BaseMicroUpdateView(BrowserView):

"""Base view with helper methods for micro-updates."""
Expand Down
91 changes: 91 additions & 0 deletions src/collective/liveblog/browser/templates/microupdate.pt
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<html xmlns="http://www.w3.org/1999/xhtml"
xml:lang="en"
xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal"
metal:use-macro="context/main_template/macros/master"
xmlns:i18n="http://xml.zope.org/namespaces/i18n"
i18n:domain="collective.liveblog">
<head>
<metal:block metal:fill-slot="top_slot"
tal:define="dummy python:request.set('disable_border', 1)" />
</head>
<body>
<metal:block fill-slot="main">
<article itemscope
itemtype="http://schema.org/BlogPosting"
tal:define="update view/update">
<header>
<div tal:replace="structure provider:plone.abovecontenttitle" />

<h1 class="documentFirstHeading"
itemprop="headline"
tal:content="update/title"
tal:condition="update/title">
Title
</h1>

<div class="documentByLine"
id="plone-document-byline"
i18n:domain="plone"
tal:condition="view/show_byline">
<span class="documentAuthor" tal:condition="not:view/is_anonymous">
<tal:i18n i18n:translate="label_by_author">
by
<span property="rnews:author" tal:content="update/creator">
Roland Barthes
</span>
</tal:i18n>
&mdash;
</span>

<tal:dates define="published update/datetime;
modified update/modified">
<span class="documentPublished">
<span i18n:translate="box_published">
published
</span>
<span tal:content="published" property="rnews:datePublished">
August 16, 2001 at 23:35:59
</span><tal:sep condition="modified">,</tal:sep>
</span>

<span class="documentModified" tal:condition="modified">
<span i18n:translate="box_last_modified">
last modified
</span>
<span tal:content="modified" property="rnews:dateModified">
August 16, 2001 at 23:35:59
</span>
</span>
</tal:dates>
</div>
</header>

<div tal:replace="structure provider:plone.abovecontentbody" />

<div id="content-core" itemprop="articleBody">
<section>
<article class="microupdate"
data-timestamp=""
itemprop="comment"
itemscope
itemtype="http://schema.org/Comment"
tal:attributes="data-timestamp update/timestamp">
<div class="microupdate-text"
itemprop="text"
tal:content="structure update/text" />
</article>
</section>
</div>

<div tal:replace="structure provider:plone.belowcontentbody" />

<div class="microupdate-back">
<span i18n:translate="" tal:omit-tag="">Extracted from:</span>
<a tal:attributes="href context/absolute_url"
tal:content="context/Title">Liveblog</a>
</div>
</article>
</metal:block>
</body>
</html>
21 changes: 13 additions & 8 deletions src/collective/liveblog/browser/templates/view.pt
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,11 @@
tal:attributes="datetime update/isoformat;
title update/datetime;
data-date update/date;
data-time update/time">
<span class="microupdate-time" tal:content="update/time" />
data-time update/time;
data-timestamp update/timestamp">
<a tal:attributes="href string:microupdate/${update/timestamp}">
<span class="microupdate-time" tal:content="update/time" />
</a>
</time>
</div>
</article>
Expand All @@ -68,14 +71,16 @@
<script>
/* show dates for micro-updates older than today */
var today = new Date().toISOString().substr(0, 10);
$("time").each(function () {
$("time a").each(function () {
"use strict";
var datetime = $(this).attr("datetime").substr(0, 10),
date = $(this).attr("data-date"),
time = $(this).attr("data-time");
var $time = $(this).parent(),
datetime = $time.attr("datetime").substr(0, 10),
date = $time.attr("data-date"),
time = $time.attr("data-time"),
timestamp = $time.attr("data-timestamp");
if (today > datetime) {
$(this).html("<span class='microupdate-date'>" + date + "</span> " +
"<span class='microupdate-time'>" + time + "</span>");
$(this).html("<a href='microupdate/" + timestamp + "'><span class='microupdate-date'>" + date + "</span> " +
"<span class='microupdate-time'>" + time + "</span></a>");
}
});
</script>
Expand Down
8 changes: 8 additions & 0 deletions src/collective/liveblog/content.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ def get_microupdates(self):
for id, update in enumerate(container):
if update is None:
continue # update has been removed

# TODO: it would be better to initialize modified field as None
if update.created == update.modified:
modified = None
else:
modified = api.portal.get_localized_time(update.modified, True) # 28/08/2014 10h58

updates.append(dict(
id=id,
creator=update.creator,
Expand All @@ -34,6 +41,7 @@ def get_microupdates(self):
date=api.portal.get_localized_time(update.created), # 28/08/2014
time=api.portal.get_localized_time(update.created, time_only=True), # 10h58
isoformat=update.created.isoformat()[:-3], # 2014-08-28T10:58:10.209468
modified=modified,
title=update.title,
text=update.text,
))
Expand Down
2 changes: 2 additions & 0 deletions src/collective/liveblog/profiles.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
i18n:attributes="title; description"
/>

<include package=".upgrades" />

<utility factory=".setuphandlers.HiddenProfiles" name="collective.liveblog" />

</configure>
2 changes: 1 addition & 1 deletion src/collective/liveblog/profiles/default/metadata.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<metadata>
<version>1000</version>
<version>1001</version>
<dependencies>
<dependency>profile-plone.app.dexterity:default</dependency>
</dependencies>
Expand Down
10 changes: 6 additions & 4 deletions src/collective/liveblog/static/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@
}
.portaltype-liveblog article .field input[type="text"] {
width: 100%;
line-height: 125%;
color: black;
letter-spacing: -0.05em;
margin: inherit -0.05em;
font-size: 2em;
font-weight: bold;
}
Expand Down Expand Up @@ -38,6 +34,9 @@
padding: 1em 0 0 0;
position: relative;
}
.template-microupdate.portaltype-liveblog #micro-updates article {
border-top: none;
}
.microupdate-byline time {
background: #f1f1f1;
padding: 1em 0;
Expand All @@ -64,6 +63,9 @@
.microupdate-title, .microupdate-text, .microupdate-byline p {
margin-left: 110px;
}
.template-microupdate.portaltype-liveblog .microupdate-text {
margin-left: auto;
}
.microupdate-byline {
color: #666;
}
Expand Down
43 changes: 43 additions & 0 deletions src/collective/liveblog/tests/test_upgrades.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
from collective.liveblog.testing import INTEGRATION_TESTING

import unittest


class UpgradeBaseTestCase(unittest.TestCase):

layer = INTEGRATION_TESTING
profile_id = u'collective.liveblog:default'

def setUp(self):
self.portal = self.layer['portal']
self.setup = self.portal['portal_setup']
self.setup.setLastVersionForProfile(self.profile_id, self.from_)

def _get_upgrade_step_by_title(self, title):
"""Return the upgrade step that matches the title specified."""
self.setup.setLastVersionForProfile(self.profile_id, self.from_)
upgrades = self.setup.listUpgrades(self.profile_id)
steps = [s for s in upgrades[0] if s['title'] == title]
return steps[0] if steps else None

def _do_upgrade(self, step):
"""Execute an upgrade step."""
request = self.layer['request']
request.form['profile_id'] = self.profile_id
request.form['upgrades'] = [step['id']]
self.setup.manage_doUpgrades(request=request)


class To1001TestCase(UpgradeBaseTestCase):

from_ = '1'
to_ = '2'

def test_profile_version(self):
version = self.setup.getLastVersionForProfile(self.profile_id)[0]
self.assertEqual(version, self.from_)

def test_registered_steps(self):
steps = len(self.setup.listUpgrades(self.profile_id)[0])
self.assertEqual(steps, 1)
14 changes: 13 additions & 1 deletion src/collective/liveblog/tests/test_viewlet.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,23 @@ def test_viewlet_order(self):
viewlets, [u'plone.path_bar', u'collective.liveblog.header'])

def test_viewlet_is_available(self):
from plone.namedfile.file import NamedBlobImage
manager = self._get_viewlet_manager()
manager.update()
viewlet = manager[u'collective.liveblog.header']
viewlet.update()
self.assertFalse(viewlet.available())
from plone.namedfile.file import NamedBlobImage
self.liveblog.image = NamedBlobImage()
self.assertTrue(viewlet.available())

# default view
self.request['URL'] = 'http://nohost/plone/liveblog/view'
self.request['PARENTS'][0] = self.liveblog
self.assertTrue(viewlet.available())

# microupdate view
self.request.path = ['1462277979.55']
self.request['URL'] = 'http://nohost/plone/liveblog/microupdate/1462277979.55'
view = api.content.get_view('microupdate', self.liveblog, self.request)
self.request['PARENTS'][0] = view
self.assertFalse(viewlet.available())
Loading

0 comments on commit eaaa2cb

Please sign in to comment.