Browse Source

initial commit (at your desire)

master
Denis Ryabov 11 years ago
parent
commit
7cd0222966
  1. 2
      README.md
  2. 51
      habr_twister.php
  3. 30
      habrrssdb.php
  4. 162
      twisterpost.php

2
README.md

@ -1,4 +1,4 @@
twister-phpbot twister-phpbot
============== ==============
Simple Twister bot written in PHP Simple Twister bot written in PHP. It is used to post messages for twister's @habr_ru account.

51
habr_twister.php

@ -0,0 +1,51 @@
<?php
set_time_limit(0);
mb_internal_encoding('UTF-8');
chdir(__DIR__);
function debugLog($msg)
{
file_put_contents('./logrss.txt', "$msg\n", FILE_APPEND);
}
/**/debugLog("\n\n\n=== " . date("Y-m-d H:i:s") . "===");
// Load RSS feed
$feed_uri = 'http://habrahabr.ru/rss/hubs/new/';
$rss = simplexml_load_file($feed_uri);
if (!$rss) die('Cannot read rss');
// Initialise TwisterPost
require_once 'twisterpost.php';
$twister = new TwisterPost('habr_ru');
// Set path to twisterd directory
$twister->twisterPath = '.' . DIRECTORY_SEPARATOR . 'twister-win32-bundle' . DIRECTORY_SEPARATOR;
// Note: we use custom rpc port for twister
$twister->rpcport = 40001;
// Initialise RSS database
require_once 'habrrssdb.php';
$db = new HabrRSSDb('habr_db.dat');
foreach ($rss->channel->item as $item) {
$link = (string)$item->link;
$title = (string)$item->title;
// get post id from link
$id = (int)preg_replace('#[^\d]#', '', $link);
if ($db->isPublished($id)) {
continue;
}
$msg = $twister->prettyPrint($title, $link, isset($item->category) ? $item->category : null);
/**/debugLog($msg);
if ($twister->postMessage($msg)) {
$db->setPublished($id);
}
}
/**/debugLog('=== Done ===');

30
habrrssdb.php

@ -0,0 +1,30 @@
<?php
class HabrRSSDb
{
protected $hDatabase = null;
public function __construct($dbFile)
{
fclose(fopen($dbFile, 'a')); // create file if not exists
$this->hDatabase = fopen($dbFile, 'r+');
}
public function __destruct()
{
fclose($this->hDatabase);
}
public function isPublished($id)
{
fseek($this->hDatabase, $id);
$status = fgetc($this->hDatabase);
return $status === '1';
}
public function setPublished($id)
{
fseek($this->hDatabase, $id);
fwrite($this->hDatabase, '1');
}
}

162
twisterpost.php

@ -0,0 +1,162 @@
<?php
class TwisterPost
{
public $user = '';
public $twisterPath = '';
public $rpcuser = 'user';
public $rpcpassword = 'pwd';
public $rpcport = 28332;
public $lastError = null;
protected $maxId = -1;
public function __construct($user)
{
$this->user = $user;
}
protected function getRpcCommand($method, $params = '')
{
$twisterd_path = $this->twisterPath . "twisterd";
$twisterd_path .= " -rpcuser={$this->rpcuser}";
$twisterd_path .= " -rpcpassword={$this->rpcpassword}";
$twisterd_path .= " -rpcport={$this->rpcport}";
$twisterd_path .= " $method";
if (!empty($params)) {
$twisterd_path .= " $params";
}
return $twisterd_path;
}
public function runRpcCommand($method, $params = '')
{
$cmd = $this->getRpcCommand($method, $params);
$result = null;
if (strncasecmp(PHP_OS, 'WIN', 3) == 0) {
$this->exec_win($cmd, $result);
} else {
exec($cmd, $result);
}
$result = json_decode(implode(' ', $result));
return $result;
}
public function updateMaxId()
{
$this->lastError = null;
$this->maxId = 0;
$result = $this->runRpcCommand('getposts', "1 '[{\"username\":\"{$this->user}\"}]'");
if (isset($result->code) && $result->code < 0) {
$this->maxId = -1;
$this->lastError = $result;
return false;
}
if (isset($result[0])) {
if (isset($result[0]->userpost->k)) {
$this->maxId = $result[0]->userpost->k;
}
}
$result = $this->runRpcCommand('dhtget', "{$this->user} status s");
if (isset($result->code) && $result->code < 0) {
$this->maxId = -1;
$this->lastError = $result;
return false;
}
if (isset($result[0]) && isset($result[0]->p)) {
if (isset($result[0]->p->seq)) {
$this->maxId = max($this->maxId, $result[0]->p->seq);
}
if (isset($result[0]->p->v) && isset($result[0]->p->v->userpost) && isset($result[0]->p->v->userpost->k)) {
$this->maxId = max($this->maxId, $result[0]->p->v->userpost->k);
}
}
return true;
}
public function postMessage($text)
{
$this->lastError = null;
if ($this->maxId < 0) {
if (!$this->updateMaxId()) {
return false;
}
}
$k = $this->maxId + 1;
$text = '"' . str_replace('"', '\\"', $text) . '"';
$result = $this->runRpcCommand('newpostmsg', "{$this->user} $k $text");
if (isset($result->code) && $result->code < 0) {
$this->maxId = -1;
$this->lastError = $result;
return false;
}
$this->maxId = $k;
return true;
}
public function prettyPrint($title, $url = '', $tags = null)
{
$maxLen = 140;
$title_len = mb_strlen($title);
$url_len = mb_strlen($url);
if ($url_len === 0) {
if ($title_len > $maxLen) {
$text = rtrim(mb_substr($title, 0, $maxLen - 1), ' ') . '…';
} else {
$text = $title;
}
} else if ($title_len + 1 + $url_len > $maxLen) {
$text = rtrim(mb_substr($title, 0, $maxLen - 2 - $url_len), ' ') . '… ' . $url;
} else {
$text = $title . ' ' . $url;
if (isset($tags)) {
foreach ($tags as $tag) {
$text .= ' #' . str_replace(' ', '_', (string)$tag);
}
}
$text = mb_substr($text, 0, $maxLen + 1);
$pos = $maxLen;
while (mb_substr($text, $pos, 1) !== ' ') {
$pos--;
}
$text = mb_substr($text, 0, $pos);
}
return $text;
}
protected function exec_win($cmd, &$output = null, &$return_var = null)
{
$tempfile = '_php_exec.bat';
$bat = "@echo off\r\n"
. "@chcp 65001 >nul\r\n"
. "@cd \"" . getcwd() . "\"\r\n"
. "$cmd\r\n";
file_put_contents($tempfile, $bat);
exec("start /b cmd /c $tempfile", $output, $return_var);
unlink($tempfile);
return count($output) ? $output[count($output) - 1] : '';
}
}
Loading…
Cancel
Save