New addon "tesseract" for OCR #1457
|
@ -1111,11 +1111,11 @@ function bluesky_process_post(stdClass $post, int $uid, int $post_reason, int $l
|
|||
$uri = bluesky_get_uri($post);
|
||||
|
||||
if ($id = Post::selectFirst(['id'], ['uri' => $uri, 'uid' => $uid])) {
|
||||
return $id['id'];
|
||||
return $id['id'];
|
||||
}
|
||||
|
||||
if ($id = Post::selectFirst(['id'], ['extid' => $uri, 'uid' => $uid])) {
|
||||
return $id['id'];
|
||||
return $id['id'];
|
||||
}
|
||||
|
||||
Logger::debug('Importing post', ['uid' => $uid, 'indexedAt' => $post->indexedAt, 'uri' => $post->uri, 'cid' => $post->cid, 'root' => $post->record->reply->root ?? '']);
|
||||
|
@ -1251,7 +1251,7 @@ function bluesky_get_text(stdClass $record, int $uri_id): string
|
|||
$url = DI::baseUrl() . '/search?tag=' . urlencode($feature->tag);
|
||||
$linktext = '#' . $feature->tag;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
Logger::notice('Unhandled feature type', ['type' => $feature->$type, 'feature' => $feature, 'record' => $record]);
|
||||
break;
|
||||
|
@ -1736,13 +1736,13 @@ function bluesky_post(int $uid, string $url, string $params, array $headers): ?s
|
|||
}
|
||||
|
||||
if (!$curlResult->isSuccess()) {
|
||||
Logger::notice('API Error', ['error' => json_decode($curlResult->getBody()) ?: $curlResult->getBody()]);
|
||||
Logger::notice('API Error', ['error' => json_decode($curlResult->getBodyString()) ?: $curlResult->getBodyString()]);
|
||||
DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_API_FAIL);
|
||||
return null;
|
||||
}
|
||||
|
||||
DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_SUCCESS);
|
||||
return json_decode($curlResult->getBody());
|
||||
return json_decode($curlResult->getBodyString());
|
||||
}
|
||||
|
||||
function bluesky_xrpc_get(int $uid, string $url, array $parameters = []): ?stdClass
|
||||
|
@ -1767,9 +1767,9 @@ function bluesky_get(string $url, string $accept_content = HttpClientAccept::DEF
|
|||
}
|
||||
|
||||
if (!$curlResult->isSuccess()) {
|
||||
Logger::notice('API Error', ['error' => json_decode($curlResult->getBody()) ?: $curlResult->getBody()]);
|
||||
Logger::notice('API Error', ['error' => json_decode($curlResult->getBodyString()) ?: $curlResult->getBodyString()]);
|
||||
return null;
|
||||
}
|
||||
|
||||
return json_decode($curlResult->getBody());
|
||||
return json_decode($curlResult->getBodyString());
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ function discourse_fetch_post($host, $topic, $pid)
|
|||
return false;
|
||||
}
|
||||
|
||||
$raw = $curlResult->getBody();
|
||||
$raw = $curlResult->getBodyString();
|
||||
$data = json_decode($raw, true);
|
||||
$posts = $data['post_stream']['posts'];
|
||||
foreach($posts as $post) {
|
||||
|
@ -162,7 +162,7 @@ function discourse_fetch_post_from_api(&$message, $post, $host)
|
|||
return false;
|
||||
}
|
||||
|
||||
$raw = $curlResult->getBody();
|
||||
$raw = $curlResult->getBodyString();
|
||||
$data = json_decode($raw, true);
|
||||
if (empty($data)) {
|
||||
return false;
|
||||
|
|
|
@ -192,7 +192,7 @@ EOT;
|
|||
Logger::debug('dwpost: data: ' . $xml);
|
||||
|
||||
if ($dw_blog !== 'test') {
|
||||
$x = DI::httpClient()->post($dw_blog, $xml, ['Content-Type' => 'text/xml'])->getBody();
|
||||
$x = DI::httpClient()->post($dw_blog, $xml, ['Content-Type' => 'text/xml'])->getBodyString();
|
||||
}
|
||||
|
||||
Logger::info('posted to dreamwidth: ' . ($x) ? $x : '');
|
||||
|
|
|
@ -186,7 +186,7 @@ EOT;
|
|||
Logger::debug('ijpost: data: ' . $xml);
|
||||
|
||||
if ($ij_blog !== 'test') {
|
||||
$x = DI::httpClient()->post($ij_blog, $xml, ['Content-Type' => 'text/xml'])->getBody();
|
||||
$x = DI::httpClient()->post($ij_blog, $xml, ['Content-Type' => 'text/xml'])->getBodyString();
|
||||
}
|
||||
Logger::info('posted to insanejournal: ' . $x ? $x : '');
|
||||
}
|
||||
|
|
|
@ -201,7 +201,7 @@ function libertree_send(array &$b)
|
|||
// 'token' => $ltree_api_token
|
||||
];
|
||||
|
||||
$result = DI::httpClient()->post($ltree_blog, $params)->getBody();
|
||||
$result = DI::httpClient()->post($ltree_blog, $params)->getBodyString();
|
||||
Logger::notice('libertree: ' . $result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -207,7 +207,7 @@ EOT;
|
|||
Logger::debug('ljpost: data: ' . $xml);
|
||||
|
||||
if ($lj_blog !== 'test') {
|
||||
$x = DI::httpClient()->post($lj_blog, $xml, ['Content-Type' => 'text/xml'])->getBody();
|
||||
$x = DI::httpClient()->post($lj_blog, $xml, ['Content-Type' => 'text/xml'])->getBodyString();
|
||||
}
|
||||
|
||||
Logger::info('posted to livejournal: ' . ($x) ? $x : '');
|
||||
|
|
|
@ -221,7 +221,7 @@ function mailstream_do_images(array &$item, array &$attachments)
|
|||
continue;
|
||||
}
|
||||
$attachments[$url] = [
|
||||
'data' => $curlResult->getBody(),
|
||||
'data' => $curlResult->getBodyString(),
|
||||
'guid' => hash('crc32', $url),
|
||||
'filename' => basename($components['path']),
|
||||
'type' => $curlResult->getContentType()
|
||||
|
|
|
@ -82,7 +82,7 @@ function mastodoncustomemojis_fetch_custom_emojis_for_url($api_base_url)
|
|||
$fetchResult = DI::httpClient()->fetchFull($api_url);
|
||||
|
||||
if ($fetchResult->isSuccess()) {
|
||||
$emojis_array = json_decode($fetchResult->getBody(), true);
|
||||
$emojis_array = json_decode($fetchResult->getBodyString(), true);
|
||||
|
||||
if (is_array($emojis_array) && count($emojis_array)) {
|
||||
foreach ($emojis_array as $emoji) {
|
||||
|
|
|
@ -121,7 +121,7 @@ function openstreetmap_get_coordinates(array &$b)
|
|||
if (is_null($j)) {
|
||||
$curlResult = DI::httpClient()->get($nomserver . $args);
|
||||
if ($curlResult->isSuccess()) {
|
||||
$j = json_decode($curlResult->getBody(), true);
|
||||
$j = json_decode($curlResult->getBodyString(), true);
|
||||
DI::cache()->set($cachekey, $j, Duration::MONTH);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1244,7 +1244,7 @@ function tumblr_get_contact_by_url(string $url, int $uid): ?array
|
|||
} catch (\Exception $e) {
|
||||
return null;
|
||||
}
|
||||
$html = $curlResult->getBody();
|
||||
$html = $curlResult->getBodyString();
|
||||
if (empty($html)) {
|
||||
return null;
|
||||
}
|
||||
|
@ -1372,7 +1372,7 @@ function tumblr_delete(int $uid, string $url, array $parameters): stdClass
|
|||
*/
|
||||
function tumblr_format_result(ICanHandleHttpResponses $curlResult): stdClass
|
||||
{
|
||||
$result = json_decode($curlResult->getBody());
|
||||
$result = json_decode($curlResult->getBodyString());
|
||||
if (empty($result) || empty($result->meta)) {
|
||||
$result = new stdClass;
|
||||
$result->meta = new stdClass;
|
||||
|
@ -1426,11 +1426,11 @@ function tumblr_get_token(int $uid, string $code = ''): string
|
|||
|
||||
$curlResult = DI::httpClient()->post('https://api.tumblr.com/v2/oauth2/token', $parameters);
|
||||
if (!$curlResult->isSuccess()) {
|
||||
Logger::info('Error fetching token', ['uid' => $uid, 'code' => $code, 'result' => $curlResult->getBody(), 'parameters' => $parameters]);
|
||||
Logger::info('Error fetching token', ['uid' => $uid, 'code' => $code, 'result' => $curlResult->getBodyString(), 'parameters' => $parameters]);
|
||||
return '';
|
||||
}
|
||||
|
||||
$result = json_decode($curlResult->getBody());
|
||||
$result = json_decode($curlResult->getBodyString());
|
||||
if (empty($result)) {
|
||||
Logger::info('Invalid result when updating token', ['uid' => $uid]);
|
||||
return '';
|
||||
|
@ -1479,7 +1479,7 @@ function tumblr_exchange_token(int $uid): stdClass
|
|||
]);
|
||||
|
||||
$response = $client->post('oauth2/exchange', ['auth' => 'oauth']);
|
||||
return json_decode($response->getBody()->getContents());
|
||||
return json_decode($response->getBodyString()->getContents());
|
||||
} catch (RequestException $exception) {
|
||||
Logger::notice('Exchange failed', ['code' => $exception->getCode(), 'message' => $exception->getMessage()]);
|
||||
return new stdClass;
|
||||
|
|
|
@ -362,7 +362,7 @@ function twitter_post(int $uid, string $url, string $type, array $data): stdClas
|
|||
]);
|
||||
|
||||
$response = $client->post($url, ['auth' => 'oauth', $type => $data]);
|
||||
$body = $response->getBody()->getContents();
|
||||
$body = $response->getBodyString()->getContents();
|
||||
|
||||
$status = [
|
||||
'code' => $response->getStatusCode(),
|
||||
|
@ -399,7 +399,7 @@ function twitter_test_connection(int $uid)
|
|||
$status = [
|
||||
'code' => $response->getStatusCode(),
|
||||
'reason' => $response->getReasonPhrase(),
|
||||
'content' => $response->getBody()->getContents()
|
||||
'content' => $response->getBodyString()->getContents()
|
||||
];
|
||||
DI::pConfig()->set(1, 'twitter', 'last_status', $status);
|
||||
Logger::info('Test successful', ['uid' => $uid]);
|
||||
|
|
21
url_replace/LICENSE.md
Normal file
21
url_replace/LICENSE.md
Normal file
|
@ -0,0 +1,21 @@
|
|||
# MIT License
|
||||
|
||||
Copyright © 2024 Dr. Tobias Quathamer <t.quathamer@mailbox.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
17
url_replace/README.md
Normal file
17
url_replace/README.md
Normal file
|
@ -0,0 +1,17 @@
|
|||
# URL replace
|
||||
|
||||
This addon will replace all occurrences of specified URLs with the address of
|
||||
alternative servers in all displayed postings on a Friendica node.
|
||||
|
||||
You can use this to switch from Twitter (or X) to a nitter instance, from
|
||||
YouTube to an invidious instance, or from some news sites to 12ft.io.
|
||||
|
||||
Note: If you are using the twitter connector on your server, the links to the
|
||||
contacts profile pages will not be replaced by this addon. Only links in the
|
||||
body of the postings are affected.
|
||||
|
||||
## Why
|
||||
|
||||
- Access a website without JavaScript enabled to prevent JavaScript analytics
|
||||
and potential IP-based tracking
|
||||
- Avoid seeing ads on YouTube videos
|
50
url_replace/lang/C/messages.po
Normal file
50
url_replace/lang/C/messages.po
Normal file
|
@ -0,0 +1,50 @@
|
|||
# ADDON url_replace
|
||||
# Copyright (C)
|
||||
# This file is distributed under the same license as the Friendica url_replace addon package.
|
||||
#
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-01-05 00:06+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: url_replace.php:54
|
||||
msgid "Nitter server"
|
||||
msgstr ""
|
||||
|
||||
#: url_replace.php:56
|
||||
msgid "Specify the URL with protocol. The default is https://nitter.net."
|
||||
msgstr ""
|
||||
|
||||
#: url_replace.php:62
|
||||
msgid "Invidious server"
|
||||
msgstr ""
|
||||
|
||||
#: url_replace.php:64
|
||||
msgid "Specify the URL with protocol. The default is https://yewtu.be."
|
||||
msgstr ""
|
||||
|
||||
#: url_replace.php:70
|
||||
msgid "Sites which are accessed through 12ft.io"
|
||||
msgstr ""
|
||||
|
||||
#: url_replace.php:72
|
||||
msgid "Specify the URLs with protocol, one per line."
|
||||
msgstr ""
|
||||
|
||||
#: url_replace.php:76
|
||||
msgid "Save settings"
|
||||
msgstr ""
|
||||
|
||||
#: url_replace.php:125
|
||||
msgid "(URL replace addon enabled for X, YouTube and some news sites.)"
|
||||
msgstr ""
|
5
url_replace/templates/admin.tpl
Normal file
5
url_replace/templates/admin.tpl
Normal file
|
@ -0,0 +1,5 @@
|
|||
{{include file="field_input.tpl" field=$nitter_server}}
|
||||
{{include file="field_input.tpl" field=$invidious_server}}
|
||||
{{include file="field_textarea.tpl" field=$twelvefeet_sites}}
|
||||
|
||||
<div class="submit"><input type="submit" name="page_site" value="{{$submit}}" /></div>
|
130
url_replace/url_replace.php
Normal file
130
url_replace/url_replace.php
Normal file
|
@ -0,0 +1,130 @@
|
|||
<?php
|
||||
/**
|
||||
* Name: URL Replace
|
||||
* Description: Replaces occurrences of specified URLs with the address of alternative servers in all displays of postings on a node.
|
||||
* Version: 1.0
|
||||
* Author: Dr. Tobias Quathamer <https://social.anoxinon.de/@toddy>
|
||||
* Maintainer: Dr. Tobias Quathamer <https://social.anoxinon.de/@toddy>
|
||||
*/
|
||||
use Friendica\Core\Hook;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\DI;
|
||||
|
||||
function url_replace_install()
|
||||
{
|
||||
Hook::register('prepare_body_final', 'addon/url_replace/url_replace.php', 'url_replace_render');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle sent data from admin settings
|
||||
*/
|
||||
function url_replace_addon_admin_post()
|
||||
{
|
||||
DI::config()->set('url_replace', 'nitter_server', rtrim(trim($_POST['nitter_server']), '/'));
|
||||
DI::config()->set('url_replace', 'invidious_server', rtrim(trim($_POST['invidious_server']), '/'));
|
||||
// Convert twelvefeet_sites into an array before setting the new value
|
||||
$twelvefeet_sites = explode(PHP_EOL, $_POST['twelvefeet_sites']);
|
||||
// Normalize URLs by using lower case, removing a trailing slash and whitespace
|
||||
$twelvefeet_sites = array_map(fn ($value): string => rtrim(trim(strtolower($value)), '/'), $twelvefeet_sites);
|
||||
// Do not store empty lines or duplicates
|
||||
$twelvefeet_sites = array_filter($twelvefeet_sites, fn ($value): bool => !empty($value));
|
||||
$twelvefeet_sites = array_unique($twelvefeet_sites);
|
||||
// Ensure a protocol and default to HTTPS
|
||||
$twelvefeet_sites = array_map(
|
||||
fn ($value): string => substr($value, 0, 4) !== 'http' ? 'https://'.$value : $value,
|
||||
$twelvefeet_sites
|
||||
);
|
||||
asort($twelvefeet_sites);
|
||||
DI::config()->set('url_replace', 'twelvefeet_sites', $twelvefeet_sites);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook into admin settings to enable choosing a different server
|
||||
* for twitter, youtube, and news sites.
|
||||
*/
|
||||
function url_replace_addon_admin(string &$o)
|
||||
{
|
||||
$nitter_server = DI::config()->get('url_replace', 'nitter_server');
|
||||
$invidious_server = DI::config()->get('url_replace', 'invidious_server');
|
||||
$twelvefeet_sites = implode(PHP_EOL, DI::config()->get('url_replace', 'twelvefeet_sites'));
|
||||
$t = Renderer::getMarkupTemplate('admin.tpl', 'addon/url_replace/');
|
||||
$o = Renderer::replaceMacros($t, [
|
||||
'$nitter_server' => [
|
||||
'nitter_server',
|
||||
DI::l10n()->t('Nitter server'),
|
||||
$nitter_server,
|
||||
DI::l10n()->t('Specify the URL with protocol. The default is https://nitter.net.'),
|
||||
null,
|
||||
'placeholder="https://nitter.net"',
|
||||
],
|
||||
'$invidious_server' => [
|
||||
'invidious_server',
|
||||
DI::l10n()->t('Invidious server'),
|
||||
$invidious_server,
|
||||
DI::l10n()->t('Specify the URL with protocol. The default is https://yewtu.be.'),
|
||||
null,
|
||||
'placeholder="https://yewtu.be"',
|
||||
],
|
||||
'$twelvefeet_sites' => [
|
||||
'twelvefeet_sites',
|
||||
DI::l10n()->t('Sites which are accessed through 12ft.io'),
|
||||
$twelvefeet_sites,
|
||||
DI::l10n()->t('Specify the URLs with protocol, one per line.'),
|
||||
null,
|
||||
'rows="6"'
|
||||
],
|
||||
'$submit' => DI::l10n()->t('Save settings'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace proprietary URLs with their specified counterpart
|
||||
*/
|
||||
function url_replace_render(array &$b)
|
||||
{
|
||||
$replaced = false;
|
||||
|
||||
$nitter_server = DI::config()->get('url_replace', 'nitter_server');
|
||||
if (empty($nitter_server)) {
|
||||
$nitter_server = 'https://nitter.net';
|
||||
}
|
||||
|
||||
$invidious_server = DI::config()->get('url_replace', 'invidious_server');
|
||||
if (empty($invidious_server)) {
|
||||
$invidious_server = 'https://yewtu.be';
|
||||
}
|
||||
|
||||
// Handle some of twitter and youtube
|
||||
$replacements = [
|
||||
'https://mobile.twitter.com' => $nitter_server,
|
||||
'https://twitter.com' => $nitter_server,
|
||||
'https://mobile.x.com' => $nitter_server,
|
||||
'https://x.com' => $nitter_server,
|
||||
'https://www.youtube.com' => $invidious_server,
|
||||
'https://youtube.com' => $invidious_server,
|
||||
'https://m.youtube.com' => $invidious_server,
|
||||
'https://youtu.be' => $invidious_server,
|
||||
];
|
||||
foreach ($replacements as $server => $replacement) {
|
||||
if (strpos($b['html'], $server) !== false) {
|
||||
$b['html'] = str_replace($server, $replacement, $b['html']);
|
||||
$replaced = true;
|
||||
}
|
||||
}
|
||||
|
||||
$twelvefeet_sites = DI::config()->get('url_replace', 'twelvefeet_sites');
|
||||
if (empty($twelvefeet_sites)) {
|
||||
$twelvefeet_sites = [];
|
||||
}
|
||||
foreach ($twelvefeet_sites as $twelvefeet_site) {
|
||||
if (strpos($b['html'], $twelvefeet_site) !== false) {
|
||||
$b['html'] = str_replace($twelvefeet_site, 'https://12ft.io/'.$twelvefeet_site, $b['html']);
|
||||
$replaced = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($replaced) {
|
||||
$b['html'] .= '<hr><p><small>' . DI::l10n()->t('(URL replace addon enabled for X, YouTube and some news sites.)') . '</small></p>';
|
||||
}
|
||||
}
|
|
@ -113,7 +113,7 @@ class WebDav implements ICanWriteToStorage
|
|||
$response = $this->client->request('propfind', $uri, $opts);
|
||||
|
||||
$responseDoc = new \DOMDocument();
|
||||
$responseDoc->loadXML($response->getBody());
|
||||
$responseDoc->loadXML($response->getBodyString());
|
||||
$responseDoc->formatOutput = true;
|
||||
|
||||
$xpath = new \DOMXPath($responseDoc);
|
||||
|
@ -205,7 +205,7 @@ class WebDav implements ICanWriteToStorage
|
|||
throw new ReferenceStorageException(sprintf('Invalid reference %s', $reference));
|
||||
}
|
||||
|
||||
return $response->getBody();
|
||||
return $response->getBodyString();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -269,7 +269,7 @@ EOT;
|
|||
Logger::debug('wppost: data: ' . $xml);
|
||||
|
||||
if ($wp_blog !== 'test') {
|
||||
$x = DI::httpClient()->post($wp_blog, $xml)->getBody();
|
||||
$x = DI::httpClient()->post($wp_blog, $xml)->getBodyString();
|
||||
}
|
||||
Logger::info('posted to wordpress: ' . (($x) ? $x : ''));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue