<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>David Beath (Posts about RSS)</title><link>https://davidbeath.com/</link><description></description><atom:link href="https://davidbeath.com/categories/rss.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><lastBuildDate>Mon, 21 Feb 2022 17:09:57 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Feedsearch API Updates</title><link>https://davidbeath.com/posts/2019-feedsearch-api-updates/</link><dc:creator>David Beath</dc:creator><description>&lt;p&gt;Over the past year I've been slowly working on improvements to the &lt;a href="https://feedsearch.dev"&gt;Feedsearch API&lt;/a&gt; that I published in late 2017, and wrote about in my &lt;a href="https://davidbeath.com/posts/feedsearch-api.html"&gt;previous post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The biggest difference is that the old Feedsearch library has now been replaced with the new &lt;a href="https://github.com/DBeath/feedsearch-crawler"&gt;Feedsearch Crawler&lt;/a&gt; library, which is available for use in other projects as a &lt;a href="https://pypi.org/project/feedsearch-crawler/"&gt;PyPI package&lt;/a&gt;. The crawler is now able to make HTTP requests asyncronously, drastically speeding up the number of URLs that can be checked for feeds in the same amount of time, which in turn increases the feed detection rate in cases where the feed URL is not properly advertised.&lt;/p&gt;
&lt;!-- TEASER_END --&gt;

