Skip to content

Commit 8de5fb1

Browse files
committed
1.3.0 - Web 2 CLI bridge
1 parent 0f62e33 commit 8de5fb1

File tree

7 files changed

+411
-2
lines changed

7 files changed

+411
-2
lines changed

composer.macerier.json

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"name": "shortpixel/shortpixel-web",
3+
"description": "ShortPixel generic web interface using the PHP SDK. Read more at https://shortpixel.com/api",
4+
"keywords": [
5+
"shortpixel",
6+
"optimize",
7+
"compress",
8+
"images",
9+
"web tool"
10+
],
11+
12+
"homepage": "https://shortpixel.com/api",
13+
"license": "MIT",
14+
"minimum-stability": "dev",
15+
16+
"repositories": [
17+
{
18+
"type": "vcs",
19+
"url": "https://github.com/macerier/shortpixel-php"
20+
}
21+
],
22+
23+
"support": {
24+
"email": "support@shortpixel.com"
25+
},
26+
27+
"authors": [{
28+
"name": "Simon Duduica",
29+
"email": "simon@shortpixel.com"
30+
}],
31+
32+
"require": {
33+
//"shortpixel/shortpixel-php": "*"
34+
"shortpixel/shortpixel-php": "dev-master"
35+
},
36+
37+
"autoload": {
38+
"psr-4": {"ShortPixelWeb\\": "lib/ShortPixelWeb/"}
39+
}
40+
}

