<?php
ob_start
(); 
define('LIMIT',50);

define('RE_SUBJECTS_INDEX','[^(?i:http://bip.gov.pl)?/*subjects/index/([0-9]+?)(?i:$|\?)]is');
define('RE_SUBJECT','[^(?i:http://bip.gov.pl)?/*subjects/([0-9]+?),.+?\.html]is');
define('RE_SUBJECT_2','[^(?i:http://bip.gov.pl)?/*subjects/view/([0-9]+?)(?i:$|\?)]is');

define('RE_OFFICE_NAME','[<title>BIP: (.+?)<\/title>]is');
define('RE_OFFICE_MAIL','[<h2><a href=\"mailto:(.*?)\"  class="red">]is');
define('RE_REDACTOR_MAIL','[e-mail: <a href="mailto:(.*?)"]is');
define('RE_SUBJECT_CHILD','[<li>'."\n".'.+?<a href=\"(/subjects/.+?,.+?\.html)"  class=\"red\">.+?<\/a>]is');

define('RE_INDEX_SUBJECT','[<li>'."\n".'.+?<h2><a href=\"(/subjects/.+?,.+?\.html)"  class=\"red\">.+?<\/a>]is');
define('RE_INDEX_NUMROW','[Rezultat.+w: 1-[0-9]+? z ([0-9]+?)<br \/>]is');
define('DEFAULT_PER_PAGE',50);

$limit 0;
function 
get_url($url,$cache_key$limit 604800){
    global 
$limit;
    if(
$limit>=LIMIT){
        return 
FALSE;
    }
    
$filename './cache/'.$cache_key;
    if(
file_exists($filename) && filemtime($filename) > time()-$limit){
        
$result file_get_contents($filename);
        
$time filemtime($filename);
    }else{
        
$limit++;
        
$result file_get_contents($url);
        
$time time();
        
file_put_contents($filename,$result);
    };
    return array(
$time,$result);
};    

function 
time2str($ts){
    
//Author: [email protected] (http://stackoverflow.com/posts/2690541/revisions)
    
if(!ctype_digit($ts))
        
$ts strtotime($ts);

    
$diff time() - $ts;
    if(
$diff == 0)
        return 
'now';
    elseif(
$diff 0)    {
        
$day_diff floor($diff 86400);
        if(
$day_diff == 0)        {
            if(
$diff 60) return 'just now';
            if(
$diff 120) return '1 minute ago';
            if(
$diff 3600) return floor($diff 60) . ' minutes ago';
            if(
$diff 7200) return '1 hour ago';
            if(
$diff 86400) return floor($diff 3600) . ' hours ago';
        }
        if(
$day_diff == 1) return 'Yesterday';
        if(
$day_diff 7) return $day_diff ' days ago';
        if(
$day_diff 31) return ceil($day_diff 7) . ' weeks ago';
        if(
$day_diff 60) return 'last month';
        return 
date('F Y'$ts);
    }else{
        
$diff abs($diff);
        
$day_diff floor($diff 86400);
        if(
$day_diff == 0){
            if(
$diff 120) return 'in a minute';
            if(
$diff 3600) return 'in ' floor($diff 60) . ' minutes';
            if(
$diff 7200) return 'in an hour';
            if(
$diff 86400) return 'in ' floor($diff 3600) . ' hours';
        }
        if(
$day_diff == 1) return 'Tomorrow';
        if(
$day_diff 4) return date('l'$ts);
        if(
$day_diff + (date('w'))) return 'next week';
        if(
ceil($day_diff 7) < 4) return 'in ' ceil($day_diff 7) . ' weeks';
        if(
date('n'$ts) == date('n') + 1) return 'next month';
        return 
date('F Y'$ts);
    }
}

function 
match_or_null($regexp,$content){
    if(
preg_match($regexp,$content,$matches)){
        return 
$matches[1];
    }else{
        return 
NULL;
    }
}

