kopia lustrzana https://github.com/nextcloud/social
commit
5ec03e2db5
|
@ -11,50 +11,78 @@ env:
|
|||
APP_NAME: social
|
||||
BRANCH: ${{ github.base_ref }}
|
||||
CYPRESS_baseUrl: http://127.0.0.1:8082/index.php
|
||||
TESTING: true
|
||||
|
||||
jobs:
|
||||
cypress:
|
||||
init:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# run 2 copies of the current job in parallel
|
||||
containers: [1, 2]
|
||||
node-version: ['12']
|
||||
php-versions: ['7.4']
|
||||
|
||||
name: Runner ${{ matrix.containers }}
|
||||
|
||||
steps:
|
||||
- name: Checkout app
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup server
|
||||
run: |
|
||||
cd cypress
|
||||
docker-compose up -d
|
||||
- name: Set up node ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
- name: Read package.json node and npm engines version
|
||||
uses: skjnldsv/read-package-engines-version-actions@v1.1
|
||||
id: versions
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
fallbackNode: "^12"
|
||||
fallbackNpm: "^6"
|
||||
|
||||
- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: "npm"
|
||||
node-version: ${{ steps.versions.outputs.nodeVersion }}
|
||||
|
||||
- name: Set up npm ${{ steps.versions.outputs.npmVersion }}
|
||||
run: npm i -g npm@"${{ steps.versions.outputs.npmVersion }}"
|
||||
|
||||
- name: Install dependencies & build app
|
||||
run: |
|
||||
npm ci
|
||||
composer install
|
||||
TESTING=true npm run build --if-present
|
||||
- name: Wait for server
|
||||
|
||||
- name: Save context
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
key: cypress-context-${{ github.run_id }}
|
||||
path: /home/runner/work/social
|
||||
|
||||
cypress:
|
||||
runs-on: ubuntu-latest
|
||||
needs: init
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# run multiple copies of the current job in parallel
|
||||
containers: [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
|
||||
name: runner ${{ matrix.containers }}
|
||||
|
||||
steps:
|
||||
- name: Restore context
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
key: cypress-context-${{ github.run_id }}
|
||||
path: /home/runner/work/social
|
||||
|
||||
- name: Setup server
|
||||
run: |
|
||||
npm install -g wait-on
|
||||
wait-on -i 500 -t 240000 $CYPRESS_baseUrl
|
||||
cd cypress
|
||||
docker-compose up -d
|
||||
|
||||
- name: Wait for server
|
||||
run: npm run wait-on $CYPRESS_baseUrl
|
||||
|
||||
- name: Enable app & configure server
|
||||
run: |
|
||||
cd cypress
|
||||
docker-compose exec --env APP_NAME=${{ env.APP_NAME }} -T nextcloud bash /initserver.sh
|
||||
docker-compose exec --env APP_NAME=${{ env.APP_NAME }} --env BRANCH=${{ env.BRANCH }} -T nextcloud bash /initserver.sh
|
||||
|
||||
- name: Cypress run
|
||||
uses: cypress-io/github-action@v1
|
||||
uses: cypress-io/github-action@v4
|
||||
with:
|
||||
record: true
|
||||
parallel: true
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
const { defineConfig } = require('cypress')
|
||||
const browserify = require('@cypress/browserify-preprocessor')
|
||||
|
||||
module.exports = defineConfig({
|
||||
projectId: '7mqhfh',
|
||||
|
||||
viewportWidth: 1280,
|
||||
viewportHeight: 720,
|
||||
defaultCommandTimeout: 6000,
|
||||
retries: 1,
|
||||
|
||||
env: {
|
||||
failSilently: false,
|
||||
type: 'actual',
|
||||
},
|
||||
|
||||
screenshotsFolder: 'cypress/snapshots/actual',
|
||||
trashAssetsBeforeRuns: true,
|
||||
|
||||
e2e: {
|
||||
baseUrl: 'http://localhost:8082/index.php',
|
||||
|
||||
setupNodeEvents(on, config) {
|
||||
// Fix browserslist extend https://github.com/cypress-io/cypress/issues/2983#issuecomment-570616682
|
||||
on('file:preprocessor', browserify())
|
||||
},
|
||||
},
|
||||
})
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"baseUrl": "http://localhost:8082/index.php/",
|
||||
"projectId": "7mqhfh",
|
||||
"viewportWidth": 1280,
|
||||
"viewportHeight": 720,
|
||||
"defaultCommandTimeout": 6000
|
||||
}
|
|
@ -1,16 +1,18 @@
|
|||
version: '3'
|
||||
version: '3.7'
|
||||
|
||||
services:
|
||||
nextcloud:
|
||||
image: nextcloudci/server
|
||||
image: ghcr.io/nextcloud/continuous-integration-shallow-server
|
||||
|
||||
ports:
|
||||
- 8082:80
|
||||
|
||||
environment:
|
||||
CYPRESS_baseUrl: "http://127.0.0.1:8082/index.php"
|
||||
BRANCH: master
|
||||
BRANCH: "${BRANCH:-master}"
|
||||
|
||||
volumes:
|
||||
- ../:/var/www/html/apps/social
|
||||
# Using fallback to make sure this script doesn't mess
|
||||
# with the mounting if APP_NAME is not provided.
|
||||
- ../:/var/www/html/apps/${APP_NAME:-social}
|
||||
- ./initserver.sh:/initserver.sh
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
let userId = 'janedoe' + Date.now();
|
||||
const userId = 'janedoe' + Date.now()
|
||||
|
||||
describe('Social app setup', function() {
|
||||
before(function() {
|
||||
|
@ -6,10 +6,6 @@ describe('Social app setup', function() {
|
|||
cy.login(userId, 'p4ssw0rd')
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
Cypress.Cookies.preserveOnce('nc_username', 'nc_token', 'nc_session_id', 'oc_sessionPassphrase');
|
||||
})
|
||||
|
||||
it('See the welcome message', function() {
|
||||
cy.visit('/apps/social/')
|
||||
cy.get('.social__welcome').should('contain', 'Nextcloud becomes part of the federated social networks!')
|
||||
|
@ -26,7 +22,7 @@ describe('Social app setup', function() {
|
|||
cy.get('.app-navigation').contains('Direct messages').click()
|
||||
cy.get('.emptycontent').should('be.visible').contains('No direct messages found')
|
||||
cy.get('.app-navigation').contains('Profile').click()
|
||||
cy.get('.emptycontent').should('be.visible').contains('You haven\'t tooted yet')
|
||||
cy.get('.emptycontent').should('be.visible').contains('You have not tooted yet')
|
||||
})
|
||||
|
||||
})
|
|
@ -20,15 +20,17 @@
|
|||
*
|
||||
*/
|
||||
|
||||
let userId = 'janedoe' + Date.now();
|
||||
const userId = 'janedoe' + Date.now()
|
||||
|
||||
describe('Create posts', function() {
|
||||
|
||||
before(function() {
|
||||
// ensure that the admin account is initialized for social
|
||||
cy.login('admin', 'admin', '/apps/social/')
|
||||
|
||||
|
||||
cy.nextcloudCreateUser(userId, 'p4ssw0rd')
|
||||
cy.logout()
|
||||
|
||||
cy.login(userId, 'p4ssw0rd', '/apps/social/')
|
||||
cy.get('.app-content').should('be.visible')
|
||||
})
|
||||
|
@ -37,10 +39,6 @@ describe('Create posts', function() {
|
|||
cy.screenshot()
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
Cypress.Cookies.preserveOnce('nc_username', 'nc_token', 'nc_session_id', 'oc_sessionPassphrase');
|
||||
})
|
||||
|
||||
it('See the empty content illustration', function() {
|
||||
cy.get('.emptycontent').should('be.visible').contains('No posts found')
|
||||
})
|
||||
|
@ -49,19 +47,19 @@ describe('Create posts', function() {
|
|||
cy.visit('/apps/social/')
|
||||
cy.server()
|
||||
cy.route('POST', '/index.php/apps/social/api/v1/post').as('postMessage')
|
||||
cy.get('.new-post input[type=submit]')
|
||||
cy.get('.new-post button[type=submit]')
|
||||
.should('be.disabled')
|
||||
cy.get('.new-post').find('[contenteditable]').type('Hello world')
|
||||
cy.get('.new-post input[type=submit]')
|
||||
cy.get('.new-post button[type=submit]')
|
||||
.should('not.be.disabled')
|
||||
cy.get('.new-post input[type=submit]')
|
||||
cy.get('.new-post button[type=submit]')
|
||||
.click()
|
||||
cy.wait('@postMessage')
|
||||
cy.get('.social__timeline div.timeline-entry:first-child').should('contain', 'Hello world')
|
||||
})
|
||||
|
||||
it('No longer see the empty content illustration', function() {
|
||||
cy.get('.emptycontent').should('not.be.visible')
|
||||
cy.get('.emptycontent').should('not.exist')
|
||||
})
|
||||
|
||||
it('Write a post to followers with shift enter', function() {
|
||||
|
@ -78,11 +76,11 @@ describe('Create posts', function() {
|
|||
cy.server()
|
||||
cy.route('POST', '/index.php/apps/social/api/v1/post').as('postMessage')
|
||||
cy.route('GET', '/index.php/apps/social/api/v1/global/accounts/search')
|
||||
cy.get('.new-post').find('[contenteditable]').type('@adm', {delay: 500})
|
||||
cy.get('.new-post').find('[contenteditable]').type('@adm', { delay: 500 })
|
||||
cy.get('.tribute-container').should('be.visible')
|
||||
cy.get('.tribute-container ul li:first').contains('admin')
|
||||
cy.get('.new-post').find('[contenteditable]').type('{enter} Hello there', {delay: 100, force: true})
|
||||
cy.get('.new-post input[type=submit]')
|
||||
cy.get('.new-post').find('[contenteditable]').type('{enter} Hello there', { delay: 100, force: true })
|
||||
cy.get('.new-post button[type=submit]')
|
||||
.click()
|
||||
cy.wait('@postMessage')
|
||||
cy.get('.social__timeline div.timeline-entry:first-child').should('contain', '@admin')
|
||||
|
@ -93,9 +91,9 @@ describe('Create posts', function() {
|
|||
cy.server()
|
||||
cy.route('POST', '/index.php/apps/social/api/v1/post').as('postMessage')
|
||||
cy.route('GET', '/index.php/apps/social/api/v1/global/accounts/search')
|
||||
cy.get('.new-post').find('[contenteditable]').click({force: true}).type('@adm{enter} Hello world', {delay: 500, force: true})
|
||||
cy.get('.new-post').find('[contenteditable]').click({ force: true }).type('@adm{enter} Hello world', { delay: 500, force: true })
|
||||
cy.wait(500)
|
||||
cy.get('.new-post input[type=submit]').should('not.be.disabled')
|
||||
cy.get('.new-post button[type=submit]').should('not.be.disabled')
|
||||
const visibilityButton = cy.get('.new-post .options > div > button')
|
||||
visibilityButton.should('have.class', 'icon-contacts-dark')
|
||||
|
||||
|
@ -105,7 +103,7 @@ describe('Create posts', function() {
|
|||
visibilityButton.click()
|
||||
cy.get('.new-post-form .popovermenu').should('not.be.visible')
|
||||
|
||||
cy.get('.new-post input[type=submit]')
|
||||
cy.get('.new-post button[type=submit]')
|
||||
.click()
|
||||
cy.wait('@postMessage')
|
||||
cy.get('.social__timeline div.timeline-entry:first-child').should('contain', 'Hello world').should('contain', '@admin')
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
echo "APP_NAME: $APP_NAME"
|
||||
echo "BRANCH: $BRANCH"
|
||||
|
||||
chown -R www-data:www-data /var/www/html/data
|
||||
|
||||
su www-data -c "
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
// ***********************************************************
|
||||
// This example plugins/index.js can be used to load plugins
|
||||
//
|
||||
// You can change the location of this file or turn off loading
|
||||
// the plugins file with the 'pluginsFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/plugins-guide
|
||||
// ***********************************************************
|
||||
|
||||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
|
||||
const {
|
||||
addMatchImageSnapshotPlugin
|
||||
} = require('cypress-image-snapshot/plugin')
|
||||
|
||||
module.exports = (on, config) => {
|
||||
addMatchImageSnapshotPlugin(on, config)
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
# RUN THIS SCRIPT FROM THE ROOT FOLDER OF YOUR APP
|
||||
APP_NAME=${PWD##*/}
|
||||
CYPRESS_baseUrl=http://127.0.0.1:8082/index.php
|
||||
|
||||
if [[ $APP_NAME == "cypress" ]]
|
||||
then
|
||||
|
@ -8,13 +9,11 @@ then
|
|||
else
|
||||
echo "Launching docker server for the $APP_NAME app"
|
||||
cd cypress
|
||||
docker-compose up -d
|
||||
echo -n "Waiting for server start "
|
||||
until [[ $(docker-compose exec -u www-data -T nextcloud php ./occ status --output=json) == *"\"installed\":true"* ]]
|
||||
do
|
||||
echo -n "."
|
||||
done
|
||||
echo ""
|
||||
docker-compose pull
|
||||
docker-compose up -d --force-recreate
|
||||
npm run wait-on $CYPRESS_baseUrl
|
||||
echo "Nextcloud successfully installed"
|
||||
docker-compose exec --env APP_NAME=$APP_NAME -T nextcloud bash /initserver.sh
|
||||
docker-compose exec -u www-data -T nextcloud php ./occ social:reset -n
|
||||
docker-compose exec -u www-data -T nextcloud php ./occ social:reset -n
|
||||
echo "Nextcloud successfully configured"
|
||||
fi
|
||||
|
|
|
@ -20,37 +20,45 @@
|
|||
*
|
||||
*/
|
||||
|
||||
import { addMatchImageSnapshotCommand } from 'cypress-image-snapshot/command'
|
||||
import axios from '@nextcloud/axios'
|
||||
|
||||
addMatchImageSnapshotCommand()
|
||||
|
||||
const url = Cypress.config('baseUrl').replace(/\/index.php\/?$/g, '')
|
||||
Cypress.env('baseUrl', url)
|
||||
|
||||
Cypress.Commands.add('login', (user, password, route = '/apps/files') => {
|
||||
cy.clearCookies();
|
||||
Cypress.Cookies.defaults({
|
||||
preserve: /^(oc|nc)/,
|
||||
})
|
||||
cy.visit(route)
|
||||
cy.get('input[name=user]').type(user)
|
||||
cy.get('input[name=password]').type(password)
|
||||
cy.get('#submit-wrapper input[type=submit]').click()
|
||||
cy.get('form[name=login] [type=submit]').click()
|
||||
cy.url().should('include', route)
|
||||
})
|
||||
|
||||
Cypress.Commands.add('logout', () => {
|
||||
if (Cypress.$("input[name=user]").length > 0) {
|
||||
// already logged out
|
||||
} else {
|
||||
cy.get('#expanddiv li[data-id="logout"] a').then(logout => {
|
||||
if (logout) {
|
||||
cy.visit(logout[0].href)
|
||||
cy.getCookies()
|
||||
.then(cookies => {
|
||||
if (cookies.length === 0) {
|
||||
cy.log('Not logged, skipping logout...')
|
||||
return
|
||||
}
|
||||
|
||||
return cy.get('body')
|
||||
.then($body => {
|
||||
const $settingsButton = $body.find('#settings #expand')
|
||||
if ($settingsButton.length === 0) {
|
||||
cy.log('Not logged in.')
|
||||
return
|
||||
}
|
||||
|
||||
$settingsButton.click()
|
||||
cy.contains('Log out').click()
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
Cypress.Commands.add('nextcloudCreateUser', (user, password) => {
|
||||
cy.clearCookies();
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: `${Cypress.env('baseUrl')}/ocs/v1.php/cloud/users?format=json`,
|
||||
|
@ -61,13 +69,12 @@ Cypress.Commands.add('nextcloudCreateUser', (user, password) => {
|
|||
},
|
||||
auth: { user: 'admin', pass: 'admin' },
|
||||
headers: {
|
||||
'OCS-ApiRequest': 'true',
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
Authorization: `Basic ${btoa('admin:admin')}`,
|
||||
'OCS-ApiRequest': 'true',
|
||||
Authorization: `Basic ${Buffer.from('admin:admin').toString('base64')}`,
|
||||
},
|
||||
}).then(response => {
|
||||
cy.log(`Created user ${user}`, response.status)
|
||||
})
|
||||
cy.clearCookies()
|
||||
})
|
||||
|
||||
Cypress.Commands.add('uploadFile', (fileName, mimeType, path = '') => {
|
||||
|
@ -82,7 +89,7 @@ Cypress.Commands.add('uploadFile', (fileName, mimeType, path = '') => {
|
|||
headers: {
|
||||
requesttoken: window.OC.requestToken,
|
||||
'Content-Type': mimeType,
|
||||
}
|
||||
},
|
||||
}).then(response => {
|
||||
cy.log(`Uploaded ${fileName}`, response)
|
||||
})
|
||||
|
@ -122,7 +129,7 @@ Cypress.Commands.add('deleteFile', fileName => {
|
|||
* Create a share link and return the share url
|
||||
*
|
||||
* @param {string} path the file/folder path
|
||||
* @returns {string} the share link url
|
||||
* @return {string} the share link url
|
||||
*/
|
||||
Cypress.Commands.add('createLinkShare', path => {
|
||||
return cy.window().then(async window => {
|
||||
|
@ -133,26 +140,15 @@ Cypress.Commands.add('createLinkShare', path => {
|
|||
}, {
|
||||
headers: {
|
||||
requesttoken: window.OC.requestToken,
|
||||
}
|
||||
},
|
||||
})
|
||||
if (!('ocs' in request.data) || !('token' in request.data.ocs.data && request.data.ocs.data.token.length > 0)) {
|
||||
throw request
|
||||
}
|
||||
cy.log('Share link created', request.data.ocs.data.token)
|
||||
return cy.wrap(request.data.ocs.data.token)
|
||||
} catch(error) {
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}).should('have.length', 15)
|
||||
})
|
||||
|
||||
Cypress.Commands.overwrite('matchImageSnapshot', (originalFn, subject, name, options) => {
|
||||
// hide avatar because random colour break the visual regression tests
|
||||
cy.window().then(window => {
|
||||
const avatarDiv = window.document.querySelector('.avatardiv')
|
||||
if (avatarDiv) {
|
||||
avatarDiv.remove()
|
||||
}
|
||||
})
|
||||
return originalFn(subject, name, options)
|
||||
})
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// ***********************************************************
|
||||
// This example support/index.js is processed and
|
||||
// This example support/e2e.js is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
|
@ -14,7 +14,4 @@
|
|||
// ***********************************************************
|
||||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands'
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
||||
import './commands.js'
|
|
@ -185,7 +185,7 @@ class AP {
|
|||
*/
|
||||
public function getItemFromData(array $data, ACore $parent = null, int $level = 0): ACore {
|
||||
if (++$level > self::REDUNDANCY_LIMIT) {
|
||||
throw new RedundancyLimitException($level);
|
||||
throw new RedundancyLimitException((string)$level);
|
||||
}
|
||||
|
||||
$item = $this->getSimpleItemFromData($data);
|
||||
|
|
|
@ -50,7 +50,6 @@ use OCA\Social\Service\StreamQueueService;
|
|||
use OCA\Social\Service\StreamService;
|
||||
use OCA\Social\Tools\Traits\TAsync;
|
||||
use OCA\Social\Tools\Traits\TNCDataResponse;
|
||||
use OCA\Social\Tools\Traits\TNCLogger;
|
||||
use OCA\Social\Tools\Traits\TStringTools;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
|
@ -63,7 +62,6 @@ class ActivityPubController extends Controller {
|
|||
use TNCDataResponse;
|
||||
use TStringTools;
|
||||
use TAsync;
|
||||
use TNCLogger;
|
||||
|
||||
private SocialPubController $socialPubController;
|
||||
private FediverseService $fediverseService;
|
||||
|
|
|
@ -12,6 +12,9 @@ use OCP\EventDispatcher\IEventListener;
|
|||
use OCP\Profile\BeforeTemplateRenderedEvent;
|
||||
use OCP\Util;
|
||||
|
||||
/**
|
||||
* @template-implements IEventListener<\OCP\EventDispatcher\Event>
|
||||
*/
|
||||
class ProfileSectionListener implements IEventListener {
|
||||
public function handle(Event $event): void {
|
||||
if (!($event instanceof BeforeTemplateRenderedEvent)) {
|
||||
|
|
|
@ -70,17 +70,12 @@ class ACore extends Item implements JsonSerializable {
|
|||
private $parent = null;
|
||||
|
||||
private string $requestToken = '';
|
||||
|
||||
private array $entries = [];
|
||||
|
||||
private ?\OCA\Social\Model\ActivityPub\ACore $object = null;
|
||||
|
||||
private ?ACore $object = null;
|
||||
private ?Document $icon = null;
|
||||
|
||||
private bool $displayW3ContextSecurity = false;
|
||||
|
||||
private ?LinkedDataSignature $signature = null;
|
||||
|
||||
private int $format = self::FORMAT_ACTIVITYPUB;
|
||||
|
||||
|
||||
|
@ -151,9 +146,9 @@ class ACore extends Item implements JsonSerializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @return ACore
|
||||
* @return null|self
|
||||
*/
|
||||
public function getObject(): ACore {
|
||||
public function getObject(): ?ACore {
|
||||
return $this->object;
|
||||
}
|
||||
|
||||
|
@ -162,7 +157,7 @@ class ACore extends Item implements JsonSerializable {
|
|||
*
|
||||
* @return ACore
|
||||
*/
|
||||
public function setObject(ACore &$object): ACore {
|
||||
public function setObject(ACore $object): self {
|
||||
$object->setParent($this);
|
||||
$this->object = $object;
|
||||
|
||||
|
@ -205,10 +200,7 @@ class ACore extends Item implements JsonSerializable {
|
|||
return ($this->icon !== null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Document
|
||||
*/
|
||||
public function getIcon(): Document {
|
||||
public function getIcon(): ?Document {
|
||||
return $this->icon;
|
||||
}
|
||||
|
||||
|
@ -217,7 +209,7 @@ class ACore extends Item implements JsonSerializable {
|
|||
*
|
||||
* @return ACore
|
||||
*/
|
||||
public function setIcon(Document &$icon): ACore {
|
||||
public function setIcon(Document $icon): ACore {
|
||||
$icon->setParent($this);
|
||||
$this->icon = $icon;
|
||||
|
||||
|
@ -255,14 +247,11 @@ class ACore extends Item implements JsonSerializable {
|
|||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function gotSignature(): bool {
|
||||
public function hasSignature(): bool {
|
||||
return ($this->signature !== null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LinkedDataSignature
|
||||
*/
|
||||
public function getSignature(): LinkedDataSignature {
|
||||
public function getSignature(): ?LinkedDataSignature {
|
||||
return $this->signature;
|
||||
}
|
||||
|
||||
|
@ -694,14 +683,14 @@ class ACore extends Item implements JsonSerializable {
|
|||
* @return array
|
||||
*/
|
||||
public function exportAsActivityPub(): array {
|
||||
if ($this->gotSignature()) {
|
||||
if ($this->hasSignature()) {
|
||||
$this->entries['signature'] = $this->getSignature();
|
||||
}
|
||||
|
||||
if ($this->isRoot()) {
|
||||
$context = [self::CONTEXT_ACTIVITYSTREAMS];
|
||||
|
||||
if ($this->gotSignature() || $this->isDisplayW3ContextSecurity()) {
|
||||
if ($this->hasSignature() || $this->isDisplayW3ContextSecurity()) {
|
||||
array_push($context, self::CONTEXT_SECURITY);
|
||||
}
|
||||
|
||||
|
|
|
@ -228,10 +228,7 @@ class Instance implements IQueryRow, JsonSerializable {
|
|||
return ($this->contactAccount !== null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Person
|
||||
*/
|
||||
public function getContactAccount(): Person {
|
||||
public function getContactAccount(): ?Person {
|
||||
return $this->contactAccount;
|
||||
}
|
||||
|
||||
|
|
|
@ -158,10 +158,7 @@ class RequestQueue implements JsonSerializable {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return InstancePath
|
||||
*/
|
||||
public function getInstance(): InstancePath {
|
||||
public function getInstance(): ?InstancePath {
|
||||
return $this->instance;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Social\Search;
|
||||
|
||||
use OCA\Social\Tools\Traits\TNCLogger;
|
||||
use OCA\Social\Tools\Traits\TArrayTools;
|
||||
use Exception;
|
||||
use OCA\Social\Exceptions\AccountDoesNotExistException;
|
||||
|
@ -58,30 +57,17 @@ class UnifiedSearchProvider implements IProvider {
|
|||
public const PROVIDER_ID = 'social';
|
||||
public const ORDER = 12;
|
||||
|
||||
|
||||
use TArrayTools;
|
||||
use TNCLogger;
|
||||
|
||||
|
||||
private IL10N $l10n;
|
||||
|
||||
private IURLGenerator $urlGenerator;
|
||||
|
||||
private StreamService $streamService;
|
||||
|
||||
private FollowService $followService;
|
||||
|
||||
private CacheActorService $cacheActorService;
|
||||
|
||||
private AccountService $accountService;
|
||||
|
||||
private SearchService $searchService;
|
||||
|
||||
private ConfigService $configService;
|
||||
|
||||
private MiscService $miscService;
|
||||
|
||||
|
||||
private ?Person $viewer = null;
|
||||
|
||||
|
||||
|
|
|
@ -30,14 +30,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Social\Service;
|
||||
|
||||
use OCA\Social\Tools\Exceptions\MalformedArrayException;
|
||||
use OCA\Social\Tools\Exceptions\RequestContentException;
|
||||
use OCA\Social\Tools\Exceptions\RequestNetworkException;
|
||||
use OCA\Social\Tools\Exceptions\RequestResultNotJsonException;
|
||||
use OCA\Social\Tools\Exceptions\RequestResultSizeException;
|
||||
use OCA\Social\Tools\Exceptions\RequestServerException;
|
||||
use OCA\Social\Tools\Traits\TNCLogger;
|
||||
use OCA\Social\Tools\Traits\TArrayTools;
|
||||
use Exception;
|
||||
use OCA\Social\AP;
|
||||
use OCA\Social\Db\CacheActorsRequest;
|
||||
|
@ -51,7 +43,15 @@ use OCA\Social\Exceptions\RetrieveAccountFormatException;
|
|||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
use OCA\Social\Exceptions\UnauthorizedFediverseException;
|
||||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||
use OCA\Social\Tools\Exceptions\MalformedArrayException;
|
||||
use OCA\Social\Tools\Exceptions\RequestContentException;
|
||||
use OCA\Social\Tools\Exceptions\RequestNetworkException;
|
||||
use OCA\Social\Tools\Exceptions\RequestResultNotJsonException;
|
||||
use OCA\Social\Tools\Exceptions\RequestResultSizeException;
|
||||
use OCA\Social\Tools\Exceptions\RequestServerException;
|
||||
use OCA\Social\Tools\Traits\TArrayTools;
|
||||
use OCP\IURLGenerator;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Class CacheActorService
|
||||
|
@ -60,28 +60,31 @@ use OCP\IURLGenerator;
|
|||
*/
|
||||
class CacheActorService {
|
||||
use TArrayTools;
|
||||
use TNCLogger;
|
||||
|
||||
private \OCP\IURLGenerator $urlGenerator;
|
||||
private CacheActorsRequest $cacheActorsRequest;
|
||||
private CurlService $curlService;
|
||||
private FediverseService $fediverseService;
|
||||
private ConfigService $configService;
|
||||
private MiscService $miscService;
|
||||
private LoggerInterface $logger;
|
||||
|
||||
/**
|
||||
* CacheService constructor.
|
||||
* CacheActorService constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
IUrlGenerator $urlGenerator, CacheActorsRequest $cacheActorsRequest, CurlService $curlService,
|
||||
FediverseService $fediverseService, ConfigService $configService, MiscService $miscService
|
||||
IUrlGenerator $urlGenerator,
|
||||
CacheActorsRequest $cacheActorsRequest,
|
||||
CurlService $curlService,
|
||||
FediverseService $fediverseService,
|
||||
ConfigService $configService,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
$this->cacheActorsRequest = $cacheActorsRequest;
|
||||
$this->curlService = $curlService;
|
||||
$this->fediverseService = $fediverseService;
|
||||
$this->configService = $configService;
|
||||
$this->miscService = $miscService;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
|
||||
|
@ -127,7 +130,7 @@ class CacheActorService {
|
|||
} catch (CacheActorDoesNotExistException $e) {
|
||||
$object = $this->curlService->retrieveObject($id);
|
||||
|
||||
$this->debug('object retrieved', ['id' => $id, 'object' => $object]);
|
||||
$this->logger->debug('object retrieved', ['id' => $id, 'object' => $object]);
|
||||
|
||||
/** @var Person $actor */
|
||||
$actor = AP::$activityPub->getItemFromData($object);
|
||||
|
@ -205,14 +208,14 @@ class CacheActorService {
|
|||
} catch (CacheActorDoesNotExistException $e) {
|
||||
}
|
||||
|
||||
$this->debug('getFromAccount', ['account' => $account, 'retrieve' => $retrieve]);
|
||||
$this->logger->debug('getFromAccount', ['account' => $account, 'retrieve' => $retrieve]);
|
||||
|
||||
try {
|
||||
$actor = $this->cacheActorsRequest->getFromAccount($account);
|
||||
|
||||
$this->debug('Found Actor', ['account' => $account, 'actor' => $actor]);
|
||||
$this->logger->debug('Found Actor', ['account' => $account, 'actor' => $actor]);
|
||||
} catch (CacheActorDoesNotExistException $e) {
|
||||
$this->debug('Actor not found', ['account' => $account]);
|
||||
$this->logger->debug('Actor not found', ['account' => $account]);
|
||||
|
||||
if (!$retrieve) {
|
||||
throw new CacheActorDoesNotExistException();
|
||||
|
@ -221,7 +224,7 @@ class CacheActorService {
|
|||
$actor = $this->curlService->retrieveAccount($account);
|
||||
$actor->setAccount($account);
|
||||
try {
|
||||
$this->warning('Saving Actor', false, ['actor' => $actor]);
|
||||
$this->logger->debug('Saving Actor', ['actor' => $actor]);
|
||||
|
||||
$this->save($actor);
|
||||
} catch (Exception $e) {
|
||||
|
|
|
@ -203,16 +203,19 @@ class CacheDocumentService {
|
|||
|
||||
|
||||
/**
|
||||
* @param $content
|
||||
* @param string $content
|
||||
*/
|
||||
private function resizeImage(&$content) {
|
||||
private function resizeImage(string &$content) {
|
||||
try {
|
||||
$image = ImageResize::createFromString($content);
|
||||
$image->quality_jpg = 100;
|
||||
$image->quality_png = 9;
|
||||
|
||||
$image->resizeToBestFit(self::RESIZED_WIDTH, self::RESIZED_HEIGHT);
|
||||
$content = $image->getImageAsString();
|
||||
$newContent = $image->getImageAsString();
|
||||
if (!$newContent) {
|
||||
$content = $newContent;
|
||||
}
|
||||
} catch (ImageResizeException $e) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -276,8 +276,10 @@ class ConfigService {
|
|||
* @param $key
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @psalm-param string $key
|
||||
*/
|
||||
public function getSystemValue($key) {
|
||||
public function getSystemValue(string $key) {
|
||||
return $this->config->getSystemValue($key, '');
|
||||
}
|
||||
|
||||
|
|
|
@ -238,7 +238,7 @@ class CurlService {
|
|||
* @throws SocialAppConfigException
|
||||
* @throws UnauthorizedFediverseException
|
||||
*/
|
||||
public function retrieveObject($id): array {
|
||||
public function retrieveObject(string $id): array {
|
||||
$this->logger->debug('retrieveObject id=' . $id);
|
||||
$url = parse_url($id);
|
||||
$this->mustContains(['path', 'host', 'scheme'], $url);
|
||||
|
@ -430,8 +430,6 @@ class CurlService {
|
|||
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
private function generateCurlRequest(Request $request) {
|
||||
$url = $request->getUsedProtocol() . '://' . $request->getHost() . $request->getParsedUrl();
|
||||
|
|
|
@ -232,7 +232,9 @@ class FollowService {
|
|||
/**
|
||||
* @param Person $actor
|
||||
*
|
||||
* @return Person[]
|
||||
* @return Follow[]
|
||||
*
|
||||
* @psalm-return array<Follow>
|
||||
*/
|
||||
public function getFollowers(Person $actor): array {
|
||||
return $this->followsRequest->getFollowersByActorId($actor->getId());
|
||||
|
@ -257,7 +259,9 @@ class FollowService {
|
|||
/**
|
||||
* @param Person $actor
|
||||
*
|
||||
* @return Person[]
|
||||
* @return Follow[]
|
||||
*
|
||||
* @psalm-return array<Follow>
|
||||
*/
|
||||
public function getFollowing(Person $actor): array {
|
||||
return $this->followsRequest->getFollowingByActorId($actor->getId());
|
||||
|
|
|
@ -39,7 +39,6 @@ use OCA\Social\Exceptions\HashtagDoesNotExistException;
|
|||
use OCA\Social\Exceptions\ItemUnknownException;
|
||||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
use OCA\Social\Model\ActivityPub\Object\Note;
|
||||
use OCA\Social\Model\ActivityPub\Stream;
|
||||
|
||||
class HashtagService {
|
||||
public const TREND_1H = 3600;
|
||||
|
@ -155,10 +154,9 @@ class HashtagService {
|
|||
/**
|
||||
* @param int $timestamp
|
||||
*
|
||||
* @return Stream[]
|
||||
* @return int[]
|
||||
* @throws DateTimeException
|
||||
* @throws ItemUnknownException
|
||||
* @throws SocialAppConfigException
|
||||
* @psalm-return array<int>
|
||||
*/
|
||||
private function getTrendSince(int $timestamp): array {
|
||||
$result = [];
|
||||
|
|
|
@ -58,7 +58,7 @@ class MiscService {
|
|||
* @param $message
|
||||
* @param int $level
|
||||
*/
|
||||
public function log($message, $level = 2) {
|
||||
public function log(string $message, $level = 2) {
|
||||
$data = array(
|
||||
'app' => Application::APP_NAME,
|
||||
'level' => $level
|
||||
|
|
|
@ -97,7 +97,7 @@ class PostService {
|
|||
* @throws StreamNotFoundException
|
||||
* @throws UnauthorizedFediverseException
|
||||
*/
|
||||
public function createPost(Post $post, string &$token = ''): ACore {
|
||||
public function createPost(Post $post, string &$token = ''): ?ACore {
|
||||
$this->fixRecipientAndHashtags($post);
|
||||
|
||||
$note = new Note();
|
||||
|
@ -130,10 +130,10 @@ class PostService {
|
|||
private function generateDocumentsFromAttachments(Note $note, Post $post) {
|
||||
$documents = [];
|
||||
if (!isset($_FILES['attachments'])) {
|
||||
return [];
|
||||
return;
|
||||
}
|
||||
if (is_array($_FILES["attachments"]["error"])) {
|
||||
foreach ($_FILES["attachments"]["error"] as $key => $error) {
|
||||
if (is_array($_FILES['attachments']['error'])) {
|
||||
foreach ($_FILES['attachments']['error'] as $key => $error) {
|
||||
if ($error == UPLOAD_ERR_OK) {
|
||||
try {
|
||||
$document = $this->generateDocumentFromAttachment($note, $key);
|
||||
|
|
|
@ -31,10 +31,10 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Social\Service;
|
||||
|
||||
use OCA\Social\Tools\Traits\TNCLogger;
|
||||
use OCA\Social\Tools\Traits\TArrayTools;
|
||||
use Exception;
|
||||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||
use OCA\Social\Tools\Traits\TArrayTools;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Class SearchService
|
||||
|
@ -43,7 +43,6 @@ use OCA\Social\Model\ActivityPub\Actor\Person;
|
|||
*/
|
||||
class SearchService {
|
||||
use TArrayTools;
|
||||
use TNCLogger;
|
||||
|
||||
|
||||
public const SEARCH_ACCOUNTS = 1;
|
||||
|
@ -51,14 +50,10 @@ class SearchService {
|
|||
public const SEARCH_CONTENT = 4;
|
||||
public const SEARCH_ALL = 7;
|
||||
|
||||
|
||||
private CacheActorService $cacheActorService;
|
||||
|
||||
private HashtagService $hashtagService;
|
||||
|
||||
private ConfigService $configService;
|
||||
|
||||
private MiscService $miscService;
|
||||
private LoggerInterface $logger;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -67,16 +62,18 @@ class SearchService {
|
|||
* @param CacheActorService $cacheActorService
|
||||
* @param HashtagService $hashtagService
|
||||
* @param ConfigService $configService
|
||||
* @param MiscService $miscService
|
||||
* @param LoggerInterface $logger
|
||||
*/
|
||||
public function __construct(
|
||||
CacheActorService $cacheActorService, HashtagService $hashtagService,
|
||||
ConfigService $configService, MiscService $miscService
|
||||
CacheActorService $cacheActorService,
|
||||
HashtagService $hashtagService,
|
||||
ConfigService $configService,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
$this->cacheActorService = $cacheActorService;
|
||||
$this->hashtagService = $hashtagService;
|
||||
$this->configService = $configService;
|
||||
$this->miscService = $miscService;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
|
||||
|
@ -100,7 +97,7 @@ class SearchService {
|
|||
try {
|
||||
$this->cacheActorService->getFromAccount($search);
|
||||
} catch (Exception $e) {
|
||||
$this->exception($e, self::$NOTICE, ['search' => $search]);
|
||||
$this->logger->notice('searchAccounts', ['exception' => $e, 'search' => $search]);
|
||||
}
|
||||
|
||||
return $this->cacheActorService->searchCachedAccounts($search);
|
||||
|
|
|
@ -451,7 +451,7 @@ class SignatureService {
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
private function parseSignatureHeader($signatureHeader) {
|
||||
private function parseSignatureHeader(string $signatureHeader) {
|
||||
$sign = [];
|
||||
|
||||
$entries = explode(',', $signatureHeader);
|
||||
|
@ -504,7 +504,7 @@ class SignatureService {
|
|||
* @return string
|
||||
* @throws InvalidOriginException
|
||||
*/
|
||||
private function getKeyOrigin($id) {
|
||||
private function getKeyOrigin(string $id) {
|
||||
$host = parse_url($id, PHP_URL_HOST);
|
||||
if (is_string($host) && ($host !== '')) {
|
||||
return $host;
|
||||
|
|
|
@ -544,7 +544,7 @@ class StreamService {
|
|||
* @throws RequestResultNotJsonException
|
||||
* @throws UnauthorizedFediverseException
|
||||
*/
|
||||
public function getAuthorFromPostId($noteId) {
|
||||
public function getAuthorFromPostId(string $noteId) {
|
||||
$note = $this->streamRequest->getStreamById($noteId);
|
||||
|
||||
return $this->cacheActorService->getFromId($note->getAttributedTo());
|
||||
|
|
|
@ -455,7 +455,10 @@ class Request implements JsonSerializable {
|
|||
}
|
||||
|
||||
|
||||
public function addHeader($key, $value): Request {
|
||||
/**
|
||||
* @psalm-param string $key
|
||||
*/
|
||||
public function addHeader(string $key, string $value): Request {
|
||||
$header = $this->get($key, $this->headers);
|
||||
if ($header !== '') {
|
||||
$header .= ', ' . $value;
|
||||
|
|
|
@ -1,200 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Some tools for myself.
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @copyright 2020, Maxence Lange <maxence@artificial-owl.com>
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
namespace OCA\Social\Tools\Traits;
|
||||
|
||||
use Exception;
|
||||
use OC\HintException;
|
||||
use OCP\Server;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Throwable;
|
||||
|
||||
trait TNCLogger {
|
||||
use TNCSetup;
|
||||
|
||||
public static int $EMERGENCY = 4;
|
||||
public static int $ALERT = 3;
|
||||
public static int $CRITICAL = 3;
|
||||
public static int $ERROR = 3;
|
||||
public static int $WARNING = 2;
|
||||
public static int $NOTICE = 1;
|
||||
public static int $INFO = 1;
|
||||
public static int $DEBUG = 0;
|
||||
|
||||
|
||||
/**
|
||||
* @param Throwable $t
|
||||
* @param array $serializable
|
||||
*/
|
||||
public function t(Throwable $t, array $serializable = []): void {
|
||||
$this->throwable($t, self::$ERROR, $serializable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Throwable $t
|
||||
* @param int $level
|
||||
* @param array $serializable
|
||||
*/
|
||||
public function throwable(Throwable $t, int $level = 3, array $serializable = []): void {
|
||||
$message = '';
|
||||
if (!empty($serializable)) {
|
||||
$message = json_encode($serializable);
|
||||
}
|
||||
|
||||
$this->logger()
|
||||
->log(
|
||||
$level,
|
||||
$message,
|
||||
[
|
||||
'app' => $this->setup('app'),
|
||||
'exception' => $t
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Exception $e
|
||||
* @param array $serializable
|
||||
*/
|
||||
public function e(Exception $e, array $serializable = []): void {
|
||||
$this->exception($e, self::$ERROR, $serializable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Exception $e
|
||||
* @param int|array $level
|
||||
* @param array $serializable
|
||||
*/
|
||||
public function exception(Exception $e, $level = 3, array $serializable = []): void {
|
||||
if (is_array($level) && empty($serializable)) {
|
||||
$serializable = $level;
|
||||
$level = 3;
|
||||
}
|
||||
|
||||
$message = '';
|
||||
if (!empty($serializable)) {
|
||||
$message = json_encode($serializable);
|
||||
}
|
||||
|
||||
if ($level === self::$DEBUG) {
|
||||
$level = (int)$this->appConfig('debug_level');
|
||||
}
|
||||
|
||||
$this->logger()
|
||||
->log(
|
||||
$level,
|
||||
$message,
|
||||
[
|
||||
'app' => $this->setup('app'),
|
||||
'exception' => $e
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param bool $trace
|
||||
* @param array $serializable
|
||||
*/
|
||||
public function emergency(string $message, bool $trace = false, array $serializable = []): void {
|
||||
$this->log(self::$EMERGENCY, '[emergency] ' . $message, $trace, $serializable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param bool $trace
|
||||
* @param array $serializable
|
||||
*/
|
||||
public function alert(string $message, bool $trace = false, array $serializable = []): void {
|
||||
$this->log(self::$ALERT, '[alert] ' . $message, $trace, $serializable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param bool $trace
|
||||
* @param array $serializable
|
||||
*/
|
||||
public function warning(string $message, bool $trace = false, array $serializable = []): void {
|
||||
$this->log(self::$WARNING, '[warning] ' . $message, $trace, $serializable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param bool $trace
|
||||
* @param array $serializable
|
||||
*/
|
||||
public function notice(string $message, bool $trace = false, array $serializable = []): void {
|
||||
$this->log(self::$NOTICE, '[notice] ' . $message, $trace, $serializable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param array $serializable
|
||||
*/
|
||||
public function debug(string $message, array $serializable = []): void {
|
||||
$message = '[debug] ' . $message;
|
||||
$debugLevel = (int)$this->appConfig('debug_level');
|
||||
$this->log($debugLevel, $message, ($this->appConfig('debug_trace') === '1'), $serializable);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $level
|
||||
* @param string $message
|
||||
* @param bool $trace
|
||||
* @param array $serializable
|
||||
*/
|
||||
public function log(int $level, string $message, bool $trace = false, array $serializable = []): void {
|
||||
$opts = ['app' => $this->setup('app')];
|
||||
if ($trace) {
|
||||
$opts['exception'] = new HintException($message, json_encode($serializable));
|
||||
} elseif (!empty($serializable)) {
|
||||
$message .= ' -- ' . json_encode($serializable);
|
||||
}
|
||||
|
||||
$this->logger()
|
||||
->log($level, $message, $opts);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return LoggerInterface
|
||||
*/
|
||||
public function logger(): LoggerInterface {
|
||||
if (isset($this->logger) && $this->logger instanceof LoggerInterface) {
|
||||
return $this->logger;
|
||||
} else {
|
||||
return Server::get(LoggerInterface::class);
|
||||
}
|
||||
}
|
||||
}
|
Plik diff jest za duży
Load Diff
15
package.json
15
package.json
|
@ -20,12 +20,14 @@
|
|||
"dev": "NODE_ENV=development webpack --config webpack.common.js",
|
||||
"watch": "NODE_ENV=development webpack --progress --watch --config webpack.common.js",
|
||||
"build": "NODE_ENV=production webpack --progress --config webpack.common.js",
|
||||
"serve": "NODE_ENV=development webpack serve --progress --config webpack.common.js",
|
||||
"lint": "eslint --ext .js,.vue src",
|
||||
"lint:fix": "eslint --ext .js,.vue src --fix",
|
||||
"test": "jest",
|
||||
"test:coverage": "jest --coverage",
|
||||
"cypress": "cypress run",
|
||||
"cypress:gui": "cypress open"
|
||||
"cypress": "./cypress/start.sh; cypress run; ./cypress/stop.sh",
|
||||
"cypress:gui": "./cypress/start.sh; cypress open; ./cypress/stop.sh",
|
||||
"wait-on": "wait-on -i 500 -t 300000"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nextcloud/auth": "^2.0.0",
|
||||
|
@ -40,6 +42,8 @@
|
|||
"@nextcloud/vue": "^7.3.0",
|
||||
"@nextcloud/vue-richtext": "^2.0.4",
|
||||
"he": "^1.2.0",
|
||||
"linkify-plugin-mention": "^4.1.0",
|
||||
"linkify-string": "^4.1.0",
|
||||
"linkifyjs": "^4.0.2",
|
||||
"sass": "^1.57.1",
|
||||
"tributejs": "^5.1.3",
|
||||
|
@ -69,13 +73,16 @@
|
|||
"npm": "^7.0.0 || ^8.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cypress/browserify-preprocessor": "^3.0.2",
|
||||
"@nextcloud/babel-config": "^1.0.0",
|
||||
"@nextcloud/browserslist-config": "^2.3.0",
|
||||
"@nextcloud/eslint-config": "^8.1.4",
|
||||
"@nextcloud/webpack-vue-config": "^5.4.0",
|
||||
"cypress": "^11.2.0",
|
||||
"jest": "^29.3.1",
|
||||
"jest-serializer-vue": "^3.1.0",
|
||||
"vue-template-compiler": "^2.7.10"
|
||||
"vue-template-compiler": "^2.7.10",
|
||||
"wait-on": "^7.0.1"
|
||||
},
|
||||
"jest": {
|
||||
"moduleFileExtensions": [
|
||||
|
@ -93,4 +100,4 @@
|
|||
"<rootDir>/node_modules/jest-serializer-vue"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -120,6 +120,7 @@
|
|||
<div class="emptySpace" />
|
||||
<NcButton :value="currentVisibilityPostLabel"
|
||||
:disabled="!canPost"
|
||||
native-type="submit"
|
||||
type="primary"
|
||||
@click.prevent="createPost">
|
||||
<template #icon>
|
||||
|
|
|
@ -78,11 +78,10 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import * as linkify from 'linkifyjs'
|
||||
// eslint-disable-next-line
|
||||
import pluginMention from 'linkifyjs/plugins/mention'
|
||||
// eslint-disable-next-line
|
||||
import 'linkifyjs/string'
|
||||
import 'linkify-plugin-mention'
|
||||
import 'linkify-string'
|
||||
import currentUser from './../mixins/currentUserMixin.js'
|
||||
import PostAttachment from './PostAttachment.vue'
|
||||
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
|
||||
|
@ -97,8 +96,6 @@ import moment from '@nextcloud/moment'
|
|||
import { generateUrl } from '@nextcloud/router'
|
||||
import RichText from '@nextcloud/vue-richtext'
|
||||
|
||||
pluginMention(linkify)
|
||||
|
||||
export default {
|
||||
name: 'TimelinePost',
|
||||
components: {
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<files psalm-version="4.30.0@d0bc6e25d89f649e4f36a534f330f8bb4643dd69">
|
||||
<file src="lib/AP.php">
|
||||
<InvalidScalarArgument occurrences="1">
|
||||
<code>$level</code>
|
||||
</InvalidScalarArgument>
|
||||
</file>
|
||||
<files psalm-version="5.4.0@62db5d4f6a7ae0a20f7cc5a4952d730272fc0863">
|
||||
<file src="lib/Model/ActivityPub/ACore.php">
|
||||
<InvalidArgument occurrences="1">
|
||||
<code>['a', 'p', 'span', 'br']</code>
|
||||
|
@ -12,20 +7,15 @@
|
|||
<InvalidClass occurrences="1">
|
||||
<code>Acore</code>
|
||||
</InvalidClass>
|
||||
<InvalidNullableReturnType occurrences="4">
|
||||
<InvalidNullableReturnType occurrences="1">
|
||||
<code>ACore</code>
|
||||
<code>ACore</code>
|
||||
<code>Document</code>
|
||||
<code>LinkedDataSignature</code>
|
||||
</InvalidNullableReturnType>
|
||||
<InvalidPropertyAssignmentValue occurrences="1">
|
||||
<code>$parent</code>
|
||||
</InvalidPropertyAssignmentValue>
|
||||
<NullableReturnStatement occurrences="4">
|
||||
<code>$this->icon</code>
|
||||
<code>$this->object</code>
|
||||
<NullableReturnStatement occurrences="1">
|
||||
<code>$this->parent</code>
|
||||
<code>$this->signature</code>
|
||||
</NullableReturnStatement>
|
||||
<TypeDoesNotContainNull occurrences="1">
|
||||
<code>$v === null</code>
|
||||
|
@ -40,28 +30,13 @@
|
|||
<code>$object = $cache->getItem($this->getObjectId())</code>
|
||||
</RedundantCondition>
|
||||
</file>
|
||||
<file src="lib/Model/Instance.php">
|
||||
<InvalidNullableReturnType occurrences="1">
|
||||
<code>Person</code>
|
||||
</InvalidNullableReturnType>
|
||||
<NullableReturnStatement occurrences="1">
|
||||
<code>$this->contactAccount</code>
|
||||
</NullableReturnStatement>
|
||||
</file>
|
||||
<file src="lib/Model/RequestQueue.php">
|
||||
<InvalidNullableReturnType occurrences="1">
|
||||
<code>InstancePath</code>
|
||||
</InvalidNullableReturnType>
|
||||
<NullableReturnStatement occurrences="1">
|
||||
<code>$this->instance</code>
|
||||
</NullableReturnStatement>
|
||||
</file>
|
||||
<file src="lib/Db/CoreRequestBuilder.php">
|
||||
<UndefinedMethod occurrences="3">
|
||||
<code>dropTable</code>
|
||||
<code>hasTable</code>
|
||||
<code>hasTable</code>
|
||||
</UndefinedMethod>
|
||||
<InvalidArgument occurrences="2"/>
|
||||
</file>
|
||||
<file src="lib/Service/CheckService.php">
|
||||
<RedundantCast occurrences="1">
|
||||
|
@ -81,36 +56,16 @@
|
|||
<TypeDoesNotContainType occurrences="1">
|
||||
<code>$this->maxDownloadSizeReached === true</code>
|
||||
</TypeDoesNotContainType>
|
||||
</file>
|
||||
<file src="lib/Service/FollowService.php">
|
||||
<InvalidReturnStatement occurrences="2">
|
||||
<code>$this->followsRequest->getFollowersByActorId($actor->getId())</code>
|
||||
<code>$this->followsRequest->getFollowingByActorId($actor->getId())</code>
|
||||
</InvalidReturnStatement>
|
||||
<InvalidReturnType occurrences="2">
|
||||
<code>Person[]</code>
|
||||
<code>Person[]</code>
|
||||
</InvalidReturnType>
|
||||
</file>
|
||||
<file src="lib/Service/HashtagService.php">
|
||||
<InvalidReturnStatement occurrences="1">
|
||||
<code>$result</code>
|
||||
</InvalidReturnStatement>
|
||||
<InvalidReturnType occurrences="1">
|
||||
<code>Stream[]</code>
|
||||
</InvalidReturnType>
|
||||
<InvalidArgument occurrences="8"/>
|
||||
</file>
|
||||
<file src="lib/Service/PostService.php">
|
||||
<InvalidNullableReturnType occurrences="1">
|
||||
<code>ACore</code>
|
||||
</InvalidNullableReturnType>
|
||||
<NullableReturnStatement occurrences="1">
|
||||
<code>$activity</code>
|
||||
</NullableReturnStatement>
|
||||
<UndefinedMethod occurrences="2">
|
||||
<code>setAttributedTo</code>
|
||||
<code>setContent</code>
|
||||
</UndefinedMethod>
|
||||
<TypeDoesNotContainType occurrences="1">
|
||||
<code>is_array($_FILES['attachments']['error'])</code>
|
||||
</TypeDoesNotContainType>
|
||||
</file>
|
||||
<file src="lib/Service/SearchService.php">
|
||||
<InvalidOperand occurrences="3">
|
||||
|
@ -131,9 +86,4 @@
|
|||
<code>$username === null</code>
|
||||
</TypeDoesNotContainNull>
|
||||
</file>
|
||||
<file src="lib/Tools/Traits/TNCLogger.php">
|
||||
<UndefinedClass occurrences="1">
|
||||
<code>HintException</code>
|
||||
</UndefinedClass>
|
||||
</file>
|
||||
</files>
|
||||
|
|
Ładowanie…
Reference in New Issue