lib/ShortPixelWeb.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
class ShortPixelWeb
1515
{
16-
const VERSION = "1.2.1";
16+
const VERSION = "1.3.0";
1717

1818
private $settingsHandler;
1919
private $xtpl;

lib/ShortPixelWeb/PhpTail.php

Lines changed: 304 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
<?php
2+
3+
namespace ShortPixelWeb;
4+
5+
class PhpTail {
6+
7+
/**
8+
* Location of the log file we're tailing
9+
* @var string
10+
*/
11+
private $log = "";
12+
/**
13+
* The time between AJAX requests to the server.
14+
*
15+
* Setting this value too high with an extremly fast-filling log will cause your PHP application to hang.
16+
* @var integer
17+
*/
18+
private $updateTime;
19+
/**
20+
* This variable holds the maximum amount of bytes this application can load into memory (in bytes).
21+
* @var string
22+
*/
23+
private $maxSizeToLoad;
24+
/**
25+
*
26+
* PHPTail constructor
27+
* @param string $log the location of the log file
28+
* @param integer $defaultUpdateTime The time between AJAX requests to the server.
29+
* @param integer $maxSizeToLoad This variable holds the maximum amount of bytes this application can load into memory (in bytes). Default is 2 Megabyte = 2097152 byte
30+
*/
31+
public function __construct($log, $defaultUpdateTime = 2000, $maxSizeToLoad = 2097152) {
32+
$this->log = is_array($log) ? $log : array($log);
33+
$this->updateTime = $defaultUpdateTime;
34+
$this->maxSizeToLoad = $maxSizeToLoad;
35+
}
36+
/**
37+
* This function is in charge of retrieving the latest lines from the log file
38+
* @param string $lastFetchedSize The size of the file when we lasted tailed it.
39+
* @param string $grepKeyword The grep keyword. This will only return rows that contain this word
40+
* @return Returns the JSON representation of the latest file size and appended lines.
41+
*/
42+
public function getNewLines($file, $lastFetchedSize, $grepKeyword, $invert) {
43+
44+
/**
45+
* Clear the stat cache to get the latest results
46+
*/
47+
clearstatcache();
48+
/**
49+
* Define how much we should load from the log file
50+
* @var
51+
*/
52+
if(empty($file)) {
53+
$file = key(array_slice($this->log, 0, 1, true));
54+
}
55+
56+
$fsize = file_exists($this->log[$file]) ? filesize($this->log[$file]) : -1;
57+
$maxLength = ($fsize - $lastFetchedSize);
58+
/**
59+
* Verify that we don't load more data then allowed.
60+
*/
61+
if($maxLength > $this->maxSizeToLoad) {
62+
$maxLength = ($this->maxSizeToLoad / 2);
63+
}
64+
/**
65+
* Actually load the data
66+
*/
67+
$data = array();
68+
if($maxLength > 0) {
69+
70+
$fp = fopen($this->log[$file], 'r');
71+
fseek($fp, -$maxLength , SEEK_END);
72+
$data = explode("\n", fread($fp, $maxLength));
73+
74+
}
75+
/**
76+
* Run the grep function to return only the lines we're interested in.
77+
*/
78+
if($invert == 0) {
79+
$data = preg_grep("/$grepKeyword/",$data);
80+
}
81+
else {
82+
$data = preg_grep("/$grepKeyword/",$data, PREG_GREP_INVERT);
83+
}
84+
/**
85+
* If the last entry in the array is an empty string lets remove it.
86+
*/
87+
if(end($data) == "") {
88+
array_pop($data);
89+
}
90+
return json_encode(array("size" => $fsize, "file" => $this->log[$file], "data" => $data));
91+
}
92+
/**
93+
* This function will print out the required HTML/CSS/JS
94+
*/
95+
public function generateGUI() {
96+
?>
97+
<!DOCTYPE html>
98+
<html lang="en">
99+
<head>
100+
<meta charset="utf-8">
101+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
102+
<meta name="viewport" content="width=device-width, initial-scale=1">
103+
<title>Bootstrap 101 Template</title>
104+
105+
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
106+
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
107+
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.0/themes/smoothness/jquery-ui.css" />
108+
109+
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
110+
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
111+
<!--[if lt IE 9]>
112+
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
113+
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
114+
<![endif]-->
115+
116+
<style type="text/css">
117+
#grepKeyword, #settings {
118+
font-size: 80%;
119+
}
120+
.float {
121+
background: white;
122+
border-bottom: 1px solid black;
123+
padding: 10px 0 10px 0;
124+
margin: 0px;
125+
height: 30px;
126+
width: 100%;
127+
text-align: left;
128+
}
129+
.contents {
130+
margin-top: 30px;
131+
}
132+
.results {
133+
padding: 40px 10px 20px;
134+
font-family: monospace;
135+
font-size: small;
136+
white-space: pre;
137+
}
138+
</style>
139+
140+
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
141+
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.0/jquery-ui.min.js"></script>
142+
143+
<script type="text/javascript">
144+
/* <![CDATA[ */
145+
//Last know size of the file
146+
lastSize = 0;
147+
//Grep keyword
148+
grep = "";
149+
//Should the Grep be inverted?
150+
invert = 0;
151+
//Last known document height
152+
documentHeight = 0;
153+
//Last known scroll position
154+
scrollPosition = 0;
155+
//Should we scroll to the bottom?
156+
scroll = true;
157+
lastFile = window.location.hash != "" ? window.location.hash.substr(1) : "";
158+
console.log(lastFile);
159+
$(document).ready(function() {
160+
// Setup the settings dialog
161+
$("#settings").dialog({
162+
modal : true,
163+
resizable : false,
164+
draggable : false,
165+
autoOpen : false,
166+
width : 590,
167+
height : 270,
168+
buttons : {
169+
Close : function() {
170+
$(this).dialog("close");
171+
}
172+
},
173+
open : function(event, ui) {
174+
scrollToBottom();
175+
},
176+
close : function(event, ui) {
177+
grep = $("#grep").val();
178+
invert = $('#invert input:radio:checked').val();
179+
$("#results").text("");
180+
lastSize = 0;
181+
$("#grepspan").html("Grep keyword: \"" + grep + "\"");
182+
$("#invertspan").html("Inverted: " + (invert == 1 ? 'true' : 'false'));
183+
}
184+
});
185+
//Close the settings dialog after a user hits enter in the textarea
186+
$('#grep').keyup(function(e) {
187+
if (e.keyCode == 13) {
188+
$("#settings").dialog('close');
189+
}
190+
});
191+
//Focus on the textarea
192+
$("#grep").focus();
193+
//Settings button into a nice looking button with a theme
194+
//Settings button opens the settings dialog
195+
$("#grepKeyword").click(function() {
196+
$("#settings").dialog('open');
197+
$("#grepKeyword").removeClass('ui-state-focus');
198+
});
199+
$(".file").click(function(e) {
200+
$("#results").text("");
201+
lastSize = 0;
202+
console.log(e);
203+
lastFile = $(e.target).attr('href').substr(1);
204+
});
205+
206+
//Set up an interval for updating the log. Change updateTime in the PHPTail contstructor to change this
207+
setInterval("updateLog()", <?php echo $this->updateTime; ?>);
208+
//Some window scroll event to keep the menu at the top
209+
$(window).scroll(function(e) {
210+
if ($(window).scrollTop() > 0) {
211+
$('.float').css({
212+
position : 'fixed',
213+
top : '0',
214+
left : 'auto'
215+
});
216+
} else {
217+
$('.float').css({
218+
position : 'static'
219+
});
220+
}
221+
});
222+
//If window is resized should we scroll to the bottom?
223+
$(window).resize(function() {
224+
if (scroll) {
225+
scrollToBottom();
226+
}
227+
});
228+
//Handle if the window should be scrolled down or not
229+
$(window).scroll(function() {
230+
documentHeight = $(document).height();
231+
scrollPosition = $(window).height() + $(window).scrollTop();
232+
if (documentHeight <= scrollPosition) {
233+
scroll = true;
234+
} else {
235+
scroll = false;
236+
}
237+
});
238+
scrollToBottom();
239+
240+
});
241+
//This function scrolls to the bottom
242+
function scrollToBottom() {
243+
$("html, body").animate({scrollTop: $(document).height()}, "fast");
244+
}
245+
//This function queries the server for updates.
246+
function updateLog() {
247+
$.getJSON('?ajax=1&file=' + lastFile + '&lastsize=' + lastSize + '&grep=' + grep + '&invert=' + invert, function(data) {
248+
lastSize = data.size;
249+
$("#current").text(data.file);
250+
$.each(data.data, function(key, value) {
251+
$("#results").append('' + value + '<br/>');
252+
});
253+
if (scroll) {
254+
scrollToBottom();
255+
}
256+
});
257+
}
258+
/* ]]> */
259+
</script>
260+
</head>
261+
<body>
262+
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
263+
<div class="container">
264+
<div class="navbar-header">
265+
<a class="navbar-brand" href="#">PHP Tail</a>
266+
</div>
267+
<div class="collapse navbar-collapse">
268+
<ul class="nav navbar-nav">
269+
<li class="dropdown">
270+
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Files<span class="caret"></span></a>
271+
<ul class="dropdown-menu" role="menu">
272+
<?php foreach ($this->log as $title => $f): ?>
273+
<li><a class="file" href="#<?php echo $f;?>"><?php echo $title;?></a></li>
274+
<?php endforeach;?>
275+
</ul>
276+
</li>
277+
<li><a href="#" id="grepKeyword">Settings</a></li>
278+
<li><span class="navbar-text" id="grepspan"></span></li>
279+
<li><span class="navbar-text" id="invertspan"></span></li>
280+
</ul>
281+
<p class="navbar-text navbar-right" id="current"></p>
282+
</div>
283+
</div>
284+
</div>
285+
<div class="contents">
286+
<div id="results" class="results"></div>
287+
<div id="settings" title="PHPTail settings">
288+
<p>Grep keyword (return results that contain this keyword)</p>
289+
<input id="grep" type="text" value="" />
290+
<p>Should the grep keyword be inverted? (Return results that do NOT contain the keyword)</p>
291+
<div id="invert">
292+
<input type="radio" value="1" id="invert1" name="invert" /><label for="invert1">Yes</label>
293+
<input type="radio" value="0" id="invert2" name="invert" checked="checked" /><label for="invert2">No</label>
294+
</div>
295+
</div>
296+
</div>
297+
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
298+
</body>
299+
</html>
300+
<?php
301+
}
302+
}
303+
304+

