Blog

Friday, November 30th, 2012

How to watch Netflix on Ubuntu Linux

I’ve only been waiting for this since the day I first purchased a netflix account… The performance wasn’t so great for me… but after shrinking the window and disabling the useless “HD”, it was watchable… Not as fast as the iPhone, could be related to the fact that I’m using the built in Free drivers and a 2d desktop.

Yesterday, developer and programmer extraordinaire Erich Hoover and I spent several hours working out all of the Netflix Desktop kinks. Most users will have no problems with installation now.

Here is how to install the Netflix Desktop App on Ubuntu. Open a terminal and run these commands:

sudo apt-add-repository ppa:ehoover/compholio

sudo apt-get update && sudo apt-get install netflix-desktop

 

http://www.iheartubuntu.com/2012/11/ppa-for-netflix-desktop-app.html


Saturday, October 13th, 2012

Maximize your blog layout

It’s been many years since the blog become the standard layout of the web. However, many people still struggle with the basics of how to use the blog layout to maximize their content and reward readers. When a friend ask me what he should do to maximize his blog content, I  went and found a couple of blogs that maximize their layout to promote content.

What is a Blog?

In case you don’t know, a blog is a traditional website with no homepage. Instead of a home page, the website has a reverse chronological listing of content. And, that’s it! Many blogs also feature comments.  But, otherwise, there is no difference between a blog and a website other than the home page.

Disadvantages of a Blog

The disadvantages of a blog are that your blog is only as good as your last post. Unlike a traditional website, a blog must be timely and each visitor is going to judge your blog entirely based on your most recent post.

Advantages of a Blog

It’s always easy to figure out where to post your most recent post. It always goes at the top of your home page. The best blogs use the sidebar (generally on the right) to feature evergreen content that rarely changes.

Layout Elements to Count On

The most effective layout elements for a blog are:

  1. A featured post section that contains a hand selected list of content that most represents the blog. For larger blogs, this might be multiple sections.
  2. A popular posts section that should change every week automatically. For high traffic blogs, this may change every day.
  3. Related posts should be a small list of related posts. Generally, these are placed at the bottom after each article. This list can be automatic, but selecting related posts by category also works well.
  4. About the author(s) with photos. Reading about you is as important as reading what you have to say. This can go below the post, in the sidebar, or near the top of each post.
  5. Social sharing, FB Like, follow buttons, and email sign up are key actions you want readers to take. Sharing buttons should be large an obvious.  If you think your social media buttons are too large… look over Move On.org again. Move on does it right.
  6. Your home page should load at least 10 posts if not more. The majority of your visitors will read everything on your front page before leaving.  They most often will not click any links to other pages of your site… so give them the goods and lots of them all on the home page.
  7. Each blog post is a new opportunity to promote previous articles. When writing for a blog, you’ll be repeating key points many times. Every time you mention a topic you’ve written about before, link to it!

As short as my list is, it’s extremely difficult to find a single blog that takes advantage of all of these layout elements. Got a better example of the perfect blog? Send it over.


Tuesday, June 26th, 2012

Drupal Scrum Tips

So, I’d like to stop using waterfall development for Drupal projects. The first step is to teach myself to be a good advocate for something different… Started way back in the early 90′s was a thing called scrum… It really is very different. Here are some resources that don’t suck.

http://blog.merge.nl/20110619/scrum-driven-drupal-development

http://slides.liip.ch/img/documents/agile-drupal-development-with-scrum_vienna.pdf

http://drupaldojo.com/session/scrum-revolution-embrace-future-interactive-development

 

Not all positive:

http://2011.doitwithdrupal.com/2011/sessions/pitfalls-being-agile

It’s funny, when I got a computer information systems degree, we all laughed about waterfall development. But, client’s demand fixed bids! Can you be agile with a fixed scope, budget, and timeline?


Wednesday, March 14th, 2012

Find Vulnerable WordPress and Drupal

Drupal:

grep 'DocumentRoot' /etc/httpd/vhost.d/* | awk {'print $2;'} | xargs -I {} nice find {} -name CHANGELOG.txt > ~/drupal-sites.txt

Produce clean report:

cat ~/drupal-sites.txt | xargs head -n 3 > ~/drupal-sites2.txt

WordPress:

grep 'DocumentRoot' /etc/httpd/vhost.d/* | awk {'print $2;'} | xargs -I {} nice find {} -name readme.html > ~/wp-sites.txt

Todo: Add string to pull WordPress version with pretty formatting.

Django:

 
nice find -L /vol/www/ -name 'PKG-INFO' | xargs grep '^Version:' > ~/django-sites.txt


Tuesday, January 31st, 2012

Drupal Security Updates with Drush

Since I get tired of hunting through forum threads for correct answers to common task. So, for the lucky souls to find this trick, here is how you run just the security updates to a Drupal install with Drush from the command line.

drush upc -u 1 --pipe | grep 'SECURITY-UPDATE' | cut -d" " -f1 | xargs drush upc -u 1 -y

Found here.


Saturday, January 28th, 2012

Decode your WordPress content to UTF-8

Ann Smarty recently posted an article about how scammers use foreign characters to disguise duplicate content as unique, original content. If you’ve never seen this before, go read her post. It’s really interesting.

No really. Read it.

http://www.seosmarty.com/content-scam-alert-using-foreign-characters-to-make-the-piece-look-unique/

She had several great suggestions for catching the hidden characters, but, checking every guest post by hand is bound to fail eventually. You’ll either get bored of never catching hidden content, or you’ll just forget about. So, here’s how you can always catch this kind of false character content the automated way:

Place this code into the functions.php file of your theme. Anywhere between is fine.


// Transform foreign characters into ?
function decode_content($content) {

    $content = utf8_decode($content);

    return $content;
}

add_filter('the_content', 'decode_content');

Now, whenever you publish an article with Cyrillic characters in it, the characters will be converted to UTF-8 and you’ll see a bunch of question marks in the post. Below is an example taken directly from Ann’s post:

This p?st l??ks at ?ne type ?f c?ntent re-packaging: turning y?ur ?ld c?ntent int? an image

As you can see, the hidden characters have been revealed. Isn’t PHP great? You could take this a step further and rewrite the characters to English, or warn the user when publishing posts with foreign characters, but that’s not a single line of code.

Now back to work on my cool WP scanner.


Thursday, January 19th, 2012

Zappos shares your password with hackers

Zappos logoSo, while I’ve been slaving away trying to get my own blog to pass my WordPress security scanner, Zappos got hacked. It happens. They were probably running WordPress right? Their customer information was accessed. While they didn’t make an announcement, they did email their customers and tweet about it. While I’m happy with their proactive response, this provides a wonderful learning opportunity for all of us who store passwords for a living. When a user gives you a password, they trust that you will keep it safe, and that you won’t share it with anyone. Part of keeping passwords safe is storing them well.

Now, Zappos comment on the hack:

We are writing to let you know that there may have been illegal and unauthorized access to some of your customer account information on Zappos.com, including one or more of the following: your name, e-mail address, billing and shipping addresses, phone number, the last four digits of your credit card number (the standard information you find on receipts), and/or your cryptographically scrambled password (but not your actual password).

http://blogs.zappos.com/securityemail (emphasis mine)

They further add, “We also recommend that you change your password on any other web site where you use the same or a similar password.” 99% of their customers are going to ignore the email even if it gets through their spam filter. So, my question for Zappos tech team is,

How did you store the passwords?

MY guess is that they used an MD5 which is NOT cryptographically scrambling a password, and it is not secure password storage. But, it’s what everyone does. If you store user passwords with Md5 hash still, or worse, in plaintext like my student loan servicing company, MD5 has been broken for years. You should always store your user’s passwords with a secure method like using bcrypt with random salt. That way, when someone copies your database, your user accounts are still secure.


Friday, December 23rd, 2011

Drupal 7 Import content with custom fields, images, and taxonomy

I’m in the process of migrating an old PHP website for Portland State University from a custom database into Drupal 7. Doing the data entry on hundreds of nodes with multiple custom fields, taxonomies, and images would have taken ages. So, instead I imported the data into Drupal with a PHP script. At first, I attempted to use phpMyAdmin, to export a CSV, and then import the CSV using the Feeds module. However, the feeds module for Drupal 7 doesn’t seem to do field matching well, and I couldn’t get the taxonomies or images to import correctly. So, with the help of my intelligent coworker, I decided to use Drush to execute a PHP script that will import the content. The process wasn’t hard for a PHP programmer, but all the directions I found on other blogs were either confusing me, or missing a few steps. Mainly the examples were missing the code to insert dynamic data from a database in a loop.

This being my first Drupal 7 project, I had a lot to learn about new Drupal features. Don’t worry, I’ve attached the code, so you can cut and paste my hard work.

Import content into Drupal 7

  1. Create the taxonomies and terms that you will need. This can be done with a script, but most websites don’t have that many categories.
  2. Create a content type for the nodes and include all the custom fields you will need. Be sure to include term reference fields for each taxonomy from step 1.
  3. Install Drush and get “Drush help” to work.
  4. Create a PHP script, and execute it with drush php-script (script name)

Drush is nifty because it loads the Drupal environment and allows you to access Drupal’s functions. This saves you from having to figure out where to insert all the node data manually.

Connect to the database and get content

// My source data was not normalized. All data was in 1 table! Lucky me. No joins.


$query = 'SELECT * FROM `tb|record`';
$result = db_query($query);
$i = 20;
foreach ($result as $row) {

Most of what Tim wrote worked perfectly, but here’s what Tim has to say about assigning content to categories…

Add a term to a node

$node->field_tags[$node->language][]['tid'] = 1;
‘field_tags’ here is the name of a term reference field attached to your content type, ’1′ is a term id you wish to assign to a node. Simple!

Now here’s the code I actually used to insert my content into a category. It wasn’t simple:

 if ( $term = taxonomy_get_term_by_name($row->culture) ) {
$terms_array = array_keys($term);
$node->field_culture[$node->language][]['tid'] = $terms_array['0'];
}

If you review my code, you’ll notice that I failed to get my loop to read and load the taxonomies from the database, so I added them one a time. If anyone can figure out the syntax error in the block of code that’s commented out, that would be awesome. Contact me, and I’ll give you credit. But, I doubt many sites have more than a handful of categories.

The script took me about 10 hours to perfect after I threw away 2-3 different methods. Hopefully, you can copy this script and get your site converted over to Drupal in much less time.

The Full Source Code


<!--?php <br ?--> cm_load_rep_data();

function cm_load_rep_data( ) {

// My source data was not normalized. All data was in 1 table! Lucky me. No joins.
$query = ‘SELECT * FROM `tb|record`’;
$result = db_query($query);
$i = 20;
foreach ($result as $row) {
$node = new stdClass(); // We create a new node object
$node->type = ‘piece’; // Or any other content type you want
$node->title = $row->subject;
$node->language = LANGUAGE_NONE; // Or any language code if Locale module is enabled. More on this below *
$node->uid = $i; // Or any id you wish
$url = str_replace(” “,”_”,$row->subject);
$node->path = array(‘alias’ => $url) ; // Setting a node path
node_object_prepare($node); // Set some default values.
$i++;

//grab the file for this node based on the “schema” from the old website…
$file_path = ‘/home/gboggs/Images_data/’
. $row->collection_alias . ‘/’
. $row->collection_alias . $row->accession_no . ‘.jpg’;

if (file_exists($file_path)) {
$file = (object) array(
‘uid’ => $i ,
‘uri’ => $file_path,
‘filemime’ => file_get_mimetype($filepath),
‘status’ => 1,
);
$file = file_copy($file, “public://”);
$node->field_image[LANGUAGE_NONE][0] = (array)$file;
}

// Grab the body content. My database had the body content repeated. You don’t need this piece.
if (!isset($row->long_des) || $row->long_des == null) {
$body = $row->short_des;
} else {
$body = $row->long_des;
}

// Insert the content into the node
$node->body[$node->language][0]['value'] = $body;
$node->body[$node->language][0]['format'] = ‘full_html’;

// Let’s add some CCK fields. This is pretty similar to the body example
$node->field_collection_number[$node->language][0]['value'] = $row->accession_no;
$node->field_dimensions[$node->language][0]['value'] = $row->dimension;
$node->field_date[$node->language][0]['value'] = $row->date;
$node->field_artist_author[$node->language][0]['value'] = $row->artist;
$node->field_provenance[$node->language][0]['value'] = $row->provenance_prior_pub;
$node->field_details[$node->language][0]['value'] = $row->object_details;

/* This doesn’t execute, and I couldn’t figure out why in < 10 minutes. so doing it the long way.
$categories = array(‘field_culture’ => ‘culture’,
‘field_medium’ => ‘medium’,
‘field_time_period’ => ‘time_periods’,
‘field_collection’ => ‘collection’,
‘field_theme’ => ‘theme’);
foreach ($categories as $field => $category) {
$term = taxonomy_get_term_by_name($row->$category);
$node->$field[$node->language][]['tid'] = $term->tid;
}
*/

// The long way to check taxonmy terms and add them to the node.
if ( $term = taxonomy_get_term_by_name($row->culture) ) {
$terms_array = array_keys($term);
$node->field_culture[$node->language][]['tid'] = $terms_array['0'];
}

if ( $term = taxonomy_get_term_by_name($row->medium) ) {
$terms_array = array_keys($term);
$node->field_medium[$node->language][]['tid'] = $terms_array['0'];
}

if ( $term = taxonomy_get_term_by_name($row->time_periods) ) {
$terms_array = array_keys($term);
$node->field_time_period[$node->language][]['tid'] = $terms_array['0'];
}

if ( $term = taxonomy_get_term_by_name($row->collection) ) {
$terms_array = array_keys($term);
$node->field_collection[$node->language][]['tid'] = $terms_array['0'];
}

if ( $term = taxonomy_get_term_by_name($row->theme) ){
$terms_array = array_keys($term);
$node->field_theme[$node->language][]['tid'] = $terms_array['0'];
}

$node = node_submit($node); // Prepare node for a submit
node_save($node); // After this call we’ll get a nid

// printing from Drush is easy
drush_print( $row->subject . ” added.\n” );
}
}
?>


Saturday, August 13th, 2011

How to get a Job on Craigslist

I’m not an amazing career blogger, but I have applied for, and gotten, alot of work on Craig’s. If you have a white-sounding, male name and aren’t getting responses, there is something wrong with your email. I give much of this advice to my friends, but every time I use the list, I improve my results a little. The first thing you need to know about Craigslist is that any posting is going to be overrun by spammers trying to drum up business. So, when replying to a job listing, your goal is to cut through the spam.

  1. Use spell check.
  2. Keep it short. After sorting through spammers, the poster doesn’t want your life story.
  3. Keep it local. In fact, bold the word local, include the name of your town, and always use a local phone number.
  4. Read the posting carefully and show the poster that you read it.
  5. Answer some of the poster’s questions, but leave them a reason to email you.
  6. Skip job postings that don’t give you a reason to apply.
  7. Use spell check, damn it.
If these tips fail you, start reading Penelope’s blog, or have several friends review your resume and cover email.

Monday, August 1st, 2011

WordPress Silent Automatic Background Updates

WordPress automatic silent updates could mean and end to WordPress security problems and kill the need for WordPress security plugins. While this solution has it’s drawbacks that could cause your website to white screen of death, silent updates have the potential to finally make WordPress a secure platform. This change, planned for November, would make my WP security scanners obsolete including my own WordPress Security Scanner because every website running WordPress will, in theory, be secure. While WordPress has many basic security flaws like account name harvesting, old versions and misplaced backup copies is by far the largest reason for hacked WordPress sites.

Given the potential silent updates have, I have to wonder, are WP Security experts going to be looking for a new line of work?

Update: Background updates for WordPress were dropped from the 3.3 release of WordPress and no mention of it has been made by the major WordPress blogs. It looks like WP is going to continue to be the leading cause of server break-ins. Is your site secure? Scan it now and find out!



All content © Copyright 2013 by Greg Boggs.
Subscribe to RSS Feed – Posts or just Comments