Skip to content

Instantly share code, notes, and snippets.

@jthoenes
Created January 24, 2010 14:14
Show Gist options
  • Save jthoenes/285219 to your computer and use it in GitHub Desktop.
Save jthoenes/285219 to your computer and use it in GitHub Desktop.
Update multiple dokuwiki installations via a ruby script
#! /usr/bin/env ruby
=begin
This script backups and updates all dokuwiki installations on this server
Copyright (c) 2010 by Johannes Thönes <johannes.thoenes@googlemail.com>
Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
=end
# Library Requirements
require 'net/http' # for download of the files
require 'open-uri' # for download of the files
require 'fileutils' # for file operation
include FileUtils
require 'tmpdir' # for Dir.tmpdir
require 'date' # for time
require 'rubygems' # Rubygems for the following libs
require 'libarchive_ruby' # for archive extraction
# Definition of existing installation
INSTALLATIONS = [
'/path/to/docu/wiki/installation1',
'/path/to/docu/wiki/installation2'
].freeze
# Files to remove Gist
OLD_FILES_URL = 'http://www.dokuwiki.org/_export/code/install:upgrade?codeblock=7'
# Helper Function (change here, if you want to customize something)
def backup_folder_base
@backup_folder_base ||= "#{Dir.tmpdir}/dokuwiki_backup_#{DateTime.now.strftime('%Y%m%d-%H%M%S')}"
end
def download_location uri
"#{Dir.tmpdir}/#{release_package_name(uri)}"
end
def release_package_name uri
uri.path.split('/').last
end
def release_name uri
release_package_name(uri).split('.').first
end
def walk_archive location
Archive.read_open_filename(location) do |archive|
while entry = archive.next_header
location = entry.pathname.split('/').reject{|dirname| dirname =~ /dokuwiki-(rc?)\d{4}-\d{2}-\d{2}/}
data = archive.read_data
yield(location, entry, data)
end
end
end
def apply_to_installation_path rel_path
INSTALLATIONS.each do |inst|
yield("#{inst}/#{rel_path}")
end
end
def create_data_folder_if_not_exists rel_path
apply_to_installation_path(rel_path) do |path|
unless File.directory?(path)
raise "'#{path}' exists but is not a directory" if File.exists?(path)
mkdir path
chown_R 'www-data', 'www-data', path
chmod_R 664, path
end
end
end
def create_folder_if_not_exists rel_path, entry
apply_to_installation_path(rel_path) do |path|
unless File.directory?(path)
raise "'#{path}' exists but is not a directory" if File.exists?(path)
mkdir path
chmod entry.mode, path
end
end
end
def copy_file rel_path, entry, data
apply_to_installation_path(rel_path) do |path|
File.open(path, 'w', entry.mode) {|f| f.write(data)}
end
end
def delete_file_if_exists rel_path
apply_to_installation_path(rel_path) do |path|
rm(path) if File.exists?(path)
end
end
# Parameter extraction
raise "You need to supply the current dokuwiki release download" if ARGV.first.nil?
package_uri = URI.parse(ARGV.first)
# Backup existing locations to a folder in tempdir
raise "Backup Folder '#{backup_folder_base}' already exists" if File.exists?(backup_folder_base)
mkdir backup_folder_base
INSTALLATIONS.each do |installation|
cp_r installation, backup_folder_base
end
# Downloading the newest dokuwiki package
archive_loc = download_location(package_uri)
Net::HTTP.start(package_uri.host) do |http|
response = http.get(package_uri.path)
File.open(download_location(package_uri), 'w') {|f| f.write(response.body)}
end
# Copy the new package (except the /data folder) into the the directories
walk_archive(archive_loc) do |location, entry, data|
if (location.first == 'data')
create_data_folder_if_not_exists(location.join('/')) if entry.directory?
else
create_folder_if_not_exists(location.join('/'), entry) if entry.directory?
copy_file(location.join('/'), entry, data) unless entry.directory?
end
end
# Delete old files
open(OLD_FILES_URL) do |f|
f.each_line do |rel_path|
if rel_path !~ /^#/ and rel_path.strip.length != 0
delete_file_if_exists(rel_path)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment