Skip to content

Instantly share code, notes, and snippets.

@Rarst
Last active September 30, 2017 07:54
Show Gist options
  • Save Rarst/4755736 to your computer and use it in GitHub Desktop.
Save Rarst/4755736 to your computer and use it in GitHub Desktop.
Parser for Opera's native bookmarks.adr format.
<?php
/**
* Parse Opera's bookmarks.adr file.
*/
class Opera_Bookmarks_Parser {
/** @var string path to bookmarks.adr */
public $adr;
/** @var array */
public $bookmarks = array();
/** @var array folder levels */
public $folder = array();
/** @var array current bookmarks */
public $bookmark = array();
/** @var string type of current section */
public $mode = '';
/** @var array reference to current place in $bookmarks */
public $target;
/**
* @param string $file_path
*/
function __construct( $file_path ) {
$this->adr = $file_path;
$this->parse();
}
/**
* Open and parse file
*/
function parse() {
$this->set_target();
$handle = fopen( $this->adr, 'r' );
while ( ( $line = fgets( $handle, 4096 ) ) !== false ) {
$line = trim( $line );
$line_key = substr( $line, 0, 1 );
if ( '#' === $line_key ) { // new item start
$this->mode = substr( $line, 1 );
}
elseif ( '-' === $line_key ) { // folder level closes
$this->pop_folder();
}
elseif ( 'URL' === $this->mode ) { // parsing URL
if ( empty( $line ) ) { // URL block over
$this->push_bookmark();
}
elseif ( false !== strpos( $line, '=' ) ) { // line with data
list( $field, $value ) = explode( '=', $line, 2 );
$this->bookmark[$field] = $value;
}
}
elseif ( 'FOLDER' === $this->mode && 'NAME=' === substr( $line, 0, 5 ) ) { // parsing folder
$this->push_folder( substr( $line, 5 ) );
}
}
fclose( $handle );
}
/**
* Push gathered bookmark data to results.
*/
function push_bookmark() {
if ( empty( $this->bookmark ) )
return;
if ( 0 === strpos( $this->bookmark['URL'], 'javascript' ) ) { // skip bookmarklets
$this->bookmark = array();
return;
}
if ( empty( $this->bookmark['VISITED'] ) )
$this->bookmark['VISITED'] = $this->bookmark['CREATED'];
$this->target[] = $this->bookmark;
$this->bookmark = array();
}
/**
* Add a folder level and adjust target for bookmarks in results.
*
* @param string $folder
*/
function push_folder( $folder ) {
$this->folder[] = $folder;
$this->set_target();
}
/**
* Pop deepest folder level and adjust target for bookmarks in results.
*/
function pop_folder() {
array_pop( $this->folder );
$this->set_target();
}
/**
* Set point in results array where bookmarks are pushed to.
*/
function set_target() {
$this->target =& $this->bookmarks;
foreach ( $this->folder as $level ) {
$this->target =& $this->target[$level];
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment