C# Project – Scraping Files for Data

I was literally receiving thousands of emails in Outlook with regard to a specific network service error, many duplicates, that quickly surpassed my ability to copy, paste and manually process that I got fed up and looked for a more creative way to handle it.

At first I thought about creating a macro in Outlook to programmatically scrape the emails and save information they contained but macros are a security hazard and actually locked down by a network policy anyways. Alternatively I opted to make a utility in C#.

Creating a utility to access Office COM objects, namely Outlook, did nothing for me but try my patience and then I thought why not have the emails saved as text files to a folder as they come in. After explaining my intentions to the network admin, he set up a script on the mail server to save specific emails to a share as text files. Excellent.

So now with the emails being saved as plain text files, I could create a text scraper to pull out data I needed and process. However, the data I needed was sandwiched inside an error with text that ran contiguous (ex: errorfound:D2A1AB9C83=|0X0C0MID:3:3) so I had to process the files by searching for a string and grabbing the text between beginning and ending characters. What I needed was simply in between the colon and the pipe characters which were always static in what they contained. Below is the parser function and button function code where I added to save the list to a file also.

//String parser
public string ParseBetween(string Subject, string Start, string End)
{
        return Regex.Match(Subject, Regex.Replace(Start, @"[][{}()*+?.\\^$|]", @"\$0") + @"\s*(((?!" + Regex.Replace(Start, @"[][{}()*+?.\\^$|]", @"\$0") + @"|" + Regex.Replace(End, @"[][{}()*+?.\\^$|]", @"\$0") + @").)+)\s*" + Regex.Replace(End, @"[][{}()*+?.\\^$|]", @"\$0"), RegexOptions.IgnoreCase).Value.Replace(Start, "").Replace(End, "");
}

//Parse between two strings and grab that contents as new string
private void button1_Click(object sender, EventArgs e)
{
    textBox1.Clear();
    tsNotify.Text = "";
        StringBuilder strFile = new StringBuilder();
        string s2 = "errorfound:";  //beginning string
        string s3 = "|0X0C0MID:3:3";    //end string
        //files to parse
        foreach (string file in Directory.EnumerateFiles(@"\\server\SomeErrors\", "*.txt"))
        {
            string contents = File.ReadAllText(file);
            string strParsed = ParseBetween(contents, s2, s3);
            //Clean up the string
            string clean = Regex.Replace(strParsed, "[^A-Za-z0-9 ]", "");
            textBox1.AppendText(clean + "\r\n");
        }
        using (StreamWriter objWriter = new StreamWriter(@"C:\ServerErrors.txt"))
        {
            objWriter.Write(textBox1.Text);
            objWriter.Flush();
            tsNotify.Text = "Parsed and saved to C:\\ServerErrors.txt";
        }
}

As the data got pulled from the text files, I experienced some string anomalies such blank lines (sometimes several in a row) and white spaces because not all of the emails with the title being saved related to the error so those emails made it to the list as blank entries. Trimming the strings helped with that.

were showing up as blank entries in the list.

private void button5_Click(object sender, EventArgs e)
{
    string filePath = "C:\\ServerErrors.txt";
    //remove any empty lines
    string[] lines = File.ReadAllLines(filePath).Where(s => s.Trim() != string.Empty).ToArray();
    listBox1.Items.AddRange(lines);
    tsNotify.Text = "Errors added for processing";
}

Once processed, I removed any duplicate data using the code below:

private void button6_Click(object sender, EventArgs e)
{
    string[] arr = new string[listBox1.Items.Count];
    listBox1.Items.CopyTo(arr, 0);
    var arr2 = arr.Distinct();
    listBox1.Items.Clear();
    foreach (string s in arr2)
    {
        string clean = Regex.Replace(s, "[^A-Za-z0-9 ]", "");
        listBox1.Items.Add(clean);
    }
    tsNotify.Text = "Duplicates removed";
}

Once finished, I processed a final list of errors that were minus white spaces, blanks lines and duplicates.

private void button7_Click(object sender, EventArgs e)
{
    foreach (object liItem in listBox1.Items)
        textBox2.Text += liItem.ToString() + "\r\n";
    tsNotify.Text = "Final list ready to copy";
}

After a few iterations I was successful at scraping and processing the data I needed and since each time I wanted to process only newer text files, at the end of each run, I would delete the files on the server share.

private void button2_Click(object sender, EventArgs e)
{
    System.IO.DirectoryInfo di = new DirectoryInfo(@"\\server\SomeErrors\");
    foreach (FileInfo file in di.GetFiles())
    {
        file.Delete();
    }
    tsNotify.Text = "Remote files at \\server\\SomeErrors deleted";
    textBox1.Text = "";
    listBox1.Items.Clear();
}

As with all of my projects, it is out of necessity and not code pretty in any way. Its functional for my needs and serves it purpose though. Code in my project is freely found around the internet by performing simple Google searches or hitting Microsoft’s programming help sites. If the code benefits anyone then awesome. I take credit for nothing more than the tool I have created to accomplish a task.

BootstrapCDN – WordPress CDN Plugin

I want to use some of the responsive features of Bootstrap and Fontawesome on my sites but have a personal preference of not wanting to pollute my header.php files with code so decided to look for a plugin and found BootstrapCDN which will give me a simple way of updating/enabling/disabling both Boostrap and Fontawesome.

I had found a decent Bootstrap CDN plugin on the main WordPress website but it was a bit outdated so in looking at the authors files I found that simply updating the bootstrapcdn.json file with newer data resolved that and made it usable.

I am a bit confused with the authors notes though as it states that in a 0.0.3 update he renamed netdna to maxcdn, which is not the case when I looked at the JSON file. Perhaps he meant elsewhere in his code.

For alternatives to using a plugin, Prakhar over at 3nions has a cool article titled How to add Bootstrap to WordPress: Use these 3 Best Methods describing three great alternative methods, one of the primary methods being the use of this plugin.

Links to respective websites, authors WordPress plugin page and modification of the bootstrapcdn.json of the plugin are below.

Bootstrap – Get from BootstrapCDN or Bootstrap.com websites.

Fontawesome – Get from BootstrapCDN or Fontawesome.io websites.

BootstrapCDN – WordPress CDN Plugin – Get from the WordPress website.


{
"timestamp": 0,
"bootstrap": {
"3.3.7": {
"css": "//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css",
"js": "//netdna.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
},
"3.3.6": {
"css": "//netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css",
"js": "//netdna.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"
},
"3.3.5": {
"css": "//netdna.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css",
"js": "//netdna.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"
},
"3.3.4": {
"css": "//netdna.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css",
"js": "//netdna.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"
},
"3.3.2": {
"css": "//netdna.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css",
"js": "//netdna.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"
},
"3.3.1": {
"css": "//netdna.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css",
"js": "//netdna.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"
},
"3.3.0": {
"css": "//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css",
"js": "//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"
},
"3.2.0": {
"css": "//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css",
"js": "//netdna.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"
},
"3.1.1": {
"css": "//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css",
"js": "//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"
},
"3.1.0": {
"css": "//netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap.min.css",
"js": "//netdna.bootstrapcdn.com/bootstrap/3.1.0/js/bootstrap.min.js"
},
"3.0.3": {
"css": "//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css",
"js": "//netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"
},
"3.0.0": {
"css": "//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css",
"js": "//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"
},
"3.0.0-noicons": {
"css": "//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.no-icons.min.css",
"js": "//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"
}
},
"fontawesome": {
"4.7.0": "//netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css",
"4.2.0": "//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css",
"4.1.0": "//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css",
"4.0.3": "//maxcdn.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css",
"4.0.2": "//maxcdn.bootstrapcdn.com/font-awesome/4.0.2/css/font-awesome.min.css",
"4.0.1": "//maxcdn.bootstrapcdn.com/font-awesome/4.0.1/css/font-awesome.min.css",
"4.0.0": "//maxcdn.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.min.css",
"3.2.1": "//maxcdn.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.min.css"
}
}

Windows Search is a pain in the ass

Windows Search is a pain in the ass! I call it like it is – and it is, a great big pain! I long for the days of the simple Windows XP search that allowed you to select to search file contents with ease.

Now, for my main system at home I use Windows 7 Professional. It is not because I hate any of the other Windows platforms, including Windows 10, but more because I have so many apps on it that I use that I do not want to chance an upgrade nightmare and lose settings, apps or files. In any event, this is about file searching and not about ranting on Windows.

I do quite a bit in WordPress so sometimes I have a need to frequently search PHP, JQuery and other files in local folder structures for their internal file contents but whenever I tried my search results would always come up with nothing found.

Having got tired of my file search woes, specifically searching for file contents, I started creating a search tool in C Sharp when I noticed that the internal code for those features was still available to set via the Windows GUI. The simple steps below are based on my main system with Windows 7 Professional. Hope this helps someone who might have a similar issue.

STEPS

Go to Windows Start button and type search in the search box which will display a few options.

Click on Change how Windows Searches.

Change Windows Search

Click on the Advanced button.

Advanced Search

Select the File Types tab.

Include File Types

In the list of file types select the files that you want to include and check the Index Properties and File Contents radio button which will help find file info in non-indexed locations as well as indexed.

In my case, none of the PHP file types were selected by default by Windows so I checked them and then the search included those files in all future searches I did to include text within files.

The main point here is that if you know you have file content that exists and you are unable to search the internal file contents then the above is probably what you need to follow. I really liked the search features of Windows XP/Vista and the code still exists within the labyrinth of millions of lines of Windows code so I’m not sure what the purpose was of changing that in Windows 7 and newer.

Its been my experience that Microsoft’s decision making skills leave a lot to be desired and they like to dictate what users need rather than listening to what users actually want. Perhaps I answered my own question then….

 

Royal Custom CSS for Page and Post

RTCSSplugin2

I have been using a really great plugin with WordPress for some time that allows me to simply add CSS to individual pages or posts instead of having to use the existing main styles sheet or a secondary one all together.

In any event, this is a great plugin but the size of the field for entering the CSS has bugged me so long that I made an adjustment to the custom_css_input function in the PHP for this plugin to accommodate a large CSS field row view.

It originally used only 5 rows so I changed the rows parameter to rows=”35″ (comfortable for me) so I didn’t always have to drag that field larger each time I want to see what CSS I had or to find something to modify.

I posted this same change on the developers WordPress plugin page as well but for anyone interested:

STEPS

  1. In WordPress navigate to Plugins, look for Royal Custom CSS for Page and Post in the list and select Edit.
  2. Look for the code section of function custom_css_input.
  3. In the second echo line for the textarea change rows=”5″ to rows=”35″ or to whatever your liking is. I was comfortable with 35.
  4. Select Update File and the next page or post that you create you should see a larger field for your CSS.

CODE

 
function custom_css_input() {
	global $post;
	echo '<input type="hidden" name="custom_css_noncename" id="custom_css_noncename" value="'.wp_create_nonce('custom-css').'" />';
	echo '<textarea name="custom_css" id="custom_css" rows="35" cols="30" style="width:100%;">'.get_post_meta($post->ID,'rt_custom_css',true).'</textarea>';
}

cURL Project Application in C#

Over time, and out of necessity, I have been throwing together a few different tools over time using C# to help me cut down the amount of time it takes me to do certain things. As I create those I make them code generic so as to not include anything company wise and I like to share those projects so that others learning to code or who might be searching for code or projects might find them beneficial.

Testing in a QA/eCommerce environment, I use cURL pretty much daily for clearing Varnish cache when testing web pages across different staging servers and was curious about creating a wrapper for the curl.exe in C# that I could include within my standalone portable tool set. I did some research and although I did find several great resources I chose to stick it out with a Microsoft article I found titled How To Write a Wrapper for a Command-Line Tool with Visual C# .NET. The article gives a great explanation of creating a class file and adding it to a project.

The cURL Project Application

My cURL project simply needs to fulfill the function of issuing a purge command at whatever URL I give it so its geared with this specific task in mind. Normally I would stick the folder to the curl.exe file in my system PATH environment variable, open a command prompt and issue curl -X PURGE v1.cms.servername.com but the task, for me, is to include this within my “forms” tools that I created in c#.

Using CMD

Issuing the curl -X PURGE command in the command console would yield the results below. I just need the same thing in my tool which I can do using return “\t” + output in the class file start.cs.

 

curl_cmd

Using cURL Tool

The URL field is for the URL on the server I want to clear varnish cache for. The drop down boxes, respectively, retain the switch and command that I want to issue. The PURGE button simply runs the app and on success will give me a message dialog as shown in the second cURL graphic below. the drop down boxes actually have the switch and command respectively listed three times via loading an array in the form_load event. It’s because I may add a couple more items. If not then I will break these out of an array but still load them in the event.

Code follows as well as a ZIP file to download that contains the project and executable. Enjoy.

mycurlapp

 

curl_app01

Start.cs file based on the Microsoft article

The class can really just get by with using System.Diagnostics and using System.IO. Modify as you see fit for your project.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.IO;

namespace MyCurlApp
{
    public class start
    {
        internal static string Run(string exeName, string argsLine, int timeoutSeconds)
        {
            StreamReader outputStream = StreamReader.Null;
            string output = "";
            bool success = false;

            try
            {
                Process newProcess = new Process();
                newProcess.StartInfo.FileName = exeName;
                newProcess.StartInfo.Arguments = argsLine;
                newProcess.StartInfo.UseShellExecute = false;
                newProcess.StartInfo.CreateNoWindow = true;
                newProcess.StartInfo.RedirectStandardOutput = true;
                newProcess.Start();

                if (0 == timeoutSeconds)
                {
                    outputStream = newProcess.StandardOutput;
                    output = outputStream.ReadToEnd();
                    newProcess.WaitForExit();
                }
                else
                {
                    success = newProcess.WaitForExit(timeoutSeconds * 1000);

                    if (success)
                    {
                        outputStream = newProcess.StandardOutput;
                        output = outputStream.ReadToEnd();
                    }
                    else
                    {
                        output = "Timed out at " + timeoutSeconds + " seconds waiting for " + exeName + " to exit.";
                    }
                }

            }
            catch (Exception e)
            {
                throw (new Exception("An error occurred running " + exeName + ".", e));
            }
            finally
            {
                outputStream.Close();
            }
            return "\t" + output;

        }
    }
}

Main Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;

namespace MyCurlApp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string[] myList = new string[3];
            myList[0] = "-X";
            myList[1] = "-X";
            myList[2] = "-X";
            comboBox1.Items.AddRange(myList);
            comboBox1.SelectedIndex = 0;

            string[] myList2 = new string[3];
            myList2[0] = "PURGE";
            myList2[1] = "PURGE";
            myList2[2] = "PURGE";
            comboBox2.Items.AddRange(myList2);
            comboBox2.SelectedIndex = 0;

        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {

                string output;
                string arg1 = comboBox1.Text;
                string arg2 = comboBox2.Text;
                string arg3 = textBox1.Text;

                // My draconian error control. maybe use a switch case if ever using another paramter
                // than -X. I only purge with this.

                if (textBox1.Text == "" || comboBox1.SelectedItem.ToString() == null || comboBox2.SelectedItem.ToString() == null)
                {
                    //MB works good if textBox is empty
                    MessageBox.Show("Select a valid parameter or URL!");
                    return;
                }
                else
                {
                    // run if all is cool
                    output = start.Run("Curl.exe", " " + arg1 + " " + arg2 + " " + textBox1.Text, 10);
                    MessageBox.Show(output + "If blank, check the URL");
                }

            }
                //If fields are blank otherwise show any exceptions
                //Should always include basic try and catch in case an error occurs
                catch (NullReferenceException ex)
                {
                    MessageBox.Show("\nPerhaps you forgot to select something?\n" + ex.Message);
                }

                catch (Exception ex)
                {
                    MessageBox.Show("Well this isn't good! " + "\r\n" + ex.Message);
                }

        }

        private void button2_Click(object sender, EventArgs e)
        {
            string getcb = Clipboard.GetText(TextDataFormat.UnicodeText);
            textBox1.Text = getcb;
        }

    }
}

