ByePie

Tags: , December 28, 2007 (0 comments)

Having put a lot of thought into the matter over the past several weeks, I've made my decision to leave development of SimplePie.

"Why!? Oh Why!?", you scream (well, maybe not, but I'm not a telepathic seer). For a start, I haven't actually really used SimplePie myself since early 2006 (now almost two years ago), and I now have less and less to do with PHP at all (and I totally hate it — a recent bug in SP was caused by the fact that "0" == false — and have therefore moved to (mainly) Python).

Furthermore, over the past year, since March/April, my time has become increasingly limited, and SP has de-facto been one of the things that I have cut a long time ago (the reason for the lack of commits from me much) — the majority of my time is now spent on schoolwork, with what is left over being spent working on various specs (predominantly HTML 5 and Tolerant HTTP Parsing).

However, what does the future of SP hold? Well, various decisions need to be made about the future direction — do you try and improve 1.x further (it was already stretched to breaking point at 1.0, mainly held back by PHP itself — a sad state to be in), or do you start on the vision of SP2? To take the former option, I doubt you could get much further than what is currently planned for 1.2 with the current 1.x base — any further development requires a large amount of reworking the internals of SP (to the extreme of being questionable about whether there is any point of not starting from scratch). The latter option is probably the best (though ideally get 1.1 out as soon as it can be).

One of the aims of SP2 is true modularity — it should be possible to use (and load) nothing more the parser itself (i.e., give it raw XML data, and it gives you an API to access the title, description, etc. as they are in the feed without sanitising them at all) — which has several advantages for deciding any successor to myself: get people to write various modules for it against pre-existing specs (most of which are only drafts and so will need further development over time). What exactly those modules will be I am mainly undecided (though it won't, I assure you, be the more complex parts of the API itself — the design of them is mainly unwritten and comes from knowledge of successes/failures from SP1's API). I will myself continue maintaining a couple of the modules (namely, the Unicode and IRI ones, both of which I use outwith of SP — though more may be added to that list).

I'm more than willing to be around in a consulting role for a while — my contact details are in the footer here, and I'll stay around in the IRC channel for a while — as well as helping people around the SP1 codebase (though I'd like to see that totally feature frozen come the end of January, with a final non-bugfix release from it in February) — which is horrifically uncommented in parts, and uses stupidly complex algorithms in others that without prior knowledge of them make no sense (I've had issues with some myself when coming back to them having not touched them in a while :) ).

Alas, there's too much to write about the vision of SP2, so that will have to be done in another post; until then, g'nite.

2007 Resolutions

Tags: , , , , January 6, 2007 (1 comment)

  1. Learn guitar - Any type of guitar really, although I know it'll end up just being an acoustic guitar.
  2. Read more - Due to being ill, I've really not managed to read much recently.
  3. Get well - Uh, yeah. Seeming I've pretty much been ill for the past four years, I could do with getting well.
  4. Ship - SimplePie 1.0, Fbug 1.0, as well as the ever mysterious BookIt 1.0, should really all ship this year. Hopefully get out 1.1 releases as well.
  5. Be strong - Mentally, that is. Anyone who knows me in the real world will know how much of a shy, nervous, embarrassed coward I am.
  6. Make best friend jealous - This, admittedly, has two prerequisites which are on this list: 3 and 5.
  7. Catch up at school - Having been ill, I've missed a heckuva lot. Getting credit passes in every subject would be succeeding in this.

Well, 7 resolutions for 2007 will do for me.

Resolving Relative URLs in PHP

Tags: , December 27, 2006 (0 comments)

This is deprecated, and has known bugs. See here for a replacement.

There are plenty of cases for needing to resolve relative URLs - RFC 3986 (Generic URI Syntax) has a whole section on how to go about it. SimplePie has code for this, written by me in it's entirety (although based on the pseudo-code in RFC 3986), used to deal with relative URLs in feeds (which happens to be possible pretty much everywhere). As I am the soul author of it, I've rearranged it slightly into a single function (in SimplePie it's in several methods within a larger class, as most of the methods are also called in other places), and re-licensed it under the 3 clause BSD license, LGPL, and zlib/libpng license (although of course if you redistribute it you must attach the appropriate notice as stated by one of the above licenses).

Without further ado, here's the code:

<?phpfunction absolutize_url($relative$base)
{
    
$relative trim($relative);
    
$base trim($base);
    if (!empty(
$relative))
    {
        
preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/i'$relative$match);
        for (
$i count($match); $i <= 9$i++)
        {
            if (!isset(
$match[$i]))
            {
                
$match[$i] = '';
            }
        }
        
$relative = array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
        if (!empty(
$relative['scheme']))
        {
            
$target $relative;
        }
        else if (!empty(
$base))
        {
            
preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/i'$base$match);
            for (
$i count($match); $i <= 9$i++)
            {
                if (!isset(
$match[$i]))
                {
                    
$match[$i] = '';
                }
            }
            
$base = array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
            
$target = array('scheme' => '''authority' => '''path' => '''query' => '''fragment' => '');
            if (!empty(
$relative['authority']))
            {
                
$target $relative;
                
$target['scheme'] = $base['scheme'];
            }
            else
            {
                
$target['scheme'] = $base['scheme'];
                
$target['authority'] = $base['authority'];
                if (!empty(
$relative['path']))
                {
                    if (
strpos($relative['path'], '/') === 0)
                    {
                        
$target['path'] = $relative['path'];
                    }
                    else
                    {
                        if (
$base['path'] == '/' || empty($base['path']))
                        {
                            
$target['path'] = '/' $relative['path'];
                        }
                        else
                        {
                            
$target['path'] = preg_replace('/^(.*)((\/)([^\/]*))?$/sU''\\1'$base['path']) . '/' $relative['path'];
                        }
                    }
                    if (!empty(
$relative['query']))
                    {
                        
$target['query'] = $relative['query'];
                    }
                    
$input $target['path'];
                    while (!empty(
$input))
                    {
                        
// A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
                        
if (strpos($input'../') === 0)
                        {
                            
$input substr($input3);
                        }
                        else if (
strpos($input'./') === 0)
                        {
                            
$input substr($input2);
                        }
                        
// B: if the input buffer begins with a prefix of "/./" or "/.", where "." is a complete path segment, then replace that prefix with "/" in the input buffer; otherwise,
                        
else if (strpos($input'/./') === 0)
                        {
                            
$input substr_replace($input'/'03);
                        }
                        else if (
$input == '/.')
                        {
                            
$input '/';
                        }
                        
// C: if the input buffer begins with a prefix of "/../" or "/..", where ".." is a complete path segment, then replace that prefix with "/" in the input buffer and remove the last segment and its preceding "/" (if any) from the output buffer; otherwise,
                        
else if (strpos($input'/../') === 0)
                        {
                            
$input substr_replace($input'/'04);
                            
$target['path'] = preg_replace('/(\/)?([^\/]+)$/U'''$target['path']);
                        }
                        else if (
$input == '/..')
                        {
                            
$input '/';
                            
$target['path'] = preg_replace('/(\/)?([^\/]+)$/U'''$target['path']);
                        }
                        
// D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
                        
else if ($input == '.' || $input == '..')
                        {
                            
$input '';
                        }
                        
// E: move the first path segment in the input buffer to the end of the output buffer, including the initial "/" character (if any) and any subsequent characters up to, but not including, the next "/" character or the end of the input buffer
                        
else
                        {
                            if (
preg_match('/^([^\/]+|(\/)[^\/]*)(\/|$)/'$input$match))
                            {
                                
$target['path'] .= $match[1];
                                
$input substr_replace($input''0strlen($match[1]));
                            }
                            else
                            {
                                
// We've ended up in a recursive loop, so do what we otherwise never will: return false.
                                
return false;
                            }
                        }
                    }
                }
                else
                {
                    if (!empty(
$base['path']))
                    {
                        
$target['path'] = $base['path'];
                    }
                    else
                    {
                        
$target['path'] = '/';
                    }
                    if (!empty(
$relative['query']))
                    {
                        
$target['query'] = $relative['query'];
                    }
                    else if (!empty(
$base['query']))
                    {
                        
$target['query'] = $base['query'];
                    }
                }
            }
            if (!empty(
$relative['fragment']))
            {
                
$target['fragment'] = $relative['fragment'];
            }
        }
        else
        {
            
// No base URL, just return the relative URL
            
$target $relative;
        }
        
$return '';
        if (!empty(
$target['scheme']))
        {
            
$return .= "$target[scheme]:";
        }
        if (!empty(
$target['authority']))
        {
            
$return .= "//$target[authority]";
        }
        if (!empty(
$target['path']))
        {
            
$return .= $target['path'];
        }
        if (!empty(
$target['query']))
        {
            
$return .= "?$target[query]";
        }
        if (!empty(
$target['fragment']))
        {
            
$return .= "#$target[fragment]";
        }
    }
    else
    {
        
$return $base;
    }
    return 
$return;
}
?>

Why SimplePie r00lz!11!!!1!!111!!!!!

Tags: , September 20, 2006 (0 comments)

Ever since this and this, I've been getting various gifts (well, actually, only two — R30 and Signals, both by Rush). Proof that you can get gifts from working on open source software, in my case SimplePie, so therefore — SimplePie > *.

(Oh, and if you still haven't done so, visit my wishlist and buy me something :D.)

We need your feeds!

Tags: , , , March 27, 2006 (1 comment)

Fwd:

RSS and Atom feeds that aren't either UTF-8 or ISO-8859-1 have proven difficult to find, so I'm calling out to all of you. If you read or publish feeds that are in a character set other than these two, please post them here in the comments. We've just finished adding iconv support to SimplePie, and want to test that support (it's in the trunk build as of this moment). Any help along these lines would be appreciated.

Page:  1 2