Archive for the ‘codeRelease’ Category

Randomly writing CSV data in PHP

Today’s project: add or replace values in a comma-separated-value file. The application is for tag-counting by week, so the first column is effectively an ID column & the rest (for me) are integers. But here’s the code with some sample data grabbed from a random Google search..

<?
/************** Vars ***************/

$str="id,age,sex,region,income,married,children,car,save_act,current_act,mortgage,pep
ID12101,48,FEMALE,INNER_CITY,17546.0,NO,1,NO,NO,NO,NO,YES
ID12102,40,MALE,TOWN,30085.1,YES,3,YES,NO,YES,YES,NO
ID12103,51,FEMALE,INNER_CITY,16575.4,YES,0,YES,YES,YES,NO,NO
ID12104,23,FEMALE,TOWN,20375.4,YES,3,NO,NO,YES,NO,NO
ID12105,57,FEMALE,RURAL,50576.3,YES,0,NO,YES,NO,NO,NO
ID12106,57,FEMALE,TOWN,37869.6,YES,2,NO,YES,YES,NO,YES
ID12107,22,MALE,RURAL,8877.07,NO,0,NO,NO,YES,NO,YES
ID12108,58,MALE,TOWN,24946.6,YES,0,YES,YES,YES,NO,NO
ID12109,37,FEMALE,SUBURBAN,25304.3,YES,2,YES,NO,NO,NO,NO
ID12110,54,MALE,TOWN,24212.1,YES,2,YES,YES,YES,NO,NO
ID12111,66,FEMALE,TOWN,59803.9,YES,0,NO,YES,YES,NO,NO
ID12112,52,FEMALE,INNER_CITY,26658.8,NO,0,YES,YES,YES,YES,NO
ID12113,44,FEMALE,TOWN,15735.8,YES,1,NO,YES,YES,YES,YES
ID12114,66,FEMALE,TOWN,55204.7,YES,1,YES,YES,YES,YES,YES
ID12115,36,MALE,RURAL,19474.6,YES,0,NO,YES,YES,YES,NO";

$tags2find_arr=array();
$tags2find_arr['ID12106']=array(1=>1,4=>100);  //additive numbers, or replacing?
$tags2find_arr['ID12102']=array(1=>1,4=>200);
$tags2find_arr['ID12114']=array(1=>1,4=>300);

$fn='test.txt';
/************** Runtime ***************/

writeCSV($fn,$str);
writeRandCSV($fn,$tags2find_arr,'add');

/************** Functions ***************/

function writeCSV($fn='',$str=''){

$fh=fopen($fn,'w');
fwrite($fh,$str);
fclose($fh);
}
/****************************/
function writeRandCSV($fn,$tags2find_arr,$addreplace='add'){
$fl=filesize($fn);
$fh=fopen($fn,'r+'); //open for reading, and writing, but don't kill the contents
$str=fread($fh, $fl);

foreach($tags2find_arr as $tag2find=>$csv_data_addreplace){  //$tag2find='ID12108';
//find the line in the str			//alt: explode by '\n' or '\r' &amp;amp; get an array &amp;amp; it's size.. find in array, truncate array,implode &amp;amp; find strlen's for loc &amp;amp; write-len
$readtagloc=strpos($str,$tag2find.',');   //this could be a problem for smaller tags found in larger.. throw a \n before &amp;amp; a , after?
//echo "\r<br/>".$tag2find." @".$readtagloc;

//find it's corollary in the file
fseek($fh,$readtagloc);
$fcsv_arr=fgetcsv($fh); //should only get one line!
//for($i=0;$i<count($fcsv_data);$i++){
//$fcsv_arr[$i]=$fcsv_arr[$i]+$csv_data_addreplace[$i]; //58->59
foreach($csv_data_addreplace as $csv_idx=>$csv_addreplace){
  if($addreplace=='add') $fcsv_arr[$csv_idx]+=$csv_addreplace; //58->59
  else $fcsv_arr[$csv_idx]=$csv_addreplace;
}
//print_r($fcsv_arr);

/******************************/
//echo '\r<br/>'.ftell($fh).' or '.(ftell($fh)-strlen(implode(',',$csv_arr))-1 );
fseek($fh,$readtagloc); //back to beginning of line to write now
//$read=fread($fh, $readlen);
//hoping the pointer is still in the same loc &amp;amp; not @ line-end!

$ok[$tag2find]=fputcsv($fh,$fcsv_arr,',');
$sz=(strlen(implode(',',$fcsv_arr))+1);

//if($ok===false){ echo "FAILURE"; }
//if($ok==$sz){ echo "\r<br/>written length ok:".$ok; }
//else { "\r<br/>written length not ok:".$ok.'<'.$sz; }

} //end foreach tag
$ok[]=fclose($fh);
return $ok;

} //close function
/******************************/
?>

Read Google Calendars from Orage!

Holy crap! My fav toolbar calendar is more than just a calendar! It does alarms & full ICS input & output! With a little scripting & cron, I get the day’s events with one click!

#!/bin/sh
cd ~/tmp
wget http://www.google.com/calendar/ical/--your-private-gcal--url/basic.ics
mv basic.ics calname.ics

Just repeat the wget & mv for all calendars, add an hourly cron job & add the files to orage’s preferences/foreign calendars tab!

Love is simplicity!

A Better Openbox transparency

I’m lately in love with openbox for it’s simplicity and lack of screen-coverage. Sure I could have setup my desktop within xubuntu, but I wanted to expand my horizons.

My original theory was for netbook application, maximizing screen real estate & reducing the hard drive & processor use. But lately, I’ve been toying with xcompmgr, hardly a ‘wise’ use of resources.

While Urukrama has a wonderfully extensive Openbox config page, I didn’t find the “make all inactive windows 60% transparent” like I was looking for.

A little googling gave me the solution I was after, but it was insanly processor/battery intensive! (That’s what ya get for writing an infinite loop! ) At first I tried putting a “sleep” command in the loop, and that did tremendous wonders for retaining processor use, and slowing down my frantic computer-work pace. Still, I wasn’t pleased.

So here, without further ado, is my xcompmgr+transset-df+perl script for setting all non-active windows:

#!/usr/bin/perl -w

# This script is a modification my M.Wallace of the
# original written by Andrei Perhinschi
# and is licensed under the GNU GPL license
# http://www.gnu.org/licenses/gpl.html

# Much thanks goes to Daniel Forchheimer (http://www.forchheimer.se/)
# for creating transset-df and the eutotrans
# script from which this script gets its inspiration

if ( !defined $ARGV[0] || !defined $ARGV[1] || !defined $ARGV[2] ) {
die "Usage: focustran-once <unfocused value> <focused value> <refresh value (secs)>\n";
}

# default values
$trans_val = $ARGV[0];
$opaque_val = $ARGV[1];
$sleep_val = $ARGV[2];

# grab all window IDs
@win_ids = `xwininfo -root -all`;
foreach my $win_id ( @win_ids ) {
unless ( $win_id =~ /has\ no\ name/ || $win_id !~ /0x/ || $win_id =~ /Desktop/ ) {
 $win_id =~ /\ \"/;
 $win_id = "$`";
 $win_id =~ s/\s//g;
 push @id_lines, $win_id;
 }
}

#print "ID_LINES:@id_lines\n";

# find my active window
my $active_id = `xprop -root  | grep "_NET_ACTIVE_WINDOW(WINDOW): window id # "`;
$active_id =~ /\#\s/;
$active_id = "$'";
chomp $active_id;

# set the active window to non-transparent value
system ( "transset-df --id $active_id $opaque_val" );

# make all other windows transparent
foreach my $win_id ( @id_lines ) {
# set active window to opaque_val and old window to trans_val
if ( $win_id ne $active_id ) {
system ( "transset-df --id $win_id $trans_val" );
 }
}

Then just add these lines to ./config/openbox/rc.xml (around line 302 for me):

    <context name="Client">
      <mousebind button="Left" action="Press">
        <action name="execute">
        <execute>perl ~/bin/focustrans-once.pl .6 1 0</execute>
        </action>
      </mousebind>
    </context>

Trouble is, I use mouse-raises windows, not click-to-focus! Anyone got some help for me, be it X11 active window or openbox mouse-motion-detect?

WordPress SQL list of active templates

Need I say more?