REFERENCES

Microsoft – How To Write a Wrapper for a Command-Line Tool with Visual C# .NET

DOWNLOAD

Windows 10 Security

Windows 10I was reading an article on the MakeUseOf website that I subscribe to about Windows 10 watching what you do. Not surprising that the Fix Windows 10 link on the page goes nowhere but there are at least two helpful apps in the article mentioned that are good for users who pay attention to the rumor mill of security issues that have been reported as concerns in Windows 10.

I’m somewhat a realist and do understand the pro’s and con’s of using Windows but ultimately go by the general golden rule that nothing is safe or secure. All of the recent hacks of data from big companies essentially enforces the same thing. I do however think it amazing how Windows users (of any version) complain about the lack of security and then cry foul when Microsoft actually implements more of it.

Microsoft is ultimately not only acting on the best interests of its user-base but the interest of its OS. A more solid product would obviously mean a more solid user-base, but like that’s even a problem for Microsoft. Anyway, that said I don’t plan to comment any further on the latter.

I have worked on a myriad of Windows PC’s though to know that the issue is not always Windows on its own but the sometimes idiot users using them. Users going to game sites, online movie streams, porn sites, whatever and not fully understanding what they are clicking on or otherwise getting themselves into.

User education on the proper use of Windows, for the most part, is still a must. I know people who are completely clueless on how do something as simple as sending an email let alone using a search engine. Certain aspects of the lack of computer education will certainly end in my generation while flourishing quite well in the next, such as my kids generation, as computers are almost mandatory in schools now as well as is computer education.

