FamousPhil.com -- Home My Calendar Youtube LinkedIn Facebook MySpace Twitter RSS Blog Feed

Blog Navigation

Partners

Latest Activity

Another way to stop the unwanted calls even when you’re on the Do Not Call list

Phil explains how to use the old telephone tones to wane off telemarketers!



Posted on: February 20th, 2012 by Famous Phil

About a month ago, I covered using MySQL in both PHP and Python briefly by posting two simple classes (code samples), you may view that post here.  Typically, I’m a more advanced user that has a lot of skills in systems administration, and unfortunately, I kind of overlooked how to get the functionality that my code exploits working correctly, so I’m going to take a step back (after a few private emailed questions) to explain how to get MySQL working with both PHP and Python in CentOS 6, which is my operating system of choice for serving PHP and Python applications.

I guess that I’ll start with PHP since it’s by far easier to get working.  Assuming that you’re using Yum (the default CentOS package manager), installing the package php-mysql (yum install php-mysql) should be sufficient in making all of the MySQL functionality work in PHP.  The Ubuntu package manager, apt-get, should have a similar installation package.  Any LAMP installation should install this package automatically (including Debian, Ubuntu, Suse, etc).  If you’re installing by source, you’ll need to install MySQL first (by source I’d assume), then compile PHP and Apache (or your web server of choice).  When compiling PHP from source, you’ll need the argument “—with-mysql” passed in as a parameter to the configure script.   I’ve linked the PHP Source Code for your convenience if you wish to go the source route (which I wouldn’t recommend personally).

Next up is Python’s MySQL connectivity.  Once again, you’re going to need at least the MySQL client installed on your local machine along with Python.  In CentOS (6, probably 5 and 4 also), you can do a “yum install mysql-client” to get MySQL’s client on the system.  I use the library called mysql-python.  MySQL for Python is linked for your convenience.  To install this library, visit the site (linked previously) and download the tar.gz file (currently MySQL-python-1.2.3.tar.gz), once you have that on the server, extract it using (tar xzf MySQL-python-1.2.3.tar.gz).  Inside the extracted archive, you’ll find several files, including a setup.py.  As root, simply run this executable with the install parameter: “python setup.py install”.  This will install the Python-MySQL library and my sample singleton class should now work.  As a tip, many Python related libraries use the setup.py executable in the same format.

I’m sure that I missed a lot of details, but this was merely to answer a few questions that I received through email, mostly about the Python-MySQL library.  Hopefully this post helps resolve these questions.

Tags: , ,
Posted in Hosting / Server Administration, Programming
|| 1 Comment »

Posted on: January 22nd, 2012 by Famous Phil

Its now time to become serious with my blog again after such a long lapse in real content.

When building new applications, it always seems like I start with the grand picture requiring no massive data storage and shortly after I begin, I find myself needing a database connection.  I’ve made the mistake several times now of not starting with a dedicated database class that connects to MySQL, and I always find myself googling for pre-made classes that don’t do exactly what I need, so I’ve decided to post my own for future reference.  As a result, I’m going to make sure that when I Google, I find my own reference before someone else’s :)  Hopefully this is useful to someone else.

PHP’s MySQL singleton class:

<?php
// Copyright (c) 2012 Philip Matuskiewicz www.famousphil.com

// To use:
// require_once("Mysql.php");
// $db = new Mysql();
class Mysql{
    private $server = "localhost";
    private $username = "";
    private $password = "";
    private $database_table = "";
    private static $instance;

    private function __construct(){
        $this->connect();
    }

    public function connect(){
        mysql_connect($this->server, $this->username, $this->password);
        mysql_select_db($this->database_table);
        $this->q("set names 'utf8'");
    }

    //query the database
    public function q($query){
        $r = mysql_query($query);
        return $r;
    }

    //returns an array containing all the rows that were returned
    public function qr($query){
        $r = $this->q($query);
        if (mysql_num_rows($r) > 0) {
            $res = array();
            while ($arr = mysql_fetch_array($r)) {
               array_push($res, $arr);
            }
            return $res;
        } else {
            return null;
        }
    }

    //number of rows returned
    public function nr($query){
        return mysql_num_rows($this->q($query));
    }

    //last inserted row id is returned
    public function lid(){
        return mysql_insert_id();
    }

    //close the database connection
    public function c(){
        mysql_close();
    }

    public static function singleton(){
        if (!isset(self::$instance)) {
            $c = __class__;
            self::$instance = new $c;
        }
        return self::$instance;
    }

    public function __clone(){
        trigger_error('no clone', E_USER_ERROR);
    }
}

?>

The Python MySQL singleton implementation is similar, but includes an external file named config.py in this example

--> config.py (configuration information for the MySQL class)
dbhost = "localhost";
dblogin = "";
dbpassword = "";
dbname = "";

--> MySQL.py (The MySQL class)
#!/usr/bin/env python
# Copyright (c) 2012 Philip Matuskiewicz www.famousphil.com

#to include / use, insert the following lines in the code
#import imp;
#mysql = imp.load_source("MySQLConnector", "PATH_TO_PYTHON_FILE/mysql.py").MySQLConnector();
#result = mysql.tryquery("Mysql Query Here");

import sys;
import os;
import string;
import base64;
import MySQLdb;#mysql library (you will need to install this on the system)

#MySQL Singleton Class
class MySQLConnector(object):
        _connection = None;
        _instance = None;

        def __init__(self):
                try:
                        if MySQLConnector._instance == None:
                                MySQLConnector._instance = self;
                                MySQLConnector._instance.connect();
                except Exception, e:
                        print "MySQL Error "+str(e);

        def instance(self):
                return MySQLConnector._instance;

        def get_connection(self):
                return MySQLConnector._connection;

        def connect(self, debug=False):
                try:
                        for line in open('includes/config.py'):
                                #this can be dangerous, but sources / executes lines in config.py, which contains the db info
                                #alternatively, you can just set the variables here manually
                                exec('%s = %s' % tuple(line.split('=', 1)));
                        MySQLConnector._connection = MySQLdb.connect(dbhost, dblogin, dbpassword, dbname);
                        if debug:
                                print "INFO: Database connection successfully established";
                except Exception, e:
                        print "ERROR: MySQL Connection Couldn't be created... Fatal Error! "+str(e);
                        sys.exit();

        def disconnect(self):
                try:
                        MySQLConnector._connection.close();
                except:
                        pass;#connection not open

        #returns escaped data for insertion into mysql
        def esc(self, esc):
                return MySQLdb.escape_string(str(esc));

        #query with no result returned
        def query(self, sql):
                cur = MySQLConnector._connection.cursor();
                return cur.execute(sql);

        def tryquery(self, sql):
                try:
                        cur = MySQLConnector._connection.cursor();
                        return cur.execute(sql);
                except:
                        return False;

        #inserts and returns the inserted row id (last row id in PHP version)
        def insert(self, sql):
                cur = MySQLConnector._connection.cursor();
                cur.execute(sql);
                return self._connection.insert_id();

        def tryinsert(self, sql):
                try:
                        cur = MySQLConnector._connection.cursor();
                        cur.execute(sql);
                        return self._connection.insert_id();
                except:
                        return -1;

        #returns the first item of data
        def queryrow(self, sql):
                cur = MySQLConnector._connection.cursor();
                cur.execute(sql);
                return cur.fetchone();

        #returns a list of data (array)
        def queryrows(self, sql):
                cur = MySQLConnector._connection.cursor();
                cur.execute(sql);
                return cur.fetchmany();

#end class MySQLConnector

Tags: , , , ,
Posted in Programming, Technology
|| 2 Comments »

Posted on: November 13th, 2011 by Famous Phil

It has been some time since my last post, and I think this is going to be the norm for at least the next year, sadly.  Today’s topic is based on information that I needed about IMAP (Internet Message Access Protocol) last week. Basically, I’m developing an application for conceptual.ly that allows for normal users to enter their login information for their email and then the application will unsubscribe them from internet mailing lists that people often dislike, yet get plentiful email from.  Since the solution is completely artificial (and requires no human intervention), it exceeds what others have done in the past.

Unfortunately, computers are not able to think and identify patterns without a lot of help and special cases already entered into databases for them to compare against.  Thankfully, emailing lists have certain unique identifiers that allow this application to effectively identify and remove users from mailing lists, although I will not disclose exactly how it is done since that research was done on company time and therefore remains property of Conceptual.ly.  But I did want to take the time to publish a cheat sheet for those of you who need to communicate with IMAP servers via telnet.

