+ http://make.opendata.ch/wiki/information:showcase
Amy added 'information:showcase [make.opendata.ch]' to Bookmarks
+ http://make.opendata.ch/wiki/information:showcase
Amy added 'information:showcase [make.opendata.ch]' to Bookmarks
Amy added 'Open Badges' to Bookmarks
+ http://make.opendata.ch/wiki/project:open_science
Amy added 'project:open_science [make.opendata.ch]' to Bookmarks
None of the install Ubuntu on chromebook instructions mention the loud beeps. Don't do it during a seminar. #proTip
+ http://www.unc.edu/%7Epmeyer/book/
Amy added 'The Newu00a0 Precision Journalism - Preface' to Bookmarks
+ https://www.authorea.com/users/23/articles/8762/_show_article
Amy added 'The "Paper" of the Future | Authorea' to Bookmarks
+ http://blog.dshr.org/2015/04/trying-to-fix-symptoms.html
Amy added 'DSHR's Blog: Trying to fix the symptoms' to Bookmarks
+ http://blog.dshr.org/2015/03/journals-considered-even-more-harmful.html
Amy added 'DSHR's Blog: Journals Considered Even More Harmful' to Bookmarks
+ http://www.sciencemag.org/content/214/4523/881
Amy added 'Chance and consensus in peer review' to Bookmarks
+ http://www.w3.org/2012/ldp/wiki/LDPNext
Amy added http://www.w3.org/2012/ldp/wiki/LDPNext to https://rhiaro.co.uk/bookmarks/
Now entering Germany
Take note weary travelers, Three's Feel At Home plan does not include Germany. Silly of me to just assume it did. I spent £5 on IRC and reading the microformats wiki.
Avoiding usual online haunts because election chatter is depressing. Maybe just won't come back from the continent. If we leave EU I'm done with UK..
Spent a fair bit of time with an 8 year old and a 7 month old the past few days. 5% adorable, 95% ohgodpleaseneverletthishappentome
This post is my own opinion, and does not necessarily represent the opinion of the Social Web WG!
tl;dr: There is increased understanding and expectation of convergence between Micropub, ActivityPump and SoLiD. We're all excited about working towards this convergence. There is increased agreement and understanding about similarities and differences between protocols, and where strong points of one protocol could plug weak points in another. More people are excited about implementing experiments to really figure out what works and what doesn't.
See also day 1 minutes and day 2 minutes and self-critique whiteboard.
What follows is more detail on my perspective of the main conversations we had over the two days. Clarifications and corrections welcome.
Closed a bunch of ActivityStreams2.0 issues with the general conclusion that issues raised in future should be more specific and actionable, rather than vague problems. An alternative for reporting this kind of issue wasn't mentioned specifically, but vague problems can probably go in brainstorming sections on the wiki somewhere (indieweb style) or into github issues.
A note that we can always re-open issues if they turn out to be a problem in the future, but we shouldn't keep them open just in case they might be.
Aaron, Jessica and Andrei and Henry walked us through exactly how some of the user stories would be carried out according to the protocols Micropub, ActivityPump and SoLiD respectively. This was super useful, and if you weren't there you need to read the accompanying documents (linked just prior) and minutes (linked at the top of this post).
Results of this were:
I particularly noted:
That's a full triangle of connections! The protocols are all friends.
The resolution, then, was that we won't rush to pick a base to work from, and instead will spend some more time (with regular updates to the group) tweaking each protocol to get closer to convergence, so everyone will be happier when a base does eventually need to get chosen.
(Exciting, right?! This was like the best meeting of minds that has happened so far. If you weren't in the room you might have missed this, so... trust those of us who were).
There should be some kind of clear warning in the spec that extensibility won't work well if you're using plain JSON, not JSON-LD (implying the best way to do vocabulary extensibility is through URI namespacing, which hasn't neccessarily been agreed, but to me seems like a sensible way). It also needs to be clear that upon receiving terms that a server does not understand it should not drop the data, even if it ignores it - in case that data gets passed forward to a server that might understand it.
We resolved "ISSUE-36, Remove all non AS2 namespaces from the normative context, keep the normative context limited to only AS2 vocabulary terms". I'm not totally sure what this means: that if there are terms we decide are crucial we will include AS versions of them even if they already existing another vocabulary (instead of reusing)? In the name of 'completeness' might we overload ActivityStreams, and because we consider AS 'complete' risk sabotaging easy extension? I still don't get everything that is throw around during extension mechanism conversations, so I could be missing something. Mostly I'd love to see someone implement AS and extend it to a specific domain, to see how this would work in practice. On a related note, I don't think I've seen documentation of the use-cases / origin of all of the vocabulary terms in AS2, does this exist?
The activity-oriented model of AS2 and the object-oriented model of microformats are actually basically the same but looked at from different perspectives. I think it's really important people try to see this, and not see them as conflicting. We're all trying to do the same thing, and there's no reason AS2-based and microformats2-based implementations can't interoperate. I'm going to work more on this, and others are too. We closed issues related to this as too vague, but it'll need revisiting when we have some more concrete proposals about what to do. By the end of the two days, people were starting to generally agree that this is the case.
We clarified that Person
in AS2 does not need to refer to a real-world person, and agreed we should make this clearer in the spec (eg. it could be a fictional person, a persona or aspect of someone, etc). We resolved to add Profile
to AS2 to enable talking about documents about people separately to talking about people, and to facilitate connecting one Person
to multiple Profile
s, which I think is useful but not everyone agrees. Thus Profile
is at-risk until there are implementations.
It's worth emphasising the two different parts of this discussion: Person
vs. Persona
is different from Person
vs. Profile
(ie. Person
!= Persona
!= Profile
). There was some conflation of this during discussion. Whilst everyone tends to agree that there are three different things there, we disagree about which level of modelling is practically necessary. Figuring this out based on observing how existing social sites model this, implementing my own aspect-based profiles, and shunting my own data around between different profiles, is something I'm concentrating on over the next couple of months.
Describing things as client or server can be misleading. Things act as a client or server depending on the perspective, and it doesn't necessarily matter if they run in the client or on the server. We either need to clarify or alter our terminology, perhaps rephrasing to describe which componants we see having which responsibility.
Not at all, with strings, with URIs? Uh... decent arguements for and against all, strong opinions all around. I dunno.
Subtle distinction between access control via the author of a post deciding who to send it to (or who can see it), and someone actively joining a group in order to see additional content.
In ActivityPump (and pump.io) you specify to
to decide who can see a note, eg. your followers. If someone new follows you, and someone else unfollows you, then you update your note, which list do the changes get propagated to? The original receivers of the note, or the current list of followers? I think this isn't specified and needs to be clarified. In ActivityPump, following someone is effectively adding yourself to a group (Collection) of their followers.
LDP doesn't have any side effects by itself, it's simply posting and getting of data to a generic store that doesn't understand the data itself. But for more domain specific purposes like social, LDP could be one layer with another layer that handles side effects like notifications and distribution of changes.
Certain activities in ActivityPump cause specific side effects. This is a fixed list, and could do with being better described in the spec. These are things like: if A creates a follow activity of B, side effects are A is added to B's list of follwers, B is added to A's list of followings, B is notified that A followed them, and anyone with permission to see A's activities also sees that A followed B. From what I can tell, side effects tend to be updating/deleting objects or adding to/removing from collections.
Micropub's side effects could include syndicating a post to other sites, or triggering webmentions (notifications). There is increasing discussion about having a following list that a reader can subscribe to (so you don't have to enter all of your subscriptions if you change reader) and keeping track of when you followed/unfollowed someone; actively doing one could trigger the other.
My vague conclusion is that specifying an extensible way to describe side effects of activities would be useful, with perhaps some core musts and shoulds, but open ended for implementations to do more focused things (eg. if Floop-o-matic decide that posting a Floop automatically likes the second most recent post of everyone named Fred, then they could describe that in a spec-conformant way. Okay that was silly, but you know what I mean).
LDP is RESTful; Micropub (and Webmention) use discoverable endpoints; ActivityPump mostly uses endpoints (specific paths rather than discoverable I think) with some things able to be done RESTfully. Endpoints mean services can be delegated to third-parties, and can therefore be used on static sites. Not sure if there's a specific benefit to RESTful (or RESTfulish) but with a bit of sideways thinking they could actually co-exist, allowing implementers to use the method they prefer.
General observation: We're all working towards the same thing. Nobody in the group is trying to sabotage this effort. I don't think it would hurt to listen more, and maybe imagine that you want someone else's [solution|use case|constraint|idea] to be better than yours, and try to fit it to your world, instead of just insisting one is the best.
Every community has different constraints, and different use cases they're trying to solve. We can't elevate one set of requirements above another, but need to try to accept - or at least entertain the idea - that they're valid, without dismissing them outright just because you haven't experienced it directly. Periodically mentioning the business use cases from IBM and Boeing (for example) is helpful in reminding everyone that there are legitimate long-standing needs that probably aren't considered by most of us, but will be implemented if we support them, and will be implemented some non-standard way if we don't.
TimBL made sure to remind everyone that JSON is 'in fashion' just as XML once was, and really everyone will regret not just using RDF from the start in the future :)
When is it a checkin (with a note) and when is it a note (with a location)? Hot topic. I differentiate them for display purposes (currently I just show a map-marker icon next to checkins, but I'm also going to want to show them on a map and stuff).
For now, my rule is:
location
property, which should be a URL of a place (venue/city/country/vague), it's a checkin.
latitude
and longitude
(my vague checkins, eg. 'home', do not).content
.latitude
and longitude
and no location
, it's a note with a location.
My inner semantic pedant is unhappy with attaching a lat and lon to a post directly, so I might rethink this at some point.
In reply to:
Please please please let me post what I want, this time.
Amy added https://rhiaro.co.uk to https://rhiaro.co.uk/bookmarks/
In reply to:
And from above:
Offline, Tantek and Loqi have never been seen in the same place at the same time, are they secretly the same person?!
I'm writing this post with Quill's shiny new editor. It's so pretty and I'm having the best time typing right now. I might use this for literally everything, including taking notes in meetings etc. Actually that's a really good idea, then I can just post meeting notes straight to my site. YAY.
Things this editor needs:
Munich Hauptbahnhof
Best hostel kitchens are ones full of stuff labeled 'take me!'
Appreciate staff at Innsbruck Hbf who helped me calculate convoluted train route to avoid reservation fees :D
WHAT 50c for 13 minutes of hob use in hostel?!
*cooks everything I can find as fast as possible*
In reply to:
At this rate, everyone in the UK will be feeling that way soon too :(
Someone took my correctly labelled and desperately craved juice from the hostel fridge :((( I don't know how to react other than by sharing my anguish with the world.
I thought today was going to be one of those staying-in-the-hostel sorta days.
But the old Vietnamese women sharing my dorm said she was inspired yesterday by my desire to climb the mountain on foot (instead of cable car) today, and wants to come with me, despite the torrential rain. So, I guess that's happening.
First she has to sleep off overeating at breakfast though.
I picked Innsbruck pretty randomly as a mid-point between Dusseldorf (where I was for IWC) and Florence (where I need to be for WWW). I haven't been to Austria before, or even the Alps bar a day-trip during a school trip to France like ten years ago. The first day I was here was clear, sunny and crazy hot, so I started loving Innsbruck pretty immediately. I wandered around town, got a feel for the place, and found the only place I could get vegan pizza and eiskaffee.
The Inn river is fast-flowing and a cartoonish blue-green. The houses are bright colours, and everywhere is walkable. The town is surrounded by a ring of snow-capped mountains.
I booked a hostel so I wouldn't have to socialise too much, as I need a break from people between all of these conferences. The hostel is super quiet, and mostly pretty good. The first night I shared my dorm with two Canadian girls. They told me the funicular up one of the mountains is reasonably priced, and that it was silly to think of walking to the base as it's really far, and I should get the bus. Also that I should pay the EUR 2.60 for a bus ticket, as one of them didn't and got caught and fined ;)
Yesterday I hacked a bunch on Slog'd in the morning, then at 2pm set off with vague intentions of either climbing a mountain or swimming in a lake, ideally both. I ignored the advice of the Canadian girls, and walked to Hungerburg where the cable car starts. It was less than an hour from the hostel, and the mountain parts were easy. Turns out the cable car to the top is over 25 EUR, and it's about a 3 hour climb to Seegrube. And climbing is WAY more interesting. However, from Seegrube to the summit at Halekefar I was advised there is too much snow for climbing, so the cable car for that stretch is mandatory (and Seegrube-Halekefar is EUR 6.10 return, which I can handle). So I figured I'd climb to Seegrube, take the cable car to the summit and back, and climb all the way back on foot. But by that point, the odds of me making it to Seegrube before the cablecar stopped running at 1730 were pretty slim. I toyed with trying to find an ATM and taking the cablecar all the way, but decided I'd prefer to climb anyway and can come back the next day, earlier.
Then I walked to Lake Rossau, which the internet claims cost EUR 3.50 to swim in but I mean, it's a lake, so nobody seemed to be enforcing this. So I swam in the lake surrounded by mountains and it was beautiful.
Then I came back to the hostel and added a first pass at ActivityStreams2.0 JSON to my site. Woo! Productive day.
Today it is raining heavily and the mountains are shrouded in clouds. Naturally. Turns out I'm going to give getting to Halekefar a shot anyway, even if I can't see anything from the top, thanks to encouragement from my new hostel roomie, a fairly old Vietnamese lady who lives in Belgium.
Also, I'll post some photos just as soon as I implement display of albums and attaching Collections to posts on Slog'd.... Aaaaany day now.
I have in-dispersed this report with messages I sent either on Twitter or to anyone who might pay attention over the course of the journey..
Rosa (the elderly Vietnamese lady) and I walked to Hungerburg. It was raining heavily, but warm. I messed up the route a bit and we did a lot of scrambling through mud and up steep slopes, but Rosa seemed thrilled to have found someone to have this adventure with.
She told me about when she had left Vietnam for Belgium as a political refugee, and all of the horrible things her family and friends had endured because of "crazy communists". Her brother and sister live in California now, and none of them ever want to go back to Vietnam even though it's safe now.
She also told me about her 27 year old son who she considers a huge disappointment as all he does is browse the web and talk to his girlfriend, and doesn't have a job. He has a masters in Informatics, but there is no work in Belgium, and he refuses to move somewhere he can find work.
She told me about a friend's son, whom everyone thought was stupid until at around 22 years old he went to university, completed some degrees in record time, and now works as an accountant in London and is married to an African woman, apparently to spite his racist family, which she finds hilarious, and wishes her son was like this instead.
She calls all of her cats 'Baby'.
This was super fun, and I'm glad she encouraged me to go out in the rain.
She didn't have time (or suitable shoes) to climb to Seegrube, so we parted ways at Hungerburg. I hope she made it back okay!
I continued to Seegrube. It was pretty thick fog the whole way, though sometimes I could see a few hundred meters ahead instead of a few meters. I took lots of pictures of where I expected there would be spectacular views if there wasn't cloud in the way.
[14:09] Just checking in. Literally in a cloud. Can't see fuck.
[14:12] It's pretty creepy. I think I hit a pub in about an hour.
[14:13] I'm soaking. GPS is good though.
I mostly followed the main road, which zigzagged and was a much less direct route, but the through-forest trails were wet and muddy and the fog didn't instil me with confidence. At one point a sign expressly pointed into the forest, so I clambered for a bit, but then found a hut and lots of scary looking forestry equipment and decided it was a horror movie waiting to happen, so back-tracked to the road...
[14:18] Ooh a sign! Pub 40 minutes. Assuming alm means pub. Then just another hour to next cable car stop..
[14:21] Mystery crashing sounds
I saw two humans and one dog for the whole three hours I was walking. Occasionally I'd see a completely empty cable car glide by overhead. The air was heavy and still, and the mist was creepy. I started to worry about flash flooding, wolves, bears, and crazy humans.
[14:24] Can you look up what to do in event of flash flood, bear, or mad axeman?
[14:25] Also if there are bears or wolves on hafelekar
[14:26] Omg if this cloud wasn't here views would be incredible. I hope it isn't all the way to the top. I at least want views over expanse of cloud.
About an hour before Seegrube was Bodensteinalm, a pub-type-thing a few minutes off the main trail. I was entertaining the idea of a cup of coffee and human contact, but the place - a cute little Alpine hut - was completely deserted. The temperature was starting to drop, so I pressed on.
[14:44] Omg snow
[15:11] Human being!!!
[15:12] And he's gone. Swallowed by fog.
[15:23] Omg mist clearing and can see end of cable car!
The last stretch to Seegrube, 6,250ft, was pretty cold, and there was snow. After 8km uphill, I was ready for a cup of coffee, and splashed out 3 Euros at Seegrube Restaurant; the coffee was horrible. I did a circuit of the top, but alas the clouds did not part in divine glory and reveal the spectacular views I had been missing. There was nobody around but weary-looking restaurant staff.
[16:02] 6,250 feet, still can't see shit. Cable car to very top is less terrifying for being engulfed in cloud.
I got a return cable car ticket to Hafelekar, the summit. I was charged for an under-18 ticket \\\\o/ (EUR 4,90). The ride was less than 10 minutes.
I stepped out briefly, but there was nothing to see. I'd really hoped the summit would be above the clouds. Took some more photos of white. Met some Australians. Cable car back to Seegrube. Was freezing and tired, so decided to cable car it all the way back to Innsbruck but I didn't have enough cash, and they didn't take card. I must have looked suitably pathetic, because the staff took pity on me and let me ride free back to Hungerburg. Also the driver liked my hat. I'm pretty sure that helped.
Back in Hungerburg, it was so much warmer! I had a snack and recovered a bit, then walked the 5km back to the hostel. I managed to go off-route again (this being the fourth time I'd walked between Innsbruck and Hungerburg); didn't have to scramble through mud but did accidentally walk through a wedding reception in the grounds of a hotel, and ended up going via the centre of Innsbruck, which was a bit out of the way.
Really I'm fine with having missed out on seeing for miles, as climbing a mountain in thick fog is an interesting experience by itself. I will post all of my photos of white in due course, but my favourite is this convenient sign showing what I could have been seeing...
Ticket inspector validating and selling tickets via NFC and qr codes on Switzerland-Italy train. Cool. The future is here.
With better power and wifi provision, I would totally consider moving my office to misc trains through Italian/Swiss/Austrian mountains.
Was just feeling grumpy about no air con and loud babies on this train but then saw a wild boar crossing a river and I guess it's okay.
Bologna. Massive station, with three of certain platforms >.>
I spy @emax telling the world about awesome rad social decentralisation stuff and how silos are bad #indieweb
"If we were still in a web 1.0 world where everyone was their own server and client [data siloing] wouldn't be a problem, but now we have to duct tape it" ~ @emax
Representin' Gordon Edwards' twitter spammer categorization poster at www2015
Found a micropub bug, turned my back for 5 minutes and they'd taken the coffee away and started the next conference session. Indieweb problems.
Amy added http://www.slideshare.net/pmika1/social-networks-and-the-semantic-web-a-retrospective-of-the-past-10-years to https://rhiaro.co.uk/bookmarks/
Florence isn't so bad.
Personal challenge: see how long I can stay in Facebook social experiments session before leaving in outrage.
+ https://eytan.github.io/www-15-tutorial/
Amy added https://eytan.github.io/www-15-tutorial/ to https://rhiaro.co.uk/bookmarks/
If you've been paying attention to me IRL or in IRC lately, you'll have had me try to persuade you that activities and posts are basically the same thing. People advocating post-centric views and people advocating activity-centric views are really describing the same thing from different angles, and with slightly different data models.
An activity looks generally like:
And a post looks generally like:
Colour coding indicates what correlates between the two. Differences:
Activity | Post | |
---|---|---|
type | explicit | implied by properties |
relationship to another object | object |
value of arbitrary property |
meta | some on activity, some on result |
all on post |
But you can see that the data they contain are basically the same. Bear with me.
To propagate changes through a network. To tell people that somebody did something.
Posts are content, an end in themselves.
As someone who just wants to publish stuff and interact on the web, do I care if I'm creating and pushing around posts, or activities? Probably not. I just want to do stuff, and have people see it.
As a developer, I want to post objects around that contain as much data as needed, and no more. I want the right people to know when something has changed. Whether I prefer to do this with activities or posts (or JSON or HTML) is, as far as I see it, personal preference. I don't think there's an inherant advantage to one over the other.
Starting with a blog perspective, the most important thing is that people see my content. Posts are my content, so I start there.
For humans, the posts are displayed in html, and for machines they're marked up with minimal microformats, which allows a reader such as Woodwind to parse out the relevant information and display however necessary. (Mine are also avaiable as RDF, but to the best of my knowledge nobody has built a blog reader that consumes RDF yet).
In the ActivityStreams model, rather than creating posts directly, the user performs some activity which may generate as a side-effect a post. The activty could be something like Post
, Share
, Like
(with many other terms currently in the vocab), with an optional target
of an object being acted upon, and an optional result
of a new object being created. Upon creation, the activity is sent by the server to the servers of anyone who is expected to receive it - either a default list such as people who have subscribed to the author, or a specific list of other people specified when the activity is created, or anyone mentioned or replied-to etc. Anyone for whom the activity ends up on their inbox might get a notification, and their server can fetch the associated post for them.
Not all activities generate a result
post and some activities generate a result
that is the same as the object
. In these cases, I would argue that an activity == a post...
Currently, when I like something I create a like post, that looks like this:
A like activity looks like this:
See how similar they are?!
So given this apparent direct mapping between posts and activities...
Dreaming of interoperability with ActivityPump implementations, I want to generate AS2.0 compliant activities that I can send out. I stuck to super basic representations for now, nesting as little as possible (figuring everything with a URI can be dereferenced anyway, so all of the data doesn't need to be present in the first layer of JSON).
So for a new post such as:
<article class="h-entry">
<h1 class="p-name">Post title</h1>
<div class="e-content">
<p>This is a post!</p>
</div>
<time class="dt-published" datetime="2015-05-15T13:06:00+02:00"><a href="https://rhiaro.co.uk/2015/05/a-post" class="u-url u-uid">15th May 2015 13:06</a></time>
<p class="h-card p-author p-name"><a href="https://rhiaro.co.uk/about#me" class="u-url">Amy Guy</a></p>
</article>
The activity generated looks like:
{
"@type": "Post",
"published": "2015-05-15T13:06:00+02:00",
"actor": "https://rhiaro.co.uk/about#me",
"object": "https://rhiaro.co.uk/2015/05/a-post",
"result": {
"@id": "https://rhiaro.co.uk/2015/05/a-post"
}
}
With no explicit audience specified, an ActivityPump compliant server would post this to the inboxes of all of my followers. Their server would see the new activity and insert it into their feed; they could click it and view the object (the post). Note that the object
of the activity and the result
here are the same, so there's some redundancy.
For a like post - because I start with posts, I keep the result
of the activity as the like post and retain this redundancy, though this isn't necessary and (see diagram above) you could in fact consider the activity to be equivalent to the like post, and use the ID of the activity to interact with it (if someone wanted to like my like, etc). I have no explicit post types, so it's implicitly considerd a 'like' post due to the like-of
microformats property:
<article class="h-entry">
<p class="p-name e-content">I like <a href="https://theperplexingpariah.co.uk/2015/05/a-post" class="u-like-of">Jessica's post</a>.</p>
<time class="dt-published" datetime="2015-05-15T13:06:00+02:00"><a href="https://rhiaro.co.uk/2015/05/a-like" class="u-url u-uid">15th May 2015 13:06</a></time>
<p class="h-card p-author p-name"><a href="https://rhiaro.co.uk/about#me" class="u-url">Amy Guy</a></p>
</article>
And the activity:
{
"@type": "Like",
"published": "2015-05-15T13:06:00+02:00",
"actor": "https://rhiaro.co.uk/about#me",
"object": "https://theperplexingpariah.co.uk/2015/05/a-post",
"result": {
"@id": "https://rhiaro.co.uk/2015/05/a-like"
}
}
In this case, as well as any explicit or default audience specified, my server would post this activity to Jessica's inbox, whether Jessica is following me or not, as it's a like of her post. Her server can notify her, insert this into her feed, and it's also her server's job to send this activity out to everyone (probably Jessica's followers) who recieved the original post (the one I'm liking), so the 'like' counter can be incremented consistently for everyone, whether they know you or not.
Without activities (my current setup), I'd send a webmention to Jessica, and there's nothing specified about how her server should handle this (beyond checking it's valid), so propagating the like out to everyone who had seen her post wouldn't necessarily happen. However, she is likely to display the number of 'likes' on her post, so a reader could pull the new number of likes each time anyone viewed it (or poll continuously if it wanted a live-update), which puts a lot of burden on the client rather than the server.
So I generate activities like this for all of my posts so far. As I removed all explicit post types from my storage, I rely only on the properties of a post to decide how to display it. I implemented similar rules to generate the activity types required by AS2.0. These rules cascade:
name
exists (object has a title) -> Post
location
exists -> Arrive
like-of
exists -> Like
bookmark-of
exists -> Save
repost-of
exists -> Share
Post
in-reply-to
exists and has category
"rsvp" -> Accept
Respond
I also check nameless posts for eat
and sleep
tags, as these indicate a lifelog post for eating or sleeping, and use types _:Consume
and _:Sleep
(my own namespace, as AS2.0 doesn't have these types. TODO: Reuse an existing vocab for these). I'll be adding running, yoga, hiking, listening to music and committing code imminantly, so I might need more activity types. I probably need to model these better than relying on tags (but... maybe not. We'll see).
If you noticed that the object
of a Consume
activity is a blog post, you're a semantic pedant, and you're right, this doesn't make sense. The next best option given the data I currently store is the object being blank node with a label of the contents of the post, eg:
{
"@type": "Consume",
"published": "2015-05-15T13:06:00+02:00",
"actor": "https://rhiaro.co.uk/about#me",
"object": {
"title": "An apple"
},
"result": {
"@id": "https://rhiaro.co.uk/2015/05/a-nom"
}
}
But ideally the object
would have it's own URI. This probably isn't something I'm going to do any time soon.
Note an object (a post) is still created as a result
of the Consume
activity. This isn't necessary - as with likes, the pure activity could be sent and displayed to people - but since I start with posts, I wouldn't drop them.
If you're squinting at my location
-> Arrive
rule, note my own special rules for displaying checkins. This is subject to change.
Sometimes, when you want to do something on the web, it doesn't feel like making a post. For example, if I want to delete a blog post, I need to tell everyone who received it that it's deleted. In indiewebland, you just delete the post, return a 410, and send a webmention to anyone who needs it. However, this doesn't leave any record of when it was deleted (or when it was created). You might have noticed I like tracking everything, so the ActivityPump way of deleting - which retains a trace of the deletion - appeals to me:
{
"@type": "Delete",
"@id": "https://rhiaro.co.uk/2015/05/delete-bad-post",
"published": "2015-05-15T13:06:00+02:00",
"actor": "https://rhiaro.co.uk/about#me",
"object": "https://rhiaro.co.uk/2015/05/bad-post",
"result": {
"@id": "https://rhiaro.co.uk/2015/05/bad-post",
"deleted": "2015-05-15T13:06:00+02:00"
}
}
(In the current ActivityPump spec, the result
is a shell of the object that is being deleted, so the URI of the deleted post is retained with a deletion date attached, but all other properties deleted).
But when you think about deleting a post, you're not thinking about creating a delete post which references the post you want to delete (if this is how you think about it, I'd love to hear from you). You want to hit delete, and have everyone suitably notified. The same for updates/edits/modifications (of your own post - creating a diff post as an edit to somene else's post or a wiki page is a different matter).
Nonetheless, if I wanted to display the delete activity for humans, I could mark it up in HTML with microformats, just as if it were a post, something like:
<article class="h-entry">
<p class="p-name e-content">I deleted <a href="https://rhiaro.co.uk/2015/05/bad-post" class="u-delete-of">a post</a>.</p>
<time class="dt-published" datetime="2015-05-15T13:06:00+02:00"><a href="https://rhiaro.co.uk/2015/05/delete-bad-post" class="u-url u-uid">15th May 2015 13:06</a></time>
<p class="h-card p-author p-name"><a href="https://rhiaro.co.uk/about#me" class="u-url">Amy Guy</a></p>
</article>
Note:
u-delete-of
, this doesn't currently exist.content
(or existing displayName
) property on the activity could be used for this. Where this content comes from could be implementation-dependant, with some sensible default fallback.So even though they're basically the same thinking about 'delete' as an activity rather than a post feels easier and it is still possible to treat as a post for display if you need to.
At the moment I store a modified date and just update this whenever I edit a post. For now I plan to add something that checks all posts for a updated
date and slots Update
activities into the stream (even though there is no explicit update-of
post). When I can update posts properly with micropub, I will generate the update activity then.
There are other activities ((un)follow/add/remove/join/leave) that I also think would be simpler to think of in this way. I don't currently know of anyone in indieweb who is displaying posts for these marked up with microformats, though I have a couple of experimantal follows posts with u-follow-of
.
Once I have AS2.0 compliant activities, I could post them to inboxes of [ActivityPump]() compliant servers. Someone should implement one please :)
Certain activities (like Follow
) may trigger special side-effects (a user is added to another users followers
collection according to pump.io and ActivityPump (not ActivityStreams)). In indieweb, if you want to follow someone you type their URL into a reader and it fetches their content. What's missing is the reader being able to post a follow activity to your site via micropub so that others (including who you have just followed) can be notified of your follow, and if you have a public list of follows, that can be updated too.
This is out of scope for this post, but I think core side-effects like this need to be clearly defined, and we also need a clear way of defining new side-effects as extensions.
Uh oh, most sessions today are about either tracking and analysing people, selling people stuff, or both. Think I'll go to W3C track..
Our epic poster about lying online, complete with laser unicorns, by eMax
Well that was a bust. W3C track, cool WebRTC demos... "our idea is to build a new advertising model inside media streams" ... "location aware targeted advertising" ... "on the fly product placement in video". I quit.
In reply to:
So why are all the use cases for cool tech that people come up with at conferences 'to sell more stuff'? I know there are other uses. People are going to buy crap anyway, but so much energy is spent on this :(
In reply to:
if the only way to get anything done in academia is to be a pawn for industry, fuck that. It's not the case - research for general public good is funded, tho probably not nearly enough. It's depressing that that is entirely not reflected in today's conference sessions
Render reposts of tweets properly
Huh, this weekend is MCM and WebWeWant Fest in London. Sorrynotsorry I'll be on a Croatian island.
It's raining, my train is delayed. Feels like home.
Go home Italy, you are drunk.
Faenza. Connection also delayed 30 minutes.
My favourite thing about Italy is whenever I hear sirens I expect Morrissey to jump out belting The Youngest Was The Most Loved. Also polenta toast with porcini mushrooms. But, happy birthday Morrissey.
Iiiiiiiii may have just got on the wrong train. Probably this situation will resolve itself. It's gotta be going roughly the right way.
Yeah it's an earlier delayed train. Terminates half way to where I'm going so I can pick up the correct train there assuming that one remains ritardo. Had to figure this out by scouring interrail timetables as there are entirely no hints on the train or any platforms passed through.
USB copy php files onto phone, upload with AndFTP. Development on train with no tether 3g contract has never been easier!
On a ferry, waiting for departure..
Arrived before hostel opened, couldn't resist climbing a hill (Marjan)
I enjoyed WWW2015 because I got to hang out with emax and Dave and other SOCIAM people and talk about decentralisation, and eat lots of vegan gelato, and was still on a travelling and hacking high from the two weeks prior.
But content-wise, what I saw was disappointing at best, largely depressing. I unfortunately missed most of the SOCM workshop, which I'm sure would have catered to my tastes a lot more, as my presence was mandated in Microposts2015 on the same day. The Microposts workshops have a bias towards SNA of Twitter, in which I'm tangentially interested, but there's only so much SNA I can take and I think I took it all in 2013. The social science 'track' (two papers) was most interesting. I much prefer when social network users are treated as complex beings than dots and lines.
I flitted between tracks on security and privacy, and web science for a couple of days. I deliberately avoided anything to do with social networks which turned out to be damned difficult. Web science can be a bit big-data-analysis heavy, but often has some interesting human-social (as opposed to social-data) stuff to pique my interest. I went to security and privacy sessions because it's almost guarenteed to not have any social networks, and is usually either scandalous or practical, or both. Often over my head, but also often contains concepts directly relevant to my day-to-day that I wouldn't pick up on otherwise.
I almost cried at the programme for the last couple of days. Literally every session was about social data mining, bulk analysis of social data for tracking and profiling social network users, targeting advertisements, and generally selling people stuff. There was even a track called 'Monetization'. I figured the safest bet would be the W3C track which promised awesome WebRTC demos, which Claudio from Telecom Italia delivered, but then he [reminded](socialwg irc minutes) me that their interest in this stems from wanting to do live product placement in streaming video based on people's interests from social media and ohmygodicannoteven. I tweeted in anguish for a while, then dret summed it up pretty well:
"generally speaking, i'd like to see more "how to make the web work better" at #www2015, and less 'how to make more money with the web'." - @dret
In desperation (I'm on a linked data burnout currently) I dropped by the RDF session but it was ten similar-but-different-mine-is-better-i-promise ways of doing entity recognition - or if it was anything else it was so far divorced from practical application - and I just don't care.
In a last ditch attempt to learn something interesting, I went to the Industry Knowledge Graphs pecha kucha session. Google, Micorsoft, Elsevier and Tagasauris talked about how great they are at absorbing all the data. And.. getting the crowd to curate it nicely... and... not giving any of it back... oh. Because if someone uses it and it's wrong they might get sued? Sure. Whatever. Oh and then Lora Aroyo broke my heart by describing how to make anything and everything a 'shoppable experience' and Dave and I bolted to join Max in a coffee shop.
I had a great ciocolatte with almond milk, then we went for pre-dinner spaghetti in a rave cafe and talked about decentralisation and I recovered.
Overall it was a pretty productive couple of days, because I wrote this post about ActivityStreams and did some more AS2.0 experiments, fixed some bugs in my micropub endpoint and templates, and tweaked my CSS and added my /travel page. And evangelised the Social Web WG to Max a bit. Maybe I couldn't have done that if the conference had captured my interest, who knows.
And I discovered polenta toast with porcini mushrooms, and ate a lot of different flavours of vegan gelato. That's a net win.
I decided last minute to get a ferry from Ancona (Italy) to Split (Croatia). I thought I'd write a note about navigating Ancona and ferries, because I didn't find much online beforehand and if you don't read Italian and/or have an intricate understanding of ports it's not a particularly welcoming experience.
Initially - which is unrelated, but sets the tone - I planned to take trains from Firenze to Faenza, then Faenza to Ancona. The train from Firenza was delayed by 25 minutes, but fortunately I had an hour to make the connection at Faenza. I have already noted that most regional trains I've been on in Italy so far don't have any clues on the outside about where they're going, and lots don't have screens or announcements on the inside either. On top of that, smaller stations don't have live departures signs on platforms (ie. which train is here next) but paper posters for looking up platform based on time and destination. Which are good, but there is a certain amount of hoping for the best when you jump on the mystery train that rolls up to where you think you should be waiting. Anyway, at Faenza the Ancona train was also delayed by 35 minutes. Despite knowing this, I jumped on a mystery train that rolled up at the correct platform at about the correct time, then realised what I'd done. This turned out to be a delayed train from earlier. This was one of the great ones with zero hints on the inside about route audibly or visibly. The Interrail timetable app is great however, and after a couple of stations I managed to pin down which train I was on and could work out that it should terminate at a station where I could pick up the train I should have got - assuming that one was still running late.
It was - even later, in fact - and I eventually switched to the Ancona train at Rimini. The last stretch of the journey was along the coast, which is always good.
The internet advised me to check in to the ferry 2 hours before departure, and I'd left an hour of buffer time, so I still had 20 minutes or so spare even with the delays when I got to Ancona. It was absolutely chucking it down, but I'm getting good at imagining how beautiful towns are in the sun. Pretty sure Ancona would've been stunning. Turn left out of the station and follow the road for about 20 minutes to reach the Ferry Port Authority. Got soaked through, but it was easy to find.
And, all closed up. I could see the ferries, but not where to go to check in. There were signs, but it wasn't clear where I was supposed to go first. I followed various signs for passport control until a disgruntled police officer managed to put me on the number 20 bus. She was grumbling and pointing in Italian so I did as she said, without really knowing why. The bus driver asked where I wanted to go in English, and I said 'check in' and he said 'aha, terminal' and took me there, which was about half way between the train station and the Port Authority, but I'm not really sure if it's reachable on foot or not. This is apparently a free shuttle bus between the different bits of the port you need to visit to successfully board a ferry.
There, the signage was more helpful, and I swapped showing my passport and PDF ticket for a paper ferry boarding pass. The next instruction was to go to Port 9, which I recalled was back by the Port Authority where I'd already been. It looked like the number 20 bus went round in a circle, so I picked that up again outside the checkin terminal and sure enough, it took me back to the Port Authority.
This time was different, because the bus was full of other ferry-bound tourists, so I was able to follow them. Also the same passport control building appeared to be open now, so I followed them into precisely where I'd failed to get in before.
Inside the post-passport-control waiting room was zero indication of where to go next. I followed other people.
We had to wait in the rain a bit, but then got straight on the ferry to be greeted by extremely cheerful staff, presumably to make up for all of the grumpy port staff.
I booked a 'deck passage' which translates to 'sit wherever you can find'. I briefly considered an extra 4 euros to guarantee a seat but then remembered I could get like three gelato for that. That turned out to be great, as the ferry isn't busy (or everyone is in super expensive cabins) and any empty 'paid' seats are fair game. I found one beside a window and a power socket!!! They're good seats, too; big and recliny, and I have a whole row to myself right now so I'm going to lie down and sleep properly in a bit.
(By the way, the ferry ticket was 38 euros with an Interrail discount).
I've eaten all of my stolen conference lunch food and I'm still starving, so Imma go on a ferry-adventure-food-quest.
Update: There are people sleeping everywhere, floors and bar sofas; weird they're not using the empty seats, but more space for me. I procured some overpriced paprika crisps and a jar of souvenir antipasti for sustainance. The rest of the ferry is pretty boring, and largely full of loud middle-aged Italians.
BRB going on adventure around Split
i couldn't take it any more so i went back to the sea
'cos that's where fishes go when fishes get the sense to flee
Arrived in Split just after 7am; it was a beautiful day and I couldn't check in to the hostel until 9, so I wandered into town. The world was just waking up, the sun was warm even though it was early, the sea was sloshing, there were mountains in the distance. Even though there were a lot of people about, and market stalls being set up, everything felt so calm.
Naturally, I got sidetracked by a hill and ended up climbing pretty far up Marjan, the forest-park-hill. The views were beautiful, and passing runners made me excited to run there. Even with two rucksacks the climb was pleasant. I looped back in time to get to the hostel just after 9.
The hostel (Tchaikovsky) is tiny and tucked away down a side street; the owner was really friendly and welcoming, and when I arrived he was running around helping out other guests, picking up laundry, fixing travel plans, and booking other hostels for people he couldn't find rooms for here. Tea and coffee are on tap, and the place is relaxed and super well maintained.
Whilst waiting for my key I made friends with R from near Manchester and L from Singapore. We all headed out together for today's adventure. First stop was a vegetarian cafe 5 minutes down the road from the hostel, where I picked up a seitan sandwich. Then we started by climbing Marjan again, and continuing all the way to the very end of the park, where we spotted this beach:
I, erm, needed to go there. So we did.
And L and I swam in the sea and it was lovely.
We headed back to town, the guys got some food. I discovered through extensive market research that here everyone makes sorbet with cream. How frustrating.
R left and L and I followed a trail of monuments and ruins in the town that he had a map for. There are 14 points with big signs that tell you all about them, which was cool. We never did find number 5 though (Jupiter's Temple). Below is not what the trail looks like on the map...
Then we wandered further east and discovered some more beaches. I paddled and pegged some more good swimming spots for tomorrow.
The threat of torrential rain was looming all day, according to the ominous clouds and the weather forecast. We obviously got seriously lucky. But even it it rains for the next few days I've now seen most of Split (L is leaving tomorrow, hence urgently covering the main attractions). Though I do plan to take a trip to Krka national park, this week is supposed to be a relaxed working environment rather than an actual holiday, so being trapped in the hostel by storms would probably be pretty good.
On that note, the hostel is great. Rooms are really nice, and the beds have privacy curtains, power sockets, big free lockers, and it's like a tenner a night.
Today's general plan:
Going for a wander to find food and somewhere to sit and write CSS, nothing strenuous.
*saves offline maps of 20km radius in case of accidental adventure*
My instincts took me to the university, where I found eduroam...
+ http://www.fallinglakes.com/location--contact.html
Amy added http://www.fallinglakes.com/location--contact.html to https://rhiaro.co.uk/bookmarks/
Today's general achievements:
If micropub used JSON instead of (/as well as) form encoding, what might submissions look like? Aaaron Parecki brainstormed about this on our Social APIs brainstorming doc. I'm going to repeat his examples for create/update/delete here, compare them with equivalent AS2.0 json, then explore other post 'types'.
Note: I've left out @context
from all AS examples because we agreed when missing, this is implied to be "https://www.w3.org/ns/activitystreams".
{
"object": {
"content": "hello world",
"category": ["indieweb"],
"published": "2015-05-15T13:06:00+02:00",
"author": "https://rhiaro.co.uk/about#me"
}
}
No URL is given so it's implied that a new post is being created. Most of this is Aaron's example but I added the explicit published date and author, but these could also be added automatically by the micropub endpoint as the current time and the authenticated user who is sending the request.
ISSUE: actor
vs author
may never get agreed upon. I think actor
is too abstract and author
is too specific. I'm a fan of agent
to mean 'whatever caused this to happen' (be it human, group, process or bot) but I know that's not an easy sell either. I think one side is going to have to suck it up, and I don't know who this is going to be. AS also has attributedTo
which may be a reasonable compromise but seems a bit clunky.
Response per micropub spec: 201 Created
and the URL of the post in the Location
header.
An AS2.0 Activity for creating a new post would look like:
{
"@type": "Post",
"published": "2015-05-15T13:06:00+02:00",
"actor": "https://rhiaro.co.uk/about#me",
"object": {
"content": "hello world",
"category": ["indieweb"]
}
}
Response per ActivityPump spec: "This has the side effect that of the object that they are posting is being created." - either I missed something more specific in the spec or this remains to be clarified (I'm not criticising, AP is very much under-development!).
I prefer the first one. Key differences:
type
on the activity (whereas Post
or Create
is implied in the micropub example).published
and actor
) are attached to the activity, not the object.There has been a bit of discussion about whether things like audience targeting (to
) would be better off attached to the object rather than the activity; I'm inclined to think there's no metadata related to the creating of an object that can't/shouldn't be attached to the object itself, rendering the activity redundant. I keep asking people of examples that contradict this, but so far nobody has given me one.
Aaron's micropub example:
{
"url": "http://example.com/post/1",
"object": {
"content": "hello moon"
}
}
ActivityStreams:
{
"@type": "Update",
"object": "http://example.org/post/1"
}
But the latter doesn't contain the updates made to the object... I might be missing something, but there are no specifics in the ActivityPump spec about this; presumably the user updates the object directly and the Update
activity is generated from that, which is a curiously object-centric happening in an activity-centric world. Neither contain the updated date; presumably for micropub the endpoint is expected to fill this gap automatically, and possibly in the AS example the activity is meant to have a published
property which could also automatically be filled in by the server. I'd like to be explicit about the updated date, though I don't know if this is a must or a should or a may. An alternative I like is:
{
"object": {
"@id": "http://example.org/post/1",
"updated": "2015-05-23T15:00:00+02:00",
"content": "hello moon"
}
}
id
is on the object as in AS, rather than outside it as in micropub, so what you're sending is just the object.type
) because an object with an id
was supplied.content
is submitted, which will replace what exists.updated
date is explicit.ISSUE: I feel like persuading microformats afficondos to use @id
instead of url
might be a toughie.
Aaron's example:
{
"url": "http://example.com/post/1",
"action": "delete"
}
ActivityStreams:
{
"@type": "Delete",
"object": "http://example.org/post/1"
}
They look pleasantly similar :) ActivityPump specifies that "this must leave a shell of the object that will be displayed in activities which reference the deleted object. If the deleted object is requested the server should respond with the HTTP 410 Gone status code."
The empty 'shell' with the deleted date is useful if you want to preserve when you deleted things. Discussed this in #indiewebcamp IRC a bit, and tantek suggested that emptying a post of all metadata but the updated
property would suffice for implying a delete. An alternative to the examples above could be:
{
"object": {
"@id": "http://example.org/post/1",
"updated": "2015-05-23T15:00:00+:02:00",
"...": "...."
}
}
where "...": "..."
means... well, we need to define update behaviour before we can define delete-via-update behaviour. If omitting properties during an update removes them, then we don't need to send empty values for a delete. But if partial updates work, and the properties you send are changed and all others remain the same (which I think is better) then we need to send empty values for everything to delete them. This also allows the possibility of replacing content
with say "This post has been deleted" or "this post was removed due to its offensive nature" or "I spelt literally every word wrong and it seemed easier just to forget about it" and so on, which could be useful for smarter display of deleted posts (ie. as normal posts that have been updated to say they've been deleted). I'm sure someone will have something to say about the semantics of delete vs update; if so, please back it up with practical examples/use cases :)
We also need to consider that someone deleting a post may not want to leave a trace, even if just an updated
date and simply return a 410 if someone tries to access. This should be allowed, with the caveat that it's not possible to advise other servers that may have consumed the post that it's gone if they don't actively try to retrieve it and see the 410.
Or posting a like. Depending on whether you have object- or activity-tinted glasses. New grounds, so I'll start with what exists in ActivityStreams:
{
"@type": "Like",
"published": "2015-05-15T13:06:00+02:00",
"actor": "https://rhiaro.co.uk/about#me",
"object": "https://theperplexingpariah.co.uk/2015/05/a-post",
}
Remember in microformats we have the like-of
property which would have the same value as object
does above, this time, and the 'like' is a first-class post object in itself. So submitting one via micropub could look like:
{
"object": {
"published": "2015-05-15T13:06:00+02:00",
"author": "https://rhiaro.co.uk/about#me"
"like-of": "https://theperplexingpariah.co.uk/2015/05/a-post"
}
}
These are preeetttty different with regards to how terms are being used. A more AS-friendly version where the like is still treated as a first-class object would be:
{
"@type": "Like",
"published": "2015-05-15T13:06:00+02:00",
"actor": "https://rhiaro.co.uk/about#me",
"object": "https://theperplexingpariah.co.uk/2015/05/a-post",
"result": {
"published": "2015-05-15T13:06:00+02:00",
"author": "https://rhiaro.co.uk/about#me"
}
}
Even though a like post is implicitly created through the result
you have to go via the activity that generated it to find out what it's a like of so it doesn't really stand on its own. In the same way as audience targeting and other metadata is useful attached to the object I think having the like relation directly between the objects is practical. For semantic pedants, one post is a like-of
another post, so it's closer to having a like type than being a like verb. But it's an implicit type, rather than an explicit one. Just to reiterate: I'm not saying 'post A likes post B'. That would be silly. 'Post A like-of post B' pretty easily implies the author of post A likes post B. It's not worth trying to overthink that, and you don't need RDF inferencing to make sense of it.
In summary, even for things other than creating posts, I think just sending an object works. You can attach other things like "content": "I like Jessica's post"
too if you wanted, for nicer display.
The closest example in ActivityStreams is an Arrive
activity:
{
"@context": "https://www.w3.org/ns/activitystreams",
"@type": "Arrive",
"actor": {
"@type": "Person",
"displayName": "Sally"
},
"location": {
"@type": "Place",
"displayName": "Work"
},
"origin": {
"@type": "Place",
"displayName": "Home"
}
}
I have never needed origin
with a checkin so I'm going to ignore that for now. I think I want to send to my micropub endpoint something more like:
{
"object": {
"published": "2015-05-23T13:00:00+02:00",
"location": "https://rhiaro.co.uk/home",
"content": "I got home"
}
}
or
{
"object": {
"published": "2015-05-23T13:00:00+02:00",
"location": "http://dbpedia.org/resource/Edinburgh",
"content": "Finally back in Auld Reekie!"
}
}
These are just like regular posts, but with a location property. Which is magically compatible with ActivityStremas and Microformats!
Where location
is always a URI, so that display name, latitude, longitude, etc, can be attached to that and don't need to be included in the checkin. I'm a big fan of not nesting. If you submit a checkin with a nested venue object, the endpoint has to try to create the venue before it can do the checkin, which means it needs to attempt to de-dup venues as part of the checkin process; and if the creation fails then there's more hassle... there's probably a smart way of designing the UI plus use of javascript that can make this pretty smooth, but it's definitely not something I want to have to deal with.
In AS we have Accept
which is supposed to have an object
of Invite
which in turn has an object
of Event
(whether these are all nested in the Accept
activity or just referenced by URI doesn't really matter, the structure is the same. I included the nesting here cos I just copied the example directly from the AS vocabulary spec):
{
"@context": "https://www.w3.org/ns/activitystreams",
"@type": "Accept",
"actor": {
"@type": "Person",
"displayName": "Sally"
},
"object": {
"@type": "Invite",
"actor": "http://john.example.org",
"object": {
"@type": "Event",
"displayName": "A Party!"
}
}
}
While it's all semantically-pedantically very lovely, I reckon the microformats way of just having an RSVP be a regular post with a reply-to
another regular post which happens to have a location
, start
and end
(thus making it an event) is easier to follow and generally simpler (and effective as evidenced by all the people posting and RSVPing to indie events). In JSON, I think that'd look like:
{
"object": {
"published: "2015-05-23T13:00:00+02:00",
"reply-to": "http://indiewebcamp.com/2015/Edinburgh",
"rsvp": "Yes",
"content": "Really looking forward to IWC Edinburgh!"
}
}
Microformats does have invitations too though - what's the fun of RSVPing to an event if you can't invite your friends! Invite posts can be part of an event post, part of an RSVP post, or a post by themselves. That's because all we're really doing to create them is adding invitee
properties for everyone you want to invite, and then sending them webmentions. If your invitation is not also the original event, you can send the original event post a webmention too (since you've mentioned it, after all) which could allow it to update its own list of who has been invited. Your invitee should reply with their RSVP both to your invitation and the event (which they can do with one post). Brainstorming about this, which is by no means sent in stone, on IWC wiki.
Here is an event with a list of invitees:
{
"object": {
"published: "2015-05-23T13:00:00+02:00",
"name": "IndieWebCamp Edinburgh",
"start": "2015-07-25T10:00:00+01:00"
"end": "2015-07-26T18:00:00+01:00",
"location": "http://dbpedia.org/resource/Edinburgh",
"content": "Bring your friends to IWC Edinburgh!",
"invitee": ["http://tantek.com", "http://theperplexingpariah.co.uk", "http://aaronpk.com"]
}
}
Neither ActivityStreams nor Micorformats have things to do with eating and drinking, but this is something I log on my site. My micropub endpoint currently recognises Aaron's p3k-food
property so I'll use that here, but I'd prefer it to be something more generic..
{
"object": {
"published": "2015-05-23T17:00:00+02:00",
"p3k-food": "A burrito",
"category": ["mexican","burrito","yum"]
}
}
A potentially useful fall back for something that wants to display this post but doesn't understand p3k-food
could just to be to treat it as content
.
Yes, I do desire to tag my food posts.
The value of p3k-food
could also be a handy URI for the food, if one existed, which when dereferenced could give you things like different language display names, calorie count, cuisine affiliations, ingredients, etc.
My micropub endpoint will accept JSON and expect an object
with a bunch of properties. From these properties my server can infer how to treat them with regards to who to send webmentions to (ie. who to explicitly notify that this object was created; if I was implementing ActivityPump I'd send the whole object to these people's inboxes) and how to display them. It dosen't need explicit types, or properties spread over activities and objects to do this.
In anther post I'll run through this for (un)follows, adding to and removing from collections, exercise posts, music listens, code commits, travel plans, offers and requests, and see if they hold up the same.
If you have examples of online social stuff you do that you don't think you could publish and propagate this way, please tell me all about it. I really want to know.
Not a bad office location today.
I did hike 10 miles to get here though.
Hey Jeremy, what date did you decide for IWC Brighton? I felt like it was in June, but also that it coincided with Portland which is July, so now I'm confused. http://indiewebcamp.com/2015/Brighton is empty..
Also if you get a minute, could you give me the Mailchimp contact you mentioned?
Cheers!
Ran into restaurant to escape torrential downpour.
"Can I get a coffee please?"
"Do you want that to go?"
... * drips *
Yesterday I jumped on a ferry at 0645 to Šolta, one of the smaller and closer islands to Split. The ferry took about an hour and was 56 kuna (£5.60) return. It seemed to be full of manual labourers commuting to work. This made a lot of sense when I arrived, as there's a lot of building work going on on the island. I'd heard there isn't anything in particular to do or see on Šolta, and that it's peaceful. My main aim was to find a nice bit of beach to set up office on for a few hours.
I thought I'd walk around the coast until I found a good spot, so set off east from Rogał. It was beautiful; the sea was shades of blue and green I can't even comprehend, and once everyone from the ferry had dispersed there wasn't a soul in sight. I only managed to get so far before my way was blocked by inpenetrable trees and/or sheer cliffs and I had to turn back. Intead of backtracking all the way back to Rogał to take a road though, I had a shot at pushing through the forest a bit. All over are tracks of rocks, like someone started building wide drystone walls and stopped after a few layers. These came in pretty handy for following through the brush, and eventually I cleared the denser part of the woods. Everywhere were vineyards and olive groves, and it was utterly peaceful. GPS was strong, so I kept off the roads and aimed for Stomorska. After an hour or so of (scr)ambling through the woods, I had noted the variety of lovely butterflies, become hyper-aware of all rustling sounds having seen several snakes disappearing into crevices not far from my feet, and carefully disassembled no small number of webs belonging to giant spiders so that I could pass. Suddenly I realised I had got turned about, and wound up on a road to Grohote, in the opposite direction to Stomorska. I particularly wanted to visit Maslinica at the west end of the island because I'd seen photos of more smaller islands off the coast there, so I kept on to Grohote. I stopped in the village for juice and chocolate, then continued the remaining 8km by following the road.
I was enjoying the walk, and it was warm, though often raining very gently. Not many cars passed, but over half that did (including one scooter) stopped to offer me a ride. I figured based on this I'd hitch back.
I made it to Maslinica and followed the coast around until I found an empty seafront bar with wifi, where I settled.
Here's the GPS trace of my walk on RunKeeper (pending runkeeper deciding to actually push it to the website...).
All day the only people who came by the bar seemed to be friends or family of the couple who were working there. It was also a beautful spot for a swim (but really where wasn't?), with a stoney beach. I worked on my site until my battery ran out, then wandered around Maslinica.
My legs were not impressed with the idea of walking 10km back to Rogał, and in any case I wouldn't have time to make the last ferry. I set off down the road, and sure enough the first car to come by picked me up, after about 20 minutes. They were going to Grohote, which is 2km from Rogał and a route I hadn't walked yet, so no problem, but last minute they decided to take me the last extra few minutes to Rogał anyway. So suddenly I had two hours to kill before the return ferry!
This time I wandered west around the coast, and found some more gorgeous swimming spots, and chilled out in a spot off the track from where I could see the ferry come in.
In conclusion, if you need distractions you should probably pick another island, but if you want understated beauty and a calm retreat, Šolta is definitely worth checking out.
Seitan > tofu
It was crazy hot this morning, though my legs made me promise not to do anything too strenuous. I deliberately set out ill-equipped for any adventures involving mountains, rocks or undergrowth. So you can imagine how that went ;)
I picked up a hemp burger and interesting couscous cake thing from Makrovega, dropped off clothes at a laundrette, and made for the beaches on the north side of Marjan. I was spoilt for choice regarding beautiful and deserted spots of clear water. I noticed this starting to roll in...
Becoming rapidly closer, and emitting thunder, but still far enough away..
I had enough time to dry off in the sun, eat my burger and get dressed and duck into the woods before the first rain started to fall. Seeing and hearing it approach across the water was cool, and I sheletered under a pine tree until it passed. I carried on around the edge of Marjan, each little rocky cove more blue and clear than the last. The next wave of rain was heavier and lasted longer. I sheltered under the trees for the worst, and managed to make it to a restaurant before it got really bad. The restaurant had wifi, coffee and a sea/rain view, so I bedded in. The rain didn't look like it was going away any time soon. I did, however, have a pressing need to pick up a chocolate amaranth pudding from Makrovega before the socialwg call at 7 (not to mention my laundry), so I couldn't stay there all day. I heard an Irish couple asking the staff to help call a taxi, so I got in on that, and they wouldn't even take any money. They happened to be staying in a perfect proximity to the laundrette, Makrovega, and my hostel, so I successfully completed all tasks shortly after being dropped off and made it back in time. And the rain had stopped.
Later I wandered out to pick up food from Vege on the seafront, but despite Google's assurance they were open til 2300, they were not. I found some pretty great box noodles on the way home, with seitan, many veggies and peanuts. Split's answer to Edinburgh's Red Box, but cheaper and all round better.
Up super early for the bus to Zadar tomorrow...
Tasting the university of Zadar eduroam
I made the 0800 bus from Split to Zadar, which was later than I intended, but oh well. That was 94 kuna, and took about 3.25 hours. I dozed a bit, but the sea views were pretty good. I floated around Zadar complete with rucksacks. I saw/heard the sea organ, wandered around the marina, sat at a cafe for the bit watching boats, wandered through the university campus, wandered through Konzum for a snack, and wandered back to to the bus station. Most of the things to see in Zadar seem to be churches, which I'm sure are very impressive and maybe I would have bothered if I hadn't been rucksack-laden. I was disappointed not to stumble upon a beach I could sit at, it was all harbour. Or at least, where I got to was all harbour. I definitely like Split better from this experience, but Zadar has some epic (and closer) islands I hear, which I'd love to hop between.
The bus to Korenica is presently 15 minutes late and counting, and if I hadn't noticed loads of other buses being late I'd be a bit concerned I was waiting in the wrong place...
+ https://peerj.com/articles/cs-1/
Amy added 'Achieving human and machine accessibility of cited data in scholarly publications [PeerJ]' to Bookmarks
This hostel has Settlers of Catan and free mountain tours and a nice kitchen and friendly staff and I can already tell one night and one day here isn't going to be enough. Also I love travelling alone, but I wish I had someone to share this with right now. (Also to play Settlers of Catan with. Yeah that might be it actually).
Tomorrow I'm going to literally walk for ten hours, so I should probably start sleeping soon.
In reply to:
Oh. I just remembered who makes the decisions about this trip. It's me. I will just stay another night. Duh.
+ http://www.egi.eu/blog/2015/05/27/resounding_success_of_the_open_science_commons_in_lisbon.html
Amy added 'Resounding success of the Open Science Commons in Lisbon - The EGI blog' to Bookmarks
Last night I arrived in Korenica (the bus showed up 35 minutes late; 84 kuna, somehow arrived on time 2 hours later, really spectacular mountain scenery), and successfully navigated to Falling Lakes hostel. I thought Tchaikovsky in Split was the best, but Falling Lakes is even nicer. Croatia could really teach the world a thing or two about how to do hostels. I was greeted by Irena, who helped me figure out buses and gave me a ton of advice about how to explore Plitvice. The hostel has a lovely kitchen, plus fresh herbs in the garden, so I immediately went to Konzum to get things I could cook. The hostel is so nice and I was dreading the rush of picking up my rucksack and catchign the bus to Zagreb after walking all day. Then suddenly I realised I could just book another night in Korenica and go to Zagreb in the morning. My host in Zagreb was happy with the change of plan, and suddenly that was a weight off.
I didn't get up quite as early as I'd planned, but still early enough that I didn't want to wait for the official (35 kuna) hostel ride to Plitvice. It's about a 15 minute drive, and the highway is not safe to walk on, with no footpaths, sometimes steep banks, many trucks and everyone going really fast. But I hadn't even made it out of Korenica before I was picked up by a middle aged couple from Zagreb who were very interested in all of my travel. They dropped me at Gate 1 at 0900, which threw off my well thought out agenda that began at Gate 2.
Entrance to the park is 80 kuna with a student card, and the ticket includes one boat ride and one mini-bus-thing ride. Maps are 20 kuna, but fortunately Irena gave me one at the hostel. I did some dynamic replanning, figured there was no way I wasn't going to have to cover a stretch twice if I wanted to leave from Gate 2, and headed for the boat. This was supposed to be the last thing, and I considered walking the length of the lake and getting the boat for the repeat of that later, but then it arrived, so I hopped on. I'm really glad I did, because when I went past again later there were three boats worth of people waiting. That took me to near Gate 2, and the start of the main bit of world-famous multi-tiered waterfalls. I followed the path.
I could have done with learning a few Japanese phrases, like "if you must walk this slowly at least stop zigzagging", "this walkway is too narrow for you to stop and look at every little thing" and "put that selfie stick away you're going to have someone's eye out". There were a lot of elderly Japanese tourists who walked very slowly and had no regard for the high risk of sending people flying into the waterfalls when they stopped suddenly and started brandishing cameras. Sigh.
The waterfalls were impressive and everything, but I had a bit of human overload. Not just the tourists (I know they were all there for the same reason I was), but the work that had gone into making the surroundings traverseable. The walkways were all wooden, and very tasteful; often stretching across whole lakes, low to the water, or steps directly above a waterfall so you were always really close.
I couldn't help wondering what this place would be like without the intervention. How many of the waterfalls and streams were actually there as a result of some footpath sculpting? I enjoyed more when the walkways were flooded and the water was trying to take back its space.
Following Irena's advice, I took a less-trodden trail, from point 1 to point 3 (purple on the map) which led deeper into the woods of the park, away from the main area. I'd have loved to go via point 2, which goes way into the park through small settlements that are still occupied, but I didn't think I had time for the full 24km. I was soon deep in peaceful woods, and saw only two other hikers the whole time. That's more like it. I started to recharge. The trail was well-marked with little read dots on trees, so I could drift. After the intial excitement of interesting mushrooms and rocks, and dappled sunlight, the woods were pretty samey. I love the woods, and it gave me lots of thinking time. I was hankering to work on indieweb and socialwg stuff.
The route took me back to the park, and in a lot less time than I expected. I was back at the Big Waterfall, not far from where I started, at 1430. This time I walked around the eastmost side of the lake, close to the water, to Gate 2. That didn't take long either, and I didn't feel I could just go back so early. I sat for a bit, and then wandered south. I decided to see how far I could get in the direction of Korenica without going back to the highway. Technically the park goes all the way, but I had no terrain information. I ploughed on over a definitely-off-track hill. The ground was leaves and squish and the trees were close and I had to fight through them. The ground though! That's what the world is made of. Decaying things, packed together. It was nice. I made it to the top of one hill and there was another, and another, and another. I'd gone too far to turn back, and my GPS was telling me I was slowly progressing in the right direction. The hills were steep; like I said, off-track, and I basically just had to charge directly upwards, clinging to bushes.
It doesn't seem to matter where I go, I will always ultimately end up scrabbling up hills through undergrowth.
It was such a relief when the track/settlement I could see on google maps appeared over the hill. I made for the highway, cos there was no way trying to go through the park all the way back was a good idea. The verge was such that I could stay off the road, so I followed the highway for about 20 minutes before I was picked up by a local. He didn't speak English but I think we managed to communicate a bit. I was passed by loads of cars that didn't stop this time; I presume they were tourists. Bah.
He dropped me in the centre of Korenica, and I stumbled back to the hostel and collapsed for a bit, by 4pm.
I walked around 18 miles today. My legs, aside from being extremely reluctant to support me, have developed all kinds of interesting enormous red lumps with varying degrees of itchiness. I assumed they were insect bites (they have been developing for several days now) but some of them are going a bit weird. I should probably at least document it...
Also I should sleep... 0625 bus to Zagreb in the morning!
Chilling in park Bundek, Zagreb
Coffee in Croatia is better than coffee in Italy, in my professional opinion.
Anti-government protests in Zagreb Upper Town. Also eduroam.
I just jumped on the train from Zagreb to Ljubljana for the final leg of my trip. My stay in Zagreb was short but magical. I will be back. To make a positive generalisation, Croatians seem to be the most hospitable people ever. Perhaps too hospitable; over the past 24 hours I've been scolded many times for saying 'thank you' too much and offering to help move/carry/cook/clean things, I've overeaten, and eaten enough dairy that I feel a bit queasy because I was already being looked after far too well, and the delight with which fritula, biscuits, pancakes and cappucinos were sent my way was impossible to say no to. I did manage to turn down ice cream a couple of times, and communicate 'vegetarian' before it was too late.
So remember L who I met in Split? He put me in touch with D, with whom he'd stayed in Zagreb. D was quick to offer me a bed too. She met me at the station on Friday morning, and I joined her, her neighbour S (who reminds me a lot of my grandma) and her daughter M in wandering around a flower exhibition for a couple of hours. D bought fritula with chocolate sauce and insisted I try this local speciality (they're like doughnut holes, but chewier). The flower exhibition was in Bundek park, and was a lovely, relaxing start to the day. We stopped in a cafe for a coffee, and S insisted on paying for mine. D shared wifi from her phone and I caught up on the internets.
Then they bought some plants; I was really tempted by a teeny tiny cactus, but it would never have made it home.
D dropped me in the city centre and headed home (with my rucksack so I didn't have to carry it). I wandered through the old town and upper town. Zagreb is pretty hilly. There were anti-government protests and lots of police near the government buildings. There also seemed to be some kind of police-escorted muscle car demo in the centre. I saw all of the main buildings listed on wikitravel, and thought about visiting the Museum of Broken Relationships but the weather was so good I didn't fancy spending the afternoon inside.
Despite this, when I found Nishta, a vegetarian restaurant with power, wifi and incredible food, I bedded in and ended up being there for a productive and delicious three hours. I 'splashed out' and spent 112 kuna on amazingly floral iced tea, BBQ barley and tofu burger, almond cream panna cotta, and coffee. So. Good. So I stayed much longer than intended, and needed to hurry back to D's place, which is in the north of the city at the base of the mountain. I took what I thought was a short diversion via Mirogoj cemetery on the way, but this ended up adding over an hour to my route. What looked close on the map was actually separated by several hills and impenetrable forest. As usual.
The cemetery was pretty spectacular, and I could spend more time there.
The walk from there to D's was mostly uphill, but so scenic. There were some rad, modern houses and tons of foresty space. The city was well and truly out of sight; views from all balconies and gardens were green. I could definitely live there.
I eventually navigated to D's, where I met her six excitable jack russells, and S's son, M. I had a room in D's attic, with a gorgeous view and my own bathroom. She made dinner, and even offered to wash my clothes. I ate rice and salad (with pumpkin oil), pancakes and homemade jam, outside on the terrace while the sun set over the mountain and M quizzed me about who controls the internet, why being vegetarian is reasonable when plants have feelings too, and why Tigo wouldn't be better off if I set him free.
This morning D was out for a bit, and I was under instruction to visit S across the road for coffee when I got up. Not only coffee, it turns out, but chocolate wafers and bread and apricot jam (I managed to stop her from cooking eggs for me) but I wasn't at any point allowed to stop eating the bread and jam >.< Again, I wasn't allowed to help, either. We sat in the garden, in the blistering sun until D got back.
D drove me to the train station, but not before S had wrapped up an armful of chocolate wafers for me, and D made me jam pancakes for the road.
Wow I'm full.
Need to go back to Zagreb.
I just reached Dobova, and Croatian and Slovenian police came through to check passports. I think the train is sitting here for about half an hour. The train is super nice! Power sockets, and every six seats are in their own little compartments with doors.
I think Croatia is my favourite country so far.
Arrived in Portoroz for ESWC2015! Hostel on the top of the hill, naturally. Anyone for dinner?
This afternoon was probably the most ad-hoc bit of travel in this whole barely-organised trip so far. I couldn't find any information online about buses from Koper to Portoroz, other than that such things exist, so I figured I'd show up in Koper and figure it out from there. What could go wrong?
Step one was easy: bus station was right outside the train station. Bus stands were all labelled with destinations, and no fewer than three had Portoroz listed.
Step two was easy: there were buses in the stands, with Portoroz even in their window signs.
Step three was more difficult: there were no timetables, and no bus drivers.
So I started to deviate from the obvious plan.
Step four: talked to accumulating small group of fellow rucksack-bearing young people. Discover nobody knows the timetable and everyone is waiting around hoping for the best. Discuss how long we should wait.
Step five: more adventurous Americans go to speak to nearby taxi drivers.
Step six: we realise splitting the cost of a taxi is the same as the bus, and all seven of us pile into a taxi-van. Most are bound for Piran, two of us to Portoroz and one person (the only other ESWC-goer) for somewhere in between.
Step seven: success! Arrived in Portoroz for a mere 3.5 Euros, less than half an hour later. Mohammed, the other Portoroz passenger, turned out to be staying in the same hostel as me, so we climbed the hill together.
The hill was knackering, and it was hot, so I was keen to crash but ended up taking an hour to check-in because Andrej the hostel owner was fun to chat to.
I'd booked a bed in a 10-bed dorm, as usual, but apparently I'm the only girl staying in the hostel. So I have a family room to myself, with my own bathroom! Score. Seems like yet another great hostel. Feeling bouncy, so I'm going to meet other ESWC-ers for dinner (thanks, twitter!).
Developers workshop off to a good start. We all introduce ourselves with hashtags so I went with indieweb and ownyourdata ^^
I'm really hoping ESWC2015 reignites my excitement about linked data, which has been kinda damp for a while. SemDev2015 seems like a great place to be for that already.
"This is an html view on the data, for humans. Is it so hard to just make it readable?!" Realtalk from http://twitter.com/essepuntato
"I wrote this code and it doesn't work really." Realtalk from @KKjernsmo xD
CLEAR YOUR CACHES EVERYONE, NEW WEBSITE IS UP.
Whew.