Skip to content

Instantly share code, notes, and snippets.

@goodevilgenius
Last active October 26, 2017 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save goodevilgenius/9ccd18758b4b39ef0194 to your computer and use it in GitHub Desktop.
Save goodevilgenius/9ccd18758b4b39ef0194 to your computer and use it in GitHub Desktop.
[Screenshots] Simple script to make screenshot of website and save to a directory (requires xvfb and cutycapt) #web #screenshots
<?php
if (!function_exists('http_build_url'))
{
define('HTTP_URL_REPLACE', 1); // Replace every part of the first URL when there's one of the second URL
define('HTTP_URL_JOIN_PATH', 2); // Join relative paths
define('HTTP_URL_JOIN_QUERY', 4); // Join query strings
define('HTTP_URL_STRIP_USER', 8); // Strip any user authentication information
define('HTTP_URL_STRIP_PASS', 16); // Strip any password authentication information
define('HTTP_URL_STRIP_AUTH', 32); // Strip any authentication information
define('HTTP_URL_STRIP_PORT', 64); // Strip explicit port numbers
define('HTTP_URL_STRIP_PATH', 128); // Strip complete path
define('HTTP_URL_STRIP_QUERY', 256); // Strip query string
define('HTTP_URL_STRIP_FRAGMENT', 512); // Strip any fragments (#identifier)
define('HTTP_URL_STRIP_ALL', 1024); // Strip anything but scheme and host
// Build an URL
// The parts of the second URL will be merged into the first according to the flags argument.
//
// @param mixed (Part(s) of) an URL in form of a string or associative array like parse_url() returns
// @param mixed Same as the first argument
// @param int A bitmask of binary or'ed HTTP_URL constants (Optional)HTTP_URL_REPLACE is the default
// @param array If set, it will be filled with the parts of the composed url like parse_url() would return
function http_build_url($url, $parts=array(), $flags=HTTP_URL_REPLACE, &$new_url=false)
{
$keys = array('user','pass','port','path','query','fragment');
// HTTP_URL_STRIP_ALL becomes all the HTTP_URL_STRIP_Xs
if ($flags & HTTP_URL_STRIP_ALL)
{
$flags |= HTTP_URL_STRIP_USER;
$flags |= HTTP_URL_STRIP_PASS;
$flags |= HTTP_URL_STRIP_PORT;
$flags |= HTTP_URL_STRIP_PATH;
$flags |= HTTP_URL_STRIP_QUERY;
$flags |= HTTP_URL_STRIP_FRAGMENT;
}
// HTTP_URL_STRIP_AUTH becomes HTTP_URL_STRIP_USER and HTTP_URL_STRIP_PASS
else if ($flags & HTTP_URL_STRIP_AUTH)
{
$flags |= HTTP_URL_STRIP_USER;
$flags |= HTTP_URL_STRIP_PASS;
}
// Parse the original URL
$parse_url = is_array($url) ? $url : parse_url($url);
// Scheme and Host are always replaced
if (isset($parts['scheme']))
$parse_url['scheme'] = $parts['scheme'];
if (isset($parts['host']))
$parse_url['host'] = $parts['host'];
// (If applicable) Replace the original URL with it's new parts
if ($flags & HTTP_URL_REPLACE)
{
foreach ($keys as $key)
{
if (isset($parts[$key]))
$parse_url[$key] = $parts[$key];
}
}
else
{
// Join the original URL path with the new path
if (isset($parts['path']) && ($flags & HTTP_URL_JOIN_PATH))
{
if (isset($parse_url['path']))
$parse_url['path'] = rtrim(str_replace(basename($parse_url['path']), '', $parse_url['path']), '/') . '/' . ltrim($parts['path'], '/');
else
$parse_url['path'] = $parts['path'];
}
// Join the original query string with the new query string
if (isset($parts['query']) && ($flags & HTTP_URL_JOIN_QUERY))
{
if (isset($parse_url['query'])) {
parse_str($parse_url['query'],$uq);
parse_str($parts['query'], $tq);
$parse_url['query'] = http_build_query(array_merge($uq, $tq));
} else
$parse_url['query'] = $parts['query'];
}
}
// Strips all the applicable sections of the URL
// Note: Scheme and Host are never stripped
foreach ($keys as $key)
{
if ($flags & (int)constant('HTTP_URL_STRIP_' . strtoupper($key)))
unset($parse_url[$key]);
}
$new_url = $parse_url;
return
((isset($parse_url['scheme'])) ? $parse_url['scheme'] . '://' : '')
.((isset($parse_url['user'])) ? $parse_url['user'] . ((isset($parse_url['pass'])) ? ':' . $parse_url['pass'] : '') .'@' : '')
.((isset($parse_url['host'])) ? $parse_url['host'] : '')
.((isset($parse_url['port'])) ? ':' . $parse_url['port'] : '')
.((isset($parse_url['path'])) ? $parse_url['path'] : '')
.((isset($parse_url['query'])) ? '?' . $parse_url['query'] : '')
.((isset($parse_url['fragment'])) ? '#' . $parse_url['fragment'] : '')
;
}
}
<!DOCTYPE html><!-- -*-html-*- -->
<html>
<head>
<meta charset="utf-8" />
<title>Screenshots</title>
<!--
Gist: https://gist.github.com/goodevilgenius/9ccd18758b4b39ef0194
Instructions: Place index.php in screenshots folder, and place somewhere
accessible in web root.
Place http_build_url.php in the same folder, or if the PECL extension is
installed, remove the 'require_once' line in here.
-->
</head>
<body>
<h1>Screenshots</h1>
<?php
$today = date('Y-m-d');
function sort_by_ts(&$a, &$b) {
return ($b['ts'] - $a['ts']);
}
$dir = dirname($_SERVER["SCRIPT_FILENAME"]);
$remote_dir = dirname($_SERVER["SCRIPT_URI"]);
$shots = array();
foreach(scandir($dir) as $file) {
if (is_file($dir . '/' . $file)) {
if (preg_match('/^([^-]+)-([0-9]+)\.(.*)$/', $file, $m)) {
$f = array('src'=>$remote_dir . '/' . $file
, 'url' => base64_decode($m[1])
, 'ts' => (int)($m[2])
, 'date' => date('Y-m-d', $m[2])
, 'rfc2822' => date('r', $m[2])
, 'easydate' => date('M j, Y g:i a T', $m[2])
);
if (empty($shots[$f['date']]))
$shots[$f['date']] = array();
$shots[$f['date']][] = $f;
}
}
}
krsort($shots);
foreach($shots as &$date) usort($date, 'sort_by_ts');
if ((!empty($_GET['date'])) && (!empty($shots[$_GET['date']]))) {
$thisone = $shots[$_GET['date']];
$date = $_GET['date'];
} else {
$thisone = $shots[$today];
$date = $today;
}
require_once('http_build_url.php');
?>
<h2><?=$date?></h2>
<ul>
<?php foreach($thisone as $pics): ?>
<li><a href="<?=$pics['src']?>"><?=$pics['url']?> <?=$pics['easydate']?></a></li>
<?php endforeach; ?>
</ul>
<h2>Dates</h2>
<ul>
<?php foreach($shots as $date => $pics): ?>
<?php $url = http_build_url($_SERVER["REQUEST_URI"], array('query'=>'date='.$date), HTTP_URL_JOIN_QUERY);?>
<li><a href="<?=$url?>"><?=$date?></a></li>
<?php endforeach;?>
</ul>
</body>
</html>
#!/bin/bash
# Usage: /path/to/screenshot.sh /path/to/screenshot/directory http://url.com/
# To display on a website, use index.php (and http_build_url)
dir="$(readlink -f "$1")"
if [ ! \( -d "$dir" -a -w "$dir" \) ]
then
echo "$dir is not a valid writeable directory" >&2
exit 4
fi
filename="$(echo -n "$2" | base64 | sed -r 's/=+$//')-$(date +%s).png"
xvfb-run --server-args="-screen 0, 1024x768x24" cutycapt --header='COOKIE: newsuser=1' --min-width=1000 --url="$2" --out="$dir/$filename"
###
#
# Gist: https://gist.github.com/goodevilgenius/9ccd18758b4b39ef0194
#
### BEGIN LICENSE
# Copyright (c) 2014 Dan Jones
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
### END LICENSE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment