Browse Source

Add a Presence and Message (disabled for now) buffers

pull/932/head
Timothée Jaussoin 6 years ago
parent
commit
b7b2ba1709
  1. 51
      app/Message.php
  2. 57
      app/MessageBuffer.php
  3. 34
      app/Presence.php
  4. 60
      app/PresenceBuffer.php
  5. 2
      app/helpers/StringHelper.php
  6. 3
      lib/moxl/src/Moxl/Xec/Action/MAM/Get.php
  7. 55
      lib/moxl/src/Moxl/Xec/Action/Presence/Muc.php
  8. 13
      lib/moxl/src/Moxl/Xec/Payload/MAMResult.php
  9. 1
      lib/moxl/src/Moxl/Xec/Payload/Message.php
  10. 62
      lib/moxl/src/Moxl/Xec/Payload/Presence.php

51
app/Message.php

@ -327,7 +327,10 @@ class Message extends Model
->where('jidfrom', $this->jidfrom)
->where('replaceid', (string)$stanza->replace->attributes()->id)
->first();
$this->oldid = $message->id;
if ($message) {
$this->oldid = $message->id;
}
/**
* We prepare the existing message to be edited in the DB
@ -441,4 +444,50 @@ class Message extends Model
}
}
}
public function valid()
{
return
strlen($this->attributes['jidto']) < 256
&& strlen($this->attributes['jidfrom']) < 256
&& (!isset($this->attributes['resource']) || strlen($this->attributes['resource']) < 256)
&& (!isset($this->attributes['thread']) || strlen($this->attributes['thread']) < 128)
&& (!isset($this->attributes['replaceid']) || strlen($this->attributes['replaceid']) < 64)
&& (!isset($this->attributes['originid']) || strlen($this->attributes['originid']) < 255)
&& (!isset($this->attributes['id']) || strlen($this->attributes['id']) < 64)
&& (!isset($this->attributes['oldid']) || strlen($this->attributes['oldid']) < 64);
}
public function toRawArray()
{
return [
'user_id' => $this->attributes['user_id'] ?? null,
'id' => $this->attributes['id'] ?? null,
'oldid' => $this->attributes['oldid'] ?? null,
'jidto' => $this->attributes['jidto'] ?? null,
'jidfrom' => $this->attributes['jidfrom'] ?? null,
'resource' => $this->attributes['resource'] ?? null,
'type' => $this->attributes['type'] ?? null,
'subject' => $this->attributes['subject'] ?? null,
'thread' => $this->attributes['thread'] ?? null,
'body' => $this->attributes['body'] ?? null,
'html' => $this->attributes['html'] ?? null,
'published' => $this->attributes['published'] ?? null,
'delivered' => $this->attributes['deliver'] ?? null,
'displayed' => $this->attributes['displayed'] ?? null,
'quoted' => $this->attributes['quoted'] ?? false,
'markable' => $this->attributes['markable'] ?? false,
'picture' => $this->attributes['picture'] ?? null,
'sticker' => $this->attributes['sticker'] ?? null,
'file' => isset($this->attributes['file']) ? $this->attributes['file'] : null,
'created_at' => $this->attributes['created_at'] ?? null,
'updated_at' => $this->attributes['updated_at'] ?? null,
'replaceid' => $this->attributes['replaceid'] ?? null,
'seen' => $this->attributes['seen'] ?? false,
'encrypted' => $this->attributes['encrypted'] ?? false,
'originid' => $this->attributes['originid'] ?? null,
'retracted' => $this->attributes['retracted'] ?? false,
'resolved' => $this->attributes['resolved'] ?? false,
];
}
}

57
app/MessageBuffer.php

@ -0,0 +1,57 @@
<?php
namespace App;
use App\Message;
class MessageBuffer
{
protected static $instance;
private $_models = null;
private $_calls = null;
public static function getInstance()
{
if (!isset(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
public function __construct()
{
$this->_models = collect();
$this->_calls = collect();
}
public function save()
{
if ($this->_models->isNotEmpty()) {
try {
Message::insert($this->_models->toArray());
} catch (\Exception $e) {
\Utils::error($e->getMessage());
}
$this->_models = collect();
}
if ($this->_calls->isNotEmpty()) {
$this->_calls->each(function ($call) {
$call();
});
$this->_calls = collect();
}
}
public function append(Message $message, $call)
{
if ($message->created_at == null && $message->updated_at == null) {
$this->_models[$message->jidfrom.$message->id] = $message->toRawArray();
$this->_calls->push($call);
} else {
$message->save();
$call();
}
}
}

34
app/Presence.php

@ -97,14 +97,9 @@ class Presence extends Model
public function set($stanza)
{
$this->session_id = SESSION_ID;
$jid = explode('/', (string)$stanza->attributes()->from);
$this->jid = $jid[0];
if (isset($jid[1])) {
$this->resource = $jid[1];
} else {
$this->resource = '';
}
$jid = explodeJid($stanza->attributes()->from);
$this->jid = $jid['jid'];
$this->resource = $jid['resource'] ?? '';
if ($stanza->status && !empty((string)$stanza->status)) {
$this->status = (string)$stanza->status;
@ -187,4 +182,27 @@ class Presence extends Model
$this->last = (int)$stanza->query->attributes()->seconds;
}
}
public function toArray()
{
$now = \Carbon\Carbon::now();
return [
'session_id' => $this->attributes['session_id'] ?? null,
'jid' => $this->attributes['jid'] ?? null,
'resource' => $this->attributes['resource'] ?? null,
'value' => $this->attributes['value'] ?? null,
'priority' => $this->attributes['priority'] ?? null,
'status' => $this->attributes['status'] ?? null,
'node' => $this->attributes['node'] ?? null,
'delay' => $this->attributes['delay'] ?? null,
'last' => $this->attributes['last'] ?? null,
'muc' => $this->attributes['muc'] ?? null,
'mucjid' => $this->attributes['mucjid'] ?? null,
'mucaffiliation' => $this->attributes['mucaffiliation'] ?? null,
'mucrole' => $this->attributes['mucrole'] ?? null,
'created_at' => $this->attributes['created_at'] ?? $now,
'updated_at' => $this->attributes['updated_at'] ?? $now,
'avatarhash' => $this->attributes['avatar_hash'] ?? null,
];
}
}

60
app/PresenceBuffer.php

@ -0,0 +1,60 @@
<?php
namespace App;
use App\Presence;
class PresenceBuffer
{
protected static $instance;
private $_models = null;
private $_calls = null;
public static function getInstance()
{
if (!isset(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
public function __construct()
{
global $loop;
$this->_models = collect();
$this->_calls = collect();
$loop->addPeriodicTimer(1, function () {
$this->save();
});
}
public function save()
{
if ($this->_models->isNotEmpty()) {
Presence::insert($this->_models->toArray());
$this->_models = collect();
}
if ($this->_calls->isNotEmpty()) {
$this->_calls->each(function ($call) {
$call();
});
$this->_calls = collect();
}
}
public function append(Presence $presence, $call)
{
// Only presences that can be inserted, not updated
if ($presence->created_at == null) {
$this->_models[$presence->muc ? $presence->mucjid : $presence->jid.$presence->resource] = $presence->toArray();
$this->_calls->push($call);
} else {
$presence->save();
$call();
}
}
}

2
app/helpers/StringHelper.php

@ -238,7 +238,7 @@ function explodeJid(string $jid): array
$arr = explode('/', $jid);
$jid = $arr[0];
$resource = isset($arr[1]) ? $arr[1] : null;
$resource = count($arr) > 1 ? implode('/', array_slice($arr, 1)) : null;
$username = null;
$arr = explode('@', $jid);

3
lib/moxl/src/Moxl/Xec/Action/MAM/Get.php

@ -6,6 +6,7 @@ use Moxl\Xec\Action;
use Moxl\Stanza\MAM;
use Movim\Session;
use App\MessageBuffer;
class Get extends Action
{
@ -52,6 +53,8 @@ class Get extends Action
$sess = Session::start();
$sess->remove('mamid'.$this->_queryid);
//MessageBuffer::getInstance()->save();
if ($this->_to) {
$this->method('handle_muc');
$this->pack($this->_to);

55
lib/moxl/src/Moxl/Xec/Action/Presence/Muc.php

@ -6,6 +6,7 @@ use Moxl\Xec\Action;
use Moxl\Stanza\Presence;
use Movim\Session;
use App\PresenceBuffer;
class Muc extends Action
{
@ -58,35 +59,35 @@ class Muc extends Action
$presence->mucjid = current(explode('/', (string)$stanza->attributes()->to));
}
$presence->save();
if ($this->_mam) {
$message = \App\User::me()->messages()
->where('jidfrom', $this->_to)
->whereNull('subject')
->orderBy('published', 'desc')
->first();
$g = new \Moxl\Xec\Action\MAM\Get;
$g->setTo($this->_to)
->setLimit(300);
if (!empty($message)
&& strtotime($message->published) > strtotime('-3 days')) {
$g->setStart(strtotime($message->published));
} else {
$g->setStart(strtotime('-3 days'));
}
if (!$this->_mam2) {
$g->setVersion('1');
PresenceBuffer::getInstance()->append($presence, function () use ($presence) {
if ($this->_mam) {
$message = \App\User::me()->messages()
->where('jidfrom', $this->_to)
->whereNull('subject')
->orderBy('published', 'desc')
->first();
$g = new \Moxl\Xec\Action\MAM\Get;
$g->setTo($this->_to)
->setLimit(300);
if (!empty($message)
&& strtotime($message->published) > strtotime('-3 days')) {
$g->setStart(strtotime($message->published));
} else {
$g->setStart(strtotime('-3 days'));
}
if (!$this->_mam2) {
$g->setVersion('1');
}
$g->request();
}
$g->request();
}
$this->pack($presence);
$this->deliver();
$this->pack($presence);
$this->deliver();
});
}
public function errorRegistrationRequired($stanza, $parent = false)

13
lib/moxl/src/Moxl/Xec/Payload/MAMResult.php

@ -4,6 +4,8 @@ namespace Moxl\Xec\Payload;
use Movim\Session;
use App\MessageBuffer;
class MAMResult extends Payload
{
public function handle($stanza, $parent = false)
@ -26,12 +28,15 @@ class MAMResult extends Payload
}
if (!$message->encrypted
&& $message->valid()
&& (!$message->isEmpty() || $message->isSubject())) {
$message->save();
$message->clearUnreads();
//MessageBuffer::getInstance()->append($message, function() use ($message) {
$message->save();
$message->clearUnreads();
$this->pack($message);
$this->deliver();
$this->pack($message);
$this->deliver();
//});
}
}
}

1
lib/moxl/src/Moxl/Xec/Payload/Message.php

@ -35,6 +35,7 @@ class Message extends Payload
}
if (!$message->encrypted
&& $message->valid()
&& (!$message->isEmpty() || $message->isSubject())) {
$message->save();
$message = $message->fresh();

62
lib/moxl/src/Moxl/Xec/Payload/Presence.php

@ -6,6 +6,7 @@ use Moxl\Xec\Action\Vcard\Get;
use Movim\Session;
use App\Presence as DBPresence;
use App\PresenceBuffer;
class Presence extends Payload
{
@ -25,42 +26,45 @@ class Presence extends Payload
} else {
$presence = DBPresence::findByStanza($stanza);
$presence->set($stanza);
$presence->save();
$refreshable = $presence->refreshable;
if ($refreshable) {
$r = new Get;
$r->setAvatarhash($presence->avatarhash)
->setTo((string)$refreshable)
->request();
}
PresenceBuffer::getInstance()->append($presence, function () use ($presence, $stanza) {
//$presence = $presence->fresh();
$refreshable = $presence->refreshable;
if ($refreshable) {
$r = new Get;
$r->setAvatarhash($presence->avatarhash)
->setTo((string)$refreshable)
->request();
}
if ($presence->muc
&& isset($stanza->x)) {
foreach ($stanza->x as $x) {
if ($x->attributes()->xmlns == 'http://jabber.org/protocol/muc#user'
&& isset($stanza->x->status)
&& \in_array((int)$stanza->x->status->attributes()->code, [110, 332, 307, 301])) {
if ($presence->value != 5 && $presence->value != 6) {
$this->method('muc_handle');
$this->pack($presence);
} elseif ($presence->value == 5) {
$this->method('unavailable_handle');
$this->pack($presence);
}
if ($presence->muc
&& isset($stanza->x)) {
foreach ($stanza->x as $x) {
if ($x->attributes()->xmlns == 'http://jabber.org/protocol/muc#user'
&& isset($stanza->x->status)
&& \in_array((int)$stanza->x->status->attributes()->code, [110, 332, 307, 301])) {
if ($presence->value != 5 && $presence->value != 6) {
$this->method('muc_handle');
$this->pack($presence);
} elseif ($presence->value == 5) {
$this->method('unavailable_handle');
$this->pack($presence);
}
$this->deliver();
$this->deliver();
break;
}
}
}
} else {
$this->pack($presence->roster);
} else {
$this->pack($presence->roster);
if ($presence->value == 5 /*|| $p->value == 6*/) {
$presence->delete();
if ($presence->value == 5 /*|| $p->value == 6*/) {
$presence->delete();
}
}
}
$this->deliver();
$this->deliver();
});
}
}
}
Loading…
Cancel
Save