This commit is contained in:
Ismo Vuorinen
2021-11-12 17:46:17 +02:00
parent f5a0a5ab4d
commit 59e6717fc2
10 changed files with 286 additions and 52 deletions

View File

@@ -7,8 +7,11 @@ root = true
[*]
end_of_line = lf
insert_final_newline = true
indent_style = space
# 4 space indentation
[*.php]
indent_style = space
indent_size = 4
[*.yml]
indent_size = 2

37
.github/workflows/phpcs.yml vendored Normal file
View File

@@ -0,0 +1,37 @@
name: PHP CS Checks
on: [ push ]
jobs:
phpcs-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Validate composer.json and composer.lock
run: composer validate
- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v2
with:
path: vendor
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-php-
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 7.4
extensions: simplexml
coverage: xdebug
env:
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Run PHPCS Check
run: |
composer install --prefer-dist --no-progress
composer require staabm/annotate-pull-request-from-checkstyle
./vendor/bin/phpcs -q --report=checkstyle | vendor/bin/cs2pr --graceful-warnings

5
.gitignore vendored
View File

@@ -1,3 +1,6 @@
config.php
.DS_Store
.idea
.idea
last.txt
phpcs.xml
vendor

15
CHANGELOG.md Normal file
View File

@@ -0,0 +1,15 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [1.0.0] - 2021-11-12
- Initial real release, of a 23 Aug 2010 started project.
- Added PHP_CodeSniffer
- Refactored the codebase for fun
- Added this changelog

View File

@@ -1,8 +1,10 @@
# xkcd-Mailer #
# xkcd-Mailer
Takes the first/latest item from the [xkcd](http://xkcd.com/) atom-feed and mails the image and punchline to a specified email address, if it has not been sent before.
Takes the first/latest item from the [xkcd](http://xkcd.com/) atom-feed
and mails the image and punchline to a specified email address,
if it has not been sent before.
## configuration ##
## configuration
The script needs a simple configuration. Modify ``config.example.php`` to fit your needs and save as ``config.php``
@@ -14,7 +16,7 @@ The script needs a simple configuration. Modify ``config.example.php`` to fit yo
*/
// Your timezone, PHP5 required.
// See full list: http://www.php.net/manual/en/timezones.php
// See full list: https://www.php.net/manual/en/timezones.php
date_default_timezone_set("Europe/Helsinki");
// Your destination
@@ -25,31 +27,33 @@ $from = "xkcd mailer <xkcdmailer@example.com>";
$lastfile = "last.txt";
```
## crontab example ##
## crontab example
Run every hour.
0 * * * * /usr/bin/php /full/path/to/xkcd-mailer.php
This version will check if the last post was already emailed and will only send the post
if it has not been emailed yet.
This version will check if the last post was already emailed and will only
send the post if it has not been emailed yet.
## caveats ##
## caveats
Make sure to set $lastfile to a path that you have write access to.
## changes ##
## changes
- 2014-03-30 @wojas added check to see if a post already sent
## contributing ##
## contributing
- Fork the code
- Do your changes
- Send pull request
- Bask in glory of open source love
## forks <3 ##
## forks <3
* [raamdev/pennyarcade-Mailer](https://github.com/raamdev/pennyarcade-Mailer) - [Penny Arcade](http://penny-arcade.com/comic) emailer by Raam Dev
* [raamdev/pennyarcade-Mailer][pa-git] - [Penny Arcade][pa-url] emailer by Raam Dev
[pa-git]: https://github.com/raamdev/pennyarcade-Mailer
[pa-url]: http://penny-arcade.com/comic

32
composer.json Normal file
View File

@@ -0,0 +1,32 @@
{
"name": "ivuorinen/xkcd-mailer",
"description": "XKCD Mailer",
"minimum-stability": "stable",
"license": "MIT",
"authors": [
{
"name": "Ismo Vuorinen",
"homepage": "https://github.com/ivuorinen"
},
{
"name": "Raam Dev",
"homepage": "https://github.com/raamdev"
},
{
"name": "wojas",
"homepage": "https://github.com/wojas"
}
],
"scripts": {
"lint": "phpcs --warning-severity=0 .",
"lint-all": "phpcs .",
"fix": "phpcbf ."
},
"require": {
"ext-simplexml": "*",
"ext-curl": "*"
},
"require-dev": {
"squizlabs/php_codesniffer": "^3.6"
}
}

75
composer.lock generated Normal file
View File

@@ -0,0 +1,75 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "0ed923ad64c14ec9e739afe660e900ad",
"packages": [],
"packages-dev": [
{
"name": "squizlabs/php_codesniffer",
"version": "3.6.1",
"source": {
"type": "git",
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
"reference": "f268ca40d54617c6e06757f83f699775c9b3ff2e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/f268ca40d54617c6e06757f83f699775c9b3ff2e",
"reference": "f268ca40d54617c6e06757f83f699775c9b3ff2e",
"shasum": ""
},
"require": {
"ext-simplexml": "*",
"ext-tokenizer": "*",
"ext-xmlwriter": "*",
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
},
"bin": [
"bin/phpcs",
"bin/phpcbf"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.x-dev"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Greg Sherwood",
"role": "lead"
}
],
"description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
"homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
"keywords": [
"phpcs",
"standards"
],
"support": {
"issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues",
"source": "https://github.com/squizlabs/PHP_CodeSniffer",
"wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki"
},
"time": "2021-10-11T04:00:11+00:00"
}
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.1.0"
}

View File

@@ -1,4 +1,8 @@
<?php if ( empty($here) ) exit('No direct script access allowed');
<?php
if (empty($here)) {
exit('No direct script access allowed');
}
/**
* xkcd-Mailer configuration example
@@ -13,5 +17,11 @@ date_default_timezone_set("Europe/Helsinki");
$mail = "your@email.com";
$from = "xkcd mailer <xkcdmailer@example.com>";
// Send using mail (false just echoes the results)
$send = true;
// File to write ID of last post to
$lastfile = "last.txt";
// Debug mode active
$debug = false;

19
phpcs.xml.dist Normal file
View File

@@ -0,0 +1,19 @@
<?xml version="1.0"?>
<ruleset
name="PHP_CodeSniffer"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/squizlabs/PHP_CodeSniffer/master/phpcs.xsd"
>
<description>PHP Code Sniffer configuration file.</description>
<arg name="basepath" value="."/>
<arg name="colors"/>
<arg name="extensions" value="php"/>
<arg name="parallel" value="10"/>
<!-- base rule: set to PSR12-->
<!-- https://www.php-fig.org/psr/psr-12/ -->
<!-- https://github.com/squizlabs/PHP_CodeSniffer/wiki/Customisable-Sniff-Properties -->
<rule ref="PSR12">
<exclude-pattern>*/vendor/*</exclude-pattern>
</rule>
</ruleset>

View File

@@ -1,35 +1,53 @@
<?php
/**
* xkcd-Mailer
*
* Sends HTML-email containing hotlinked latest xkcd
* Sends HTML-email containing hotlinked the latest xkcd
* strip with alt/title-text underneath the image.
*
* @category Default
* @package Default
* @author Ismo Vuorinen <ivuorinen@me.com>
* @author wojas <https://github.com/wojas>
* @author Raam Dev <https://github.com/raamdev>
* @link https://github.com/ivuorinen/xkcd-Mailer
* @license The MIT License http://www.opensource.org/licenses/mit-license.php
* @version 1.0.20140525
* @link https://github.com/ivuorinen/xkcd-Mailer
**/
*/
// Use config.example.php as base for your configurations.
$lastfile = "last.txt";
$here = dirname(__FILE__);
$here = __DIR__;
if (! is_readable($here . '/config.php')) {
die("Please configure me. I don't know where I should sent the comic. (Config file {$here}/config.php missing.)");
}
require_once $here . '/config.php';
$feed = "http://xkcd.com/atom.xml";
if (! isset($mail, $from) || empty($mail) || empty($from)) {
die('Configuration values $mail and $from cannot be empty');
}
$lastfile = $lastfile ?? 'last.txt';
$debug = $debug ?? false;
$send = $send ?? false;
$feed = "https://xkcd.com/atom.xml";
/**
* Get xml feed and parse it.
* Checks if http(s):// wrapper is allowed.
*
* @param string $feed Feed to fetch and parse.
*
* @return \SimpleXMLElement
*/
function getFeed(string $feed): SimpleXMLElement
{
if (ini_get('allow_url_fopen')) {
// https://bugs.php.net/bug.php?id=62577
return simplexml_load_string(file_get_contents($feed));
}
// Check if http:// wrapper is allowed
if (ini_get('allow_url_fopen')) {
$data = simplexml_load_file($feed);
} else {
// If http:// wrapper is disabled (by allow_url_fopen=0, for example), then fall back on cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $feed);
@@ -40,19 +58,17 @@ if (ini_get('allow_url_fopen')) {
$result = curl_exec($ch);
curl_close($ch);
$data = simplexml_load_string($result);
return simplexml_load_string($result);
}
$data = getFeed($feed);
$item = $data->entry[0];
$last = 0;
if (file_exists($lastfile)) {
$f = fopen($lastfile, 'r');
$last = (int) fread($f, 1024);
fclose($f);
}
$last = file_exists($lastfile)
? file_get_contents($lastfile)
: 0;
$parts = explode('/', $item->id);
$parts = explode('/', $item->id, 4);
$current = (int) $parts[3];
if ($current > $last) {
@@ -60,25 +76,45 @@ if ($current > $last) {
preg_match("#title=\"(.+)\"#iU", $item->summary, $t);
// To send HTML mail, the Content-type header must be set
//$headers = 'MIME-Version: 1.0' . "\r\n";
$headers = 'Content-type: text/html; charset=UTF-8' . "\r\n";
$headers .= 'From: '. $from . "\r\n";
$headers = "Content-type: text/html; charset=UTF-8\r\n" .
sprintf("From: %s\r\n", $from);
$subject = "xkcd {$date}: {$item->title}";
$punchline = $t[1];
$subject = sprintf('xkcd %s: %s', $date, $item->title);
$punchline = $t[1];
$msg = "<html><body><h1><a href=\"{$item->id}\">{$item->title}</a></h1>\n"
. "<small>Posted {$date}</small><br />\n"
. $item->summary."<br />\n"
. "<p>{$punchline}</p></body></html>\n";
$title = sprintf('<h1><a href="%s">%s</a></h1>', $item->id, $item->title);
$body = sprintf(
'<small>Posted %s</small><br>%s<br><p>%s</p>',
$date,
$item->summary,
$punchline
);
mail($mail, $subject, $msg, $headers);
$msg = sprintf(
"<html lang='en'><body>%s\n%s</body></html>",
$title,
$body
);
$f = fopen($lastfile, 'w');
fwrite($f, $current);
fclose($f);
if ($send) {
mail($mail, $subject, $msg, $headers);
} else {
echo $msg . "\n\n";
}
echo "New last is $current (was $last)\n";
} else {
echo "No new XKCD: last=$last current=$current\n";
$file_write_result = file_put_contents($lastfile, $current);
if (! $file_write_result) {
echo "Error writing to file: $lastfile\n";
exit(1);
}
if ($debug) {
echo "New last is $current (was $last)\n";
}
exit(0);
}
if ($debug) {
echo sprintf("No new XKCD: last=%d current=%d\n", $last, $current);
}