Changing to a different OS such as Linux or OSX, Chromebooks, Android, whatever, is not a real solution to security as some purport as each has their own set of security issues. In the old days hackers and script-kiddies wouldn’t even give MAC or Linux OS’s the time of day as they were not as widely used. Once these OS’s made their way more mainstream they then became an interest to them and vulnerable. Now we have seen the horror stories

I’m not going to side with these scrupulous people but I cant say I’m totally against what they are doing in showing the vulnerabilities of these OS’s. It would be nice if it could happen in less catastrophic ways but in some ways that’s what is necessary to get a point across. Politeness in notifying OS developers I don’t believe has ever statistically gone well. Ive worked around developers before and “some” have a chip on their shoulder that their code can do no wrong (denial), have an OH SHIT moment or sit on the issue too long until after it has become a major problem.

In any regard, I think Windows users should prepare themselves mentally for the future as Windows gradually gets more and more “security” features rolled into it. Not just to keep Windows echo system as safe as possible but to also save Windows users from themselves.

I’m expecting flack for some of this but right or wrong, I’m just speaking my mind while being open to criticism.

Changing Your Privacy Settings

If you want to change your privacy settings in Windows 10 to elect information you want to share with Microsoft:

From your Windows desktop, click on the Start menu and select Settings > Privacy.