CONNECTING: The general command to telnet to an insecure IMAP server is “telnet imap.server.com 143”, remembering that IMAP runs on port 143.  If you’d like to connect through IMAPS over port 993, your computer will need OpenSSL and the command to do so is “openssl s_client -connect imap.server.com:993”.  OpenSSL will take care of all the connection securing / establishing for you, the commands following the initial connection are exactly the same.

IDENTIFIERS: IMAP commands start with an identifier, I’ve seen “. “ as the identifier (a dot followed by a space) and I’ve also seen “a1 “ (a1 followed by a space) as the identifier.  I’ve also seen incrementing the 1 to 2, 3, etc work, and reading the RFC was not specific to what had to be used.  I typically use “. “ as my identifier and fall back to using a1 for all of the commands I enter, it has worked for every IMAP implementation I’ve dealt with thus far (including Gmail, Dovecot, AOL, and Exchange).

LOGIN: To login to the IMAP server, you need to enter the identifier followed by “login username password” replacing username and password with the appropriate login information.  Note that your username may be your email address.

LIST: This command is typically followed by a login and lists all of the available mailboxes in the IMAP account.  The syntax for this command is list “” “*”  which simply gets all of the mailboxes and subfolders.  The usual response is * LIST (\HasNoChildren) “.” “INBOX” which can easily be parsed, the \HasNoChildren can change if there are children.  Usually with children, the output will make the actual folder (the last segment of the output) contain the parent and a . so that you can simply use this to formulate a connection to a specific folder to retrieve messages, etc.  This isn’t always the case, so it is helpful to use IMAP over telnet to verify the response of the command for the specific IMAP server that you are connecting to.

STATUS: This command will return information about the folder you inquire about, I’ve only seen it return the total messages and unread messages in a folder in my experiences.  The syntax of this command is “STATUS FOLDER (flags which are optional)”.

SELECT: In order to search or retrieve items from a folder, you must first select that folder.  The syntax of this command is “SELECT FOLDER”.

SEARCH: This command has some ambiguity that caused me some difficulty that I will get to shortly.  The syntax for search is “SEARCH (PARAMS)”.  The parameters are identified in the RFC3501, but there are some specifics I’d like to talk about.  First, I’ve found that SENTSINCE does not need to be in (), instead you would do “SEARCH SENTSINCE 01-01-11 (PARAMS)”.  Next, if you want to search for more than 2 items using the OR syntax, you would need to use nested ORs, this might look like the following: “(OR (OR HEADER From yahoo.com BODY hello) BODY phil)” to search for a message that might be from yahoo.com (partial match) with the body containing hello, or just having “phil” in the body.  This works similarly for the AND parameter.  When search returns, it returns a space separated array of numbers which are identifiers for the FETCH command.  Remember that to search, you have to SELECT the folder to search first.

FETCH: This command will retrieve messages from a folder, you must have selected that folder first before you can retrieve a message.  Typically, messages are identified by a number which the FETCH command uses, so a SEARCH is generally executed before fetching messages.  The syntax is “IDENTIFIER FETCH (PARAMS)”.  IDENTIFIER is the number that search returned, and there are numerous PARAMS that you can do.  I’ve seen (RFC822) work at grabbing the entire raw message source (both headers and body), but in AOL’s implementation it does not, so I’ve reverted back to getting the header and body of each message through 2 fetches, the first parameter is (RFC822.HEADER) and the second is (RFC822.TEXT).  I do not believe that IMAP servers return a decoded version of the message in all cases, so I also used an email parsing engine in Python to decode the message source that these commands returned.

LOGOUT: The syntax for this command is “LOGOUT”.  It simply disconnects you properly from the IMAP server.

For the needs of my program, these were all the commands I needed, so I’d strongly suggest that you look at RFC 3501 at http://tools.ietf.org/html/rfc3501 for more information about the IMAP protocol and its usage.

I would also like to note that GMail has added commands to their implementation that better follow the speed and reliability of their web interface, those commands can be found at http://code.google.com/apis/gmail/imap/ (this was kind of hidden from my initial searches for information about GMail’s IMAP implementation, so I wanted to make this more visible).  If you use standard IMAP commands on Gmail, you can expect it to be much slower than other IMAP servers and much slower than their web interface.

