<?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 < 7 + (7 - 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'] >= 0 ? $_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>