53°F 7:21am

Aaron Parecki

  • Articles
  • Notes
  • Micropub CR

    Tue, Aug 23, 2016 10:00am -07:00

    I'm excited to announce that Micropub is now a W3C Candidate Recommendation!

    Three Years of Incubation and Selfdogfooding

    Micropub began in 2013 when I outlined a simple API to create blog posts and short notes for my website, and then implemented it both on my server, several new clients, and started using it day-to-day. Micropub aims to be simple to understand and implement, built on top of existing standards such as OAuth 2.0 and the Microformats 2 vocabulary.

    Designed for Incremental Implementation

    Micropub is also intended to be implemented incrementally. You can start by implementing just the basics of creating simple posts, and then expand your implementation to support additional properties of posts, and later expand to enable editing posts as well.

    Widespread Interoperability Across Numerous Implementations

    One of the benefits of supporting Micropub is that it allows you to leverage other peoples' work in building an interface to create posts on your own website. By 2014, there were already six independent server implementations: five created by individuals for their own websites, as well as a plugin for the Known content management system. In addition to the client I wrote, there were four other people who built their posting interfaces using Micropub, which meant that anybody else with a Micropub server could sign in and use them!

    Over the next several months, more and more people built out Micropub support in their blogging systems, including plugins for Wordpress and Drupal! I continued to build Micropub clients like OwnYourGram, which imports your Instagram photos to your website, and Teacup which I use to track everything I eat and drink, even posting from my watch.

    See also: Complete list of live Micropub implementations

    Openly Iterated and Formally Standardized

    I gave a talk on Micropub at Open Source Bridge in 2015, when we had just started prototyping clients and servers that could start editing posts.

    At the beginning on 2016, we published the First Public Working Draft of Micropub under the W3C Social Web Working Group. For the past several months, we've been iterating on the spec, refining the language, clarifying how to edit and delete posts, and working on ways to ensure a good user experience for applications that post photos and videos.

    W3C Official Call For Micropub Implementations

    Last week the W3C announced that Micropub is now a Candidate Recommendation, and is inviting a wider audience to implement it and provide feedback.

    Stay tuned for updates as I build out the test suite and debugging tools to help you build Micropub clients and servers. They will be launched at micropub.rocks in the coming months!

    Portland, Oregon
    58 likes 7 reposts 4 replies 17 mentions
    #w3c #socialwg #micropub #indieweb
    Tue, Aug 23, 2016 10:00am -07:00
  • Centered and Cropped Thumbnails with CSS

    Sat, Aug 13, 2016 11:30am -07:00

    When working on my photo album thumbnail navigation for this site, I wanted a way to show a square thumbnail of a photo, centered and cropped from the original version. I wanted this to work without pre-rendering a square version on the server, and without using background image tricks.

    I found a great technique for doing exactly this at jonathannicol.com/blog/2014/06/16/centre-crop-thumbnails-with-css, adapted from the WordPress media library. The code below is modified slightly from this example.

    Markup

    <div class="album-thumbnails">
      <a href="photo-1.jpg">
        <img src="photo-1.jpg">
      </a>
      <a href="photo-2.jpg">
        <img src="photo-2.jpg">
      </a>
    </div>
    

    CSS

    .album-thumbnails a {
      /* set the desired width/height and margin here */
      width: 14%;
      height: 88px;
      margin-right: 1px;
    
      position: relative;
      overflow: hidden;
      display: inline-block;
    }
    .album-thumbnails a img {
      position: absolute;
      left: 50%;
      top: 50%;
      height: 100%;
      width: auto;
      -webkit-transform: translate(-50%,-50%);
          -ms-transform: translate(-50%,-50%);
              transform: translate(-50%,-50%);
    }
    .album-thumbnails a img.portrait {
      width: 100%;
      height: auto;
    }
    

    For my use, I am showing a series of 7 square thumbnails on one line, so I set the width to 14% (about 1/7) so that they will fit on one line. Since the width of my container is about 620px wide, I set the height to a fixed amount, 88px, so that the thumbnails will be approximately square.

    The neat thing about this is that when the container shrinks when viewed on smaller devices, the widths of the thumbnails will shrink as well. This does mean the thumbnails will no longer be square on narrow screens, but I'm okay with that result. You can also use a fixed pixel height and width if you don't want them to shrink at all.

    Javascript

    You may notice that the last CSS rule requires a class of "portrait" on image tags where the image is portrait orientation. You can either add that class server-side, or use the Javascript below to add the class when viewed.

    document.addEventListener("DOMContentLoaded", function(event) { 
    
      var addImageOrientationClass = function(img) {
        if(img.naturalHeight > img.naturalWidth) {
          img.classList.add("portrait");
        }
      }
    
      // Add "portrait" class to thumbnail images that are portrait orientation
      var images = document.querySelectorAll(".album-thumbnails img");
      for(var i=0; i<images.length; i++) {
        if(images[i].complete) {
          addImageOrientationClass(images[i]);
        } else {
          images[i].addEventListener("load", function(evt) {
            addImageOrientationClass(evt.target);
          });
        }
      }
    
    });
    
    Portland, Oregon
    4 likes 3 reposts 1 reply 1 mention
    #css #layout
    Sat, Aug 13, 2016 11:30am -07:00
  • Signed git commits with Tower

    Fri, Jul 29, 2016 10:18am -07:00

    My favorite Git client is Tower. I wanted to find a way to sign my git commits despite that not being a supported feature of Tower. Turns out it only took a couple configuration options to make it work.

    First, set up your GPG key however you normally do it. I use GPG Tools for OSX, as well as Keybase. Follow GitHub's instructions for adding your GPG key to your account here.

    Configure your git client to always sign commits:

    git config --global commit.gpgsign true

    Try to sign a commit from the command line before trying it with Tower. Once you're able to successfully sign commits from the command line, you can set it up to work with Tower.

    Add no-tty to your GPG configuration, to allow Tower to use it:

    echo no-tty >> ~/.gnupg/gpg.conf

    You'll need to specify the absolute path to the gpg program in order for Tower to be able to find it.

    git config --global gpg.program /usr/local/bin/gpg

    Now when you make a commit from Tower, you should be prompted to unlock your key with your passphrase from GPG Tools, and if you save it in your keychain it should continue to work seamlessly.

    Now, whenever you make a commit and push it to GitHub, you should see the "verified" mark next to your commits!

    Portland, Oregon
    5 replies
    #git #tower #gpg
    Fri, Jul 29, 2016 10:18am -07:00
  • This Year in the IndieWeb

    Mon, Jul 18, 2016 7:30pm -07:00

    It's been an exciting year in the IndieWeb so far!

    June 2016: IndieWeb Summit, Portland

    IndieWeb Summit 2016

    In June, we held our main event in Portland, newly called IndieWeb Summit to differentiate it from the IndieWebCamps happening all over the world.

    One of our attendees, Julie Anne, is an amazing photographer and took some great pictures of the event!

    • Day 1 Photos
    • Day 2 Photos

    We livestreamed the morning keynotes and second day demos, so you can watch them online!

    • State of the IndieWeb
    • Cutting Edge IndieWeb
    • Day 2 Demos

    Some people wrote some great blog posts afterwards.

    • gRegor Morrill
    • Kyle Mahan
    • Jim Pick
    • Tantek Çelik

    May 2016: Düsseldorf, Germany

    Düsseldorf 2016

    We had a great IndieWebCamp in Düsseldorf in May, adjacent to the beyond tellerrand conference.

    Julie Anne took some amazing photos of this one as well!

    Steffen Rademacker wrote a great post afterwards and included some of his own photos as well.

    April 2016: Nürnberg, Germany

    Nürnberg 2016

    • More Photos

    March 2016: MIT, Cambridge

    MIT 2016

    January 2016: New York

    New York 2016

    December 2015: San Francisco

    San Francisco 2015

    November 2015: MIT, Cambridge

    MIT 2015

    July 2015: Portland, Brighton and Edinburgh

    PDX 2015

    Brighton 2015

    Edinburgh 2015

    Homebrew Website Club

    Between IndieWebCamp Portland 2015 and IndieWeb Summit 2016, the community organized 102 Homebrew Website Club events across 11 cities worldwide! San Francisco, Los Angeles, Portland, Bellingham, Montréal, Detroit, Brighton, Washington DC, Edinburgh, Göteborg, Nürnberg, and Malmö.

    IndieWeb at the W3C

    This year, thanks to a lot of effort on the part of everyone participating in the W3C Social Web Working Group, the Webmention specification that started from the IndieWeb community has been published as a Candidate Recommendation by the W3C!

    w3.org/TR/webmention

    We developed a Webmention test suite so you can test your implementations as well!

    The Micropub specification has also been published by the W3C as a Working Draft, and a couple more specs are on the way!

    New Logo and Website!

    Portland, Oregon, USA
    #indieweb
    Mon, Jul 18, 2016 7:30pm -07:00
  • Where was I when I took this photo?

    Sat, Jul 16, 2016 8:59pm -07:00

    My DSLR camera doesn't have GPS, so normally all my photos would not include the location of where I was when I took the photo. I used to use the Eye-Fi card that did geotagging, but that is no longer supported in the new "mobi" line. I could get an external GPS unit for my camera, but that sounds cumbersome and would only work with that one camera.

    Since I already track everywhere I go, I figured I could use this data to geotag my photos when I upload them to Flickr. It turns out, due to the limitations of Exif, the metadata format that digital cameras use to store information about photos, it wasn't so easy.

    Adventures in Exif

    Exif lets the camera write arbitrary text data into a jpg when it saves it. There are a handful of standard properties that most cameras write, such as the time the photo was taken, the camera settings such as shutter speed, f-stop, etc, and GPS location if the camera knows where it is. My thought was that if I know when the photo was taken, I can find out where I was at that time, and then add the GPS data to the photo.

    Unfortunately, the format for storing dates in Exif does not support specifying a timezone offset. The format for dates is YYYY:MM:DD HH:MM:SS. Without the timezone offset, this series of numbers corresponds to many different actual points in time, depending on which timezone you interpret it as. So what I need is a way to turn the camera time into a specific point in time in order to find out where I was at that time.

    A + B = C

    I realized that since I have a complete log of my GPS coordinates, I should have enough information to piece this together. Essentially the question I am asking is "where was I when my clock read 7:00pm on July 16 2016?" Note that there are two parts to the answer: my location, and the absolute point in time. It's kind of like solving an equation where there are three variables and you know two of them. The three variables are: my location, the clock time, and the timezone offset. If we knew my location and the clock time, we could find the timezone offset. If we knew the timezone offset and the clock time, then we could find my location. 

    Where was I when my clock read "7:00pm on July 16 2016"?

    If we knew what timezone I was in, then "7:00pm on July 16, 2016" becomes a single reference to an absolute point in time. But we don't know what timezone I was in yet, so there are actually 24 possible absolute points in time this could be. (I'm simplifying this problem slightly by ignoring the 30-minute offset timezones.)

    The solution is to find my location (which includes the absolute point in time) at all 24 possible points in time, find the timezone offset that corresponds to each location, then find the location where its timezone offset matches the candidate offset. Below is an example:

    Offset-less time in question: 2016-05-12 16:00:00

    This could be any of the absolute points in time:

    • 2016-05-12 16:00:00 -23:00
    • 2016-05-12 16:00:00 -22:00
    • ...
    • 2016-05-12 16:00:00 -07:00
    • 2016-05-12 16:00:00 -08:00
    • 2016-05-12 16:00:00 -06:00
    • 2016-05-12 16:00:00 -05:00
    • 2016-05-12 16:00:00 -04:00
    • 2016-05-12 16:00:00 -03:00
    • ...
    • 2016-05-12 16:00:00 +00:00
    • 2016-05-12 16:00:00 +01:00
    • 2016-05-12 16:00:00 +02:00
    • ...
    • 2016-05-12 16:00:00 +22:00
    • 2016-05-12 16:00:00 +23:00

    (I left out some of the less common timezone offsets I frequent for the sake of clarity in this example.) Now let's query my GPS database to find out what my local time actually was at each of these points in time:

    Potential Time Time from GPS Location
    2016-05-12 16:00:00 -23:00 2016-05-13 10:59:03 -04:00 New York
    2016-05-12 16:00:00 -22:00 2016-05-13 10:00:00 -04:00 New York
    ...
    2016-05-12 16:00:00 -07:00 2016-05-12 19:00:00 -04:00 New York
    2016-05-12 16:00:00 -08:00 no data
    2016-05-12 16:00:00 -06:00 2016-05-12 17:59:21 -04:00 New York
    2016-05-12 16:00:00 -05:00 2016-05-12 16:59:53 -04:00 New York
    2016-05-12 16:00:00 -04:00 2016-05-12 15:59:57 -04:00 New York
    2016-05-12 16:00:00 -03:00 2016-05-12 14:52:46 +02:00 France
    ...
    2016-05-12 16:00:00 +00:00 2016-05-12 14:52:46 +02:00 France
    2016-05-12 16:00:00 +01:00 2016-05-12 14:52:46 +02:00 France
    2016-05-12 16:00:00 +02:00 2016-05-12 14:52:46 +02:00 France
    ...
    2016-05-12 16:00:00 +22:00 2016-05-11 19:15:41 +02:00 Düsseldorf
    2016-05-12 16:00:00 +23:00 2016-05-11 18:46:26 +02:00 Düsseldorf

    (Note that the times aren't an exact match, because my GPS device doesn't log a point every second. In reality it's more like every second when I'm moving and have a good GPS lock, and when I'm not moving, it records less data. Also on plane flights I sometimes lose the GPS signal part way through the flight which is why many of the rows in this case show the same time from my GPS.)

    As you can see by comparing the potential timezone on the left with the actual timezone on the right, there are two offsets that match (highlighted in yellow), so we need to determine which is the correct one. This happens when I am traveling on a plane and cross timezones very quickly.

    If we take the two candidates and look at the actual time difference in seconds between the timestamps described, the answer becomes obvious.

    Potential Time Time from GPS Difference
    2016-05-12 16:00:00 -04:00
    unixtime: 1463083200
    2016-05-12 15:59:57 -04:00
    unixtime: 1463083197
    3
    2016-05-12 16:00:00 +02:00
    unixtime: 1463061600
    2016-05-12 14:52:46 +02:00
    unixtime: 1463057566
    4034

    From this, I can conclude that when my clock read "2016-05-12 16:00:00" it was at "2016-05-12 16:00:00 -0400" when I was in New York.

    Most of the time only one offset matches, so this last step isn't necessary. It's only when I quickly cross timezones that there are potentially more than one match.

    Turning this into an API

    Since I want to be able to use this to geotag photos, it makes sense to include it as an API in the same system that stores my GPS logs. I encapsulated this logic in my GPS server, Compass with a simple API that returns the answer given an offset-less time. Now I can use it in my geotagging script!

    Portland, Oregon
    12 likes 9 replies 1 mention
    #time #timezone #geotag #gps #p3k
    Sat, Jul 16, 2016 8:59pm -07:00
  • The Sad State of Wifi SD Cards

    Fri, Jul 15, 2016 1:51pm -07:00

    I've been a long-time fan of the Eye-Fi SD cards. My primary use for them is to have all my photos automatically uploaded to Flickr from my camera. It turns out I'm lazy and having to manually copy photos off an SD card and upload them is too much work.

    I've had the Eye-Fi Pro X2 card for years. I have it configured to upload everything to Flickr marked "private". I recently got an email saying that they are discontinuing the X2 product line in favor of their new "mobi" line, which will essentially brick the cards. I, as well as many others, were upset by this news.

    Eyefi Mobi

    Their new "mobi" line seems to be completely different, and heavily promotes subscribing to the Eye-Fi cloud service, something that I have no interest in. I don't want to use their tools to store and manage my photos. I want to send them to Flickr, or even better, my own website. Sadly their new cloud service doesn't even support uploading to Flickr.

    I started looking into other options, but the state of wifi-enabled SD cards is pretty terrible right now. There are a handful of other brands of cards, but they all are limited to downloading photos directly to an iPhone/Android, rather than uploading from the card to something on the Internet.

    The one promising card I found is the Toshiba FlashAir, which has the ability to write custom code that runs on it. I wrote up my initial experiments with it, which were only mildly successful. I tried to pick up that work again, but did not have any luck. There's almost no visibility into the code that's running, so it's very hard to debug. I decided it's not worth it to sink any more time into making that card work.

    I decided to again look into the new Eye-Fi card to see what it's actually all about. It seems that my initial understanding of it was completely wrong. I managed to get a Eyefi Mobi Pro card for $36, including a year of their cloud service, so at least worst case I can write that off as paying $3/mo for a year of their service.

    What I Learned

    After some experiments, I learned that everything I read about the new Mobi card was actually totally wrong! Here is my understanding of the difference between the two cards.

    Eyefi Pro X2

    The card connects to a configured wifi network, and uploads the photos to the Eyefi servers. The Eyefi servers then upload to Flickr, or whatever I've configured. The upside is that the card can upload to the internet without my computer or phone helping. The downside is that it requires Eyefi servers to be involved in the process. Also they are shutting down these servers in September presumably because they never figured out a way to make people want to pay for them.

    Eyefi mobiPRO

    The card connects to a configured wifi network. If my computer is also on that same network, the app on my computer will download the photos from the card. If I have an Eyefi Cloud account, my computer will upload the photos there as well. The upside is that I don't need a Eyefi servers in order to use the card. The downside is the card can only upload photos when my computer is on the same network.

    So for now, I'll try out this Mobi card and see if it ends up being useful even though it can't connect to the internet on its own.

    My wish is for a wifi SD card that can join a wifi network and upload to an FTP/HTTP server itself, without going through a third-party cloud service and without another device helping it out.

    Portland, Oregon
    #eyefi #flashair #wifi #sdcard #photography
    Fri, Jul 15, 2016 1:51pm -07:00
  • Videos from IndieWeb Summit 2016

    Sat, Jun 18, 2016 1:32pm -07:00

    The videos from IndieWeb Summit are finished and online now! I put together separate video clips for the two keynote talks in the morning, and also for the demos on the second day. (Apologies for the somewhat noisy audio, the air conditioners in the space were loud!)

    State of the IndieWeb

    Tantek Çelik

    Cutting Edge IndieWeb

    Aaron Parecki, Ben Werdmüller, Kyle Mahan

    Demos from IndieWeb Summit 2016



    Portland, Oregon
    14 likes 10 reposts 6 replies 3 mentions
    #video #indieweb #indiewebcamp
    Sat, Jun 18, 2016 1:32pm -07:00
  • Monocle is Offline

    Tue, Apr 26, 2016 8:08am -07:00

    When I first built Monocle, I modeled it after the "timeline" or "stream" view now common in social networks, but made it possible to subscribe to h-entry feeds as well. The main UI showed a stream of posts, with the full post contents rendered inline, along with the author info and favorite/repost/reply buttons.

    While this sounds good in theory, it turns out that I found myself not actually using it regularly, likely for the same reasons I don't often read my Twitter home timeline. Instead, I continued to primarily follow content using my IRC channels.

    Last year, I wrote up details on "why I live in IRC", as a way to capture why that interface is more compelling to me than a stream of posts like Monocle and Twitter.

    Since I wasn't using it as my primary reader, I wasn't regularly giving it attention, and several bugs have appeared that have been left unfixed. So for now, I feel it's best to officially shut down Monocle, rather than have it be a partially functional example of an IndieWeb reader.

    You can expect to see development of Monocle resume in the future, but it will take on a very different form than what it previously was.

    Foster City, California
    3 replies
    #monocle #indieweb
    Tue, Apr 26, 2016 8:08am -07:00
  • IndieWebCamp Nürnberg Hack Day

    Fri, Apr 22, 2016 1:00pm -07:00

    At IndieWebCamp Nürnberg, I didn't end up spending time on my home page design, despite a great day 1 discussion on the topic. Instead, I made a few fixes to my site, and built a quick indie reader in IRC, which shows me posts from people I'm following, and lets me reply to them from IRC as well.

    It's ugly, but it works!

    When I type !reply in IRC, my bot makes a Micropub request to my server which creates the post.

    After I got home, I was inspired to spruce up my home page design since there were quite a few great ideas from people. Jeremy Keith added sparklines to his home page, showing activity in a few different kinds of posts. I liked that idea, and wanted to do the same. I also moved my bio to the top of my home page, since that's more of the primary content of the page. Now my posts appear below the header block. 

    I also added four mini previews of posts, showing the last night's sleep, the last thing I ate, the last photo I posted, and the next event. I think this does a good job of showing a little more about me than just my bio and just the last few notes I've posted.

    Now my home page looks like this! I think it's a great improvement over what it was before, when it just started with the latest post.

    Overall, IndieWebCamp Nürnberg was a huge success and I had a great time! I'm looking forward to going back in a couple weeks for Düsseldorf! Thanks to everyone who made the event possible!

    Portland, Oregon
    2 likes
    #indiewebcamp #p3k
    Fri, Apr 22, 2016 1:00pm -07:00
  • New integrated authorization server for p3k

    Wed, Apr 13, 2016 3:21pm +02:00

    I just launched an update to p3k which adds an integrated authorization server. This means that now when I sign in to Micropub apps like Quill, it will redirect me to my own server where I can have more fine-grained control over the access I am granting the application.

    My new authorization endpoint displays the scopes the application is requesting, and lets me modify the scope when granting the request. This means if an application I don't yet trust requests the ability to update or delete my posts, I can un-check those boxes but still allow it to create posts.

    I also have the ability to have all posts from an application be added to a specific channel, rather than showing up in my main feed. I use the concept of "channels" to create different lists of posts depending on what kind of content the post has. For example, /photos contains all of my photo posts, and /travel contains travel plans, plane flight and train logs, and events that occur outside of Portland. 

    Now that I have a built-in authorization endpoint, I'm looking forward to adding more features to it, such as setting the default privacy of posts so I can allow an application to create posts that are only visible to me (or a specific audience) unless I make them public.

    Nürnberg, Bayern
    3 likes 1 mention
    #indieweb #p3k #indieauth
    Wed, Apr 13, 2016 3:21pm +02:00
load more

Hi, I'm Aaron Parecki, co-founder of IndieWebCamp. I maintain oauth.net, and am the editor of the Webmention specification.

I've been tracking my location since 2008, and write down everything I eat and drink. I've spoken at conferences around the world about owning your data, OAuth, quantified self, and explained why R is a vowel.

  • IndieWebCamp Founder
  • W3C Editor
  • All
  • Articles
  • Bookmarks
  • Notes
  • Photos
  • Sleep
  • Travel
  • Contact
© 1999-2016 by Aaron Parecki. Powered by p3k. This site supports Webmention.
Except where otherwise noted, text content on this site is licensed under a Creative Commons Attribution 3.0 License.