Finally, AOL’s IMAP implementation doesn’t allow searching certain header fields and the body of the message, so I’d recommend testing your commands ahead of time to ensure you are getting responses that you expect.  As a tradeoff, AOL’s IMAP implementation is very fast at returning messages via the FETCH command, so where the SEARCH lacks ability on AOL’s IMAP server, the speed in downloading messages far makes up for this lack of functionality.  It is also possible that AOL’s IMAP implementation has certain extensions that I didn’t notice, so you may want to look into that possibility also if you’re dealing with their IMAP servers.

Hopefully this blog post can help someone save time so that they don’t have to do as much searching as I had to for connecting to IMAP servers.

Tags: , , , , ,
Posted in Programming, Technology
|| No Comments »

Posted on: July 2nd, 2011 by Famous Phil

Last night, I was tasked with moving 25,000 files (3GB worth) between two of my Linux systems.  Traditionally, I use tar and gunzip (tar czf file.tar.gz directory/) to archive files for network transfer, but for whatever reason, I used the zip utility that is bundled with most Linux distributions (zip -r file.zip directory/).

The zip process went through fine and created a zip archive of the directory, but this is because the zip was done on a 64 bit build of CentOS Linux (where zip is compiled for large file support).  I transferred the archive to the destination server (32 bit build of CentOS Linux).  As any decent admin does, I verified that the checksum (openssl md5 file.zip) matched on both ends (to check for corruption).  The md5 checksums matched, so I proceeded to unzip the file (unzip file.zip).  Below is the error I received:

End-of-central-directory signature not found. Either this file is nota zipfile, or it constitutes one disk of a multi-part archive. In the latter case the central directory and zipfile comment will be found on the last disk(s) of this archive.

unzip: cannot find zipfile directory in one of file.zip or
file.zip.zip, and cannot find file.zip.ZIP, period.

It turns out that the 32 bit version of CentOS includes the zip utility that isn’t compiled with large file support.  To rectify this, we must download the zip source code and recompile with large file support.  The instructions that I used are at http://www.stevenbarre.com/blog/2007/03/04/how-to-unzip-large-files-greater-than-2-gb/

1. install zlib and zlib_devel using yum if you don’t already have them.

2. Download the source code of unzip from http://www.info-zip.org/.

wget http://sourceforge.net/projects/infozip/files/UnZip%205.x%20and%20earlier/5.52/unzip552.tar.gz/download

3. Extract the source code and move the appropriate make file to the main directory

tar xzf unzip552.tar.gz
cd unzip-5.52/
mv unix/Makefile ./

4. Modify the MakeFile to enable large file support

Find:

CF="-O3 -Wall -I. -DASM_CRC $(LOC)"

Replace With:

CF="-O3 -Wall -I. -DASM_CRC -DLARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 $(LOC)"

5. Compile unzip

make linux

6. Use the executable unzip to extract file.zip

#assume file.zip is at /root/test/file.zip
mv unzip /root/test
cd ..
#clean up the directory, remove unzip's source code
rm -Rf unzip-5.52
rm unzip552.tar.gz
#unzip the file
cd /root/test
./unzip file.zip

Tags: , , , , ,
Posted in Hosting / Server Administration, Programming, Technology
|| No Comments »

Posted on: July 1st, 2011 by Famous Phil

Often times, I find myself working in a remote Linux terminal window. The other day, I had the need to share what I was doing with a friend, but I didn’t want to share my entire local desktop because sharing a full desktop is slow and laggy. So I quickly looked into sharing a screen session with him so he’d only see the command line window that I was in, and I know I will need it again, so its going up here.  For those of you who have a Mac or Linux, you might know that you can have multiple desktops and go through them by some key combination (usually ctrl-alt-arrow).  In a very simplified nutshell, screen basically allows for the user to exploit multiple desktops.

Here is how you share a screen session:

#User 1, initiator of the screen session
screen -R sessionName

#User 2, connecting to an existing session
screen -x -R sessionName

The -R flag means try to reattach to an existing session, if the existing session does not exist, create a new session and attach to that.  The -x flag means to connect to an already attached session, which allows for session sharing.

I ran into a problem as a non-root user (that I normally run as) when I first started using shared screen sessions.  The error is as follows:

Cannot open your terminal '/dev/pts/0' - please check.

