Drupal 8 – Composer: updating, module installs, & external library support notes

This is a set of configuration steps used to setup the requirements for the Tulane Library website using Drupal. PHP-Composer with Bower and NPM integration is used for updating and installing Drupal core, modules, and libraries. Included are procedures, configurations, and websites with information.

Prerequisites – May be necessary on the composer system used for installation and updates.

  1. Use npm to install bower for package management on system. In this case it is installed globally with by using the -g option. If npm is not installed you will need to install that first, so use your operating system specific procedures to install npm.
    npm install -g bower

All command-line commands noted below should be run from the Drupal root folder where the site is downloaded to in the step #1.

  1. Downloaded initially prepared Drupal website with git. This site has been prepared by Campus IT and uses a Git repository. Website code is committed to the repository labeled as “/dev” where it will be uploaded to libdev8.tulane.edu
  2. Update composer.json file to support bower and npm as additional css and javascript package managers.

    Under in the repositories section, add asset-packagist.org as an additional repository.
    Look for “repositories” and add (commas as needed): { “type”: “composer”, “url”: “https://asset-packagist.org”> }
  3. Update site to current available Drupal version using composer. Use following commands:
    composer update drupal/core –with-dependencies
    drush updatedb
    – if Drush is working otherwise look at /update.php
    drush cache:rebuild
    – if Drush is working otherwise look in admin configuration > performance.
  4. Install Drupal modules needed for development and production work:

    composer –update-with-dependencies require ‘drupal/ctools’
    Activated: Chaos Tools
    composer –update-with-dependencies require ‘drupal/rabbit_hole’
    Activated: Rabbit Hole, Rabbit hole nodes, rabbit hole taxonomy
    composer –update-with-dependencies require ‘drupal/ds’
    Activated: Display Suite, Display Suite Extras, Display Suite switch views.
    composer –update-with-dependencies require ‘drupal/field_group’
    Activate: Field Groups module
    composer –update-with-dependencies require ‘drupal/token’
    Activate: token module
    composer –update-with-dependencies require ‘drupal/redirect’
    Activate: redirect module
    composer –update-with-dependencies require ‘drupal/entity_reference_revisions’
    Activate: Entity Reference Revisions module
    composer –update-with-dependencies require ‘drupal/autogrow’
    Activate: Autogrow module
    composer –update-with-dependencies require ‘drupal/metatag’
    Activate: Metatag module
    composer –update-with-dependencies require ‘drupal/imce’
    Activate: IMCE File Manager module
    composer –update-with-dependencies require ‘drupal/simplesamlphp_auth’
    Activate: SimpleSAMLphp Authentication module.
    composer –update-with-dependencies require ‘drupal/seckit’
    Activate: Security Kit module
    composer –update-with-dependencies require ‘drupal/securelogin’
    Activate: Secure Login module
    composer –update-with-dependencies require ‘drupal/antibot’
    Activate: Antibot module
    composer –update-with-dependencies require ‘drupal/honeypot’
    Activate: Honeypot module
    composer –update-with-dependencies require ‘drupal/webform’
    Activate Webform module
    composer –update-with-dependencies require ‘drupal/pathauto’
    Activate: Pathauto module
    composer –update-with-dependencies require ‘drupal/diff’
    Activate Diff module
    composer –update-with-dependencies require ‘drupal/slick’
    Activate: Slick and Slick UI modules. You must enable the Blazy, Media modules to install Slick.
    composer –update-with-dependencies require ‘drupal/auto_entitylabel’
  5. Installing external libraries with Composer as written about at:
    https://www.drupal.org/docs/8/modules/webform/webform-frequently-asked-questions/how-to-use-composer-to-install-libraries
    – This should help eliminate the warnings: Webform: External libraries and lay foundation for external libraries into drupal-root: /libraries. External libraries are needed for the Webform and Slick Carousel modules.
  6. From drupal root directory in terminal use:
    composer require wikimedia/composer-merge-plugin
    – installs the composer merge plugin to install separate libraries.
    – (untested!) May no longer be necessary after executing step #2.
    If you install these plugins, you may need to add the following to the composer.json file:
    Look for “config” and add:
    “fxp-asset”: { “installer-paths”: { “npm-asset-library”: “libraries”, “bower-asset-library”: “libraries” } }
  7. It may also be necessary to have the installer extender composer plugin installed:
    composer global require oomphinc/composer-installers-extender
  8. Edit Drupal root composer.json file to support npm and bower assets:
    Look for “extra”, add:
    – Added options may need commas for syntax.
    “installer-types”: [ “bower-asset”, “npm-asset” ],
    – Adds bower and npm support.

    “merge-plugin”: {
                “include”: [
                    “modules/contrib/webform/composer.libraries.json”
                ]
            },
    – informs composer to look in referenced composer.libraries.json file for installs.

    Look for “installer-paths” and confirm these additions or changes.
    “installer-paths”: { “core”: [“type:drupal-core”], “libraries/slick”: [ “bower-asset/slick-carousel”, “npm-asset/slick-carousel” ], “libraries/{$name}”: [ “type:drupal-library”, “type:bower-asset” ]
    – Add /library folder location. You may need to create this location drupal-root:/libraries
  9. From terminal in drupal root:
    composer update –lock
    – update lock, usually finishes install

    Follow up install checks:
    composer update –with-dependencies
    – to perform full updates

Helpful info: https://www.drupal.org/project/slick/issues/2855190
More notes: https://www.drupal.org/project/lightning/issues/3014759
Troubleshoot composer bower integration: https://www.drupal.org/project/lightning/issues/3014759
Composer & Bower integration, path configurations: https://www.drupal.org/project/slick/issues/2907371#comment-12882235
Slick Carousel requirements with bower integration notes – has set of command-line commands.: https://git.drupalcode.org/project/slick/blob/8.x-1.x/README.md
Installing External libraries requited by a Drupal module: https://www.drupal.org/docs/7/modules/libraries-api/installing-an-external-library-that-is-required-by-a-contributed-module
Helpful information about Composer and Bower integration including npm, bower, composer installations: https://gist.github.com/macagua/d85f8790dba9c0ad2745926937b2d240

Install slick libraries with bowser integration.

This is an example to install the slick-carousel library using composer with bower integration.

composer require bower-asset/slick-carousel

To install specific versions use:

composer require bower-asset/slick-carousel:dev-master
— Note: some external javascript requited use of dev-master versions.
— It will be necessary to update the drupal-root:/composer.json file, and you should also check the required areas.

To check versions of installed packages with composer use:
composer show

Github – create token to download slick assets. From command-line output of above. Can also be regenerated at github.com.

Installing Recommended Drupal Core updates with Composer
composer update drupal/core-recommended –with-dependencies

Here’s the source article http www frederico araujo…

Here’s the source article:
http://www.frederico-araujo.com/2011/07/30/installing-rails-on-os-x-lion-with-homebrew-rvm-and-mysql/

My goals here are to update an environment and move to a new Susy release: http://susy.oddbird.net/

1. Install and upgrade XCode from the Mac App Store (4.3.2 in this case). Also install the Command Line Tools found in the Preferences pane.

2. Install Homebrew. Not entirely necessary, but I’m enjoying it lately.

Install Homebrew Package Manager
$ /usr/bin/ruby -e "$(/usr/bin/curl -fsSL https://raw.github.com/mxcl/homebrew/master/Library/Contributions/install_homebrew.rb)"

3. Install RVM – Ruby Version Manager

// Install RVM
$  bash -s master < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)
// Reset some paths
$ echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" # Load RVM function' >> ~/.bash_profile
// Run to reset your open terminals
$ source ~/.bash_profile
// Make sure RVM is updated
$ rvm get stable
// Had to do a reinstall for Ruby stable
$ rvm reinstall 1.9.3-p194
// Use Ruby 1.9.3-p194
$ rvm use 1.9.3-p194 --default
// Check my ruby version
$ ruby -v

4. Install Compass

// Make sure all is good
$ sudo gem update --system
// Some XML Tools
$ sudo gem install builder
// Install Compass
$ sudo gem install compass
// Here's where things went wacky, so Installed the kitchen sink - over-install-panic-attack!
$ sudo gem install haml
$ sudo gem install haml-edge
$ sudo gem install rails
// Oh it's a damn bug see: 
// http://stackoverflow.com/questions/10610254/cant-install-compass-via-rvm
$ rubygems-bundler-uninstaller
// Test Compass
$ compass version

5. Install my favorite Compass add-ons

// Oily_PNG to for sprite creation performance
$ sudo gem install oily_png
// Susy because grids are awesome - Now this will install some alpha SASS and Compass code but why not.
$ sudo gem install susy --pre
// Normailze CSS sortof-reset
$ sudo gem install compass-normalize

Unfollow Non-twitter followers


// ==UserScript==
// @name           Twitter Remove Non-Followers
// @namespace      http://userscripts.org/users/28
// @description    Remove Twitter friends who don't follow you back. Click the "Remove marked users" button at the bottom of the list to activate.
// @include        http*://*twitter.com/following*
// @include        http*://*twitter.com/*/following*
// ==/UserScript==

/*
ABOUT
=====

This script highlights the "remove" buttons for "friends" who don't follow you 
back on your Twitter Friends pages. A new action button is added at the bottom
of the page. When you click this button, all marked friends will be removed.

The scrip marks only users who:
<ul>
<li>don't follow you ("don't return the love")</li>
<li>have their updates unprotected (you can always remove these manually if you want).</li>
</ul>
By default, no action is taken, so you have the chance to inspect which users will
be removed before clicking the "Remove Marked" button.

Auto-mode: set property TwitterRemoveNonFollowers.autoMode to true and open
the "following" page, http://twitter.com/following
The script will auto-advance one page at a time.


NOTE: make sure you also allow scripts included from twimg.com if you're using the NoScript add-on!!!

LICENSE
=======

(c) 2009 Johannes la Poutre


This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA


CHANGELOG
=========

Version 1.23 - 20091005
	- Fix for auto mode: just follow "next" link

Version 1.23 - 20090915
	- Fix for changed Twitter CSS
	- Thanks Coree Silvera for letting me know!

Version 1.22 - 20090820
	- Minor fix when running in auto-mode
	- Added note about NoScript

Version 1.21 - 20090702
	- Extra @include rule for /username/following pages

Version 1.20 - 20090702
	- complete rewrite for new Twitter user interface

Version 1.01 - 20090403
	- updated color scheme, removed debugging code

Version 1.00 - 20090403
	- initial release
	- does NOT remove users whose timeline is protected

*/

var TwitterRemoveNonFollowers = {
	hitlist: [], // the list of 'friends' to remove
	autoMode: false,
	authenticity_token: '',
	
	init: function() {
		// select users w/o DM command link and no Lock icon image
//		var rows = document.evaluate("//button[contains(@class, 'remove-button')][not(following-sibling::span/a[contains(@href, '/direct_messages/create/')])]", 
//					document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
//		<tr id="user_15356378" class="user following direct-message-able odd">
		var rows = document.evaluate("//tr[contains(@class, 'following')][not(contains(@class, 'direct-messageable'))]", 
					document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
		for (var i = 0; i < rows.snapshotLength; i++) {
			var btn = rows.snapshotItem(i);
			btn.style.backgroundColor = '#bbb';
			btn.setAttribute('class', 'user following');
			// id="user_20707860"
			var id = rows.snapshotItem(i).getAttribute('id').substring(5);
			this.hitlist.push(id);
		}
		if (this.hitlist.length) {		
			this.authenticity_token = unsafeWindow.twttr.form_authenticity_token;
			var rmBtn = document.createElement('input');
			rmBtn.setAttribute('type', 'button');
			rmBtn.setAttribute('id', 'TwitterRemoveNonFollowersBtn');
			rmBtn.setAttribute('value', 'Remove marked (' + this.hitlist.length + ')');
			rmBtn.setAttribute('style', 'float:right;border: 1px solid lime');
			document.getElementById("pagination").appendChild(rmBtn);
			rmBtn.addEventListener('click', function() {
					rmBtn.setAttribute('disabled', 'disabled');
					rmBtn.style.border = '1px solid silver';
					TwitterRemoveNonFollowers.remove(); 
				}, true);
			if (this.autoMode) {
				rmBtn.click();
			}
		} else {
			if (this.autoMode) {
				this.nextPage();
			}
		}
		// FIX...
		unsafeWindow.alert = function(msg) {
			GM_log("" + msg);
		}
	},
	
	nextPage: function() {
		var rows = document.evaluate("//a[contains(@rel, 'next')]", 
					document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
		if (rows.snapshotLength) {
			var next = rows.snapshotItem(0);
			var link = next.getAttribute('href');
//			var page = link.match(/page=(\d+)/)[1];
//			if (parseInt(page, 10) > this.keepPages) {
				if (0 === link.indexOf('/')) {
					link = window.location.protocol + '//' + window.location.host + link;
				}
				GM_log(link);
				window.location.href = link;
//			}
		}
	},
	

	remove: function() {
		if (this.hitlist.length) {
			document.getElementById("TwitterRemoveNonFollowersBtn").setAttribute('value', 'Removing: ' + this.hitlist.length + ' to go...');
			
			// use native XMLHttpRequest otherwise the referrer gets not set correctly
			var data = 'authenticity_token='+this.authenticity_token+'&twttr=true';
			var uid = this.hitlist.shift();
			var url = window.location.protocol + '//' + window.location.host +'/friendships/destroy/' + uid;
			var req = new XMLHttpRequest();
			req.onreadystatechange =  function() {
					TwitterRemoveNonFollowers.remove_callback(req, uid);
				};
			req.open("POST", url, true);
			req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
			req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
			req.setRequestHeader("Accept", "application/json, text/javascript, */*");
			req.setRequestHeader("Referer", window.location.href);
			req.setRequestHeader("Content-Length", data.length);
			req.send(data);
			// id="user_20707860"
			document.getElementById('user_'+uid).style.backgroundColor = 'orange';
			
			setTimeout(function() { TwitterRemoveNonFollowers.remove(); }, 1000);
		} else {
			document.getElementById("TwitterRemoveNonFollowersBtn").setAttribute('value', 'All done.');
			if (this.autoMode) {
				this.nextPage();
			}
		}
	},
	
	remove_callback: function(req, uid) {
	    if (req.readyState == 4) {
	        // only if "OK"
	        if (req.status == 200) {
			// {"result":"unfollowed","success":true}
			// GM_log(req.responseText);
			document.getElementById('user_'+uid).style.display = 'none';
	        } else {
			GM_log("There was a problem retrieving the XML data:\n" + req.statusText);
				document.getElementById('user_'+uid).style.backgroundColor = 'red';
	        }
	    }
//		GM_log(req.responseText);
	}
};

TwitterRemoveNonFollowers.init();

WordPress Post Types and Custom Taxonomy Articles

I’m putting links to these two articles together. Understanding both makes things magical.

WordPress Custom Taxonomy Input Panels

http://new2wp.com/pro/wordpress-custom-post-types-object-oriented-series2/

The test for feeding out text/css from a custom post type:
http://work.funroe.net/wp_t/viewmaker/1-viewmaker-css/

Mac OSX 10.6 Shell Script to Configure, Launch, and Shutdown Screen Sharing

Apple’s MacOS has a tidy built in remote access client and service generically known as “Screen Sharing”. Yay! This works great for headless machines, testing servers, and annoying your spouse. The paranoid and performance conscious user may not want these services continuously running. Rogue services hanging out, listening, and waiting for some punk to probe them in an Internet dark alley. This cobbled together shell script might be for you!

This shell script has four simple commands (I use sudo because I really should):

  • # sudo ./share-screen.sh start
  • # sudo ./share-screen.sh stop
  • # sudo ./share-screen.sh allow {username}
  • # sudo ./share-screen.sh deny {username}

I use this in terminal. Make sure you put a copy of this script on the target machine and make it executable. First I make sure that Remote Login is active on the target computer. It’s under Sharing in System Preferences. Then I login remotely using ssh. I fire up the script, activate Screen Sharing, do my business, shutdown Screen Sharing, log off, and go home.

Of course, no warranty, no guaranty. Good Luck!

#!/bin/bash

if [ $# == 0 ]; then
	echo  "Commands: start, stop, allow <username>, deny <username>"
	exit
fi

case "$1" in
	start)
		echo 'Starting Remote Access'
		# Activate Apple Remote Access with current settings
		sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -activate
		;;
	stop)
		echo 'Stopping Remote Access'
		# Deactivate Apple Remote Access
		sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -deactivate -stop
		;;
	allow)
		if [ -z "$2" ]; then
			echo  "ERROR: Provide a valid user"
			exit
		fi
		sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -configure -allowAccessFor -specifiedUsers
		sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -configure -access -on -privs -all -users ${2}
		;;
	deny)
		if [ -z "$2" ]; then
			echo  "ERROR: Provide a valid user"
			exit
		fi  
		sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -configure -allowAccessFor -specifiedUsers
		sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -configure -access -off -privs -none -users ${2}  
		;;  
