Skip to content

Instantly share code, notes, and snippets.

@Fil
Last active January 3, 2016 04:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Fil/8407898 to your computer and use it in GitHub Desktop.
Save Fil/8407898 to your computer and use it in GitHub Desktop.
<?php
# seenthis sync:
# export
define('_DIR_EXPORT', 'export/');
# import
#chdir ('..');
include_once 'ecrire/inc_version.php';
include_spip('base/abstract_sql');
include_spip('inc/filtres');
/*
* Exemples d'utilisation
*/
// tout exporter en mode text
#seenthis_sync_export(100000000, array('html' => false));
// importer un message au format email
#seenthis_sync_import_one('export/2014/2014-01/52d798e9-03b4-4290-b519-6db6f06a467e.eml');
// importer tous les messages du dossier janvier 2011
#foreach (glob('export/2011/2011-01/*.eml') as $m) seenthis_sync_import_one($m);
/*
* Import all recent files
*/
function seenthis_sync_import($age) {
# find _DIR_EXPORT -mtime -$age
}
/*
* Export recent messages to disk;
* int $limit : number of most recent articles to export
* array $options (
* bool $html : export an HTML version as well
* bool $overwrite : erase files even if they are most recent than database
* )
*
*/
function seenthis_sync_export($limit = 10, $options = array()) {
include_spip('base/abstract_sql');
$s = sql_query('SELECT m.*, t.texte, a.login, a.nom AS name, p.uuid puuid
FROM spip_me m
LEFT JOIN spip_me_texte t ON m.id_me = t.id_me
LEFT JOIN spip_auteurs a ON a.id_auteur=m.id_auteur
LEFT JOIN spip_me p ON p.id_me=m.id_parent
ORDER BY m.date DESC LIMIT '.intval($limit));
while ($t = sql_fetch($s)) {
seenthis_sync_export_one($t, $options);
}
}
/*
* import one file in eml format into seenthis
*/
function seenthis_sync_import_one($f) {
if (!$m = seenthis_sync_parse(file_get_contents($f))) {
echo "Could not parse $f\n";
return false;
} else {
$m['date_modif'] = @filemtime($f);
}
// reponse ?
if (isset($m['puuid'])
AND !$p = sql_fetsel('id_me', 'spip_me', 'uuid='.sql_quote($m['puuid']))) {
echo "Parent not yet known $m[puuid]\n";
return false;
}
$id_parent = $p ? array_pop($p) : 0;
// est-ce qu'on prend les messages de userkey ?
// à quel user (à créer éventuellement) correspond-t-il ?
if ($id_auteur = seenthis_sync_auteur($m)) {
if ($id_me = sql_fetsel('id_me', 'spip_me', 'uuid='.sql_quote($m['uuid']))) {
echo "Message already known… need to check date_modif\n";
return false;
} else {
instance_me ($id_auteur, $m['text'], 0, $id_parent, $m['date'], $m['uuid']);
}
return $m['uuid'];
}
}
function seenthis_sync_auteur($m) {
static $mem = array();
if (isset($mem[$m['userkey']]))
return $mem[$m['userkey']];
if ($m['userkey'] == 'fil@localhost')
return $mem[$m['userkey']] = 1;
// autres auteurs : les chercher ou les creer
if(preg_match('/^(\w+)@localhost$/', $m['userkey'], $r)) {
if ($p = sql_fetsel('id_auteur', 'spip_auteurs', 'login='.sql_quote($r[1])))
return $mem[$m['userkey']] = $p['id_auteur'];
if ($id_auteur = sql_insertq('spip_auteurs', array(
'login' => $r[1],
'nom' => sinon($m['name'], $r[1]),
'statut' => '6forum',
))) {
echo "creation auteur $id_auteur = $r[1]\n";
return $mem[$m['userkey']] = $id_auteur;
}
}
return $mem[$m['userkey']] = null; // par défaut, refuser
return $mem[$m['userkey']] = 1; // auteur 1 par défaut
}
function seenthis_sync_parse($c) {
$headers = array();
while (preg_match('/^([\w-]+): (.*)\n/S', $c, $r)) {
$headers[strtolower($r[1])] = $r[2];
$c = substr($c, strlen($r[0]));
}
$body = substr($c,1,-1);
// convert headers into seenthis fields
$m = array();
if (isset($headers['message-id'])
AND preg_match('/^<?([0-9a-f-]+)>?$/Si', trim($headers['message-id']), $r)
)
$m['uuid'] = $r[1];
if (isset($headers['in-reply-to'])
AND preg_match('/^<?([0-9a-f-]+)>?$/Si', trim($headers['in-reply-to']), $r))
$m['puuid'] = $r[1];
if (isset($headers['date'])
AND $date = DateTime::createFromFormat(
'D, d M Y H:i:s O', $headers['date']
))
$m['date'] = $date->format( 'Y-m-d H:i:s');
if (isset($headers['from'])
AND preg_match('/^(.*?)<([^<>]+)>$/Si', trim($headers['from']), $r)) {
$m['name'] = trim($r[1]);
$m['userkey'] = $r[2];
}
# ignore subject line
$m['text'] = $body;
if (isset($headers['status'])
AND preg_match('/canceled/Si', trim($headers['message-id']), $r)
) {
$m['statut'] = 'supp';
$m['text'] = null;
} else {
$m['statut'] = 'publi';
}
// sanity checks
return $m;
}
function seenthis_sync_export_one($t, $options = array()) {
$f = _DIR_EXPORT
.substr($t['date'],0,4).'/'.substr($t['date'],0,7).'/'
.$t['uuid'].'.eml';
mkdir (dirname($f), 0755, true);
echo "exporting $t[id_me] to $f\n";
# $overwrite = false
if (!$options['overwrite']
AND ($last = strtotime($t['date_modif']))
AND (@filemtime($f) >= $last)) {
echo "do not rewrite. ";
if (@filemtime($f) == $last)
echo "on-disk is the same\n";
else
echo "on-disk is more recent.\n";
return;
}
$userkey = $t['login'].'@localhost';
if ($t['statut'] !== 'publi') {
$t['texte'] = '--canceled--';
$status = 'canceled';
} else {
$status = 'published';
}
$headers = sprintf(
"Message-Id: <%s>
Date: %s
From: %s <%s>
Subject: %s
Status: %s",
$t['uuid'],
date('D, d M Y H:i:s O', strtotime($t['date'])),
encodeHeader($t['name']), $userkey,
encodeHeader(html_entity_decode(extraire_titre($t['texte']))),
$status
);
if ($t['puuid'])
$headers .= sprintf("\nIn-Reply-To: <%s>", $t['puuid']);
# export HTML ? Mais il faudrait un HTML plus modeste. Et que faire des images ? Les ajotuer dans le multipart ?
if ($options['html']
AND $payload = microcache($t['id_me'], "noisettes/afficher_message")) {
while ($c = rand(0,1000000) AND preg_match("/part$c/", $t['texte'])){};
$headers .= "\nMIME-Version: 1.0\nContent-Type: multipart/alternative; boundary=\"part$c\"";
$body = "
--part$c
Content-Type: text/plain; charset=utf-8
".$t['texte']."
--part$c
Content-Type: text/html; charset=utf-8
".$payload."\n";
}
else {
$body = $t['texte'];
}
$message = "$headers\n\n$body\n";
if (ecrire_fichier($f,$message)) {
touch ($f, strtotime($t['date_modif']));
}
}
function encodeHeader($input, $charset = 'utf-8')
{
if (preg_match_all('/(\w*[\x80-\xFF]+\w*)/', $input))
$input=mb_encode_mimeheader($input,$charset, 'Q');
return $input;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment