Bash Script to Restore Tmux Session After Reboot

Listen to this Post. Powered by iSpeech.org

I first learned about Tmux from this SitePoint article. And it’s awesome. I don’t need to open 3-4 terminals anymore for my everyday work.

Anyway, what I’ll talk about here is a way to restore Tmux sessions after you reboot your computer. Actually, “restore” is the wrong word since as of now, you can’t store Tmux sessions (as of now). But, you can script it.

Here’s my take on the whole thing:

#!/bin/bash
#/home/ryann/scripts/restoretmux.sh
 
SESSIONNAME="work"
tmux has-session -t $SESSIONNAME $> /dev/null
 
if [ $? != 0 ]
	then
		# new session with name $SESSIONNAME and window 0 named "base"
		tmux new-session -s $SESSIONNAME -n base -d
		tmux split-window -t $SESSIONNAME:0 -h
 
		# new window for asterisk-billing project
		tmux new-window -t $SESSIONNAME:1 -n "asterisk-billing"
		tmux split-window -t $SESSIONNAME:1 -h
		# set directory for right pane
		tmux send-keys 'cd /home/ryann/projects/asterisk-billing/html/' 'C-m'
		# switch to left pane and set directory
		tmux select-pane -t $SESSIONNAME:1 -L
		tmux send-keys 'cd /home/ryann/projects/asterisk-billing/' 'C-m'
 
		## new window for processwire project
		tmux new-window -t $SESSIONNAME:2 -n "processwire"
		tmux split-window -t $SESSIONNAME:2 -h
		tmux send-keys 'cd /home/ryann/projects/processwire/build/processwire/' 'C-m'
		tmux select-pane -t $SESSIONNAME:2 -L
		tmux send-keys 'cd /home/ryann/projects/processwire/build/' 'C-m'
 
		## switch the "base" window
		tmux select-window -t $SESSIONNAME:0
fi
 
tmux attach -t $SESSIONNAME

I just then run /home/ryann/scripts/restoretmux.sh on the terminal and I get my Tmux session with 3 windows and 2 panes each.

How to Create and Delete System Templates in Processwire API

Listen to this Post. Powered by iSpeech.org

processwireAfter poring through Processwire’s awesome code for the past few hours, I’ve finally figured out how to create and delete system templates using Processwire’s API.

But, before I show you the code, a little background on why I needed one in the first place.

I’ve been creating this workflow module and wanted to create templates and fields that regular users won’t be able to use or delete. That’s the main reason. The second reason is simply because I thought it’d be cool to know how :D

Anyhow, here is the code for creating a system template:

/* We first make sure the template doesn't exist */
$temp = $this->templates->get($tname);
if(is_null($temp)){
   /* Every template needs a fieldgroup to add fields in */
   $fg = $this->fieldgroups->get($tname);
   if(!$fg){
      $fg = new Fieldgroup();
      $fg->name = $tname; //fieldgroup and template have the same name
      $fg->add($this->fields->get('title')); //required field
      $fg->save();
   }
 
   /* create our template */
   $temp = new Template();
   $temp->name = $tname;
   $temp->fieldgroup = $fg;
   $temp->noGlobal = 1;
   $temp->nameContentTab = 1;
   $temp->flags = $this->template->flags | Template::flagSystem;
 
   /* just something extra to let the user know what happened */
   if($temp->save()){
      $this->message('Created template: ' . $tname);
   } else {
      $this->error('Problem creating template: ' . $tname);
   }
}

And this is how you delete a system template:

$tname = 'mytemplate';
$temp = $this->templates->get($tname);
if(!is_null($temp)){
   //try to delete our custom template
   try{
      $fg = $temp->fieldgroup;
 
      $temp->flags = Template::flagSystemOverride;
      $temp->flags = 0;
      $temp->save();
 
      if($this->templates->delete($temp)){
         $this->message('Removed template: ' . $tname);
      } else {
         $this->message('Could not remove template: ' . $tname);
      }
 
      //TODO: check if other templates are using fieldgroup??
      $this->fieldgroups->delete($fg);
 
   } catch(Exception $e){
      //this can happen if *someone* uses our holder templates. not really sure
      $this->error('Fatal error while deleting template: ' . $tname);
   }
}

The core file I’ve looked at for creating the system template was wire/modules/Process/ProcessTemplate/ProcessTemplate.module within the executeSave() method.

For deleting, this was the forum thread that helped me: http://processwire.com/talk/topic/572-release-discussions/?p=4657

Sync (Push) from Local to Remote Database Using Capistrano

Listen to this Post. Powered by iSpeech.org

So, I could already deploy my site from local to remote using Capistrano. This was the easy part. Now, I needed to push my database from local to remote. Previously, what I did was to go to get a database dump of my local, go to remote database, drop/empty the tables in the target database and import the sql file I got from local. I was lazy, so I wanted something more… automatic :) At the same time, I also wanted to learn how to create custom capistrano tasks.