For more info, see the item below in reading resources with regard to the Windows 10 and privacy FAQ.

Some good reading resources:

Preventing comments on the image attachment pages in WordPress

I think Don’t Tread On Me has pretty much lost its meaning these days, especially with regard to spamming. I really hate spam and wish nothing but wicked things to those who do it. In any event, lately I had started seeing spam type comments cropping up on image attachment pages of my site and in checking them out I had no idea that comments could even be placed on these pages. Perhaps I missed that in reading the WordPress Codex at some point or I just plain forgot.

I’m not sure why WordPress does not have a central settings area specifically for controlling comments but it would be nice. Essentially this is left to configuring by way of manual editing of code or using third party plug-ins and I question the necessity of the latter since it seems like a no-brainer to just add the functionality.

The way WordPress handles comments currently allows someone to click on a thumbnail of an image and that in turn displays the image as a post along with a comment area under it. I guess comments on individual images is valuable in some way?

picturespam_40

In any regard, it really drove me nuts whenever I would get a comment notification, review it and find it was on the image page in Russian, jibberish or just nonsense text so I decided to review some of the php files to look for anything related to comments.

I’m currently using the Misty Lake theme by Automattic and noticed in the Image Attachment Template (the image.php file) that towards the bottom it instantiated a call to comments_templates.

mistylake code_60

After making a backup of the image.php file, backups are always recommended, I used the editor in WordPress to removed the line, updated it, and now the comment area no longer appears on image attachment posts.

I will need to remember this moving forward should I ever update the theme as I am sure at some point the image.php file will be updated and I will need to manually remove the line again. Equally, should I change themes I will need to remember to double-check comments. It has actually been a few weeks since I made this manual modification and I have not experienced the spam as I was before. Hopefully the info will help someone.

Well, as an update to this, I decided to create my own custom-functions.php and add a function to do the above.

function DisableMediaComments( $open, $post_id ) {
$post = get_post( $post_id );
if ( 'attachment' == $post-&gt;post_type ) {
$open = false;
}
return $open;
}
add_filter( 'comments_open', 'DisableMediaComments', 10, 2 );

The code above should generically work within any theme. There is also another way, based on the comments_template line I removed from the theme I am using. Change the comments_template line from this:

<?php comments_template(); ?>

To this which will only show a Comments form if the parent post has comments enabled:

<?php if (comments_open($post->post_parent)) {
 comments_template();
} ?>

So with the above, if your post is enabled for comments then so will any attached images. Otherwise, if comments are disabled in the post, they will also be disabled for attached images. I believe I Googled the aforementioned and saw it on a few websites/forums so kudos go to whomever posted it first.

In any regard, I still elected for the function in my custom-functions.php file. To me its just easier that way and I don’t have to worry about any code changes to the theme.

C# Programming out of need – Getting IP and MAC Addresses

getipmac-ipThis is my C Sharp project for getting IP and MAC addresses. Code kudos go out to respective developers and websites, such as MSDN, stackoverflow, C# Corner and others I have left out but all code is in the public domain and modified by me to fit my needs.

As far as I am concerned my projects are as-is and there is nothing code efficient in my projects so please don’t beat me up too bad over any of it.

I am not a professional programmer in any regard but do consider myself a coder, this is just my slapped together get ‘er done tool befitting my personal need. If you want to comment on my project offline send me an email at stevegossett (AT) outlook.com

NOTE
You will need .NET 4.5 installed for this C# project and you will need to right-click on the
project name from within the IDE and add references to:

  • System.Management
  • System.Management.Instrumentation


Download Project

 

Nexus 7 First Gen (2012) – Flashing Lollipop Factory image

I got tired of waiting for Android Lollipop to become available for my Nexus 7 (2012) so decided to grab the factory image and flash it myself. I was pleasantly surprised at how easy this was to accomplish and so far I have not had any issues with Android 5.0. I even dare say that it seems faster than KitKat 4.4.4. I will run a Geekbench on it at some point.

First I downloaded the Android SDK and unzipped it to the root of my D: drive. I chose this location because it has been my experience that the folders run a bit deep and Windows Explorer will eventually bomb out on copying files. Unzipping to the root folder keeps the character count and folder names to a minimum.

nexus_ss2

Installing Google USB Driver

Once unzipped, I ran the SDK Manager under the root of the adt-bundle-windows-x86_64-20140702 folder, the folder name as of version currently available.

In the SDK Manager, I left what was currently checked, scrolled down to Extras, checked the box for Google USB Driver and clicked to install the packages.

When the packages were finished installing, I needed to install the Android USB driver on my system with Windows 7 Professional.

There is a guide for installing the Google USB driver on the various platforms of Windows here.

  1. Click on Start, right-click on Computer and select Manage.
  2. Select Device Manager on the left.
  3. On the right, under list of items under the computer name, look for Other device. It should already be expanded.
  4. Right-click the item name and select Update Driver. This will launch the Hardware Update Wizard.
  5. Select Browse my computer for driver software and click Next.
  6. Click Browse and navigate to the USB driver folder located in <sdk folder location>\extras\google\usb_driver\.) As an example, for me it was D:\adt-bundle-windows-x86_64-20140702\sdk\extras\google\usb_driver.
  7. Click Next to install the driver.
  8. I rebooted the system but don’t know that I exactly needed to.

Next I downloaded the factory image from Android Nexus images page under Factory Images “nakasi” for Nexus 7 (Wi-Fi) and then 5.0 (LRX21P) and unzipped it to the root of my D: drive (D:\nakasi-lrx21p-factory-93daa4d3) as well.

nexus_ss1

Add folder to Path System Variables

Now, I needed to start my Nexus in fastboot mode and opted to use the keys on the tablet rather than the adb tool in the Android SDK.

I know I’m going to use that tool later and opted to enter its folder location in my PATH system variable so I can run adb commands no matter what folder I was in.

I powered off my Nexus 7 and then pressed the volume up/down and power buttons at the same time until I saw the fastboot screen.

Opening a command console (CMD) as administrator on my computer I typed in the command to unlock the boot loader (This erases all data on the device):

At command line: fastboot oem unlock

I could see the confirmation on my Nexus 7 and saw the red text at lower left reflected it is now unlocked.

Next, in the command console window I navigated to the system image directory I unzipped earlier (for me D:\nakasi-lrx21p-factory-93daa4d3\nakasi-lrx21p) and typed the fast install command which started the flash process of the 5.0 image to my Nexus and waited out the process until it was done.

At command line: flash-all.bat

When the flash process is finished the command prompt will show to click any key to finish, the Nexus rebooted and I had a nice clean version of 5.0 Lollipop.

Before doing anything I re-locked the boot loader by turning off the tablet, booting to fastboot mode and from the command prompt issuing the command

At command line: fastboot oem lock

The text at the lower left confirms the lock was successful.

 

Resources

https://developer.android.com/sdk

https://developers.google.com/android/nexus/images

http://developer.android.com/tools/device.html