function 
match_child($regexp,$content,$depth){
    
$child = array();
    if(
$depth<=0){ return $child; };
    if(
preg_match_all($regexp,$content,$child_matches)){
        foreach(
$child_matches[1] as $value){
            
$child[] = parse($value,False,$depth-1);
        }
    };
    return 
$child;
}
function 
parse_index($id,$depth){
    
$url 'http://bip.gov.pl/subjects/index/'.$id;
    
$result get_url($url,'i_'.$id);
    
$content $result[1];

    
$child = array();
    if(
$depth>=0){
        
$num_count match_or_null(RE_INDEX_NUMROW,$content);
        
$page_count ceil($num_count/DEFAULT_PER_PAGE);
        if(
preg_match_all(RE_INDEX_SUBJECT,$content,$child_matches)){
                foreach(
$child_matches[1] as $value){
                    
$child[] = parse($value,False,$depth-1);
                }
        };
        for(
$page=2;$page<=$page_count;$page++){
            
$child_url 'http://bip.gov.pl/subjects/index/'.$id.'?page='.$page;
            
$child_result get_url($child_url,'i_'.$id.'_'.$page);
            
$child_content $child_result[1];
            if(
preg_match_all(RE_INDEX_SUBJECT,$child_content,$child_matches)){
                foreach(
$child_matches[1] as $value){
                    
$child[] = parse($value,False,$depth-1);
                }
            };
        };
    };

    
$data = array('id'=>$id
                  
'url'=>$url,
                  
'time'=>$result[0],
                  
                  
'name'=>match_or_null(RE_OFFICE_NAME,$content),
                  
'child'=>$child);
    return 
$data;
}
function 
parse_subject($id,$depth){
    
$url 'http://bip.gov.pl/subjects/'.$id.',Adam_Dobrawy.html';
    
$result get_url($url,'s_'.$id);
    
$content $result[1];
    
$data = array('id'=>$id,
                  
'url'=>$url,
                  
'time'=>$result[0],
                  
                  
'name'=>match_or_null(RE_OFFICE_NAME,$content),
                  
'mail'=>match_or_null(RE_OFFICE_MAIL,$content),
                  
'mail2'=>match_or_null(RE_REDACTOR_MAIL,$content),
                  
'child'=>match_child(RE_SUBJECT_CHILD,$content,$depth));

    return 
$data;

};
function 
parse($url,$only_validate False$depth 3){
    if(
preg_match(RE_SUBJECTS_INDEX,$url,$matches)){
        return (
$only_validate True parse_index($matches[1],$depth));
    }elseif(
preg_match(RE_SUBJECT,$url,$matches)){
        return (
$only_validate True parse_subject($matches[1],$depth));
    }elseif(
preg_match(RE_SUBJECT_2,$url,$matches)){
        return (
$only_validate True parse_subject($matches[1],$depth));
    }else{
        return 
False;
    }

};

function 
as_flat($data,$depth=0){
     
$rows = array();
     if(
$depth==0){
         
$rows[]=array('Depth','ID','Czas dostępu','-','Źródło','Nazwa','E-mail podmiotu','E-mail redaktora');
     }
     
$rows[] = array($depth,$data['id'],$data['time'],time2str($data['time']),$data['url'],$data['name'],$data['mail'],$data['mail2']);
    foreach(
$data['child'] as $key=>$value){
        
$rows array_merge($rows,as_flat($value,$depth+1));
    }
    return 
$rows;
}
?>
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>SGBIP exporter</title>
    <!--[if IE]>
    <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
