Über Community-Schöpfer Dan Harmon und seinen 8 Point Story Circle, das Fundament einer jeden Story.
Ludwig und ich gerieten neulich in ein Argument über Videokonsum in Deutschland, genauer über Videotheken vs. Internet.
Er sagt: Die Anzahl der Videotheken in Deutschland mag in den nächsten 5 Jahren zurückgehen, Video-on-Demand wird aber nicht ausschlaggebend sein. Die Filmrechteinhaber werden nicht schnell genug von der Musikindustrie lernen, legale Videoangebote werden immernoch unzureichend sein (zu teuer, selten Originalsprache, DRM, schlechte Qualität). Nicht genug Leute haben Breitband und einfache Möglichkeiten, Filme online zu leihen/kaufen. Nur furchtlose/dumme Nerds raubkopieren noch. Videotheken sind klasse zum Entdecken neuer Filme.
Ich sage: Legale Video-on-Demand-Angebote sind zwar noch schlecht, Piraterie ist zu kompliziert und gefährlich für die meisten Leute und nicht jeder hat die nötige Breitbandverbindung. Aber trotzdem: Physische Datenträger sind am Aussterben; die Blu-Ray wird das letzte physische Medium für Heimvideos sein. In den nächsten 5 Jahren haben mehr Leute Breitband und die Chance, dass sich die Filmindustrie mit ihren Rechten auskäst, steigt jedes Jahr. Zudem sind Videotheken umständlich. Aus dem Haus gehen um einen Film auszuleihen? Und zurückzubringen? Viel zu aufwändig, Faulheit obsiegt.
Es gibt keine Aussicht auf Einigung zwischen uns, die Fronten sind verhärtet. Zeit, die Einsätze zu erhöhen und eine Wette zu starten:
Tritt dieser Fall ein, zahlt Ludwig 100€ an Robert.
Tritt dieser Fall nicht ein, zahlt Robert 100€ an Ludwig.
Quelle der Zahlen sind die Geschäftsberichte des IVD (Interessenverband des Video- und Medienfachhandels in Deutschland e.V.). Der folgende Graph wird fortan jährlich aktualisiert:
Quellen: IVD Geschäftsberichte für 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2014, 2015, 2017
Es wird spannend.
Edit: Sieg! Die Wettschuld ist beglichen, die Wette beendet. Dem Verlauf nach müsste es 2021 die letzte handvoll Videotheken geben. Für die 100€ legen wir dann einen schmucken Trauerkranz vor die letzte.
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
Als ich den Song hörte, kamen mir die Lyrics bekannt vor.
So genau wie möglich transkribiert:
</nobar>
</iable>=center>=/d=they body / (html =
<"doctype html public "-// W3C// dtd html 4. transitional // en>
<html>
<head>
<meta http=-eqiv=(Contenttype=content"Text/html;kset=iso-8859-1">
function fensterAufTo(url) {
pict = window.open(url "toolbar=no location=no directories=no status=no men=no ubar=no,
scrollbars=yes resizable=no width 420 hoehe=460 screenX=90 screenY=80
pict.location href=weg(save.location a href)+url=
}
<meta name=generator=content=(EditPlus 1.1)>
<title>news<>
Störung=<base target=blank(_)i
link related in stylesheet type="text/sss" = href="css/agf.css">
<hype/ =
<body style="font family: Arial=" styles
I MISS YOU
<table border=0 cellspacing=0 cellpadding=0>
<b> = small <b nsbp = small
<this>/small = <p = table/
(body html head script language javascript <"--
HIDE ME
browserOk = false // 001 = 55
script/
(script language) = "javascript 1.1=<"--
HIDE ME
browserOk=true
/--1-(</script/"--
HIDE ME
HIDE ME
bgcolor ffffff
swLiveConnect = false
width = 270
height = 56
= type = application
/
Anscheinend versucht er ein Popup zu öffnen. Musiker und HTML...
Die neue Diktat vom Tsunami X morgen längst erstaunlich gut, wenn man deutlich spricht SunPower Versuch. Heute etliche mit Abstrom 55,99 €
Die neue Diktatfunktion in Mac OS X Mountain Lion ist erstaunlich gut, wenn man deutlich spricht und es ein paar Mal versucht. Ab heute erhältlich im Mac App Store für nur 15,99€.
Das beste Review wie immer von John Siracusa.
GO.COM: Das kleinste hilfreiche Programm, das erfolgreich verkauft wurde. 0 Bytes, 5$.
Schön verständliches Tutorial für Backbone.js, das JavaScript-Framework für Single-Page-WebApps™.