esac

I almost forgot. Credit where credit is due! Inspiration from these articles and resources:

http://www.macosxhints.com/article.php?story=20080318190503111

https://rentzsch.tumblr.com/post/515009165/starting-vnc-remotely-via-kickstart

My Reply to E-mail with Text File AppleScript

At work I deal with a large volume of e-mail. There just aren’t enough people to handle all the e-mail requests or questions. When I have people to help handle e-mail, I still answer some of the same questions over and over and over. You just don’t want to know the volume or scope of my daily e-mail chores.

As a long time MacOS user I have repeatedly turned to AppleScript as a useful tool for dealing with making the same e-mail replies constantly (the real solution is to fix the breakdown in communication, but that’s a whole other story). Here is the most recent incarnation of my AppleScript solution using Apple Mail on MacOS 10.6.

My solution is simple; Highlight the message, run the script, select a pre-written text file to include, customize the reply, and send. The respondent gets a solution or reply that is usually edited over time for clarity, and I get to customize it a bit so it doesn’t seem too much like an auto-reply.

tell application "Mail"
		
	set theSelection to selection
	set theSelectedMessage to item 1 of theSelection
	set theSelectedMessageSender to sender of theSelectedMessage
	
	set theSelectedMessageSenderName to extract name from sender of theSelectedMessage
	set theSelectedMessageSenderAddress to extract address from sender of theSelectedMessage
	
	set theSelectedMessageSubject to subject of theSelectedMessage
	set theSelectedMessageContent to content of theSelectedMessage
		
	set myHomeDefault to the path to home folder
	set myHomeDefault to myHomeDefault & "nicholls:Documents:e-mail_templates:" as text
	set myHomeDefault to myHomeDefault as alias
		
	set myTemplateFile to (choose file with prompt "Select E-mail Template File:" of type {"TEXT"} default location myHomeDefault)
	
	open for access myTemplateFile
	set prefsContents to read myTemplateFile using delimiter {"#--#"}
	close access myTemplateFile
	set MessageText to item 1 of prefsContents
		
	set theMessage to make new outgoing message with properties {visible:true, subject:"Re: " & theSelectedMessageSubject, content:MessageText & theSelectedMessageContent}
	tell theMessage
		make new to recipient at end of to recipients with properties {name:theSelectedMessageSenderName, address:theSelectedMessageSenderAddress}
		make new bcc recipient at end of bcc recipients with properties {name:"Website Manager", address:"nichweb@nicholls.edu"}
	end tell