http://forum.xda-developers.com/showthread.php?t=1907796

Bitnami WordPress Virtual Machine

bitnami-wp-greyWhen pushing websites, even my own personal, I would rather screw up in a staged environment rather than pushing something live and finding out the site is hosed or dysfunctional in some way. I recently came across Bitnami’s site and saw that they had a free self-contained WordPress virtual machine (virtual appliance) so I thought I would give that a try and share a bit of the experience.  I currently run WordPress on my domain but simply wanted something I could use and stage on even if I lost connection with the net. Among using it as my stage environment, I can also use it for other things such as theme or plugin development.

How It Works

Essentially, the way this works is you are using a server that is running on your local computer, which the virtual machine is providing, and using your internet browser to log into that server like you would to log into any WordPress site but by its IP address (ex: http://123.123.123.123/wp-login) rather than a domain name like http://www.mysite.com.

The virtual machine contains a minimal Linux OS (Ubuntu Server 14.04.01 LTS) and a fully configured Bitnami application stack, meaning it has a group of all applications necessary to get started right away with WordPress such as the latest ready to run versions of WordPress, Apache, MySQL, Varnish, PHP and phpMyAdmin. You simply start the server, point your web browser to it and log in.

Caveat – Sort Of 

Ubuntu Server does not include a GUI but a command line by default so I decided to install as thin a desktop as possible that would be light on resources and give me basic functions in the OS and went with the lightweight Lubuntu LXDE desktop environment. The VM will only be used on my home network so security wise I’m only concerned with local login to the VM, and having the desktop will let me do admin stuff on the fly.

To install minimal Lubuntu desktop without all the recommended applications, once booted to the command line of the virtual machine:

  1. Type: sudo apt-get install –no-install-recommends lubuntu-desktop
  2. Click ENTER

If you get an error then drop to the root prompt and try it like below (you will be prompted for the admin login):

  1. Type: sudo su
  2. Click ENTER
  3. Type: apt-get install –no-install-recommends lubuntu-desktop
  4. Click ENTER

You will get a few prompts to answer, the VM will reboot and you will see the desktop login prompt. If you don’t see a blank username prompt to log into then click the drop down box and select Other.

bitnami1

Lubuntu Desktop Login

 

 

 

 

 

 

 

 

 

 

Access the Server (Virtual Appliance)

As explained on the Bitnami WordPress Virtual Machine webpage the default username and password are both “bitnami”. You may have seen a reminder of this during the first time the VM booted up. Once you have logged in the first time, you will be prompted for a new password so use that to log into the virtual machine.

Getting Started

Open a web browser and type in the IP address of the virtual machine. If you do not know it, look on the Bitnami command console window (if you did not install a desktop) or log into the server, go to System Tools > XTerm and type ifconfig at the terminal command prompt.

Your IP address will be listed as inet addr:XXX.XXX.XXX.XXX. On success, you will land on a very  plain and very bland sample WordPress page with Hello World in it. Under the META section, click on Log in or append /wp-admin.php to the end of the IP to get the WordPress login page (http://123.123.123.123/wp-login.php). From here, log in with the username: user and the password: bitnami to get to the WordPress dashboard, configure your settings, import data, install themes, etc., and you are off and running.

wp_login

WordPress Logon

 

 

 

 

 

 

 

 

 

I have a free WordPress account on WordPress.com but since getting my website some time ago I don’t use it as frequently since it lacks the ability of plugins and the flexibility that I need unless I pay a premium. For the cost of a premium account I can have my own so made no sense. I exported all the data from the free WordPress site using their export tool and imported into my website when I started it to save me some time. I used the same exported data, logging into the virtual machine and importing it from within WordPress. This gave me my content to work with and saved me quite a bit of time.

 

RESOURCES

Bitnami Learn More

Bitnami WordPress

Bitnami WordPress Wiki

Bitnami Virtual Applicance Quick Start Guide

How to Export and Import a WordPress Blog

WordPress Tools Export Screen

 

REQUIREMENTS

To install Bitnami WordPress Stack you will need:

  • Intel x86 or compatible processor
  • Minimum of 256 MB RAM
  • Minimum of 150 MB hard drive space
  • Compatible operating systems:
    • x86 or x64 Linux operating system.
    • Windows XP, Vista, 7, Windows 8 or Windows Server 2003 or greater.
    • OS X operating system.
  • VMware Workstation, VMware Player, or VirtualBox