There are several terminal devices that screen can use under the /dev/pts directory, starting with 0.  Only root can traditionally access these terminal devices, therefore, we need to modify each necessary device to allow normal users access.  I didn’t research the security implications that the following fix has, so use this at your own risk.  The server that I was using has only trusted users on it, so I was not concerned about possible risks.

#run this as root, or as sudo
#this gives others read and write access to the device
chmod o+rw /dev/pts/0

Finally, up until last week, I could never get myself out of a screen session safely without completely closing my putty terminal window.  Here is the proper key sequence to detach from a screen session.

ctrl-A  followed by  ctrl-D

To terminate a session in screen, simply type exit.

Tags: , , ,
Posted in Hosting / Server Administration, Programming, Technology
|| 1 Comment »

Posted on: June 13th, 2011 by Famous Phil

I bring you a guest post from Jason who is associated with the subtext project which is a blog written in ASP.net!  Disclaimer… I do not guarantee (or verify) the accuracy of guest posts.

A webmaster has many things to think about from choosing the right host to making sure everything is running smoothly on the backend servers. Fortunately, different tools, applications and developments exist that can help us simplify the process of running a website. Subtext skins can help designers more effectively and efficiently create the styles used for personal blogs on their website.

While you can always decrease your workload by choosing options like managed hosting, if you are responsible for web design then you should look into the many advantages of Subtext skins for blogging.

What is a Subtext skin?
Subtext is a blogging platform offered as open source software under the BSD license. The whole concept behind Subtext was to create a very simplified blogging engine that allows bloggers to concentrate on creating actual blog content rather than trying to figure out how to use the blogging software.

Almost all websites these days have their own blogs. In addition, many sites offer blogging as a service to their users who can sign up to create their own personal blogs. You can use Subtext both for the site’s own blog and to offer blogs to site members.

A Subtext skin refers to the styling and layout of the blog page. Skins are versatile as they allow you to create page formats and designs without coding from scratch. A Subtext skin is actually made up of five separate style sheets that can be used to format different elements on the page like divs, spans, boxes, headers, footers, sidebars and forms.

The five style sheets used for each Subtext skin are:

• style.css – the default style sheet that determines the basic underlying skin layout.
• secondary style sheet – this file handles the specific Stylesheet attribute of the skin. The secondary style sheet is generally used to create styling contrasts over the style.css file. For example, the web designer may choose to give the header a different border than the sidebars where in the style.css file they use the same border.
• custom.css – this style sheet is used for custom design features set by the blog author. Primarily used to set styles and layout for personal badges or for the actual post content.
• non-attribute css files – generally used for CSS frameworks or for system styles.
• css files with limited attributes – these stylesheets have a title and media attribute, and cannot be merged with other css files. The attributes specify IE version compatibility and that they are applicable only in screen mode or in printing mode.

Packaged and custom Subtext skins
Web designers can choose from a large library of pre-designed skins or they can create their own custom skins. Creating a custom Subtext skin requires some basic knowledge of CSS scripting and also learning the basic Subtext parsing rules.

Fortunately, Subtext is highly simplified to allow users to quickly master the underlying script.

Skin templates are folders that can be used to render different Subtext skins. Each folder actually contains a number of skins that are related in certain attributes and themes. The folders or templates have their own series of controls that are used to render a skin in that template along with associated style sheets.

Once you have a library of packaged and/or custom skins, you will be able to style blogs quickly after learning how to tweak the skins and templates.

Instead of racking your brain each time you need to come up with a new design, you can simply browse through your selection of Subtext skins. Each skin can be modified according to the primary and secondary CSS files associated with the skin. You can easily find the types of skins you are looking for because they will be arranged in skin templates or families according to related attributes. For example, you can have a Rainbow template. a Geometric template and an Origami template – each having multiple skins that express the same theme. The number of templates is only limited by your imagination and willingness to create custom skins.

When using the Subtext blogging software, the skin templates are arranged in folders in an easy to manage directory system. The setup makes it simple to find the skin you are looking for and simply click on the selection to implement it on the Subtext blog.

By using Subtext skins, you can save time and energy creating page designs and layouts for multiple blogs. No need to code style sheets from scratch when you can access an easy-to-use Subtext skin library and quickly find what you need.

Each skin will handle the styling and layout of all page elements including headers, footers, sidebars, text format, boxes and forms.

You can find out more about Subtext and skins at the Subtext Project Site: http://www.subtextproject.com/.

