UPSTREAM BASELINE: nextcloud/spreed v22.0.12 (без изменений)
Type checking / changes (push) Has been cancelled
Type checking / test (push) Has been cancelled
Type checking / typescript-summary (push) Has been cancelled
Node tests / changes (push) Has been cancelled
Node tests / test (push) Has been cancelled
Node tests / test-summary (push) Has been cancelled
Type checking / changes (push) Has been cancelled
Type checking / test (push) Has been cancelled
Type checking / typescript-summary (push) Has been cancelled
Node tests / changes (push) Has been cancelled
Node tests / test (push) Has been cancelled
Node tests / test-summary (push) Has been cancelled
Источник: https://github.com/nextcloud/spreed/archive/refs/tags/v22.0.12.tar.gz С этого коммита ветка официального Nextcloud Talk отрезана (решение владельца 2026-07-06). Все дальнейшие изменения — только наши; версии релизов: 22.0.12-f7.N.
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
- SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
|
||||
- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-->
|
||||
<info>
|
||||
<id>spreedcheats</id>
|
||||
<name>Talk cheats app for Intergration tests</name>
|
||||
<namespace>SpreedCheats</namespace>
|
||||
<description/>
|
||||
|
||||
<licence>AGPL</licence>
|
||||
<author>Joas Schilling</author>
|
||||
<version>22.0.0</version>
|
||||
|
||||
<types>
|
||||
<logging/>
|
||||
</types>
|
||||
|
||||
<dependencies>
|
||||
<nextcloud min-version="32" max-version="32" />
|
||||
</dependencies>
|
||||
</info>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
return [
|
||||
'ocs' => [
|
||||
['name' => 'Api#resetSpreed', 'url' => '/', 'verb' => 'DELETE'],
|
||||
['name' => 'Api#ageChat', 'url' => '/age', 'verb' => 'POST'],
|
||||
['name' => 'Api#forgedFederationLeave', 'url' => '/forged/federation/active', 'verb' => 'DELETE'],
|
||||
['name' => 'Api#createEventInCalendar', 'url' => '/calendar', 'verb' => 'POST'],
|
||||
['name' => 'Api#createDashboardEvents', 'url' => '/dashboardEvents', 'verb' => 'POST'],
|
||||
['name' => 'Api#createEventAndInviteParticipant', 'url' => '/mutualEvents', 'verb' => 'POST'],
|
||||
],
|
||||
];
|
||||
@@ -0,0 +1,18 @@
|
||||
BEGIN:VCALENDAR
|
||||
PRODID:-//IDN nextcloud.com//Calendar app 5.2.0-dev.1//EN
|
||||
CALSCALE:GREGORIAN
|
||||
VERSION:2.0
|
||||
BEGIN:VEVENT
|
||||
CREATED:20250310T171800Z
|
||||
DTSTAMP:20250310T171819Z
|
||||
LAST-MODIFIED:20250310T171819Z
|
||||
SEQUENCE:2
|
||||
UID:{{{UID}}}
|
||||
DTSTART:{{{START}}}
|
||||
DTEND:{{{END}}}
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY:{{{NAME}}}-single
|
||||
LOCATION:{{{LOCATION}}}
|
||||
DESCRIPTION:{{{NAME}}}
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
@@ -0,0 +1,20 @@
|
||||
BEGIN:VCALENDAR
|
||||
CALSCALE:GREGORIAN
|
||||
VERSION:2.0
|
||||
PRODID:-//IDN nextcloud.com//Calendar app 5.3.0-dev.1//EN
|
||||
BEGIN:VEVENT
|
||||
CREATED:20250428T161339Z
|
||||
DTSTAMP:20250428T172521Z
|
||||
LAST-MODIFIED:20250428T172521Z
|
||||
SEQUENCE:3
|
||||
UID:{{{UID}}}
|
||||
DTSTART:{{{START}}}
|
||||
DTEND:{{{END}}}
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY:{{{NAME}}}-attachment
|
||||
LOCATION:{{{LOCATION}}}
|
||||
DESCRIPTION:{{{NAME}}}
|
||||
ATTACH;FMTTYPE=image/jpeg;FILENAME=/Calendar/signal-2025-03-21-121810_004.j
|
||||
peg;X-NC-FILE-ID=566;X-NC-HAS-PREVIEW=true:/index.php/f/566
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
@@ -0,0 +1,23 @@
|
||||
BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
CALSCALE:GREGORIAN
|
||||
PRODID:-//IDN nextcloud.com//Calendar app 5.3.0-dev.1//EN
|
||||
BEGIN:VEVENT
|
||||
CREATED:20250428T163259Z
|
||||
DTSTAMP:20250428T163714Z
|
||||
LAST-MODIFIED:20250428T163714Z
|
||||
SEQUENCE:2
|
||||
UID:{{{UID}}}
|
||||
DTSTART:{{{START}}}
|
||||
DTEND:{{{END}}}
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY:{{{NAME}}}-attendees
|
||||
LOCATION:{{{LOCATION}}}
|
||||
DESCRIPTION:{{{NAME}}}
|
||||
ATTENDEE;CN=bob;CUTYPE=INDIVIDUAL;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPAN
|
||||
T;RSVP=TRUE;LANGUAGE=en_GB;SCHEDULE-STATUS=1.1:mailto:bob@domain.tld
|
||||
ATTENDEE;CN=Alice Alice;CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED;ROLE=REQ-PARTIC
|
||||
IPANT;LANGUAGE=en_GB;SCHEDULE-STATUS=2.0:mailto:alice@domain.tld
|
||||
ORGANIZER;CN=admin:mailto:admin@example.net
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
@@ -0,0 +1,19 @@
|
||||
BEGIN:VCALENDAR
|
||||
PRODID:-//IDN nextcloud.com//Calendar app 5.3.0-dev.1//EN
|
||||
CALSCALE:GREGORIAN
|
||||
VERSION:2.0
|
||||
BEGIN:VEVENT
|
||||
CREATED:20250430T095901Z
|
||||
DTSTAMP:20250430T095947Z
|
||||
LAST-MODIFIED:20250430T095947Z
|
||||
SEQUENCE:2
|
||||
UID:{{{UID}}}
|
||||
DTSTART:{{{START}}}
|
||||
DTEND:{{{END}}}
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY:{{{NAME}}}-recurring
|
||||
LOCATION:{{{LOCATION}}}
|
||||
DESCRIPTION:{{{NAME}}}
|
||||
RRULE:FREQ=WEEKLY;COUNT=3;BYDAY=TH
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
@@ -0,0 +1,18 @@
|
||||
BEGIN:VCALENDAR
|
||||
PRODID:-//IDN nextcloud.com//Calendar app 5.2.0-dev.1//EN
|
||||
CALSCALE:GREGORIAN
|
||||
VERSION:2.0
|
||||
BEGIN:VEVENT
|
||||
CREATED:20250310T171800Z
|
||||
DTSTAMP:20250310T171819Z
|
||||
LAST-MODIFIED:20250310T171819Z
|
||||
SEQUENCE:2
|
||||
UID:{{{UID}}}
|
||||
DTSTART:{{{START}}}
|
||||
DTEND:{{{END}}}
|
||||
STATUS:CANCELLED
|
||||
SUMMARY:{{{NAME}}}-single
|
||||
LOCATION:{{{LOCATION}}}
|
||||
DESCRIPTION:{{{NAME}}}
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
@@ -0,0 +1,17 @@
|
||||
BEGIN:VCALENDAR
|
||||
PRODID:-//IDN nextcloud.com//Calendar app 5.2.0-dev.1//EN
|
||||
CALSCALE:GREGORIAN
|
||||
VERSION:2.0
|
||||
BEGIN:VEVENT
|
||||
CREATED:20250310T171800Z
|
||||
DTSTAMP:20250310T171819Z
|
||||
LAST-MODIFIED:20250310T171819Z
|
||||
SEQUENCE:2
|
||||
UID:{{{UID}}}
|
||||
DTSTART:{{{START}}}
|
||||
DTEND:{{{END}}}
|
||||
SUMMARY:{{{NAME}}}-no-status
|
||||
LOCATION:{{{LOCATION}}}
|
||||
DESCRIPTION:{{{NAME}}}
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
@@ -0,0 +1,17 @@
|
||||
BEGIN:VCALENDAR
|
||||
PRODID:-//IDN nextcloud.com//Calendar app 5.2.0-dev.1//EN
|
||||
CALSCALE:GREGORIAN
|
||||
VERSION:2.0
|
||||
BEGIN:VEVENT
|
||||
CREATED:20250310T171800Z
|
||||
DTSTAMP:20250310T171819Z
|
||||
LAST-MODIFIED:20250310T171819Z
|
||||
SEQUENCE:2
|
||||
UID:{{{UID}}}
|
||||
DTSTART:{{{START}}}
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY:{{{NAME}}}-no-end
|
||||
LOCATION:{{{LOCATION}}}
|
||||
DESCRIPTION:{{{NAME}}}
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\SpreedCheats\AppInfo;
|
||||
|
||||
use OCA\SpreedCheats\PreferenceListener;
|
||||
use OCA\SpreedCheats\SpeechToText\LoremIpsumSpeechToTextProvider;
|
||||
use OCA\SpreedCheats\Translation\LoremIpsumTranslationProvider;
|
||||
use OCP\AppFramework\App;
|
||||
use OCP\AppFramework\Bootstrap\IBootContext;
|
||||
use OCP\AppFramework\Bootstrap\IBootstrap;
|
||||
use OCP\AppFramework\Bootstrap\IRegistrationContext;
|
||||
use OCP\Config\BeforePreferenceDeletedEvent;
|
||||
|
||||
class Application extends App implements IBootstrap {
|
||||
public const APP_ID = 'spreedcheats';
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct(self::APP_ID);
|
||||
}
|
||||
|
||||
public function register(IRegistrationContext $context): void {
|
||||
$context->registerSpeechToTextProvider(LoremIpsumSpeechToTextProvider::class);
|
||||
$context->registerTranslationProvider(LoremIpsumTranslationProvider::class);
|
||||
$context->registerEventListener(BeforePreferenceDeletedEvent::class, PreferenceListener::class);
|
||||
}
|
||||
|
||||
public function boot(IBootContext $context): void {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\SpreedCheats\Calendar;
|
||||
|
||||
use Sabre\VObject\UUIDUtil;
|
||||
|
||||
class EventGenerator {
|
||||
public static function generateEvents(string $name, string $location, int $start, int $end): array {
|
||||
$files = scandir(__DIR__ . '/../../calendars/');
|
||||
$events = [];
|
||||
$startDate = (new \DateTime())->setTimestamp($start);
|
||||
$endDate = (new \DateTime())->setTimestamp($end);
|
||||
foreach ($files as $file) {
|
||||
if ($file === '.' || $file === '..') {
|
||||
continue;
|
||||
}
|
||||
$calData = file_get_contents(__DIR__ . '/../../calendars/' . $file);
|
||||
if ($calData === false) {
|
||||
continue;
|
||||
}
|
||||
$interval = new \DateInterval('P1D');
|
||||
$startDate->add($interval);
|
||||
$endDate->add($interval);
|
||||
$uid = UUIDUtil::getUUID();
|
||||
$events[] = str_replace(['{{{NAME}}}', '{{{START}}}', '{{{END}}}', '{{{UID}}}', '{{{LOCATION}}}'], [$name, $startDate->format('Ymd\THis'), $endDate->format('Ymd\THis'), $uid, $location], $calData);
|
||||
}
|
||||
return $events;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,353 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\SpreedCheats\Controller;
|
||||
|
||||
use OCA\SpreedCheats\Calendar\EventGenerator;
|
||||
use OCA\Talk\Model\Attendee;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\OCSController;
|
||||
use OCP\Calendar\Exceptions\CalendarException;
|
||||
use OCP\Calendar\ICreateFromString;
|
||||
use OCP\Calendar\IManager;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\IRequest;
|
||||
use OCP\Share\IShare;
|
||||
use Sabre\VObject\Component\VCalendar;
|
||||
use Sabre\VObject\UUIDUtil;
|
||||
|
||||
class ApiController extends OCSController {
|
||||
public function __construct(
|
||||
string $appName,
|
||||
IRequest $request,
|
||||
protected IDBConnection $db,
|
||||
private IManager $calendarManager,
|
||||
private ?string $userId,
|
||||
) {
|
||||
parent::__construct($appName, $request);
|
||||
}
|
||||
|
||||
public function resetSpreed(): DataResponse {
|
||||
$delete = $this->db->getQueryBuilder();
|
||||
$delete->delete('talk_attachments')->executeStatement();
|
||||
|
||||
$delete = $this->db->getQueryBuilder();
|
||||
$delete->delete('talk_attendees')->executeStatement();
|
||||
|
||||
$delete = $this->db->getQueryBuilder();
|
||||
$delete->delete('talk_bots_conversation')->executeStatement();
|
||||
|
||||
$delete = $this->db->getQueryBuilder();
|
||||
$delete->delete('talk_bots_server')->executeStatement();
|
||||
|
||||
$delete = $this->db->getQueryBuilder();
|
||||
$delete->delete('talk_bridges')->executeStatement();
|
||||
|
||||
$delete = $this->db->getQueryBuilder();
|
||||
$delete->delete('talk_commands')
|
||||
->where($delete->expr()->neq('app', $delete->createNamedParameter('')))
|
||||
->andWhere($delete->expr()->neq('command', $delete->createNamedParameter('help')))
|
||||
->executeStatement();
|
||||
|
||||
$delete = $this->db->getQueryBuilder();
|
||||
$delete->delete('talk_consent')->executeStatement();
|
||||
|
||||
$delete = $this->db->getQueryBuilder();
|
||||
$delete->delete('talk_internalsignaling')->executeStatement();
|
||||
|
||||
$delete = $this->db->getQueryBuilder();
|
||||
$delete->delete('talk_invitations')->executeStatement();
|
||||
|
||||
$delete = $this->db->getQueryBuilder();
|
||||
$delete->delete('talk_phone_numbers')->executeStatement();
|
||||
|
||||
$delete = $this->db->getQueryBuilder();
|
||||
$delete->delete('talk_polls')->executeStatement();
|
||||
|
||||
$delete = $this->db->getQueryBuilder();
|
||||
$delete->delete('talk_poll_votes')->executeStatement();
|
||||
|
||||
$delete = $this->db->getQueryBuilder();
|
||||
$delete->delete('talk_proxy_messages')->executeStatement();
|
||||
|
||||
$delete = $this->db->getQueryBuilder();
|
||||
$delete->delete('talk_reminders')->executeStatement();
|
||||
|
||||
$delete = $this->db->getQueryBuilder();
|
||||
$delete->delete('talk_retry_ocm')->executeStatement();
|
||||
|
||||
$delete = $this->db->getQueryBuilder();
|
||||
$delete->delete('talk_rooms')->executeStatement();
|
||||
|
||||
$delete = $this->db->getQueryBuilder();
|
||||
$delete->delete('talk_sessions')->executeStatement();
|
||||
|
||||
$delete = $this->db->getQueryBuilder();
|
||||
$delete->delete('talk_threads')->executeStatement();
|
||||
|
||||
$delete = $this->db->getQueryBuilder();
|
||||
$delete->delete('talk_thread_attendees')->executeStatement();
|
||||
|
||||
$delete = $this->db->getQueryBuilder();
|
||||
$delete->delete('share')
|
||||
->where($delete->expr()->orX(
|
||||
$delete->expr()->eq('share_type', $delete->createNamedParameter(IShare::TYPE_ROOM)),
|
||||
$delete->expr()->eq('share_type', $delete->createNamedParameter(11 /*RoomShareProvider::SHARE_TYPE_USERROOM*/))
|
||||
))
|
||||
->executeStatement();
|
||||
|
||||
|
||||
$delete = $this->db->getQueryBuilder();
|
||||
$delete->delete('preferences')
|
||||
->where($delete->expr()->in('configkey', $delete->createNamedParameter(['changelog', 'note_to_self', 'samples_created'], IQueryBuilder::PARAM_STR_ARRAY)))
|
||||
->andWhere($delete->expr()->eq('appid', $delete->createNamedParameter('spreed')))
|
||||
->executeStatement();
|
||||
|
||||
try {
|
||||
$delete = $this->db->getQueryBuilder();
|
||||
$delete->delete('notifications')
|
||||
->where($delete->expr()->eq('app', $delete->createNamedParameter('spreed')))
|
||||
->executeStatement();
|
||||
} catch (\Throwable $e) {
|
||||
// Ignore
|
||||
}
|
||||
|
||||
$delete = $this->db->getQueryBuilder();
|
||||
$delete->delete('calendarobjects')->executeStatement();
|
||||
|
||||
$delete = $this->db->getQueryBuilder();
|
||||
$delete->delete('calendarobjects_props')->executeStatement();
|
||||
|
||||
|
||||
return new DataResponse();
|
||||
}
|
||||
|
||||
public function ageChat(string $token, int $hours): DataResponse {
|
||||
$query = $this->db->getQueryBuilder();
|
||||
$query->select('id', 'last_activity', 'object_id')
|
||||
->from('talk_rooms')
|
||||
->where($query->expr()->eq('token', $query->createNamedParameter($token)));
|
||||
|
||||
$result = $query->executeQuery();
|
||||
$room = $result->fetch();
|
||||
$result->closeCursor();
|
||||
|
||||
if (!$room) {
|
||||
return new DataResponse(null, Http::STATUS_NOT_FOUND);
|
||||
}
|
||||
$roomId = (int)$room['id'];
|
||||
|
||||
$lastActivity = new \DateTime($room['last_activity']);
|
||||
$lastActivity->sub(new \DateInterval('PT' . $hours . 'H'));
|
||||
|
||||
$update = $this->db->getQueryBuilder();
|
||||
$update->update('talk_rooms')
|
||||
->set('last_activity', $update->createNamedParameter($lastActivity, IQueryBuilder::PARAM_DATETIME_MUTABLE))
|
||||
->where($update->expr()->eq('id', $update->createNamedParameter($roomId)));
|
||||
|
||||
$eventConversationObjectId = explode('#', $room['object_id']);
|
||||
if (count($eventConversationObjectId) === 2) {
|
||||
$eventConversationObjectId[0] -= $hours * 3600;
|
||||
$eventConversationObjectId[1] -= $hours * 3600;
|
||||
$update->set('object_id', $update->createNamedParameter(implode('#', $eventConversationObjectId)));
|
||||
}
|
||||
$update->executeStatement();
|
||||
|
||||
|
||||
$update = $this->db->getQueryBuilder();
|
||||
$update->update('comments')
|
||||
->set('creation_timestamp', $update->createParameter('creation_timestamp'))
|
||||
->set('expire_date', $update->createParameter('expire_date'))
|
||||
->set('meta_data', $update->createParameter('meta_data'))
|
||||
->where($update->expr()->eq('id', $update->createParameter('id')));
|
||||
|
||||
$query = $this->db->getQueryBuilder();
|
||||
$query->select('id', 'creation_timestamp', 'expire_date', 'meta_data')
|
||||
->from('comments')
|
||||
->where($query->expr()->eq('object_type', $query->createNamedParameter('chat')))
|
||||
->andWhere($query->expr()->eq('object_id', $query->createNamedParameter($roomId)));
|
||||
|
||||
$result = $query->executeQuery();
|
||||
while ($row = $result->fetch()) {
|
||||
$creationTimestamp = new \DateTime($row['creation_timestamp']);
|
||||
$creationTimestamp->sub(new \DateInterval('PT' . $hours . 'H'));
|
||||
|
||||
$expireDate = null;
|
||||
if ($row['expire_date']) {
|
||||
$expireDate = new \DateTime($row['expire_date']);
|
||||
$expireDate->sub(new \DateInterval('PT' . $hours . 'H'));
|
||||
}
|
||||
|
||||
$metaData = 'null';
|
||||
if ($row['meta_data'] !== 'null') {
|
||||
$metaData = json_decode($row['meta_data'], true);
|
||||
if (isset($metaData['last_edited_time'])) {
|
||||
$metaData['last_edited_time'] -= $hours * 3600;
|
||||
}
|
||||
$metaData = json_encode($metaData);
|
||||
}
|
||||
|
||||
$update->setParameter('id', $row['id']);
|
||||
$update->setParameter('creation_timestamp', $creationTimestamp, IQueryBuilder::PARAM_DATE);
|
||||
$update->setParameter('expire_date', $expireDate, IQueryBuilder::PARAM_DATE);
|
||||
$update->setParameter('meta_data', $metaData);
|
||||
$update->executeStatement();
|
||||
}
|
||||
$result->closeCursor();
|
||||
|
||||
return new DataResponse();
|
||||
}
|
||||
|
||||
public function forgedFederationLeave(string $token, string $actingUser, string $targetUser): DataResponse {
|
||||
$query = $this->db->getQueryBuilder();
|
||||
$query->select('id')
|
||||
->from('talk_rooms')
|
||||
->where($query->expr()->eq('token', $query->createNamedParameter($token)));
|
||||
|
||||
$result = $query->executeQuery();
|
||||
$roomId = (int)$result->fetchOne();
|
||||
$result->closeCursor();
|
||||
|
||||
$query = $this->db->getQueryBuilder();
|
||||
$query->select('access_token', 'invited_cloud_id')
|
||||
->from('talk_attendees')
|
||||
->where($query->expr()->eq('actor_id', $query->createNamedParameter($actingUser)))
|
||||
->andWhere($query->expr()->eq('actor_type', $query->createNamedParameter(Attendee::ACTOR_USERS)))
|
||||
->andWhere($query->expr()->eq('room_id', $query->createNamedParameter($roomId)));
|
||||
|
||||
$result = $query->executeQuery();
|
||||
$access = $result->fetch();
|
||||
$result->closeCursor();
|
||||
|
||||
$query = $this->db->getQueryBuilder();
|
||||
$query->select('s.session_id')
|
||||
->from('talk_attendees', 'a')
|
||||
->leftJoin('a', 'talk_sessions', 's', $query->expr()->eq('a.id', 's.attendee_id'))
|
||||
->where($query->expr()->eq('actor_id', $query->createNamedParameter($targetUser)))
|
||||
->andWhere($query->expr()->eq('actor_type', $query->createNamedParameter(Attendee::ACTOR_USERS)))
|
||||
->andWhere($query->expr()->eq('room_id', $query->createNamedParameter($roomId)));
|
||||
|
||||
$result = $query->executeQuery();
|
||||
$session = $result->fetch();
|
||||
$result->closeCursor();
|
||||
|
||||
return new DataResponse([
|
||||
'access' => $access,
|
||||
'session' => $session,
|
||||
]);
|
||||
}
|
||||
|
||||
#[NoAdminRequired]
|
||||
public function createDashboardEvents(string $name, string $location): DataResponse {
|
||||
if ($this->userId === null) {
|
||||
return new DataResponse(null, Http::STATUS_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
$calendar = null;
|
||||
$calendars = $this->calendarManager->getCalendarsForPrincipal('principals/users/' . $this->userId);
|
||||
foreach ($calendars as $c) {
|
||||
if ($c instanceof ICreateFromString) {
|
||||
$calendar = $c;
|
||||
}
|
||||
}
|
||||
|
||||
if ($calendar === null) {
|
||||
return new DataResponse(null, Http::STATUS_NOT_FOUND);
|
||||
}
|
||||
|
||||
$start = time();
|
||||
$end = time() + 3600;
|
||||
$events = EventGenerator::generateEvents($name, $location, $start, $end);
|
||||
|
||||
foreach ($events as $event) {
|
||||
try {
|
||||
/** @var ICreateFromString $calendar */
|
||||
$calendar->createFromString(random_int(0, 10000) . '.ics', $event);
|
||||
} catch (CalendarException) {
|
||||
return new DataResponse(null, Http::STATUS_FORBIDDEN);
|
||||
}
|
||||
}
|
||||
|
||||
return new DataResponse();
|
||||
}
|
||||
|
||||
#[NoAdminRequired]
|
||||
public function createEventAndInviteParticipant(string $organizer, string $attendee): DataResponse {
|
||||
if ($this->userId === null) {
|
||||
return new DataResponse(null, Http::STATUS_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
$calendar = null;
|
||||
// Create a calendar event with LOCATION and time via OCP
|
||||
$calendars = $this->calendarManager->getCalendarsForPrincipal('principals/users/' . $this->userId);
|
||||
foreach ($calendars as $c) {
|
||||
if ($c instanceof ICreateFromString) {
|
||||
$calendar = $c;
|
||||
}
|
||||
}
|
||||
|
||||
if ($calendar === null) {
|
||||
return new DataResponse(null, Http::STATUS_NOT_FOUND);
|
||||
}
|
||||
|
||||
$start = time();
|
||||
$end = $start + 3600;
|
||||
$startTime = (new \DateTime())->setTimestamp($start);
|
||||
$endTime = (new \DateTime())->setTimestamp($end);
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$interval = new \DateInterval('PT2H');
|
||||
$startTime->add($interval);
|
||||
$endTime->add($interval);
|
||||
|
||||
$vCalendar = new VCalendar();
|
||||
$vevent = $vCalendar->createComponent('VEVENT');
|
||||
$vevent->add('UID', UUIDUtil::getUUID());
|
||||
$vevent->add('DTSTART');
|
||||
$vevent->DTSTART->setDateTime($startTime);
|
||||
$vevent->add('DTEND');
|
||||
$vevent->DTEND->setDateTime($endTime);
|
||||
$vevent->add('SUMMARY', 'Test');
|
||||
$vevent->add('DESCRIPTION', 'Test');
|
||||
$vevent->add('ORGANIZER', 'mailto:' . $organizer . '@example.tld', ['CN' => $organizer]);
|
||||
$vevent->add('ATTENDEE', 'mailto:' . $attendee . '@example.tld', [
|
||||
'CN' => $attendee,
|
||||
'CUTYPE' => 'INDIVIDUAL',
|
||||
'PARTSTAT' => 'NEEDS-ACTION',
|
||||
'ROLE' => 'REQ-PARTICIPANT',
|
||||
'RSVP' => 'TRUE'
|
||||
]);
|
||||
$vevent->add('STATUS', 'CONFIRMED');
|
||||
$vCalendar->add($vevent);
|
||||
if ($i === 1) {
|
||||
$vevent->add('ATTACH', '/index.php/f/3226', [
|
||||
'FMTTYPE' => 'application/pdf',
|
||||
'FILENAME' => 'test.pdf',
|
||||
]);
|
||||
}
|
||||
if ($i === 2) {
|
||||
$vevent->add('ATTACH', '/index.php/f/3226', [
|
||||
'FMTTYPE' => 'application/pdf',
|
||||
'FILENAME' => 'test.pdf',
|
||||
'X-NC-FILE-ID' => '3226',
|
||||
'X-NC-HAS-PREVIEW' => 'false'
|
||||
]);
|
||||
}
|
||||
$cal = $vCalendar->serialize();
|
||||
try {
|
||||
/** @var ICreateFromString $calendar */
|
||||
$calendar->createFromString(random_int(0, 10000) . '.ics', $cal);
|
||||
} catch (CalendarException) {
|
||||
return new DataResponse(null, Http::STATUS_FORBIDDEN);
|
||||
}
|
||||
}
|
||||
return new DataResponse();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\SpreedCheats;
|
||||
|
||||
use OCP\Config\BeforePreferenceDeletedEvent;
|
||||
use OCP\EventDispatcher\Event;
|
||||
use OCP\EventDispatcher\IEventListener;
|
||||
|
||||
/**
|
||||
* @template-implements IEventListener<Event>
|
||||
*/
|
||||
class PreferenceListener implements IEventListener {
|
||||
public function handle(Event $event): void {
|
||||
if (!$event instanceof BeforePreferenceDeletedEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($event->getAppId() === 'spreed') {
|
||||
$event->setValid(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\SpreedCheats\SpeechToText;
|
||||
|
||||
use OCP\Files\File;
|
||||
use OCP\SpeechToText\ISpeechToTextProvider;
|
||||
|
||||
class LoremIpsumSpeechToTextProvider implements ISpeechToTextProvider {
|
||||
|
||||
public function getName(): string {
|
||||
return 'Lorem ipsum - Talk Integrationtests';
|
||||
}
|
||||
|
||||
public function transcribeFile(File $file): string {
|
||||
if (str_contains($file->getName(), 'leave')) {
|
||||
throw new \RuntimeException('Transcription failed by name');
|
||||
}
|
||||
|
||||
sleep(1); // make sure Postgres manages the order of the messages
|
||||
return 'Lorem ipsum';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\SpreedCheats\Translation;
|
||||
|
||||
use OCP\Translation\ITranslationProvider;
|
||||
use OCP\Translation\LanguageTuple;
|
||||
|
||||
class LoremIpsumTranslationProvider implements ITranslationProvider {
|
||||
public function getName(): string {
|
||||
return 'Lorem ipsum - Talk Integrationtests';
|
||||
}
|
||||
|
||||
public function getAvailableLanguages(): array {
|
||||
return [
|
||||
new LanguageTuple(
|
||||
'en',
|
||||
'English',
|
||||
'lorem',
|
||||
'Lorem ipsum',
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
public function translate(?string $fromLanguage, string $toLanguage, string $text): string {
|
||||
return 'Lorem ipsum';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user