ChunkMail
DailyLit ist klasse. Sendet einem täglich einen kleinen Teil eines langen Buches per Mail oder RSS. E-Mails liest man eh; warum so also nicht auch das Buch, das seit 3 Wochen auf dem Nachttisch verstaubt? Nachteil von DailyLit: Keine eigenen Texte hochladbar.
Drum schrieb ich mir gestern ein simples kleines PHP-Script, das einem auf Anfrage den nächsten Teil eines langen Textes per Mail schickt. Mehr nicht. Keine User-Accounts, multiplen Dateien, Admin-Interfaces etc.
Wer es gebrauchen kann:
<?
/*
ChunkMail
(c) Robert Gerlach 2012 - robsite.de
Sends and displays chunks of a long text per mail. Inspired by DailyLit.com
Usage:
1. Upload chunkmail.php to a PHP capable web server
2. Put a long text file in the same folder as chunkmail.php
3. Edit $config below with the name of your long text file.
4. Make the chunkmail folder writeable by PHP (so chunkmail can create meta_$longTextFile, which stores the already mailed pages)
5. Call chunkmail.php:
chunkmail.php - Display smallest unread page. Mail it, if it hasn't been mailed yet.
chunkmail.php?page=123 - Display page 123. Mail it, if it hasn't been mailed yet.
chunkmail.php?reset - Reset list of mailed pages. Display page 1, mail it.
To send you the newest page daily at 6:00, use cron:
> crontab -e
0 6 * * * wget http://example.com/where/chunkmail/is/chunkmail.php > /dev/null
Optional: Secure chunkmail folder via .htaccess on Apache:
1. Create a .htpasswd file somewhere your webserver can't access it. You can generate the password with tools like
- http://www.4webhelp.net/us/password.php
- http://www.htaccesstools.com/htpasswd-generator/
2. Create .htaccess in the chunkmail folder
AuthUserFile /absolute/path/to/.htpasswd
AuthType Basic
AuthName "ChunkMail"
Require valid-user
3. Modify wget in crontab to use HTTP-Authentication:
wget http://YOUR_USERNAME:YOUR_PASSWORD@example.com/where/chunkmail/is/chunkmail.php > /dev/null
License: WSCECPUCYUS - Wear a Slice of Cheese for Every CPU Core You Use the Software on
*/
$config = array(
'longTextFile' => "longtextislong.txt", // Your long text file
'chunkSize' => 3*1024, // Chunk size in bytes
'chunkPadding' => 512, // Chunk padding in bytes. Displays a bit of the previous chunk, so you know where you left off.
'receiver' => 'you@somewhere.com' // Receiver email
);
$serverURL = $_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'];
if ($_SERVER['HTTPS']) {
$serverURL = 'https://'.$serverURL;
} else {
$serverURL = 'http://'.$serverURL;
}
// File with sent page numbers, comma separated
$metaFile = 'meta_'.$config['longTextFile'];
// Get text length and pages length
$longText = file_get_contents($config['longTextFile']);
$longTextLength = strlen($longText);
$pagesLength = floor($longTextLength / $config['chunkSize']);
if ($pagesLength < 1) {
$pagesLength = 1;
}
// Reset sent pages. Start from the beginning
$reset = false;
if (isset($_GET['reset'])) {
file_put_contents($metaFile, "");
$reset = true;
}
$currentPage = 0;
$sentPages = array(); // all the already sent pages
if (file_exists($metaFile)) {
$fileContents = file_get_contents($metaFile);
if (strlen($fileContents) > 0) {
$sentPagesFromFile = explode(",", $fileContents);
}
if (is_array($sentPagesFromFile)) {
$sentPages = $sentPagesFromFile;
}
}
// Get current page (starting with 0). Either the ?page, or the smallest unread page
if (isset($_GET['page'])) {
$currentPage = $_GET['page']-1;
} else {
// Smallest unread page or last page
$currentPage = $pagesLength - 1;
for ($i = 0; $i < $pagesLength; $i++) {
if (!in_array($i."", $sentPages)) {
$currentPage = $i."";
break;
}
}
}
if ($currentPage >= $pagesLength) {
$currentPage = $pagesLength - 1;
} else if ($currentPage < 0) {
$currentPage = 0;
}
// Get text chunk for this page plus a little padding to ease you into the text
$ratio = $currentPage / $pagesLength;
$chunkStart = $ratio * $longTextLength;
$chunkLength = $longTextLength / $pagesLength;
$chunk = substr($longText, $chunkStart, $chunkLength); // don't bother with cutting off words. That's what the padding is for.
$paddingChunkStart = $chunkStart - $config['chunkPadding'];
if ($paddingChunkStart < 0) {
$paddingChunkStart = 0;
}
$paddingChunkLength = $chunkStart - $paddingChunkStart;
if ($paddingChunkLength > 0) {
$paddingChunk = substr($longText, $paddingChunkStart, $paddingChunkLength);
} else {
$paddingChunk = '';
}
$nextPage = $currentPage + 1;
if ($nextPage >= $pagesLength) {
$nextPage = $pagesLength - 1;
}
$previousPage = $currentPage - 1;
if ($previousPage < 0) {
$previousPage = 0;
}
// Send current chunk per mail, but only once
$wasSent = false;
if (!in_array($currentPage, $sentPages)) {
$to = $config['receiver'];
$subject = $config['longTextFile'] . " ".($currentPage+1) . "/" . $pagesLength . " — ChunkMail";
$message = $subject . "\n\n";
$message .= $paddingChunk."\n\n--------\n\n".$chunk;
$message .= "\n\n\n";
$message .= "Send next unread page: " . $serverURL."\n\n";
$message .= "First Page: " . $serverURL."?page=1\n";
$message .= "Previous Page: " . $serverURL."?page=".($previousPage + 1)."\n";
$message .= "Next Page: " . $serverURL."?page=".($nextPage + 1)."\n";
$message .= "Last Page: " . $serverURL."?page=".($pagesLength)."\n\n";
$message .= "Reset mailed pages: " . $serverURL."?reset";
$headers = 'From: chunkmail@'.$_SERVER['SERVER_NAME'] . "\r\n" .
'Reply-To: chunkmail@'.$_SERVER['SERVER_NAME'] . "\r\n";
mail($to, $subject, $message, $headers);
$sentPages[] = $currentPage;
$wasSent = true;
}
sort($sentPages); // unnecessary but nice
file_put_contents($metaFile, implode(",", $sentPages));
?><!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title><?= $config['longTextFile']." ". ($currentPage+1) . "/" . $pagesLength?> — ChunkMail</title>
<style type="text/css" media="screen">
div {
margin-bottom: 20px;
}
.reset,
.wasSent {
font-weight: bold;
}
.paddingChunk {
color: #999;
}
.links a {
display: inline-block;
padding: 20px 30px;
text-decoration: none;
}
.links a:first-child,
.links .reset {
padding-left: 0;
}
</style>
</head>
<body>
<? if ($reset) { ?>
<div class="reset">
Resetting pages. Now starting with page 1.
</div>
<? } ?>
<? if ($wasSent) { ?>
<div class="wasSent">
This page was sent to <?=htmlentities($config['receiver'])?>.
</div>
<? } ?>
<h1>
<?= $config['longTextFile']." ". ($currentPage+1) . "/" . $pagesLength?>
</h1>
<div class="text">
<span class="paddingChunk"><?=nl2br(htmlentities($paddingChunk))?></span><?=nl2br(htmlentities($chunk))?>
</div>
<div class="links">
<a href="<?=$serverURL;?>?page=1" title="First Page">|<</a>
<a href="<?=$serverURL;?>?page=<?=$previousPage + 1?>" title="Previous Page"><</a>
<a href="<?=$serverURL;?>?page=<?=$nextPage + 1?>" title="Next Page">></a>
<a href="<?=$serverURL;?>?page=<?=$pagesLength?>" title="Last Page">>|</a>
<br>
<a class="reset" href="<?=$serverURL;?>?reset" title="Reset sent pages">Reset</a>
</div>
</body>
</html>
Später sah ich dann, dass Dripread genau das gleiche macht bzw. DailyLit-mit-eigenen-Texten ist :D
· ★