SELECT posts.ID, posts.post_title, meta.meta_value
FROM wp_posts as posts
LEFT JOIN wp_postmeta as meta
ON posts.ID=meta.post_id where
posts.post_type=’page’ and posts.post_status=’publish’ and  meta.meta_key like ‘_wp_page_template’;

Subversion Mac fix

Subversion is great for more than just simple backups.. it’ll let me know when files were edited, and which files were changed in each sync.

But Subversion was written for the land of *nix/Windows, where these obnoxious things called resource forks don’t exist, where Finder doesn’t auto-create files.

Hear ye, hear ye, I have created the solution.
Mac OS’ .DS_Store files: killed.
Mac OS’ ._blah files: killed.
KDE’s .directory files: killed.

Furthermore, this bash script will auto-update & commit too. Handy for an all-in-one’er. Now, I know, many of you out there are more subversion-knowledgeable, and use hooks for this, but this little beasty will solve already-present crap-files in a repository.

Hope it works for y’all. I’ve tested it against all my repos with lots of crazy characters.. all the quotes out there, etc.

Future improvements: I’m willing to hear about. (like perl regEx’ing svn’s errors to stop the script.. or one-control+c script-stopping)

#/bin/sh
####################################################
## Usage:
##     sh thisscriptfilename.sh folder
##
## Config: change the value of 'export loc'.
##
## Issues handled:
##  quotes in filenames: -print0 / xargs -0
##  spaces in filenames: -print0 / xargs -0
##  svn can't delete files not added: --force
##  svn can't --force delete files in un-added folders: rm -f after svn --force delete
####################################################

export loc="/Volumes/storage/"

cd "$loc/$1"

echo "Displaying status: $loc/$1"
svn status .

echo "Updating changes from server"
svn update .

echo "Cleaning up"
## no MacOS Resource forks!
find "$loc/$1" \( ! -name .svn -o -prune \) -type f -iname "._*" -print0 | xargs -0  svn --force delete
find "$loc/$1" \( ! -name .svn -o -prune \) -type f -iname "._*" -print0 | xargs -0  rm -f

## no KDE .directory!
find "$loc/$1" \( ! -name .svn -o -prune \) -type f -iname ".directory" -print0 | xargs -0 svn --force delete
find "$loc/$1" \( ! -name .svn -o -prune \) -type f -iname ".directory" -print0 | xargs -0 rm -f

## no .DS_Stores!
find "$loc/$1" \( ! -name .svn -o -prune \) -type f -iname ".DS_Store" -print0 | xargs -0 svn --force delete
find "$loc/$1" \( ! -name .svn -o -prune \) -type f -iname ".DS_Store" -print0 | xargs -0 rm -f

### test:
## find "$loc/$1" \( ! -name .svn -o -prune \) -type f -iname "._*" -print0 | xargs -0 ls -lsa

echo "Adding.."
svn --force add .

echo "Status to send:"
svn status .

echo "Sending.."
svn commit -m '' .

echo "Final status:"
svn status .

WordPress categories, multiple months.

While making my own archives page, I needed to display the most recent 3 months posts (by sub-category list, where parent category_id=7). So I needed to smash all the tables together & filter out what I didn’t need. In this case, I needed the category names which had posts in the past 3 months. Easily modifiable to get the post names as well.


