Webpage Screenshot Bloghttps://linkpeek.com/blog/2015-01-17T14:41:00+01:00What does LinkPeek mean?2015-01-17T14:41:00+01:002015-01-17T14:41:00+01:00Russelltag:linkpeek.com,2015-01-17:/blog/what-does-linkpeek-mean.html<p><strong>What does LinkPeek mean?</strong></p>
<p>LinkPeek is the combination of the work "link" and "peek".</p>
<p>Link is short for "hyperlink" a piece of text that may be clicked on to travel to another web page.
Peek is the act of sneaking a look at something.
Put them together you have LinkPeek.</p>
<p>Originally the usecase for LinkPeek was to be a Link previewing service.
Allow users to peek at a …</p><p><strong>What does LinkPeek mean?</strong></p>
<p>LinkPeek is the combination of the work "link" and "peek".</p>
<p>Link is short for "hyperlink" a piece of text that may be clicked on to travel to another web page.
Peek is the act of sneaking a look at something.
Put them together you have LinkPeek.</p>
<p>Originally the usecase for LinkPeek was to be a Link previewing service.
Allow users to peek at a link without traveling to it.</p>
<p>Since then LinkPeek's functionality has increased but the name stays the same.</p>
How to add a custom Jinja filter to Pelican2014-02-19T15:16:00+01:002014-02-19T15:16:00+01:00Russelltag:linkpeek.com,2014-02-19:/blog/how-to-add-a-custom-jinja-filter-to-pelican.html<p>So you use Pelican static site generator and you want to add a custom Jinja filter for use in your templates? Great!</p>
<p>In this post I show how to take a simple Python function and make it accessable as a custom filter. As an example we will create a filter called LinkPeek which will allow us to easily embed website screenshots into our pages.</p>
<p>First, we need to …</p><p>So you use Pelican static site generator and you want to add a custom Jinja filter for use in your templates? Great!</p>
<p>In this post I show how to take a simple Python function and make it accessable as a custom filter. As an example we will create a filter called LinkPeek which will allow us to easily embed website screenshots into our pages.</p>
<p>First, we need to choose a function to become the filter, in this case we will download <a class="reference external" href="https://bitbucket.org/russellballestrini/liblinkpeek/src/tip/python/liblinkpeek.py">liblinkpeek.py</a> which has a function called <cite>api_v1</cite>:</p>
<blockquote>
<div class="highlight"><pre><span></span><span class="ch">#!/usr/bin/python</span>
<span class="kn">from</span> <span class="nn">hashlib</span> <span class="kn">import</span> <span class="n">md5</span>
<span class="kn">from</span> <span class="nn">urllib</span> <span class="kn">import</span> <span class="n">quote</span>
<span class="c1"># signup for an APIKEY here: https://linkpeek.com/signup</span>
<span class="n">APIKEY</span> <span class="o">=</span> <span class="s1">''</span>
<span class="n">SECRET</span> <span class="o">=</span> <span class="s1">''</span>
<span class="k">def</span> <span class="nf">api_v1</span><span class="p">(</span> <span class="n">uri</span><span class="p">,</span> <span class="n">apikey</span><span class="o">=</span><span class="n">APIKEY</span><span class="p">,</span> <span class="n">secret</span><span class="o">=</span><span class="n">SECRET</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="s1">'336'</span> <span class="p">):</span>
<span class="sd">"""LinkPeek.com API v1 helper function"""</span>
<span class="n">token</span> <span class="o">=</span> <span class="n">md5</span><span class="p">(</span> <span class="n">secret</span> <span class="o">+</span> <span class="n">uri</span> <span class="o">+</span> <span class="n">size</span> <span class="p">)</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
<span class="n">uri</span> <span class="o">=</span> <span class="n">quote</span><span class="p">(</span> <span class="n">uri</span> <span class="p">)</span>
<span class="k">return</span> <span class="s2">"https://linkpeek.com/api/v1?uri=</span><span class="si">%s</span><span class="s2">&apikey=</span><span class="si">%s</span><span class="s2">&token=</span><span class="si">%s</span><span class="s2">&size=</span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span>
<span class="n">uri</span><span class="p">,</span> <span class="n">apikey</span><span class="p">,</span> <span class="n">token</span><span class="p">,</span> <span class="n">size</span><span class="p">)</span>
</pre></div>
</blockquote>
<p>Next, we hook or register this function to Pelican as a Jinja filter.
We do this in the <cite>pelicanconf.py</cite> file, and it looks like this:</p>
<blockquote>
<div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">sys</span>
<span class="n">sys</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">liblinkpeek</span>
<span class="n">JINJA_FILTERS</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'linkpeek'</span><span class="p">:</span><span class="n">liblinkpeek</span><span class="o">.</span><span class="n">api_v1</span><span class="p">}</span>
</pre></div>
</blockquote>
<p>Last, we use the new filter in our template, for example:</p>
<blockquote>
<div class="highlight"><pre><span></span><span class="p"><</span><span class="nt">img</span> <span class="na">src</span><span class="o">=</span><span class="s">"{{russell.ballestrini.net|linkpeek(size='500')}}"</span> <span class="p">/></span>
</pre></div>
<p>In this example we create an <cite>img</cite> tag and set the <cite>src</cite> to the return value from our <cite>linkpeek</cite> filter. We pass two arguments, <cite>russell.ballestrini.net</cite> (the target URI) and <cite>size</cite> (the size of the image). The end result is a pixel perfect screenshot image of <cite>russell.ballestrini.net</cite> embeded into our page which will automatically stay fresh and up-to-date.</p>
</blockquote>
<p>You might have noticed that the first argument (the target uri) is piped into the filter and then subsequint arguments are supplied like normal. This Jinja oddity also caught me off guard from conventional Python programming.</p>
We added Google web font support2013-12-06T16:35:00+01:002013-12-06T16:35:00+01:00Russelltag:linkpeek.com,2013-12-06:/blog/we-added-google-web-font-support.html<p><strong>The LinkPeek snapshot workers now have support for Google Web Fonts!</strong></p>
<p>We solved this issue by installing the fonts locally on each snapshot worker. As a way of giving back to the community, we have decided to share our font install proceedure.</p>
<p><strong>How to install Google web fonts to a Linux localhost</strong></p>
<ol class="arabic">
<li><p class="first">create a directory for google fonts</p>
<div class="highlight"><pre><span></span>mkdir -p /usr/share/fonts/truetype/google-fonts/
</pre></div>
</li>
<li><p class="first">install mercurial hg …</p></li></ol><p><strong>The LinkPeek snapshot workers now have support for Google Web Fonts!</strong></p>
<p>We solved this issue by installing the fonts locally on each snapshot worker. As a way of giving back to the community, we have decided to share our font install proceedure.</p>
<p><strong>How to install Google web fonts to a Linux localhost</strong></p>
<ol class="arabic">
<li><p class="first">create a directory for google fonts</p>
<div class="highlight"><pre><span></span>mkdir -p /usr/share/fonts/truetype/google-fonts/
</pre></div>
</li>
<li><p class="first">install mercurial hg</p>
<div class="highlight"><pre><span></span><span class="c1"># ubuntu or debian</span>
sudo apt-get install -y mercurial
<span class="c1"># fedora or redhat or centos</span>
sudo yum install -y mercurial
</pre></div>
</li>
<li><p class="first">clone the hg font repo (this could take a while)</p>
<div class="highlight"><pre><span></span>hg clone https://googlefontdirectory.googlecode.com/hg/ googlefontdirectory<span class="p">;</span>
</pre></div>
</li>
<li><p class="first">install fonts: find fonts, copy to the new directory, fix mode</p>
<div class="highlight"><pre><span></span><span class="nb">cd</span> googlefontdirectory
find . -name <span class="s1">'*.ttf'</span> -exec sudo cp <span class="o">{}</span> /usr/share/fonts/truetype/google-fonts/ <span class="se">\;</span>
sudo chmod -R <span class="m">644</span> /usr/share/fonts/truetype/google-fonts/
</pre></div>
</li>
</ol>
<p>Now local applications like Libre Office and Gimp should have access to web fonts!</p>
Peeker the LinkPeek Mascot2013-12-03T21:17:00+01:002013-12-03T21:17:00+01:00Russelltag:linkpeek.com,2013-12-03:/blog/peeker-the-linkpeek-mascot.html<p>On Thanksgiving I learned how to use Inkscape to create vector graphics and I produced an icon-logo-mascot for LinkPeek. I'm proud to introduce Peeker!</p>
<p>Here is the <a class="reference external" href="/m/img/peeker-linkpeek.svg">SVG version of Peeker</a> which may be further manipulated in Inkscape.</p>
<blockquote>
<img alt="peeker the linkpeek icon logo mascot" src="/m/img/peeker-linkpeek.png" />
</blockquote>
<p>On Thanksgiving I learned how to use Inkscape to create vector graphics and I produced an icon-logo-mascot for LinkPeek. I'm proud to introduce Peeker!</p>
<p>Here is the <a class="reference external" href="/m/img/peeker-linkpeek.svg">SVG version of Peeker</a> which may be further manipulated in Inkscape.</p>
<blockquote>
<img alt="peeker the linkpeek icon logo mascot" src="/m/img/peeker-linkpeek.png" />
</blockquote>
Viewport gives you more control of website screenshots2013-09-11T23:51:00+02:002013-09-11T23:51:00+02:00Russelltag:linkpeek.com,2013-09-11:/blog/viewport-gives-you-more-control-of-website-screenshots.html<p>We have implemented <em>viewport</em> a new request parameter.</p>
<p><em>Viewport</em> allows you to:</p>
<ul class="simple">
<li>snapshot responsive designs</li>
<li>take wide panorama website screenshots</li>
<li>emulate mobile screen sizes</li>
</ul>
<p><strong>Before viewport:</strong></p>
<blockquote>
<img alt="after viewport=400" src="/api/v1?uri=http%3A//getbootstrap.com/getting-started/&apikey=9fhvyH9KP&token=e47e1c9ab1bd505b77661ec4270765a6&size=400x240" />
</blockquote>
<p><strong>After viewport=400:</strong></p>
<blockquote>
<img alt="after viewport=400" src="/api/v1?uri=http%3A//getbootstrap.com/getting-started/&apikey=9fhvyH9KP&token=e47e1c9ab1bd505b77661ec4270765a6&size=400x240&viewport=400" />
</blockquote>
<p>For complete documentation visit <a class="reference external" href="/docs/request-options">website screenshot request options</a></p>
<p>We have implemented <em>viewport</em> a new request parameter.</p>
<p><em>Viewport</em> allows you to:</p>
<ul class="simple">
<li>snapshot responsive designs</li>
<li>take wide panorama website screenshots</li>
<li>emulate mobile screen sizes</li>
</ul>
<p><strong>Before viewport:</strong></p>
<blockquote>
<img alt="after viewport=400" src="/api/v1?uri=http%3A//getbootstrap.com/getting-started/&apikey=9fhvyH9KP&token=e47e1c9ab1bd505b77661ec4270765a6&size=400x240" />
</blockquote>
<p><strong>After viewport=400:</strong></p>
<blockquote>
<img alt="after viewport=400" src="/api/v1?uri=http%3A//getbootstrap.com/getting-started/&apikey=9fhvyH9KP&token=e47e1c9ab1bd505b77661ec4270765a6&size=400x240&viewport=400" />
</blockquote>
<p>For complete documentation visit <a class="reference external" href="/docs/request-options">website screenshot request options</a></p>
Firework Project Screenshot every two-letter Domain2013-08-05T09:42:00+02:002013-08-05T09:42:00+02:00Russelltag:linkpeek.com,2013-08-05:/blog/firework-project-screenshot-every-two-letter-domain.html<p>This post will discuss planning and engineering involved in taking a <a class="reference external" href="website-screenshot-of-every-two-letter-domain.html">Website Screenshot of every two-letter Domain</a>. In addition I will share some analytics regarding the traffic Hacker News sent my way.</p>
<p><strong>The original idea</strong></p>
<p>I originally had this idea "Dec 5, 2012 at 10:23 pm" according to my Trello board. I had a number of tasks and hurdles to solve before I was ready to tackle …</p><p>This post will discuss planning and engineering involved in taking a <a class="reference external" href="website-screenshot-of-every-two-letter-domain.html">Website Screenshot of every two-letter Domain</a>. In addition I will share some analytics regarding the traffic Hacker News sent my way.</p>
<p><strong>The original idea</strong></p>
<p>I originally had this idea "Dec 5, 2012 at 10:23 pm" according to my Trello board. I had a number of tasks and hurdles to solve before I was ready to tackle the idea.</p>
<p><strong>Tasks and hurdles</strong></p>
<ol class="arabic">
<li><p class="first"><em>First</em>, I didn't even have a real blog system. I was adding blog divs to a static mako template. I switched over to using <a class="reference external" href="linkpeeks-blog-was-migrated-to-pelican-static-site-generator.html">Pelican static site generator</a> "January 06, 2013 11:54 AM" according to the blog post.</p>
</li>
<li><p class="first"><em>Next</em>, I needed a way to request screenshot images just-in-time otherwise the bandwidth usage and the LinkPeek website screenshot service would have been at capacity after only a few page views. For that I developed <a class="reference external" href="images-on-hover-lib.html">hover-lib</a> which is a small css/javascript library which handles most of the heavy lifting. If you need just-in-time on-hover images, check out hover-lib.</p>
</li>
<li><p class="first"><em>Finally</em>, I needed to write the page. For that I used the following jinja2 template and custom LinkPeek filter (which is just the python function found here - <a class="reference external" href="/docs/snapshot-website-screenshots-with-python">liblinkpeek.py</a>):</p>
<blockquote>
<div class="highlight"><pre><span></span><span class="cp">{%</span> <span class="k">set</span> <span class="nv">pool</span> <span class="o">=</span> <span class="s1">'abcdefghijklmnopqrstuvwxyz1234567890'</span> <span class="cp">%}</span><span class="x"></span>
<span class="cp">{%</span> <span class="k">for</span> <span class="nv">drip</span> <span class="k">in</span> <span class="nv">pool</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> <h3></span><span class="cp">{{</span> <span class="nv">drip</span> <span class="cp">}}</span><span class="x"></h3></span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">for</span> <span class="nv">drop</span> <span class="k">in</span> <span class="nv">pool</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">set</span> <span class="nv">target</span> <span class="o">=</span> <span class="nv">drip</span><span class="o">+</span><span class="nv">drop</span><span class="o">+</span><span class="s1">'.com'</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> <a href="http://</span><span class="cp">{{</span> <span class="nv">target</span> <span class="cp">}}</span><span class="x">" class="hover-lib"</span>
<span class="x"> id="</span><span class="cp">{{</span><span class="nv">target</span><span class="o">|</span><span class="nf">linkpeek</span><span class="o">(</span><span class="nv">size</span><span class="o">=</span><span class="s1">'500'</span><span class="o">)</span><span class="cp">}}</span><span class="x">" target="_blank"</span>
<span class="x"> rel="nofollow"></span><span class="cp">{{</span><span class="nv">target</span><span class="cp">}}</span><span class="x"></a></span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> <br /></span>
<span class="x"> <br /></span>
<span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span><span class="x"></span>
</pre></div>
<p>Above we loop over a pool of letters and numbers, create an h3 header for each section, create a link for every domain, set the link class to hover-lib, and set the link ID to the api call (which hover-lib uses for on-hover images).</p>
</blockquote>
</li>
</ol>
<p><strong>Analytics</strong></p>
<ul class="simple">
<li>The page reached position #5 on Hacker News</li>
<li>Max concurrent and active users was 274</li>
<li>Average concurrent and active users was 181</li>
<li>Sunday had 7,432 unique visits</li>
<li>Monday had 4,038 unique visits</li>
<li>We served over 182,025 website screenshot images during the two days</li>
<li>No sign ups! (appearently my target market is not Hacker News)</li>
</ul>
<p><strong>Graphs</strong></p>
<p>CPU usage -</p>
<blockquote>
<img alt="website-screenshot-every-domain-cpu" class="align-center" src="static/images/website-screenshot-every-domain-cpu.png" />
</blockquote>
<p>Network usage -</p>
<blockquote>
<img alt="website-screenshot-every-domain-network" class="align-center" src="static/images/website-screenshot-every-domain-network.png" />
</blockquote>
<p>IO usage -</p>
<blockquote>
<img alt="website-screenshot-every-domain-io" class="align-center" src="static/images/website-screenshot-every-domain-io.png" />
</blockquote>
<p><strong>Miscellaneous Thoughts</strong></p>
<ol class="arabic simple">
<li>People reminded me that I only covered the .com TLD. Perhaps I will follow up on other TLDs at some point (the code only needs a few changes).</li>
<li>This idea was both driven as a learning experience and as a way to get LinkPeek's name out to the world. I think it was successful.</li>
<li>In the next few days the traffic to the page will converge to zero. This type of hype or linkbait project is like a firework display. It takes lots of planning and engineering to setup and in a moments time it becomes consumed and forgotten.</li>
<li>I need to start coming up with ideas that are not "firework displays" so that the energy I put into the project continues for years.</li>
</ol>
Images on hover-lib2013-07-20T15:25:00+02:002013-07-20T15:25:00+02:00Russelltag:linkpeek.com,2013-07-20:/blog/images-on-hover-lib.html<p>We built hover-lib at LinkPeek because we needed a way to add on-hover images to select links. Images are loaded just-in-time to reduce bandwidth usage.</p>
<p><em>Update</em>: We wrote a really neat example of what hover-lib does: <a class="reference external" href="/blog/website-screenshot-of-every-two-letter-domain.html">Website Screenshot of every two-letter domain</a></p>
<p>The hover-lib library may be downloaded here: <a class="reference external" href="https://bitbucket.org/russellballestrini/hover-lib/get/tip.zip">hover-lib</a>.</p>
<p><strong>How to use hover-lib</strong></p>
<p>include hover-lib.css in the head:</p>
<div class="highlight"><pre><span></span><span class="p"><</span><span class="nt">head</span><span class="p">></span>
<span class="c"><!-- include the hover-lib stylesheet --></span>
<span class="p"><</span><span class="nt">link</span> <span class="na">rel</span><span class="o">=</span><span class="s">"stylesheet …</span></pre></div><p>We built hover-lib at LinkPeek because we needed a way to add on-hover images to select links. Images are loaded just-in-time to reduce bandwidth usage.</p>
<p><em>Update</em>: We wrote a really neat example of what hover-lib does: <a class="reference external" href="/blog/website-screenshot-of-every-two-letter-domain.html">Website Screenshot of every two-letter domain</a></p>
<p>The hover-lib library may be downloaded here: <a class="reference external" href="https://bitbucket.org/russellballestrini/hover-lib/get/tip.zip">hover-lib</a>.</p>
<p><strong>How to use hover-lib</strong></p>
<p>include hover-lib.css in the head:</p>
<div class="highlight"><pre><span></span><span class="p"><</span><span class="nt">head</span><span class="p">></span>
<span class="c"><!-- include the hover-lib stylesheet --></span>
<span class="p"><</span><span class="nt">link</span> <span class="na">rel</span><span class="o">=</span><span class="s">"stylesheet"</span> <span class="na">href</span><span class="o">=</span><span class="s">"hover-lib.css"</span><span class="p">></span>
<span class="p"></</span><span class="nt">head</span><span class="p">></span>
</pre></div>
<p>include jquery.js and hover-lib.js after the body:</p>
<div class="highlight"><pre><span></span><span class="p"></</span><span class="nt">body</span><span class="p">></span>
<span class="c"><!-- after the closing body tag import jquery.js --></span>
<span class="p"><</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">"text/javascript"</span> <span class="na">src</span><span class="o">=</span><span class="s">"jquery.js"</span><span class="p">></</span><span class="nt">script</span><span class="p">></span>
<span class="c"><!-- after the closing body tag import hover-lib.js --></span>
<span class="p"><</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">"text/javascript"</span> <span class="na">src</span><span class="o">=</span><span class="s">"hover-lib.js"</span><span class="p">></</span><span class="nt">script</span><span class="p">></span>
</pre></div>
<p>and now you are ready to use hover-lib on your links!</p>
<div class="highlight"><pre><span></span><span class="p"><</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"https://www.google.com/"</span> <span class="na">class</span><span class="o">=</span><span class="s">"hover-lib"</span> <span class="na">id</span><span class="o">=</span><span class="s">"https://www.google.com/images/srpr/logo4w.png"</span><span class="p">></span>hover this link!<span class="p"></</span><span class="nt">a</span><span class="p">></span>
</pre></div>
<dl class="docutils">
<dt><strong>class="hover-lib"</strong></dt>
<dd>causes the link to become a hover-lib link.</dd>
<dt><strong>id="/location/of/the/hover-image.png"</strong></dt>
<dd>is the src URI location of the image which you want to appear on-hover</dd>
</dl>
<p>There is a complete example in the download listed above.</p>
The whole LinkPeek site had a make-over2013-07-20T14:10:00+02:002013-07-20T14:10:00+02:00Russelltag:linkpeek.com,2013-07-20:/blog/the-whole-linkpeek-site-had-a-make-over.html<p>We have finished moving the rest of the LinkPeek site to the new theme.</p>
<p>The new theme does not appear to have altered the conversion frequency of
new customers. I would have thought a more professional looking site would
cause the conversions frequency to increase.</p>
<p>We have finished moving the rest of the LinkPeek site to the new theme.</p>
<p>The new theme does not appear to have altered the conversion frequency of
new customers. I would have thought a more professional looking site would
cause the conversions frequency to increase.</p>
We have a new look2013-03-10T22:34:00+01:002013-03-10T22:34:00+01:00Russelltag:linkpeek.com,2013-03-10:/blog/we-have-a-new-look.html<p>Yay, we are sporting a new look! We finally got around to creating a custom theme and web design for LinkPeek.</p>
<p>The first area of the site to switch over is this blog. The other sections should move over in the next week.</p>
<p>Man this is pretty great looking!</p>
<p>: )</p>
<p>Yay, we are sporting a new look! We finally got around to creating a custom theme and web design for LinkPeek.</p>
<p>The first area of the site to switch over is this blog. The other sections should move over in the next week.</p>
<p>Man this is pretty great looking!</p>
<p>: )</p>
How to batch convert xcf to png2013-03-02T20:23:33+01:002013-03-02T20:23:33+01:00Russelltag:linkpeek.com,2013-03-02:/blog/how-to-batch-convert-xcf-to-png.html<p>My favorite image manipulator program is GIMP and I often find myself with a directory full of xcf (gimp project files) that I would like to convert into PNGs for use on the web or in a video game. I like to keep my "master" copy of image assets in xcf format to preserve layer and history meta-data.</p>
<div class="line-block">
<div class="line"><br /></div>
</div>
<p>Today I was experimenting with an idea called sketch notes …</p><p>My favorite image manipulator program is GIMP and I often find myself with a directory full of xcf (gimp project files) that I would like to convert into PNGs for use on the web or in a video game. I like to keep my "master" copy of image assets in xcf format to preserve layer and history meta-data.</p>
<div class="line-block">
<div class="line"><br /></div>
</div>
<p>Today I was experimenting with an idea called sketch notes on some of my personal blog posts. I ended up with several xcf files which I needed to to export to png for use on the blog.</p>
<div class="line-block">
<div class="line"><br /></div>
</div>
<p>Opening each project individually to perform an export felt tedious and time consuming. There had to be a better way, so I started a search!</p>
<div class="line-block">
<div class="line"><br /></div>
</div>
<p>Duckduckgo linked me to xcf2png, which is a perfect match.</p>
<div class="line-block">
<div class="line"><br /></div>
</div>
<p><strong>This is how I installed xcf2png:</strong></p>
<blockquote>
<div class="highlight"><pre><span></span>sudo yum install xcftools
</pre></div>
</blockquote>
<div class="line-block">
<div class="line"><br /></div>
</div>
<p><strong>This is the one-line bash program I wrote to batch convert xcf to png</strong>:</p>
<blockquote>
<div class="highlight"><pre><span></span><span class="k">for</span> file in *.xcf<span class="p">;</span> <span class="k">do</span> xcf2png <span class="s2">"</span><span class="nv">$file</span><span class="s2">"</span> > <span class="s2">"</span><span class="nv">$file</span><span class="s2">.png"</span> <span class="p">;</span> <span class="k">done</span>
</pre></div>
</blockquote>
<p>Tada! like magic I now had both the original xcf and a new png of each image!</p>
<div class="line-block">
<div class="line"><br /></div>
</div>
<p><strong>Oh I made a practice sketch note for this post too! : )</strong></p>
<img alt="infographic of batch converting xcf to png files" class="align-center" src="/blog/static/images/2013-03-02-batch-convert-xcf-2-png-scaled.png" />
LinkPeek website screenshot teams up with The Easy API2013-02-09T13:34:19+01:002013-02-09T13:34:19+01:00Russelltag:linkpeek.com,2013-02-09:/blog/linkpeek-website-screenshot-teams-up-with-the-easy-api.html<p>LinkPeek website screenshot service has teamed up with The Easy API to improve user experience and value for our members.</p>
<p><strong>What is The Easy API?</strong></p>
<p>The Easy API is a centralized service which reduces multiple API endpoints down to one standardized endpoint. This means you can access LinkPeek webpage screenshots and many other APIs from one place.</p>
<p><strong>Meet Jeff</strong></p>
<p>Jeff operates an awesome SEO company but needs to …</p><p>LinkPeek website screenshot service has teamed up with The Easy API to improve user experience and value for our members.</p>
<p><strong>What is The Easy API?</strong></p>
<p>The Easy API is a centralized service which reduces multiple API endpoints down to one standardized endpoint. This means you can access LinkPeek webpage screenshots and many other APIs from one place.</p>
<p><strong>Meet Jeff</strong></p>
<p>Jeff operates an awesome SEO company but needs to obtain website snapshots, Google PR, and SEOMoz domainAuthority all on the same page. Jeff doesn't want to deal with three different API providers so he chooses to use <a class="reference external" href="http://theeasyapi.com/docs/services/linkpeek">The Easy API to get his PR and snapshots</a>. Jeff is happy because he wrote less code, and his code was reusable. That is the power of The Easy API!</p>
<img alt="Web page screenshot of TheEasyAPI" src="/api/v1?uri=http%3A//theeasyapi.com/docs/services/linkpeek/summary&apikey=9fhvyH9KP&token=62783acaa62278544080d8080ccc465a&size=720x280" />
Display image on hover using HTML, Javascript and CSS2013-01-26T13:22:55+01:002013-01-26T13:22:55+01:00Russelltag:linkpeek.com,2013-01-26:/blog/display-image-on-hover-using-html-javascript-and-css.html<p>This post explains how to build a link which will display an image when a user hovers over their mouse. This technique could be used to create help balloons or link previews.</p>
<p><strong>OK, lets build the special link one step at a time.</strong></p>
<ol class="arabic">
<li><p class="first">Create a link:</p>
<div class="highlight"><pre><span></span><span class="p"><</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"https://linkpeek.com"</span><span class="p">></span>website screenshot service<span class="p"></</span><span class="nt">a</span><span class="p">></span>
</pre></div>
</li>
<li><p class="first">Add a place holder image like this <a class="reference external" href="/theme/img/linkpeek-transparent-pixel-placeholder.png">transparent 1x1 pixel png</a>. Notice that …</p></li></ol><p>This post explains how to build a link which will display an image when a user hovers over their mouse. This technique could be used to create help balloons or link previews.</p>
<p><strong>OK, lets build the special link one step at a time.</strong></p>
<ol class="arabic">
<li><p class="first">Create a link:</p>
<div class="highlight"><pre><span></span><span class="p"><</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"https://linkpeek.com"</span><span class="p">></span>website screenshot service<span class="p"></</span><span class="nt">a</span><span class="p">></span>
</pre></div>
</li>
<li><p class="first">Add a place holder image like this <a class="reference external" href="/theme/img/linkpeek-transparent-pixel-placeholder.png">transparent 1x1 pixel png</a>. Notice that we give the place holder img an id and set some style attributes.:</p>
<div class="highlight"><pre><span></span><span class="p"><</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"https://linkpeek.com"</span><span class="p">></span>
website screenshot service
<span class="p"><</span><span class="nt">img</span> <span class="na">src</span><span class="o">=</span><span class="s">"/theme/img/linkpeek-transparent-pixel-placeholder.png"</span> <span class="na">id</span><span class="o">=</span><span class="s">"place-holder-1"</span> <span class="na">style</span><span class="o">=</span><span class="s">"zindex: 100; position: absolute;"</span> <span class="p">/></span>
<span class="p"></</span><span class="nt">a</span><span class="p">></span>
</pre></div>
</li>
<li><p class="first">Add Javascript to change the place holder image <em>onmouseover</em>:</p>
<div class="highlight"><pre><span></span><span class="nx">onmouseover</span><span class="o">=</span><span class="s2">"document.getElementById('place-holder-1').src='https://linkpeek.com/api/v1?uri=http%3A//linkpeek.com&apikey=9fhvyH9KP&token=ada234417193f502523a7d1da2ef1501&size=336x336';"</span>
</pre></div>
</li>
<li><p class="first">Add Javascript to change back to the place holder image <em>onmouseout</em>:</p>
<div class="highlight"><pre><span></span><span class="nx">onmouseout</span><span class="o">=</span><span class="s2">"document.getElementById('place-holder-1').src='/theme/img/linkpeek-transparent-pixel-placeholder.png';"</span>
</pre></div>
</li>
<li><p class="first">Lets put it all together:</p>
<div class="highlight"><pre><span></span><span class="p"><</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"https://linkpeek.com"</span>
<span class="na">onmouseover</span><span class="o">=</span><span class="s">"document.getElementById('place-holder-1').src='https://linkpeek.com/api/v1?uri=http%3A//linkpeek.com&apikey=9fhvyH9KP&token=ada234417193f502523a7d1da2ef1501&size=336x336';"</span>
<span class="na">onmouseout</span><span class="o">=</span><span class="s">"document.getElementById('place-holder-1').src='/theme/img/linkpeek-transparent-pixel-placeholder.png';"</span>
<span class="p">></span>
website screenshot service
<span class="p"><</span><span class="nt">img</span> <span class="na">src</span><span class="o">=</span><span class="s">"/theme/img/linkpeek-transparent-pixel-placeholder.png"</span> <span class="na">id</span><span class="o">=</span><span class="s">"place-holder-1"</span> <span class="na">style</span><span class="o">=</span><span class="s">"zindex: 100; position: absolute;"</span> <span class="p">/></span>
<span class="p"></</span><span class="nt">a</span><span class="p">></span>
</pre></div>
</li>
</ol>
<p><strong>And finally our result:</strong></p>
<a href="/"
onmouseover="document.getElementById('place-holder-1').src='https://linkpeek.com/api/v1?uri=http%3A//linkpeek.com&apikey=9fhvyH9KP&token=ada234417193f502523a7d1da2ef1501&size=336x336';"
onmouseout="document.getElementById('place-holder-1').src='/theme/img/linkpeek-transparent-pixel-placeholder.png';"
>
website screenshot service
<img src="/theme/img/linkpeek-transparent-pixel-placeholder.png" id="place-holder-1" style="zindex: 100; position: absolute;" />
</a><div class="line-block">
<div class="line"><br /></div>
</div>
<p><em>Pretty neat huh?</em></p>
<p><strong>How to make this method better?:</strong></p>
<ul class="simple">
<li>make the hover effect look better with more css styling</li>
<li>move all styles into a reusable class</li>
<li>move all classes into a reusable CSS stylesheet</li>
<li>move the <em>onmouseover</em> and <em>onmouseout</em> toggle into a reuseable Javascript function</li>
<li>move all Javascript into a reusable file</li>
<li>wrap everything up into a downloadable library project</li>
</ul>
<div class="line-block">
<div class="line"><br /></div>
</div>
<p><strong>Update:</strong> We did a follow-up post <a class="reference external" href="/blog/images-on-hover-lib.html">images on hover-lib</a> to cover the ideas listed above.</p>
filevault will manage a tree of directories and files2013-01-14T22:43:38+01:002013-01-14T22:43:38+01:00Russelltag:linkpeek.com,2013-01-14:/blog/filevault-will-manage-a-tree-of-directories-and-files.html<p>We are please to release <a class="reference external" href="http://pypi.python.org/pypi/filevault">filevault</a> into the public domain. This module allows programmers to easily create and maintain large and complex directory trees. The LinkPeek API uses this module heavily!</p>
<p>The latest documentation and verison live here: <a class="reference external" href="https://bitbucket.org/russellballestrini/filevault">[sourcecode]</a></p>
<p>A Vault will:</p>
<ul class="simple">
<li>Create a directory tree of custom depth</li>
<li>Spreads files out which keeps CLI snappy when traversing the tree</li>
<li>Scale to hundreds of thousands of files</li>
<li>Obfuscate …</li></ul><p>We are please to release <a class="reference external" href="http://pypi.python.org/pypi/filevault">filevault</a> into the public domain. This module allows programmers to easily create and maintain large and complex directory trees. The LinkPeek API uses this module heavily!</p>
<p>The latest documentation and verison live here: <a class="reference external" href="https://bitbucket.org/russellballestrini/filevault">[sourcecode]</a></p>
<p>A Vault will:</p>
<ul class="simple">
<li>Create a directory tree of custom depth</li>
<li>Spreads files out which keeps CLI snappy when traversing the tree</li>
<li>Scale to hundreds of thousands of files</li>
<li>Obfuscate directory paths and filenames</li>
</ul>
<div class="section" id="how-to-install">
<h2>how to install</h2>
<p>Setuptools:</p>
<pre class="literal-block">
easy_install filevault
</pre>
<p>Pip:</p>
<pre class="literal-block">
pip install filevault
</pre>
</div>
<div class="section" id="how-to-use">
<h2>how to use</h2>
<p>How to create a default Vault object:</p>
<div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">filevault</span> <span class="kn">import</span> <span class="n">Vault</span>
<span class="n">v</span> <span class="o">=</span> <span class="n">Vault</span><span class="p">()</span>
</pre></div>
<p>You may (and should) customize the Vault instance. Here are the arguments:</p>
<dl class="docutils">
<dt>vaultpath</dt>
<dd>Where should the tree be created? Defaults to 'vault' in pwd.</dd>
<dt>depth</dt>
<dd>How deep should the tree span? Defaults to 3 directories deep.</dd>
<dt>salt</dt>
<dd>Add a custom salt for a unique and more secure tree, defaults to 'changeme'</dd>
</dl>
<p>Another custom example:</p>
<div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">filevault</span> <span class="kn">import</span> <span class="n">Vault</span>
<span class="n">v</span> <span class="o">=</span> <span class="n">Vault</span><span class="p">(</span> <span class="n">vaultpath</span><span class="o">=</span><span class="s2">"/tmp/for-test"</span><span class="p">,</span> <span class="n">depth</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">salt</span><span class="o">=</span><span class="s2">"sugar"</span> <span class="p">)</span>
</pre></div>
<p>Now that we have a Vault object named v, we may review its two methods:</p>
<dl class="docutils">
<dt>create_filename( seed, ext='' )</dt>
<dd>Create a valid vault filename seeded with input. Optional extension.</dd>
<dt>create_random_filename( ext='' )</dt>
<dd>Create a valid vault filename seeded with random input. Optional extension.</dd>
</dl>
<p>Here is a full example:</p>
<div class="highlight"><pre><span></span><span class="c1"># import Vault class</span>
<span class="kn">from</span> <span class="nn">filevault</span> <span class="kn">import</span> <span class="n">Vault</span>
<span class="c1"># create vault object named v, with custom path, depth, and salt</span>
<span class="n">v</span> <span class="o">=</span> <span class="n">Vault</span><span class="p">(</span> <span class="n">vaultpath</span><span class="o">=</span><span class="s2">"/tmp/for-test"</span><span class="p">,</span> <span class="n">depth</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">salt</span><span class="o">=</span><span class="s2">"sugar"</span> <span class="p">)</span>
<span class="c1"># print a valid vault filename with extension</span>
<span class="k">print</span> <span class="n">v</span><span class="o">.</span><span class="n">create_filename</span><span class="p">(</span> <span class="s2">"my-first-file"</span><span class="p">,</span> <span class="s2">".png"</span> <span class="p">)</span>
<span class="c1"># result:</span>
<span class="c1"># 3/9/3993817d4f9b3867c6db29b23c9d2ff9bb8a87d89426002adbb6ed34289d9e32.png</span>
<span class="k">print</span> <span class="n">v</span><span class="o">.</span><span class="n">create_filename</span><span class="p">(</span> <span class="s2">"my-first-file"</span><span class="p">,</span> <span class="s2">".png"</span> <span class="p">)</span>
<span class="c1"># Same result:</span>
<span class="c1"># 3/9/3993817d4f9b3867c6db29b23c9d2ff9bb8a87d89426002adbb6ed34289d9e32.png</span>
<span class="c1"># print a random valid vault filename without extension</span>
<span class="n">v</span><span class="o">.</span><span class="n">create_random_filename</span><span class="p">()</span>
<span class="c1"># result:</span>
<span class="c1"># 6/1/6169d6ee0ac0bc63ab667fb94d9cc747df0c03596ac43e24a51b3517d74bdc42</span>
</pre></div>
</div>
Pad zeros on Java BigInteger when making MD5 hash2013-01-13T22:07:38+01:002013-01-13T22:07:38+01:00Russelltag:linkpeek.com,2013-01-13:/blog/pad-zeros-on-java-biginteger-when-making-md5-hash.html<dl class="docutils">
<dt>Problem:</dt>
<dd>liblinkpeek.java was occasionally produced invalid security tokens.</dd>
<dt>Diagnosis:</dt>
<dd>Java's BigInteger strips leading zeros. This causes resulting MD5 hashes to be incorrect.</dd>
<dt>Solution:</dt>
<dd>Pad the security token (MD5 hash) with leading 0s until 32 characters in length.</dd>
</dl>
<div class="highlight"><pre><span></span><span class="k">while</span> <span class="o">(</span> <span class="n">token</span><span class="o">.</span><span class="na">length</span><span class="o">()</span> <span class="o"><</span> <span class="mi">32</span> <span class="o">)</span> <span class="o">{</span> <span class="n">token</span> <span class="o">=</span> <span class="s">"0"</span> <span class="o">+</span> <span class="n">token</span><span class="o">;</span> <span class="o">}</span> <span class="c1">// pad with 0's</span>
</pre></div>
<p>Special thanks goes out to Shazin Shafi Ahamed (<a class="reference external" href="https://bitbucket.org/shazinahmed">https://bitbucket.org/shazinahmed</a>) for reporting this bug and providing details …</p><dl class="docutils">
<dt>Problem:</dt>
<dd>liblinkpeek.java was occasionally produced invalid security tokens.</dd>
<dt>Diagnosis:</dt>
<dd>Java's BigInteger strips leading zeros. This causes resulting MD5 hashes to be incorrect.</dd>
<dt>Solution:</dt>
<dd>Pad the security token (MD5 hash) with leading 0s until 32 characters in length.</dd>
</dl>
<div class="highlight"><pre><span></span><span class="k">while</span> <span class="o">(</span> <span class="n">token</span><span class="o">.</span><span class="na">length</span><span class="o">()</span> <span class="o"><</span> <span class="mi">32</span> <span class="o">)</span> <span class="o">{</span> <span class="n">token</span> <span class="o">=</span> <span class="s">"0"</span> <span class="o">+</span> <span class="n">token</span><span class="o">;</span> <span class="o">}</span> <span class="c1">// pad with 0's</span>
</pre></div>
<p>Special thanks goes out to Shazin Shafi Ahamed (<a class="reference external" href="https://bitbucket.org/shazinahmed">https://bitbucket.org/shazinahmed</a>) for reporting this bug and providing details on a possible patch.</p>
<p>Patch: <a class="reference external" href="https://bitbucket.org/russellballestrini/liblinkpeek/commits/826c4b89c77d759a559411750c2e363d0dd081b9">https://bitbucket.org/russellballestrini/liblinkpeek/commits/826c4b89c77d759a559411750c2e363d0dd081b9</a></p>
LinkPeek's blog was migrated to pelican static site generator2013-01-06T11:54:00+01:002013-01-06T11:54:00+01:00Russelltag:linkpeek.com,2013-01-06:/blog/linkpeeks-blog-was-migrated-to-pelican-static-site-generator.html<p>We migrated the LinkPeek blog from static HTML to a <a class="reference external" href="http://docs.getpelican.com/">static HTML blog generated with pelican</a>. There are many static site generators and blogs frameworks to choose from. We decided to move our blog to pelican for the following reasons:</p>
<ul class="simple">
<li><dl class="first docutils">
<dt>To improve blog organization</dt>
<dd>We now have Categories, tags, and a blog roll. Our posts are now linked together intelligently.</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt>To improve efficiency</dt>
<dd>We can now quickly write …</dd></dl></li></ul><p>We migrated the LinkPeek blog from static HTML to a <a class="reference external" href="http://docs.getpelican.com/">static HTML blog generated with pelican</a>. There are many static site generators and blogs frameworks to choose from. We decided to move our blog to pelican for the following reasons:</p>
<ul class="simple">
<li><dl class="first docutils">
<dt>To improve blog organization</dt>
<dd>We now have Categories, tags, and a blog roll. Our posts are now linked together intelligently.</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt>To improve efficiency</dt>
<dd>We can now quickly write posts in ReSTructuredText which converts into HTML. The markup is also portable.</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt>To improve design</dt>
<dd>We had the ability to write a custom theme using jinja.</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt>To improve enjoyment</dt>
<dd>Pelican is more fun to use then writing static HTML by hand.</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt>To improve SEO</dt>
<dd>Each post now has a direct URI which promotes sharing.</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt>To improve blog speed and durability</dt>
<dd>Static HTML is now served directly by nginx instead of paster/cherrypy.</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt>To improve project organization</dt>
<dd>We placed the linkpeek blog into a separate repository to the rest of the linkpeek.com website. We still may use hg mercurial!</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt>To save developer resources</dt>
<dd>At first we wanted to code our own static site generator. This would have taken time away from developing our core product, linkpeek webpage to screenshot API. We choose pelican over the competition because we agreed with the projects software design choices, we thought the pelican-quickstart was a great way to setup a skeleton project, and the configuration required was minimal to get started.</dd>
</dl>
</li>
</ul>
<p><strong>Hopefully this change help create a habit of more frequent posting!</strong></p>
logmongo will log messages to a capped MongoDB collections2012-07-16T21:27:54+02:002012-07-16T21:27:54+02:00Russelltag:linkpeek.com,2012-07-16:/blog/logmongo-will-log-messages-to-a-capped-mongodb-collections.html<p>We are please to release <a class="reference external" href="http://pypi.python.org/pypi/logmongo/0.0.3">logmongo</a> into the public domain. This module allows programmers to easily log messages to a capped MongoDB collections. <a class="reference external" href="https://bitbucket.org/russellballestrini/logmongo">[sourcecode]</a></p>
<p>What does it do?</p>
<ul class="simple">
<li>Gracefully creates capped collections.</li>
<li>Auto expires oldest records first and solves log rotation.</li>
<li>Writes complex (dicts and kwargs) log records.</li>
<li>Logs asynchronously.</li>
<li>Collects logs locally or remotely or in a central location.</li>
<li>Allows access to logs via MongoDB queries and …</li></ul><p>We are please to release <a class="reference external" href="http://pypi.python.org/pypi/logmongo/0.0.3">logmongo</a> into the public domain. This module allows programmers to easily log messages to a capped MongoDB collections. <a class="reference external" href="https://bitbucket.org/russellballestrini/logmongo">[sourcecode]</a></p>
<p>What does it do?</p>
<ul class="simple">
<li>Gracefully creates capped collections.</li>
<li>Auto expires oldest records first and solves log rotation.</li>
<li>Writes complex (dicts and kwargs) log records.</li>
<li>Logs asynchronously.</li>
<li>Collects logs locally or remotely or in a central location.</li>
<li>Allows access to logs via MongoDB queries and APIs.</li>
</ul>
<div class="section" id="installation">
<h2>Installation</h2>
<p>Simply use easy_install or pip:</p>
<div class="highlight"><pre><span></span>easy_install logmongo
pip install logmongo
</pre></div>
</div>
<div class="section" id="why-should-i-use-logmongo-instead-of-just-pymongo">
<h2>Why should I use Logmongo instead of just pymongo?</h2>
<p>Logmongo subclasses the pymongo Collection object and
provides the following additions -</p>
<dl class="docutils">
<dt>A new Logmongo object will:</dt>
<dd><ul class="first last simple">
<li>gracefully create a named capped collection</li>
<li>allow a max size to be specified</li>
</ul>
</dd>
<dt>write method which:</dt>
<dd><ul class="first last simple">
<li>logs all passed keywords</li>
<li>adds current time to record</li>
<li>adds hostname to record</li>
</ul>
</dd>
<dt>query method which:</dt>
<dd><ul class="first last simple">
<li>allows keywords (kwargs) querying
example: log.query( tags='finance' )</li>
</ul>
</dd>
<dt>tail method which:</dt>
<dd><ul class="first last simple">
<li>prints all records that match query until killed</li>
</ul>
</dd>
</dl>
</div>
<div class="section" id="how-does-it-work">
<h2>How does it work?</h2>
<p>Example:</p>
<pre class="literal-block">
from logmongo import Logmongo
log = Logmongo()
log.write( message='No required kwargs or fields!' )
entry = {
'tags':['but','we','like','tags'],
'level':'info'
}
log.write( entry )
# for more help check out
help( logmongo )
</pre>
</div>
<div class="section" id="license">
<h2>License</h2>
<p>Public Domain</p>
</div>
<div class="section" id="how-do-i-thank-you">
<h2>How do I thank you?</h2>
<p>Write me an email! I always respond back!</p>
</div>
Coupon codes emailed2012-05-12T09:02:07+02:002012-05-12T09:02:07+02:00Russelltag:linkpeek.com,2012-05-12:/blog/coupon-codes-emailed.html<p>Today we sent coupon codes to anyone who signed up early. Forgot to signup and still want a coupon code? <a class="reference external" href="/contact">Tell us</a> what you will be using LinkPeek for, and we will reply back with a code.</p>
<p>Today we sent coupon codes to anyone who signed up early. Forgot to signup and still want a coupon code? <a class="reference external" href="/contact">Tell us</a> what you will be using LinkPeek for, and we will reply back with a code.</p>
Hit count bug2012-05-05T00:13:59+02:002012-05-05T00:13:59+02:00Russelltag:linkpeek.com,2012-05-05:/blog/hit-count-bug.html<p>Apparently we had a bug that only registered 1 hit for really quick API requests. The request counts appear atomic now.</p>
<p><em>No more freebies! ; )</em></p>
<p>Apparently we had a bug that only registered 1 hit for really quick API requests. The request counts appear atomic now.</p>
<p><em>No more freebies! ; )</em></p>
Dashboard update change card and plan2012-05-03T11:14:52+02:002012-05-03T11:14:52+02:00Russelltag:linkpeek.com,2012-05-03:/blog/dashboard-update-change-card-and-plan.html<p>Members now have the ability to change their credit card and plan.
Check out the new <a class="reference external" href="/dashboard">dashboard</a> today!</p>
<p>Members now have the ability to change their credit card and plan.
Check out the new <a class="reference external" href="/dashboard">dashboard</a> today!</p>
StartupGrind covered a story on LinkPeek2012-01-26T19:23:07+01:002012-01-26T19:23:07+01:00Russelltag:linkpeek.com,2012-01-26:/blog/startupgrind-covered-a-story-on-linkpeek.html<img alt="web page screenshot of LinkPeek post on StartupGrind" src="/api/v1?uri=http%3A//startupgrind.com/2012/01/linkpeek-api-takes-high-res-screenshots-so-you-never-forget-a-web&apikey=9fhvyH9KP&token=88b5af112b0e16ffeaccd1b07d1ccd8e&size=650x250&viewport=1280" />
<div class="line-block">
<div class="line"><br /></div>
</div>
<img alt="web page screenshot of LinkPeek post on StartupGrind" src="/api/v1?uri=http%3A//startupgrind.com/2012/01/linkpeek-api-takes-high-res-screenshots-so-you-never-forget-a-web&apikey=9fhvyH9KP&token=88b5af112b0e16ffeaccd1b07d1ccd8e&size=650x250&viewport=1280" />
<div class="line-block">
<div class="line"><br /></div>
</div>
We survived your beta testing2012-01-25T06:43:47+01:002012-01-25T06:43:47+01:00Russelltag:linkpeek.com,2012-01-25:/blog/we-survived-your-beta-testing.html<p>Beta is now over. Thank you for the support during the testing.</p>
<p>Beta is now over. Thank you for the support during the testing.</p>
LinkPeek Wordpress plugin released2012-01-18T02:07:32+01:002012-01-18T02:07:32+01:00Russelltag:linkpeek.com,2012-01-18:/blog/linkpeek-wordpress-plugin-released.html<p>We have just released the official <a class="reference external" href="http://wordpress.org/extend/plugins/linkpeek/">LinkPeek Wordpress plugin</a>. You might also be interested in a list of LinkPeek <a class="reference external" href="http://russell.ballestrini.net/linkpeek-wordpress-shortcodes/">Web Page Screenshot Wordpess shortcodes</a>.</p>
<p>We have just released the official <a class="reference external" href="http://wordpress.org/extend/plugins/linkpeek/">LinkPeek Wordpress plugin</a>. You might also be interested in a list of LinkPeek <a class="reference external" href="http://russell.ballestrini.net/linkpeek-wordpress-shortcodes/">Web Page Screenshot Wordpess shortcodes</a>.</p>
Added account helper pages2012-01-10T23:03:09+01:002012-01-10T23:03:09+01:00Russelltag:linkpeek.com,2012-01-10:/blog/added-account-helper-pages.html<p>I finally got around to building the forgot username, forgot password, and change password pages.
LinkPeek should be a bit more functional now.</p>
<p>I finally got around to building the forgot username, forgot password, and change password pages.
LinkPeek should be a bit more functional now.</p>
LinkPeek appears in rrrewind's 365 top stories on Hacker News | 20112011-12-26T09:51:13+01:002011-12-26T09:51:13+01:00Russelltag:linkpeek.com,2011-12-26:/blog/linkpeek-appears-in-rrrewinds-365-top-stories-on-hacker-news-2011.html<p>According to rrrewind.com, <a class="reference external" href="http://rrrewind.com/assets/yearly/2010hn.html">LinkPeek was the top story on HN on December 4th, 2011</a>.</p>
<p>According to rrrewind.com, <a class="reference external" href="http://rrrewind.com/assets/yearly/2010hn.html">LinkPeek was the top story on HN on December 4th, 2011</a>.</p>
Fetch snapshot images from LinkPeek using HTTPS2011-12-18T10:03:10+01:002011-12-18T10:03:10+01:00Russelltag:linkpeek.com,2011-12-18:/blog/fetch-snapshot-images-from-linkpeek-using-https.html<p>Linkpeek's <a class="reference external" href="/docs/request-options">webpage snapshot request options</a> now support fetching images securely over HTTPS / SSL.</p>
<p>Requesting secure website screenshot images from a secure site will prevent mixed content warnings.</p>
<p>Linkpeek's <a class="reference external" href="/docs/request-options">webpage snapshot request options</a> now support fetching images securely over HTTPS / SSL.</p>
<p>Requesting secure website screenshot images from a secure site will prevent mixed content warnings.</p>
Added HTTPS support2011-12-07T19:23:50+01:002011-12-07T19:23:50+01:00Russelltag:linkpeek.com,2011-12-07:/blog/added-https-support.html<p>We have added secure site (https) support to LinkPeek.
Special thanks to Charles Campbell, Sami, and Anthony for reporting the bug.</p>
<p>We have added secure site (https) support to LinkPeek.
Special thanks to Charles Campbell, Sami, and Anthony for reporting the bug.</p>
LinkPeek Apology2011-12-05T06:59:32+01:002011-12-05T06:59:32+01:00Russelltag:linkpeek.com,2011-12-05:/blog/linkpeek-apology.html<p>I am truly sorry for the grotesque and disgusting imagery posted on our site this morning. I left the "most recent" image on the website even though multiple people warned me about the possible misuse. I blame only myself.</p>
<p>I lost my lunch today. My nerves are all messed up. I have worked on the LinkPeek software for the past 6 months. The thought that LinkPeek was used …</p><p>I am truly sorry for the grotesque and disgusting imagery posted on our site this morning. I left the "most recent" image on the website even though multiple people warned me about the possible misuse. I blame only myself.</p>
<p>I lost my lunch today. My nerves are all messed up. I have worked on the LinkPeek software for the past 6 months. The thought that LinkPeek was used as a weapon against my peers makes me sick.</p>
<p>I feel exploited, I feel embarrassed, I feel ashamed and I have only myself to blame. This is a nightmare.</p>
LinkPeek was #1 story on hacker news2011-12-05T01:55:41+01:002011-12-05T01:55:41+01:00Russelltag:linkpeek.com,2011-12-05:/blog/linkpeek-was-1-story-on-hacker-news.html<p>LinkPeek.com became the top story on hacker news sunday night into monday morning! Thank you all for the support.</p>
<p>LinkPeek.com became the top story on hacker news sunday night into monday morning! Thank you all for the support.</p>
Free thumbnails until Christmas2011-12-03T00:00:00+01:002011-12-03T00:00:00+01:00Russelltag:linkpeek.com,2011-12-03:/blog/free-thumbnails-until-christmas.html<p>LinkPeek is offering 140x100 pixel thumbnails until Christmas 2011! Try the <a class="reference external" href="/website-thumbnail-generator">Website thumbnail generator</a> now!</p>
<dl class="docutils">
<dt>Update</dt>
<dd>Unlimited webpage thumbnails forever!</dd>
</dl>
<p>LinkPeek is offering 140x100 pixel thumbnails until Christmas 2011! Try the <a class="reference external" href="/website-thumbnail-generator">Website thumbnail generator</a> now!</p>
<dl class="docutils">
<dt>Update</dt>
<dd>Unlimited webpage thumbnails forever!</dd>
</dl>
LinkPeek listed on ProgrammableWeb2011-12-02T19:13:48+01:002011-12-02T19:13:48+01:00Russelltag:linkpeek.com,2011-12-02:/blog/linkpeek-listed-on-programmableweb.html<p>LinkPeek, webpage to image snapshot API, has joined forces with ProgrammableWeb directory!</p>
<p>LinkPeek, webpage to image snapshot API, has joined forces with ProgrammableWeb directory!</p>
Website Thumbnail Generator2011-11-30T20:55:47+01:002011-11-30T20:55:47+01:00Russelltag:linkpeek.com,2011-11-30:/blog/website-thumbnail-generator.html<p>The <a class="reference external" href="/website-thumbnail-generator">Website Thumbnail Generator</a> is the first application powered by LinkPeek.com. Generate a thumbnail image of your site now!</p>
<p>The <a class="reference external" href="/website-thumbnail-generator">Website Thumbnail Generator</a> is the first application powered by LinkPeek.com. Generate a thumbnail image of your site now!</p>
Website to image API released2011-11-22T18:55:47+01:002011-11-22T18:55:47+01:00Russelltag:linkpeek.com,2011-11-22:/blog/website-to-image-api-released.html<p>We are proud to present the <a class="reference external" href="/docs">Website to image API</a>. Embed self updating webpage snapshots on your site now, or we'll do it for you!</p>
<p>We are proud to present the <a class="reference external" href="/docs">Website to image API</a>. Embed self updating webpage snapshots on your site now, or we'll do it for you!</p>