Some Processing.JS fun

November 28th, 2013

I’ve recently played a bit with Processing.JS. Here is the result

imageslices0imageslices1

Run it yourself at http://dirty-motherfucker.org/imageslices.js Using Chrome is highly recommended.

The sketch itself can be found at http://dirty-motherfucker.org/imageslices.js/imageslices.pde (yes, the style is intentionally messed up).

Alternative rendering for single EXT:powermail checkboxes

August 1st, 2012

I was pissed off because I couldn’t find a proper option in Powermail to render a single checkbox (without a legend and all that crap).

The solution I’m using right now seems to provide exactly what I was looking for. If you create a new Checkbox field and only supply a single option, a single checkbox will be rendered. If you supply multiple options, the behavior is the same as always:

{namespace vh=Tx_Powermail_ViewHelpers}

<div id="powermail_fieldwrap_{field.uid}" class="powermail_fieldwrap powermail_fieldwrap_check powermail_fieldwrap_{field.uid} {field.css}">
  <f:if condition="<f:count subject='{field.settings}' /> == 1">
    <f:then>
      <div class="powermail_check_outer">
        <f:for each="{field.settings}" as="setting" iteration="index">
          <div class="powermail_check_inner powermail_check_inner_{index.cycle}">
            <f:form.checkbox name="field[{field.uid}][{index.index}]" value="{setting.value}" checked="{vh:Misc.PrefillField(field: '{field}', cycle: '{index.cycle}')}" id="powermail_field_{field.marker}_{index.cycle}" class="powermail_checkbox powermail_checkbox_{field.uid} {vh:Misc.ValidationClass(field: '{field}')}" title="{setting.label}" />
            <label for="powermail_field_{field.marker}_{index.cycle}">
              {field.title}<f:if condition="{field.mandatory}"><span class="mandatory">*</span></f:if>
            </label>
          </div>
        </f:for>
      </div>
    </f:then>
    <f:else>
      <fieldset>
        <legend class="powermail_label powermail_check_legend">
          {field.title}<f:if condition="{field.mandatory}"><span class="mandatory">*</span></f:if>
        </legend>
        <div class="powermail_check_outer">
          <f:for each="{field.settings}" as="setting" iteration="index">
            <div class="powermail_check_inner powermail_check_inner_{index.cycle}">
              <f:form.checkbox name="field[{field.uid}][{index.index}]" value="{setting.value}" checked="{vh:Misc.PrefillField(field: '{field}', cycle: '{index.cycle}')}" id="powermail_field_{field.marker}_{index.cycle}" class="powermail_checkbox powermail_checkbox_{field.uid} {vh:Misc.ValidationClass(field: '{field}')}" />
              <label for="powermail_field_{field.marker}_{index.cycle}">{setting.label}</label>
            </div>
          </f:for>
        </div>
      </fieldset>
    </f:else>
  </f:if>
</div>

I guess I wouldn’t need the ForEachViewHelper for the single record, but I just wanted to get something working quickly. So there you have it.

Error code 600 when viewing Autodiscover.xml WTF?

May 9th, 2012

So you’re trying to set up the Exchange Autodiscovery but it just won’t work?

You’re checking your autodiscover URL http://exchange.contoso.com/autodiscover/autodiscover.xml but all you’re seeing it this stupid error message that tells you nothing, except:

<?xml version="1.0" encoding="utf-8" ?>  
<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/responseschema/2006">
  <Response>
    <Error Time="09:28:57.8739220" Id="2715916636">
      <ErrorCode>600</ErrorCode>
      <Message>Invalid Request</Message>
      <DebugData />
    </Error>
  </Response>
</Autodiscover>

If this is what’s happening to you, stop doing it :P You’ll never be able to check the autodiscover.xml from a browser. The contents of the file depend on the user agent of the client that requests it. Only Outlook (or compatible clients) will receive ANY configuration.

So, before you start deleting your virtual Autodiscover directory and re-create it it, make sure you’re using the correct client to verify your results.

How to fix failing language pack updates in TYPO3

February 27th, 2012

If you update language packs through the TYPO3 extension manager, it can happen that it will mark the update as “failed”, but if you check for updates again, it tells you there are no updates available.

Generally it behaves kind of weird with language pack updates. What’s going on and how do I fix it?

The cause of the problem is broken ZIP support in TYPO3. At least that’s what my research concluded.

To fix this, you need to set the path to the unzip utility in the TYPO3 configuration (so it doesn’t use the internal ZIP support). To do so you need to set this configuration variable:

$TYPO3_CONF_VARS['BE']['unzip_path'] = '/usr/bin/unzip';

Set it to wherever your unzip utility is located.

So what if you’re on Windows and don’t have unzip? I have no idea. Would be glad if someone told me.

Self-updating PHP script

February 26th, 2012

Now that we have thoroughly covered self-updating bash scripts, let’s have a look at the PHP counterpart:

 #!/usr/bin/php
<?php
define( "SELF", basename( __FILE__ ) );
define( "INVNAME", $argv[ 0 ] );

// The base location from where to retrieve new versions of this script
$UPDATE_BASE = "http://typo3scripts.googlecode.com/svn/trunk";

/**
 * Update check
 */
function updateCheck() {
  $_contentVersions = file_get_contents( $UPDATE_BASE . "/versions" );
  $_contentSelf     = split( "\n", file_get_contents( INVNAME ), 2 );
  $_sumSelf         = md5( $_contentSelf[ 1 ] );
  
  $_isListed = preg_match( "/^" . SELF . " (?P<sum>[0-9a-zA-Z]{32})/ms", $_contentVersions, $_sumLatest );
  if( !$_isListed ) {
    file_put_contents( "php://stderr", "No update information is available for '" . SELF . "'.\n" );
    file_put_contents( "php://stderr", "Please check the project home page http://code.google.com/p/typo3scripts/.\n" );
    
  } else if( $_sumSelf != $_sumLatest[ 1 ] ) {
    file_put_contents( "php://stderr", "NOTE: New version available!\n" );
  }
}

/**
 * Self-update
 */
function runSelfUpdate() {
  echo "Performing self-update...\n";

  $_tempFileName = INVNAME . ".tmp";
  
  // Download new version
  echo "Downloading latest version...";
  global $UPDATE_BASE;
  $_fileContents = @file_get_contents( $UPDATE_BASE . "/" . SELF );
  if( strlen( $_fileContents ) <= 0 ) {
    echo "Failed: Error while trying to download new version!\n";
    echo "File requested: " . $UPDATE_BASE . "/" . SELF . "\n";
    exit( 1 );
  }
  $_payload = split( "\n", $_fileContents, 2 );
  echo "Done.\n";
  
  // Restore shebang
  $_selfContent = split( "\n", file_get_contents( INVNAME ), 2 );
  $_interpreter = $_selfContent[ 0 ];
  file_put_contents( $_tempFileName, $_interpreter . "\n" );
  file_put_contents( $_tempFileName, $_payload[ 1 ], FILE_APPEND );
  
  // Copy over modes from old version
  $_octalMode = fileperms( INVNAME );
  if( FALSE == chmod( $_tempFileName, $_octalMode ) ) {
    echo "Failed: Error while trying to set mode on $_tempFileName.\n";
    exit( 1 );
  }
  
  // Spawn update script
  $_name = INVNAME;
  $_updateScript = <<<EOS
#!/bin/bash
# Overwrite old file with new
if mv "$_tempFileName" "$_name"; then
  echo "Done."
  echo "Update complete."
  rm -- $0
else
  echo "Failed!"
fi
EOS;
  file_put_contents( "updateScript.sh", $_updateScript );

  echo "Inserting update process...";
    file_put_contents( "updateScript.sh", $_updateScript );
  chmod( "updateScript.sh", 0700 );

  if( function_exists( "pcntl_exec" ) ) {
    pcntl_exec( "/bin/bash", array( "./updateScript.sh" ) );
    
  } else if( function_exists( "passthru" ) ) {
    die( passthru( "./updateScript.sh" ) );
    
  } else {
    die( "Please execute ./updateScript.sh now." );
  }
}
?>

You might notice that it’s pretty much a line-by-line translation of the bash version. That was intentional due to maintenance concerns within the project this was developed for. So, it might not be the optimal solution, but it works at least just as well as the bash version.

Self-updating Bash Script Revised

February 26th, 2012

I recently posted an approach for a self-updating bash script. Shortly after using it in production, I noticed a critical shortcoming.

Due to the simple way in which I implemented my update checking (an MD5 sum over the script itself), changes to the script interpreter line (aka shebang) would cause the script to output that a new version was available.

In addition to that, if the user did perform the update, his modification to the interpreter line would be overwritten.

So here is the revised version, that respects the first line on the script itself:

#!/bin/bash

set -o nounset
set -o errexit

SELF=$(basename $0)

# The base location from where to retrieve new versions of this script
UPDATE_BASE=http://typo3scripts.googlecode.com/svn/trunk

# Update check
function updateCheck() {
  SUM_LATEST=$(curl $UPDATE_BASE/versions 2>&1 | grep $SELF | awk '{print $2}')
  SUM_SELF=$(tail --lines=+2 "$0" | md5sum | awk '{print $1}')
  if [[ "" == $SUM_LATEST ]]; then
    echo "No update information is available for '$SELF'" >&2
    echo "Please check the project home page http://code.google.com/p/typo3scripts/." >&2
    
  elif [[ "$SUM_LATEST" != "$SUM_SELF" ]]; then
    echo "NOTE: New version available!" >&2
  fi
}

# Self-update
function runSelfUpdate() {
  echo "Performing self-update..."
  
  _tempFileName="$0.tmp"
  _payloadName="$0.payload"
  
  # Download new version
  echo -n "Downloading latest version..."
  if ! wget --quiet --output-document="$_payloadName" $UPDATE_BASE/$SELF ; then
    echo "Failed: Error while trying to wget new version!"
    echo "File requested: $UPDATE_BASE/$SELF"
    exit 1
  fi
  echo "Done."
  
  # Restore shebang
  _interpreter=$(head --lines=1 "$0")
  echo $_interpreter > "$_tempFileName"
  tail --lines=+2 "$_payloadName" >> "$_tempFileName"
  rm "$_payloadName"
  
  # Copy over modes from old version
  OCTAL_MODE=$(stat -c '%a' $SELF)
  if ! chmod $OCTAL_MODE "$_tempFileName" ; then
    echo "Failed: Error while trying to set mode on $_tempFileName."
    exit 1
  fi
  
  # Spawn update script
  cat > updateScript.sh << EOF
#!/bin/bash
# Overwrite old file with new
if mv "$_tempFileName" "$0"; then
  echo "Done."
  echo "Update complete."
  rm -- \$0
else
  echo "Failed!"
fi
EOF
  
  echo -n "Inserting update process..."
  exec /bin/bash updateScript.sh
}

Safely updating TYPO3 extensions

February 22nd, 2012

A difference between the originally installed version and the current was detected!

If you have ever read that warning in the TYPO3 extension manager, you know exactly how annoying it can be to find that difference.

You made some minor tweak or fix and forgot about it and now you don’t know what it was and if the updated extension contains the same fix.

Or even worse. You’re already up to the new extension manager interface where there are neither upload comments nor the warning about local modification. Oh boy, oh boy.

So what can you do? Here’s what.

To do this, we need 3 scripts from the typo3scripts script suite.

  1. extUpdate.sh
  2. extChangelog.sh
  3. extExtract.php

How to install and configure these scripts is explained on their respective wiki pages on the project homepage, so I won’t repeat that here. Let’s get right to the interesting parts.

$ ./extUpdate.sh
Sourcing script configuration from typo3scripts.conf...Done.
Checking dependencies...Succeeded.
New version of 'direct_mail' available. Installed: 2.6.10 Latest: 2.7.0
New version of 'div2007' available. Installed: 0.7.2 Latest: 0.8.1
New version of 'kb_md5fepw' available. Installed: 0.4.0 Latest: 0.4.1
New version of 'realurl' available. Installed: 1.12.0 Latest: 1.12.1

First of all, let’s see the upload comments for those extensions:

./extUpdate.sh --changelog
Sourcing script configuration from typo3scripts.conf...Done.
Checking dependencies...Succeeded.
New version of 'direct_mail' available. Installed: 2.6.10 Latest: 2.7.0
2.7.0 (2012-01-30 00:44:37)
 - layout tweaking
 - create draft newsletter and auto sending (e.g. weekly) (thanks to Benni Mack)
 - bug fixes
 please refer to changelog for further info.
 please report any bug or feature or anything in Forge (forge.typo3.org)

New version of 'div2007' available. Installed: 0.7.2 Latest: 0.8.1
0.8.0 (2012-01-23 21:19:28)
 add new classes for email and error message generation
 ready for TYPO3 4.6
0.8.1 (2012-01-28 18:10:45)
 allow the usage of a pibase object instead of class.tx_div2007_alpha_language_base

New version of 'kb_md5fepw' available. Installed: 0.4.0 Latest: 0.4.1
0.4.1 (2010-10-27 21:04:19)
 DEPRECATED: Use "saltedpasswords" and "rsaauth" extensions instead!

New version of 'realurl' available. Installed: 1.12.0 Latest: 1.12.1
1.12.1 (2012-02-17 13:23:27)
 Bug fixes. This is a recommended update to everybody.

Great! Now we even know that kb_md5fepw is deprecated. The extension manager doesn’t list deprecated extensions in the update panel as it seems. Oh well, let’s have a look at those local modifications that keep us from updating our extension.

