]> git.r.bdr.sh - rbdr/lyricli/commitdiff
Use swiftsoup for parsing
authorRuben Beltran del Rio <redacted>
Mon, 10 Apr 2023 13:00:55 +0000 (15:00 +0200)
committerRuben Beltran del Rio <redacted>
Mon, 10 Apr 2023 13:00:55 +0000 (15:00 +0200)
Makefile
Package.resolved
Package.swift
Sources/lyricli/lyrics_engine.swift

index 8428b44460bdc9b1a236e01acf397dfb05da0c07..e535bdbe2ee576b50fd0e506a83fbe2ac3dfefed 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -18,7 +18,7 @@ build:
        swift build --build-path $(build_path) --configuration $(configuration)
 
 install: build
-       cp $(source_binary_path) $(install_binary_path)
+       sudo cp $(source_binary_path) $(install_binary_path)
 
 test: build
        swift test
index 4d93f8f012c6038db6437fe8e29040549475ec79..54140ee0471b7909c695e05b8acf89caeaf86e86 100644 (file)
@@ -8,6 +8,15 @@
         "revision" : "fee6933f37fde9a5e12a1e4aeaa93fe60116ff2a",
         "version" : "1.2.2"
       }
+    },
+    {
+      "identity" : "swiftsoup",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/scinfu/SwiftSoup.git",
+      "state" : {
+        "revision" : "f707b8680cddb96dc1855632340a572ef37bbb98",
+        "version" : "2.5.3"
+      }
     }
   ],
   "version" : 2
index 2f49d107c935aeb4dbd79d94f578177367ab9962..508b5fbd57ae59ba34db44636da1b6a90994d303 100644 (file)
@@ -5,12 +5,18 @@ import PackageDescription
 let package = Package(
     name: "lyricli",
     dependencies: [
+        /// HTML Parsing
+        .package(url: "https://github.com/scinfu/SwiftSoup.git", from: "2.5.3"),
+
         /// ðŸš© Command Line Arguments
         .package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.2.2")
     ],
     targets: [
         .executableTarget(
             name: "lyricli",
-            dependencies: [.product(name: "ArgumentParser", package: "swift-argument-parser")])
+            dependencies: [
+                .product(name: "SwiftSoup", package: "SwiftSoup"),
+                .product(name: "ArgumentParser", package: "swift-argument-parser")
+            ])
     ]
 )
index f0a02db53fb280dd79dce5301bfed30bb91886ba..620e5215c0a3834a271332106e51093e6e345100 100644 (file)
@@ -1,4 +1,5 @@
 import Foundation
+import SwiftSoup
 
 // Given a track, attempts to fetch the lyrics from lyricswiki
 class LyricsEngine {
@@ -11,9 +12,6 @@ class LyricsEngine {
     // Method used to call the API
     private let apiMethod = "GET"
 
-    // Regular expxression used to find the lyrics in the lyricswiki HTML
-    private let lyricsMatcher = "class='lyricbox'>(.+)<div"
-
     // The track we'll be looking for
     private let track: Track
 
@@ -25,8 +23,9 @@ class LyricsEngine {
         // Encode the track artist and name and finish building the API call URL
 
         if let artist = track.artist.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) {
-            if let name: String = track.name.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) {
-                if let url = URL(string: "\(apiURL)&q=\(artist) \(name)") {
+            if let name = track.name.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) {
+
+                if let url = URL(string: "\(apiURL)?access_token=\(clientToken)&q=\(artist)%20\(name)") {
 
                     // We'll lock until the async call is finished
 
@@ -74,18 +73,20 @@ class LyricsEngine {
             if let data = data {
                 if let jsonResponse = try? JSONSerialization.jsonObject(with: data) {
                     if let jsonResponse = jsonResponse as? [String: Any] {
-                        if let hits = jsonResponse["hits"] as? [Any] {
-                            if let firstHit = hits[0] as? [String: Any] {
-                                if let firstHitData = firstHit["result"] as? [String: Any] {
-                                    if let lyricsUrlString = firstHitData["url"] as? String {
-                                        if let lyricsUrl = URL(string: lyricsUrlString) {
-
-                                            // At this point we have a valid wiki url
-                                            self.fetchLyricsFromPage(
-                                                withURL: lyricsUrl,
-                                                completionHandler: completionHandler
-                                            )
-                                            return
+                        if let response = jsonResponse["response"] as? [String:Any] {
+                            if let hits = response["hits"] as? [Any] {
+                                if let firstHit = hits[0] as? [String: Any] {
+                                    if let firstHitData = firstHit["result"] as? [String: Any] {
+                                        if let lyricsUrlString = firstHitData["url"] as? String {
+                                            if let lyricsUrl = URL(string: lyricsUrlString) {
+
+                                                // At this point we have a valid wiki url
+                                                self.fetchLyricsFromPage(
+                                                    withURL: lyricsUrl,
+                                                    completionHandler: completionHandler
+                                                )
+                                                return
+                                            }
                                         }
                                     }
                                 }
@@ -126,30 +127,14 @@ class LyricsEngine {
     // Parses the wiki to find the lyrics, decodes the lyrics object
     private func parseHtmlBody(_ body: String, completionHandler: @escaping (String?) -> Void) {
 
-        // Look for the lyrics lightbox
-
-        if let regex = try? NSRegularExpression(pattern: lyricsMatcher) {
-            let matches = regex.matches(in: body, range: NSRange(location: 0, length: body.count))
-
-            for match in matches {
-
-                let nsBody = body as NSString
-                let range = match.range(at: 1)
-                let encodedLyrics = nsBody.substring(with: range)
-
-                let decodedLyrics = decodeLyrics(encodedLyrics)
-
-                completionHandler(decodedLyrics)
-                return
-            }
+        do {
+            let document: Document = try SwiftSoup.parse(body)
+            let lyricsBox = try document.select("div[data-lyrics-container=\"true\"]")
+            try lyricsBox.select("br").after("\\n")
+            let lyrics = try lyricsBox.text()
+            completionHandler(lyrics.replacingOccurrences(of: "\\n", with: "\r\n"))
+        } catch {
+            completionHandler(nil)
         }
-
-        completionHandler(nil)
-    }
-
-    // Escapes the HTML entities and HTML
-    private func decodeLyrics(_ lyrics: String) -> String {
-
-        return lyrics
     }
 }