Nextcloud Cookbook Parser Probleme

Es gibt für Nextcloud die Cookbook App, mit der man einfach Rezepte von verschiedenen Quellen sammeln kann.
Leider sind manche Seiten nicht kompatibel und liefern beim Herunterladen eine Parser Fehlermeldung.
Dies betrifft z.B. die Picnic Seite.
Mit diesem Patch ist das Herunterladen wieder möglich.

Subject: [PATCH] adding support for next.js recipes embedded in an unattributed script tag
---
Index: lib/Helper/HTMLParser/HttpJsonLdParser.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/lib/Helper/HTMLParser/HttpJsonLdParser.php b/lib/Helper/HTMLParser/HttpJsonLdParser.php
--- a/lib/Helper/HTMLParser/HttpJsonLdParser.php	(revision a246a0eed8e757118599d2c74f407b181a70bba5)
+++ b/lib/Helper/HTMLParser/HttpJsonLdParser.php	(date 1775395557183)
@@ -26,7 +26,7 @@
 	public function parse(\DOMDocument $document, ?string $url): array {
 		$xpath = new \DOMXPath($document);
 
-		$json_ld_elements = $xpath->query("//*[@type='application/ld+json']");
+		$json_ld_elements = $xpath->query("//*[@type='application/ld+json'] | //script");
 
 		foreach ($json_ld_elements as $json_ld_element) {
 			if (!$json_ld_element || !$json_ld_element->nodeValue) {
@@ -58,9 +58,14 @@
 		$json = json_decode($string, true);
 
 		if ($json === null) {
-			throw new HtmlParsingException($this->l->t('JSON cannot be decoded.'));
-		}
+			$extractedJson = $this->extractNextJsJson($string);
+			if ($extractedJson === null) {
+				throw new HtmlParsingException($this->l->t('JSON cannot be decoded.'));
+			}
 
+			$json = json_decode($extractedJson, true);
+		}
+
 		if ($json === false || $json === true || !is_array($json)) {
 			throw new HtmlParsingException($this->l->t('No recipe was found.'));
 		}
@@ -85,6 +90,34 @@
 		throw new HtmlParsingException($this->l->t('No recipe was found.'));
 	}
 
+	/**
+	 * Try to extract escaped JSON from a Next.js flight payload.
+	 *
+	 * Example:
+	 * self.__next_f.push([1,"{\"@context\":\"https://schema.org\",...}"])
+	 *
+	 * @param string $rawContent
+	 * @return string|null
+	 */
+	private function extractNextJsJson(string $rawContent): ?string {
+		if (strpos($rawContent, 'self.__next_f.push(') === false) {
+			return null;
+		}
+
+		$matches = [];
+		$matched = preg_match('/self\.__next_f\.push\(\[\s*\d+\s*,\s*"((?:\\\\.|[^"\\\\])*)"/s', $rawContent, $matches);
+		if ($matched !== 1 || !isset($matches[1])) {
+			return null;
+		}
+
+		$decoded = stripcslashes($matches[1]);
+		if ($decoded === '') {
+			return null;
+		}
+
+		return $decoded;
+	}
+
 	/**
 	 * Fix any JSON issues before trying to decode it
 	 *
Index: lib/Helper/Filter/JSON/FixInstructionsFilter.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/lib/Helper/Filter/JSON/FixInstructionsFilter.php b/lib/Helper/Filter/JSON/FixInstructionsFilter.php
--- a/lib/Helper/Filter/JSON/FixInstructionsFilter.php	(revision a246a0eed8e757118599d2c74f407b181a70bba5)
+++ b/lib/Helper/Filter/JSON/FixInstructionsFilter.php	(date 1775396186726)
@@ -98,6 +98,11 @@
 					continue;
 				}
 
+				if ($this->jsonService->isSchemaObject($value, 'HowToTip', false)) {
+					$instructions[$key] = [$this->extractHowToStep($value)];
+					continue;
+				}
+
 				if ($this->jsonService->isSchemaObject($value, 'HowToSection', false)) {
 					$newInstructions = $this->flattenHowToSection($value);
 					$instructions[$key] = $newInstructions;

Dieser Beitrag wurde unter Allgemein veröffentlicht. Setze ein Lesezeichen auf den Permalink.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre, wie deine Kommentardaten verarbeitet werden.