Tags: , , , , , ,
Posted in Hosting / Server Administration, Programming, Student Life, Technology
|| 3 Comments »

Posted on: June 11th, 2011 by Famous Phil

Here is a relatively short blog for a change!  A client came to me today to have PDFLib installed onto the Matthouse CPanel server.  PDFLib allows you to create PDF files programatically (in this case, PHP), so I can see a lot of uses for this extension.  As expected, CPanel wasn’t able to install this extension through PECL without a little help, so below is the procedure that I used.

#get latest pdflib lite 7 from http://www.pdflib.com/download/
#http://www.pdflib.com/download/pdflib-family/pdflib-lite-7/

cd ~
wget http://www.pdflib.com/binaries/PDFlib/705/PDFlib-Lite-7.0.5.tar.gz
tar xzf PDFlib-Lite-7.0.5.tar.gz
cd PDFlib-Lite-7.0.5
#java isn't installed on the server, compile without java
./configure --prefix=/usr/local/pdflib --without-java
make
make install
pecl install pdflib 
#when asked for a path, enter "/usr/local/pdflib" then hit <enter>

I opted to install the lite version of PDFLib since its free and my client didn’t need all of the features that the program includes.  I installed pdflib to its own directory that isn’t included in path since I don’t anticipate anyone actually using this via other languages on the server (besides PHP).  Once PDFLib is installed, we will need to use the command line (as root) to install the pecl extension and tell it where to find the compiled version of pdflib.  Note that CPanel’s PECL installer will not be able to install this extension since there is no way to enter the path (and I’d prefer to not add this to the global PATH variable on my server).  The extension is now installed, in order to test the extension, make a PHP file for the below code and execute it in a web browser, you should see “Hello World” as a PDF document.

<?php

try {
$p = new PDFlib();

/*  open new PDF file; insert a file name to create the PDF on disk */
if ($p->begin_document("", "") == 0) {
die("Error: " . $p->get_errmsg());
}

$p->set_info("Creator", "hello.php");
$p->set_info("Author", "AUTHOR");
$p->set_info("Title", "Hello world (PHP)!");

$p->begin_page_ext(595, 842, "");

$font = $p->load_font("Helvetica-Bold", "winansi", "");

$p->setfont($font, 24.0);
$p->set_text_pos(50, 700);
$p->show("Hello world!");
//$p->continue_text("continue text");
$p->end_page_ext("");

$p->end_document("");

$buf = $p->get_buffer();
$len = strlen($buf);

header("Content-type: application/pdf");
header("Content-Length: $len");
header("Content-Disposition: inline; filename=hello.pdf");
print $buf;
}
catch (PDFlibException $e) {
die("PDFlib exception occurred in hello sample:n". $e->get_errnum() ." " . $e->get_apiname() . " : " .$e->get_errmsg() . "nn");
}
catch (Exception $e) {
die($e);
}
$p = 0;
?>

Source: I used the guide at http://www.supportfacility.com/blog/cpanel/install-pdflib-php-on-cpanel-dedicated-server/ to write an updated version for my blog.  I’d like to thank them for blogging about this topic!

Tags: , , , ,
Posted in Hosting / Server Administration, Programming
|| 3 Comments »

Posted on: June 7th, 2011 by Famous Phil

I’m willing to bet that someone who reads my blog thinks that I forgot about the 2nd part of my original blog post (Installing Hadoop, Located here).  If you thought that I forgot, think again!  Just as a recap, I left off with a fully functional installation of Hadoop and Eclipse support on my last blog.  The goal of this blog is to implement and run Dijkstra’s shortest path algorithm on the local Hadoop installation.

Dijkstra’s algorithm is a solution to the shortest path problem in graph theory.  Given several vertices (or nodes) and several edges (or arcs), find the shortest path (or the least amount of vertices to traverse across) from a starting node to an ending node.  My goal is to solve the presented problem (below) from nodes 1 and 5.  Intuition says that the shortest path length is 2 using node 2 as a hop.  Below is a picture of a sample graph that I will have my Hadoop installation solve.

Dijkstra Graph Example Input

Dijkstra Graph Example Input

Read the rest of this entry »

Tags: , , , ,
Posted in Programming
|| 5 Comments »

Posted on: June 3rd, 2011 by Famous Phil