So, here’s my recipe:

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
namespace :db do
   desc "Push db from local to remote"
   task :push, :roles => :web do
      random = rand( 10 ** 5 ).to_s.rjust( 5, '0' )
      filename = "pwcap-#{random}.sql"
      temp = "/tmp/#{filename}"
 
      puts 'db:push'
      puts stage
      l = wpdb[:local]
      r = wpdb[stage]
      puts "executing: mysqldump -u #{l[:user]} --result-file=#{temp} -h #{l[:host]} -p#{l[:password]} #{l[:name]}"
      system "mysqldump -u #{l[:user]} --result-file=#{temp} -h #{l[:host]} -p#{l[:password]} #{l[:name]}"
 
      #upload sql file to remote
      upload("#{temp}", "#{temp}", :via => :scp)
 
      remote_mysql = "mysql -u #{r[:user]} -p#{r[:password]} -h #{r[:host]} #{r[:name]}"
 
      ##
      # drop tables in remote database
      ##
 
      #get list of tables and prepare db command
      puts "DROPPING TABLES"
      tables = capture "#{remote_mysql} -e " + '"show tables;"'
      tables = tables.split(/$/).map{|t| t.strip}.reject{|t| t.empty?}
      tables.shift
      sql_drop = "DROP TABLE " + tables.map{|t| "#{t}"}.join(', ') + ';'
      puts sql_drop
      #run db command
      run remote_mysql + ' -e "' + sql_drop + '"'
 
      ##
      # Import db
      ##
      run "#{remote_mysql} < #{temp}"
 
      #cleanup
      run "rm #{temp}"
   end
end

I then run the command: cap STAGE_NAME db:push and capistrano does the rest.

This is assuming you have a multistage set-up i.e. dev, staging, production

and somewhere in your configuration, have the following:

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#Database
#Set the values for host, user, pass and name for all stages
set :wpdb do
   {
      :local => {
         :host     => 'localhost',
         :user     => 'username',
         :password => 'password',
         :name     => 'databasename',
      },
      :dev => {
         :host     => 'localhost',
         :user     => 'username',
         :password => 'password',
         :name     => 'databasename',
      }
   }
end

How to Edit a Remote File over SSH Using Sublime Text and Rmate

Listen to this Post. Powered by iSpeech.org

I wanted to be able to edit a file in my computer but have it save on the remote server.

That’s when I found the rsub plugin for Sublime Text 2 and rmate.

What does Rmate do?

Rmate is a script that you install on the remote server – the server you want to edit files from. It was originally created for Textmate.

Basically, what it does is when you run this script on a file, it sort of *pushes* that file from the remote server down to your computer where your text editor – Sublime Text or Textmate – is waiting to *catch* it. Well, that’s the for dummies (like me) explanation. Technically, we use an SSH tunnel or something.

What does Rsub do?

Rsub is a plugin that you install on Sublime Text 2. This is the thing allows ST2 to *catch* the file *pushed* down from the server and edit the file.

Installation and Setup

  1. Install rsub plugin for ST2.
  2. SSH to your remote machine: ssh user@remote.com
  3. Download Rmate: curl https://raw.github.com/aurora/rmate/master/rmate > rmate
  4. Move Rmate to bin: sudo mv rmate /usr/local/bin so don’t need to specify the path to rmate script
  5. Make it executable: sudo chmod +x /usr/local/bin/rmate
  6. Done!

How to use

  1. Run Sublime Text 2 in your computer.
  2. SSH to remote: ssh -R 52698:localhost:52698 user@remote.com
  3. Rmate the file you want to edit locally: rmate file.php
  4. The file should open in ST2 in your computer.

Creating Symlink in KDE

Listen to this Post. Powered by iSpeech.org

I’m new to KDE – the desktop environment I went with when I installed Fedora 18. I’ve previously been using Ubuntu + Gnome + Nautilus (not the Unity version though, I think it sucks but that’s another story).

Anyway, one of the things I’m used to doing in Nautilus was creating symlinks using the mouse by right-clicking the file or folder that I wanted to create a symlink to, and in the context menu choose “Make Link” which is a great way of making symlinks without opening the command line.

Unfortunately, Dolphin – the default file manager Fedora 18 came with – didn’t have this in it’s context menu – or Service Menu. Anyway, it took me awhile to figure this out but it’s actually dumb easy.

Ctrl + Shift + drag

  1. Hold down Shift + Ctrl key. Don’t let go and go to #2.
  2. Left click + drag the file or folder that you want to create a symlink of.
  3. Drop. You should get a prompt to enter the file name for the symlink.
  4. Name your symlink and that’s it!

P.S. This works for

Editing Right-Click Action (Service Menu) in KDE

Listen to this Post. Powered by iSpeech.org

