Version 1.0 à la pelle de chantier
This commit is contained in:
commit
b77bdd3da1
13 changed files with 1143 additions and 0 deletions
22
.gitattributes
vendored
Normal file
22
.gitattributes
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# Auto detect text files and perform LF normalization
|
||||||
|
* text=auto
|
||||||
|
|
||||||
|
# Custom for Visual Studio
|
||||||
|
*.cs diff=csharp
|
||||||
|
*.sln merge=union
|
||||||
|
*.csproj merge=union
|
||||||
|
*.vbproj merge=union
|
||||||
|
*.fsproj merge=union
|
||||||
|
*.dbproj merge=union
|
||||||
|
|
||||||
|
# Standard to msysgit
|
||||||
|
*.doc diff=astextplain
|
||||||
|
*.DOC diff=astextplain
|
||||||
|
*.docx diff=astextplain
|
||||||
|
*.DOCX diff=astextplain
|
||||||
|
*.dot diff=astextplain
|
||||||
|
*.DOT diff=astextplain
|
||||||
|
*.pdf diff=astextplain
|
||||||
|
*.PDF diff=astextplain
|
||||||
|
*.rtf diff=astextplain
|
||||||
|
*.RTF diff=astextplain
|
215
.gitignore
vendored
Normal file
215
.gitignore
vendored
Normal file
|
@ -0,0 +1,215 @@
|
||||||
|
#################
|
||||||
|
## Eclipse
|
||||||
|
#################
|
||||||
|
|
||||||
|
*.pydevproject
|
||||||
|
.project
|
||||||
|
.metadata
|
||||||
|
bin/
|
||||||
|
tmp/
|
||||||
|
*.tmp
|
||||||
|
*.bak
|
||||||
|
*.swp
|
||||||
|
*~.nib
|
||||||
|
local.properties
|
||||||
|
.classpath
|
||||||
|
.settings/
|
||||||
|
.loadpath
|
||||||
|
|
||||||
|
# External tool builders
|
||||||
|
.externalToolBuilders/
|
||||||
|
|
||||||
|
# Locally stored "Eclipse launch configurations"
|
||||||
|
*.launch
|
||||||
|
|
||||||
|
# CDT-specific
|
||||||
|
.cproject
|
||||||
|
|
||||||
|
# PDT-specific
|
||||||
|
.buildpath
|
||||||
|
|
||||||
|
|
||||||
|
#################
|
||||||
|
## Visual Studio
|
||||||
|
#################
|
||||||
|
|
||||||
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
|
||||||
|
[Dd]ebug/
|
||||||
|
[Rr]elease/
|
||||||
|
x64/
|
||||||
|
build/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
|
||||||
|
# MSTest test Results
|
||||||
|
[Tt]est[Rr]esult*/
|
||||||
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.tmp_proj
|
||||||
|
*.log
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.builds
|
||||||
|
*.pidb
|
||||||
|
*.log
|
||||||
|
*.scc
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.cachefile
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*.vspx
|
||||||
|
|
||||||
|
# Guidance Automation Toolkit
|
||||||
|
*.gpState
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*/
|
||||||
|
*.[Rr]e[Ss]harper
|
||||||
|
|
||||||
|
# TeamCity is a build add-in
|
||||||
|
_TeamCity*
|
||||||
|
|
||||||
|
# DotCover is a Code Coverage Tool
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
# NCrunch
|
||||||
|
*.ncrunch*
|
||||||
|
.*crunch*.local.xml
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress/
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help/*.HxT
|
||||||
|
DocProject/Help/*.HxC
|
||||||
|
DocProject/Help/*.hhc
|
||||||
|
DocProject/Help/*.hhk
|
||||||
|
DocProject/Help/*.hhp
|
||||||
|
DocProject/Help/Html2
|
||||||
|
DocProject/Help/html
|
||||||
|
|
||||||
|
# Click-Once directory
|
||||||
|
publish/
|
||||||
|
|
||||||
|
# Publish Web Output
|
||||||
|
*.Publish.xml
|
||||||
|
*.pubxml
|
||||||
|
|
||||||
|
# NuGet Packages Directory
|
||||||
|
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
|
||||||
|
#packages/
|
||||||
|
|
||||||
|
# Windows Azure Build Output
|
||||||
|
csx
|
||||||
|
*.build.csdef
|
||||||
|
|
||||||
|
# Windows Store app package directory
|
||||||
|
AppPackages/
|
||||||
|
|
||||||
|
# Others
|
||||||
|
sql/
|
||||||
|
*.Cache
|
||||||
|
ClientBin/
|
||||||
|
[Ss]tyle[Cc]op.*
|
||||||
|
~$*
|
||||||
|
*~
|
||||||
|
*.dbmdl
|
||||||
|
*.[Pp]ublish.xml
|
||||||
|
*.pfx
|
||||||
|
*.publishsettings
|
||||||
|
|
||||||
|
# RIA/Silverlight projects
|
||||||
|
Generated_Code/
|
||||||
|
|
||||||
|
# Backup & report files from converting an old project file to a newer
|
||||||
|
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||||
|
_UpgradeReport_Files/
|
||||||
|
Backup*/
|
||||||
|
UpgradeLog*.XML
|
||||||
|
UpgradeLog*.htm
|
||||||
|
|
||||||
|
# SQL Server files
|
||||||
|
App_Data/*.mdf
|
||||||
|
App_Data/*.ldf
|
||||||
|
|
||||||
|
#############
|
||||||
|
## Windows detritus
|
||||||
|
#############
|
||||||
|
|
||||||
|
# Windows image file caches
|
||||||
|
Thumbs.db
|
||||||
|
ehthumbs.db
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
Desktop.ini
|
||||||
|
|
||||||
|
# Recycle Bin used on file shares
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
|
# Mac crap
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
|
||||||
|
#############
|
||||||
|
## Python
|
||||||
|
#############
|
||||||
|
|
||||||
|
*.py[co]
|
||||||
|
|
||||||
|
# Packages
|
||||||
|
*.egg
|
||||||
|
*.egg-info
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
eggs/
|
||||||
|
parts/
|
||||||
|
var/
|
||||||
|
sdist/
|
||||||
|
develop-eggs/
|
||||||
|
.installed.cfg
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
.coverage
|
||||||
|
.tox
|
||||||
|
|
||||||
|
#Translations
|
||||||
|
*.mo
|
||||||
|
|
||||||
|
#Mr Developer
|
||||||
|
.mr.developer.cfg
|
183
auto_restrict.php
Normal file
183
auto_restrict.php
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author bronco@warriordudimanche.com / www.warriordudimanche.net
|
||||||
|
* @copyright open source and free to adapt (keep me aware !)
|
||||||
|
* @version 2.0
|
||||||
|
*
|
||||||
|
* Verrouille l'accès à une page
|
||||||
|
* Il suffit d'inclure ce fichier pour bloquer l'accès
|
||||||
|
* il gère seul l'expiration de session, la connexion,
|
||||||
|
* la déconnexion.
|
||||||
|
*
|
||||||
|
* Améliorations eventuelles:
|
||||||
|
* ajouter compteur de tentatives sur ban id.
|
||||||
|
* ajouter la sécurisation du $_POST (en cas d'usage d'une base de donnees)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
// configuration
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
$auto_restrict['error_msg']='Erreur - impossible de se connecter.';// utilisé si on ne veut pas rediriger
|
||||||
|
$auto_restrict['cookie_name']='sonarrss';// nom du cookie
|
||||||
|
$auto_restrict['encryption_key']='abcdef';// clé pour le cryptage de la chaine de vérification
|
||||||
|
$auto_restrict['session_expiration_delay']=120;//minutes
|
||||||
|
//$auto_restrict['login']='bronco'; // caractères alphanum + _ et .
|
||||||
|
$auto_restrict['redirect_error']='index.php';// si précisé, pas de message d'erreur
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
// sécurisation du passe: procédure astucieuse de JérômeJ (http://www.olissea.com/)
|
||||||
|
@include('pass.php');
|
||||||
|
if(!isset($auto_restrict['pass'])){
|
||||||
|
if(isset($_POST['pass'])&&isset($_POST['login'])&&$_POST['pass']!=''&&$_POST['login']!=''){ # Création du fichier pass.php
|
||||||
|
$salt = md5(uniqid('', true));
|
||||||
|
file_put_contents('pass.php', '<?php $auto_restrict["login"]="'.$_POST['login'].'";$auto_restrict["salt"] = '.var_export($salt,true).'; $auto_restrict["pass"] = '.var_export(hash('sha512', $salt.$_POST['pass']),true).'; ?>');
|
||||||
|
include('login_form.php');exit();
|
||||||
|
}
|
||||||
|
else{ # On affiche un formulaire invitant à rentrer le mdp puis on exit le script
|
||||||
|
include('login_form.php');exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
// gestion de post pour demande de connexion
|
||||||
|
// si un utilisateur tente de se loguer, on gère ici
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
if (isset($_POST['login'])&&isset($_POST['pass'])){
|
||||||
|
log_user($_POST['login'],$_POST['pass']);
|
||||||
|
if (isset($_POST['cookie'])){setcookie($auto_restrict['cookie_name'],sha1($_SERVER['HTTP_USER_AGENT']),time()+31104000);}//un an
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
// si pas de demande de connexion on verifie les vars de session
|
||||||
|
// et la duree d'inactivité de la session
|
||||||
|
// si probleme,on include un form de login.
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
if (!is_ok()){session_destroy();include('login_form.php');exit();}
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
// demande de deco via la variable get 'deconnexion'
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
if (isset($_GET['deconnexion'])){log_user($_POST['login'],$_POST['pass']);}
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
// fonctions de cryptage
|
||||||
|
// récupérées sur http://www.info-3000.com/phpmysql/cryptagedecryptage.php
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
function GenerationCle($Texte,$CleDEncryptage)
|
||||||
|
{
|
||||||
|
$CleDEncryptage = md5($CleDEncryptage);
|
||||||
|
$Compteur=0;
|
||||||
|
$VariableTemp = "";
|
||||||
|
for ($Ctr=0;$Ctr<strlen($Texte);$Ctr++)
|
||||||
|
{
|
||||||
|
if ($Compteur==strlen($CleDEncryptage))
|
||||||
|
$Compteur=0;
|
||||||
|
$VariableTemp.= substr($Texte,$Ctr,1) ^ substr($CleDEncryptage,$Compteur,1);
|
||||||
|
$Compteur++;
|
||||||
|
}
|
||||||
|
return $VariableTemp;
|
||||||
|
}
|
||||||
|
function Crypte($Texte,$Cle)
|
||||||
|
{
|
||||||
|
srand((double)microtime()*1000000);
|
||||||
|
$CleDEncryptage = md5(rand(0,32000) );
|
||||||
|
$Compteur=0;
|
||||||
|
$VariableTemp = "";
|
||||||
|
for ($Ctr=0;$Ctr<strlen($Texte);$Ctr++)
|
||||||
|
{
|
||||||
|
if ($Compteur==strlen($CleDEncryptage))
|
||||||
|
$Compteur=0;
|
||||||
|
$VariableTemp.= substr($CleDEncryptage,$Compteur,1).(substr($Texte,$Ctr,1) ^ substr($CleDEncryptage,$Compteur,1) );
|
||||||
|
$Compteur++;
|
||||||
|
}
|
||||||
|
return base64_encode(GenerationCle($VariableTemp,$Cle) );
|
||||||
|
}
|
||||||
|
function Decrypte($Texte,$Cle)
|
||||||
|
{
|
||||||
|
$Texte = GenerationCle(base64_decode($Texte),$Cle);
|
||||||
|
$VariableTemp = "";
|
||||||
|
for ($Ctr=0;$Ctr<strlen($Texte);$Ctr++)
|
||||||
|
{
|
||||||
|
$md5 = substr($Texte,$Ctr,1);
|
||||||
|
$Ctr++;
|
||||||
|
$VariableTemp.= (substr($Texte,$Ctr,1) ^ $md5);
|
||||||
|
}
|
||||||
|
return $VariableTemp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function id_user(){
|
||||||
|
// retourne une chaine identifiant l'utilisateur que l'on comparera par la suite
|
||||||
|
// cette chaine cryptée contient les variables utiles sérialisées
|
||||||
|
$id=array();
|
||||||
|
$id['REMOTE_ADDR']=$_SERVER['REMOTE_ADDR'];
|
||||||
|
$id['HTTP_USER_AGENT']=$_SERVER['HTTP_USER_AGENT'];
|
||||||
|
$id['session_id']=session_id();
|
||||||
|
$id=serialize($id);
|
||||||
|
return $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function is_ok(){
|
||||||
|
// vérifie et compare les variables de session
|
||||||
|
// en cas de problème on sort/redirige en détruisant la session
|
||||||
|
global $auto_restrict;
|
||||||
|
$expired=false;
|
||||||
|
if (isset($_COOKIE[$auto_restrict['cookie_name']])&&$_COOKIE[$auto_restrict['cookie_name']]==sha1($_SERVER['HTTP_USER_AGENT'])){return true;}
|
||||||
|
if (!isset($_SESSION['id_user'])){return false;}
|
||||||
|
if ($_SESSION['expire']<time()){$expired=true;}
|
||||||
|
$sid=Decrypte($_SESSION['id_user'],$auto_restrict['encryption_key']);
|
||||||
|
$id=id_user();
|
||||||
|
if ($sid!=$id || $expired==true){// problème
|
||||||
|
return false;
|
||||||
|
}else{ // tout va bien
|
||||||
|
//on redonne un délai à la session
|
||||||
|
$_SESSION['expire']=time()+(60*$auto_restrict['session_expiration_delay']);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function log_user($login_donne,$pass_donne){
|
||||||
|
//cree les variables de session
|
||||||
|
global $auto_restrict;
|
||||||
|
if ($auto_restrict['login']==$login_donne && $auto_restrict['pass']==hash('sha512', $auto_restrict["salt"].$pass_donne)){
|
||||||
|
$_SESSION['id_user']=Crypte(id_user(),$auto_restrict['encryption_key']);
|
||||||
|
$_SESSION['login']=$auto_restrict['login'];
|
||||||
|
$_SESSION['expire']=time()+(60*$auto_restrict['session_expiration_delay']);
|
||||||
|
return true;
|
||||||
|
}else{
|
||||||
|
|
||||||
|
exit_redirect();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function redirect_to($page){header('Location: '.$page); }
|
||||||
|
function exit_redirect(){
|
||||||
|
global $auto_restrict;
|
||||||
|
@session_unset();
|
||||||
|
@session_destroy();
|
||||||
|
setcookie($auto_restrict['cookie_name'],'',time()+1);
|
||||||
|
if ($auto_restrict['redirect_error']&&$auto_restrict['redirect_error']!=''){//tester sans la deuxième condition
|
||||||
|
redirect_to($auto_restrict['redirect_error']);
|
||||||
|
}else{exit($auto_restrict['error_msg']);}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
BIN
design/actions.png
Normal file
BIN
design/actions.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
BIN
design/favicon2.png
Normal file
BIN
design/favicon2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
design/foil.png
Normal file
BIN
design/foil.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 154 B |
BIN
design/lined_paper.png
Normal file
BIN
design/lined_paper.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
BIN
design/logo2.png
Normal file
BIN
design/logo2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.7 KiB |
BIN
design/paper.png
Normal file
BIN
design/paper.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 83 KiB |
52
design/style.css
Normal file
52
design/style.css
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
* { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; }
|
||||||
|
body {
|
||||||
|
background:url(paper.png) #efe;
|
||||||
|
width: 100%;
|
||||||
|
margin:0;padding:0;
|
||||||
|
font-family: Georgia, Serif;font-size : 16px; color: #050;
|
||||||
|
}
|
||||||
|
a:hover { color: #050;text-shadow:0 0 5px green;}
|
||||||
|
|
||||||
|
a { color: black; text-decoration: none;}
|
||||||
|
|
||||||
|
input{outline:none;-moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; height:25px;padding : 3px ; vertical-align: bottom; margin-top : 3px ;}
|
||||||
|
input[type=text]{width:80%;min-width:200px; background-color:rgba(255,255,255,0.8);border:1px solid #444;border-top-color:#333;border-bottom-color:#aaa; -moz-box-shadow: inset 0 1px 3px #000000; -webkit-box-shadow: inset 0 1px 3px #000000; box-shadow: inset 0 1px 3px #000000; #000}
|
||||||
|
input[type=text]:hover{background-color:rgba(200,255,200,0.8);-moz-box-shadow: inset 0 1px 3px #040; -webkit-box-shadow: inset 0 1px 3px #040; box-shadow: inset 0 1px 3px #040; }
|
||||||
|
input[type=text]:focus{background-color:rgba(200,255,200,0.9);-moz-box-shadow: inset 0 0 3px #040; -webkit-box-shadow: inset 0 0 3px #040; box-shadow: inset 0 0 3px #040; }
|
||||||
|
input[type=submit]{cursor: pointer; border:1px solid #494;border-bottom-color:#272;border-top-color:#afa; background-color:rgba(0,200,0,0.8); -moz-box-shadow: 0 1px 2px #080; -webkit-box-shadow: 0 1px 2px #080; box-shadow: 0 1px 2px #080; -ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=2, Direction=135, Color='#000')"; filter: progid:DXImageTransform.Microsoft.Shadow(Strength=2, Direction=135, Color='#000'); }
|
||||||
|
input[type=submit]:hover{ background-color:rgba(0,255,0,0.8);}
|
||||||
|
input[type=submit]:active{border-color:black; background-color:rgba(0,255,0,0.8);}
|
||||||
|
#____q{margin-top:20px;}
|
||||||
|
header{
|
||||||
|
-webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;
|
||||||
|
border-bottom:1px solid #222;
|
||||||
|
-moz-box-shadow: 0 1px 3px #888; -webkit-box-shadow: 0 1px 3px #888; box-shadow: 0 1px 3px #888; -ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=2, Direction=135, Color='#888')"; filter: progid:DXImageTransform.Microsoft.Shadow(Strength=2, Direction=135, Color='#888');
|
||||||
|
padding : 10px ; width: 100%; height:auto;margin: 0;
|
||||||
|
text-align: left;box-shadow: 0 1px 2px;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr = #555, endColorstr = #333); -ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr = #555, endColorstr = #333)";
|
||||||
|
background-image: -moz-linear-gradient( top, #555, #333); background-image: -ms-linear-gradient( top, #555, #333);
|
||||||
|
background-image: -o-linear-gradient( top, #555, #333); background-image: -webkit-gradient(linear, center top, center bottom, from(#555), to(#333)); background-image: -webkit-linear-gradient( top, #555, #333); background-image: linear-gradient( top, #555, #333);
|
||||||
|
}
|
||||||
|
header nav{display:inline-block; vertical-align: top;}
|
||||||
|
|
||||||
|
aside{height:100%;padding-bottom : 70px;text-align:center;}
|
||||||
|
aside ul{padding:0;}
|
||||||
|
aside li{margin:5px;list-style:none;vertical-align:middle;border-radius:3px;}
|
||||||
|
aside .public li{background:rgba(100,255,100,0.2);}
|
||||||
|
aside .private li{background:rgba(255,100,100,0.2);}
|
||||||
|
aside li em {font-size:10px ; color:#484;}
|
||||||
|
aside li img {vertical-align:bottom;margin:1px;width:16px;height:16px;}
|
||||||
|
aside li a.suppr, aside li a.origine{opacity:0.5;width:16px;height:16px;display:inline-block;background:url(actions.png) no-repeat 0 -159px ;}
|
||||||
|
aside li a.origine{background-position: 0 -396px ;}
|
||||||
|
aside li a.suppr:hover,aside li a.origine:hover{opacity:1;}
|
||||||
|
aside li a.toprivate,aside li a.topublic{float:right;margin-right:5px;opacity:0.5;}
|
||||||
|
aside li a.toprivate:hover,aside li a.topublic:hover{opacity:1;}
|
||||||
|
|
||||||
|
aside .public,.private{text-align:left;vertical-align:top; margin-top:25px;padding:10px; border-radius:5px; border:1px dashed;display:inline-block;width:45%;}
|
||||||
|
aside .public{border-color:green;}
|
||||||
|
aside .private{border-color:red;}
|
||||||
|
footer {text-align: right; color:#F80;text-shadow: 0 1px 1px black; position:fixed;bottom:0;left:0;right:0;height:auto;min-height:20px;padding : 5px ; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; border-top:1px solid #888;-moz-box-shadow: 0 0px 9px #000; -webkit-box-shadow: 0 0px 9px #000; box-shadow: 0 0px 9px #000; -ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=9, Direction=135, Color='#000')"; filter: progid:DXImageTransform.Microsoft.Shadow(Strength=9, Direction=135, Color='#000'); filter: progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr = #555, endColorstr = #333); -ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr = #555, endColorstr = #333)"; background-image: -moz-linear-gradient( top, #555, #333); background-image: -ms-linear-gradient( top, #555, #333); background-image: -o-linear-gradient( top, #555, #333); background-image: -webkit-gradient(linear, center top, center bottom, from(#555), to(#333)); background-image: -webkit-linear-gradient( top, #555, #333); background-image: linear-gradient( top, #555, #333); }
|
||||||
|
footer p {margin:0;padding:0;color:lightgreen;text-shadow:0 1px 1px green;}
|
||||||
|
footer a {color:lightgreen;text-shadow:0 1px 1px green;}
|
||||||
|
footer a:hover {color:white;}
|
||||||
|
|
619
index.php
Normal file
619
index.php
Normal file
|
@ -0,0 +1,619 @@
|
||||||
|
<?php
|
||||||
|
if (isset($_GET['public'])){$public=true;}else{$public=false;include 'auto_restrict.php';}
|
||||||
|
|
||||||
|
/* (webpage retriever by Timo Van Neerden; http://lehollandaisvolant.net/contact December 2012)
|
||||||
|
* last updated : December, 10th, 2012
|
||||||
|
*
|
||||||
|
* This piece of software is under the WTF Public Licence.
|
||||||
|
* Everyone is permitted to copy and distribute verbatim or modified
|
||||||
|
* copies of this program, under the following terms of the WFTPL :
|
||||||
|
*
|
||||||
|
* DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||||
|
* TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
*
|
||||||
|
* 0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* all the enhancements (logo, css, session lock, bookmarklet) are from Bronco (www.warriordudimanche.net)
|
||||||
|
* and are based on the same licence ;)
|
||||||
|
* thanks a lot to Timo for his great job on this app ;) */
|
||||||
|
|
||||||
|
// PHP 5.1.2 minimum required
|
||||||
|
|
||||||
|
error_reporting(-1);
|
||||||
|
date_default_timezone_set('UTC');
|
||||||
|
// CONFIGURABLE OPTIONS
|
||||||
|
// change those directories'names for more security
|
||||||
|
$GLOBALS['data_folder'] = 'mypersonaldata';
|
||||||
|
$GLOBALS['private_data_folder'] = $GLOBALS['data_folder'].'/private';
|
||||||
|
$GLOBALS['public_data_folder'] = $GLOBALS['data_folder'].'/public';
|
||||||
|
$GLOBALS['default_data_folder'] = $GLOBALS['public_data_folder'];
|
||||||
|
$GLOBAL['version']='1.0';
|
||||||
|
$GLOBALS['message'] = 'Votre webliothèque perso';
|
||||||
|
$bookmarklet='<a title="Drag this link to your shortcut bar" href=\'javascript:javascript:(function(){var url = location.href;window.open("http://'.$_SERVER['SERVER_NAME'].$_SERVER['PHP_SELF'].'?q="+ encodeURIComponent(url),"_blank","menubar=yes,height=600,width=1000,toolbar=yes,scrollbars=yes,status=yes");})();\' >Bookmarklet</a>';
|
||||||
|
if ($public){$bookmarklet='';}
|
||||||
|
if (!creer_dossier($GLOBALS['data_folder'], TRUE)) { die('Cant create '.$GLOBALS['data_folder'].' folder.'); }
|
||||||
|
if (!creer_dossier($GLOBALS['private_data_folder'], TRUE)) { die('Cant create '.$GLOBALS['private_data_folder'].' folder.'); }
|
||||||
|
if (!creer_dossier($GLOBALS['public_data_folder'], TRUE)) { die('Cant create '.$GLOBALS['public_data_folder'].' folder.'); }
|
||||||
|
|
||||||
|
//
|
||||||
|
// BEGIN SCRIPT
|
||||||
|
//
|
||||||
|
|
||||||
|
#TODO
|
||||||
|
/*
|
||||||
|
- remplacer les liens relatifs par les liens absolus (ne chercher que les liens relatifs, uri)
|
||||||
|
- gestion des pages DL (classement ?)
|
||||||
|
- gestion de la taille max des fichiers à télélcharger
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// init
|
||||||
|
// url not yet retrieved
|
||||||
|
$GLOBALS['done']['d'] = FALSE;
|
||||||
|
if (!$public){
|
||||||
|
// Get URL to save.
|
||||||
|
if (!empty($_GET['q'])) {
|
||||||
|
|
||||||
|
|
||||||
|
$url = htmlspecialchars($_GET['q']);
|
||||||
|
if (strpos($url, '://') === false) {
|
||||||
|
$url = 'http://'.$url;
|
||||||
|
}
|
||||||
|
$GLOBALS['url'] = $url;
|
||||||
|
$url_p = url_parts();
|
||||||
|
|
||||||
|
// retrieve the file main HTML file
|
||||||
|
|
||||||
|
$GLOBALS['main_page_data'] = get_external_file($GLOBALS['url'], 6);
|
||||||
|
|
||||||
|
|
||||||
|
if ($GLOBALS['main_page_data'] === FALSE) {
|
||||||
|
die('error retrieving external main page');
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
// crée le nouveau dossier basé sur le TS.
|
||||||
|
$new_folder = date('Y-m-d-H-i-s');
|
||||||
|
if (!creer_dossier($GLOBALS['default_data_folder'].'/'.$new_folder) === TRUE ) {
|
||||||
|
die('error creating data folder');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$GLOBALS['target_folder'] = $GLOBALS['default_data_folder'].'/'.$new_folder;
|
||||||
|
}
|
||||||
|
$liste_css = array();
|
||||||
|
// parse le fichier principal à la recherche de données à télécharger
|
||||||
|
$files = list_retrievable_data($GLOBALS['url'], $GLOBALS['main_page_data']);
|
||||||
|
// les récupère et les enregistre.
|
||||||
|
//echo '<pre>';print_r($files);die();
|
||||||
|
foreach ($files as $i => $file) {
|
||||||
|
if ($data = get_external_file($file['url_fichier'], 3) and ($data !== FALSE) ) {
|
||||||
|
// CSS files need to be parsed aswell
|
||||||
|
if ($file['type'] == 'css') {
|
||||||
|
$liste_css[] = $file;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
file_put_contents($GLOBALS['target_folder'].'/'.$file['nom_destination'], $data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// remplace juste les liens <a href=""> relatifs vers des liens absolus
|
||||||
|
absolutes_links($GLOBALS['main_page_data']);
|
||||||
|
|
||||||
|
// enregistre le fichier HTML principal
|
||||||
|
file_put_contents($GLOBALS['target_folder'].'/'.'index.html', $GLOBALS['main_page_data']);
|
||||||
|
|
||||||
|
// récupère le titre de la page
|
||||||
|
// cherche le charset spécifié dans le code HTML.
|
||||||
|
// récupère la balise méta tout entière, dans $meta
|
||||||
|
preg_match('#<meta .*charset=.*>#Usi', $GLOBALS['main_page_data'], $meta);
|
||||||
|
|
||||||
|
// si la balise a été trouvée, on tente d’isoler l’encodage.
|
||||||
|
if (!empty($meta[0])) {
|
||||||
|
// récupère juste l’encodage utilisé, dans $enc
|
||||||
|
preg_match('#charset="?(.*)"#si', $meta[0], $enc);
|
||||||
|
// regarde si le charset a été trouvé, sinon le fixe à UTF-8
|
||||||
|
$html_charset = (!empty($enc[1])) ? strtolower($enc[1]) : 'utf-8';
|
||||||
|
} else { $html_charset = 'utf-8'; }
|
||||||
|
// récupère le titre, dans le tableau $titles, rempli par preg_match()
|
||||||
|
preg_match('#<title>(.*)</title>#Usi', $GLOBALS['main_page_data'], $titles);
|
||||||
|
if (!empty($titles[1])) {
|
||||||
|
$html_title = trim($titles[1]);
|
||||||
|
// ré-encode le titre en UTF-8 en fonction de son encodage.
|
||||||
|
$title = ($html_charset == 'iso-8859-1') ? utf8_encode($html_title) : $html_title;
|
||||||
|
// si pas de titre : on utilise l’URL.
|
||||||
|
} else {
|
||||||
|
$title = $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// récupère, parse, modifie & enregistre les fichier CSS (et les fichiés liés)
|
||||||
|
$n = 0;
|
||||||
|
$count = count($liste_css);
|
||||||
|
while ( $n < $count ) {
|
||||||
|
$i = $n;
|
||||||
|
$file = $liste_css[$i];
|
||||||
|
if ($data = get_external_file($file['url_fichier'], 3) and ($data !== FALSE) ) {
|
||||||
|
if (preg_match('#(css|php|txt|html|xml|js)#', $file['url_fichier']) ) {
|
||||||
|
|
||||||
|
$matches_url = array();
|
||||||
|
preg_match_all('#url\s*\(("|\')?([^\'")]*)(\'|")?\)#i', $data, $matches_url, PREG_SET_ORDER);
|
||||||
|
$matches_url2 = array();
|
||||||
|
preg_match_all('#@import\s*(url\()?["\']?([^\'"\(\);]*)["\']?\)?([^;]*);#i', $data, $matches_url2, PREG_SET_ORDER);
|
||||||
|
|
||||||
|
$matches_url = array_merge($matches_url2, $matches_url);
|
||||||
|
|
||||||
|
// pour chaque URL/URI
|
||||||
|
foreach ($matches_url as $j => $valuej) {
|
||||||
|
|
||||||
|
if (preg_match('#^data:#', $matches_url[$j][2])) break; // if BASE64 data, dont download.
|
||||||
|
|
||||||
|
// get the filenam (basename)
|
||||||
|
$nom_fichier = (preg_match('#^(ht|f)tps?://#', $matches_url[$j][2])) ? pathinfo(parse_url($matches_url[$j][2], PHP_URL_PATH), PATHINFO_BASENAME) : pathinfo($matches_url[$j][2], PATHINFO_BASENAME);
|
||||||
|
|
||||||
|
// get the URL. For URIs, uses the GLOBALS[url] tu make the URL
|
||||||
|
// the files in CSS are relative to the CSS !
|
||||||
|
if (preg_match('#^https?://#', $matches_url[$j][2])) {
|
||||||
|
$url_fichier = $matches_url[$j][2];
|
||||||
|
}
|
||||||
|
elseif (preg_match('#^/#', $matches_url[$j][2])) {
|
||||||
|
$url_fichier = $url_p['s'].'://'.$url_p['h'].$matches_url[$j][2];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$url_fichier = substr($file['url_fichier'], 0, -strlen($file['nom_fich_origine'])).$matches_url[$j][2];
|
||||||
|
}
|
||||||
|
// new rand name, for local storage.
|
||||||
|
$nouveau_nom = rand_new_name($nom_fichier);
|
||||||
|
$add = TRUE;
|
||||||
|
|
||||||
|
// avoids downloading the same file twice. (yes, we re-use the same $retrievable ($files), why not ?)
|
||||||
|
foreach ($files as $key => $item) {
|
||||||
|
if ($item['url_fichier'] == $url_fichier) {
|
||||||
|
$nouveau_nom = $item['nom_destination'];
|
||||||
|
$add = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we do download, add it to the array.
|
||||||
|
if ($add === TRUE) {
|
||||||
|
$files_n = array(
|
||||||
|
'url_origine' => $matches_url[$j][2],
|
||||||
|
'url_fichier' => $url_fichier,
|
||||||
|
'nom_fich_origine' => $nom_fichier,
|
||||||
|
'nom_destination' => $nouveau_nom
|
||||||
|
);
|
||||||
|
$files[] = $files_n;
|
||||||
|
$liste_css[] = $files_n;
|
||||||
|
}
|
||||||
|
|
||||||
|
// replace url in CSS $data
|
||||||
|
$data = str_replace($matches_url[$j][2], $nouveau_nom, $data);
|
||||||
|
// echo $nouveau_nom."<br>\n";
|
||||||
|
|
||||||
|
if (!preg_match('#(css|php|txt|html)#', $file['url_fichier']) ) {
|
||||||
|
if (FALSE !== ($f = get_external_file($url_fichier, 3)) ) {
|
||||||
|
file_put_contents($GLOBALS['target_folder'].'/'.$nouveau_nom, $f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't forget to save data
|
||||||
|
file_put_contents($GLOBALS['target_folder'].'/'.$file['nom_destination'], $data);
|
||||||
|
}
|
||||||
|
$n++;
|
||||||
|
$count = count($liste_css);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// enregistre un fichier d’informations concernant la page (date, url, titre)
|
||||||
|
$info = '';
|
||||||
|
$info .= 'URL="'.$GLOBALS['url'].'"'."\n";
|
||||||
|
$info .= 'TITLE="'.$title.'"'."\n";
|
||||||
|
$info .= 'DATE="'.time().'"'."\n";
|
||||||
|
|
||||||
|
file_put_contents($GLOBALS['target_folder'].'/'.'index.ini', $info);
|
||||||
|
|
||||||
|
//
|
||||||
|
$GLOBALS['done']['d'] = 'ajout';
|
||||||
|
$GLOBALS['done']['lien'] = $GLOBALS['target_folder'].'/';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// in case of delete an entry
|
||||||
|
if (isset($_GET['suppr']) and $torem = $_GET['suppr'] and $torem != '') {
|
||||||
|
$torem = htmlspecialchars($_GET['suppr']);
|
||||||
|
/*
|
||||||
|
$liste = scandir($GLOBALS['data_folder']); // listage des dossiers de data.
|
||||||
|
$nb_fichier = count($liste);
|
||||||
|
for ($i = 0 ; $i < $nb_fichier ; $i++) {
|
||||||
|
if ($liste[$i] == $torem and !($liste[$i] == '..' or $liste[$i] == '.')) {*/
|
||||||
|
|
||||||
|
// the folder exists and can be removed:
|
||||||
|
|
||||||
|
|
||||||
|
// included files first (noway doing it like "rmdir -R" :/)
|
||||||
|
|
||||||
|
if (is_dir($_GET['suppr'])){
|
||||||
|
$sousliste = scandir($_GET['suppr']); // listage des dossiers de data.
|
||||||
|
$nb_sousfichier = count($sousliste);
|
||||||
|
for ($j = 0 ; $j < $nb_sousfichier ; $j++) {
|
||||||
|
if (!($sousliste[$j] == '..' or $sousliste[$j] == '.')) {
|
||||||
|
unlink($_GET['suppr'].'/'.$sousliste[$j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// then the folder itself.
|
||||||
|
if (TRUE === rmdir($_GET['suppr'])) {
|
||||||
|
$GLOBALS['done']['d'] = 'remove';
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
header("location: index.php");
|
||||||
|
}
|
||||||
|
|
||||||
|
// to private
|
||||||
|
if (isset($_GET['toprivate']) and $torem = $_GET['toprivate'] and $torem != '') {
|
||||||
|
$torem = htmlspecialchars($_GET['toprivate']);
|
||||||
|
if (is_dir($GLOBALS['public_data_folder'].'/'.$_GET['toprivate'])){
|
||||||
|
rename ($GLOBALS['public_data_folder'].'/'.$_GET['toprivate'],$GLOBALS['private_data_folder'].'/'.$_GET['toprivate']);
|
||||||
|
header("location: index.php");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// to public
|
||||||
|
if (isset($_GET['topublic']) and $torem = $_GET['topublic'] and $torem != '') {
|
||||||
|
$torem = htmlspecialchars($_GET['topublic']);
|
||||||
|
if (is_dir($GLOBALS['private_data_folder'].'/'.$_GET['topublic'])){
|
||||||
|
rename ($GLOBALS['private_data_folder'].'/'.$_GET['topublic'],$GLOBALS['public_data_folder'].'/'.$_GET['topublic']);
|
||||||
|
header("location: index.php");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // end of private admin acces
|
||||||
|
|
||||||
|
function url_parts() {
|
||||||
|
$url_p['s'] = parse_url($GLOBALS['url'], PHP_URL_SCHEME); $url_p['s'] = (is_null($url_p['s'])) ? '' : $url_p['s'];
|
||||||
|
$url_p['h'] = parse_url($GLOBALS['url'], PHP_URL_HOST); $url_p['h'] = (is_null($url_p['h'])) ? '' : $url_p['h'];
|
||||||
|
$url_p['p'] = parse_url($GLOBALS['url'], PHP_URL_PORT); $url_p['p'] = (is_null($url_p['p'])) ? '' : ':'.$url_p['p'];
|
||||||
|
$url_p['pat'] = parse_url($GLOBALS['url'], PHP_URL_PATH); $url_p['pat'] = (is_null($url_p['pat'])) ? '' : $url_p['pat'];
|
||||||
|
$url_p['file'] = pathinfo($url_p['pat'], PATHINFO_BASENAME);
|
||||||
|
return $url_p;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Gets external file by URL.
|
||||||
|
// Make a stream context (better).
|
||||||
|
//
|
||||||
|
|
||||||
|
function get_external_file($url, $timeout) {
|
||||||
|
$context = stream_context_create(array('http'=>array('timeout' => $timeout))); // Timeout : time until we stop waiting for the response.
|
||||||
|
$data = @file_get_contents($url, false, $context, -1, 4000000); // We download at most 4 Mb from source.
|
||||||
|
if (isset($data) and isset($http_response_header) and isset($http_response_header[0]) and (strpos($http_response_header[0], '200 OK') !== FALSE) ) {
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// CREATE FOLDER
|
||||||
|
//
|
||||||
|
|
||||||
|
function creer_dossier($dossier, $indexfile = FALSE) {
|
||||||
|
if ( !is_dir($dossier) ) {
|
||||||
|
if (mkdir($dossier, 0777, TRUE) === TRUE) {
|
||||||
|
chmod($dossier, 0777);
|
||||||
|
if ($indexfile == TRUE) touch($dossier.'/index.html'); // make a index.html file : avoid the possibility of listing folder's content
|
||||||
|
return TRUE;
|
||||||
|
} else {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE; // if folder already exists
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// PARSE TAGS AND LISTE DOWNLOADABLE CONTENT IN ARRAY
|
||||||
|
// Also modify html source code to replace absolutes URLs with local URIs.
|
||||||
|
//
|
||||||
|
|
||||||
|
function list_retrievable_data($url, &$data) {
|
||||||
|
$url_p = url_parts();
|
||||||
|
|
||||||
|
$retrievable = array();
|
||||||
|
|
||||||
|
// cherche les balises 'link' qui contiennent un rel="(icon|favicon|stylesheet)" et un href=""
|
||||||
|
// (on ne cherche pas uniquement le "href" sinon on se retrouve avec les flux RSS aussi)
|
||||||
|
$matches = array();
|
||||||
|
preg_match_all('#<\s*link[^>]+rel=["\'][^"\']*(icon|favicon|stylesheet)[^"\']*["\'][^>]*>#Si', $data, $matches, PREG_SET_ORDER);
|
||||||
|
// dans les link avec une icone, stylesheet, etc récupère l’url.
|
||||||
|
foreach($matches as $i => $key) {
|
||||||
|
$type = (strpos($key[1], 'stylesheet') !== FALSE) ? 'css' : 'other';
|
||||||
|
if ( (preg_match_all('#(href|src)=["\']([^"\']*)["\']#i', $matches[$i][0], $matches_attr, PREG_SET_ORDER) === 1) ) {
|
||||||
|
$retrievable = add_table_and_replace($data, $retrievable, $matches[$i][0], $matches_attr[0][2], $url_p, $type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// recherche les images, scripts, audio & videos HTML5.
|
||||||
|
// dans les balises, récupère l’url/uri contenue dans les src="".
|
||||||
|
// le fichier sera téléchargé.
|
||||||
|
// Le nom du fichier sera modifié pour être unique, et sera aussi modifié dans le code source.
|
||||||
|
$matches = array();
|
||||||
|
preg_match_all('#<\s*(source|audio|img|script|video)[^>]+src="([^"]*)"[^>]*>#Si', $data, $matches, PREG_SET_ORDER);
|
||||||
|
|
||||||
|
foreach($matches as $i => $key) {
|
||||||
|
if (preg_match('#^data:#', $matches[$i][2])) break;
|
||||||
|
$retrievable = add_table_and_replace($data, $retrievable, $matches[$i][0], $matches[$i][2], $url_p, 'other');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dans les balises <style>, remplace les url() et src()
|
||||||
|
$matches = array();
|
||||||
|
preg_match_all('#<\s*style[^>]*>(.*?)<\s*/\s*style[^>]*>#is', $data, $matches, PREG_SET_ORDER);
|
||||||
|
|
||||||
|
// pour chaque élement <style>
|
||||||
|
foreach($matches as $i => $value) {
|
||||||
|
$matches_url = array();
|
||||||
|
preg_match_all('#url\s*\(("|\')?([^\'")]*)(\'|")?\)#i', $matches[$i][1], $matches_url, PREG_SET_ORDER);
|
||||||
|
|
||||||
|
// pour chaque URL/URI
|
||||||
|
foreach ($matches_url as $j => $valuej) {
|
||||||
|
if (preg_match('#^data:#', $matches_url[$j][2])) break;
|
||||||
|
$retrievable = add_table_and_replace($data, $retrievable, $matches[$i][1], $matches_url[$j][2], $url_p, 'other');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// recherche les url dans les CSS inlines.
|
||||||
|
$matches = array();
|
||||||
|
// pour chaque élement contenant un style=""
|
||||||
|
preg_match_all('#<\s*[^>]+style="([^"]*url\s*\(([^)]*)\)[^"]*)"[^>]*>+#is', $data, $matches, PREG_SET_ORDER);
|
||||||
|
foreach($matches as $i => $value) {
|
||||||
|
$matches_url = array();
|
||||||
|
|
||||||
|
// pour chaque URL/URI trouvé
|
||||||
|
preg_match_all('#url\s*\(("|\')?([^\'")]*)(\'|")?\)#i', $matches[$i][1], $matches_url, PREG_SET_ORDER);
|
||||||
|
|
||||||
|
foreach ($matches_url as $j => $valuej) {
|
||||||
|
if (preg_match('#^data:#', $matches_url[$j][2])) break; // if BASE64 data, dont download.
|
||||||
|
$retrievable = add_table_and_replace($data, $retrievable, $matches[$i][1], $matches_url[$j][2], $url_p, 'other');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $retrievable;
|
||||||
|
}
|
||||||
|
|
||||||
|
function absolutes_links(&$data) {
|
||||||
|
$url_p = url_parts();
|
||||||
|
// cherche les balises 'a' qui contiennent un href
|
||||||
|
$matches = array();
|
||||||
|
preg_match_all('#<\s*a[^>]+href=["\'](([^"\']*))["\'][^>]*>#Si', $data, $matches, PREG_SET_ORDER);
|
||||||
|
|
||||||
|
// ne conserve que les liens ne commençant pas par un protocole « protocole:// » ni par une ancre « # »
|
||||||
|
foreach($matches as $i => $link) {
|
||||||
|
$link[1] = trim($link[1]);
|
||||||
|
if (!preg_match('#^(([a-z]+://)|(\#))#', $link[1]) ) {
|
||||||
|
|
||||||
|
// absolute path w/o HTTP : add http.
|
||||||
|
if (preg_match('#^//#', $link[1])) {
|
||||||
|
$matches[$i][1] = $url_p['s'].':'.$link[1];
|
||||||
|
}
|
||||||
|
// absolute local path : add http://domainname.tld
|
||||||
|
elseif (preg_match('#^/#', $link[1])) {
|
||||||
|
$matches[$i][1] = $url_p['s'].'://'.$url_p['h'].$link[1];
|
||||||
|
}
|
||||||
|
// relative local path : add http://domainename.tld/path/
|
||||||
|
else {
|
||||||
|
$uuu = (strlen($url_p['file']) == 0 or preg_match('#/$#', $url_p['pat'])) ? $GLOBALS['url'] : substr($GLOBALS['url'], 0, -strlen($url_p['file'])) ;
|
||||||
|
|
||||||
|
$matches[$i][1] = $uuu.$link[1];
|
||||||
|
}
|
||||||
|
$new_match = str_replace($matches[$i][2], $matches[$i][1], $matches[$i][0]);
|
||||||
|
$data = str_replace($matches[$i][0], $new_match, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function add_table_and_replace(&$data, $retrievable, &$match1, $match, $url_p, $type) {
|
||||||
|
// get the filenam (basename)
|
||||||
|
$nom_fichier = (preg_match('#^https?://#', $match)) ? pathinfo(parse_url($match, PHP_URL_PATH), PATHINFO_BASENAME) : pathinfo($match, PATHINFO_BASENAME);
|
||||||
|
// get the URL. For relatives URL, uses the GLOBALS[url] tu make the complete URL
|
||||||
|
// the files in CSS are relative to the CSS !
|
||||||
|
if (preg_match('#^https?://#', $match)) { // url
|
||||||
|
$url_fichier = $match;
|
||||||
|
//echo "u ";
|
||||||
|
}
|
||||||
|
elseif (preg_match('#^//#', $match)) { // absolute path w/o HTTP
|
||||||
|
$url_fichier = $url_p['s'].':'.$match;
|
||||||
|
//echo "h ";
|
||||||
|
}
|
||||||
|
elseif (preg_match('#^/#', $match)) { // absolute local path
|
||||||
|
$url_fichier = $url_p['s'].'://'.$url_p['h'].$match;
|
||||||
|
//echo "l ";
|
||||||
|
}
|
||||||
|
else { // relative local path
|
||||||
|
//echo "r ";
|
||||||
|
// echo '<pre>';print_r($url_p);
|
||||||
|
$uuu = (strlen($url_p['file']) == 0 or preg_match('#/$#', $url_p['pat'])) ? $GLOBALS['url'] : substr($GLOBALS['url'], 0, -strlen($url_p['file'])) ;
|
||||||
|
|
||||||
|
// echo '<pre>'; echo $uuu;
|
||||||
|
$url_fichier = $uuu . substr($match, 0, -strlen($nom_fichier)).$nom_fichier;
|
||||||
|
}
|
||||||
|
|
||||||
|
$url_fichier = html_entity_decode(urldecode($url_fichier));
|
||||||
|
//echo $url_fichier."<br/>\n";
|
||||||
|
|
||||||
|
|
||||||
|
// new rand name, for local storage.
|
||||||
|
$nouveau_nom = rand_new_name($nom_fichier);
|
||||||
|
if ($type == 'css') {
|
||||||
|
$nouveau_nom = $nouveau_nom.'.css';
|
||||||
|
}
|
||||||
|
$add = TRUE;
|
||||||
|
|
||||||
|
// avoids downloading the same file twice.
|
||||||
|
foreach ($retrievable as $key => $item) {
|
||||||
|
if ($item['url_fichier'] == $url_fichier) {
|
||||||
|
$nouveau_nom = $item['nom_destination'];
|
||||||
|
$add = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we do want to download it, we add to the array.
|
||||||
|
if ($add === TRUE) {
|
||||||
|
$retrievable[] = array(
|
||||||
|
'url_origine' => $match,
|
||||||
|
'url_fichier' => $url_fichier,
|
||||||
|
'nom_fich_origine' => $nom_fichier,
|
||||||
|
'nom_destination' => $nouveau_nom,
|
||||||
|
'type' => $type
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// replace the URL with the new filename in the &data.
|
||||||
|
$new_match = str_replace($match, $nouveau_nom, $match1);
|
||||||
|
$data = str_replace($match1, $new_match, $data);
|
||||||
|
$match1 = $new_match;
|
||||||
|
|
||||||
|
return $retrievable;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function rand_new_name($name) {
|
||||||
|
// return 'f_'.str_shuffle('abcd').mt_rand(100, 999).'--'.''.$name;
|
||||||
|
return 'f_'.str_shuffle('abcd').mt_rand(100, 999).'--'.preg_replace('#[^\w.]#', '_', $name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ($GLOBALS['done']['d'] !== FALSE) {
|
||||||
|
switch($GLOBALS['done']['d']) {
|
||||||
|
|
||||||
|
case 'ajout' :
|
||||||
|
header('Location: index.php?done='.$GLOBALS['done']['d'].'&lien='.urlencode($GLOBALS['url']).'&loclink='.urlencode($GLOBALS['done']['lien']));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'remove' :
|
||||||
|
header('Location: index.php?done='.$GLOBALS['done']['d']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
echo '</div>'."\n";
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Displays main form (page to retrieve)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
echo '<!DOCTYPE html>'."\n";
|
||||||
|
echo '<html>'."\n";
|
||||||
|
echo "\t".'<head>'."\n";
|
||||||
|
echo "\t".'<meta charset="utf-8" /></head>'."\n";
|
||||||
|
echo "\t".'<title>Respawn – a PHP WebPage Saver</title>'."\n";
|
||||||
|
echo "\t".'<link rel="stylesheet" type="text/css" href="design/style.css"/>'."\n";
|
||||||
|
echo "\t".'<link rel="shortcut icon" type="/image/png" href="design/favicon2.png">'."\n";
|
||||||
|
echo "\t".'<!--[if IE]><script> document.createElement("article");document.createElement("aside");document.createElement("section");document.createElement("footer");</script> <![endif]-->
|
||||||
|
'."\n";
|
||||||
|
echo '</head>'."\n";
|
||||||
|
echo '<body>'."\n";
|
||||||
|
echo "\t<header>".'<a href="'.$_SERVER['PHP_SELF'].'"><img src="design/logo2.png"/></a>'."\n";
|
||||||
|
if (!$public){
|
||||||
|
echo '<nav id="orpx_nav-bar">'."\n";
|
||||||
|
echo "\t".'<form method="get" action="'.$_SERVER['PHP_SELF'].'" style="text-align:center">'."\n";
|
||||||
|
|
||||||
|
echo "\t\t".'<input id="____q" type="text" size="70" name="q" value="" placeholder="URL from the page to download" />'."\n";
|
||||||
|
echo "\t\t".'<input type="submit" value="Retrieve"/>'."\n";
|
||||||
|
echo "\t".'</form>'."\n";
|
||||||
|
}
|
||||||
|
echo '</nav></header>'."\n";
|
||||||
|
echo '<aside>'."\n";
|
||||||
|
|
||||||
|
if (!$public){
|
||||||
|
if (isset($_GET['done']) and $_GET['done'] !== FALSE) {
|
||||||
|
echo '<div id="new-link">'."\n";
|
||||||
|
switch($_GET['done']) {
|
||||||
|
case 'ajout' :
|
||||||
|
echo "\t".'<a target="_blanc" href="'.urldecode($_GET['loclink']).'">Retrieved page</a> - (<a href="'.htmlspecialchars(urldecode($_GET['lien'])).'">orig. page</a>)' ."\n";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'remove' :
|
||||||
|
echo "\t".'Page removed'."\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
echo '</div>'."\n";
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo '<div class="public">'."\n";
|
||||||
|
$liste_pages = scandir($GLOBALS['public_data_folder']);
|
||||||
|
if ( ($nb = count($liste_pages)) != 0 ) {
|
||||||
|
echo '<ul id="liste-pages-sauvees">'."\n";
|
||||||
|
|
||||||
|
for ($i = 0 ; $i < $nb ; $i++) {
|
||||||
|
// dont list '.' and '..' folders.
|
||||||
|
if (is_dir($GLOBALS['public_data_folder'].'/'.$liste_pages[$i]) and ($liste_pages[$i] != '.') and ($liste_pages[$i] != '..')) {
|
||||||
|
// each folder should contain such a file "index.ini".
|
||||||
|
$ini_file = $GLOBALS['public_data_folder'].'/'.$liste_pages[$i].'/index.ini';
|
||||||
|
$favicon=glob($GLOBALS['public_data_folder'].'/'.$liste_pages[$i].'/*favicon.*');
|
||||||
|
if (!empty($favicon)){$favicon=$favicon[0];}
|
||||||
|
if ( is_file($ini_file) and is_readable($ini_file) ) {
|
||||||
|
$infos = parse_ini_file($ini_file);
|
||||||
|
} else {
|
||||||
|
$infos = FALSE;
|
||||||
|
}
|
||||||
|
if (FALSE !== $infos) {
|
||||||
|
$titre = $infos['TITLE']; $url = $infos['URL']; $date = date('d/m/Y, H:i:s', $infos['DATE']);
|
||||||
|
} else {
|
||||||
|
$titre = 'titre'; $url = '#'; $date = 'date inconnue';
|
||||||
|
}
|
||||||
|
echo "\t".'<li><a class="suppr" onclick="return window.confirm(\'Sure to remove?\')" href="?suppr='.$GLOBALS['public_data_folder'].'/'.$liste_pages[$i].'" title="suppr"> </a><a class="origine" href="'.$url.'" title="origin"> </a> - <a href="'.$GLOBALS['public_data_folder'].'/'.$liste_pages[$i].'"><img src="'.$favicon.'"/>'.$titre.'</a> <em> ['.$date.']</em><a href="?toprivate='.$liste_pages[$i].'" class="toprivate" title="Change to private">▶</a></li>'."\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo '</ul>'."\n";
|
||||||
|
}
|
||||||
|
echo '</div>'."\n";
|
||||||
|
if (!$public){ // don't list private pages
|
||||||
|
echo '<div class="private">'."\n";
|
||||||
|
$liste_pages = scandir($GLOBALS['private_data_folder']);
|
||||||
|
if ( ($nb = count($liste_pages)) != 0 ) {
|
||||||
|
echo '<ul id="liste-pages-sauvees">'."\n";
|
||||||
|
|
||||||
|
for ($i = 0 ; $i < $nb ; $i++) {
|
||||||
|
// dont list '.' and '..' folders.
|
||||||
|
if (is_dir($GLOBALS['private_data_folder'].'/'.$liste_pages[$i]) and ($liste_pages[$i] != '.') and ($liste_pages[$i] != '..')) {
|
||||||
|
// each folder should contain such a file "index.ini".
|
||||||
|
$ini_file = $GLOBALS['private_data_folder'].'/'.$liste_pages[$i].'/index.ini';
|
||||||
|
$favicon=glob($GLOBALS['private_data_folder'].'/'.$liste_pages[$i].'/*favicon.*');
|
||||||
|
if (!empty($favicon)){$favicon=$favicon[0];}
|
||||||
|
if ( is_file($ini_file) and is_readable($ini_file) ) {
|
||||||
|
$infos = parse_ini_file($ini_file);
|
||||||
|
} else {
|
||||||
|
$infos = FALSE;
|
||||||
|
}
|
||||||
|
if (FALSE !== $infos) {
|
||||||
|
$titre = $infos['TITLE']; $url = $infos['URL']; $date = date('d/m/Y, H:i:s', $infos['DATE']);
|
||||||
|
} else {
|
||||||
|
$titre = 'titre'; $url = '#'; $date = 'date inconnue';
|
||||||
|
}
|
||||||
|
echo "\t".'<li><a class="suppr" onclick="return window.confirm(\'Sure to remove?\')" href="?suppr='.$GLOBALS['private_data_folder'].'/'.$liste_pages[$i].'" title="suppr"> </a><a class="origine" href="'.$url.'" title="origin"> </a> - <a href="'.$GLOBALS['private_data_folder'].'/'.$liste_pages[$i].'"><img src="'.$favicon.'"/>'.$titre.'</a> <em> ['.$date.']</em><a href="?topublic='.$liste_pages[$i].'" class="topublic" title="Change to public">◀</a></li>'."\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo '</ul>'."\n";
|
||||||
|
}
|
||||||
|
echo '</div>'."\n";
|
||||||
|
}
|
||||||
|
echo '</aside>'."\n";
|
||||||
|
echo '<footer>'."\n";
|
||||||
|
echo "\t<p style='float:left'>$bookmarklet</p><p><a title='from TiMo' href='http://lehollandaisvolant.net/index.php?mode=links&id=20121211195941'>Respawn</a> (bronco edition v".$GLOBAL['version'].") - ".$GLOBALS['message']." - <a href='?public'>Public page link</a></p>\n";
|
||||||
|
echo '</body>'."\n";
|
||||||
|
echo '</html>'."\n";
|
41
login_form.php
Normal file
41
login_form.php
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
<style>
|
||||||
|
.form_content{box-shadow:0 1px 2px black;border-radius:3px;margin:auto; border:2px solid #000;font-family: 'georgia';
|
||||||
|
font-size:18px;background-color:#333;width:200px;padding:20px;text-shadow:0 1px 1px black;color:#ddd;}
|
||||||
|
h1{font-size:22px; }
|
||||||
|
.logo{margin: auto;background:url(design/logo2.png) no-repeat;height:70px;width:70px;}
|
||||||
|
label{display:block;}
|
||||||
|
input[type=checkbox]+label{display:inline;width:auto;cursor:pointer;}
|
||||||
|
input[type=checkbox]{display:inline;width:auto;}
|
||||||
|
input{border-radius:3px;width:100%;}
|
||||||
|
|
||||||
|
#login, #pass{border:1px solid #999;padding:3px;}
|
||||||
|
#login:focus{text-shadow:0 0 3px green;}
|
||||||
|
#pass:focus{text-shadow:0 0 3px red;}
|
||||||
|
@media (max-width:600px){
|
||||||
|
.form_content{width:90%;font-size:26px!important;}
|
||||||
|
input{font-size:26px!important;}
|
||||||
|
}
|
||||||
|
@viewport{
|
||||||
|
width: device-width;
|
||||||
|
zoom:1;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="form_content">
|
||||||
|
<form action='' method='post' name='' >
|
||||||
|
<p class="logo"> </p>
|
||||||
|
<?php if(file_exists('pass.php')){echo '<h1>Identifiez-vous</h1>';}else{echo '<h1>Creez votre passe</h1>';} ?>
|
||||||
|
<hr/>
|
||||||
|
<label for='login'>Login </label>
|
||||||
|
<input type='text' name='login' id='login' required="required"/>
|
||||||
|
<br/>
|
||||||
|
<hr/>
|
||||||
|
<label for='pass'>Passe </label>
|
||||||
|
<input type='password' name='pass' id='pass' required="required"/>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
<input id="cookie" type="checkbox" value="cookie" name="cookie"/><label for="cookie">Rest. connect.</label>
|
||||||
|
<hr/>
|
||||||
|
<input type='submit' value='Connexion'/>
|
||||||
|
</form>
|
||||||
|
</div>
|
11
readme.md
Normal file
11
readme.md
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
Ceci est un fork de l'appli Respawn de Timo le Hollandais Volant.
|
||||||
|
J'ai utilisé le moteur de cette appli et y ai ajouté quelques aspect :
|
||||||
|
-le verrouillage par mot de passe,
|
||||||
|
-deux espaces séparés : un public et un privé (dont on peut (doit!) renommer les dossiers dans la config)
|
||||||
|
-l'ajout (si possible) de la favicon
|
||||||
|
-l'ajout d'icones et d'un design un peu amélioré, même si beaucoup reste à faire (mais là j'ai les yeux qui piquent)
|
||||||
|
-l'ajout d'un logo propre à cette appli
|
||||||
|
|
||||||
|
Merci à Timo pour cette merveille de simplicité et d'efficacité qui concourt à conserver et diffuser l'information !
|
||||||
|
|
||||||
|
Bronco - bronco@warriordudimanche.net
|
Reference in a new issue