Skip to content

Commit

Permalink
update from master (#24)
Browse files Browse the repository at this point in the history
* YouTubeChannel2RssFeed: setting for duration (#22)

* add setting to declare YouTube videos as short based on their duration
* Improving user-friendliness
* fix problem on shown of settings page if no config params of the extension is saved yet
* bump version
* update readme

* Add info about YT shorts

* New Crowdin updates (#23)

* New translations ext.php (German)

* New translations ext.php (English)
  • Loading branch information
cn-tools authored Jun 3, 2024
1 parent 08835e7 commit 5a222b5
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 28 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Have a look into the [DOCUMENTATION](https://github.com/cn-tools/cntools_FreshRs

### YouTubeChannel2RssFeed

Transfer on the fly a YouTube URL into an RSS Feed\
Transfer on the fly a YouTube URL into an RSS Feed and detect YouTube shorts\
Have a look into the [DOCUMENTATION](https://github.com/cn-tools/cntools_FreshRssExtensions/tree/master/xExtension-YouTubeChannel2RssFeed#documentation)

## Translations
Expand Down
8 changes: 7 additions & 1 deletion xExtension-YouTubeChannel2RssFeed/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,12 @@ Based on the example above, you need to enter the following URL in the settings
http://youtube-operational-api:80
```

### Detect YouTube shorts
### Detect YouTube shorts (by duration too)

In addition, YT-OAPI makes it possible to identify YouTube shorts. Therefore, there is an option in the settings to mark these YouTube shorts as readed when the RSS article is received, or not to save it in the database at all. In order to be able to track it, a log is written into FreshRSS LOG file in both of these cases.

There is also a setting to declare YouTube videos as short based on their duration.

#### Default configuration for YouTube shorts

Add YouTube shorts into database without any restcritions or changes.
Expand All @@ -72,6 +74,10 @@ Extensions must be in the ./extensions directory of your FreshRSS installation.

## Change log

### v0.6.1-alpha (2024-05-29)

- Add an option to also interpret short YouTube videos as 'short'

### v0.6.0-alpha (2024-05-06)

- add option window
Expand Down
14 changes: 11 additions & 3 deletions xExtension-YouTubeChannel2RssFeed/configure.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,24 @@
<div class="group-controls">
<select name="shorts" id="shorts">
<option value="0" title="<?php echo _t('ext.YouTubeChannel2RssFeed.shorts.options.default.title'); ?>"><?php echo _t('ext.YouTubeChannel2RssFeed.shorts.options.default.text'); ?></option>
<option value="block"<?= FreshRSS_Context::$user_conf->YouTubeChannel2RssFeed["shorts"] == 'block' ? ' selected="selected"' : '' ?> title="<?php echo _t('ext.YouTubeChannel2RssFeed.shorts.options.block.title'); ?>"><?php echo _t('ext.YouTubeChannel2RssFeed.shorts.options.block.text'); ?></option>
<option value="mark_as_read"<?= FreshRSS_Context::$user_conf->YouTubeChannel2RssFeed["shorts"] == 'mark_as_read' ? ' selected="selected"' : '' ?> title="<?php echo _t('ext.YouTubeChannel2RssFeed.shorts.options.mark_as_read.title'); ?>"><?php echo _t('ext.YouTubeChannel2RssFeed.shorts.options.mark_as_read.text'); ?></option>
<option value="block"<?= $this->getConfigValueByKeyWithDef('shorts', '') == 'block' ? ' selected="selected"' : '' ?> title="<?php echo _t('ext.YouTubeChannel2RssFeed.shorts.options.block.title'); ?>"><?php echo _t('ext.YouTubeChannel2RssFeed.shorts.options.block.text'); ?></option>
<option value="mark_as_read"<?= $this->getConfigValueByKeyWithDef('shorts', '') == 'mark_as_read' ? ' selected="selected"' : '' ?> title="<?php echo _t('ext.YouTubeChannel2RssFeed.shorts.options.mark_as_read.title'); ?>"><?php echo _t('ext.YouTubeChannel2RssFeed.shorts.options.mark_as_read.text'); ?></option>
</select>
</div>
</div>

<div class="form-group">
<label class="group-name" for="short_duration"><?= _t('ext.YouTubeChannel2RssFeed.shorts.duration.label'); ?></label>
<div class="group-controls">
<input type="number" name="short_duration" id="short_duration" value="<?= $this->getShortDuration(); ?>">
<br /><span><?= _t('ext.YouTubeChannel2RssFeed.shorts.duration.hint') ?></span>
</div>
</div>

<div class="form-group">
<label class="group-name" for="3rd_party_url"><?php echo _t('ext.YouTubeChannel2RssFeed.3rd_party.url'); ?></label>
<div class="group-controls">
<input type="url" name="3rd_party_url" id="3rd_party_url" placeholder="Ex: https://yt.lemnoslife.com" value="<?php echo FreshRSS_Context::$user_conf->YouTubeChannel2RssFeed["3rd_party_url"]; ?>">
<input type="url" name="3rd_party_url" id="3rd_party_url" placeholder="Ex: https://yt.lemnoslife.com" value="<?= $this->getThirdPartyUrl(); ?>">
<br /><span><?= _t('ext.YouTubeChannel2RssFeed.3rd_party.hint') ?></span>
<br /><span><?= _t('ext.YouTubeChannel2RssFeed.3rd_party.instance') ?> <a href="https://github.com/Benjamin-Loison/YouTube-operational-API" target="_blank">https://github.com/Benjamin-Loison/YouTube-operational-API</a></span>
<br /><br /><span><?= _t('ext.YouTubeChannel2RssFeed.3rd_party.help.text') ?> <a href="https://github.com/cn-tools/cntools_FreshRssExtensions/tree/master/xExtension-YouTubeChannel2RssFeed#documentation" target="_blank"><?= _t('ext.YouTubeChannel2RssFeed.3rd_party.help.lnk_txt') ?></a></span>
Expand Down
97 changes: 84 additions & 13 deletions xExtension-YouTubeChannel2RssFeed/extension.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,60 @@ public function handleConfigureAction() {
$config = [
'3rd_party_url' => rtrim(Minz_Request::paramString('3rd_party_url', ''), '/'),
'shorts' => Minz_Request::paramString('shorts', ''),
'short_duration' => Minz_Request::paramString('short_duration', 0),
];

FreshRSS_Context::$user_conf->YouTubeChannel2RssFeed = $config;
FreshRSS_Context::$user_conf->save();
}
}

public static function CntYTRssHookCheckURL($url) {
private function configKeyExists($key):bool {
Minz_Log::debug('YouTubeChannel2RssFeed-configKeyExists: START');
$result = false;
if ($key != '') {
Minz_Log::debug('YouTubeChannel2RssFeed-configKeyExists: key=' . $key);
if (null !== FreshRSS_Context::$user_conf) {
Minz_Log::debug('YouTubeChannel2RssFeed-configKeyExists: user_conf available');
if (null !== FreshRSS_Context::$user_conf->YouTubeChannel2RssFeed) {
Minz_Log::debug('YouTubeChannel2RssFeed-configKeyExists: YouTubeChannel2RssFeed available');
if (is_array(FreshRSS_Context::$user_conf->YouTubeChannel2RssFeed) ) {
Minz_Log::debug('YouTubeChannel2RssFeed-configKeyExists: YouTubeChannel2RssFeed is a array');
if (array_key_exists($key, FreshRSS_Context::$user_conf->YouTubeChannel2RssFeed)) {
Minz_Log::debug('YouTubeChannel2RssFeed-configKeyExists: key in array found');
$result = true;
}
}
}
}
}

Minz_Log::debug('YouTubeChannel2RssFeed-configKeyExists: END result=' . ($result ? 'found' : 'not found'));
return $result;
}

public function getConfigValueByKeyWithDef($key, $def) {
Minz_Log::debug('YouTubeChannel2RssFeed-getConfigValueByKeyAsStr: START');
$value = $def;
if ($this->configKeyExists($key) == true) {
$value = FreshRSS_Context::$user_conf->YouTubeChannel2RssFeed[$key];
}

Minz_Log::debug('YouTubeChannel2RssFeed-getConfigValueByKeyAsStr: value=' . var_export($value, true));
return $value;
}

public function getThirdPartyUrl():string {
Minz_Log::debug('YouTubeChannel2RssFeed-getThirdPartyUrl: START');
return $this->getConfigValueByKeyWithDef('3rd_party_url', '');
}

public function getShortDuration():int {
Minz_Log::debug('YouTubeChannel2RssFeed-getShortDuration: START');
return intval($this->getConfigValueByKeyWithDef('short_duration', 0));
}

public function CntYTRssHookCheckURL($url) {
Minz_Log::debug('YouTubeChannel2RssFeed-CntYTRssHookCheckURL: START - ' . $url);
if (stripos($url, self::CNT_YT_FEEDURL) === false) {
$origUrl = $url;
Expand All @@ -68,7 +114,7 @@ public static function CntYTRssHookCheckURL($url) {
return 'https://www.youtube.com/feeds/videos.xml?playlist_id=' . $matches[2];
}

$extUrl = FreshRSS_Context::$user_conf->YouTubeChannel2RssFeed["3rd_party_url"];
$extUrl = $this->getThirdPartyUrl();
if ($extUrl != ''){
if (preg_match('#^https?://(www\.|)youtube\.com/([\@0-9a-zA-Z_-]{1,60})#', $url, $matches) === 1) {
$origAllowUrlFopen = ini_get('allow_url_fopen');
Expand Down Expand Up @@ -98,20 +144,20 @@ public static function CntYTRssHookCheckURL($url) {
return $url;
}

public static function CntYTRssHookEntryBeforeInsert($entry) {
public function CntYTRssHookEntryBeforeInsert($entry) {
Minz_Log::debug('YouTubeChannel2RssFeed-EntryBeforeInsert - START');
try {
if ((is_object($entry)) && (strpos($entry->guid(), self::CNT_YT_VIDEO) !== false)) {
Minz_Log::debug('YouTubeChannel2RssFeed-EntryBeforeInsert - isYT: ' . serialize($entry));
$externalUrl = strval(FreshRSS_Context::$user_conf->YouTubeChannel2RssFeed["3rd_party_url"]);
if ($externalUrl != '') {
$extUrl = $this->getThirdPartyUrl();
if ($extUrl != '') {
$shorts = strtolower(strval(FreshRSS_Context::$user_conf->YouTubeChannel2RssFeed["shorts"]));
Minz_Log::debug('YouTubeChannel2RssFeed-EntryBeforeInsert: short-content = ' . $shorts);

if ($shorts != '0') {
$ytID = substr($entry->guid(), strlen(self::CNT_YT_VIDEO));
Minz_Log::debug('YouTubeChannel2RssFeed-EntryBeforeInsert: before check isShort (id=' . $ytID . ')');
if (self::isShort($entry, $externalUrl, $ytID) == true) {
if (self::isShort($entry, $extUrl, $ytID) == true) {
switch ($shorts) {
case "block":
Minz_Log::debug('YouTubeChannel2RssFeed-EntryBeforeInsert: block short');
Expand Down Expand Up @@ -144,7 +190,7 @@ public static function CntYTRssHookEntryBeforeInsert($entry) {
return $entry;
}

private static function isShort($entry, $extUrl, $ytID): bool {
private function isShort($entry, $extUrl, $ytID): bool {
Minz_Log::debug('YouTubeChannel2RssFeed-isShort: START');
$result = false;
try {
Expand All @@ -154,10 +200,17 @@ private static function isShort($entry, $extUrl, $ytID): bool {

$origAllowUrlFopen = ini_get('allow_url_fopen');

$part = 'short';

$shortDuration = $this->getShortDuration();
if ($shortDuration > 0) {
$part .= ',contentDetails';
}

try {
Minz_Log::debug('YouTubeChannel2RssFeed-isShort: fOpen - start');
ini_set("allow_url_fopen", 1);
$json = file_get_contents($extUrl . '/videos?part=short&id=' . $ytID);
$json = file_get_contents($extUrl . '/videos?part=' . $part . '&id=' . $ytID);
Minz_Log::debug('YouTubeChannel2RssFeed-isShort: fOpen - data: ' . serialize($json));
} finally {
ini_set("allow_url_fopen", $origAllowUrlFopen);
Expand All @@ -175,19 +228,37 @@ private static function isShort($entry, $extUrl, $ytID): bool {
Minz_Log::debug('YouTubeChannel2RssFeed-isShort: id is set');
if ($item->id == $ytID) {
Minz_Log::debug('YouTubeChannel2RssFeed-isShort: id found: ' . $ytID);
if (isset($item->short)) {

// check short directly
if (($result == false) && (isset($item->short))) {
Minz_Log::debug('YouTubeChannel2RssFeed-isShort: short is set');
if (isset($item->short->available)) {
Minz_Log::debug('YouTubeChannel2RssFeed-isShort: available is set');
if ($item->short->available == true) {
$result = true;
Minz_Log::debug('YouTubeChannel2RssFeed-isShort: THIS IS A SHORT');
} else {
$result = false;
Minz_Log::debug('YouTubeChannel2RssFeed-isShort: THIS IS NO SHORT');
}
}
}

// check short by user defined duration
$extraLogTxt = '';
if (($result == false) && (isset($item->contentDetails))) {
Minz_Log::debug('YouTubeChannel2RssFeed-isShort: contentDetails is set');
if (isset($item->contentDetails->duration) && is_numeric($item->contentDetails->duration)) {
Minz_Log::debug('YouTubeChannel2RssFeed-isShort: duration is set and numeric');
$ytDuration = intval($item->contentDetails->duration);
$extraLogTxt = '('.strval($ytDuration).'<'.strval($shortDuration).')';
if ($ytDuration < $shortDuration) {
Minz_Log::debug('YouTubeChannel2RssFeed-isShort: THIS IS A SHORT (by duration)'.$extraLogTxt);
$result = true;
}
}
}

if ($result == false) {
Minz_Log::debug('YouTubeChannel2RssFeed-isShort: THIS IS NO SHORT'.$extraLogTxt);
}
break; // video was found => exit 'foreach'
}
}
Expand All @@ -199,7 +270,7 @@ private static function isShort($entry, $extUrl, $ytID): bool {
Minz_Log::error('YouTubeChannel2RssFeed-isShort: ' . $e->getMessage());
}

Minz_Log::debug('YouTubeChannel2RssFeed-isShort: isShort - END - result = ' . var_export($result, true));
Minz_Log::debug('YouTubeChannel2RssFeed-isShort: isShort - END - result = ' . ($result ? 'true' : 'false'));
return $result;
}
}
14 changes: 9 additions & 5 deletions xExtension-YouTubeChannel2RssFeed/i18n/de/ext.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,32 @@
'lnk_txt' => 'Dokumentation',
'text' => 'Details über die Konfiguration und Funktionsweise finden sie hier:',
),
'hint' => 'Mit Hilfe der anzugebenden URL können einerseits YoutTube Shorts identifiziert werden und andererseits können YouTube Handels in Feeds umgewandelt werden',
'hint' => 'Mit Hilfe der anzugebenden URL können einerseits YoutTube Shorts identifiziert werden und andererseits können YouTube Handels in Feeds umgewandelt werden.',
'instance' => 'Instanz von:',
'url' => 'URL',
),
'install' => array(
'bad_freshrss' => 'Für "YouTubeChannel2RssFeed" ist mindestens die FreshRSS-Version `%s` erforderlich. (Sie verwenden die FreshRSS-Version `%s`)',
),
'shorts' => array(
'duration' => array(
'label' => 'Dauer in Sekunden',
'hint' => 'Wenn Sie eine Dauer größer als 0 festlegen, werden alle kürzeren Videos als Short idetifiziert, selbst wenn es laut YouTube kein Short ist.',
),
'label' => 'YouTube Shorts',
'hint' => 'Diese Einstellung wird nur berücksichtigt, wenn eine Instanz-URL hinterlegt ist. Ist keine hinterlegt, werden Shorts erlaubt',
'hint' => 'Diese Einstellung wird nur berücksichtigt, wenn eine Instanz-URL hinterlegt ist. Ist keine hinterlegt, werden Shorts erlaubt.',
'options' => array(
'default' => array(
'text' => 'Standard',
'title' => 'Keine Prüfung auf Youtube Shorts und der Feed-Eintrag wird ganz normal in die Datenbank aufgenommen',
'title' => 'Keine Prüfung auf Youtube Shorts und der Feed-Eintrag wird ganz normal in die Datenbank aufgenommen.',
),
'block' => array(
'text' => 'Blockieren',
'title' => 'Wird der neue Feed-Eintrag als Youtube Short erkannt, wird dieser nicht in die Datenbank aufgenommen',
'title' => 'Wird der neue Feed-Eintrag als Youtube Short erkannt, wird dieser nicht in die Datenbank aufgenommen.',
),
'mark_as_read' => array(
'text' => 'Als gelesen markieren',
'title' => 'Wird der neue Feed-Eintrag als Youtube Short erkannt, wird dieser als gelesen markiert',
'title' => 'Wird der neue Feed-Eintrag als Youtube Short erkannt, wird dieser als gelesen markiert.',
),
),
),
Expand Down
12 changes: 8 additions & 4 deletions xExtension-YouTubeChannel2RssFeed/i18n/en/ext.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,24 @@
'bad_freshrss' => '`YouTubeChannel2RssFeed`required at least FreshRSS version `%s`. (You use FreshRSS version `%s`)',
),
'shorts' => array(
'duration' => array(
'label' => 'Duration in seconds',
'hint' => 'If you set a duration greater than 0, all shorter videos will be identified as short, even if YouTube says it is not short.',
),
'label' => 'YouTube Shorts',
'hint' => 'This setting is only taken if an instance URL is stored. If none is deposited, shorts are permitted',
'hint' => 'This setting is only taken if an instance URL is stored. If none is deposited, shorts are permitted.',
'options' => array(
'default' => array(
'text' => 'Default',
'title' => 'No check for YouTube Shorts and the feed entry is added to the database as normal',
'title' => 'No check for YouTube Shorts and the feed entry is added to the database as normal.',
),
'block' => array(
'text' => 'Block',
'title' => 'If the new feed entry is recognized as a Youtube Short, it will not be added into the database',
'title' => 'If the new feed entry is recognized as a Youtube Short, it will not be added into the database.',
),
'mark_as_read' => array(
'text' => 'Mark as read',
'title' => 'If the new feed entry is recognized as a Youtube Short, it will be marked as read',
'title' => 'If the new feed entry is recognized as a Youtube Short, it will be marked as read.',
),
),
),
Expand Down
2 changes: 1 addition & 1 deletion xExtension-YouTubeChannel2RssFeed/metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "YouTubeChannel2RssFeed",
"author": "CNTools | Clemens Neubauer",
"description": "Transfer YouTube URL into RSS Feed URL.",
"version": "0.6.0-alpha",
"version": "0.6.1",
"entrypoint": "YouTubeChannel2RssFeed",
"type": "user"
}

0 comments on commit 5a222b5

Please sign in to comment.