global $wpdb;
$categories = $wpdb->get_results("select wt.term_id,wt.name,wtt.description from $wpdb->term_relationships as `wtr`
left join $wpdb->posts wp on wtr.object_id=wp.id
left join $wpdb->term_taxonomy wtt on wtr.term_taxonomy_id=wtt.term_id
left join $wpdb->terms wt on wt.term_id=wtt.term_id
where  parent = '7' and post_date>= DATE_SUB(CURDATE(), INTERVAL 3 month) and post_type='post' and post_status='publish'; ");

foreach($categories as $category) {
print_r( $category);
}
?>

WordPress: Author List by Category

I just keep functioning out WP! (What can I say, it’s my job!)

This is a rework of WP’s own list_authors() function, but with some extra SQL:


<?php

function my_list_authors_by_category($args = '', $cat_id=0) {
global $wpdb;

$defaults = array(
'optioncount' => false, 'exclude_admin' => true,
'show_fullname' => false, 'hide_empty' => true,
'feed' => '', 'feed_image' => '', 'feed_type' => '', 'echo' => true
);

$r = wp_parse_args( $args, $defaults );
extract($r, EXTR_SKIP);

$return = '';

/** @todo Move select to get_authors(). */
//&#160;&#160;&#160; $authors = $wpdb->get_results("SELECT ID, user_nicename from $wpdb->users " . ($exclude_admin ? "WHERE user_login <> 'admin' " : '') . "ORDER BY display_name");
//replace with the 'author by category' SQL
$authors = $wpdb->get_results("SELECT distinct post_author as `ID`, user_nicename FROM `default_posts` as `dp`, `default_terms` as `dt`, `default_term_relationships` as `dtr`,`default_users` as `du` where `dp`.`post_author`=`du`.`ID` and `dp`.`ID`=`dtr`.`object_id` and `dtr`.`term_taxonomy_id`=".$cat_id.";");

$author_count = array();
foreach ((array) $wpdb->get_results("SELECT DISTINCT post_author, COUNT(ID) AS count FROM $wpdb->posts WHERE post_type = 'post' AND " . get_private_posts_cap_sql( 'post' ) . " GROUP BY post_author") as $row) {
$author_count[$row->post_author] = $row->count;
}

foreach ( (array) $authors as $author ) {
$author = get_userdata( $author->ID );
$posts = (isset($author_count[$author->ID])) ? $author_count[$author->ID] : 0;
$name = $author->display_name;

if ( $show_fullname && ($author->first_name != '' && $author->last_name != '') )
$name = "$author->first_name $author->last_name";

if ( !($posts == 0 && $hide_empty) )
$return .= '<li>';
if ( $posts == 0 ) {
if ( !$hide_empty )
$link = $name;
} else {
$link = '<a href="' . get_author_posts_url($author->ID, $author->user_nicename) . '" title="' . sprintf(__("Posts by %s"), attribute_escape($author->display_name)) . '">' . $name . '</a>';

if ( (! empty($feed_image)) || (! empty($feed)) ) {
$link .= ' ';
if (empty($feed_image))
$link .= '(';
$link .= '<a href="' . get_author_rss_link(0, $author->ID, $author->user_nicename) . '"';

if ( !empty($feed) ) {
$title = ' title="' . $feed . '"';
$alt = ' alt="' . $feed . '"';
$name = $feed;
$link .= $title;
}

$link .= '>';

if ( !empty($feed_image) )
$link .= "<img src=\"$feed_image\" style=\"border: none;\"$alt$title" . ' />';
else
$link .= $name;

$link .= '</a>';

if ( empty($feed_image) )
$link .= ')';
}

if ( $optioncount )
$link .= ' ('. $posts . ')';

}

if ( !($posts == 0 && $hide_empty) )
$return .= $link . '</li>';
}
if ( !$echo )
return $return;
echo $return;
}
?>

And then to call, just define the category you want:


<?php

$cat=0;
if (have_posts()){&#160;&#160;&#160; //get the present category, if there is one
if (is_category()) {
$cat = get_query_var('cat');
}
}
if($cat!=0){
?>
<h2>Authors:</h2>
<ul>
<? my_list_authors_by_category('exclude_admin=1',$cat); ?>
</ul>
<? } ?>

Fake out wordpress to pull in another page-content..

Sometimes using <? $thispost=get_post($id); echo $thispost->post_content ?> isn’t enough.

Sometimes, you need a full menu structure to be highlighted or built according to that post.

Sometimes you need a menu parent pull in the ‘first child’ content.

Sometimes, you need to fake wordpress out:


<? //Usage: given, any time this template is called and happens to be on page_id '6' make page '6' act  like page '8'.
$wp_query=fakePage($wp_query->post->ID,"6","8",$wp_query);

function fakePage($currid,$thisid,$fakeid,$wp_query){
if(strcmp($currid,$thisid)==0){
$thispost=get_post($fakeid);

//the fake-out
$wp_query->post->ID=$fakeid;
$wp_query->post->post_content=$thispost->post_content;

$wp_query->queried_object->ID=$fakeid;
$wp_query->queried_object_id=$fakeid;
$wp_query->queried_object->post_content=$thispost->post_content;

$wp_query->posts[0]->ID=$fakeid;
$wp_query->posts[0]->post_content=$thispost->post_content;
}
return $wp_query;
} ?>