end tell

This is a sample text file I might use. I made this really basic. You should note the #–# deliminator used. I have that so I can do some other interesting things with the templates, like BCC: my boss if I have too. Anyway this would be saved something like email-reply-standard.txt and I would load it through the dialog created by the script when it runs.

Thank you for your interest!


If you have further questions, please let me know.

Jess Planck

 ----------------------------
 Nice Signature with phone 
 ----------------------------
 Probably has the website too
 
----[ Your Original Message Follows ]----

#--#

For some reason the syntaxhighligher I’ve got here doesn’t like AppleScript comments, so I’ve removed them.

My Ugly WordPress, HyperDB, & BuddyPress Deployment Shell Script

This is the source of some of the website deployment scripts I have. This is one is fairly complex and it is my pocket tool of choice for development of big nasty WordPress sites. Probably only interesting to folks who deal with unix shells and do mildly heavy WordPress work.

It’s designed to update from SVN trunk for WordPress, HyperDB, & BuddyPress. My favorite is quick rsync for folders and subfolders so you can upload theme changes quickly because the web is my sketchpad.

Common List of Commands:

# Get the configured site 
./wp-work.sh get
# Put the configured site 
./wp-work.sh put
# Upgrade the configured site to latest WordPress, HyperDB, &amp; BuddyPress
./wp-work.sh upgrade
# Put specific folders in the sites root
./wp-work.sh work put the-site-folder
# get specific folders in the sites root
./wp-work.sh work get the-site-folder

The Big Ugly Script:

You will really want to customize the top values for sure.

#!/bin/sh

# Batch Update jess
#
# Uses flat array list of site locations, updates using latest source from SVN and performs all update steps.
#

# Website Name
WEB_ROOT_NAME="example.com"

# Web Direcory locations Using $HOME is good.
WEB_ROOT_LOCAL="${HOME}/luser/${WEB_ROOT_NAME}/"
WEB_ROOT_REMOTE="/home/luser/${WEB_ROOT_NAME}/"

# Archive -a mode is -rlptgoD -pgo is permission, user, group and be an issue had to add -vz
RSYNC_SWITCH='-vzrltD'
# SSH command because you might need: 'ssh -i /shh/secret-key/master-magic-key -p 56232'
RSYNC_SSH='ssh'
# Remember the ssh account is where your files land.
RSYNC_SSH_ACCOUNT='me@example.com'

# Tools location for exclude files ans stuff. Using $HOME is good.
TOOLS_ROOT_LOCAL="${HOME}/luser/stuff/"
TOOLS_ROOT_EXCLUDES="${HOME}/luser/stuff/"

# Temp files
TEMP_ROOT_LOCAL="${HOME}/luser/tmp/"

# Putting the path into a variable gets tricky
WORKING_TEMP_LOCATION=$( readlink -nf ${TEMP_ROOT_LOCAL} )

# Move to tools directory so we can find things easier.
cd ${TOOLS_ROOT_LOCAL}

# Print good ole help if no command
if [ $# == 0 ]; then
	echo  "${WEB_ROOT_NAME} Commands: get, put, upgrade, work [put or get] [directory]"
	exit	
fi

# Get all remote
if [ $1 == "get" ]; then
  echo '----- Start Site Download -----'
  echo  "Get all stuff with a few exceptions."
  rsync ${RSYNC_SWITCH} --delete -e "${RSYNC_SSH}" ${RSYNC_SSH_ACCOUNT}:${WEB_ROOT_REMOTE} ${WEB_ROOT_LOCAL}
  exit
fi

# Put all with some exceptions
if [ $1 == "put" ]; then
  echo '----- Start Site Upload -----'
  echo  "Put all stuff with a few exceptions."
  rsync ${RSYNC_SWITCH} --delete --exclude-from=${TOOLS_ROOT_EXCLUDES}wordpress-exclude.txt -e "${RSYNC_SSH}" ${WEB_ROOT_LOCAL} ${RSYNC_SSH_ACCOUNT}:${WEB_ROOT_REMOTE}
  exit
fi

# Upgrade with merge from several sources
if [ $1 == "upgrade" ]; then

	echo  "Don't have this for work.funroe.net"

	exit
	
	mkdir ${WORKING_TEMP_LOCATION}
	mkdir ${WORKING_TEMP_LOCATION}/wordpress
	mkdir ${WORKING_TEMP_LOCATION}/buddypress
	mkdir ${WORKING_TEMP_LOCATION}/hyperdb
	
	svn co http://svn.automattic.com/wordpress/trunk/ ${WORKING_TEMP_LOCATION}/wordpress/
	svn co http://svn.buddypress.org/trunk/ ${WORKING_TEMP_LOCATION}/buddypress/
	svn co http://svn.wp-plugins.org/hyperdb/trunk/ ${WORKING_TEMP_LOCATION}/hyperdb/
	 
	mv -f ${WORKING_TEMP_LOCATION}/buddypress ${WORKING_TEMP_LOCATION}/wordpress/wp-content/plugins/buddypress
	mv -f ${WORKING_TEMP_LOCATION}/hyperdb/db.php ${WORKING_TEMP_LOCATION}/wordpress/wp-content/db.php
	
	echo '----- Update local site -----'
	rsync ${RSYNC_SWITCH} --delete --exclude-from=${TOOLS_ROOT_EXCLUDES}wpmu-bbpres-bp-exclude.txt  ${WORKING_TEMP_LOCATION}/wordpress/ ${WEB_ROOT_LOCAL}
	
	echo  "----- Remove temp working directory! -----"
	rm -Rf ${WORKING_TEMP_LOCATION}
	
	echo  "----- Update remote site! -----"	
	rsync ${RSYNC_SWITCH} --delete --exclude-from=${TOOLS_ROOT_EXCLUDES}wordpress-exclude.txt -e "${RSYNC_SSH}" ${WEB_ROOT_LOCAL} ${RSYNC_SSH_ACCOUNT}:${WEB_ROOT_REMOTE}
	echo '----- DONE! -----'
	
	exit
fi

# Work allows get and put of specific directories starting at web root ie. this.command work put wp-content/themes
if [ $1 == "work" ]; then

 	# Putting the path into a variable gets tricky
 	WORKING_LOCAL_LOCATION=$( readlink -nf ${WEB_ROOT_LOCAL}${3} )
	
	if [ ! -d "${WORKING_LOCAL_LOCATION}" ]; then
		if [ ! -f "${WORKING_LOCAL_LOCATION}" ]; then
			 echo "Not a valid work site! Please try again."
			 exit
		fi
	fi
	
	# Set remote location
	WORKING_REMOTE_LOCATION=${WEB_ROOT_REMOTE}${3}
			
	# Add slashes to end if they were omitted
	if [ `echo "$WORKING_LOCAL_LOCATION" | grep "[^/]$"` ]; then 
		WORKING_LOCAL_LOCATION="${WORKING_LOCAL_LOCATION}/"; 
		WORKING_REMOTE_LOCATION="${WORKING_REMOTE_LOCATION}/"; 
	fi
	
	# Remove double slashes
	WORKING_LOCAL_LOCATION=${WORKING_REMOTE_LOCATION//\/\//\/}	
	WORKING_REMOTE_LOCATION=${WORKING_REMOTE_LOCATION//\/\//\/}

	echo "rsync ${RSYNC_SWITCH} --delete --exclude-from=${TOOLS_ROOT_EXCLUDES}wordpress-exclude.txt -e "${RSYNC_SSH}" ${WORKING_LOCAL_LOCATION}  ${RSYNC_SSH_ACCOUNT}:${WORKING_REMOTE_LOCATION}"

	if [ $2 == "get" ]; then
	  echo "----- Get All ${WEB_ROOT_NAME} -----"
	  echo  "Downloading all work.funroe.net/$work_site files..."
	  rsync ${RSYNC_SWITCH} --delete -e "${RSYNC_SSH}" ${RSYNC_SSH_ACCOUNT}:${WORKING_REMOTE_LOCATION} ${WORKING_LOCAL_LOCATION}
	  exit
	fi
	
	if [ $2 == "put" ]; then
	  echo "----- Put ${WEB_ROOT_NAME} -----"
	  echo  "Uploading selected work.funroe.net/$work_site files..."
      rsync ${RSYNC_SWITCH} --delete --exclude-from=${TOOLS_ROOT_EXCLUDES}wordpress-exclude.txt -e "${RSYNC_SSH}" ${WORKING_LOCAL_LOCATION}  ${RSYNC_SSH_ACCOUNT}:${WORKING_REMOTE_LOCATION}
	  exit
	fi	

fi

Exclude file: wordpress-exclude.txt needs to be in that TOOLS_ROOT_EXCLUDES directory. I use it skip stuff that I don’t want to be synced on upload because the remote file changes are most important.

.htaccess
wp-config.php
bb-config.php
cache/
blogs.dir
uploads
wp-content/advanced-cache.php
wp-cache-config.php
sitemap.xml.gz
robots.txt
sitemap.xml
googlee-thingyfile.html

Exclude file: wpmu-bbpress-bp.txt needs to be in that TOOLS_ROOT_EXCLUDES directory. This is to keep files from being overwritten when a package is created from the SVN repositories and moved to the local site staging area. This really may need customized to protect your personal themes, plugins, and files.

# WP Core excludes
- .htaccess
- wp-config.php
- bb-config.php
- /cgi-bin
- /cache
- blogs.dir
- uploads

# Themes
+ themes/index.php
+ themes/classic
+ themes/default
+ themes/twentyten
- themes/*

# Plugins
+ plugins/readme.txt
+ plugins/index.php
+ plugins/buddypress
- plugins/*

# MU Plugins
+ mu-plugins/readme.txt
+ mu-plugins/index.php
- mu-plugins/*

# Hyper DB
- db-settings.php

Tommy’s diggall.sh revised

Think you know the linux digg command? Ever try to do some simple network discovery with it? This script by Tommy Johnson does some nice condensed discovery. Just pass a domain for the argument.

./diggall.sh example.com

That is all!

#!/bin/bash
echo "MX points to:"
dig MX $1 +short | sort -n
echo ""
echo "A points to:"
dig A $1 +short
echo ""
echo "www points to:"
dig A www.$1 +short
echo ""
echo "mail points to:"
dig A mail.$1 +short
echo ""
echo "SOA Nameserver declared:"
echo `dig SOA $1 +short | awk '{print $1}'`
echo ""
#echo "oldmail points to:"
#dig A oldmail.$1 +short
domain1=( $(echo $1 | awk -F '.' '{print $1}'))
domain2=( $(echo $1 | awk -F '.' '{print $2}'))
domain3=( $(echo $1 | awk -F '.' '{print $3}'))
domain2=( $(echo $domain2.$domain3 | sed 's/[:.:]$//') )
first=( $(dig NS +short $domain2 | sed 's/[:.:]$//') )
second=( $(dig +short NS $domain2 @$first | sed 's/[:.:]$//') )
#echo "Authoritative nameserver for TLD is: "$second
#echo '+===============================================+'
echo "Name Servers as reported by registrar:"
echo `dig NS $domain1.$domain2 @$second | grep "AUTHORITY SECTION" -A3 | grep -v AUTHORITY | awk '{print $5}'`
echo "IPs declared by registrar:"
echo `dig NS $domain1.$domain2 @$second | grep "ADDITIONAL SECTION" -A3 | grep -v ADDITIONAL | awk '{print $5}'`
#echo '+===============================================+'
echo ""
echo "Name Servers in zone file are:"
dig NS $1 +short
dig NS $1 | grep "ADDITIONAL SECTION" -A3 | grep -v ADDITIONAL | awk '{print $5}'
echo "txt record is:"
dig txt $1 +short