lib/shortpixel-web-req.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
<?php
22

3+
if(PHP_MAJOR_VERSION < 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4)) {
4+
die("ShortPixel Web Tool needs at least PHP 5.4. Please upgrade and retry.");
5+
}
6+
37
require_once("ShortPixelWeb/XTemplate.php");
48
require_once("ShortPixelWeb.php");

webroot/js/sp-web.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@
134134
$(document).on('click', '.optimized-view', function(e) {
135135
e.preventDefault();
136136
var url = $(this).attr('data-optimized');
137-
console.log('I clicked the eye');
137+
//console.log('I clicked the eye');
138138
var file = url.substring(url.indexOf(window.location.host) + window.location.host.length);
139139
showModal(file+'/');
140140
});

webroot/tail.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
/**
3+
* User: simon
4+
* Date: 03.08.2018
5+
*/
6+
7+
require dirname(__DIR__) . '/lib/ShortPixelWeb/PhpTail.php';
8+
/**
9+
* Initilize a new instance of PHPTail
10+
* @var PHPTail
11+
*/
12+
$tail = new ShortPixelWeb\PhpTail(array("ShortPixel CLI" => urldecode($_GET['file'])));
13+
14+
/**
15+
* We're getting an AJAX call
16+
*/
17+
if(isset($_GET['ajax'])) {
18+
echo $tail->getNewLines("ShortPixel CLI", $_GET['lastsize'], $_GET['grep'], $_GET['invert']);
19+
die();
20+
}
21+
/**
22+
* Regular GET/POST call, print out the GUI
23+
*/
24+
$tail->generateGUI();

0 commit comments

Comments
 (0)