Internet

Nov
30
Posted by JB at 11:34 am

A very close friend of mine released a new type of pastebin that has some very fancy features that really make it shine over any other interpretation on this type of idea. The client, which is written in Ruby and open source, is quickly installed through the use of the standard Ruby Gem installation approach. At this point you can immediately echo any code that you wish into the haste command on the terminal and it will be pushed up to a node.js powered backend which stores it, syntax highlighted, and returns a URL back down to you.

The web interface is simplistic, yet beautifully crafted to allow for inline text editing right in your web browser. Shortcut commands exist to create a new piece of code, save one, and tweet it immediately. In a single day it has climbed among the top spot on Hacker News, and is already getting some very constructive feedback. The fact that both the server and the client are open source allow for internal implementations to be rolled out without any worry to proprietary code being leaked to the outside.

I know he’ll be reading this post so I’ll gripe a little, and give my wish list:

  • It’d be nice to allow for a quick shortcut for tab spacing. I work in C/C++ every day, and like to have a little bit more tab that you have there by default. More tab please!
  • In the future when the Gist API becomes public it’d be really awesome to allow for forking, and pushing back up to your Gist.
  • An emacs plugin would be nice, but since I know at the main site itself, and of course, go download the client and the server and deploy it at your nine-to-five today!

  • You may have noticed that there are several websites now that included integration with social networking websites such as Facebook, Google Plus and Twitter. These small buttons allow your user’s to share content instantly with their friends. Depending on which you’re including on your site it’ll show up differently, and each has a separate process to include them on your blog’s pages. Since I am using WordPress I will explain how to do this, but if you follow the example it should work in the broad case as well.

    This functionality is provided by using meta information that is stored on the user’s browser. Unless you decide to do something nefarious, you do not have to their data by merely adding these buttons, but it does expose your user’s to a potential security risk. There are browser plugins that allow them to turn off this functionality if they have it enabled. If you’re comfortable with all this, then go on ahead and follow the instructions.

    A useful wizard is available that provides you with both the XHTML and Javascript necessary to make this functionality work correctly on your site. The Javascript code snippet provides the bridge between the user’s browser and the Facebook social graph that this is using in the background. There are a few routes regarding how to implement it, I chose the HTML5 approach which asked me to add a schema namespace to the HTML element, and then used the custom like button element that is provided to display it.

    Javascript snippet Place this after your BODY element

    <script src="//connect.facebook.net/en_US/all.js"></script>
            <div id="fb-root"></div>
            <script>(function(d, s, id) {
            var js, fjs = d.getElementsByTagName(s)[0];
            if (d.getElementById(id)) {return;}
            js = d.createElement(s); js.id = id;
            js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId=309698452382243";
            fjs.parentNode.insertBefore(js, fjs);
            }(document, 'script', 'facebook-jssdk'));</script>

    HTML element Place this where you want the button to appear.

    <fb:like href="http://example.com" send="true" layout="button_count" show_faces="true" action="recommend" font="lucida grande" display="inline"></fb:like>

    You will be given the exact HTML element tag that you should use based upon your wizard settings. If you want to use this dynamically in the WordPress Loop to display under each post you’ll have to use a PHP function the_permalink(); which will return the URI to the page in question. This can also be done on the single pages if you so desire. One last step is to include meta information at the top of each page to let Facebook know how the post should be described in the user’s activity feed. This is very straight forward and simple. An optional title element should be used on individual pages. Categories can be selected through the wizard.

    Meta information Place this in the HEAD element

    <meta property="og:type" content="blog" />
    <meta property="og:site_name" content="Thoughtless Banter" />
    <meta property="fb:admins" content="199800257" />

    The Google Plus approach is very similar, and doesn’t require any meta information tags. When a user decides to “+1″ any of your posts they will in a special location on that user’s profile, and in any the subscriber’s feeds as well. You’ll need to include a Javascript snippet, like above, and a special HTML tag element. You can add all of this below the Facebook directives if you desire.

    Javascript snippet Place this after the BODY element.

    <script type="text/javascript">
      (function() {
        var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
        po.src = 'https://apis.google.com/js/plusone.js';
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
      })();
    </script>

    HTML element tag Place this where you wish the button to appear.

    <g:plusone href="http://example.com" size="medium" annotation="inline"></g:plusone>

    Finally, the Twitter button is the easiest to place, and they once again provide a wizard for you to change the colors of the background, design, and number of tweets you wish to show (if you do not just want a button, but rather the feed itself). This one-liner can be placed anywhere you want the button to appear.

    <a href="https://twitter.com/share" class="twitter-share-button" data-url="http://thoughtlessbanter.com/2011/11/23/furniture-for-men/" data-text="Furniture For Men" data-count="horizontal" data-via="johnbellone">Tweet</a><script type="text/javascript" src="//platform.twitter.com/widgets.js">

    That should basically the gist of how to get this functionality working on your website. Facebook offers more comprehensive widgets that take advantage of the social graph to display photos, and even information about user’s actions on your page. There is beta examples of how to post directly to the new Facebook Timeline feature that will be rolling out to your profile shortly. As more and more of these snippets become available you should consider both the advantages and the disadvantages of using them. I know that many user’s are worried about privacy and tracking that all the social sites are beginning to do. It is quite possible in the future that this type of functionality will be opt-in rather than opt-out and it may not work with the breadth of your user’s without their explicit consent. So be wary designing your website around these widgets specifically.

    In the past I have had some problems with shared hosting services mainly due to the speed and limited functionality that was offered through their control panel interfaces. This one in particular used that famous cPanel garbage that got popular when most administrators didn’t know a lick about using Linux. A few years ago there was this whole “cloud” term that was passed around like the town slut. What this basically means is distributed, always-on, fault-tolerant, all those terms that your rockstar network engineer has thrown at you but really doesn’t know anything about. What it gives us neophyte administrators is a cheap, virtual Linux server that we can configure to our own liking.

    This meant that I was no longer tethered to the limitations of the infrastructure provided by the website. My previous host got swallowed up by Rackspace and went to shit. A few months ago someone told me about Linnode as it is a local Jersey business, so I started to check them out, and finally bit the bullet today and started the migration process from my old host to this brand spanking-new piece of iron. It took me about an hour and a half to get the blog post that you’re reading up and going. Not too shabby.

    I’d like to reminisce for a moment: I remember way back when I had to work with someone that was paying hundreds of dollars a month for hosting to get ten megabytes and a subdomain for their account to start a video game portal in the late nineties. These bastards were being charged, by the subdomain, some absurd amount by the web host to set up a few DNS records. Now, mind you, it took sometimes several days for DNS to propagate across the Internet back then. I was able to accomplish this feat in the matter of about fifteen minutes, and ironically enough, the last machine that I had access to to actually receive the DNS update was my previous virtual host. Bastards.

    So if you’re going to take the leap to virtual cloud hosting, give Jersey some love and set it up on Linnode.com, and by clicking on that link you’ll give me a free credit for $20 if you sign up for three months. Not going to lie, I completely wrote this post to hopefully get two or three of you poor schmucks to get me a month of free hosting. But hell, I’m going to be posting more set up information regarding my LAMP stack in the upcoming day or so. Free consulting as far as I am concerned.

    As always, go fuck yourself.

    For the past year or so I have been using nginx as a proxy in front of my Apache instances on the server that runs this blog, and a few other websites that I manage. The virtual machine itself is running an older LTS version of Ubuntu, and most of the applications on here are a traditional LAMP setup with a few C/C++ testing tools scattered around. For the most part it is operating as web server with a small work load. But as I’ve been adding a few more services running in the background I have noticed a little slowdown with WordPress.

    There are some obvious advantages to this set up: Nginx can serve up all of the static content very, very quickly without having to send it down to the Apache instances to process. This frees up those daemons to only serve application logic, which in this case is the WordPress PHP application, but would work for nearly anything that you have set up with it. I will give you a quick example of the configuration that I have set up for this site.

    This is the main configuration file for the Nginx application. Most of the commands here I have plucked from various tutorials across the internet, specifically dealing with the gzip settings, and as you can see there are a few connection and process related settings. These can all be tweaked at your desire, but I find that they work best on my low load cloud virtual server. The information to note here is the location of the proxy server (127.0.0.1:8080) that the requests will be sent to, as well as some folders for errors, logs, etc. These are all standard with the Nginx installation from aptitude and should be modified to suite you. Note the section where we include any scripts that are in /etc/nginx/sites-enabled/* which is similar to the set up of the Apache portion of the LAMP stack.

    /etc/nginx/nginx.conf

    user  op;
    worker_processes  2;
     
    error_log  logs/error.log warn;
    #error_log  logs/error.log  notice;
    #error_log  logs/error.log  info;
     
    pid        logs/nginx.pid;
     
    events {
        worker_connections  1024;
    }
     
    http {
        include       mime.types;
        default_type  application/octet-stream;
     
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
     
        access_log  logs/access.log  main;
     
        gzip on;
        gzip_http_version 1.0;
        gzip_comp_level 2;
        gzip_min_length 1100;
        gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
        gzip_buffers 16 8k;
        gzip_disable "MSIE [1-6].(?!.*SV1)";
        gzip_vary on;
     
        include /etc/nginx/sites-enabled/*;
     
        server {
            listen       80 default;
            access_log  logs/host.access.log  main;
     
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   html;
            }
     
            location / {
                     include /etc/nginx/proxy.conf;
                     proxy_pass http://127.0.0.1:8080;
            }
        }
    }

    This configuration file sets up the particular domain inside of the Nginx proxy. It covers both the fully qualified domain name and the alias, and provides the root directory for serving up the static content. If there is content that you do not want to be served up (e.g. you have a public folder) make sure to point this only to your assets directory. We set up the path for logs to be written to (you’ll have to mkdir -p those directories) as well. The real gem here is the regular expression that specifies what static content will not get fielded off to the apache daemons. Obviously you can make any corrections here that you see fit. When you are done set up a symbolic link in /etc/nginx/sites-enabled/.

    /etc/nginx/sites-available/thoughtlessbanter.com

    server {
     server_name www.thoughtlessbanter.com thoughtlessbanter.com;
     root /path/to/thoughtlessbanter.com/;
     
     access_log /var/log/nginx/thoughtlessbanter.com/access.log;
     error_log /var/log/nginx/thoughtlessbanter.com/error.log warn;
     
     location ~* ^.+.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$ {
                  access_log off;
                  expires 30d;
     }
     
     location / {
                  include /etc/nginx/proxy.conf;
                  proxy_pass http://127.0.0.1:8080;
     }
    }

    This little tidbit is necessary to send over the header information from the HTTP client to the Apache daemon. These proxy settings, with this configuration set up, will affect every single web request, so be careful with what you modify here. There are additional parameters involving the maximum size of a payload, send, connect, and read timeouts, etc. These can all be looked up with a quick Google search and modified freely.

    /etc/nginx/proxy.conf

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    Last you’ll need to modify your virtual host for all of the websites to now accept the connection on the new port, 8080, which is were Nginx will proxy the requests to. Be sure to set the server alias for both the fully qualified domain, and the shortened one. I am not an Apache configuration guru here, so some of the other options may not be applicable, but they seem to do the job for me. Most of my domains are further configured appropriately in the .htaccess in the document root directory.

    /etc/apache2/sites-available/thoughtlessbanter.com

    <VirtualHost *:8080>
                  ServerAdmin jb@thunkbrightly.com
                  ServerName thoughtlessbanter.com
                  ServerAlias www.thoughtlessbanter.com
                  DocumentRoot /path/to/thoughtlessbanter.com
                  <Directory />
                   Options FollowSymLinks
                   AllowOverride All
                  </Directory>
                  <Directory /path/to/thoughtlessbanter.com>
                   Options Indexes FollowSymLinks MultiViews
                   AllowOverride All
                   Order allow,deny
                   allow from all
                  </Directory>
     
                  ErrorLog /var/log/apache2/thoughtlessbanter.com-error.log
                  CustomLog /var/log/apache2/access.log combined
    </VirtualHost>

    When you have made all of the changes feel free to restart the services and test your website. Once all the instances are bounced you should be able to point the browser to the location and still bring up your website. If you check the logs located in /var/log/nginx/ and /var/log/apache2/.log you should be able to see your static content requests hitting nginx, and being served up right from there. The apache daemons will now only serve the application logic.

    Let me know what you think. I’m sure I’ve made a few mistakes.

    Jul
    26
    Posted by JB at 11:08 pm

    At some point near the end of last week I decided to try out this new fangled operating system that Apple has been toting for the better part of the year. I used their Mac App Store but within the first few minutes I ran into some issues that should have been a forewarning to spending the time to be an early adopter of Lion.

    Earlier in the year I installed a developer preview of Lion which did not seem to include too many features. In fact, I did not even remember that I installed this, and when it came to the Mac App Store at first it believed that I already had Lion installed. After some searching through Google and forum posts I was able to figure out how to reset the Mac App Store and get Lion downloaded. The installer kicked off without any problems. This is when the proverbial shit hit the fan.

    I was greeted with a failure message that basically told me jack squat. My disk was corrupt and unable to be repaired by the Lion installation image (or the bundled Disk Utility program). This was a real problem. After some quick searching some fellow patrons suggested trying a repair installation with the original Snow Leopard installation disk. I tried this and was met with a little success – I was now greeted with a seemingly updated installer that included Safari and an updated version of Disk Utility. But to no avail was I able to actually get Lion installed on the disk. My laptop was effectively a brick.

    Since I was actually busy this weekend (riding the Monster around New Jersey) I decided that I would make an appointment to see the “Genius” bar at the heralded 5th Avenue Apple Store in New York City. This was a big mistake. Despite making the appointment an hour and a half ahead, arriving fifteen minutes before my appointment, it took them a full hour to actually see me. Not the best service thus far. The “Genius” that I met with was baffled at the problem claiming to never have seen the installation do this to a laptop. Great.

    What really complicated the matter was that I was using FileVault to encrypt my home directory just in case my laptop got stolen. If it wasn’t for this fact I would have merely copied all of my music, photos, and documents over from the directory to an intermediate storage device. After completing the re-installation of Lion I could copy it over and all is good. But, rightfully so, this was not the way to actually complete the measure.

    Now I am writing this without actually attempting to open up the encrypted sparsebundle that my data is stored in. I have a copy on an external drive that I mounted in the Lion installer, and copied over the files from the Terminal application. The actual Lion installation (after using Disk Utility to erase my main disk) went smoothly without a hitch. All of my applications were installed and ready to go after about an hour and a half.

    The only thing that remains right now is getting the sparsebundle mounted unencrypted so I can extract the data, and figuring out why my instructions for using a third party device to backup with Time Machine don’t work. It is looking like that Apple is requiring the use of AFP protocol for Time Machine backups. This won’t be too much of a problem as the open source netatalk solves this for all of you Linux users, but for people using an integrated device that runs a stripped down version of Linux it may be a little bit of a pain to get this on the device. Nevertheless, I am on the problem.

    Mar
    02

    Today was a very long day, and I expected tonight to be quite the norm lately (uneventful) but spending a little time tonight reflecting actually has turned out to be something, at least that I think, will make me better in the short term. The past couple of months have been a wild ride for many reasons (there really are many) stemming from relationships, to work and even friendships dwindling and being replaced by other, more important social relationships. I usually write my thoughts in a little black book that hopefully will be burnt in the not-so-distant future, but I’ve told myself lately in order to promote Type Aloud I need to do a little more to get people to be interested in the person behind the website, if that sounds like a crock of shit or not.

    One thing that I have not (ever, really) been afraid of is to state my opinion. I don’t pride myself in being an idiot; I know when to keep my mouth shut even when I shouldn’t, but I also know when people need to hear what I have to say. Just more lately the person on the other end of my verbal sparring tended to push back without realizing that I was merely giving advice and not trying to start World War III. There are just times in life that you need to hear the bitter, brutal, honest truth and sometimes you really only listen to it from people that you trust. There are other times that you are too stubborn to listen at all, and then you tend to get bitten in the ass.

    I have been called several names by people that do not really know me. Some people call me a nerd, a geek, very few people call me a genius, but I tend to hear the utterance of asshole more than all of them. I know that I can be an asshole if I want to be, but I believe that it boils down to people not quite understanding where I am coming from. My view on the world is quite abysmal; I am not what I would describe as religious person, and I generally do not really have any faith in the human race as a whole. Really, how could I? The world is full of death, famine, war and generally a bunch of unhappy people that are content with being exactly that: unhappy.

    If I am bothered by something I am damn well going to voice my opinion. Now, I am lucky enough to live in a part of the world where I am not going to be castrated for doing so, but even those around me tend to complain and bitch more often than not. My commute home from work I hear (and see) people that have given up on life. They are tired, hopeless, shell of human beings who go through the motions because they feel as-if there is nothing left for them to live for. This is the kind of shit that makes me sick. I think one of the only things I enjoyed about not being in the city landscape is that there are generally less people, and a smaller sample of people meant that you saw a less amount of unhappy souls.

    This is partially the reason why I started Type Aloud; some of the best memories I have are those where my nose was stuffed in some book. I can also admit that I did what most kids do and leafed through the pages until the end because I did not want to read the whole book if it bored me. Shit, I still do that with novels that I purchase because I realize three-quarters of the way through that it is a piece of crap. There is just a part of me that needs to know the ending of a story in order to sleep at night.

    For me, Type Aloud represents a place that all of these sad souls can come home and lose themselves for a few hours in reading. Despite the people in my life that are causing problems, think that I am an asshole, or otherwise have ill feelings towards me and mine: I always have the people who spend their time and effort writing their pains, wonders and dreams onto digital parchment. That’s the kind of life that I hope for.

    It has been a few weeks now since I launched the “unofficial” Type Aloud beta and I have been quietly working on improvements after having some good friends and family pound the site. My aim is to have announce a bigger and better version within the upcoming weeks (sooner, if possible) as I believe there are only a few kinks left to work out of the system. At this point I am going to take some time and actually write some content for the site and work on promoting this bad mamma jamma.

    This week’s work schedule includes:

    1. Getting the commenting system on stories and chapters working properly.
    2. Finalizing unpublished for stories and draft mode for chapters.
    3. ‘Report this story’ (and chapter) button for flagging either spam or inappropriate content.
    4. Fixing some minor style and navigation issues.

    Some longer term issues will be working on proper poem support as well as permissions on story and chapter viewing. I hope to have the beginnings of these worked out in the upcoming weeks after the unpublished, flagging and draft modes are completed. Some improvements that are in the pipeline but aren’t dated yet: user (crowd source) tagging and descriptions, badges and search.