/about/ + extendedGitGraph
This commit is contained in:
parent
d77954ddae
commit
28ae8beb2d
@ -89,6 +89,19 @@ body {
|
||||
width: 0 !important;
|
||||
height: 0 !important; }
|
||||
|
||||
.boxedcontent {
|
||||
color: #333;
|
||||
border: 1px solid black;
|
||||
background-color: #E0E0E0;
|
||||
width: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto; }
|
||||
.boxedcontent .bc_header {
|
||||
background-color: #BBB;
|
||||
padding: 0 4px; }
|
||||
.boxedcontent .bc_data {
|
||||
padding: 8px; }
|
||||
|
||||
/* 400px */
|
||||
#headerdiv {
|
||||
z-index: 999;
|
||||
@ -265,21 +278,6 @@ html, body {
|
||||
.ble_title {
|
||||
font-size: 1.25em; } }
|
||||
/* 400px */
|
||||
.blogcontent {
|
||||
color: #333;
|
||||
border: 1px solid black;
|
||||
background-color: #E0E0E0;
|
||||
width: 90%;
|
||||
margin-left: auto;
|
||||
margin-right: auto; }
|
||||
|
||||
.bc_header {
|
||||
background-color: #BBB;
|
||||
padding: 0 4px; }
|
||||
|
||||
.bc_data {
|
||||
padding: 8px; }
|
||||
|
||||
.base_markdown code {
|
||||
font-family: Consolas, Monaco, "Courier New", Menlo, monospace;
|
||||
direction: ltr;
|
||||
@ -348,6 +346,9 @@ html, body {
|
||||
border: none !important;
|
||||
background: transparent !important; }
|
||||
|
||||
.blogcontent_euler, .blogcontent_markdown, .blogcontent_plain {
|
||||
width: 90%; }
|
||||
|
||||
/* 400px */
|
||||
#PEB_tableProblems .PEB_tablerowProblems:hover {
|
||||
background-color: #888; }
|
||||
@ -796,6 +797,97 @@ html, body {
|
||||
#prgv_header h1 {
|
||||
font-size: 28pt; } }
|
||||
/* 400px */
|
||||
.aboutcontent {
|
||||
display: block;
|
||||
width: 100%; }
|
||||
|
||||
.aboutcontent .boxedcontent {
|
||||
margin-bottom: 20px; }
|
||||
|
||||
.about_egh_container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center; }
|
||||
|
||||
.git_list {
|
||||
display: inline-block;
|
||||
width: 715px;
|
||||
height: 115px;
|
||||
overflow: visible; }
|
||||
|
||||
@media (max-width: 991px) {
|
||||
.git_list {
|
||||
width: 100%;
|
||||
height: auto; }
|
||||
|
||||
.extGitGraphContainer {
|
||||
width: 95%;
|
||||
width: calc(100% - 16px); } }
|
||||
.git_list text.caption {
|
||||
font-size: 10px;
|
||||
fill: #666; }
|
||||
|
||||
.git_list text.caption_month {
|
||||
font-size: 8px;
|
||||
fill: #BBB; }
|
||||
|
||||
.git_list text.caption_day {
|
||||
font-size: 8px;
|
||||
fill: #BBB; }
|
||||
|
||||
.svg-tip:after {
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
height: 5px;
|
||||
width: 5px;
|
||||
bottom: -10px;
|
||||
margin: 0 0 0px -5px;
|
||||
content: " ";
|
||||
border: 5px solid transparent;
|
||||
border-top-color: rgba(0, 0, 0, 0.8);
|
||||
-moz-border-top-colors: none;
|
||||
-moz-border-right-colors: none;
|
||||
-moz-border-bottom-colors: none;
|
||||
-moz-border-left-colors: none;
|
||||
border-image: none; }
|
||||
|
||||
.svg-tip {
|
||||
padding: 5px;
|
||||
background: none repeat scroll 0 0 rgba(0, 0, 0, 0.8);
|
||||
color: #BBB;
|
||||
font-size: 12px;
|
||||
position: absolute;
|
||||
z-index: 99999;
|
||||
text-align: center;
|
||||
border-radius: 3px;
|
||||
box-sizing: border-box;
|
||||
opacity: 0; }
|
||||
|
||||
.extGitGraphContainer {
|
||||
background-color: #FCFCFC;
|
||||
margin: 10px;
|
||||
display: inline-block;
|
||||
border: 1px solid #222;
|
||||
border-radius: 0;
|
||||
box-shadow: 0 0 1px rgba(0, 0, 0, 0.25) inset; }
|
||||
|
||||
.egg_footer {
|
||||
margin-top: 5px;
|
||||
text-align: right;
|
||||
margin-right: 5px;
|
||||
margin-bottom: 5px;
|
||||
color: #888; }
|
||||
|
||||
.egg_footer > a {
|
||||
text-decoration: none;
|
||||
color: inherit; }
|
||||
|
||||
.egg_footer > a:hover {
|
||||
text-decoration: none;
|
||||
color: #22F; }
|
||||
|
||||
/* 400px */
|
||||
.euler_pnl_base {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
|
24
www/data/css/styles.min.css
vendored
24
www/data/css/styles.min.css
vendored
@ -18,6 +18,9 @@ body{background-color:#EEE;color:#CCC;font-family:serif}
|
||||
.blockcontent{display:block;width:100%}
|
||||
.generic_hidden{visibility:hidden !important}
|
||||
.generic_collapsed{visibility:collapse !important;display:none !important;width:0 !important;height:0 !important}
|
||||
.boxedcontent{color:#333;border:1px solid black;background-color:#e0e0e0;width:100%;margin-left:auto;margin-right:auto}
|
||||
.boxedcontent .bc_header{background-color:#BBB;padding:0 4px}
|
||||
.boxedcontent .bc_data{padding:8px}
|
||||
#headerdiv{z-index:999;background-color:#333;display:flex;border-bottom:1px solid #111;box-shadow:0 0 8px #000;position:fixed;width:100%}
|
||||
#headerdiv .logowrapper{flex:initial;margin:0;padding:0;height:42px}
|
||||
#headerdiv .logowrapper .logo{height:30px;margin:4px 0 8px 6px;flex:initial}
|
||||
@ -58,9 +61,6 @@ html,body{margin:0;padding:0;height:100%}
|
||||
.ble_date{background-color:#AAA;padding:2px;font-size:.8em;font-style:italic}
|
||||
.ble_title{font-weight:bold;font-size:1.2em;text-align:left;margin:2px 0 2px 10px}
|
||||
@media(max-width:767px){.ble_title{font-size:1.25em}}
|
||||
.blogcontent{color:#333;border:1px solid black;background-color:#e0e0e0;width:90%;margin-left:auto;margin-right:auto}
|
||||
.bc_header{background-color:#BBB;padding:0 4px}
|
||||
.bc_data{padding:8px}
|
||||
.base_markdown code{font-family:Consolas,Monaco,"Courier New",Menlo,monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;-moz-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}
|
||||
.base_markdown pre{font-size:14px;display:block;padding:9.5px;margin:0 0 10px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre-wrap;background-color:#f8f8f8;color:black;border:1px solid rgba(0,0,0,0.15);border-radius:2px}
|
||||
.base_markdown blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #CCC}
|
||||
@ -77,6 +77,7 @@ html,body{margin:0;padding:0;height:100%}
|
||||
.mdtable_container{overflow-x:auto}
|
||||
.notable{width:unset !important;border:none !important}
|
||||
.notable th,.notable td,.notable tr{border:none !important;background:transparent !important}
|
||||
.blogcontent_euler,.blogcontent_markdown,.blogcontent_plain{width:90%}
|
||||
#PEB_tableProblems .PEB_tablerowProblems:hover{background-color:#888}
|
||||
#PEB_tableProblems .PEB_TC_Value{font-family:Consolas,Monaco,"Courier New",Menlo,monospace}
|
||||
#PEB_tableProblems .PEB_TC_Value:not(:hover){color:transparent;-o-transition:.5s;-ms-transition:.5s;-moz-transition:.5s;-webkit-transition:.5s;transition:.5s}
|
||||
@ -203,6 +204,23 @@ html,body{margin:0;padding:0;height:100%}
|
||||
.prgv_right_lang{justify-content:space-evenly}
|
||||
#prgv_header h1{font-size:28pt}
|
||||
}
|
||||
.aboutcontent{display:block;width:100%}
|
||||
.aboutcontent .boxedcontent{margin-bottom:20px}
|
||||
.about_egh_container{display:flex;flex-direction:column;align-items:center}
|
||||
.git_list{display:inline-block;width:715px;height:115px;overflow:visible}
|
||||
@media(max-width:991px){
|
||||
.git_list{width:100%;height:auto}
|
||||
.extGitGraphContainer{width:95%;width:calc(100% - 16px)}
|
||||
}
|
||||
.git_list text.caption{font-size:10px;fill:#666}
|
||||
.git_list text.caption_month{font-size:8px;fill:#BBB}
|
||||
.git_list text.caption_day{font-size:8px;fill:#BBB}
|
||||
.svg-tip:after{box-sizing:border-box;position:absolute;left:50%;height:5px;width:5px;bottom:-10px;margin:0 0 0 -5px;content:" ";border:5px solid transparent;border-top-color:rgba(0,0,0,0.8);-moz-border-top-colors:none;-moz-border-right-colors:none;-moz-border-bottom-colors:none;-moz-border-left-colors:none;border-image:none}
|
||||
.svg-tip{padding:5px;background:none repeat scroll 0 0 rgba(0,0,0,0.8);color:#BBB;font-size:12px;position:absolute;z-index:99999;text-align:center;border-radius:3px;box-sizing:border-box;opacity:0}
|
||||
.extGitGraphContainer{background-color:#fcfcfc;margin:10px;display:inline-block;border:1px solid #222;border-radius:0;box-shadow:0 0 1px rgba(0,0,0,0.25) inset}
|
||||
.egg_footer{margin-top:5px;text-align:right;margin-right:5px;margin-bottom:5px;color:#888}
|
||||
.egg_footer>a{text-decoration:none;color:inherit}
|
||||
.egg_footer>a:hover{text-decoration:none;color:#22F}
|
||||
.euler_pnl_base{display:inline-flex;flex-direction:column;border:1px solid #AAA;border-radius:5px 5px 0 0;margin:15px}
|
||||
.euler_pnl_header{display:flex;align-items:center;justify-content:center;padding:4px;background:#AAA}
|
||||
.euler_pnl_header a{color:#222;text-decoration:none;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:22px;font-weight:900}
|
||||
|
@ -9,6 +9,7 @@
|
||||
@import 'styles_errorview';
|
||||
@import 'styles_programslist';
|
||||
@import 'styles_programsview';
|
||||
@import 'styles_about';
|
||||
|
||||
@import 'styles_eulerpanel';
|
||||
@import 'styles_programspanel';
|
||||
|
104
www/data/css/styles_about.scss
Normal file
104
www/data/css/styles_about.scss
Normal file
@ -0,0 +1,104 @@
|
||||
@import 'styles_config';
|
||||
|
||||
.aboutcontent {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.aboutcontent .boxedcontent{
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.about_egh_container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.git_list {
|
||||
display: inline-block;
|
||||
width: 715px;
|
||||
height: 115px;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
@include rdmedia_range(0,2) {
|
||||
.git_list { width: 100%; height: auto; }
|
||||
.extGitGraphContainer { width: 95%; width: calc(100% - 16px); }
|
||||
}
|
||||
|
||||
.git_list text.caption {
|
||||
font-size: 10px;
|
||||
fill: #666;
|
||||
}
|
||||
|
||||
.git_list text.caption_month {
|
||||
font-size: 8px;
|
||||
fill: #BBB;
|
||||
}
|
||||
|
||||
.git_list text.caption_day {
|
||||
font-size: 8px;
|
||||
fill: #BBB;
|
||||
}
|
||||
|
||||
.svg-tip:after {
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
height: 5px;
|
||||
width: 5px;
|
||||
bottom: -10px;
|
||||
margin: 0 0 0px -5px;
|
||||
content: " ";
|
||||
border: 5px solid transparent;
|
||||
border-top-color: rgba(0, 0, 0, 0.8);
|
||||
-moz-border-top-colors: none;
|
||||
-moz-border-right-colors: none;
|
||||
-moz-border-bottom-colors: none;
|
||||
-moz-border-left-colors: none;
|
||||
border-image: none;
|
||||
}
|
||||
|
||||
.svg-tip {
|
||||
padding: 5px;
|
||||
background: none repeat scroll 0 0 rgba(0, 0, 0, 0.8);
|
||||
color: #BBB;
|
||||
font-size: 12px;
|
||||
position: absolute;
|
||||
z-index: 99999;
|
||||
text-align: center;
|
||||
border-radius: 3px;
|
||||
box-sizing: border-box;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.extGitGraphContainer {
|
||||
background-color: #FCFCFC;
|
||||
margin: 10px;
|
||||
display: inline-block;
|
||||
|
||||
border: 1px solid #222;
|
||||
border-radius: 0;
|
||||
box-shadow: 0 0 1px rgba(0, 0, 0, 0.25) inset;
|
||||
}
|
||||
|
||||
.egg_footer {
|
||||
margin-top: 5px;
|
||||
|
||||
text-align: right;
|
||||
margin-right: 5px;
|
||||
margin-bottom: 5px;
|
||||
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.egg_footer > a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.egg_footer > a:hover {
|
||||
text-decoration: none;
|
||||
color: #22F;
|
||||
}
|
@ -1,23 +1,5 @@
|
||||
@import 'styles_config';
|
||||
|
||||
.blogcontent {
|
||||
color: $COL_TEXT_DARK;
|
||||
border: 1px solid black;
|
||||
background-color: $COL_BACKGROUND_2;
|
||||
width: 90%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.bc_header {
|
||||
background-color: #BBB;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.bc_data {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.base_markdown {
|
||||
|
||||
code {
|
||||
@ -115,3 +97,5 @@
|
||||
background: transparent !important;
|
||||
}
|
||||
}
|
||||
|
||||
.blogcontent_euler, .blogcontent_markdown, .blogcontent_plain { width: 90%;}
|
||||
|
@ -86,3 +86,21 @@ body {
|
||||
width:0 !important;
|
||||
height:0 !important;
|
||||
}
|
||||
|
||||
.boxedcontent {
|
||||
color: $COL_TEXT_DARK;
|
||||
border: 1px solid black;
|
||||
background-color: $COL_BACKGROUND_2;
|
||||
width: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
|
||||
.bc_header {
|
||||
background-color: #BBB;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.bc_data {
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
57
www/data/javascript/egh.js
Normal file
57
www/data/javascript/egh.js
Normal file
@ -0,0 +1,57 @@
|
||||
function formatDate(date) {
|
||||
const monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
||||
const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
||||
|
||||
let wday = days[date.getDay()];
|
||||
let day = date.getDate();
|
||||
let monthIndex = date.getMonth();
|
||||
let year = date.getFullYear();
|
||||
|
||||
let suffix = 'th';
|
||||
if (day === 1) suffix = 'st';
|
||||
if (day === 2) suffix = 'nd';
|
||||
if (day === 3) suffix = 'rd';
|
||||
|
||||
return wday + ' ' + day + suffix + ' ' + monthNames[monthIndex] + ', ' + year;
|
||||
}
|
||||
|
||||
window.onload = function ()
|
||||
{
|
||||
let svgtips = document.getElementsByClassName("svg-tip");
|
||||
let rects = document.getElementsByClassName("egg_rect");
|
||||
|
||||
let masterTip = null;
|
||||
|
||||
for (let tip of svgtips)
|
||||
{
|
||||
tip.style.opacity = '1';
|
||||
tip.style.display = 'none';
|
||||
|
||||
masterTip = tip;
|
||||
}
|
||||
|
||||
let masterTipHeader = masterTip.getElementsByTagName('strong')[0];
|
||||
let masterTipContent = masterTip.getElementsByTagName('span')[0];
|
||||
|
||||
for (let rect of rects)
|
||||
{
|
||||
rect.addEventListener("mouseenter", function(event)
|
||||
{
|
||||
let datesplit = event.target.getAttribute('data-date').split('-');
|
||||
let count = event.target.getAttribute('data-count');
|
||||
let date = new Date(Number(datesplit[0]), Number(datesplit[1])-1, Number(datesplit[2]));
|
||||
|
||||
masterTip.style.display = 'block';
|
||||
|
||||
masterTipHeader.innerHTML = count + ' commits';
|
||||
masterTipContent.innerHTML = ' on ' + formatDate(date);
|
||||
|
||||
masterTip.style.left = (window.pageXOffset + event.target.getBoundingClientRect().left - masterTip.getBoundingClientRect().width /2 - 3.5 + 9) + 'px';
|
||||
masterTip.style.top = (window.pageYOffset + event.target.getBoundingClientRect().top - masterTip.getBoundingClientRect().height -10) + 'px';
|
||||
});
|
||||
rect.addEventListener("mouseleave", function(event)
|
||||
{
|
||||
masterTip.style.display = 'none';
|
||||
});
|
||||
}
|
||||
};
|
3
www/dynamic/.gitignore
vendored
Normal file
3
www/dynamic/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
*
|
||||
!.gitignore
|
||||
!.gitkeep
|
0
www/dynamic/.gitkeep
Normal file
0
www/dynamic/.gitkeep
Normal file
39
www/extern/egh/ConnectionGitea.php
vendored
Normal file
39
www/extern/egh/ConnectionGitea.php
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
require_once 'SingleCommitInfo.php';
|
||||
|
||||
class ConnectionGitea
|
||||
{
|
||||
/* @var string */
|
||||
private $url;
|
||||
|
||||
/* @var string */
|
||||
private $owner;
|
||||
|
||||
/**
|
||||
* @param $owner ExtendedGitGraph
|
||||
*/
|
||||
public function __construct($owner) {
|
||||
$this->owner = $owner;
|
||||
}
|
||||
|
||||
public function setURL($giteaurl) {
|
||||
$this->url = $giteaurl;
|
||||
}
|
||||
|
||||
/* @return SingleCommitInfo[] */
|
||||
public function getDataUser($cfg)
|
||||
{
|
||||
$result = []; //TODO
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/* @return SingleCommitInfo[] */
|
||||
public function getDataRepository($cfg)
|
||||
{
|
||||
$result = []; //TODO
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
166
www/extern/egh/ConnectionGithub.php
vendored
Normal file
166
www/extern/egh/ConnectionGithub.php
vendored
Normal file
@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
require_once 'SingleCommitInfo.php';
|
||||
require_once 'Utils.php';
|
||||
|
||||
class ConnectionGithub
|
||||
{
|
||||
const API_OAUTH_AUTH = 'https://github.com/login/oauth/authorize?client_id=%s';
|
||||
const URL_OAUTH_TOKEN = 'https://github.com/login/oauth/access_token?client_id={id}&client_secret={secret}&code={code}';
|
||||
|
||||
const API_RATELIMIT = 'https://api.github.com/rate_limit';
|
||||
const API_REPOSITORIESLIST = 'https://api.github.com/users/{user}/repos?page={page}&per_page=100';
|
||||
const API_COMMITSLIST = 'https://api.github.com/repos/{repo}/commits?per_page=100&page={page}&author={author}';
|
||||
|
||||
/* @var string */
|
||||
private $token;
|
||||
|
||||
/* @var string */
|
||||
private $owner;
|
||||
|
||||
/**
|
||||
* @param $owner ExtendedGitGraph
|
||||
*/
|
||||
public function __construct($owner) {
|
||||
$this->owner = $owner;
|
||||
}
|
||||
|
||||
public function setAPIToken($token) {
|
||||
$this->token = $token;
|
||||
}
|
||||
|
||||
public function queryAPIToken($client_id, $client_secret) {
|
||||
$url = Utils::sharpFormat(self::URL_OAUTH_TOKEN, ['id'=>$client_id, 'secret'=>$client_secret, 'code'=>'egh']);
|
||||
$result = file_get_contents($url);
|
||||
|
||||
$result = str_replace('access_token=', '', $result);
|
||||
$result = str_replace('&scope=&token_type=bearer', '', $result);
|
||||
|
||||
$this->setAPIToken($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $cfg EGHRemoteConfig
|
||||
* @return SingleCommitInfo[]
|
||||
*/
|
||||
public function getDataUser($cfg)
|
||||
{
|
||||
$repos = $this->listRepositoriesByUser($cfg->Param);
|
||||
|
||||
$result = [];
|
||||
foreach ($repos as $repo)
|
||||
{
|
||||
$commits = $this->listCommitsFromRepo($repo, $cfg->Author);
|
||||
foreach ($commits as $c) $result []= $c;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $cfg EGHRemoteConfig
|
||||
* @return SingleCommitInfo[]
|
||||
*/
|
||||
public function getDataRepository($cfg)
|
||||
{
|
||||
return $this->listCommitsFromRepo($cfg->Param, $cfg->Author);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $user string
|
||||
* @return string[]
|
||||
*/
|
||||
private function listRepositoriesByUser($user)
|
||||
{
|
||||
$result = [];
|
||||
|
||||
$page = 1;
|
||||
$url = Utils::sharpFormat(self::API_REPOSITORIESLIST, ['user'=>$user, 'page'=>$page, 'token'=>$this->token]);
|
||||
|
||||
$json = $this->getJSON($url);
|
||||
|
||||
while (! empty($json)) {
|
||||
foreach ($json as $result_repo) {
|
||||
$result []= $result_repo->{'full_name'};
|
||||
$this->owner->out("Found Repo: " . $result_repo->{'full_name'});
|
||||
}
|
||||
|
||||
$page++;
|
||||
$url = Utils::sharpFormat(self::API_REPOSITORIESLIST, ['user'=>$user, 'page'=>$page, 'token'=>$this->token]);
|
||||
$json = $this->getJSON($url);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $repo string
|
||||
* @param $user string
|
||||
* @return SingleCommitInfo[]
|
||||
*/
|
||||
private function listCommitsFromRepo($repo, $user)
|
||||
{
|
||||
$page = 1;
|
||||
$url = Utils::sharpFormat(self::API_COMMITSLIST, ['repo'=>$repo, 'author'=>$user, 'page'=>$page, 'token'=>$this->token]);
|
||||
|
||||
$result = $this->getJSON($url);
|
||||
|
||||
$commit_list = [];
|
||||
|
||||
while (! empty($result)) {
|
||||
foreach ($result as $rc) $commit_list[] = new SingleCommitInfo(DateTime::createFromFormat(DateTime::ISO8601, $rc->{'commit'}->{'author'}->{'date'}), 'github', $user, $repo);
|
||||
$this->owner->out("Found " . count($result) . " Commits in " . $repo);
|
||||
|
||||
$page++;
|
||||
$url = Utils::sharpFormat(self::API_COMMITSLIST, [ 'repo'=>$repo, 'author'=>$user, 'page'=>$page, 'token'=>$this->token ]);
|
||||
$result = $this->getJSON($url);
|
||||
}
|
||||
|
||||
return $commit_list;
|
||||
}
|
||||
public function getJSON($url) {
|
||||
if (array_key_exists('HTTP_USER_AGENT', $_SERVER)) {
|
||||
$options =
|
||||
[
|
||||
'http' =>
|
||||
[
|
||||
'user_agent' => $_SERVER['HTTP_USER_AGENT'],
|
||||
'header' => 'Authorization: token ' . $this->token,
|
||||
],
|
||||
'https' =>
|
||||
[
|
||||
'user_agent' => $_SERVER['HTTP_USER_AGENT'],
|
||||
'header' => 'Authorization: token ' . $this->token,
|
||||
],
|
||||
];
|
||||
} else {
|
||||
$options =
|
||||
[
|
||||
'http' =>
|
||||
[
|
||||
'user_agent' => 'ExtendedGitGraph_for_mikescher.com',
|
||||
'header' => 'Authorization: token ' . $this->token,
|
||||
],
|
||||
'https' =>
|
||||
[
|
||||
'user_agent' => 'ExtendedGitGraph_for_mikescher.com',
|
||||
'header' => 'Authorization: token ' . $this->token,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
$context = stream_context_create($options);
|
||||
|
||||
$response = @file_get_contents($url, false, $context);
|
||||
|
||||
if ($response === false)
|
||||
{
|
||||
$this->owner->out("Error recieving json: '" . $url . "'");
|
||||
return [];
|
||||
}
|
||||
|
||||
return json_decode($response);
|
||||
}
|
||||
|
||||
}
|
27
www/extern/egh/EGHRemoteConfig.php
vendored
Normal file
27
www/extern/egh/EGHRemoteConfig.php
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
class EGHRemoteConfig
|
||||
{
|
||||
/* @var string|null */
|
||||
public $Type;
|
||||
/* @var string|null */
|
||||
public $URL;
|
||||
/* @var string|null */
|
||||
public $Author;
|
||||
/* @var string|null */
|
||||
public $Param;
|
||||
|
||||
/**
|
||||
* @param $typ string|null
|
||||
* @param $url string|null
|
||||
* @param $usr string|null
|
||||
* @param $param string|null
|
||||
*/
|
||||
public function __construct($typ, $url, $usr, $param) {
|
||||
$this->Type = $typ;
|
||||
$this->URL = $url;
|
||||
$this->Author = $usr;
|
||||
$this->Param = $param;
|
||||
}
|
||||
|
||||
}
|
224
www/extern/egh/EGHRenderer.php
vendored
Normal file
224
www/extern/egh/EGHRenderer.php
vendored
Normal file
@ -0,0 +1,224 @@
|
||||
<?php
|
||||
|
||||
require_once 'ExtendedGitGraph.php';
|
||||
require_once 'SingleCommitInfo.php';
|
||||
require_once 'Utils.php';
|
||||
|
||||
class EGHRenderer
|
||||
{
|
||||
const DIST_X = 13;
|
||||
const DIST_Y = 13;
|
||||
const DAY_WIDTH = 11;
|
||||
const DAY_HEIGHT = 11;
|
||||
|
||||
const COMMITCOUNT_COLOR_UPPERLIMIT = 16;
|
||||
|
||||
const COLOR_SCHEMES =
|
||||
[
|
||||
'custom' => ['#F5F5F5', '#DBDEE0', '#C2C7CB', '#AAB0B7', '#9099A2', '#77828E', '#5E6B79', '#455464', '#2C3E50'],
|
||||
'standard' => ["#ebedf0", "#c6e48b", "#7bc96f", "#239a3b", "#196127"],
|
||||
'modern' => ["#afaca8", "#d6e685", "#8cc665", "#44a340", "#1e6823"],
|
||||
'gray' => ["#eeeeee", "#bdbdbd", "#9e9e9e", "#616161", "#212121"],
|
||||
'red' => ["#eeeeee", "#ff7171", "#ff0000", "#b70000", "#830000"],
|
||||
'blue' => ["#eeeeee", "#6bcdff", "#00a1f3", "#0079b7", "#003958"],
|
||||
'purple' => ["#eeeeee", "#d2ace6", "#aa66cc", "#660099", "#4f2266"],
|
||||
'orange' => ["#eeeeee", "#ffcc80", "#ffa726", "#fb8c00", "#e65100"],
|
||||
'halloween' => ["#eeeeee", "#ffee4a", "#ffc501", "#fe9600", "#03001c"],
|
||||
];
|
||||
|
||||
const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
||||
const DAYS = ['M', 'T', 'W', 'T', 'F', 'S', 'S'];
|
||||
|
||||
/* @var ExtendedGitGraph */
|
||||
private $owner;
|
||||
/* @var SingleCommitInfo[] */
|
||||
public $data;
|
||||
/* @var string */
|
||||
public $colorScheme = 'standard';
|
||||
/* @var int[] */
|
||||
public $yearList;
|
||||
/* @var array */
|
||||
public $commitMap; // date('Y-m-d') -> count
|
||||
|
||||
public function __construct($egh) {
|
||||
$this->owner = $egh;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data SingleCommitInfo[]
|
||||
*/
|
||||
public function init($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
|
||||
$this->yearList = $this->getYears($data);
|
||||
$this->owner->out("Found " . count($this->yearList) . " year to generate.");
|
||||
|
||||
$this->commitMap = $this->generateCommitMap($data, $this->yearList);
|
||||
$this->owner->out("Commitmap with ".count($this->commitMap)." entries generated.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data SingleCommitInfo[]
|
||||
* @return int[]
|
||||
*/
|
||||
public function getYears($data) {
|
||||
$years = array();
|
||||
|
||||
foreach ($data as $commit) {
|
||||
if(! in_array($commit->Timestamp->format('Y'), $years))
|
||||
$years[] = intval($commit->Timestamp->format('Y'));
|
||||
}
|
||||
|
||||
asort($years);
|
||||
|
||||
return $years;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data SingleCommitInfo[]
|
||||
* @param $yearList int[]
|
||||
* @return array
|
||||
*/
|
||||
private function generateCommitMap($data, $yearList)
|
||||
{
|
||||
$result = [];
|
||||
|
||||
foreach ($yearList as $year)
|
||||
{
|
||||
$ymap = [];
|
||||
|
||||
$date = new DateTime($year . '-01-01');
|
||||
while($date->format('Y') == $year)
|
||||
{
|
||||
$ymap[$date->format('Y-m-d')] = 0;
|
||||
$date = $date->modify("+1 day");
|
||||
}
|
||||
|
||||
foreach ($data as $commit)
|
||||
{
|
||||
if(array_key_exists($commit->Timestamp->format('Y-m-d'), $ymap)) $ymap[$commit->Timestamp->format('Y-m-d')]++;
|
||||
}
|
||||
|
||||
$result = array_merge($result, $ymap);
|
||||
}
|
||||
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $year int
|
||||
* @return int
|
||||
*/
|
||||
private function getMaxCommitCount($year)
|
||||
{
|
||||
$max = 0;
|
||||
foreach ($this->commitMap as $date => $count) if (Utils::startsWith($date, strval($year))) $max = max($max, $count);
|
||||
return $max;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $year int
|
||||
* @return string
|
||||
*/
|
||||
public function render($year)
|
||||
{
|
||||
$now = new DateTime();
|
||||
$date = new DateTime($year . '-01-01');
|
||||
$monthlist = array_fill(0, 12, [0, 0]);
|
||||
$colors = self::COLOR_SCHEMES[$this->colorScheme];
|
||||
|
||||
$ymapmax = $this->getMaxCommitCount($year);
|
||||
$exponent = log(0.98/(count($colors)-1), 1/$ymapmax); // (1/max)^n = 0.98 // => 1 commit erreicht immer genau die erste stufe
|
||||
|
||||
$html = '';
|
||||
|
||||
$html .= '<div class="extGitGraphContainer">' . "\n";
|
||||
$html .= '<svg class="git_list" viewBox="0 0 715 115">' . "\n";
|
||||
$html .= '<g transform="translate(20, 20) ">' . "\n";
|
||||
$html .= '<g transform="translate(0, 0)">' . "\n";
|
||||
|
||||
$week = 0;
|
||||
$wday = 0;
|
||||
while($date->format('Y') == $year)
|
||||
{
|
||||
if ($date > $now) // THE FUTURE, SPONGEBOB
|
||||
{
|
||||
while ($date->format('d') != $date->format('t'))
|
||||
{
|
||||
if ($date->format('N') == 1 && $date->format('z') > 0) $week++;
|
||||
$date = $date->modify("+1 day");
|
||||
}
|
||||
$monthlist[$date->format('m') - 1][1] = $week + ($wday / 7);
|
||||
|
||||
$date = $date->modify("+1 year"); // Kill
|
||||
continue;
|
||||
}
|
||||
|
||||
$c_count = $this->commitMap[$date->format('Y-m-d')];
|
||||
$color_idx = min((count($colors)-1), ceil(pow($c_count/$ymapmax, $exponent) * (count($colors)-1)));
|
||||
$color = $colors[$color_idx];
|
||||
|
||||
$wday = ($date->format('N') - 1);
|
||||
|
||||
if ($date->format('N') == 1 && $date->format('z') > 0)
|
||||
{
|
||||
$html .= '</g>' . "\n";
|
||||
$week++;
|
||||
$html .= '<g transform="translate(' . $week * self::DIST_X . ', 0)">' . "\n";
|
||||
}
|
||||
|
||||
if ($date->format('d') == 1)
|
||||
{
|
||||
$monthlist[$date->format('m') - 1][0] = $week + ($wday / 7);
|
||||
}
|
||||
else if ($date->format('d') == $date->format('t'))
|
||||
{
|
||||
$monthlist[$date->format('m') - 1][1] = $week + ($wday / 7);
|
||||
}
|
||||
|
||||
$html .= '<rect'.
|
||||
' style=' .'"fill:'.$color.';' . '"' .
|
||||
' y="' . ($wday * self::DIST_Y) . '"' .
|
||||
' height="' . self::DAY_HEIGHT . '"' .
|
||||
' width="' . self::DAY_WIDTH . '"' .
|
||||
' class="' . 'egg_rect' . '"' .
|
||||
' data-count="' . $c_count . '"' .
|
||||
' data-date="' . ' ' . $date->format('Y-m-d') . '"' .
|
||||
'></rect>' . "\n";
|
||||
|
||||
$date = $date->modify("+1 day");
|
||||
}
|
||||
|
||||
$html .= '</g>' . "\n";
|
||||
|
||||
for($i = 0; $i < 12; $i++)
|
||||
{
|
||||
if ($monthlist[$i][1]-$monthlist[$i][0] > 0)
|
||||
{
|
||||
$posx = (($monthlist[$i][0]+$monthlist[$i][1])/2) * self::DIST_X;
|
||||
$html .= '<text y="-3" x="' . $posx . '" style="text-anchor: middle" class="caption_month">' . self::MONTHS[$i] . '</text>' . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
for($i = 0; $i < 7; $i++) {
|
||||
$html .= '<text y="' . ($i*self::DIST_Y + self::DAY_HEIGHT/2) . '" x="-6" style="text-anchor: middle" class="caption_day" dominant-baseline="central">' . self::DAYS[$i] . '</text>' . "\n";
|
||||
}
|
||||
|
||||
$html .= '<text x="-10" y="-5" class="caption">' . $year . '</text>' . "\n";
|
||||
|
||||
$html .= '</g>' . "\n";
|
||||
$html .= '</svg>' . "\n";
|
||||
$html .= '<div class="svg-tip n">' . "\n";
|
||||
$html .= '<strong> </strong><span> </span>' . "\n";
|
||||
$html .= '</div>' . "\n";
|
||||
$html .= '<div class="egg_footer">' . "\n";
|
||||
$html .= '<a href="https://www.mikescher.com/programs/view/ExtendedGitGraph">extendedGitGraph</a>' . "\n";
|
||||
$html .= '</div>' . "\n";
|
||||
$html .= '</div>' . "\n";
|
||||
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
184
www/extern/egh/ExtendedGitGraph.php
vendored
Normal file
184
www/extern/egh/ExtendedGitGraph.php
vendored
Normal file
@ -0,0 +1,184 @@
|
||||
<?php
|
||||
|
||||
require_once 'EGHRemoteConfig.php';
|
||||
require_once 'ConnectionGithub.php';
|
||||
require_once 'ConnectionGitea.php';
|
||||
require_once 'SingleCommitInfo.php';
|
||||
require_once 'EGHRenderer.php';
|
||||
|
||||
class ExtendedGitGraph
|
||||
{
|
||||
const OUT_SESSION = 0;
|
||||
const OUT_STDOUT = 1;
|
||||
const OUT_LOGFILE = 2;
|
||||
|
||||
const PROGRESS_SESSION_COOKIE = 'ajax_progress_egh_refresh';
|
||||
|
||||
const COMMITCOUNT_COLOR_UPPERLIMIT = 16;
|
||||
|
||||
/* @var string */
|
||||
private $filenamecache;
|
||||
/* @var EGHRemoteConfig[] */
|
||||
private $remoteconfigs;
|
||||
|
||||
/* @var ConnectionGithub */
|
||||
public $ConnectionGithub;
|
||||
/* @var ConnectionGitea */
|
||||
public $ConnectionGitea;
|
||||
|
||||
/* @var int */
|
||||
private $outputMode = self::OUT_SESSION;
|
||||
/* @var string */
|
||||
private $logFilePath;
|
||||
/* @var array */
|
||||
private $renderedHTML;
|
||||
/* @var SingleCommitInfo[] */
|
||||
private $queriedData;
|
||||
|
||||
/* @var string */
|
||||
private $colorScheme = 'blue';
|
||||
|
||||
public function __construct($filename_cache, $outmode, $logfile) {
|
||||
$this->filenamecache = $filename_cache;
|
||||
$this->remoteconfigs = [];
|
||||
$this->ConnectionGithub = new ConnectionGithub($this);
|
||||
$this->ConnectionGitea = new ConnectionGitea($this);
|
||||
$this->outputMode = $outmode;
|
||||
$this->logFilePath = $logfile;
|
||||
}
|
||||
|
||||
public function addRemote($type, $url, $user, $param) {
|
||||
$this->remoteconfigs []= new EGHRemoteConfig($type, $url, $user, $param);
|
||||
}
|
||||
|
||||
public function setColorScheme($s) {
|
||||
$this->colorScheme = $s;
|
||||
}
|
||||
|
||||
public function out($txt)
|
||||
{
|
||||
if ($txt !== '') $txt = '[' . date('H:i:s') . '] ' . $txt;
|
||||
|
||||
if ($this->outputMode === self::OUT_SESSION)
|
||||
{
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
$_SESSION[self::PROGRESS_SESSION_COOKIE] .= $txt . "\r\n";
|
||||
session_commit();
|
||||
}
|
||||
else if ($this->outputMode === self::OUT_STDOUT)
|
||||
{
|
||||
print $txt;
|
||||
print "\r\n";
|
||||
}
|
||||
|
||||
$logfile = Utils::sharpFormat($this->logFilePath, ['num'=>'']);
|
||||
file_put_contents($logfile, $txt.PHP_EOL , FILE_APPEND | LOCK_EX);
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
if ($this->outputMode === self::OUT_SESSION)
|
||||
{
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
$_SESSION[self::PROGRESS_SESSION_COOKIE] = '';
|
||||
session_commit();
|
||||
}
|
||||
|
||||
$f3 = Utils::sharpFormat($this->logFilePath, ['num'=>'_3']);
|
||||
$f2 = Utils::sharpFormat($this->logFilePath, ['num'=>'_2']);
|
||||
$f1 = Utils::sharpFormat($this->logFilePath, ['num'=>'_1']);
|
||||
$f0 = Utils::sharpFormat($this->logFilePath, ['num'=>'' ]);
|
||||
|
||||
if (file_exists($f3)) @unlink($f3);
|
||||
if (file_exists($f2)) @rename($f2, $f3);
|
||||
if (file_exists($f1)) @rename($f1, $f2);
|
||||
if (file_exists($f0)) @rename($f0, $f1);
|
||||
if (file_exists($f0)) @unlink($f0);
|
||||
|
||||
$this->out('EXTENDED_GIT_GRAPH started');
|
||||
$this->out('');
|
||||
}
|
||||
|
||||
public function updateFromRemotes()
|
||||
{
|
||||
$data = [];
|
||||
|
||||
foreach ($this->remoteconfigs as $cfg)
|
||||
{
|
||||
if ($cfg->Type === 'github-user')
|
||||
$data = array_merge($data, $this->ConnectionGithub->getDataUser($cfg));
|
||||
else if ($cfg->Type === 'github-repository')
|
||||
$data = array_merge($data, $this->ConnectionGithub->getDataRepository($cfg));
|
||||
else if ($cfg->Type === 'gitea-user')
|
||||
$data = array_merge($data, $this->ConnectionGitea->getDataUser($cfg));
|
||||
else if ($cfg->Type === 'gitea-repository')
|
||||
$data = array_merge($data, $this->ConnectionGitea->getDataRepository($cfg));
|
||||
else
|
||||
$this->out("Unknown type: " . $cfg->Type);
|
||||
}
|
||||
|
||||
$this->out("Found " . count($data) . " commits.");
|
||||
|
||||
file_put_contents($this->filenamecache, serialize($data));
|
||||
|
||||
$this->queriedData = $data;
|
||||
|
||||
}
|
||||
|
||||
public function updateFromCache()
|
||||
{
|
||||
if (file_exists($this->filenamecache))
|
||||
$this->queriedData = unserialize(file_get_contents($this->filenamecache));
|
||||
else
|
||||
$this->queriedData = [];
|
||||
}
|
||||
|
||||
public function generate()
|
||||
{
|
||||
$renderer = new EGHRenderer($this);
|
||||
$renderer->colorScheme = $this->colorScheme;
|
||||
|
||||
$renderer->init($this->queriedData);
|
||||
|
||||
$this->renderedHTML = [];
|
||||
foreach ($renderer->yearList as $y) $this->renderedHTML[$y] = $renderer->render($y);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $url string
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function getJSON($url) {
|
||||
if (array_key_exists('HTTP_USER_AGENT', $_SERVER)) {
|
||||
$options =
|
||||
[
|
||||
'http' => ['user_agent'=> $_SERVER['HTTP_USER_AGENT']],
|
||||
'https' => ['user_agent'=> $_SERVER['HTTP_USER_AGENT']],
|
||||
];
|
||||
} else {
|
||||
$options =
|
||||
[
|
||||
'http' => ['user_agent'=> 'ExtendedGitGraph_for_mikescher.com'],
|
||||
'https' => ['user_agent'=> 'ExtendedGitGraph_for_mikescher.com'],
|
||||
];
|
||||
}
|
||||
|
||||
$context = stream_context_create($options);
|
||||
|
||||
$response = @file_get_contents($url, false, $context);
|
||||
|
||||
if ($response === false)
|
||||
{
|
||||
$this->out("Error recieving json: '" . $url . "'");
|
||||
return [];
|
||||
}
|
||||
|
||||
return json_decode($response);
|
||||
}
|
||||
|
||||
public function get()
|
||||
{
|
||||
return $this->renderedHTML;
|
||||
}
|
||||
}
|
31
www/extern/egh/SingleCommitInfo.php
vendored
Normal file
31
www/extern/egh/SingleCommitInfo.php
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
class SingleCommitInfo
|
||||
{
|
||||
/* @var DateTime */
|
||||
public $Timestamp;
|
||||
|
||||
/* @var string */
|
||||
public $SourcePlatform;
|
||||
|
||||
/* @var string */
|
||||
public $SourceUser;
|
||||
|
||||
/* @var string */
|
||||
public $SourceRepository;
|
||||
|
||||
/**
|
||||
* @param $ts DateTime
|
||||
* @param $src string
|
||||
* @param $usr string
|
||||
* @param $repo string
|
||||
*/
|
||||
public function __construct($ts, $src, $usr, $repo) {
|
||||
$this->Timestamp = $ts;
|
||||
$this->SourcePlatform = $src;
|
||||
$this->SourceUser = $usr;
|
||||
$this->SourceRepository = $repo;
|
||||
}
|
||||
|
||||
|
||||
}
|
19
www/extern/egh/Utils.php
vendored
Normal file
19
www/extern/egh/Utils.php
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
class Utils
|
||||
{
|
||||
public static function sharpFormat($str, $args)
|
||||
{
|
||||
foreach ($args as $key => $val)
|
||||
{
|
||||
$str = str_replace('{'.$key.'}', $val, $str);
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
public static function startsWith($haystack, $needle)
|
||||
{
|
||||
$length = strlen($needle);
|
||||
return (substr($haystack, 0, $length) === $needle);
|
||||
}
|
||||
}
|
@ -58,7 +58,7 @@ if ($interactive) {
|
||||
$result .= ' </div>' . "\n";
|
||||
$result .= '</div>' . "\n";
|
||||
|
||||
$result .= includeScriptOnce("/data/javascript/blogpost_bef93runner.js", false) . "\n";
|
||||
$result .= includeScriptOnce("/data/javascript/blogpost_bef93runner.js", false, '') . "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -35,6 +35,6 @@ $result .= '</div>' . "\n";
|
||||
|
||||
$result .= '' . "\n";
|
||||
|
||||
$result .= includeScriptOnce("/data/javascript/blogpost_BFJoustBot_script.js", false) . "\n";
|
||||
$result .= includeScriptOnce("/data/javascript/blogpost_BFJoustBot_script.js", false, '') . "\n";
|
||||
|
||||
return $result;
|
@ -8,7 +8,7 @@ $problems = Euler::listAll();
|
||||
|
||||
?>
|
||||
|
||||
<div class="blogcontent bc_euler base_markdown">
|
||||
<div class="boxedcontent blogcontent_euler base_markdown">
|
||||
|
||||
<div style="position: relative;">
|
||||
<a href="https://github.com/Mikescher/Project-Euler_Befunge" style="position: absolute; top: 0; right: 0; border: 0;">
|
||||
|
@ -25,7 +25,7 @@ $max = ceil($max / 20) * 20;
|
||||
|
||||
?>
|
||||
|
||||
<div class="blogcontent bc_euler base_markdown">
|
||||
<div class="boxedcontent blogcontent_euler base_markdown">
|
||||
|
||||
<div style="position: relative;">
|
||||
<a href="https://github.com/Mikescher/Project-Euler_Befunge" style="position: absolute; top: 0; right: 0; border: 0;">
|
||||
|
@ -4,7 +4,7 @@ require_once (__DIR__ . '/../internals/blog.php');
|
||||
require_once (__DIR__ . '/../internals/ParsedownCustom.php');
|
||||
?>
|
||||
|
||||
<div class="blogcontent base_markdown">
|
||||
<div class="boxedcontent blogcontent_markdown base_markdown">
|
||||
|
||||
<div class="bc_header">
|
||||
<?php echo $post['date']; ?>
|
||||
|
@ -3,7 +3,7 @@ require_once (__DIR__ . '/../internals/base.php');
|
||||
require_once (__DIR__ . '/../internals/blog.php');
|
||||
?>
|
||||
|
||||
<div class="blogcontent bc_plain">
|
||||
<div class="boxedcontent blogcontent_plain">
|
||||
|
||||
<div class="bc_header">
|
||||
<?php echo $post['date']; ?>
|
||||
|
@ -173,4 +173,6 @@ try {
|
||||
//TODO euler best of on top of list (?)
|
||||
//TODO optimize image sizes for display/download (? - auto?)
|
||||
//TODO send cache header (?)
|
||||
//TODO programs add [license]
|
||||
//TODO programs add [license]
|
||||
//TODO admin
|
||||
//TODO last 3 blog entries on /index/ (?)
|
@ -88,7 +88,7 @@ function formatMilliseconds($millis)
|
||||
}
|
||||
}
|
||||
|
||||
function includeScriptOnce($script, $echo = true)
|
||||
function includeScriptOnce($script, $echo = true, $attr=false)
|
||||
{
|
||||
global $REGISTERED_SCRIPTS;
|
||||
|
||||
@ -96,14 +96,14 @@ function includeScriptOnce($script, $echo = true)
|
||||
{
|
||||
if (in_array($script, $REGISTERED_SCRIPTS)) return false;
|
||||
$REGISTERED_SCRIPTS []= $script;
|
||||
echo "<script src=\"$script\" type=\"text/javascript\"></script>";
|
||||
echo "<script src=\"$script\" type=\"text/javascript\" $attr></script>";
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (in_array($script, $REGISTERED_SCRIPTS)) return '';
|
||||
$REGISTERED_SCRIPTS []= $script;
|
||||
return "<script src=\"$script\" type=\"text/javascript\"></script>";
|
||||
return "<script src=\"$script\" type=\"text/javascript\" $attr></script>";
|
||||
}
|
||||
}
|
||||
|
||||
|
54
www/pages/about.php
Normal file
54
www/pages/about.php
Normal file
@ -0,0 +1,54 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Mikescher.com - About</title>
|
||||
<link rel="icon" type="image/png" href="/data/images/favicon.png"/>
|
||||
<link rel="canonical" href="https://www.mikescher.com/about"/>
|
||||
<?php printCSS(); ?>
|
||||
<?php includeScriptOnce("/data/javascript/egh.js", true, 'defer') ?>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mastercontainer">
|
||||
|
||||
<?php $HEADER_ACTIVE = 'about'; include (__DIR__ . '/../fragments/header.php'); ?>
|
||||
|
||||
<div id="content" class="content-responsive">
|
||||
|
||||
<div class="aboutcontent">
|
||||
|
||||
<div class="contentheader"><h1>About mikescher.com</h1><hr/></div>
|
||||
|
||||
<div class="boxedcontent">
|
||||
<div class="bc_header">About me</div>
|
||||
|
||||
<div class="bc_data">
|
||||
|
||||
<p>Welcome to my private homepage.</p>
|
||||
<p>My name is Mike, and this is my homepage. I use it to upload programs I have written and sometimes for a little bit of blogging.</p>
|
||||
<p>There are also sections about Project Euler, self-printed books and more</p>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="boxedcontent">
|
||||
<div class="bc_header">My git timeline</div>
|
||||
|
||||
<div class="bc_data about_egh_container">
|
||||
|
||||
<?php if (file_exists(__DIR__ . '/../dynamic/egh.html')) include __DIR__ . '/../dynamic/egh.html' ?>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<?php include (__DIR__ . '/../fragments/footer.php'); ?>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,3 +1,278 @@
|
||||
A little PHP library to display and update an commit Overview from [Github](https://github.com/).
|
||||
extendedGitGraph
|
||||
================
|
||||
|
||||
Design-wise its similiar to the official Commit Graph from github - but you can see your commits over a bigger timeframe.
|
||||
Displays a Commit Table for every of your github-years.
|
||||
This is practically a copy of githubs Commit-Graph functionality.
|
||||
But with the extra feature of showing commits older than a year, from private repositories abd from other git remotes.
|
||||
|
||||
*See it live in action [here](http://www.mikescher.de/about)*
|
||||
|
||||
### How to use:
|
||||
|
||||
Create a new ExtendedGitGraph object
|
||||
|
||||
The constructor parameters are:
|
||||
|
||||
* the path to the cache file
|
||||
* The output mode
|
||||
- STDOUT: Log to `print` and logfile
|
||||
- SESSION: Log session-variable and logfile (used for ajax calls)
|
||||
- LOGFILE: Only log to logfile
|
||||
* The logfile path. The 4 latest logs are kept and the placeholder {num} is used for different filenames
|
||||
|
||||
~~~php
|
||||
include 'src/ExtendedGitGraph.php';
|
||||
|
||||
$v = new ExtendedGitGraph(__DIR__ . '/egh_cache.bin', ExtendedGitGraph::OUT_STDOUT, __DIR__ . '/../temp/egh_log{num}.log');
|
||||
~~~
|
||||
|
||||
Next you need to add sources for us to search, currently supported are:
|
||||
|
||||
* Github User accounts
|
||||
* Github Repositories
|
||||
* Gitea User accounts *(WIP)*
|
||||
* Gitea Repositories *(WIP)*
|
||||
|
||||
~~~php
|
||||
$v->addRemote('github-user', null, 'Mikescher', 'Mikescher');
|
||||
$v->addRemote('github-user', null, 'Mikescher', 'Blackforestbytes');
|
||||
$v->addRemote('github-repository', null, 'Mikescher', 'Anastron/ColorRunner');
|
||||
$v->addRemote('gitea-user', null, 'Mikescher', 'Mikescher');
|
||||
$v->addRemote('gitea-repository', null, 'Mikescher', 'Benzin/MVU_API');
|
||||
~~~
|
||||
|
||||
If you use github you need to specify an API token to get more than 60 API calls:
|
||||
(get one from [Github -> Settings -> Developer Settings -> Personal access tokens](https://github.com/settings/tokens))
|
||||
|
||||
~~~php
|
||||
$v->ConnectionGithub->setAPIToken('1234567890ABCDEF');
|
||||
~~~
|
||||
|
||||
If you use gitea you need to specify the server url
|
||||
|
||||
~~~php
|
||||
$v->ConnectionGitea->setURL('https://my-git-server.tld');
|
||||
~~~
|
||||
|
||||
Now we generate the graphs, first call `init()`
|
||||
~~~php
|
||||
$v->init();
|
||||
~~~
|
||||
|
||||
Then either query the data from our specified sources with `updateFromRemotes()` or load teh values from the last query from our specified cache file with `updateFromCache()`
|
||||
~~~php
|
||||
$v->updateFromRemotes();
|
||||
//$v->updateFromCache();
|
||||
~~~
|
||||
|
||||
Next call `generate()` to create HTML and get the snippets by calling `get()`.
|
||||
|
||||
~~~php
|
||||
$v->setColorScheme('blue');
|
||||
$v->generate();
|
||||
|
||||
foreach ($v->get() as $year => $html)
|
||||
{
|
||||
file_put_contents(__DIR__ . '/../output/out_'.$year.'.html', $html);
|
||||
}
|
||||
~~~
|
||||
|
||||
You can set the used color scheme with `setColorScheme`, supported are:
|
||||
- custom
|
||||
- standard
|
||||
- modern
|
||||
- gray
|
||||
- red
|
||||
- blue
|
||||
- purple
|
||||
- orange
|
||||
- halloween
|
||||
|
||||
![](https://raw.githubusercontent.com/Mikescher/extendedGitGraph/master/README-DATA/preview_orange.png)
|
||||
![](https://raw.githubusercontent.com/Mikescher/extendedGitGraph/master/README-DATA/preview_purple.png)
|
||||
![](https://raw.githubusercontent.com/Mikescher/extendedGitGraph/master/README-DATA/preview_green.png)
|
||||
![](https://raw.githubusercontent.com/Mikescher/extendedGitGraph/master/README-DATA/preview_red.png)
|
||||
|
||||
### Reload with Ajax:
|
||||
|
||||
The reloading can take a **long** time if you have a lot of commits and repositories.
|
||||
Because of that you can also refresh via Ajax:
|
||||
|
||||
- Call the file `ajax/ajaxReload.php?scheme=x` to start the reloading
|
||||
- Call the file `ajax/ajaxStatus.php` to get the current status (for displaying purposes)
|
||||
- Call the file `ajax/ajaxRedraw.php?scheme=x` to only redraw from cache
|
||||
|
||||
> **Attention:**
|
||||
> You need to create a file `ajaxSecret.php` that returns an ExtendedGitGraph object with your settings (remotes, repositories, tokens, etc).
|
||||
> Don't forget to set output mode to `ExtendedGitGraph::OUT_SESSION`
|
||||
|
||||
Below a crappy example implementation with jQuerys Ajax calls:
|
||||
|
||||
~~~html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/style.css">
|
||||
<script type="text/javascript" language="JavaScript">
|
||||
<?php include __DIR__ . '/../script.js'; ?>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" language="JavaScript">
|
||||
function startAjaxRedraw() {
|
||||
$('#drawdiv').html("");
|
||||
|
||||
var scheme = $("#select_scheme").val();
|
||||
|
||||
val = setInterval(
|
||||
function()
|
||||
{
|
||||
jQuery.ajax({
|
||||
url: '/ajax/ajaxStatus.php',
|
||||
success: function(result)
|
||||
{
|
||||
var ajaxOutput = $('#ajaxOutput');
|
||||
|
||||
ajaxOutput.val(result);
|
||||
ajaxOutput.scrollTop(ajaxOutput[0].scrollHeight);
|
||||
},
|
||||
async: true
|
||||
});
|
||||
}, 500);
|
||||
|
||||
jQuery.ajax({
|
||||
url: '/ajax/ajaxRedraw.php?scheme='+scheme,
|
||||
success: function(result)
|
||||
{
|
||||
clearInterval(val);
|
||||
$('#drawdiv').html(result)
|
||||
},
|
||||
error: function(result)
|
||||
{
|
||||
clearInterval(val);
|
||||
|
||||
jQuery.ajax({
|
||||
url: '/ajax/ajaxStatus.php',
|
||||
success: function(result)
|
||||
{
|
||||
var ajaxOutput = $('#ajaxOutput');
|
||||
|
||||
ajaxOutput.val(result + '\r\n' + 'AN ERROR OCCURED:' + '\r\n' + textStatus);
|
||||
ajaxOutput.scrollTop(ajaxOutput[0].scrollHeight);
|
||||
},
|
||||
async: true
|
||||
});
|
||||
},
|
||||
async: true
|
||||
});
|
||||
}
|
||||
|
||||
function startAjaxRefresh()
|
||||
{
|
||||
var scheme = $("#select_scheme").val();
|
||||
|
||||
$('#ajaxOutput').val("");
|
||||
$('#drawdiv').html("");
|
||||
|
||||
val = setInterval(
|
||||
function()
|
||||
{
|
||||
jQuery.ajax({
|
||||
url: '/ajax/ajaxStatus.php',
|
||||
success: function(result)
|
||||
{
|
||||
var ajaxOutput = $('#ajaxOutput');
|
||||
|
||||
ajaxOutput.val(result);
|
||||
ajaxOutput.scrollTop(ajaxOutput[0].scrollHeight);
|
||||
},
|
||||
async: true
|
||||
});
|
||||
}, 500);
|
||||
|
||||
jQuery.ajax({
|
||||
url: '/ajax/ajaxReload.php?scheme='+scheme,
|
||||
success: function(result)
|
||||
{
|
||||
clearInterval(val);
|
||||
|
||||
jQuery.ajax({
|
||||
url: '/ajax/ajaxStatus.php',
|
||||
success: function(result)
|
||||
{
|
||||
var ajaxOutput = $('#ajaxOutput');
|
||||
|
||||
ajaxOutput.val(result + '\r\n.');
|
||||
ajaxOutput.scrollTop(ajaxOutput[0].scrollHeight);
|
||||
},
|
||||
async: true
|
||||
});
|
||||
|
||||
$('#drawdiv').html(result);
|
||||
},
|
||||
error: function( jqXHR, textStatus, errorThrown)
|
||||
{
|
||||
clearInterval(val);
|
||||
|
||||
jQuery.ajax({
|
||||
url: '/ajax/ajaxStatus.php',
|
||||
success: function(result)
|
||||
{
|
||||
var ajaxOutput = $('#ajaxOutput');
|
||||
|
||||
ajaxOutput.val(result + '\r\n' + 'AN ERROR OCCURED:' + '\r\n' + textStatus);
|
||||
ajaxOutput.scrollTop(ajaxOutput[0].scrollHeight);
|
||||
},
|
||||
async: true
|
||||
});
|
||||
},
|
||||
async: true
|
||||
});
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<textarea style="width: 800px; height: 250px;" id="ajaxOutput" readonly="readonly" title="?"></textarea>
|
||||
|
||||
<br>
|
||||
|
||||
<a href="javascript:startAjaxRedraw()">[REDRAW]</a>
|
||||
|
||||
<a href="javascript:startAjaxRefresh()">[REGENERATE]</a>
|
||||
|
||||
<select id="select_scheme">
|
||||
<option value="custom">custom</option>
|
||||
<option value="standard">standard</option>
|
||||
<option value="modern">modern</option>
|
||||
<option value="gray">gray</option>
|
||||
<option value="red">red</option>
|
||||
<option value="blue" selected="selected">blue</option>
|
||||
<option value="purple">purple</option>
|
||||
<option value="orange">orange</option>
|
||||
<option value="halloween">halloween</option>
|
||||
</select>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<div id="drawdiv" >
|
||||
<?php
|
||||
foreach (glob(__DIR__ . '/../output/out_*.html') as $f)
|
||||
{
|
||||
echo file_get_contents($f);
|
||||
echo "\n\n\n<br/>\n\n\n";
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
~~~
|
||||
|
Loading…
Reference in New Issue
Block a user