There are many reasons why you might be reading this post, but likely, you’re trying to figure out how to install this complex heap of code (that has its root node removed, no doubt, ha ha).  If you didn’t get my last joke, I feel sorry for you, but the show must go on.

Gitorious is an open source repository management system similar to Trac on SVN.  The software looks really nice (gitorious.org), and it has a lot of built in features for managing git repositories.  For those of you who are not familiar with coding, code repositories are often set up to enable many coders to work on the same project simultaneously (different portions of course).  Repositories also enable versioning so that you can easily revert to an older copy of your code base if something breaks along the way.  Repositories are often centralized so that only a single location has to be backed up, in this case Gitorious centralizes git repositories.

Truthfully, there are three memorable software programs that have been notoriously difficult to install and configure in my experience, these are as follows:

  • Shibboleth- I never did successfully install this myself, this was because I was asked to help a friend install it over the phone.  I don’t work well when I can’t see the problem and play with stuff, I test hunches, and doing it with this method would have taken way too long.  From what I’ve seen of Shibboleth, I would rate this as worst of the worst programs to install.
  • Gitorious – This is probably the second worst application I’ve ever installed.  It required a lot of research and resources since it is poorly documented and requires a lot of Ruby Gems to operate successfully.  Of course, I will hopefully document it a little more today!
  • Exchange – I wish I would have documented the install of my Exchange server internally so I could have shared it here.  Exchange isn’t awful to install, but the configuration of Exchange is very tricky and there are many gotchas.  This is why I place it as the best of the worst software programs to install.

With all of the above said, the installation process of gitorious isn’t for the leisure system administrator to install.  This took me approximately 3 days of research to successfully install and understand.  I installed it on a separate system only because I didn’t want it hurting any of my existing production systems.  In the end, I’m glad I did this because I learned that Ruby isn’t very memory efficient and this application easily eats up most of the 1GB of ram allocated to it in a VPS (Virtual Private Server).  And with this said, I invite you to continue reading if you really want to know how to install this software.

Update 6/14: After a few requests, I’ve decided that I will provide a Gitorious installation service on your CentOS server.  I will be happy to install Gitorious and make it work (as described below) for a one time paypal payment of $100.  For details, contact me directly (see my contact page).

LAST UPDATE: 6/8/2011 – Suggestions from Gitorious Discussion Group

Read the rest of this entry »

Tags: , , , , ,
Posted in Hosting / Server Administration, My Site, Programming, Technology
|| 33 Comments »

Posted on: May 31st, 2011 by Famous Phil

I’m still working on other blogs for my site, but my other projects have sort of been put on hold because I don’t have all the information / tools / research I need to write them.  So today I thought I’d write a short reference on .htaccess redirects for a problem I started researching yesterday and failed to get a quick answer to.

Using .htaccess, I wanted to force a website URL to always goto https://www..com no matter what part of the URL was entered.  In order to do this, simply create a .htaccess in the main www / public_html directory of your website (files with a . preceeding them are hidden files in Linux and aren’t served by Apache).  The code that can be placed in the file is (Replace with your website):

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://www.<DOMAIN>.com/$1 [R=301,L]
RewriteCond %{HTTP_HOST} !^www.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]

All .htaccess files start with turning the RewriteEngine on.

RewriteCond is similar to an if statement, if the condition is true, run the next line.   With that said, the second line checks to see if the website is being access via SSL  / HTTPS (secure method).  If it isn’t, the third rule takes whatever the url is and changes it to https://www..com/? where ? is any trailing information that was attached to the original non-SSL URL.  R means return a Redirect status code to the client’s browser, 301 is a permanent redirect, meaning the page was permanently moved.  If you change this to 302, it means the page was moved temporarily.  This status code helps for SEO on websites (Search Engine Optimization).  The L is “Last Rule” and this tells Apache to stop processing rules in the .htaccess file for the current page load.  The fourth line checks to see if the URL doesn’t have a www in front of the domain, if www doesn’t exist, the fifth rule adds the www.

Today was interesting because I didn’t know the 301 and 302 status codes off the top of my head, but now I have a good self-reference for the future :)  That is all I have for now.  Hopefully I can get some Hadoop code posted in the near future that I promised a few blogs ago!

Tags: , , , ,
Posted in Hosting / Server Administration, Programming, Technology
|| No Comments »