</head>
<body>
<h1>SGBIP exporter</h1>
<p>SGBIP (<a href="http://bip.gov.pl/">Strona Główna Biuletynu Informacji Publicznej</a>) to witryna zbierająca dane na temat wszystkich <abbr title="urzędy i instytucje dysponujące majątkiem publicznym lub realizujące zadania publiczne">podmiotów zobowiązanych do udostępniania informacji publicznej</abbr>. Została utworzona na podstawie art. 9 ust. 1 <a href="http://informacjapubliczna.org.pl/31,265,ustawa_o_dostepie_do_informacji_publicznej.html">ustawy z dnia 6 września o dostępie do informacji publicznej</a> (dalej: u.d.i.p.).</p>
<p>Na podstawie art. 9 ust. 3 u.d.i.p. te podmioty zobowiązane są obowiązane przekazać ministrowi właściwemu do spraw informatyzacji informacje niezbędne do zamieszczenia na SGBIP. Zgodnie z § 9 ust. 2 rozporządzenia Ministra Spraw Wewnętrznych i Administracji z dnia 18 stycznia 2007 r. w sprawie Biuletynu Informacji Publicznej podmioty te powiadamiają niezwłocznie ministra właściwego do spraw informatyzacji o zmianach w treści informacji, które przekazały w celu zamieszczania na stronie głównej BIP.</p>
<p>Niniejsza strona pozwala po wskazaniu adresu podstrony SGBIP pobrać dane o podmiotach i zapisać w formie arkusza kalkulacyjnego dla dalszego wykorzystania. Tak możemy pobrać np.adresy wszystkich  <a href="?url=http%3A%2F%2Fbip.gov.pl%2Fsubjects%2Findex%2F7489&depth=1&format=html">urzędów wojewodzkich</a>,<a href="?url=http%3A%2F%2Fbip.gov.pl%2Fsubjects%2Findex%2F6198&depth=1&format=html">urzędów marszałkowskich</a>,<a href="?url=http%3A%2F%2Fbip.gov.pl%2Fsubjects%2F4593%2CNaczelny%2BS%25C4%2585d%2BAdministracyjny.html&depth=1&format=html">sądów administracyjnych</a> lub <a href="?url=http%3A%2F%2Fbip.gov.pl%2Fsubjects%2Findex%2F4560&depth=1&format=html">ministerstw</a>.</p>
<p>Dostępna jest <a href="javascript:void(window.open('http://ochrona.jawne.info.pl/magazyn-danych/2014/export-SGBIP/?depth=1&format=html&url='+encodeURIComponent(document.URL)));">skryptozakładka</a>. Możesz dodać je do zakładek (klikając na nie prawym przyciskiem myszy) albo przeciągnąć na pasek narzędzi, aby szybko przejść tu z właściwej podstrony SGBIP.</p> 
<form action="?">
<input name="url" type="url" placeholder="SGBIP URL" value="<?php echo htmlentities($_GET['url']);?>">
<input name="depth" type="number" min="1" placeholder="Depth" value="<?php echo isset($_GET['depth']) ? (int)$_GET['depth'] :'';?>">
<select name="format">
    <option value="csv">CSV (arkusz kalkulacyjny)</option>
    <option value="html" selected>Strona (podgląd)</option>
</select>
<input type="submit" value="Export">
</form>

<?php
if(isset($_GET['url'])):
    
$depth = (isset($_GET['depth']) && ctype_digit($_GET['depth']) && $_GET['depth'] >= $_GET['depth'] : 2);
    
$format = (isset($_GET['format']) && $_GET['format'] == 'html' 'html' 'csv');
    
    if(!
parse($_GET['url'],True)):
        echo 
"Incorrect URL (".htmlentities($_GET['url']).")";
    else:
        
$data parse($_GET['url'],False,$depth);
        
$flat as_flat($data);
        if(
$format == 'csv'){
            
$filename './output/'.time().sha1($_GET['url']).'.csv';
            
$fp fopen($filename'w');
            foreach (
$flat as $fields) {
                
fputcsv($fp$fields);
            }
            
fclose($fp);
            
header('Location: '.$filename);
        }else{
            
?><table border="1"><?php
            $i
=0;
            foreach (
$flat as $tr) {
                
?><tr>
                <td><?php echo $i;?></td>
                <?php
                    
foreach($tr as $td){
                        
?><td><?php echo htmlentities($td,ENT_COMPAT ENT_HTML401,'UTF-8');?></td><?php
                    
}
                
?></tr><?php
                $i
++;
            };
            
?></table><?php 
        
};
    endif; 

endif; 
?>
<p>Kod źródłowy PHP niniejszej strony jest <a href="code.php">publiczny</a>.</p>
<p>Dane jednokrotnie pobrane z SGBIP są archiwizowane przez 7 dni. Jednokrotnie możliwe jest skierowanie do SGBIP zapytań o <?php echo LIMIT;?> <abbr title="niezarchwizowanych dotyczas">nowych podmiotów</abbr>.</p>
</body>
</html>