&lt;p&gt;The second new feature is that all discovered feeds are now saved to a database, along with the website and the URL paths where they were discovered. In this way we can now return a list of all feeds that have been discovered on a site, and remove the need to crawl a site or URL every time a feed search is requested.&lt;/p&gt;
&lt;p&gt;In addition to these, I've extended the results provided by the API to add few new fields:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;content_length: The length of the feed in bytes at the time it was last seen.&lt;/li&gt;
&lt;li&gt;is_podcast: Whether or not the feed contains valid &lt;a href="https://en.wikipedia.org/wiki/Podcast"&gt;podcast&lt;/a&gt; elements and enclosures.&lt;/li&gt;
&lt;li&gt;last_seen: The date that the feed was last crawled by Feedsearch.&lt;/li&gt;
&lt;li&gt;last_updated: The date that the feed was last updated by the publisher.&lt;/li&gt;
&lt;li&gt;velocity: A calculation of the mean number of entries per day in the feed, at the time that the feed was last crawled.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Feedsearch Crawler&lt;/h3&gt;
&lt;p&gt;The &lt;a href="https://github.com/DBeath/feedsearch-crawler"&gt;Feedsearch Crawler&lt;/a&gt; is built as a separate library from the API, so that it's available for others to use, fork, and extend as they see fit.&lt;/p&gt;
&lt;p&gt;I had been thinking for a few years now that what was really needed for feed detection was to use a proper &lt;a href="https://en.wikipedia.org/wiki/Web_crawler"&gt;Web crawler&lt;/a&gt;. As I kept upgrading the original &lt;a href="https://github.com/DBeath/feedsearch"&gt;Feedsearch library&lt;/a&gt; to improve detection rates and add features such as &lt;a href="https://en.wikipedia.org/wiki/Favicon"&gt;Favicon&lt;/a&gt; fetching, the time needed perform a search kept increasing, due to the synchronous design of the &lt;a href="https://docs.python-requests.org/en/latest/"&gt;Requests&lt;/a&gt; HTTP library. It was at the time that I started adding asynchronous HTTP requests to Feedsearch, and therefore requiring that I keep track of which URLs have been requested, that I realised I was just building a crappier Web crawler, without a proper architecture. So I built my own, because why not?&lt;/p&gt;
&lt;p&gt;The design and features of the base crawler itself are nothing special, but the FeedsearchSpider built on top of it is meant to be as discriminating as possible in what it crawls, while still finding as many feeds as possible. In order to do this the spider uses a number of regular expressions to filter page links that may lead to feeds, and then prioritises them for the crawl queue.&lt;/p&gt;
&lt;h3&gt;Feedsearch Gateway API&lt;/h3&gt;
&lt;p&gt;The API is built as the &lt;a href="https://github.com/DBeath/feedsearch-gateway"&gt;Feedsearch Gateway&lt;/a&gt; project, and is responsible for all the custom functionality that is not required in the generic crawler library, such as providing the actual API and dealing with saving results.&lt;/p&gt;
&lt;p&gt;When crawling websites, it's not particularly polite to use a lot of resources, and so I needed the ability to cache the results. Because I already had Feedsearch running on &lt;a href="https://aws.amazon.com/lambda/"&gt;AWS Lambda&lt;/a&gt;, I decided to use &lt;a href="https://aws.amazon.com/dynamodb/"&gt;DynamoDB&lt;/a&gt; for the database. Whenever a search is completed, the following information is saved to the database:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;All feeds found in the crawl and their metadata.&lt;/li&gt;
&lt;li&gt;The host URL of the site and the time it was crawled.&lt;/li&gt;
&lt;li&gt;The URL of the path that was crawled, the time it was crawled, and the URLs of the feeds that were found from that path.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When a search is started, the API first queries the database for the feeds that were already found and the site information. If the search is for the host URL of the site (e.g. &lt;a href="https://example.com"&gt;https://example.com&lt;/a&gt;), then the site is only crawled again if it hasn't been crawled recently, and all feeds that have ever been found to belong to the site are returned.&lt;/p&gt;
&lt;p&gt;If the search contains a path (e.g. &lt;a href="https://example.com/path/testing/"&gt;https://example.com/path/testing/&lt;/a&gt;) then the database is checked to see if that path has already been crawled. If the path has been crawled recently, then the list of URLs found at that path are checked against the sites feeds, and the matching feeds are returned. When the path is searched, only feeds found from the crawl of that path are returned. This is done to increase the chance that only feeds relevant to that particular query are returned, especially if the site contains a lot of feeds.&lt;/p&gt;
&lt;p&gt;Finally, the &lt;a href="https://feedsearch.dev"&gt;Feedsearch site&lt;/a&gt; itself is run behind &lt;a href="https://workers.cloudflare.com/"&gt;Cloudflare Workers&lt;/a&gt;. Cloudflare doesn't cache HTML by default, but because the API homepage is designed to be as static as possible, it makes sense to cache it with the Workers cache API, so that we don't have to make a request to the Lambda function every time the page is requested. Instead, only requests to the API route are forwarded to the Lambda.&lt;/p&gt;</description><category>API</category><category>crawling</category><category>IT</category><category>RSS</category><category>Web</category><guid>https://davidbeath.com/posts/2019-feedsearch-api-updates/</guid><pubDate>Thu, 07 Nov 2019 16:50:14 GMT</pubDate></item><item><title>Feedsearch API</title><link>https://davidbeath.com/posts/feedsearch-api/</link><dc:creator>David Beath</dc:creator><description>&lt;p&gt;I've just published a new microsite and API called &lt;a href="https://feedsearch.dev"&gt;Feedsearch&lt;/a&gt;, which provides an easy way to search websites for &lt;a href="https://en.wikipedia.org/wiki/RSS"&gt;RSS&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Atom_(standard)"&gt;Atom&lt;/a&gt;, and &lt;a href="https://jsonfeed.org/"&gt;JSON&lt;/a&gt; feeds.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://feedsearch.dev"&gt;Feedsearch&lt;/a&gt; is primarily meant to be a thin public API wrapper around the &lt;a href="https://pypi.org/project/feedsearch/"&gt;Feedsearch Python package&lt;/a&gt;, which I wrote to support feed search capabilities in my side project &lt;a href="https://auctorial.com"&gt;Auctorial&lt;/a&gt;. I couldn't find a public library or service that both searched for feeds and returned feed and site metadata, so I wrote this one. In addition to the API, the site allows users to search for feeds using a standard webform.&lt;/p&gt;
&lt;!-- TEASER_END --&gt;

&lt;p&gt;The code and documentation for the Feedsearch package is hosted in the &lt;a href="https://github.com/DBeath/feedsearch"&gt;Feedsearch Github repository&lt;/a&gt;. The site and API code is &lt;a href="https://github.com/DBeath/feedsearch-gateway"&gt;also on Github&lt;/a&gt;. The API runs on the &lt;a href="https://github.com/pallets/flask"&gt;Flask&lt;/a&gt; framework, and is converted with the ridiculously easy to use &lt;a href="https://github.com/Miserlou/Zappa"&gt;Zappa&lt;/a&gt; library to run on &lt;a href="https://aws.amazon.com/lambda/"&gt;AWS Lambda&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Acknowledgements are due to &lt;a href="https://dfm.io/"&gt;Dan Foreman-Mackey&lt;/a&gt; for his &lt;a href="https://github.com/dfm/feedfinder2"&gt;Feedfinder2&lt;/a&gt; library, from which I stole and extended the original code for Feedsearch, and to &lt;a href="https://scripting.com/"&gt;Dave Winer&lt;/a&gt; for giving us RSS in the first place.&lt;/p&gt;
&lt;p&gt;I hope people keep using and writing code for RSS. I think it's important that RSS continues to thrive, both on a personal level (it's how I get most of my reading material), and on a professional level (it's used heavily in &lt;a href="https://auctorial.com"&gt;Auctorial&lt;/a&gt;). RSS is by far the best way we currently have to propagate news and articles around the web; Facebook, Twitter, and Reddit aren't suited for the kind of aggregation that RSS enables.&lt;/p&gt;</description><category>API</category><category>IT</category><category>RSS</category><category>Web</category><guid>https://davidbeath.com/posts/feedsearch-api/</guid><pubDate>Fri, 08 Dec 2017 10:03:53 GMT</pubDate></item><item><title>Installing Tiny Tiny RSS from scratch</title><link>https://davidbeath.com/posts/installing-tiny-tiny-rss-from-scratch/</link><dc:creator>David Beath</dc:creator><description>&lt;p&gt;Considering that a couple of times now I've been a proponent of using an RSS reader, I figured it was time I wrote a tutorial on how to install &lt;a href="https://tt-rss.org/"&gt;Tiny Tiny RSS&lt;/a&gt;, using &lt;a href="https://nginx.org/"&gt;Nginx&lt;/a&gt; as the server and &lt;a href="https://www.postgresql.org/"&gt;PostgreSQL&lt;/a&gt; for the database. While as with any piece of software there are a number of tutorials and guides already out there, I've found that none of them provided a complete instruction set that didn't have me running into and searching for solutions to multiple errors. To that end, this tutorial aims to both provide as complete a set of fool-proof instructions as I can make, both for newbies to self-hosting, and simply as a reference for my future self should I need to do this again.&lt;/p&gt;
&lt;!-- TEASER_END --&gt;

&lt;p&gt;This set of instructions assumes that you're running a Debian based Linux distro. I've tested this setup on a clean Ubuntu Server 12.04 virtual machine, and the settings are roughly the same as I'm using on my Debian server. It's assumed that you either know how to set up a server already, or are capable of reading a tutorial to do so (If not, then why are you reading this? Go use &lt;a href="https://cloud.feedly.com/"&gt;Feedly&lt;/a&gt;). There are some very good tutorials at &lt;a href="https://www.digitalocean.com/community/"&gt;Digital Ocean&lt;/a&gt; and &lt;a href="https://library.linode.com/"&gt;Linode&lt;/a&gt;, and I'd recommend either of them for hosting purposes.&lt;/p&gt;
&lt;h3&gt;Installation&lt;/h3&gt;
&lt;p&gt;On to the install. While not strictly necessary, the first thing I recommend is to make sure that your server is using the correct time, so install ntp to keep the system clock updated.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; sudo apt-get install ntp
&lt;/pre&gt;
&lt;p&gt;For most of the commands in this tutorial you'll need super user privileges, so you can either run them as root (not recommended) or use &lt;code&gt;sudo&lt;/code&gt; like I've used in this tutorial.
You'll also need to edit a bunch of files in a text editor. I've used &lt;code&gt;nano&lt;/code&gt; for this tutorial because it's easier to use and you can just copy the commands straight, but I usually use &lt;code&gt;vim&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;PHP&lt;/h3&gt;
&lt;p&gt;Unfortunately, despite the fact that &lt;a href="https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/"&gt;PHP sucks&lt;/a&gt; (seriously, read the article, even if you disagree it's an interesting read), Tiny Tiny RSS is built with PHP. However, just because a language sucks doesn't mean that programs written in it necessarily have to, and tt-rss is the best of the self-hosted RSS readers. Still, that means you're going to have to install PHP, and get it working nicely with Nginx.&lt;/p&gt;
&lt;p&gt;Install PHP 5 and the components necessary to get it playing nicely with everything else.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; sudo apt-get install php5 php5-fpm php5-curl php5-pgsql php5-gd php5-mcrypt php5-cli
&lt;/pre&gt;
&lt;p&gt;There's one line in php.ini you'll need to change, which will prevent a possible &lt;a href="https://wiki.nginx.org/Pitfalls#Passing_Every_.7E_.5C.php.24_request_to_to_PHP"&gt;security issue&lt;/a&gt;.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; sudo nano /etc/php5/fpm/php.ini
&lt;/pre&gt;
&lt;p&gt;Change this line:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span class="na"&gt;cgi.fix_pathinfo&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;To this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span class="na"&gt;cgi.fix_pathinfo&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;The other change is to make PHP-FPM listen on a UNIX socket rather than a TCP socket.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; sudo nano /etc/php5/fpm/pool.d/www.conf
&lt;/pre&gt;
&lt;p&gt;Change the line:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;127.0.0.1:9000&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;To:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/var/run/php5-fpm.sock&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Finally, restart PHP.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; sudo /etc/init.d/php5-fpm restart
&lt;/pre&gt;
&lt;h3&gt;Nginx&lt;/h3&gt;
&lt;p&gt;Now that PHP is configured, you'll want to configure Nginx. There's a very good &lt;a href="https://blog.martinfjordvald.com/nginx-primer/"&gt;primer&lt;/a&gt; by Martin Fjordvald on the basics of Nginx configuration which you can read to get an understanding of what's going on. If you want to dig deeper for various other settings, the &lt;a href="https://nginx.org/en/docs/"&gt;documentation&lt;/a&gt; for Nginx is quite thorough.&lt;/p&gt;
&lt;p&gt;This tutorial is going to have you build Nginx from source, since the .deb packages are not always up to date. It's really not that much harder than setting it up from a package install anyway.&lt;/p&gt;
&lt;p&gt;First, install the packages required to compile the source.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; sudo apt-get install gcc make libpcre3-dev openssl libssl-dev
&lt;/pre&gt;
&lt;p&gt;I also prefer to have Nginx use a dedicated system account with no login or password access for a bit of extra security.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; sudo adduser --system --no-create-home --disabled-login --disabled-password --group nginx
&lt;/pre&gt;
&lt;p&gt;Then download and unpack the latest Nginx version.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; wget https://nginx.org/download/nginx-1.5.6.tar.gz

&amp;gt; tar -xzvf nginx-1.5.6.tar.gz

&amp;gt; &lt;span class="nb"&gt;cd&lt;/span&gt; nginx-1.5.6
&lt;/pre&gt;
&lt;p&gt;The configure command sets the parameters for the build. This is where you can change the default install directory and the different modules that Nginx uses. Nginx doesn't allow you to change modules without rebuilding, so you'll need to select or deselect any modules here. The only module I'll add is the http_ssl module, which will allow you to add SSL to your site later if you wish. I also prefer to just use the default install directory, so I won't change that, but I'll set the user and group Nginx uses to the one I created earlier.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; ./configure --user&lt;span class="o"&gt;=&lt;/span&gt;nginx --group&lt;span class="o"&gt;=&lt;/span&gt;nginx --with-http_ssl_module
&lt;/pre&gt;
&lt;p&gt;Now we can build and install Nginx.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; make &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo make install
&lt;/pre&gt;
&lt;h4&gt;Nginx Configuration&lt;/h4&gt;
&lt;p&gt;Change to the directory you installed Nginx to:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; &lt;span class="nb"&gt;cd&lt;/span&gt; /usr/local/nginx
&lt;/pre&gt;
&lt;p&gt;There are various methods people use for controlling the sites on their server. The .deb install uses a &lt;code&gt;sites-enabled&lt;/code&gt; and &lt;code&gt;sites-disabled&lt;/code&gt; style configuration, but since I don't have many sites on my server, I prefer to keep each site configuration file in the conf/ folder, and include each one manually in nginx.conf.&lt;/p&gt;
&lt;p&gt;So, for this tutorial, we'll create a ttrss.conf file.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; sudo nano conf/ttrss.conf
&lt;/pre&gt;
&lt;p&gt;My ttrss.conf looks something like this (except I have SSL enabled):&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span class="c1"&gt;# Tiny Tiny RSS Configuration&lt;/span&gt;

&lt;span class="k"&gt;server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;listen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;server_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;domainname&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;www.domainname&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;root&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/var/www/ttrss&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;index&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;index.php&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;error_log&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/var/log/nginx/ttrss.error.log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;access_log&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/var/log/nginx/ttrss.access.log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;location&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;try_files&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$uri&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$uri/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/index.php&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;location&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;~&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sr"&gt;\.php$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;fastcgi.conf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# don't use fastcgi_params&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;fastcgi_pass&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;unix:/var/run/php5-fpm.sock&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;fastcgi_index&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;index.php&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;A brief primer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;listen&lt;/em&gt;: the port that the server listens for incoming connections on.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;server_name&lt;/em&gt;: the FQDN (fully qualified domain name) that the server uses for this connection. I set this to listen on both example.com and www.example.com.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;root&lt;/em&gt;: the root directory that the site's files are located at.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;index&lt;/em&gt;: the index file that the server directs traffic to. In this case you only need index.php, but can also include index.html or .htm, or any other file you want to use as a homepage.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;error_log&lt;/em&gt;: the location of the error log for this site.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;access_log&lt;/em&gt;: the location of the access log for this site.
The first location block accepts all incoming requests:&lt;/li&gt;
&lt;li&gt;&lt;em&gt;try_files&lt;/em&gt;: this just makes the URL search engine friendly. Not really necessary in this case, but it doesn't hurt.
The second location block catches all incoming php requests:&lt;/li&gt;
&lt;li&gt;&lt;em&gt;include fastcgi.conf&lt;/em&gt;: this file comes with Nginx and includes all the parameters for using fastcgi. It's almost the same as fastcgi_params, but you'll have issues using fastcgi_params in Ubuntu 12.04, unless you include the line &lt;code&gt;SCRIPT_FILENAME $document_root$fastcgi_script_name&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;fastcgi_pass&lt;/em&gt;: the socket that fastcgi passes requests through.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;fastcgi_index&lt;/em&gt;: the index file that fastcgi uses.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Next, you'll need to edit nginx.conf.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; sudo nano conf/nginx.conf
&lt;/pre&gt;
&lt;p&gt;The only change that you really need to make to this file is to add the line &lt;code&gt;include ttrss.conf&lt;/code&gt; in the http block, but this is my recommended configuration below.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span class="c1"&gt;# Nginx Configuration&lt;/span&gt;

&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;nginx&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="k"&gt;worker_processes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# optimal value is number of cpu cores&lt;/span&gt;

&lt;span class="k"&gt;error_log&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/var/log/nginx/error.log&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="s"&gt;events&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;worker_connections&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2048&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="k"&gt;http&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# Virtual Host Configuration&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;ttrss.conf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# Basic Settings&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;mime.types&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;default_type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;application/octet-stream&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;sendfile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;tcp_nopush&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;tcp_nodelay&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;off&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;client_header_timeout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;20s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;client_body_timeout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;20s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;send_timeout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;20s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# Disable Nginx version number in error pages and Server header&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;server_tokens&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;off&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# Silently block all undefined vhost access&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;server_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;_&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;444&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# Gzip Settings&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;gzip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;gzip_disable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"msie6"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;gzip_comp_level&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;gzip_min_length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;gzip_vary&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;gzip_proxied&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;gzip_types&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Finally, start Nginx.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; sudo /usr/local/nginx/sbin/nginx
&lt;/pre&gt;
&lt;p&gt;If you need to make any changes to Nginx after it's been started, just open and change the config files. Then run this command to reload the Nginx with the new configuration.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; sudo /usr/local/nginx/sbin/nginx -s reload
&lt;/pre&gt;
&lt;h3&gt;Postgres&lt;/h3&gt;
&lt;p&gt;Tiny Tiny RSS recommends using &lt;a href="https://www.postgresql.org/"&gt;PostgreSQL&lt;/a&gt; over MySQL for the database, as PostgreSQL is slightly faster. For a single user, it probably wouldn't make much difference, depending on how many feeds you have. The instructions for installing PostgreSQL are mostly taken from the Ubuntu community wiki &lt;a href="https://help.ubuntu.com/community/PostgreSQL"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Install PostgreSQL.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; sudo apt-get install postgresql
&lt;/pre&gt;
&lt;p&gt;Log in to the postgres command line as user postgres.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; sudo -u postgres psql postgres
&lt;/pre&gt;
&lt;p&gt;Change the password for the postgres user. Type in the command below, hit enter, then enter as password. Make sure to save all your passwords in a good password manager somewhere. I recommend &lt;a href="https://keepass.info/"&gt;KeePass&lt;/a&gt;.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; &lt;span class="se"&gt;\p&lt;/span&gt;assword postgres
&lt;/pre&gt;
&lt;p&gt;While you're still in the postgres command line, create a database and database user for tt-rss. The password must be entered surrounded by single quotes.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span class="nv"&gt;postgres&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="c1"&gt;# CREATE USER ttrss WITH PASSWORD 'password';&lt;/span&gt;

&lt;span class="nv"&gt;postgres&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="c1"&gt;# CREATE DATABASE ttrssdb;&lt;/span&gt;

&lt;span class="nv"&gt;postgres&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="c1"&gt;# GRANT ALL PRIVILEGES ON DATABASE ttrssdb to ttrss;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Exit the postgres command line.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span class="nv"&gt;postgres&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="c1"&gt;# \q&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;From this point, you might be able to get tt-rss to access the database, but I wasn't until I edited a line in the postgresql config to allow access.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; sudo nano /etc/postgresql/9.1/main/pg_hba.conf
&lt;/pre&gt;
&lt;p&gt;Add this line to allow tt-rss to use the database:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span class="na"&gt;local all ttrss md5&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Now restart PostgreSQL.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; sudo service postgresql restart
&lt;/pre&gt;
&lt;h3&gt;Tiny Tiny RSS&lt;/h3&gt;
&lt;p&gt;Finally, it's now time to install Tiny Tiny RSS itself. Yeah, I know it takes a while to get here. I assure you, it's worth it in the end, and you shouldn't have to worry about it much at all once you've got it properly set up. The installation instructions for tt-rss can be be found &lt;a href="https://tt-rss.org/redmine/projects/tt-rss/wiki/InstallationNotes"&gt;here&lt;/a&gt;, but once again they seem somewhat incomplete.&lt;/p&gt;
&lt;p&gt;First, make a directory for tt-rss to be served from. This should be the same as the directory you specified as root in your ttrss.conf file for Nginx.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; sudo mkdir -p /var/www/ttrss
&lt;/pre&gt;
&lt;p&gt;You'll need to set the owner of the directory to the user that you're installing and running tt-rss as.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; sudo chown -R user:group /var/www/
&lt;/pre&gt;
&lt;p&gt;Now change to the directory above.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; &lt;span class="nb"&gt;cd&lt;/span&gt; /var/www
&lt;/pre&gt;
&lt;p&gt;Download and extract the latest version of Tiny Tiny RSS.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; wget https://github.com/gothfox/Tiny-Tiny-RSS/archive/1.10.tar.gz

&amp;gt; tar -xzvf &lt;span class="m"&gt;1&lt;/span&gt;.10.tar.gz
&lt;/pre&gt;
&lt;p&gt;Rename the extracted directory so that it matches the root directory you specified earlier, then open the directory.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; mv Tiny-Tiny-RSS-1.10/ ttrss

&amp;gt; &lt;span class="nb"&gt;cd&lt;/span&gt; /var/www/ttrss
&lt;/pre&gt;
&lt;p&gt;The following folders need to have their permissions changed to be writable by anyone with an account on the system, or tt-rss won't be able to save files there.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; sudo chmod -R &lt;span class="m"&gt;777&lt;/span&gt; cache/images/ cache/js/ cache/export/ cache/upload/ feed-icons/ lock/
&lt;/pre&gt;
&lt;p&gt;Now you should be able to navigate in your browser to the site that you are hosting tt-rss from. This should be the same as the server_name you specified in ttrss.conf. If you installed tt-rss into a sub-folder of the domain, then the address will be &lt;code&gt;https://domainname/ttrss/&lt;/code&gt;. If you got the configuration correct, you should see the Tiny Tiny RSS install page.&lt;/p&gt;
&lt;p&gt;The installation page will have a few fields to enter. These will be the credentials for tt-rss to use the database, as well as the full URL that you'll access tt-rss from. Once you've entered the database details, click the 'Test Configuration' button. If there are errors, you'll get a message saying so, and it shouldn't be too hard to figure out what to do from there. If it's good to go, you'll see a text box with a lot of configuration lines. Copy that config data to your clipboard, and then into a config file on your server with:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; sudo nano /var/www/ttrss/config.php
&lt;/pre&gt;
&lt;p&gt;Save that file, and reload tt-rss in your browser. You should now be able to login with the default user &lt;code&gt;admin&lt;/code&gt; and password &lt;code&gt;password&lt;/code&gt;. Once you're logged in, change the admin settings in the preferences at top right.&lt;/p&gt;
&lt;p&gt;The final required step is to set up automatic updating of your feeds. You can skip this, but you'll have to manually click on each feed to check for updates if you don't. The &lt;a href="https://www.gnu.org/software/screen/"&gt;screen&lt;/a&gt; command will permanently run feed updates in the background, defaulting to once every 30 minutes.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&amp;gt; screen -d -m php ./update_daemon2.php
&lt;/pre&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;You should now have a working installation of Tiny Tiny RSS on your server, accessible from anywhere in the world. If you've used RSS Readers before, you can import your feeds from an OPML file, otherwise, find some good blogs and start adding feeds.&lt;/p&gt;</description><category>hosting</category><category>IT</category><category>Nginx</category><category>RSS</category><category>servers</category><category>tutorial</category><category>Web</category><guid>https://davidbeath.com/posts/installing-tiny-tiny-rss-from-scratch/</guid><pubDate>Wed, 02 Oct 2013 03:43:39 GMT</pubDate></item><item><title>Typography: New Style and Fonts</title><link>https://davidbeath.com/posts/typography-new-style-and-fonts/</link><dc:creator>David Beath</dc:creator><description>&lt;p&gt;I've spent a few hours over the last few days reading &lt;a href="https://practicaltypography.com"&gt;Butterick's Practical Typography&lt;/a&gt;, which I felt might be a good idea considering that I enjoyed his rant about Web Design that I posted a while back. I feel that in some ways I damn myself as the worst (or best, depending on how twisted your perceptions are) type of geek for being interested in and recommending a book on the intricacies of typography. Though really, much as there is on the site, it's still only a primer, and I don't think I'm going to go much farther down the rabbit hole than this.&lt;/p&gt;
&lt;!-- TEASER_END --&gt;

&lt;p&gt;The further I read through the book, the more little details in my site started to annoy me a bit. As a result, I've spent even more hours slowly and meticulously changing the styling and fonts of this blog. The changes are relatively minor, but while you won't be able to do a direct comparison, as obviously I've already updated the site, I assure you they make a big difference in the quality of this site's appearance.&lt;/p&gt;
&lt;p&gt;The biggest difference comes simply from changing the font. While I'm still using the &lt;a href="https://foundation.zurb.com"&gt;Foundation framework&lt;/a&gt;, I've changed the font from it's trusty default, &lt;a href="https://en.wikipedia.org/wiki/Helvetica#Neue_Helvetica_.281983.29"&gt;Helvetica Neue&lt;/a&gt;, to &lt;a href="https://practicaltypography.com/charter.html"&gt;Charter&lt;/a&gt;. Ordinarily I've always tended to use Sans-Serif fonts whenever I've actually thought about it and gone beyond the default Times New Roman or Arial in my writing, but this time I figured a good Serif font looks more professional and easier to read. A serif font also allows for better use of &lt;em&gt;emphasis&lt;/em&gt;. Doing side by side comparisons between the old and new versions of my site, I find Helvetica Neue to be slightly blurry to my eyes, while Charter looks relatively crisp and sharp.&lt;/p&gt;
&lt;p&gt;For code blocks I've switched from the default css monospace to &lt;a href="https://levien.com/type/myfonts/inconsolata.html"&gt;Inconsolata&lt;/a&gt;.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;helloworld&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;"Hello World"&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;It's a nicely legible monospace font, and quite importantly when it comes to code, makes it very easy to distinguish between characters such as &lt;code&gt;O&lt;/code&gt; and &lt;code&gt;0&lt;/code&gt;. While any good font will do this, it's especially important in a monospace font when you're reading code, and trying to figure out what character you're dealing with at a quick glance. Witness the relatively subtle difference between O and 0 in Charter. While the capital O is slightly wider than the number 0, it can be confusing in the absence of other references. The strikethrough in Inconsolata's zero makes the difference clear. Many fonts have the same issue between capital I and lowercase l as well. Most monospace fonts take pains to make these differences plain, so it largely comes down to a matter of personal preference.&lt;/p&gt;
&lt;p&gt;One small change that makes a big difference is increasing the whitespace by slightly separating the lines with the line-height value. This separation just makes each line a little more distinct and less cramped feeling, making for easier reading. I also increased the margins a touch around the code in the code blocks, making the code stand out a little more, and combined with the line-height change makes the code in my previous post stand out nicely.&lt;/p&gt;
&lt;p&gt;Finally with the typography changes, centering the titles of each post provides a clearer visual indication of the start of a new post. It also makes the difference between the title of a post and the subheadings stand out more, especially if I should want to start a new post with a subheading, or have one after a single paragraph.&lt;/p&gt;
&lt;p&gt;The last little change I've made is to include a couple of cool little icons from &lt;a href="https://fortawesome.github.io/Font-Awesome/"&gt;Font Awesome&lt;/a&gt;. I always wanted an RSS icon on my RSS feed button, and now I have one. There are also icons for the links on my About page, which I really should update with a bit more info sometime.&lt;/p&gt;
&lt;p&gt;One final point: If you're still reading this far, you'll hopefully be wondering what the hell I'm talking about fonts and spacing for, because you should be reading this in a proper RSS reader, and all my typography has been stripped out. I'll forgive you if this is your first time visiting, or you've come from a link posted somewhere. Otherwise, go be a good geek and learn how to host and run &lt;a href="https://tt-rss.org/redmine/projects/tt-rss/wiki"&gt;Tiny Tiny RSS&lt;/a&gt;, or if you're not into self hosting, then I recommend &lt;a href="https://feedly.com"&gt;Feedly&lt;/a&gt;. And if you're into Web Design, do any typing or publishing, or need to write a résumé, then read &lt;a href="https://practicaltypography.com"&gt;Practical Typography&lt;/a&gt;.&lt;/p&gt;</description><category>Design</category><category>fonts</category><category>RSS</category><category>typography</category><category>Web</category><guid>https://davidbeath.com/posts/typography-new-style-and-fonts/</guid><pubDate>Wed, 25 Sep 2013 00:51:40 GMT</pubDate></item><item><title>A New Blog</title><link>https://davidbeath.com/posts/a-new-blog/</link><dc:creator>David Beath</dc:creator><description>&lt;p&gt;So, I guess it's time I started to write a blog. I've always read that it's recommended in IT to write a blog, or maybe in any industry these days, in order to have some sort of recognisable professional presence. Or, at the very least, to keep your rants off Facebook.&lt;/p&gt;
&lt;p&gt;At any rate, there are plenty of things I could talk about, and I will. I tend mostly to have strong opinions on Politics, Information Technology, Economics, the Environment, and any intersection between the bunch, though not necessarily in that order. I think I'll start off properly with a politics post next.&lt;/p&gt;
&lt;!-- TEASER_END --&gt;

&lt;p&gt;Anyway, I figure I might as well write about the tools I used to set this blog up. Starting from the bottom of the stack, my server is a VPS hosted by &lt;a href="https://www.linode.com/"&gt;Linode&lt;/a&gt;. I like that I have full control over my machine, without having to worry about the hardware. Even the lowest tier plan gets me more than enough machine for my needs, and the documentation and tools they have are really good. Definitely recommended.&lt;/p&gt;
&lt;p&gt;The server OS is &lt;a href="https://debian.org"&gt;Debian&lt;/a&gt;, because for me it was either that or Ubuntu Server for the easy and familiar option. Fanboys can feel free to flame away at whatever choice is made, but I like something stable.&lt;/p&gt;
&lt;p&gt;For the HTTP server itself, I'm using &lt;a href="https://nginx.org"&gt;nginx&lt;/a&gt;. Apache is just to mainstream, and from everything I've read it doesn't scale as well. Not that scaling should be a problem for me for a long time, if ever, but you never know. I've found nginx to be just as easy, if not easier, to understand and configure compared to Apache anyway.&lt;/p&gt;
&lt;p&gt;Finally, I use &lt;a href="https://getnikola.com/"&gt;Nikola&lt;/a&gt; to generate this blog. Nikola is a static blog generator, so all the files on this site are just plain HTML, no CMS needed. The site design is basically just an unmodified &lt;a href="https://get.foundation/"&gt;Foundation&lt;/a&gt; theme, which for now looks good enough. Besides, if you're not using an RSS reader to read this blog (once you've first visited and decided to keep reading of course), then you damned well should be. Why on earth would you manually visit blogs to read?&lt;/p&gt;
&lt;p&gt;On the non-essential side of things, analytics on the blog are handled by &lt;a href="https://piwik.org"&gt;Piwik&lt;/a&gt;, so that I don't have to send all my data to Google Analytics. The thing I use this server for the most though, is &lt;a href="https://tt-rss.org"&gt;Tiny Tiny RSS&lt;/a&gt;. I find that using an RSS reader is essential for keeping up with the world. Like most everyone else, I used to use Google Reader, but of course anyone who hasn't been living under a rock this year knows the story of how they shut it down, and the gnashing and wailing of teeth that ensued. I contributed my part of that, on my tiny corner of Google Plus and Facebook.&lt;/p&gt;
&lt;p&gt;Just like many others, I decided that if I couldn't trust even Google with my stuff, then it might be better to go self-hosted. Tiny Tiny RSS was the self hosted solution with the most recommendations, and I've been pretty happy with it so far. It's nice to know that you've got a service that no-one is going to arbitrarily remove, just so long as you have a good backup policy in place.&lt;/p&gt;
&lt;p&gt;Someday soon, I might get round to routing my mail through my server as well, though I might like to have it on a different one. A single point of failure for everything I rely on makes me nervous.&lt;/p&gt;
&lt;p&gt;In conclusion, Welcome to my Blog, and don't be afraid to look into self hosting if you're at all technically inclined. It's the 21st century, and all the information you need is out there.&lt;/p&gt;</description><category>hosting</category><category>IT</category><category>RSS</category><category>servers</category><guid>https://davidbeath.com/posts/a-new-blog/</guid><pubDate>Fri, 23 Aug 2013 09:23:54 GMT</pubDate></item></channel></rss>