O=$IFS
IFS=$(echo -en "\n\b")
for f in $(ls *)
do
echo "$f"
done
IFS=$O
A piggy bank of commands, fixes, succinct reviews, some mini articles and technical opinions from a (mostly) Perl developer.
Jump to
Perl debugger basics
- n - next step
- s - step into
- c - continue
- b 100 - break at line 100
- b sub - break at sub 'sub' (must be in the right file)
- { v - display the surrounding lines before each step
- w $var - watch variable $var (displays changed $var and stops)
XSL data types
<xsl:stylesheet
xmlns:sch="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0"
exclude-result-prefixes=" sch">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:variable name="a" as="sch:integer" select="12"/>
<xsl:variable name="b" as="sch:float" select="12.123456789123456789"/>
<xsl:variable name="c" as="sch:double" select="12.123456789123456789"/>
<xsl:variable name="d" as="sch:decimal" select="12.123456789123456789"/>
</xsl:stylesheet>
Subversion basics
svn up /your-workspace
svn up -r {2010-11-14} /your-workspace
# ignore a file or directory
svn propset svn:ignore [file or dir] [parent dir]
Parsing HTML with Perl
XML::LibXML has a parse_html method and a toString method.
Debugging XSLT
<!-- DEBUG -->
<xsl:if test="$debug">
<xsl:message><xsl:text>--------</xsl:text></xsl:message>
<xsl:message><xsl:text>FUNCTION display-pagination-links:</xsl:text></xsl:message>
<xsl:message><xsl:text>--------</xsl:text></xsl:message>
<xsl:message><xsl:text>direction: </xsl:text><xsl:value-of select="$direction"/></xsl:message>
<xsl:message><xsl:text>link_type: </xsl:text><xsl:value-of select="$link_type"/></xsl:message>
</xsl:if>
vim features
Basic CSS
#id = ID (mnemonic: I'd like some *hash*)
.class = class (mnemonic: polka *dots* are classic and classy)
* margin direction:
top right bottom left
(clockwise, starting from top)
* comments
/* this is a comment */
// this is not a comment!
* debugging
border: 2px solid red !important
or
display: none !important
* specifying elements:
html:
<ul id="list">
<li>
<div class="d1">one</div>
<div class="d2">two</div>
<div class="d3">three</div>
</li>
</ul>
css:
#list li div.d1 { //css }
--------------------------
http://robertnyman.com/2007/10/18/dont-over-specify-your-css-code/
/* Instead of this: */
div#container p.pre-amble{
margin-top: 1em;
}
/* Write it like this: */
.pre-amble{
margin-top: 1em;
}
/* Or like this: */
#container .pre-amble{
margin-top: 1em;
}
/* Instead of this: */
div#container div#header ul#navigation li{
float: left;
}
/* Write it like this: */
#navigation li{
float: left;
}
/* Or like this: */
#header #navigation li{
float: left;
}
XSLT math
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:template match="numbers">
A. 4 + 3.2 = <xsl:value-of select="x + y"/>
B. 3.2 - 4 = <xsl:value-of select="y - x"/>
C. 4 * 3.2 = <xsl:value-of select="x * y"/>
D. 11/3.2 = <xsl:value-of select="z div y"/>
E. 4 + 3.2 * 11 = <xsl:value-of select="x+y*z"/>
F. (4 + 3.2) * 11 = <xsl:value-of select="(x+y)*z"/>
G. 11 mod 4 = <xsl:value-of select="z mod x"/>
H. 4 + 3.2 + 11 = <xsl:value-of select="sum(*)"/>
I. floor(3.2) = <xsl:value-of select="floor(y)"/>
J. ceiling(3.2) = <xsl:value-of select="ceiling(y)"/>
K. round(3.2) = <xsl:value-of select="round(y)"/>
L. 11 + count(*) = <xsl:value-of select="11+count(*)"/>
M. 3.2 + string-length("3.2") =
<xsl:value-of select="y + string-length(y)"/>
N. 11 + "hello" = <xsl:value-of select="z + 'hello'"/>
</xsl:template>
</xsl:stylesheet>
Warning With some XSLT processors, the use of decimal numbers may introduce a tiny error. For example, the "3.2 - 4" in this example comes out as "-.7999999999999998" on some processors. While being off by .0000000000000002 isn't much, being off at all shows that math is not XSLT's strong point.
Display output of XSL transformation using PHP
<?
$query = $_GET['q'];
$filePath = 'http://source-server:8889/page/'.$query;
$xslDoc = new DOMDocument();
$xslDoc->load("http://localhost/xslt/page_render.xsl");
$xmlDoc = new DOMDocument();
$xmlDoc->load( $filePath );
$proc = new XSLTProcessor();
$proc->importStylesheet($xslDoc);
echo $proc->transformToXML($xmlDoc);
?>
Screen capture for long pages in firefox
No XSLT2 in PHP
There is only one known xslt2 processor called SAXON (http://saxon.sourceforge.net/), built by Michael Kay, which was released for the Java and .NET platforms.
Other XSLT processors, including Sablotron, Xalan and MSXML, have not yet adopted xslt2.
Kay writes: "implementation [for xslt2 in php] does not exist because no-one has written one". He continues, "The usual workaround I recommend is to implement XSLT 2.0 transformation as a (Java-based or .NET-based) REST web service, and for the php application to submit transformation requests to that web service by means of HTTP requests. An alternative is to use a php-Java bridge"
Michael Kay manages an email-based discussion group called MulberryTech, a good resource for learning XSLT techniques (both 1 and 2). (http://www.mulberrytech.com/xsl/xsl-list/)
Don't display dynamic elements until page has loaded
<script type="text/javascript">
function getRefToDiv(divID,oDoc) {
if( document.getElementById ) {
return document.getElementById(divID); }
if( document.all ) {
return document.all[divID]; }
if( !oDoc ) { oDoc = document; }
if( document.layers ) {
if( oDoc.layers[divID] ) { return oDoc.layers[divID]; } else {
//repeatedly run through all child layers
for( var x = 0, y; !y && x < oDoc.layers.length; x++ ) {
//on success, return that layer, else return nothing
y = getRefToDiv(divID,oDoc.layers[x].document); }
return y; } }
return false;
}
function toggleDiv(divID_as_a_string,action) {
//get a reference as above ...
myReference = getRefToDiv(divID_as_a_string);
if( !myReference ) {
//window.alert('Nothing works in this browser');
return; //don't go any further
}
//now we have a reference to it
if( myReference.style ) {
//DOM & proprietary DOM
if (action == 'on') {
myReference.style.visibility = 'visible';
} else {
myReference.style.visibility = 'hidden';
}
} else {
//layers syntax
if (action == 'on') {
myReference.visibility = 'show';
} else {
myReference.visibility = 'hide';
}
}
}
function start() {
toggleDiv('slider','on');
}
window.onload = start;
</script>
</head>
<body>
<div id="slider" style="visibility: hidden">
</body>
(If, Then, Else) LOGIC in XSL
<xsl:if test="XXX">
<!-- do something -->
</xsl:if>
<xsl:choose>
<xsl:when test="XXX">
<!-- do one thing -->
</xsl:when>
<xsl:when test="YYY">
<!-- do another thing -->
</xsl:when>
<xsl:otherwise>
<!-- do default thing -->
</xsl:otherwise>
</xsl:choose>
Logic examples:
<xsl:when test="matches(sql:feedurl_id, '^(\d+)$')">
<xsl:if test="$canonical-urls/agg:canonical-url[text()=$canonical-link-href][1]/@module = $module-type">
<xsl:when test="$module-type = 'knowledge'">
<xsl:when test="$module-type='iplayer' or $module-type='schedule'">
<xsl:if test="$debug">
<xsl:when test="document('')//this:modules/this:module[@type=$module-type]/this:merge-feeds">
<xsl:if test="position()=1">
<xsl:if test="position()=3 and count(agg:module)=0">
<xsl:when test="starts-with($name,'profile') or starts-with($name,'weather')">
<xsl:when test="starts-with(@type,'profile')">
<xsl:when test="@type='weather'">
<xsl:when test="count($modules/agg:modules/agg:module[starts-with(@type,'profile')])>0">
Histogram with perl
$i = the value with which you want to make a histogram
$h = hashref holding the histogram data
$s = histogram step size
$m = maximum histogram value
$c = loop counter
Cocoon XSLT errors
This could mean you've used the wrong attribute name in a tag, e.g.
<xsl:attribute type="type">
instead of
<xsl:attribute name="type">
There seems to be no syntax checking to warn in cases like this.
Basic Javascript
if( document.getElementById ){
var myReference = document.getElementById('divID');
}
Show/hide invisible/non-printable characters in Outlook (and probably Word)
XML::Validator::Schema
use XML::SAX::ParserFactory;
use XML::Validator::Schema;
# create a new validator object, using foo.xsd
$validator = XML::Validator::Schema->new(file => 'foo.xsd');
# create a SAX parser and assign the validator as a Handler
$parser = XML::SAX::ParserFactory->parser(Handler => $validator);
# validate foo.xml against foo.xsd
eval { $parser->parse_uri('foo.xml') };
die "File failed validation: $@" if $@;
The problem is:
- XML::Validator::Schema ignores missing tags
- and attribute fixing doesn't work, at all
Validating with XML::XPath
use Test::More qw(no_plan);
my $id = 298;
my $xml = &get_url("/$id")->{xml};
my $xp = XML::XPath->new( xml => $xml );
my $r = '/feed'; # root
ok( $xp->exists($r), "there should be a feed" );
ok( $xp->exists("$r/id"), "there should be a feed ID" );
ok( $xp->find("$r/id") =~ m{/$id}, "feed ID should be correct" );
ok( $xp->exists("$r/link[\@rel=\"self\"]"), "rel=self attr is correct" );
ok( ($xp->find("$r/link")->get_nodelist)[0]->getAttribute('href'), "href link exists" ); # this is ugly
check( $xp->find("$r/updated") => like => qr/^\d{4}\-\d\d\-\d\dT\d\d:\d\d:\d\d\.\d+Z$/ );
my $entries = $xp->find("/feed/entry"); # find all entry sections
ok( $entries, "there are entries" );
if ($entries->size) {
my $e = "/entry";
foreach my $node ($entries->get_nodelist) {
# it's bloody stupid transforming the XML::XPath object to a string and then parsing back to an object
# instead maybe loop through each node in the list using xpath [0] [1], etc?
# But why should I have to hack around this....
my $entry = XML::XPath->new( xml => $node->toString );
ok( $entry->exists("$e/title"), "title exists" );
}
}
# Conclusion: XML::XPath is bad for writing tests.
Crontab format (V3)
# minute (0-59),
# | hour (0-23),
# | | day of the month (1-31),
# | | | month of the year (1-12),
# | | | | day of the week (0-6 with 0=Sunday).
# | | | | | commands
# 3 2,3,4 * * 0,6 /command to run on more than one day/hour
# 3 2,4-7 * * 1-5 /another/command to run on a range of days/hours
04 10 * * * /command/here 2>> /path/to/log/prog.$(date +\%Y\%m\%d).log
NOTES:
- You must escape percent signs with a backslash
- Putting them in double quotes doesn't work
- Putting in double quotes and backslashes works, but the backslashes are written as part of the filename. So don't so that.
Perl test template
#!/usr/bin/perl
#################################################################################
# Description of tests
#################################################################################
use strict;
use warnings;
use Test::More qw(no_plan);
use Test::Differences; # eq_or_diff()
use Test::Lazy qw/try check/; # check() displays the expected & actual upon failure, even for scalars
use Log::Log4perl;
use XML::Simple qw(:strict);
Log::Log4perl::init('conf/log4perl-test.conf');
my $LOG = Log::Log4perl->get_logger('log4perl.appender.LOGFILE');
$| = 1; select STDERR;
$| = 1; select STDOUT;
$LOG->info("Started tests");
use_ok('MyNamespace::MyModule');
dies_ok { MyNamespace::MyModule->new } 'fail to instantiate without parameters';
my $m = MyNamespace::MyModule->new( url => "foo", name => 'bar');
isa_ok($m, 'MyNamespace::MyModule');
How to find which function does what in Drupal 6
In Drupal 6, inside the theme() function of /includes/theme.inc, change line 617 from this:
$output = call_user_func_array($info['function'], $args);
To this:
$output = '<!-- begin ' . $info['function'] . ' -->' . call_user_func_array($info['function'], $args) . '<!-- end ' . $info['function'] . ' -->' ;
The advice about not doing this on a production site stands.
Unix timezone settings
The current timezone is set by the /etc/localtime file, which is either a symlink, or a hard link, or a copy of a file in /usr/share/zoneinfo. If the file's timestamp is a long time ago it's a fair bet it's been configured this way for a while.
The files in /usr/share/zoneinfo contain the definitions of a time zone -- its offset from UTC and any daylight savings in use. The problem is working out which file is in use. It could be a symlink:
[root@server ~]# ls -l /etc/localtime
lrwxrwxrwx 1 root root 27 Jun 26 2008 /etc/localtime -> /usr/share/zoneinfo/Etc/GMT
Given the timestamp on the symlink to the GMT zone file is June last year I'd say it's likely that it's been configured this way (ie, GMT) for a long time.
Other boxes don't have symlinked timezone files:
[root@server ~]# ls -l /etc/localtime
-rw-r--r-- 1 root root 118 Mar 4 2008 /etc/localtime
They might have a hard link (which is like having a file known by another name -- same contents, more than one name) to a zoneinfo file. You can try to work this out using find:
[root@server ~]# ls -l /etc/localtime
-rw-r--r-- 11 root root 118 Apr 13 2009 /etc/localtime
[root@server ~]# find /usr/share/zoneinfo -samefile /etc/localtime
/usr/share/zoneinfo/GMT0
/usr/share/zoneinfo/Greenwich
/usr/share/zoneinfo/GMT
/usr/share/zoneinfo/Etc/GMT0
/usr/share/zoneinfo/Etc/Greenwich
/usr/share/zoneinfo/Etc/GMT
/usr/share/zoneinfo/Etc/GMT-0
/usr/share/zoneinfo/Etc/GMT+0
/usr/share/zoneinfo/GMT-0
/usr/share/zoneinfo/GMT+0
You can see here that /etc/localtime and all the GMT zone files are hard links to the same file contents -- ie, the file contents that set the time to GMT, showing this box is in GMT.
If /etc/localtime isn't a symlink or a hard link it must be a straight copy of a zone file (or it's totally broken). You can work this out by MD5 summing /etc/localtime's contents against all the possible time zone files it could be. Get the MD5 sum (like an abbreviation of the contents) of /etc/localtime:
[root@server ~]# md5sum /etc/localtime
fcccbcf95c718cf2fdee557763e460be /etc/localtime
Then find other files with the same contents:
[root@server ~]# find /usr/share/zoneinfo/ -type f -exec md5sum {} \; | grep fcccbcf95c718cf2fdee557763e460be
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/GMT+0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/GMT0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/Greenwich
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/GMT
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/GMT+0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/GMT0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/Greenwich
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/GMT
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/Etc/GMT+0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/Etc/GMT0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/Etc/Greenwich
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/Etc/GMT
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/Etc/GMT-0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/GMT-0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/Etc/GMT+0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/Etc/GMT0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/Etc/Greenwich
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/Etc/GMT
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/Etc/GMT-0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/GMT-0
So it looks like this server's /etc/localtime has the same contents as all the GMT files. This box is in GMT.
Taxonomy menu for Drupal
$vid = 1; /* <---- put correct vocabulary ID here */
$terms = taxonomy_get_tree($vid);
print "<div class=\"item-list\">";
print "<ul>";
foreach ( $terms as $term ) {
$tcount = taxonomy_term_count_nodes($term->tid);
print "<li>".
l($term->name." (".$tcount.")",'taxonomy/term/'.$term->tid, array('title' => $tcount." posts in ".$term->name)).
"</li>";
} /* end foreach */
print "</ul>";
print "</div>";
?>
How to use Catalyst to automatically create Perl DBIx::Class modules
1. install Catalyst
2. pretend like you're going to create a catalyst app
catalyst.pl MyFakeApp
3.
cd MyFakeApp
./script/myfakeapp_create.pl model MyModelName DBIC::Schema \
MyApp::SchemaClass create=static dbi:mysql:... user password
http://search.cpan.org/~rkitover/Catalyst-Model-DBIC-Schema-0.29/lib/Catalys
t/Helper/Model/DBIC/Schema.pm
one I did earlier
perl ./script/tagindexer_create.pl model RequestDB DBIC::Schema
TagIndexer::Schema create=static
'dbi:mysql:database=request;host=[ip address];port=3306' tagindexer
tagindexer
Edit text files on remote linux servers
> I've never managed to figure out how to rig up editors to edit
> files on remote servers.
On the server, put this in smb.conf
[homes]
comment = Home Directories
hide dot files = yes
read only = No
browseable = yes
Then in the finder/windows explorer connect to 'smb://hostname/' . Then make an alias to it on your desktop.
Alternatively, TextWrangler on the Mac has an ftp/sftp browser.
http://www.barebones.com/products/TextWrangler/
Nested comments
They may already be inside a comment.
Lowercasing in XSL
How to use PHP snippets in Drupal
Using Java classes from XSLT under Coocon / JBoss
<xsl:value-of select="md5:encode('$term')" xmlns:md5="java:org.jboss.security.Base64Encoder" />
<xsl:value-of select="md5:encodeString($term,'ISO-8859-1')" xmlns:md5="java:org.hsqldb.lib.MD5" />
Search through built-in classes in JBoss:
find /path/to/jboss-4.2.2.GA/server/default/ -name "*.jar" -exec jar tf {} \; | grep MD5 -H
Parents node's position in XSL
Number can be extracted:
($n)=$c=~/(\d+)\.\d+\.\d+\.\d+$/;
and adjusted:
$n=((($n/2)-5)+1)
<xsl:number count="." level="multiple" from="/page" format="1"/>
Or with format="a", interpret like j=1, l=2, n=3, p=4, etc.
2. Count parents using position()
Simpler -- but apparently this is a weird way to do it. Probably inefficient too.
<xsl:value-of select="count(parent::*/parent::*/parent::*/preceding-sibling::*) - 3"/>
Read an internal Apache variable
RewriteEngine On
RewriteRule ^(.*)$ $1 [E=MY_MOD_ENV_VAR:%{ENV:MY_MOD_OUTPUT_NOTE}]
Apache error "premature EOF in parsed file"
What it means is "You've messed up the attribute syntax in a mod_include command".
Examples:
<!--#config timefmt=%s --> (no quotes)
<!--#set var='title' value='This title would've screwed things up' --> (apostrophe not escaped)
JSP/XSP generator in Cocoon
In the sitemap.xmap:
<map:match pattern="^(\d+)$" type="regexp">
<map:generate type="serverpages" src="sfapi.xsp">
<map:parameter name="feedid" value="{1}"/>
</map:generate>
The source of sfapi.xsp
<?xml version="1.0" encoding="UTF-8"?>
<xsp:page language="java" xmlns:xsp="http://apache.org/xsp" xmlns:soap="http://apache.org/xsp/soap/3.0">
<results>
<xsp:logic>
int feedid=0;
try {
feedid = Integer.parseInt(parameters.getParameter("feedid"));
} catch (Exception e) {
feedid = -999;
}
</xsp:logic>
<soapcall
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/1999/XMLSchema"
url="/FeedManager"
>
<m:getFeedData xmlns:m="http://else.something.co.uk/ns/feeds">
<int_1 xsi:type="xsd:int"><xsp:expr>feedid</xsp:expr></int_1>
</m:getFeedData>
</soapcall>
</results>
</xsp:page>
XSL to copy XML
<xsl:stylesheet version="1.0" xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes">
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="@* | node()">
</xsl:apply-templates>
</xsl:copy>
</xsl:template></xsl:output></xsl:stylesheet>
Another way:
<!-- copy the whole document -->
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|text()|comment()|processing-instruction">
<xsl:copy-of select="."/>
</xsl:template>
Case sensitive MySQL column
CREATE TABLE `page_dm` (
`url` varchar(500) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html
http://dev.mysql.com/doc/refman/5.0/en/create-table.html
Different files for log4perl levels
log4perl.rootLogger=DEBUG,CONSOLE,ViewableLog,DebugLog,ErrorLog
###################################################################################
# console - what to watch
log4perl.appender.CONSOLE=Log::Log4perl::Appender::Screen
log4perl.appender.CONSOLE.layout=PatternLayout
log4perl.appender.CONSOLE.layout.ConversionPattern=[%d] [%p %c] - %m%n
log4perl.appender.CONSOLE.Filter = ViewableFilter
log4perl.filter.ViewableFilter = sub { \
my %p = @_; \
$p{log4p_level} eq "FATAL" or \
$p{log4p_level} eq "ERROR" or \
$p{log4p_level} eq "INFO" or \
$p{log4p_level} eq "WARN" \
}
###################################################################################
# Viewable log - record of CONSOLE
log4perl.appender.ViewableLog=Log::Log4perl::Appender::File
log4perl.appender.ViewableLog.layout=PatternLayout
log4perl.appender.ViewableLog.layout.ConversionPattern=[%d] [%p %c] - %m%n
log4perl.appender.ViewableLog.filename = logs/output.log
log4perl.appender.ViewableLog.Filter = ViewableFilter
###################################################################################
# Error log - warnings and errors
log4perl.appender.ErrorLog=Log::Log4perl::Appender::File
log4perl.appender.ErrorLog.layout=PatternLayout
log4perl.appender.ErrorLog.layout.ConversionPattern=[%d] [%p %c] - %m%n
log4perl.appender.ErrorLog.filename = logs/error.log
log4perl.appender.ErrorLog.Filter = ErrorFilter
log4perl.filter.ErrorFilter = sub { \
my %p = @_; \
$p{log4p_level} eq "FATAL" or \
$p{log4p_level} eq "ERROR" or \
$p{log4p_level} eq "WARN" \
}
###################################################################################
# Debug Log - everything
log4perl.appender.DebugLog = Log::Log4perl::Appender::File
log4perl.appender.DebugLog.layout=PatternLayout
log4perl.appender.DebugLog.layout.ConversionPattern=[%d] [%p %c] - %m%n
log4perl.appender.DebugLog.filename = logs/debug.log
log4perl.appender.DebugLog.Filter = AllFilter
log4perl.filter.AllFilter = sub { \
my %p = @_; \
$p{log4p_level} eq "FATAL" or \
$p{log4p_level} eq "ERROR" or \
$p{log4p_level} eq "WARN" or \
$p{log4p_level} eq "INFO" or \
$p{log4p_level} eq "DEBUG" or \
$p{log4p_level} eq "TRACE" \
}
###################################################################################
# To enable DEBUG-level logging for a particular module (and any modules that subclass it),
# un-comment the following and change e.g. 'TempTopicsAdminTools.ModuleManager' to the your own module.
##log4perl.logger.TempTopicsAdminTools.ModuleManager=DEBUG
#log4perl.logger.TempTopicsAdminTools.PageManager=WARN
#log4perl.logger.TempTopicsAdminTools.CategoryManager=WARN
Remove MySQL user password
root@dsdsdsdsd:~# mysql -p
Enter password:
mysql> use mysql;
mysql> update user set Password='' where User='yourusername';
mysql> commit;
mysql> flush privileges;
mysql> quit;
Phone twiddles
- *#06# - show IMEI number
Blackberry only:
- from home screen: Hold Alt and type E, A, C, E - displays OS version
Elementary JSON
{
"Image": {
"Width":800,
"Height":600,
"Title":"View from 15th Floor",
"Thumbnail":
{
"Url":"http:\/\/scd.mm-b1.yimg.com\/image\/481989943",
"Height": 125,
"Width": "100"
},
"IDs":[ 116, 943, 234, 38793 ]
}
}
Thanks Yahoo!
Coloured log output
#!/usr/bin/perl
use warnings;
use strict;
use Term::ANSIColor qw(color);
while( <> ) {
chomp;
s/\t/ /g;
(/ERROR|failed/) && do {
print( color( 'red' ). $_ .color( 'reset' )."\n" );
next;
};
(/WARN/) && do {
print( color( 'magenta' ). $_ .color( 'reset' )."\n" );
next;
};
(/succeeded/) && do {
print( color( 'green' ). $_ .color( 'reset' )."\n" );
next;
};
(/INFO/) && do {
print( color( 'yellow' ). $_ .color( 'reset' )."\n" );
next;
};
(/DEBUG/) && do {
print( color( 'blue' ). $_ .color( 'reset' )."\n" );
next;
};
print $_."\n";
}
Taking Screenshots in Mac OS X
Shortcuts
* Command-Shift-3: Take a screenshot of the screen, and save it as a file on the desktop
* Command-Shift-4, then select an area: Take a screenshot of an area and save it as a file on the desktop
* Command-Shift-4, then space, then click a window: Take a screenshot of a window and save it as a file on the desktop
* Command-Control-Shift-3: Take a screenshot of the screen, and save it to the clipboard
* Command-Control-Shift-4, then select an area: Take a screenshot of an area and save it to the clipboard
* Command-Control-Shift-4, then space, then click a window: Take a screenshot of a window and save it to the clipboard
In Leopard, the following keys can be held down while selecting an area (via Command-Shift-4 or Command-Control-Shift-4):
* Space, to lock the size of the selected region and instead move it when the mouse moves
* Shift, to resize only one edge of the selected region
* Option, to resize the selected region with its center as the anchor point
How to see the answers for free on Expert Exchange
Solution:
Scroll down
Code folding in vi
Config settings for code folding: http://smartic.us/2009/04/06/code-folding-in-vim/
Vim documentation for folding: http://www.vim.org/htmldoc/fold.html
There are six methods to select folds:
manual manually define folds
indent more indent means a higher fold level
expr specify an expression to define folds
syntax folds defined by syntax highlighting
diff folds for unchanged text
marker folds defined by markers in the text
Key concepts:
- To use the indent method you need to set the :tabstop correctly
- Syntax method requires the correct syntax files to be present
- zc -> close fold
- zo -> open fold
How to talk to memcached
- telnet to the server (or localhost) on the right port
- type "flush_all" to invalidate the whole cache
- type "delete [key]" to invalidate a particular item
Combine multiple lines in multiple files into a single spreadsheet row
Toggle visibility of non-printable characters in Mac Word
seq on Mac?
instead of: seq 1 10
seq [first] [increment] [last]
try: jot 10 1 10
jot [reps] [start] [finish] [step]
How big are my MySQL databases?
SELECT TABLE_SCHEMA AS 'Database', TABLE_NAME AS 'Table', CONCAT(ROUND(((DATA_LENGTH + INDEX_LENGTH - DATA_FREE) / 1024 / 1024),2)," MB") AS Size FROM INFORMATION_SCHEMA.TABLES
Combinations, permuations and iterations
To generate sequential values for a set of slots, e.g. all binary numbers, or the number of 'max_results' for several modules do this:
- add one to the first slot
- if that takes it over the maximum, set it to zero and add one to the next slot
- repeat step 2 until you reach all zeroes
- if all zeroes, you are finished.
Upper and lowercase in vi
Intermittent bugs
Turn a lot of logging on, then check the logs for occurrences of the bug.
Setting up xemacs xslt-process mode
#########################
# copied from /etc/java/java.conf
# JPackage Project
#########################
# Location of jar files on the system
export JAVA_LIBDIR=/usr/share/java
# Location of arch-specific jar files on the system
export JNI_LIBDIR=/usr/lib/java
# List of known java homes (used for autodetection if none is provided)
export JAVA_HOME_LIST=$JAVA_LIBDIR-utils/java_home.list
# Root of all JVM installations
export JVM_ROOT=/usr/lib/jvm
# Default jvm
export JAVA_HOME=$JVM_ROOT/java
# Options to pass to the java interpreter
export JAVACMD_OPTS=
#########################
export CLASSPATH=/usr/share/java
Now when I try to run xslt-process, it says:
Starting the BeanShell. Please wait...
...but then straight away it still always says:
Could not process file, most probably (Xalan1|Saxon) could not be found!
What I think is happening:
- xalan-2.4.1.jar is installed, not xalan1 as is required.
- Not all of saxon's dependencies are installed.
Installing an XSLT processor
Installing Saxon on Linux. Is JAXP 1.3 required? And then how would I test it anyway?
Could install Xalan. But it's already included with Java:
java org.apache.xalan.xslt.EnvironmentCheck
Why can't xemacs' xlst-process mode find any xslt processor?
Simple XSL test
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="xsl.xsl"?>
<hello-world>
<greeter>An XSLT Programmer</greeter>
<greeting>Hello, World!</greeting>
</hello-world>
xsl.xsl file:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/hello-world">
<HTML>
<HEAD>
<TITLE></TITLE>
</HEAD>
<BODY>
<H1>
<xsl:value-of select="greeting"/>
</H1>
<xsl:apply-templates select="greeter"/>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="greeter">
<DIV>from <I><xsl:value-of select="."/></I></DIV>
</xsl:template>
</xsl:stylesheet>
Working with xemacs XSLT-process mode
C-c C-x v - run the xslt processor and view results (be sure to type slowly enough!)
M-x customize-group RET xslt-process - options menu: change engine, customise key bindings, etc.
NOTE: the default run command above may have problems under cygwin. Redefine it to C-x C-c C-v and it should work.
xemacs buffer control
C-x C-b - list existing buffers
C-x 1 - close the buffer list
Emacs and Cygwin
From within Cygwin, if you start xemacs with: xemacs -nw (for No Window), then C-x C-c to quit emacs does not work. Instead you must type C-g to exit.
xemacs mode line
http://www.xemacs.org/Documentation/21.5/html/xemacs_4.html#SEC10
GNU info
b | go to beginning of the page |
? | help |
m | choose a menu item from the current page (has tab completion) |
f | choose a cross-reference to follow (tab completion) |
f? | list all cross-references on the current page |
l | go back to last page |
Ctrl-g | cancel menu command |
i | search index for topic |
d | directory of all info pages |
t | go to 'top' of current manual |
s | search forward |
q | quit info screen |
Pass a parameter to XSL in Cocoon
<map:transform src="xslt/page.xsl">
<map:parameter name="param1" value="{1}"/>
</map:transform>
In the XSL:
<xsl:param name="param1"/>
...
<xsl:template match="whatever">
<xsl:attribute name="something">
<xsl:value-of select="$param1"/>
</xsl:attribute>
</xsl:template>
XSL variables
<xsl:variable name="something" select="21">
Use a variable
<xsl:value-of select="$something">
You can't change the value of variables.
Emacs
Viper is a full-featured Vi emulator for GNU Emacs and XEmacs. But if you don't use that, keep reading.
Emacs notes, from the perspective of a vi user
Problems:
* The manual calls for C-h (Ctrl-h) to be used as a special command
** but when using Putty from Windows, by default Ctrl-h just does a backspace.
** from Windows, it can't tell the difference between Ctrl-H and the backspace key
** This means if you re-map Ctrl-H, it also re-maps the Backspace key. I haven't solved this yet.
--------------------------------------------------------
To read the manual on key commands:
1) type F1, i - gets you to the info menu
2) type m, emacs, [enter] - takes you to the Emacs info file
3) Page down to "Fundamental Editing Commands", "Important Text-Changing Commands", etc. and press [enter] on the menu items you want (typing lowercase L takes you
'back' one page)
--------------------------------------------------------
Notes:
* Terminology: C-x means Ctrl-x, C-M-x means Ctrl-Meta-x - the Meta key is Alt under MS Windows)
* For some commands, holding Ctrl is required for the second character (e.g. quit: C-x, C-c), and for others commands it's not (e.g. undo: C-x u)
* Commands like this "M-x set-visited-file-name" mean: type Meta-x, then type the string 'set-visited-file-name'.
* After typing M-x you can also use tab-completion to find commands.
Translation of common Emacs commands for vi users:
command | vi | emacs |
save file | :w | C-x C-s |
save & exit read-only file | :wq! | C-x, C-c, follow prompts |
save to a different file | :w foo | M-x set-visited-file-name |
find a file to open | C-x C-f | |
delete to end of line | Shift-d | C-k |
undo | u | C-x u |
u | C-_ (hold Ctrl, press dash/hypen/underscore key) | |
redo | r | break out of undo mode, and type C-_ again |
note: these searches are case insensitive | ||
search forward | / | C-s (incremental / search-as-you-type) |
/ | C-s, [enter] (non incremental / type whole word, then search) | |
search backward | ? | C-r (incremental) |
? | C-r, [enter] (non incremental) | |
note: even these *regex* searches are case insensitive. There is a way to make them case sensitive: set the variable `case-fold-search' to `nil'. | ||
search forward using regex | C-M-s (incremental) | |
and backward | C-M-r | |
call out to the shell | ! | M-! (Meta-Shift-1) |
start a full subshell | M-x eshell |
Notes on differences to vi:
* undo commands wrap around. Once you undo all your edits, the undo command reverses direction and starts re-doing the edits! break out of the undo mode and press C-_ (undo) again to change the direction of undo/redo command.
* files are autosaved to a seperate buffer. to recover after a crash, type: M-x recover-file
Emacs-only commands:
list commands in help menu | F1, ? |
get help on key combinations | F1, k, [some key combination] |
toggle read-only status of the buffer | C-x, C-q |
get out of a command | C-g |
redo an edit (undo the undo) | type any harmless character to break out of undo mode. You will now be able to undo your undo commands. |
remove help window | C-x 1 |
scroll the help | C-M-v |
re-map a key | M-x global-set-key [enter] |
XSL de-duping
<xsl:choose> <xsl:when test="/session/dataset = 'news'"> <xsl:for-each-group select="item" by="lower-case(title)"> <xsl:apply-templates select="current-group()[1]"> </xsl:apply-templates></xsl:for-each-group> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="item[title != '']"> </xsl:apply-templates></xsl:otherwise>
</xsl:choose>
PHP 5 XML
PHP 4 XSL
NOTE:
This extension uses Sablotron and expat, which can both be found at http://www.gingerall.org/sablotron.html. Binaries are provided as well as source.
You must run configure with the --enable-xslt --with-xslt-sablot options.
<?php
$xml = <<<EOT
<?xml version="1.0"?>
<hello-world>
<greeter>An XSLT Programmer</greeter>
<greeting>Hello, World!</greeting>
</hello-world>
EOT;
$xsl = <<<EOT
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/hello-world">
<HTML>
<HEAD>
<TITLE></TITLE>
</HEAD>
<BODY>
<H1>
<xsl:value-of select="greeting"/>
</H1>
<xsl:apply-templates select="greeter"/>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="greeter">
<DIV>from <I><xsl:value-of select="."/></I></DIV>
</xsl:template>
</xsl:stylesheet>
EOT;
$arguments = array(
'/_xml' => $xml,
'/_xsl' => $xsl
);
// Allocate a new XSLT processor
$xh = xslt_create();
// Process the document
$result = xslt_process($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $arguments);
if ($result) {
echo "SUCCESS, sample.xml was transformed by sample.xsl into the \$result";
echo " variable, the \$result variable has the following contents\n<br />\n";
//echo "<pre>\n";
echo $result;
//echo "</pre>\n";
} else {
echo "Sorry, sample.xml could not be transformed by sample.xsl into";
echo " the \$result variable the reason is that " . xslt_error($xh);
echo " and the error code is " . xslt_errno($xh);
}
xslt_free($xh);
?>
PHP for Mac OSX
PHP command line
file.php contains:
<?php
php -r "some code;"
Don't forget the trailing semicolon.
PHP 4 XML
$doc = xmldocfile("myfile.xml");
if ($doc){
print $doc->dumpmem();
}
NOTE: PHP must be compiled with --with-dom and --with-xml.
phpinfo() will display this information right at the top.
PHP 5 XSL
PHP regular expressions
/(.*)something/s
The s at the end causes the dot to match all characters including newlines.
Use a string to make a variable name
{
no strict 'refs';
my $num = 10;
print eval "\$rank$num";
}
result:
42
Type a literal tab in vi
Enjoy logging with Zend
Beware of backslashes in login strings
...can lead to problems.ftp://domain\user:pass@host/path
The backslash is not a legal URI character, so $uri->user may bring back just the domain!
Scanning HTML
my $real_h1 = $tree->look_down(
'_tag', 'h1',
sub {
my $link = $_[0]->look_down('_tag','a');
return 1 unless $link; # no link means it's fine
return 0 if $link->attr('href') =~ m{/dyna/}; # a link to there is bad
return 1; # otherwise okay
}
);
C# SQL database connections
//get db connection to copy from
MySqlConnection sourceDbConn = getConnection(db);
sourceDbConn.Open();
try
{
System.Data.DataSet ds = new System.Data.DataSet();
MySqlDataAdapter da;
MySqlCommandBuilder cb;
da = new MySqlDataAdapter("SELECT id FROM page where pageType = '" + pageType + "'", sourceDbConn);
cb = new MySqlCommandBuilder(da);
ds.DataSetName = "pageIds";
da.Fill(ds);
foreach (DataTable thisTable in ds.Tables)
{
foreach (DataRow row in thisTable.Rows)
{
idsArray[i++] = Int32.Parse(row["id"].ToString());
}
}
return idsArray;
}
catch
{
throw new Exception("Failed to get list of page to publish");
}
finally
{
sourceDbConn.Close();
}
}
Another way to do it, with bound parameters:
// get feed changes - picking up all data required to create new feeds
MySqlCommand getFeeds = new MySqlCommand("select id, type, title, maxresults, minrelevance, mindate from feeds where client_id = ?client_id and updated_date > ?max_updated_date", editorialConn);
getFeeds.Parameters.AddWithValue("?client_id", selected_staging_client_id);
getFeeds.Parameters.AddWithValue("?max_updated_date", PublishChangesSince);
MySqlDataReader getFeedsRdr = getFeeds.ExecuteReader();
while (getFeedsRdr.Read())
{
Int32 FeedID = getFeedsRdr.GetInt32(0);
String FeedType = getFeedsRdr.GetString(1);
String FeedTitle = getFeedsRdr.GetString(2);
Int32 FeedMaxResults = getFeedsRdr.GetInt32(3);
float FeedMinRelevance = getFeedsRdr.GetFloat(4);
DateTime FeedMinDate = getFeedsRdr.GetDateTime(5);
}
getFeedsRdr.Close();