I just installed Fedora with KDE on my work station and wanted to edit the Service Menu – the menu you get when you right-click->Action.

I googled around and found this and this but both seemed to need to a bit more config editing than what I wanted to do. I wanted a simpler way of doing it.

Luckily, I found the KDE4 Service Menu Editor.

Just one snag though. I installed the Service Menu Editor on a fresh install of Fedora 18 by doing $ sudo ./setup.py install and I got the following error:

Install error

Basically, it says that I don’t have the required modules installed. So, if you get this, just type this out in your terminal (or konsole):

$ sudo yum install python-distutils-extra

Then install again: $ sudo ./setup.py install

How to Install Packages for End of Life Ubuntu Editions

Listen to this Post. Powered by iSpeech.org

I use Ubuntu 10.10. Have been for 4 years now. So, basically my installation has reached EOL (End of Life) and won’t receive any more updates/support as the longest supported editions (LTS editions) only span 4 years.

So, what happens when your edition reaches EOL?

First, you can no longer install new apps/packages using

apt-get install APPNAME

You also can’t update anything. This is because the repositories for the unsupported edition have been removed from the main servers.

The Good News

Repositories for unsupported editions aren’t removed off the face of the internet universe. They’re moved to http://old-releases.ubuntu.com/releases/.

There's hope for you yet

There’s hope for you yet

To use this new repository, we just need to change software sources in /etc/apt/sources.list. For Ubuntu 10.10, the file should look like this:

## EOL upgrade sources.list
# Required
deb http://old-releases.ubuntu.com/ubuntu/ maverick main restricted universe multiverse
deb http://old-releases.ubuntu.com/ubuntu/ maverick-updates main restricted universe multiverse
deb http://old-releases.ubuntu.com/ubuntu/ maverick-security main restricted universe multiverse

# Optional
#deb http://old-releases.ubuntu.com/ubuntu/ maverick-backports main restricted universe multiverse
#deb http://old-releases.ubuntu.com/ubuntu/ maverick-proposed main restricted universe multiverse

That’s it.

Resources

P.S.

Some of you might be asking why I haven’t bothered to upgrade my edition? At the time of this writing, latest version is at 12.10, codenamed Quantal Quetzal. So why not upgrade? Must be tons of new features. Plus it’s better security-wise.

The answer is simple really.

I have no time.

No time to troubleshoot why upgrade hung up. No time to change the default user interface from Unity back to Gnome. (Why would I change it you ask? Because I prefer it) No time to troubleshoot why my favorite app isn’t working after the upgrade. No time to…

I will keep using what I have until it stops working for me, or when a new app gets released that I really, really need but it only runs on the latest edition.

Git Tip: Delete a Remote Branch

Listen to this Post. Powered by iSpeech.org

There are a couple ways to delete a remote branch in Git and some ways will depend on the installed version:

git push origin --delete <branchName> [available in v1.7+]

which is just a wrapper to:

git push origin :branchName

Also, if you have version 1.7+ installed, you can also delete multiple remote branches with:

git push origin --delete branch1 branch2 branch3

3 Services for Setting Up Cron Jobs

Photo by lett -/\=
Listen to this Post. Powered by iSpeech.org

Photo by lett -/\=

Last year, I talked about how to set up Linux cron jobs in BlueHost to trigger WordPress’ pseudo-cron service. This is helpful when you want to automate certain tasks and execute scripts periodically – like sending reminders using my Email Reminder plugin for example.

Unfortunately, setting up cron jobs in your server requires a wee bit of technical know-how. Fortunately, there are services [some free] that can help you out.

Here are three of them.

WebCron.org

What I like about this service is that they offer an API for their customers to use. This allows developers to create applications on top of their service – like creating cron jobs within your WordPress dashboard for instance.

That said, their pricing is straight forward – pay as you go for as low as $ 0.00014 per launch [I am in no way affiliated with them].

 Visit the site

 GetCron.com

This service offers 3 yearly pricing tiers – Personal, Business and Enterprise – depending on the number of web cron jobs you want to run. They also offer a free 1 year account to use 1 web based cron job.

Key features include:

  • 5 minute script execution time-out
  • Timezone support for cron jobs – very helpful when you want your script to only execute at midnight Mountain Time but your server is located in Australia and the web cron service is in the Eastern seaboard.
  • No programming skills required
  • Very Easy and Intuitive – 3 Step Wizard to create even the most complicated time schedule for your web cron
  • Web Crons output tracking
  • Any script can be called – PHP, Ruby On Rails, JSP, ASP Classic, ASP.NET, Perl and others
  • Technical Support

View the site

SetCronJob.com

SetCronJob gives their members a set number of cron jobs that can be executed – called Points – per day. So, on the Free Account plan, you get 50 Points. This allows you to create two cron jobs that execute every hour [24 points x 2 jobs] or 50 cron jobs that execute once a day [1 point x 50 jobs].

Nuff said, view the site.