$ ./extExtract.php direct_mail
Sourcing script configuration from typo3scripts.conf...Done.
NOTE: New version available!
Retrieving original extension file for 'direct_mail' 2.6.10...Done.
Extracting file 'direct_mail_2.6.10.t3x'...Done.
$ diff --recursive direct_mail_2.6.10.t3x-extracted/ typo3/typo3conf/ext/direct_mail
diff --recursive direct_mail_2.6.10.t3x-extracted//ext_tables.php typo3/typo3conf/ext/direct_mail/ext_tables.php
100c100
<                       )
---
>                       ),
diff --recursive direct_mail_2.6.10.t3x-extracted//mod2/class.tx_directmail_dmail.php typo3/typo3conf/ext/direct_mail/mod2/class.tx_directmail_dmail.php
421c421
<                       if (t3lib_div::testInt($createMailFrom_UID))    {
---
>                       if (t3lib_div::testInt($createMailFrom_UID) && $createMailFrom_UID > 0) {
diff --recursive direct_mail_2.6.10.t3x-extracted//mod4/class.tx_directmail_statistics.php typo3/typo3conf/ext/direct_mail/mod4/class.tx_directmail_statistics.php
439c439
<                               ' AND type=0'.
---
>                               ' AND (type=0 OR type=1)'.
diff --recursive direct_mail_2.6.10.t3x-extracted//res/scripts/class.tx_directmail_checkjumpurl.php typo3/typo3conf/ext/direct_mail/res/scripts/class.tx_directmail_checkjumpurl.php
132c132
<                                                       $jumpurl = str_replace('###SYS_TABLE_NAME###', $theTable, $jumpurl);
---
>                                                       $jumpurl = str_replace('###SYS_TABLE_NAME###', substr($theTable, 0, 1), $jumpurl);

Well, I don’t know what those changes do (actually, I totally do), but I better make sure I put them back after the update.

Integrate Progress Indicator in Console Output

January 4th, 2012

I recently tried to use pv in a bash script so that it wouldn’t interfere with my concept of communicating overall progress to the user.

When I usually like to do is to echo -n a description of the current task and then later echo either “Done.” or “Failed!” (or something similar).
Obviously, that somewhat conflicts with pv. So here is the solution:

# Create backup archive
_statusMessage="Compressing installation..."
echo -n $_statusMessage
if hash pv 2>&- && hash gzip 2>&- && hash du 2>&-; then
  echo
  _folderSize=`du --summarize --bytes $BASE | cut --fields 1`
  if ! tar --create --file - $BASE | pv --progress --rate --bytes --size $_folderSize | gzip --best > $FILE; then
    echo "Failed!"
    exit 1
  fi
  # Clear pv output and position cursor after status message
  tput cuu 2 && tput cuf ${#_statusMessage} && tput ed
else
  if ! tar --create --gzip --file $FILE $BASE; then
    echo "Failed!"
    exit 1
  fi
fi

echo "Done."

The snippet also shows how to conditionally use pv if it is available, which I really like.

Check Write Permissions for Folder Hierachcy

January 2nd, 2012

While working on a bash script, I wanted to check if I could rm -rf a folder before actually attempting it and flushing the console with tons of write permission error messages.

Upon failing to find what I wanted online, I constructed this beauty:

find . \( -exec test -w {} \; -o \( -exec echo {} \; -quit \) \) | xargs -I {} bash -c "if [ -n "{}" ]; then echo {} is not writeable\!; exit 1; fi"

This will print the name of the item that is not writeable in addition to the non-zero return value needed when used in more complex scripts.

If you don’t want/need the output, you can go with the simpler version:

find . \( -exec test -w {} \; -o \( -exec echo {} \; -quit \) \) | xargs -I {} test -z "{}"

If there is a more simple solution, please let me know.

Self-updating Bash Script

December 22nd, 2011

Note: There is a revised version of this script available.

While working on the typo3scripts project, I wanted to implement a self-updating feature into each of the scripts as that seemed most convenient for where these scripts would be used. My initial approach was OK but left me wondering.

So, here is the revised approach for a bash script that has the ability to update itself:

#!/bin/bash

set -o nounset
set -o errexit

SELF=$(basename $0)

# The base location from where to retrieve new versions of this script
UPDATE_BASE=http://typo3scripts.googlecode.com/svn/trunk

# Self-update
runSelfUpdate() {
  echo "Performing self-update..."
  
  # Download new version
  echo -n "Downloading latest version..."
  if ! wget --quiet --output-document="$0.tmp" $UPDATE_BASE/$SELF ; then
    echo "Failed: Error while trying to wget new version!"
    echo "File requested: $UPDATE_BASE/$SELF"
    exit 1
  fi
  echo "Done."
  
  # Copy over modes from old version
  OCTAL_MODE=$(stat -c '%a' $SELF)
  if ! chmod $OCTAL_MODE "$0.tmp" ; then
    echo "Failed: Error while trying to set mode on $0.tmp."
    exit 1
  fi
  
  # Spawn update script
  cat > updateScript.sh << EOF
#!/bin/bash
# Overwrite old file with new
if mv "$0.tmp" "$0"; then
  echo "Done. Update complete."
  rm \$0
else
  echo "Failed!"
fi
EOF
  
  echo -n "Inserting update process..."
  exec /bin/bash updateScript.sh
}

# Update check
SUM_LATEST=$(curl $UPDATE_BASE/versions 2>&1 | grep $SELF | awk '{print $1}')
SUM_SELF=$(md5sum $0 | awk '{print $1}')
if [[ "$SUM_LATEST" != "$SUM_SELF" ]]; then
  echo "NOTE: New version available!"
fi

It also includes the update check which wasn’t discussed over at StackOverflow. In case I revise the approach yet again, you’ll find the latest version over at the typo3scripts project page.