Migrate Post From One WordPress Database To Another

Internet No Comments

I made a mistake and posted a blog entry to the wrong WordPress website. A comment was made before I could manually delete and post it to the other website. While I could just lose that comment, I decided it would be interesting to see if I could manually migrate the post content (with comments) directly from one WordPress MySQL database to the other.

After looking at the WordPress database schema, I found that I only needed to pull data from two tables and modify a few column values.

These are the essentials to keep in mind when migrating a post:

  • The two “wp_posts” and “wp_comments” tables contain the data we need to migrate.
  • For “wp_posts”, we need to modify columns “ID”, “post_author” (foreign key to “wp_users” table), and “guid”.
  • For “wp_comments”, we need to modify columns “comment_ID”, “comment_post_ID”, and “comment_parent” (references “comment_ID” for replies).
  • We can ignore tables “wp_postmeta” (contains edit lock info) and “wp_commentmeta” (contains Akismet approval data).
  • No need to deal with categories and tags (kept in “wp_term_taxonomy”, “wp_termmeta”, and “wp_terms” tables). We can manually set category (from the default “Uncategorized”) and insert tags after the migration.
  • Image links in the post will point back at the old WordPress site, so we will need to add the images to the new WordPress site and update the image URLs accordingly.

Before we start, make sure that both the WordPress websites are updated to the same version. (My websites are using the latest WordPress version 4.9.7.)

Read Post From Old WordPress Database

Identify the post identifier that you wish to move. If you click on your post header, the URL will change to include the identifier. For example, my URL is “https://www.chanhvuong.com/3048/how-to-sell-a-used-computer-like-a-car-salesman/” and the post identifier is 3048.

# SSH into your server and log into MySQL.
mysql -u root -p
    # Input your MySQL root password if it is not blank

# Select the <database_name> to read from.
mysql> use <database_name>;

# By default, MySQL is configured to only support reading/writing files from a "mysql-files" directory.
# You could remove this requirement, but I decided to just make use it.
mysql> show variables like 'secure_file_priv';
| Variable_name    | Value                 |
| secure_file_priv | /var/lib/mysql-files/ |

# Output the post content matching <post_id> to a file.
mysql> select * from wp_posts where ID=<post_id> into outfile '/var/lib/mysql-files/post.txt';

# Output the post comments matching <post_id> to a file.
mysql> select * from wp_comments where comment_post_ID=<post_id> into outfile '/var/lib/mysql-files/comments.txt';

Insert Post Into New WordPress Database

While we could modify the column data in the output files, I decided to do manual overwrites when importing. (You will need to be the root user in order to access “/var/lib/mysql-files/” directory.)

# Select the <other_database_name> to write to.
mysql> use <other_database_name>;

# WordPress orders posts by publish date so insert using next auto-increment post id.
# You'll need this to modify the "guid" string below.
mysql> select max(ID)+1 from wp_posts;

# Find a user ID to use as the "post_author".
mysql> select ID,user_login,display_name from wp_users;

# Insert the post into the other database.
# Set ID as NULL so the next auto-increment value will be used.
# Select existing <my_user_id> as post_author.
# Update guid with other WordPress domain and the next auto-increment post id.
mysql> load data infile '/var/lib/mysql-files/post.txt' into table wp_posts set ID=NULL, post_author=<my_user_id>, guid="http://www.<other_domain>.com/?p=<auto_incremended_post_id>";

Inserting comments is problematic because reply comments require the identifier for the parent comment, which doesn’t exist yet.

One solution is to lookup the next auto-incremented comment ID and then edit the “comments.txt” outfile accordingly before importing. However, because my website is active, some comments could be inserted before I do the import, making all the identifiers in the outfile invalid.

The second solution, which I chose, is to import the comments and then manually fix the “comment_parent” identifiers (and the “user_id” which is nonzero for users in “wp_users”).

# Insert the comments into the other database.
# Set comment_ID as NULL so the next auto-increment value will be used.
# Set the comment_post_ID to be our <auto_incremented_post_id> from above.
mysql> load data infile '/var/lib/mysql-files/comments.txt' into table wp_comments set comment_ID=NULL, comment_post_ID=<auto_incremented_post_id>;

# Lookup the newly-inserted comments.
mysql> select comment_ID,comment_author,comment_author_email,comment_parent,user_id from wp_comments where comment_post_ID=<auto_incremented_post_id>;

# Update comment_parent to the correct comment_ID (replace 472365 and 472366 below accordingly).
mysql> update wp_comments set comment_parent=472365 where comment_ID=472366;

# Update user_id for reply comments made by you (replace <my_user_id> and 472366 below accordingly).
mysql> update wp_comments set user_id=<my_user_id> where comment_ID=472366;

Fix Category, Tags, and Images

The post and comments should now be visible on your other WordPress website. You can set the post’s category and tags using the normal editing process. And add any images and update the image URLs in the post body accordingly.

Once you’re confident that the post is displayed correctly, you can delete its duplicate (and related images) from the old WordPress website. Also, you can delete the no longer necessary outfiles from the “/var/lib/mysql-files” directory.

And finally, for completeness, set a redirection from the old post URL to the new post URL.

Some info above gotten from:

No Comments

Split One WordPress Blog Into Two

Internet No Comments

When I started my Do It Scared! blog (later moved to Do The Void), I did not have in mind any goal beyond sharing technical knowledge and random thoughts. As I’ve written more content, I’ve come to realize that my posts split into two very different camps, technical how-to instructions and non-technical realizations about life. One of my non-technical friends told me a while ago, “I enjoy reading your blog except for the stuff that I have no idea what you are talking about.” My blog had become schizophrenic.

spideywebheadThe cure I’ve implemented is to split the blog into two different blogs, one technical and the other non-technical. Readers can focus on one or the other, without getting distracted. Because I’m certain that this is not a rare problem for a blog creator to have, I’ve documented what I’ve done to separate my blog into two.

A Domain By Any Other Name

Choosing a second domain name is probably the toughest step because a good domain name is hard to come up with and when you do, the chances of it being available are very low. However, there is hope because not all domain names are taken. You might just luck out or come up with something so unique that no one else has thought about it before (and had been willing to register it).

I suggest first deciding which content you want to keep under the old domain name and which content you wish to move to the new domain name. The nature of the latter’s content will help you to come up with an appropriate new domain name. I’ve decided to keep the non-technical content at the old domain and move the technical content to the new domain. Because I know the new domain is technical, I could try to come up with a nerdy domain name.

If you don’t have a preference for where each content should go after splitting the content into two, you may wish to keep the larger half at the old domain and move the smaller half to the new domain. This will reduce the effort required later to create redirects from the old domain to the new. Unfortunately, I’ve decided to move the technical content, the much larger half of my blog, to a new domain.

Being dissatisfied with all the potential, available new domain names that I came up with for my technical content, I’ve decided to put the technical content under an existing domain name that I had registered previously; this domain name is composed of my full name.

Attack of the WordPress Clones

To start the move, I’ve duplicated the WordPress content from the old domain to the new domain. This involved copying the Nginx site configuration file, WordPress source files and the WordPress MySQL database, and then making minor modifications. The instructions below were performed on my unmanaged virtual private server.

Note: To keep things consistent, I’ve always taken care to name the Nginx www directory, Nginx domain server configuration file, MySQL database name and username the same as the domain name. The instructions below will reflect this naming convention. Please adjust to match your own custom names accordingly.

Once the new domain name is registered and the DNS records are updated, we can configure Nginx to serve the new domain by doing the following:

# Copy the Nginx site config file
sudo cp /etc/nginx/sites-available/olddomain /etc/nginx/sites-available/newdomain

# Edit the new Nginx config file
sudo nano /etc/nginx/sites-available/newdomain
    # Update file location and server name
    root /var/www/newdomain;
    server_name newdomain.com www.newdomain.com

# Enable the new Nginx domain
sudo ln -s /etc/nginx/sites-available/newdomain /etc/nginx/sites-enabled/newdomain

# Copy WordPress code from the old domain to new domain
sudo mkdir /var/www/newdomain
sudo cp -r /var/www/olddomain /var/www/newdomain

# Adjust permissions for the new domain directory
sudo chown -R www-data:www-data /var/www/newdomain
sudo chmod -R g+w /var/www/newdomain

# Update the new domain WordPress configuration
sudo nano /var/www/newdomain/wp-config.php
    # Update database, user, and password variables.
    define('DB_NAME', 'newdomain');
    define('DB_USER', 'newdomain');
    define('DB_PASSWORD', 'newdomain_password');

# Reload the Nginx server to make the changes effective
sudo service nginx reload

Create the new domain’s WordPress MySQL database and user:

# Open a MySQL interactive command shell
mysql -u root -p

# Create MySQL WordPress database for new domain blog
mysql> create database newdomain;

# Create MySQL user and password
mysql> create user newdomain@localhost;
mysql> set password for newdomain@localhost = PASSWORD('newdomain_password');

# Grant the MySQL user full privileges on the WordPress database
mysql> grant all privileges on newdomain.* to newdomain@localhost identified by 'newdomain_password';

# Make the privilege changes effective
mysql> flush privileges;

# Exit the MySQL interactive shell
mysql> quit

The old domain’s WordPress database may contain URL references (to the old domain) and directory references (to the old domain directory). Because I’ve named the old domain directory the same as the old domain name (and likewise for the new domain), modifying the old WordPress database for the new domain requires a simple text replacement. A global search and replacement of the old domain name with the new domain name fixes all the URL and directory references.

# Export the old domain's WordPress database
mysqldump -u[olddomain] -p[mypassword] olddomain > /tmp/olddomain_modified.sql

# Use your favorite editor to search and replace all olddomain matches with newdomain
# Below is an example using the vi editor to do a global string replace
sudo vi /tmp/olddomain_modified.sql

# Import the modified WordPress database into the new domain's WordPress database
mysql -u newdomain -p[mypassword] newdomain < /tmp/olddomain_modified.sql

At this point, you should be able to browse to the new domain address to see an identical copy of your old domain’s blog.

Note: If your WordPress uses embedded code (like Google Analytics) or WordPress plugins that contain references to the old domain name (like Google FeedBurner), you will want to update them manually to use the new domain name.

Posts Not Here!

To ensure that external links to my old domain’s blog will continue to work, I need to create redirects from the old domain to the new domain for the posts that have been moved. To do so, I recommend using the WordPress Redirection plugin. It is a simple plugin that supports regular expression matching and keeps a history of the number of redirects that occur (very useful to record which URLs are being redirected).

My old website’s permalink format looks like the below. Many variations of it are also allowed.

# Permalink format

# Allowed variations include just the post_id

# Also allowed is removal of the ending forward-slash

In addition, the post title doesn’t matter because the title could be incorrect and WordPress will pull up the correct post using the post identifier. Because we need to redirect any of these variations, regular expression matching is required.

An example regular expression matching a URL like “/olddomain.com/314/the-value-of-pie/” and its variations would be:


Note: The “olddomain.com” is dropped when doing URL matching, so the actual match is against “/314/the-value-of-pie/”.

Here’s a very brief explanation of the regular expression above.

  • The first caret “^” character says to match starting with the beginning of the string. The last dollar sign “$” character says to match to the end of the string.
  • The “/314” means that the beginning of the string should match that sequence exactly.
  • The parenthesis and vertical bar combination “( | )” creates a logical OR construct.
  • The first alternative “(|” means that nothing follows ‘/314’. This alternative would match a URL like “/domain.com/314” exactly.
  • The second alternative “|/.*)$” means that there should be a forward-slash “/” followed by zero or more number of any characters “.*” until the end “$”. This would match URLs like “/domain.com/314/”, “/domain/314/blah”, “/domain/314/blah/”, “/domain/314/blah/blah/”, and of course, “/domain.com/314/the-value-of-pie/”.

Create a URL redirect using the Redirection plugin.

  1. Install and activate the WordPress Redirection plugin on the old domain.
  2. Go to the Redirection plugin’s Settings (also found under menu Tools->Redirection).
  3. Click on the “Redirects” section.
  4. In the “Add new redirection” form at the bottom, input the matching regular expression into the “Source URL”, check the “Regular expression” checkbox, and input the new domain target in the “Target URL”.
  5. Click the “Add Redirection” button when done.
  6. Repeat the steps for each post that will be moved to the new domain.


The Redirection plugin will create a 301 permanent redirect. When encountering 301 redirects, browsers will cache the resulting redirected URLs. Search engines may also update their records accordingly. If you are just experimenting, I recommend editing the redirect (under the Redirection Settings, click on the redirect item, select Edit, and click on the empty square under “Source URL” to expand the set of available options) and choosing “307 – Temporary Redirect” in the “HTTP Code” field.

Besides the permalink format, WordPress accepts this default query format, “/olddomain.com/?p=post_id”. Unfortunately, the Redirection plugin does not support this format for redirects. I looked at some other redirect plugins but they require that the original posts be kept on the old domain’s WordPress because they use an extended post property to perform the redirect. Because I wish to delete the moved posts, I cannot use any of the existing WordPress redirect plugins to redirect the query formatted URLs. However, because external websites should only use the permalink format when referencing my old blog, I don’t actually need to redirect the query format.

Nginx Rewrites

As an alternative to the WordPress Redirection plugin, Nginx rewrite directives can be used. The advantage is speed because Nginx will redirect before WordPress is even involved. The disadvantage is that there isn’t an easy way to track the redirects that occur.

To perform a redirect using Nginx, edit the Nginx configuration file “/etc/nginx/sites-available/olddomain” and insert the following rewrite statement immediately beneath the “server_name” directive:

# 301 permanent redirect
rewrite ^/314(|/.*)$ http://newdomain.com/314/the-value-of-pie/ permanent;

# Or 307 temporary redirect
rewrite ^/314(|/.*)$ http://newdomain.com/314/the-value-of-pie/ redirect;

You will need to create a rewrite directive for each post to be moved. The rewrite directives will take effect when the Nginx server is reloaded.

Unlike the WordPress redirect plugins, Nginx supports redirecting post identifier query formatted URLs. In the old domain’s Nginx configuration file, immediately beneath the “server_name” directive, insert the if-return statement below:

# 301 permanent redirect
if ($arg_p = 314) {
    return 301 http://newdomain.com/314/the-value-of-pie/;

# Or 307 temporary redirect
if ($arg_p = 314) {
    return 307 http://newdomain.com/314/the-value-of-pie/;

Note: You will need an if-return statement for each post which you wish to redirect. If there are many posts to redirect, the Nginx configuration file may become bloated with if-return statements. It may be possible to use the Nginx map function to replace the if-return statements; unfortunately, I haven’t figured out how to use the map function yet.

Batch Import For Redirection

Because I have over a hundred technical URLs to redirect and do not wish to manually input them, I’ve looked into ways to batch import them into the Redirection plugin. The most direct method is to insert the redirects directly into the MySQL database.

Here is an example MySQL insert statement:

# Log into MySQL interface
mysql -u root -p

# Use the old domain's WordPress database
mysql> use olddomain;

# Insert the redirect into Redirection's items table
mysql> INSERT INTO wp_redirection_items VALUES (NULL,'^/314(|/.*)$',1,0,0,

# Exit MySQL interface
mysql> quit

Note: Before executing the MySQL insert statement above, view the Redirection plugin’s Settings page at least once to trigger the Redirection plugin to create its MySQL tables, including “wp_redirection_items”.

Because I am lazy, I wrote a PHP script to generate a file containing the MySQL insert statements for all my moved posts, and then executed that file against the old domain’s WordPress database.

The Redirection plugin’s user interface exposes support for importing a comma-separated file containing the redirects. Unfortunately, there is no documentation on the import format and I could not get it to work based upon the few related forum posts which I found. Even had I gotten import to work, it looks like a MySQL update statement is required to enable the regular expression type check on all the imported redirects. Since MySQL would be required in any case, I am satisfied with the MySQL insert solution above.

Very Slow Cleanup

Once the redirects are working, you can start moving the moved posts from the old domain’s blog to the trash. Also, move the posts in the new domain’s blog that remain in the old domain to the trash. I recommend waiting a few weeks to make sure everything is working fine before emptying the trash. Once you have emptied the trash, don’t forget to delete any images referenced by the deleted posts.

In a few months, I plan to look at the redirect statistics to figure out which URLs are being redirected. I plan to delete the redirects that are not being used. Once I’ve reduced the number of redirects as much as I can, I intend to convert them into permanent Nginx rewrite statements and disable the Redirection plugin.

Update: The latest version of the Redirection plugin has a bulk action “Reset Hits” which resets the redirect counts, so we wouldn’t need to use the MySQL commands below.

Because I want to do several rounds of checking which URLs are being redirected, I needed a way to reset the redirection counts to zero. Unfortunately, there is no user interface option to reset the counts, so I had to use these MySQL statements:

# Log into MySQL interface
mysql -u root -p

# Use the old domain's WordPress database
mysql> use olddomain;

# Reset the redirection counts to zero
mysql> update wp_redirection_items set last_count=0;

# Exit MySQL interface
mysql> quit

If you decide to split your blog, I hope the instructions above will help.

No Comments

Online Fax For Free (Cheaper And Faster Than A Stamp)

Internet 2 Comments

Recently, my rebate application was rejected. I called and was told that I needed to resubmit the rebate with a copy of the invoice, instead of the order receipt that I had included in the original application. They offered to receive it by fax, in addition to snail mail. (The original rebate application did not mention a fax option. I was told about the fax option verbally by the customer representative.)

Unfortunately, I had just canceled my GreenFax Internet faxing service because I hadn’t used it for longer than a year. (GreenFax is a paid service which charges 5-10 cents per page sent.) I had believed that email or online form submission had made faxing obsolete. So I had arrived at the conclusion that fax was dead and no longer necessary. But I was premature because many companies were still using fax and were slow to adopt better technology (such as online form submission). Faxing remains a viable, convenient and much faster alternative to a stamped letter.

Rather than re-opened a GreenFax account for this rare instance, I decided to look for free options. Surprisingly, there were several free online faxing services. I ended up choosing FaxZero because it had good reviews, had a simple webpage, allowed 3 pages (excluding the cover sheet), and did not require me to create an online account. FaxZero does place its logo on the fax cover sheet. I was concerned about how large that logo would be, but discovered it to be small and unobtrusive. After using FaxZero, I whole-heartedly recommend it. Hey, it saved me a 49 cent stamp and a trip to the post office!

faxzero_submitTo send a free fax, do the following:

  1. Browse to FaxZero.
  2. Fill out the Sender and Receiver Information.
  3. Attach your multi-page PDF or Word document. You can only send 3 pages for free.
  4. Type some text into the cover sheet. The FaxZero logo will appear on the top-right corner of the cover sheet. (The cover sheet is not counted as one of the 3 free pages.)
  5. Input the displayed confirmation code to prove that you are a living human.
  6. Click on the “Send Free Fax Now” button.
  7. Check you inbox for an email titled “FaxZero.com Action Required – Please Confirm Your Fax”. Click on the confirmation link.
  8. You will be directed to a page with a link to your fax’s unique status page. Save that status page link so you can refresh it to see what is going on.
  9. Though FaxZero warns that it can take up to 30 minutes to send the fax; I found that my fax was sent within a few minutes. The status page was updated with a success message and I also got an email stating the same.

faxzero_logoThe rebate company scanned what I had faxed and helpfully provided the scan online (in the rebate status page). I was able to verify that the FaxZero logo was as small and unobtrusive as the sample image in the FaxZero FAQ.

A question plagued me. Why didn’t the rebate company support uploading the rebate form? Instead, the company forces people to mail in the rebate form, scans it, and then puts it online. I’m afraid that the answer is good, old capitalism.

Companies want customers to jump through hoops when submitting rebates. You have to mail it in, which requires you to get a stamp and go the post office. And of course, to make copies of everything you send in case they claim to have never received anything. You need to wait months before having to call in to ask why you haven’t received your check (you need to resubmit because they never got your rebate form) or that your rebate was denied because of something or another. I must admit that the online rebate status (and emails) that most companies provide nowadays is very helpful; instead of the black hole of waiting without any information common in the past.

I found the FaxZero free faxing experience very pleasant, convenient, and quick. So if you ever need to fax something and don’t have an old, clunky fax machine, consider using FaxZero or another free faxing service. I hope that FaxZero remains in business until faxing is finally obsolete.


The Internet’s Future is Blacklisted

Internet No Comments

Over the weekend, I signed up for a shared web hosting plan because of a special deal. I spent a day setting up the host, migrating a website, and testing to make sure it worked. On Monday, when I went to work, I thought I would check to see the status of my website. Imagine my surprise when I got a security warning that my website was dangerous, known to host viruses and spyware. How could this be? This is a respectable website which I have just moved to a new server.

senderbase_bad_ipIt turns out that my work’s Intranet is protected by a network security appliance called Ironport. Ironport in turn depends upon SenderBase, a blacklist service that identifies dangerous websites. The blacklist is keyed off the IP address. The new server’s IP address was flagged and thus, anything hosted on it (like my website) inherits the negative status.

When we get a shared web hosting account, we are assigned one of the servers which have available capacity. Now, why would that server have excess capacity? Perhaps, it is because a previous user was kicked out for bad behavior, like distributing viruses, spyware, or spam. Well, that someone’s bad behavior got the IP address blacklisted. And now, I am the proud owner of that banned IP address.

Note: The above doesn’t just apply to shared web hosting. If you get a private server or virtual private server, the provider company will give you an available IP address. That IP address could have belonged to someone previously who had misbehaved.

So maybe I and others whose companies use network security appliances can’t browse to my website. So what, we’re supposed to be working, right? Unfortunately, it turns out that email is also affected. If you expect to send and receive mail using your server, the server’s blacklisted IP address could cause all the email traffic to and from your server to get bounced (not delivered).

Worse, as far as I can tell, once the IP address is blacklisted, it is very hard to get that status removed. You’ll have to hope that your hosting provider is motivated enough to go through the hassle of engaging one or more blacklisting companies to remove that negative status. Even if your provider is willing, it will take time before the IP address is cleared.

Having learnt my lesson, the first thing I suggest doing after getting a web hosting or private server account is to check that its IP address is not blacklisted. You can check the IP address on the following websites:

Note: Not all of the blacklists are widely used, so it may be okay for the IP address to be on one or two blacklists. However, to be on the safe side, it is best to have an IP address which doesn’t appear on any blacklist.

If your IP address is blacklisted, ask your hosting provider company for another. If the company won’t accommodate you, then cancel and go with one that will. Believe me, doing so will avoid a lot of wasted effort and work. You don’t want a customer browsing to your company website only to get a stern warning that your website is known to distribute viruses.

I am afraid that I am seeing the future of the Internet. As security concerns grow, companies will invest in solutions, like network security appliances, that make use of blacklists (and maybe whitelists). Heck, if I was in charge of my company’s network security, a network security appliance would be the minimal that I would advocate. I would take more drastic steps like locking down inbound and outbound ports, and aggressively running heuristic checks on all internal traffic to detect viruses and spyware.

No Comments

File Upload With PHP

Internet No Comments

I recently needed to handle a file upload using PHP and was pleasantly surprised by how easy it was. I am sharing my file upload test script below.

Create a file named “upload.php” with the following content:


  // Handle GET or POST
  if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  } else { // GET

// GET Handler
function showForm() {

<form action="upload.php" method="post" enctype="multipart/form-data" >
<label for="file">Filename:</label><input type="file" name="file" id="file"/><br>
<input type="submit" value="Upload File"/>


// POST Handler
function processRequest() {
  // Check for file upload errors
  if ($_FILES["file"]["error"] > 0) {
    echo "Error on File Upload: error code " . $_FILES["file"]["error"] . "<br>";

  // Successful upload
  echo "Success on File Upload: Filename: " . $_FILES["file"]["name"] .
    ", Type: " . $_FILES["file"]["type"] .
    ", Size: " . ($_FILES["file"]["size"] / 1024) . " kB" .
    ", Location: " . $_FILES["file"]["tmp_name"] . "<br>";

  // Open the uploaded file (which will be deleted after this script ends)
  $file = fopen($_FILES["file"]["tmp_name"], "r");
  if (!$file) {
    echo "Error on File Read: Unable to open " . $_FILES["file"]["tmp_name"] . "<br>";

  // Insert your code to consume the file content here!

  echo "Success on File Read: Opened and closed " . $_FILES["file"]["tmp_name"] . "<br>";


To test, put this PHP file on your web server and browse to it.

Portions of the code above were sourced from W3Schools’ PHP File Upload page.

No Comments

Prevent Google And Youtube From Tracking You

Internet No Comments

google+tubeHave you ever noticed that Youtube’s initial page shows videos that are related to those that you have viewed in the past? While one could argue that it is convenient, I am a bit disturbed that Youtube remembers my past viewing history. Worse, now that Google has purchased Youtube, that viewing history is tied to my user account (which includes Gmail and Google+). I just don’t feel comfortable allowing Google and Youtube to track my searching and viewing habits. Thankfully, there are ways to disable the tracking function.

Note: If you have trouble getting any Youtube functions like adding/deleting channels to work (ex: the page would freeze), make sure to allow third-party cookies on your browser.

Because Google has not fully integrated with Youtube, there are three separate settings that we need to turn off: prevent Google from recording web searches, prevent Youtube from recording video searches, and prevent Youtube from remembering videos watched.

Prevent Google From Recording Web Searches

  1. Browse to Google’s Web History Settings page. Sign into Google if you need to.
  2. Click the “delete all” link in the paragraph to clear the search history. To confirm, click the “Delete all” button.
  3. Click the “Turn off” button to disable web history. The related text will change to “Web History is off”.

Prevent Youtube From Recording Video Searches

  1. Browse to Youtube’s My Search History page.
  2. Click the “Clear all search history” button to delete any remembered video searches. To confirm, click the “Clear all search history” button in the popup window.
  3. Click the “Search History” link again and click the “Pause search history” button to disable recording video searches.

Prevent Youtube From Recording Watched Videos

  1. Browse to Youtube’s Watch History page.
  2. Click the “Clear all watch history” button to delete all the remembered watched videos. To confirm, click the “Clear all watch history” button in the popup window.
  3. Click the “Pause watch history” to prevent Youtube from remembering the videos that you watch.

Doing the above will preserve your privacy. Below are additional security measures concerning Youtube and Google+ which you might want to take.

Keep Youtube Likes And Subscriptions Private

  1. Browse to Youtube’s Account Settings page.
  2. Click the Privacy link on the left.
  3. On the right content pane, check both of these options, “Keep all my likes private” and “Keep all my subscriptions private”.
  4. Click the Save button on the top-right to commit your changes.

Disconnect Youtube From Google+

Unfortunately and all too easily, Google will create a Google+ profile for you, a Youtube account for you, a Youtube public channel for you, and link that Youtube channel to your Google+ profile. All you have to do is to click the wrong Google link or browse to the wrong Google page while signed in. Here’s how to undo some of the damage.

google_productsDetermine if you have a Google+ profile and whether a Youtube channel is connected to it or not:

  1. Browse to Google’s Account page Click the “Sign In” button if you are not already logged in.
  2. Click the Products link to the left to view all the Google products your account is using.
  3. If you see a Google+ product icon, then you have a Google+ profile. (If you don’t see the Google+ product icon, then the rest of these instructions are unnecessary.)
  4. Click the Google+ product icon to go to your Google+ account.
  5. On the Google+ account page, there is a drop-down list on the top-left that is labeled Home. Click the drop-down list and select Profile to see your profile.
  6. Under the photo banner, you will see a horizontal list of links starting with the About link. If you see a Youtube link, then your Google+ profile has a Youtube channel connected.

Strangely, the above is not valid for a Google/Youtube identity attached to your Google account which has a linked Google+ page (different from a Google+ profile). That is, the Google+ product icon won’t be visible even if an associated identity has a Google+ page. Supposedly, if you create a Youtube channel with a name different than your suggested Google account name (using the “business or other name” option), Google will create a new identity with a Youtube channel attached to a Google+ page. When you sign into Youtube, Youtube will ask you which identity to use with a “Use Youtube as…” prompt. You can delete the Google+ page only after deleting the Youtube channel; Google does not allow you to unlink a Google+ page from its associated Youtube channel.

Disconnect your Youtube channel from Google+ (to remove the Youtube link from your Google+ profile):

  1. Browse to Youtube’s Account Settings page.
  2. Near the top-middle is your profile with photo and email address. If you don’t see a “Return name to… and disconnect Google+ profile” link next to your profile info, then do the following:
    • Click the Advanced link next to your profile info.
    • Note: If you see a “Delete channel” button near the bottom-middle of the Advanced page, then your Youtube channel is not associated with your Google+ profile. In this case, you don’t need to do anything further. (The “Delete channel” button would not be visible if the Youtube channel is associated to a Google+ profile.)
    • Under “Channel settings”, click the “Create custom URL” link.
    • Input a custom name. If you plan to keep the public Youtube channel even after disconnecting it from Google+, you will want to carefully select an appropriate name. Otherwise, you can just input a random string of letters and numbers.
    • Click the “Create Channel URL” button.
    • When you click the Overview link again, you should now see the “Return name to… and disconnect Google+ profile” link.
  3. Click the “Return name to… and disconnect Google+ profile” link. Click the OK button to confirm.
  4. Click the Overview link again. You will see a new “Link channel with Google+” link on the right of your profile info.

Delete Youtube Channel

  1. Browse to Youtube’s Advanced Account Settings page.
  2. Click the “Delete channel” button. To confirm, click the “Delete channel” button again.
    • If you don’t see the “Delete channel” button, then your Youtube channel is connected to your Google+ profile. Follow the “Disconnect your Youtube channel from Google+” steps above to disconnect your Youtube channel.
    • If you are using an alternate Google identity when signed into Youtube, you will see the “Delete channel” button even if there is a Google+ page attached (your Youtube overview profile info will have an “Edit on Google+” link next to the channel name). You cannot disconnect the Youtube channel from the Google+ page. You will need to delete the Youtube channel first before you can delete the Google+ page.
    • If you see an error message, “You have either created this channel or closed another account too recently, please try again later”, when attempting to delete the Youtube channel, wait 24 hours and try again.

Unfortunately, there is no way to delete the Youtube account without deleting your Google account. However, there is a way to delete the Google+ profile.

Delete Google+ Profile

  1. Browse to Google’s Account page.
  2. Click the “Delete profile and remove related Google+ features” link at the bottom-middle.
  3. Check the two options at the bottom, “Also unfollow me from anyone I am following in other Google products” and “Required: I understand that deleting this service can’t be undone and the data I delete can’t be restored”.
  4. Click the “Remove selected services” button.
  5. If you go back to view the list of Google products attached to your account, you will no longer see the Google+ product icon.

Delete Google+ Page

  1. Note: You must delete the Youtube channel linked to the Google+ page before you can delete the Google+ page.
  2. Browse to the Google+ Dashboard. The top-left dropdown list will have Pages selected by default.
  3. In the middle pane, you should see your Google+ page listed. Click on the “Manage this page” button.
  4. You will be taken to the Overview for the Google+ page.
  5. Click the Settings link at the end of the top horizontal list of options. If you don’t see Settings, click on the More link and then select Settings.
  6. Click the “Delete page” link at the bottom of the Settings page.
  7. On the confirm page, check all three checkboxes and click the DELETE button.

Some info above gotten from How to Remove Your YouTube Viewing and Search History Before Google’s New Privacy Policy Takes Effect.

No Comments

Buy Your Own (Time Warner) Cable Modem

Internet 7 Comments

A few months ago, my sister complained that her Time Warner Cable Internet Broadband Plan’s monthly charge had increased by $4-5. I asked to see the bill and saw a $3.95 cable modem rental fee, which after checking with her, was a new addition. A quick google revealed that Time Warner Cable had started charging a rental fee for cable modems, which previously were free. (I guess the penny-pinchers finally got control of Time Warner.)

CiscoDPC2100_BackI don’t know why my sister complains about technical stuff like this to me. Oh, wait, it’s because I usually solve the issue for her. Anyhow, I decided to buy a cable modem for my sister so that she could avoid paying that rental fee. I ended up getting a used cable modem compatible with Time Warner for $20 from craigslist. The following contains some information which might be useful if you are also looking to buy a cable modem.

DOCSIS 2.0 vs 3.0

DOCSIS (Data Over Cable Service Interface Specification) is a term which you will encounter when shopping for cable modems. Simply, DOCSIS is a communication standard for cable modems which allow cable modems from different companies to work with an Internet broadband cable provider’s equipment. There are two versions of DOCSIS, 2.0 and 3.0, which are commonly supported by Internet cable providers. The main difference between DOCSIS 2.0 and 3.0 is the speed which they can handle.

If your Internet service speed is significantly less than 42Mbps downstream and 30Mbps upstream, you should be okay with DOCSIS 2.0 cable modem because those are the maximum throughputs for DOCSIS 2.0. If your Internet service is around that speed or higher, you should invest in a DOCSIS 3.0 cable modem.

Because my sister had the Time Warner Basic plan, which is rated for up to 3Mbps and actually tested at 20Mbps (please, don’t let the penny-pinchers at corporate find out), a DOCSIS 2.0 cable modem is more than adequate. (You can easily test your Internet connection speed by browsing to speedtest.net.)

Time Warner’s Compatible Cable Modem Models

Originally, Time Warner recommended five expensive DOCSIS 3.0 cable modems on their Buy Your Personal Internet Modem page. Thankfully, the latest version of that page adds more models, including DOCSIS 2.0 modems, and breaks them into two groups tied to service plans; which are very helpful. Still, my sister’s rented cable modem is a Cisco DPC2100, which isn’t on the official list of recommended modems to buy.

After googling, I found Time Warner’s Lease Your Modem page which lists all the rented modems that Time Warner supported. This list contains three times the number of modems as the previous webpage. In the rented list, I found the Cisco DPC2100 which is a DOCSIS 2.0 modem.

The point is that if I buy a modem in this rented list, it must be acceptable to Time Warner because they rent the same out to their current customers. This is good because more options mean a greater supply which leads to lower prices when purchasing.

Shop for Cable Modems on Craigslist

When looking for cable modems on craigslist, it pays to do your research. I found that in the majority of instances, the cable modems on craigslist were overpriced. In some cases, new modems on craigslist (without the warranty) were sold at the same price or more than brand new modems that I found on Amazon and other reputable sites. Craigslist sellers were not reducing the price to account for the risk (lack of warranty, no returns, etc.) that buyers had. So if you are looking for a new cable modem, it pays to check stores (online and offline) in addition to craigslist.

If a used cable modem is acceptable, you will want to check craigslist for deals. (Also, if you don’t mind, look for online and offline deals concerning manufacturer-refurbished cable modems, which are almost as good as new and come with warranty.) As a general rule, I would target around $20 for a used DOCSIS 2.0 cable modem and around $40 for a used DOCSIS 3.0 cable modem. If you don’t have the fastest broadband plan, you don’t need to get an expensive cable modem with extra features that you won’t be able to take advantage of.

I ended up getting my sister a Scientific Atlanta DPC2100 version 2 cable modem for $20. This is basically a newer version of the Cisco DPC2100 (Cisco purchased Scientific Atlanta) that my sister was currently renting from Time Warner. At $20, it will take five months of not paying the $3.99 rental charge before we break even; after which, the saving begins. Because I paid for the cable modem, my sister enjoyed the savings immediately. (Again, this is why she complains to me about this stuff.)

Install Your New Cable Modem

Installing your newly-purchased cable modem is very simple. Here is Time Warner’s FAQ on what you need to do to install a purchased cable modem.

Basically, you will want to know your cable modem’s model (some service agents will ask for the model, others won’t) and the MAC address. Along with the model, the MAC address should be printed on a label on your cable modem. The MAC address will look like 00B0D086BBF7. Once you have these two tidbits of info, you can call Time Warner at 800-892-2253. The Time Warner agent will ask you to hook up the new cable modem (if you haven’t already done so) and update your service with the new MAC address. Within a minute or two of the agent activating your new modem, your Internet access should be re-established.

Don’t forget to return your rented cable modem to the nearest Time Warner store. Anyone can return it. The agent at the store won’t ask for anything (like account number) and will provide a receipt. Depending on where you are in your billing cycle, you may see that rental charge one more time before it goes away.

Save money on your Time Warner monthly bill by buying a used cable modem. It’s a breeze to setup.


Create WordPress Widget for the Yelp Bling

Internet 2 Comments

I was writing a Yelp review (log into Yelp and click the “About Me” tab) and noticed a small google map object on the Yelp page that showed the locations for my reviews one by one. At the bottom of that object was a link named “I want this bling on my blog”. So I clicked on it. It took me to a page where I could generate the HTML code for my very own Yelp Bling object. (I kept the default Javascript version and did not select the Flash version.)

To put the Yelp Bling on my blog, I decided that the cleanest way is to create a WordPress widget to contain all that bling. I inputted a border color (C33907), text color (000000) and background color (FFFFF) which matched my blog’s theme. To find the RGB (Red, Green, Blue) values from your theme, use the Windows Paint program per these instructions.

Follow these instructions to create your very own Yelp Bling widget:

  1. Create a text file named “yelpbling.php” with the following content:
    Plugin Name: YelpBling
    Plugin URI: https://www.chanhvuong.com/
    Description: Yelp Bling widget
    Author: chanhvuong.com
    Version: 1
    Author URI: https://www.chanhvuong.com/

    function yelpbling_widget() {

    <!-- Paste generated Yelp Bling HTML code here -->

    function init_yelpbling() {
       register_sidebar_widget("YelpBling", "yelpbling_widget");    
    add_action("plugins_loaded", "init_yelpbling");
  2. Paste your Yelp generated HTML code into the file under the “Paste generated Yelp Bling HTML code here” comment.
  3. Copy the “yelpbling.php” file to your web server’s WordPress plugin directory, usually “wp-content/plugins”.
  4. Log into your website as an administrator and select the Plugins tab. You should see the YelpBling widget listed.
  5. Activate the YelpBling widget.
  6. Go to the Appearance->Widgets tab and drag the YelpBling widget from “Available Widgets” into the Sidebar.
  7. View your blog and you should now see the Yelp Bling object in the Sidebar.

You may need to adjust the CSS style directives in the generated HTML code to make the Yelp Bling object fit nicely in the Sidebar. For example, I deleted the <div> containing the “Recent reviews by …” headline link (to compensate, I adjusted the header height to 25px from 40px) and the <div> containing the “What’s this?” footer link.

In the end, I decided that the Yelp Bling object did not belong on my blog and removed it.


PHP Script to Convert Firefox’s “sessionstore.js” to HTML

Internet 5 Comments

Today, my Firefox browser decided to freeze on startup while loading the pre-existing tabs. After killing it and restarting several times, I realized that the only way to recover was to prevent Firefox from loading the tabs. I located Firefox’s “sessionstore.js” file and moved it (one could also rename it). I started Firefox and it came up fine.

To find the “sessionstore.js” file on Windows 7, open up a “Command Prompt” and type the following:

cd %APPDATA%\Mozilla\Firefox\Profiles
cd <random_alphanumeric>.default

The macro %APPDATA% will translate to “C:\Users\your_username\AppData\Roaming”.
Windows XP and Mac OS X will have the “sessionstore.js” file in a different location.

I had about 25 tabs opened in the previous session and I did not want to lose those tabs. The tab URLs were stored in the “sessionstore.js” file but the file was big (it contained the open tab URLs and historical URLs) and hard to parse (it was a single huge JSON text string).

I decided to write a PHP script to convert the JSON string into an HTML file with a list of all the URL as links. Below is the PHP script I wrote. Just run it using the command line PHP executable, provide the “sessionstore.js” file location as the input, and it will create a “sessionstore.js.html” file (in the current directory), which you can then open in a browser to see the list of links.

 // Make sure we have the correct number of args
 $args = $_SERVER['argv'];
 if (2 != $_SERVER['argc']) {
   echo "Format: $args[0] <filename>\n";
 $filename = $args[1];

 // Read the input file into a json string
 $jsonStore = file_get_contents($filename) or die("Failed to open input file");

 // Convert the json string into an object
 $store = json_decode($jsonStore);

 // Create an output .html file
 $file = fopen("$filename.html", "w") or die("Failed to create output file");

 // Add HTML header
 fwrite($file, "<html><body><ul>\n");

 // Parse the session store object and generate HTML links for each tab.
 // Session stores have windows->tabs->entries array-of-arrays structure.
 $windows = $store->windows;
 foreach ($windows as $window) {
   $tabs = $window->tabs;
   foreach ($tabs as $tab) {
     $entries = $tab->entries;
     foreach ($entries as $entry) {
       fwrite($file, "<li><a href="$entry->url">$entry->title</a>\n");

 // Add HTML footer
 fwrite($file, "</ul></body></html>\n");

 // Close the output file

If you find that the “sessionstore.js” does not contain your open tabs, use the “sessionstore.bak” backup file instead. I hope that the script above may prove useful for you. Good luck with your Firefox blues.


Purchasing a Wireless Router for Real People

Internet No Comments

Recently, my trusty 2.4Ghz wireless G router (a Netgear WGR614) died after many years of service. I went looking for a new router and found that the information on which router to get was not clear or conclusively. The routers that people agreed were the best cost easily over $100. I wanted an inexpensive, reliable router with a strong signal, the same or better than my old router. In the end, I got a 2.4Ghz wireless N router for $25 (a new Cisco Linksys E1000 from craigslist) that matched my needs and actually provided a stronger wireless signal.

LinksysE1000RouterTo help others avoid having to repeat my research, I will summarize my findings below. I will simplify things and that will mean leaving out some info; otherwise, this post would turn into a small book.

2.4Ghz or 5.0Ghz

Un-intuitively, the first choice is whether you want 2.4Ghz or 5.0Ghz wireless signals, not Wireless G or Wireless N. Though Wireless G can operate only in 2.4Ghz, Wireless N can operate in both 2.4Ghz and 5.0Ghz, separately (dual-band router) or simultaneously (simultaneous dual-band router). While the 5.0Ghz wireless signal supports greater bandwidth, it turns out that the 2.4Ghz wireless signal has greater range. With a lower frequency, a 2.4Ghz wireless signal will actually penetrate better through walls. The 2.4Ghz wireless signal is like a sub-woofer in how its low frequency sounds penetrate the walls and floor. Comparatively, the 5.0Ghz wireless’s high-frequency signals might bounce off a wall, rather than penetrate.

Note: A non-simultaneous dual-band 2.4Ghz/5.0Ghz Wireless N router will switch to 2.4Ghz Wireless G mode if you have just one 2.4Ghz Wireless G client device connecting. You would then end up effectively with a more expensive 2.4Ghz Wireless G router.

To compensate, 5.0Ghz Wireless N has methods to overcome such obstacles as walls. The most visible method is to use multiple antennas. Two or three antennas are common, though the newer routers have six or more. The antennas receive the 5.0Ghz wireless N signal and its many reflections (from bouncing off walls), which the router analyzes and combines into a strong signal. A second method is waveform shaping to increase the signal strength. This is similar to using a cone-shaped horn to amplify your voice. Unfortunately, like with the router, you have to know where the person you are shouting to is located so you can point the horn at him. A third method is to increase the signal spread from the standard 20Mhz to 40Mhz, similar to magically doubling the width of a clogged water pipe in order to get more water through. This would result in the router taking up double the frequency range and would only be viable if there is little or no congestion; if the pipe you are doubling the size of is right next to a bunch of other pipes, those other pipes would interfere with the size change.

Your environment will determine whether 2.4Ghz Wireless G/N or 5.0Ghz Wireless N has the most range. Currently, 2.4Ghz Wireless G/N congestion will increase the chances of interference and reduce the 2.4Ghz Wireless G/N range. Many household devices like wireless digital phones, microwaves, garage opener remotes, etc., might use the same 2.4Ghz signal. And neighbors left, right, front, and behind are getting wireless routers (almost all 2.4Ghz Wireless G/N routers because they are cheap and provided free by the Internet broadband providers). So, it might be best to go with 5.0Ghz Wireless N for now, until it too gets congested.

Tip: If you have a Windows machine, I suggest getting the free inSSIDer Home tool; the latest inSSIDer is no longer free. It will scan the 2.4Ghz Wireless G/N and 5.0Ghz Wireless N (if your Windows machine has a 5.0Ghz wireless N capable adapter) ranges and show all the wireless routers nearby. This will give you an idea of the congestion.

Single Band or Dual Band

Your devices will determine whether you can use 5.0Ghz Wireless N. If all your devices support 5.0Ghz wireless N, I would say to go with a 5.0Ghz Wireless N router. If some of your devices are 2.4Ghz Wireless G, then you might choose a 2.4Ghz wireless G/N router or if you have spending cash, a simultaneous dual-band Wireless N router. Again, simultaneous dual-band means that the wireless router handles both 2.4Ghz Wireless G and 5.0Ghz Wireless N traffic in parallel and at the same time. It is like having two routers, a 2.4Ghz Wireless G and a 5.0Ghz Wireless N router, in one. A non-simultaneous dual-band Wireless N router can operate either as a 2.4Ghz Wireless G/N or as a 5.0Ghz Wireless N router.

Note: I tested inSSIDer with a simultaneous dual-band Wireless N router (at work) which outputted both 2.4Ghz Wireless G and 5.0Ghz Wireless N signals; inSSIDer showed that the 5.0Ghz Wireless N signal was about 20% weaker than the 2.4Ghz Wireless G signal.

I have found that the SmallNetBuilder website provides the best review of wireless routers. If you don’t mind spending the money, the best router to get is the Cisco Linksys E4200 Wireless N router for about $180 retail. After that is the Netgear WNDR4000 N750 Wireless N router for $170 retail. Both are simultaneous dual-band routers.

Update: If you have the cash, get the Linksys WRT1900ACS Dual-Band Wi-Fi Router. I purchased it for my brother’s large house and the signal strengths for both 2.4Ghz and 5.0Ghz were the best (strong and solid) that he had ever ever gotten. The 5.0Ghz signal was still 10-15% weaker though.

If you get a dual band wireless router, I recommend using different SSIDs (Service Set Identifiers, a.k.a. network names) for the 2.4Ghz and 5.0Ghz signals. Some recommend using the same SSID for both and leaving it to each wireless client to pick the strongest signal to use. The wireless client could also switch signals on-the-fly to ensure the fastest connection. However, in practice, I found that due to interference on the 2.4Ghz frequency, wireless clients switching to and from the 2.4Ghz signal caused the network connections to misbehave. And some old 2.4Ghz-only wireless clients, like Sonos hubs, got very confused. So, it is best to use separate SSIDs for now.

What I Ended Up With

I decided to get a 2.4Ghz Wireless N router because my old 2.4Ghz Wireless G router worked fine (without congestion issues), none of my devices were 5.0Ghz Wireless N capable, and I didn’t want to spend more than $50. In the end, buying a wireless router is like playing Russian roulette. I went on craigslist and searched for name brand wireless routers like Linksys, Netgear, and D-Link. I found a sweet deal, a brand new Cisco Linksys E1000 2.4Ghz Wireless N router for $25 (50% off retail price), and managed to purchase it. (The Linksys E1000 supports Wireless N on the 2.4Ghz frequency so I consider it essentially a Wireless G router.)

Setup was a breeze. I plugged the Linksys E1000 into the wall outlet, connected my laptop by Ethernet cable to it, browsed to the E1000’s default gateway address, logged in (had to google for the default user/password which was blank user and “admin” password), and manually configured it. (I did not run the software on the included CD.) I setup up the same WPA-Personal security as my old router’s configuration. I manually forced Wireless G only mode (since any one of my Wireless G device connecting would force this), selected 20Mhz range (since WPA-Personal and Wireless G mode would force this), and channel 11 (it worked well in the old router and inSSIDer showed it was the best option).

After I finished configuring the router, I was pleasantly surprised to find that the 2.4Ghz Wireless G signal was significantly stronger than my old router’s signal. Machines at the back of the house that showed low connectivity before were now reporting good connectivity. The inSSIDer tool on my desktop (about 15 feet and two walls from the router) showed an increase from -50db to -40db in signal strength.

Finally, a cautionary tale on wireless repeaters which are devices used to extend the wireless range. It is like shouting to a friend, who then repeats the message to a second friend further away. A few years ago, I tried to use a Linksys WRE54G wireless G extender with my Netgear WGR614 wireless G router. It worked and boosted the wireless signal, but after a few minutes, my Netgear router went dead and needed to be rebooted. This consistently happened and I could only conclude that the Netgear router and Linksys extender did not like each other. Probably, compatibility is a lot better now. However, if you decide to get an extender, I would recommend getting the same brand as the router’s or getting something you can easily return. This gives me a thought… The Linksys WRE54G extender could get rid of my neighborhood wireless congestion if I were to use it to “helpfully” extend (aka “kill”) the neighbors’ routers. But that would be too evil.

Good luck with your wireless router purchase.

No Comments

« Previous Entries