From 1158b489f752529b4801170fc888e44e5041b58f Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Thu, 18 May 2017 22:31:54 -0500 Subject: Add the pinned package file --- Package.pins | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 Package.pins diff --git a/Package.pins b/Package.pins new file mode 100644 index 0000000..4bb7a96 --- /dev/null +++ b/Package.pins @@ -0,0 +1,18 @@ +{ + "autoPin": true, + "pins": [ + { + "package": "CommandeLineKit", + "reason": null, + "repositoryURL": "https://github.com/rbdr/CommandLineKit", + "version": "4.0.0" + }, + { + "package": "HTMLEntities", + "reason": null, + "repositoryURL": "https://github.com/IBM-Swift/swift-html-entities.git", + "version": "3.0.3" + } + ], + "version": 1 +} \ No newline at end of file -- cgit From 47f1de79ed1d0007dbba84dc3d511528c7fed3f0 Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Thu, 18 May 2017 22:44:25 -0500 Subject: Show the optional arguments --- Sources/main.swift | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Sources/main.swift b/Sources/main.swift index e4b2760..42d4855 100644 --- a/Sources/main.swift +++ b/Sources/main.swift @@ -21,6 +21,21 @@ func createParser() -> ([String:Option], CommandLineKit) { parser.addOptions(Array(flags.values)) + parser.formatOutput = {parseString, type in + + var formattedString: String + + switch(type) { + case .About: + formattedString = "\(parseString) [ ]" + break + default: + formattedString = parseString + } + + return parser.defaultFormat(formattedString, type: type) + } + return (flags, parser) } -- cgit From 169297c8e8464ca0cf600e9e426f11d170ee169d Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Thu, 18 May 2017 22:44:41 -0500 Subject: Include makefile for easier building --- Makefile | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..34eec3a --- /dev/null +++ b/Makefile @@ -0,0 +1,28 @@ +configuration = debug +build_path = .build + +# These are used to rename the executable to lrc without renaming the package +source_binary_name = lyricli +target_binary_name = lrc +install_path = /usr/local/bin +source_binary_path = $(build_path)/$(configuration)/$(source_binary_name) +install_binary_path = $(install_path)/$(target_binary_name) + +# Default to release configuration on install +install: configuration = release + +default: build + +build: + swift build --build-path $(build_path) --configuration $(configuration) + +install: build + cp $(source_binary_path) $(install_binary_path) + +test: build + swift test + +clean: + swift build --clean + +.PHONY: build test clean -- cgit From 6608973cc785af2363b71299e03407e5dd436f54 Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Thu, 18 May 2017 22:58:05 -0500 Subject: Add code license --- LICENSE | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8dada3e --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. -- cgit From 1263f62c5c6379f11e19eb184ffedf5889390b70 Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Thu, 18 May 2017 23:39:25 -0500 Subject: Fix linter warnings --- Sources/arguments_source.swift | 14 +++--- Sources/configuration.swift | 24 ++++++--- Sources/lyricli.swift | 6 +-- Sources/lyrics_engine.swift | 66 ++++++++++++------------ Sources/main.swift | 111 ++++++++++++++++++++++++++++------------- Sources/source_manager.swift | 29 +++++------ 6 files changed, 144 insertions(+), 106 deletions(-) diff --git a/Sources/arguments_source.swift b/Sources/arguments_source.swift index c07c952..d1bf4c6 100644 --- a/Sources/arguments_source.swift +++ b/Sources/arguments_source.swift @@ -1,17 +1,15 @@ /// Source that deals with command line class ArgumentsSource: Source { public var currentTrack: Track? { - get { - if CommandLine.arguments.count >= 3 { + if CommandLine.arguments.count >= 3 { - // expected usage: $ ./lyricli + // expected usage: $ ./lyricli - let trackName: String = CommandLine.arguments[2] - let trackArtist: String = CommandLine.arguments[1] + let trackName: String = CommandLine.arguments[2] + let trackArtist: String = CommandLine.arguments[1] - return Track(withName: trackName, andArtist: trackArtist) - } - return nil + return Track(withName: trackName, andArtist: trackArtist) } + return nil } } diff --git a/Sources/configuration.swift b/Sources/configuration.swift index f5e4b0f..bc21769 100644 --- a/Sources/configuration.swift +++ b/Sources/configuration.swift @@ -21,14 +21,19 @@ public class Configuration { // IMPROVEMENT: Enable a debug mode if let data = try? NSData(contentsOfFile: configurationPath) as Data { - if let parsedConfig = try? JSONSerialization.jsonObject(with: data) as! [String:Any] { - for (key, value) in parsedConfig { + if let parsedConfig = try? JSONSerialization.jsonObject(with: data) { + if let parsedConfig = parsedConfig as? [String: Any] { + for (key, value) in parsedConfig { - if key == "enabled_sources" { - configuration[key] = value as! [String] - } - else { - configuration[key] = value as! String + if key == "enabled_sources" { + if let value = value as? [String] { + configuration[key] = value + } + } else { + if let value = value as? String { + configuration[key] = value + } + } } } } @@ -43,7 +48,10 @@ public class Configuration { if let outputStream = OutputStream(toFileAtPath: configurationPath, append: false) { outputStream.open() - JSONSerialization.writeJSONObject(configuration, to: outputStream, options: [JSONSerialization.WritingOptions.prettyPrinted], error: &error) + JSONSerialization.writeJSONObject(configuration, + to: outputStream, + options: [JSONSerialization.WritingOptions.prettyPrinted], + error: &error) outputStream.close() } } diff --git a/Sources/lyricli.swift b/Sources/lyricli.swift index c44a7f4..5931ca1 100644 --- a/Sources/lyricli.swift +++ b/Sources/lyricli.swift @@ -18,13 +18,11 @@ public class Lyricli { } print(lyrics) - } - else { + } else { print("Lyrics not found :(") } - } - else { + } else { print("No Artist/Song could be found :(") } } diff --git a/Sources/lyrics_engine.swift b/Sources/lyrics_engine.swift index d6b1985..9741a2c 100644 --- a/Sources/lyrics_engine.swift +++ b/Sources/lyrics_engine.swift @@ -13,40 +13,37 @@ class LyricsEngine { // Fetches the lyrics and returns if found var lyrics: String? { - get { + var lyrics: String? - var lyrics: String? + if let artist = track.artist.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) { + if let name: String = track.name.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) { + if let url = URL(string: "\(apiURL)&artist=\(artist)&song=\(name)") { - if let artist = track.artist.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) { - if let name: String = track.name.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) { - if let url = URL(string: "\(apiURL)&artist=\(artist)&song=\(name)") { + // We'll lock until the async call is finished - // We'll lock until the async call is finished + var requestFinished = false + let asyncLock = NSCondition() + asyncLock.lock() - var requestFinished = false - let asyncLock = NSCondition() - asyncLock.lock() + // Call the API and unlock when you're done - // Call the API and unlock when you're done - - fetchLyricsFromAPI(withURL: url, completionHandler: {lyricsResult -> Void in - if let lyricsResult = lyricsResult { - lyrics = lyricsResult - requestFinished = true - asyncLock.signal() - } - }) - - while(!requestFinished) { - asyncLock.wait() + fetchLyricsFromAPI(withURL: url, completionHandler: {lyricsResult -> Void in + if let lyricsResult = lyricsResult { + lyrics = lyricsResult + requestFinished = true + asyncLock.signal() } - asyncLock.unlock() + }) + + while !requestFinished { + asyncLock.wait() } + asyncLock.unlock() } } - - return lyrics } + + return lyrics } init(withTrack targetTrack: Track) { @@ -61,20 +58,21 @@ class LyricsEngine { var apiRequest = URLRequest(url: url) apiRequest.httpMethod = "GET" - let task = URLSession.shared.dataTask(with: apiRequest, completionHandler: {data, response, error -> Void in + let task = URLSession.shared.dataTask(with: apiRequest, completionHandler: {data, _, _ -> Void in // If the response is parseable JSON, and has a url, we'll look for // the lyrics in there if let data = data { - let jsonResponse = try? JSONSerialization.jsonObject(with: data) as! [String: Any] - if let jsonResponse = jsonResponse { - if let lyricsUrlString = jsonResponse["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 jsonResponse = try? JSONSerialization.jsonObject(with: data) { + if let jsonResponse = jsonResponse as? [String: Any] { + if let lyricsUrlString = jsonResponse["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 + } } } } @@ -92,7 +90,7 @@ class LyricsEngine { var pageRequest = URLRequest(url: url) pageRequest.httpMethod = "GET" - let task = URLSession.shared.dataTask(with: pageRequest, completionHandler: {data, response, error -> Void in + let task = URLSession.shared.dataTask(with: pageRequest, completionHandler: {data, _, _ -> Void in // If the response is parseable JSON, and has a url, we'll look for // the lyrics in there diff --git a/Sources/main.swift b/Sources/main.swift index 42d4855..5c39cb5 100644 --- a/Sources/main.swift +++ b/Sources/main.swift @@ -1,11 +1,43 @@ import CommandLineKit import Foundation +func main() { + let (flags, parser) = createParser() + + do { + try parser.parse() + } catch { + parser.printUsage(error) + exit(EX_USAGE) + } + + // Boolean Options + + checkHelpFlag(flags["help"], withParser: parser) + checkVersionFlag(flags["version"], withParser: parser) + checkListSourcesFlag(flags["listSources"], withParser: parser) + checkTitleFlag(flags["title"], withParser: parser) + + // String Options + + checkEnableSourceFlag(flags["enableSource"], withParser: parser) + checkDisableSourceFlag(flags["disableSource"], withParser: parser) + checkResetSourceFlag(flags["resetSource"], withParser: parser) + + // Remove any flags so anyone after this gets the unprocessed values + + let programName: [String] = [CommandLine.arguments[0]] + CommandLine.arguments = programName + parser.unparsedArguments + + // Run Lyricli + + Lyricli.printLyrics() +} + /// Sets up and returns a new options parser /// /// - Returns: A Dictionary of Options, and a new CommandLineKit instance -func createParser() -> ([String:Option], CommandLineKit) { - +private func createParser() -> ([String:Option], CommandLineKit) { let parser = CommandLineKit() var flags: [String:Option] = [:] @@ -25,7 +57,7 @@ func createParser() -> ([String:Option], CommandLineKit) { var formattedString: String - switch(type) { + switch type { case .About: formattedString = "\(parseString) [ ]" break @@ -39,71 +71,80 @@ func createParser() -> ([String:Option], CommandLineKit) { return (flags, parser) } -func main() { - - let (flags, parser) = createParser() +// Handle the Help flag - do { - try parser.parse() - } - catch { - parser.printUsage(error) - exit(EX_USAGE) - } - - if let helpFlag = flags["help"] as? BoolOption { - if helpFlag.value == true { +private func checkHelpFlag(_ flag: Option?, withParser parser: CommandLineKit) { + if let helpFlag = flag as? BoolOption { + if helpFlag.value { parser.printUsage() exit(0) } } +} - if let versionFlag = flags["version"] as? BoolOption { - if versionFlag.value == true { +// Handle the version flag + +private func checkVersionFlag(_ flag: Option?, withParser parser: CommandLineKit) { + if let versionFlag = flag as? BoolOption { + if versionFlag.value { print(Lyricli.version) exit(0) } } +} - if let listSourcesFlag = flags["listSources"] as? BoolOption { - if listSourcesFlag.value == true { +// Handle the list sources flag + +private func checkListSourcesFlag(_ flag: Option?, withParser parser: CommandLineKit) { + if let listSourcesFlag = flag as? BoolOption { + if listSourcesFlag.value { Lyricli.printSources() exit(0) } } +} + +// Handle the title flag + +private func checkTitleFlag(_ flag: Option?, withParser parser: CommandLineKit) { + if let titleFlag = flag as? BoolOption { + if titleFlag.value { + Lyricli.showTitle = true + } + } +} + +// Handle the enable source flag - if let enableSourceFlag = flags["enableSource"] as? StringOption { +private func checkEnableSourceFlag(_ flag: Option?, withParser parser: CommandLineKit) { + if let enableSourceFlag = flag as? StringOption { if let source = enableSourceFlag.value { Lyricli.enableSource(source) exit(0) } } +} + +// Handle the disable source flag - if let disableSourceFlag = flags["disableSource"] as? StringOption { +private func checkDisableSourceFlag(_ flag: Option?, withParser parser: CommandLineKit) { + if let disableSourceFlag = flag as? StringOption { if let source = disableSourceFlag.value { Lyricli.disableSource(source) exit(0) } } +} + +// Handle the reset source flag - if let resetSourceFlag = flags["resetSource"] as? StringOption { +private func checkResetSourceFlag(_ flag: Option?, withParser parser: CommandLineKit) { + if let resetSourceFlag = flag as? StringOption { if let source = resetSourceFlag.value { Lyricli.resetSource(source) exit(0) } } - - if let titleFlag = flags["title"] as? BoolOption { - if titleFlag.value == true { - Lyricli.showTitle = true - } - } - - // Remove any flags so anyone after this gets the unprocessed values - let programName: [String] = [CommandLine.arguments[0]] - CommandLine.arguments = programName + parser.unparsedArguments - - Lyricli.printLyrics() } main() diff --git a/Sources/source_manager.swift b/Sources/source_manager.swift index dd956ad..e55cc8b 100644 --- a/Sources/source_manager.swift +++ b/Sources/source_manager.swift @@ -6,16 +6,13 @@ class SourceManager { ] var currentTrack: Track? { - get { - - for source in enabledSources { - if let currentTrack = source.currentTrack { - return currentTrack - } + for source in enabledSources { + if let currentTrack = source.currentTrack { + return currentTrack } - - return nil } + + return nil } var enabledSources: [Source] { @@ -23,19 +20,17 @@ class SourceManager { // Checks the config and returns an array of sources based on the // enabled and available ones - get { - var sources = [Source]() + var sources = [Source]() - if let sourceNames = Configuration.sharedInstance["enabled_sources"] as? [String]{ - for sourceName in sourceNames { - if let source = availableSources[sourceName] { - sources.append(source) - } + if let sourceNames = Configuration.sharedInstance["enabled_sources"] as? [String] { + for sourceName in sourceNames { + if let source = availableSources[sourceName] { + sources.append(source) } } - - return sources } + + return sources } func enable(sourceName: String) { -- cgit From e17e616e2fa2059ef9cb93b7d654687c15d3cb07 Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Thu, 18 May 2017 23:51:30 -0500 Subject: Add contributing file --- CONTRIBUTING.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..57fb72e --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,37 @@ +# Contributing to Lyricli + +At this moment this is a really small project that I used to revive an +old ruby project and learn swift, it probably has a lot of bad code that +is not in "the swift way", it has no tests and can always be extended to +support more sources. + +## The ~~Roadmap~~ ~~Streetmap~~ ~~Pathmap~~ Corridormap + +* Writing sources (They're used to automatically obtain artist and song + name from +* Writing tests +* Improving code to match idiomatic swift +* Improving the documentation +* Extending the lyrics engine to support different lyrics sources +* Improving the build system + +## How to contribute + +Be nice, always, to others and yourself: use welcoming and inclusive language, +be patient and respectful of others' opinions and experiences. + +Do not insult others, use sexualized language, publish others' personal +information without their consent. Do not harass others. + +To report unacceptabe behavior, send an [e-mail][email] + +## Sending Pull Requests + +* Run [swiftlint][swiftlint] on the Source directory and make sure there are no errors +* There should be no warnings on compilation +* Make the PRs according to [Git Flow][gitflow]: (features go to + develop, hotfixes go to master) + +[gitflow]: https://github.com/nvie/gitflow +[swiftlint]: https://github.com/realm/SwiftLint +[email]: mailto:ben@nsovocal.com -- cgit From 255dbbaee3d3d440da1565b913d982372f72479d Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Thu, 18 May 2017 23:51:44 -0500 Subject: Add a more detailed readme --- README.md | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 71d7259..2e7545c 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,73 @@ # Lyricli (lrc) -A command line tool to show the lyrics of your current song +A command line tool to show the lyrics of your current song. + +## Usage + +Lyricli can be invoked with the command `lrc`. It can be invoked without +arguments, with an artist and song or with a special command: + +``` +$ lrc [-t] +``` + +When you run it without arguments, it will look in the available source +to try to find a playing song and extract the lyrics. If you include the +`-t` flag, it will show the song and artist names before the lyrics. + +``` +$ lrc [-t] +``` + +When you run it with arguments, it will use them to search for the +lyrics. This won't work if you manually disable the arguments source in +your configuration file. If you include the `-t` flag, it will show the +song and artist names before the lyrics. + +### Commands + +In order to configure + +* `lrc -l` or `lrc --list-sources` lists the available sources. Enabled + sourcess will have a `*` +* `lrc -e` or `lrc --enable ` enables a source +* `lrc -d` or `lrc --disable ` disables a source +* `lrc -r` or `lrc --reset-source ` resets the configuration for + a source and disables it. +* `lrc -v` or `lrc --version` prints the version +* `lrc -h` or `lrc --help` display built-in help ## Building -Run `swift build` +The build has only been tested on OSX using Swift 3.1. Building defaults +to the debug configuration. + +``` +make +``` + +## Installing from source + +Builds lyricli in release configuration and copies the executable as +`lrc` to `/usr/local/bin` + +``` +make install +``` + +### Installing to a custom directory + +This can be done by overriding the `install_path` variable + +``` +make install install_path=/opt/bin +``` ## Running tests -Run `swift test` +No tests at the moment 😬... but the makefile is mapped to run the swift +tests. + +``` +make test +``` -- cgit From 942fbbc8e7085fd5704ad2ffa096f02a42ab3afe Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Thu, 18 May 2017 23:57:25 -0500 Subject: Add travis config --- .travis.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..7c2bbed --- /dev/null +++ b/.travis.yml @@ -0,0 +1,7 @@ +language: + - swift + +osx_image: xcode8.3 + +script: + - make build -- cgit From 307993a0c51d3207581c33068d69e2b826348bd6 Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Fri, 19 May 2017 00:05:14 -0500 Subject: Add lint target to make --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 34eec3a..abbfd02 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,10 @@ install: build test: build swift test +lint: + cd Sources && swiftlint + clean: swift build --clean -.PHONY: build test clean +.PHONY: build install test clean lint -- cgit From 76055210073bc0e39137b455e3c8311214ae4107 Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Fri, 19 May 2017 00:07:14 -0500 Subject: Add swiftlint install script --- Scripts/install_swiftlint.sh | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100755 Scripts/install_swiftlint.sh diff --git a/Scripts/install_swiftlint.sh b/Scripts/install_swiftlint.sh new file mode 100755 index 0000000..6a2f250 --- /dev/null +++ b/Scripts/install_swiftlint.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +# Taken from: https://alexplescan.com/posts/2016/03/03/setting-up-swiftlint-on-travis-ci/ + +# Installs the SwiftLint package. +# Tries to get the precompiled .pkg file from Github, but if that +# fails just recompiles from source. + +set -e + +SWIFTLINT_PKG_PATH="/tmp/SwiftLint.pkg" +SWIFTLINT_PKG_URL="https://github.com/realm/SwiftLint/releases/download/0.18.1/SwiftLint.pkg" + +wget --output-document=$SWIFTLINT_PKG_PATH $SWIFTLINT_PKG_URL + +if [ -f $SWIFTLINT_PKG_PATH ]; then + echo "SwiftLint package exists! Installing it..." + sudo installer -pkg $SWIFTLINT_PKG_PATH -target / +else + echo "SwiftLint package doesn't exist. Compiling from source..." && + git clone https://github.com/realm/SwiftLint.git /tmp/SwiftLint && + cd /tmp/SwiftLint && + git submodule update --init --recursive && + sudo make install +fi -- cgit From 691c09f872dfd69d6e3df12ce0e1d2f0807b3937 Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Fri, 19 May 2017 00:07:26 -0500 Subject: Add linting to travis --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 7c2bbed..3e2236d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,5 +3,9 @@ language: osx_image: xcode8.3 +install: + - ./Scripts/install_swiftlint.sh + script: + - make lint - make build -- cgit From 22172f7d09afee10de0329160e0003e0aa9ff7ed Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Fri, 19 May 2017 00:10:15 -0500 Subject: Add build status badge --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2e7545c..d3ad9e9 100644 --- a/README.md +++ b/README.md @@ -71,3 +71,5 @@ tests. ``` make test ``` + +[![Build Status](https://travis-ci.org/lyricli-app/lyricli.svg?branch=master)](https://travis-ci.org/lyricli-app/lyricli) -- cgit From fc3f842abd1fd804fbb7a04f123c2102a785dfc3 Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Fri, 19 May 2017 00:12:14 -0500 Subject: Add changes to CHANGELOG --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6712ba..74adbd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ### Added +- Apache License +- Documentation to help use lyricli and contribute +- Makefile to help build and install +- CI integration +- Lyrics engine to fetch the lyrics from lyricswiki +- Arguments source to read song and artist from command line - Parsing of options to match legacy lyricli - Placeholder for the library with expected endpoints -- cgit From a489422bb6e7b631cbd83a2b555c150d8ee5aed9 Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Fri, 19 May 2017 00:13:42 -0500 Subject: Add mentions of CI to CONTRIBUTING --- CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 57fb72e..966e0e1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,9 +29,11 @@ To report unacceptabe behavior, send an [e-mail][email] * Run [swiftlint][swiftlint] on the Source directory and make sure there are no errors * There should be no warnings on compilation +* [CI][ci] should be green * Make the PRs according to [Git Flow][gitflow]: (features go to develop, hotfixes go to master) [gitflow]: https://github.com/nvie/gitflow [swiftlint]: https://github.com/realm/SwiftLint [email]: mailto:ben@nsovocal.com +[ci]: https://travis-ci.org/lyricli-app/lyricli -- cgit From 74b4bbe9f35e7d29e0822a892b8498cab9b1801c Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Fri, 19 May 2017 00:19:14 -0500 Subject: Set the version to 0.0.0 --- Sources/lyricli.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/lyricli.swift b/Sources/lyricli.swift index 5931ca1..10d9270 100644 --- a/Sources/lyricli.swift +++ b/Sources/lyricli.swift @@ -1,6 +1,6 @@ /// The main Lyricli interface public class Lyricli { - public static var version = "0.0.0-feature/option-parsing" + public static var version = "0.0.0" public static var showTitle = false -- cgit From cd24d1cbf0d0ef907714cbf767ad6199bcaf9bcd Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Fri, 19 May 2017 00:30:51 -0500 Subject: Add docs to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 02c0875..2deb6d7 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /.build /Packages /*.xcodeproj +docs -- cgit From 0a349ded18c79cfab18627e48bbd5ddeb21153d1 Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Fri, 19 May 2017 00:32:10 -0500 Subject: Add documentation target to make --- Makefile | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Makefile b/Makefile index abbfd02..499e1d1 100644 --- a/Makefile +++ b/Makefile @@ -25,6 +25,18 @@ test: build lint: cd Sources && swiftlint +document: build + sourcekitten doc --spm-module $(source_binary_name) > $(build_path)/$(source_binary_name).json + jazzy \ + -s $(build_path)/$(source_binary_name).json \ + --readme README.md \ + --clean \ + --author Lyricli \ + --author_url https://github.com/lyricli-app \ + --github_url https://github.com/lyricli-app/lyricli \ + --module-version 0.0.0 \ + --module Lyricli \ + clean: swift build --clean -- cgit From 259284d03aba0302b1a65cf82bb1fa97535d4ad3 Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Fri, 19 May 2017 00:32:30 -0500 Subject: Add docs and lint info to readme --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index d3ad9e9..5e7c995 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,12 @@ This can be done by overriding the `install_path` variable make install install_path=/opt/bin ``` +## Linting and Generating Documentation + +We use [swiftlint][swiftlint] to lint, and `make lint` to run it. +We use [jazzy][jazzy] and [SourceKitten][sourcekitten] to document, and +`make document` to generate it. + ## Running tests No tests at the moment 😬... but the makefile is mapped to run the swift @@ -73,3 +79,7 @@ make test ``` [![Build Status](https://travis-ci.org/lyricli-app/lyricli.svg?branch=master)](https://travis-ci.org/lyricli-app/lyricli) + +[swiftlint]: https://github.com/realm/SwiftLint +[jazzy]: https://github.com/realm/jazzy +[sourcekitten]: https://github.com/jpsim/SourceKitten -- cgit From 5398a7be137c5f4567ec535242eb899a3715269c Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Fri, 19 May 2017 00:33:00 -0500 Subject: Add documentation to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74adbd2..810e765 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ### Added +- Documentation with Jazzy / SourceKitten - Apache License - Documentation to help use lyricli and contribute - Makefile to help build and install -- cgit From 892c577e9147f2b60e9238ba4eb8c274a9af2bf0 Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Fri, 19 May 2017 00:36:40 -0500 Subject: Add script to install sourcekitten --- Scripts/install_sourcekitten.sh | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 Scripts/install_sourcekitten.sh diff --git a/Scripts/install_sourcekitten.sh b/Scripts/install_sourcekitten.sh new file mode 100644 index 0000000..9420a26 --- /dev/null +++ b/Scripts/install_sourcekitten.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +# Taken from: https://alexplescan.com/posts/2016/03/03/setting-up-swiftlint-on-travis-ci/ +# And adapted for sourcekitten + +# Installs the SourceKitten package. +# Tries to get the precompiled .pkg file from Github, but if that +# fails just recompiles from source. + +set -e + +SOURCEKITTEN_PKG_PATH="/tmp/SourceKitten.pkg" +SOURCEKITTEN_PKG_URL="https://github.com/jpsim/SourceKitten/releases/download/0.17.3/SourceKitten.pkg" + +wget --output-document=$SOURCEKITTEN_PKG_PATH $SOURCEKITTEN_PKG_URL + +if [ -f $SOURCEKITTEN_PKG_PATH ]; then + echo "SourceKitten package exists! Installing it..." + sudo installer -pkg $SOURCEKITTEN_PKG_PATH -target / +else + echo "SourceKitten package doesn't exist. Compiling from source..." && + git clone https://github.com/jspim/SourceKitten.git /tmp/SourceKitten && + cd /tmp/SourceKitten && + sudo make install +fi -- cgit From cb8adfd113438fcf33a8e840c26c2661d782d738 Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Fri, 19 May 2017 00:45:04 -0500 Subject: Add doc generation to linter --- .travis.yml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3e2236d..119df91 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,8 +4,25 @@ language: osx_image: xcode8.3 install: - - ./Scripts/install_swiftlint.sh + - gem install jazzy + - "./Scripts/install_sourcekitten.sh" + - "./Scripts/install_swiftlint.sh" script: - make lint - make build + +after_script: + - make document + +deploy: + provider: pages + skip_cleanup: true + github_token: "$GITHUB_TOKEN" + local_dir: docs + on: + branch: feature/rbdr-document-and-cleanup + +env: + global: + secure: EyOzJFSGY2ifBVqnQz7Xc0sDcg9maLb7VDKWIC2+1n2RsMHGptsxDfJf9r/bOc2kJN9mCzw19eA3XTkypeHKgIgPZ+boLPTDqiiNcD+0iVkYxqw/Q0v5et1+pJaOUo93cKfl2WLWXvISU1MYuzbjGwmnjPDUmujTwGZH1SFvhOKynqx9V/PiL4ZF+CurU2far+diLDhJXUPT4mDV6lDfiALUBvfj50AplM928Vwc6xr71SFii4fE+1GGGGI23ZyXmhnYIJBfQ/9d2wzW6szSRz+q0Gq8jQFJ2cZmBQPnfPY6/xARkDIf5H55HIxLg8pqA7Yn+WDT6/a8uoFLY6OzI8B/TTZ/pX4LXhkK0gbmXeeigRjxN3Dcsb++n9e5+3/Bq0y/Vm+Ufy+TtEvExvU6vdzDu8YZQaE0T2Loyqaw3BQBMoCunv4i7z0crXTLyNYNuc3zDGDmjkR3laxX8lcEZ85zTRTuYqxmvQxkxWUHKYQOvGy7SfkD1xc73f1XvCqpx45utZX0U/OzIxRflWFNy4mlgLvo23h5T0b44LGBBBWEVkjt5YduOuSo9L1wtOrADcDYyxSciIby2SHd4B2fGOb059KyCIUcX/qgOS6FJlmPeC963NCAuZB6DyscaoT6DrJto9nuZW2wNYdo7dvCC2E4ZqHnRPl2zux/RTmeuCU= -- cgit From 24500f5c638a73394322773c47472764072c51df Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Fri, 19 May 2017 00:47:21 -0500 Subject: Make sourceKitten script executable --- Scripts/install_sourcekitten.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 Scripts/install_sourcekitten.sh diff --git a/Scripts/install_sourcekitten.sh b/Scripts/install_sourcekitten.sh old mode 100644 new mode 100755 -- cgit From ae17fa044414076efbf19f70833537302c922cf4 Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Fri, 19 May 2017 00:50:40 -0500 Subject: Ensure docs only happen on after success --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 119df91..ce7ca0f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ script: - make lint - make build -after_script: +after_success: - make document deploy: -- cgit From a4c9b31e812baf67a4a3b092247bd18a23dd3b85 Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Fri, 19 May 2017 00:51:06 -0500 Subject: Use before_deploy to generate docs --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ce7ca0f..bf6c733 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ script: - make lint - make build -after_success: +before_deploy: - make document deploy: -- cgit From 34ce0eef8e29cb156e6fb92fc3bf7ad13ff9598c Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Fri, 19 May 2017 00:58:22 -0500 Subject: Only build docs on master --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index bf6c733..46250e5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ deploy: github_token: "$GITHUB_TOKEN" local_dir: docs on: - branch: feature/rbdr-document-and-cleanup + branch: master env: global: -- cgit From d852b84edc24f1f1bbf4c34aa359447970e732b0 Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Sat, 20 May 2017 09:40:03 -0500 Subject: Improve comments in code --- Sources/arguments_source.swift | 11 +++++++---- Sources/configuration.swift | 26 +++++++++++++------------- Sources/lyricli.swift | 31 +++++++++++++++++++++---------- Sources/lyrics_engine.swift | 26 +++++++++++++++++--------- Sources/main.swift | 3 ++- Sources/source_manager.swift | 13 ++++++++----- Sources/source_protocol.swift | 2 ++ Sources/track.swift | 6 +++++- 8 files changed, 75 insertions(+), 43 deletions(-) diff --git a/Sources/arguments_source.swift b/Sources/arguments_source.swift index d1bf4c6..9615318 100644 --- a/Sources/arguments_source.swift +++ b/Sources/arguments_source.swift @@ -1,10 +1,13 @@ -/// Source that deals with command line +// Source that reads track artist and name from the command line class ArgumentsSource: Source { - public var currentTrack: Track? { - if CommandLine.arguments.count >= 3 { - // expected usage: $ ./lyricli + // Returns a track based on the arguments. It assumes the track artist + // will be the first argument, and the name will be the second, excluding + // any flags. + var currentTrack: Track? { + if CommandLine.arguments.count >= 3 { + // expected usage: $ ./lyricli let trackName: String = CommandLine.arguments[2] let trackArtist: String = CommandLine.arguments[1] diff --git a/Sources/configuration.swift b/Sources/configuration.swift index bc21769..f1a1ee1 100644 --- a/Sources/configuration.swift +++ b/Sources/configuration.swift @@ -1,24 +1,23 @@ import Foundation -/// Handles reading and writing the configuration -public class Configuration { - - let configurationPath = NSString(string: "~/.lyricli.conf").expandingTildeInPath - - // The defaults are added here +// Reads and writes the configuration. Config keys are accessed as a dictionary. +class Configuration { + // Location of the global configuration file + private let configurationPath = NSString(string: "~/.lyricli.conf").expandingTildeInPath + // Default options, will be automatically written to the global config if + // not found. private var configuration: [String: Any] = [ - "enabled_sources": ["arguments"], - "default": true + "enabled_sources": ["arguments"] ] - static let sharedInstance: Configuration = Configuration() + // The shared instance of the object + static let shared: Configuration = Configuration() private init() { - // Read the config file and attempt toset any of the values. Otherwise - // Don't do anything. - // IMPROVEMENT: Enable a debug mode + // Read the config file and attempt to set any of the values. Otherwise + // don't do anything. if let data = try? NSData(contentsOfFile: configurationPath) as Data { if let parsedConfig = try? JSONSerialization.jsonObject(with: data) { @@ -42,6 +41,7 @@ public class Configuration { writeConfiguration() } + // Write the configuration back to the file private func writeConfiguration() { var error: NSError? @@ -56,7 +56,7 @@ public class Configuration { } } - // Allow access as an object + // Allow access to the config properties as a dictionary subscript(index: String) -> Any? { get { return configuration[index] diff --git a/Sources/lyricli.swift b/Sources/lyricli.swift index 10d9270..e7d14b9 100644 --- a/Sources/lyricli.swift +++ b/Sources/lyricli.swift @@ -1,15 +1,20 @@ -/// The main Lyricli interface -public class Lyricli { - public static var version = "0.0.0" +// The main class, handles all the actions that the executable will call +class Lyricli { - public static var showTitle = false + // Version of the application + static var version = "0.0.0" - public static func printLyrics() { + // Flag that controls whether we should show the track artist and name before + // the lyrics + static var showTitle = false + + // Obtains the name of the current track from a source, fetches the lyrics + // from an engine and prints them + static func printLyrics() { let sourceManager = SourceManager() if let currentTrack = sourceManager.currentTrack { - let engine = LyricsEngine(withTrack: currentTrack) if let lyrics = engine.lyrics { @@ -27,22 +32,28 @@ public class Lyricli { } } - public static func printSources() { + // Print the currently available sources + static func printSources() { print("Listing Sources: Not yet implemented") } - public static func enableSource(_ sourceName: String) { + // Runs the enable method of a source and writes the configuration to set it + // as enabled + static func enableSource(_ sourceName: String) { print("Enable source \(sourceName): Not yet implemented") } - public static func disableSource(_ sourceName: String) { + // Remove a source from the enabled sources configuration + static func disableSource(_ sourceName: String) { print("Disable source \(sourceName): Not yet implemented") } - public static func resetSource(_ sourceName: String) { + // Removes any configuration for a source, and disables it + static func resetSource(_ sourceName: String) { print("Reset source \(sourceName): Not yet implemented") } + // Prints the track artist and name private static func printTitle(_ track: Track) { print("\(track.artist) - \(track.name)") } diff --git a/Sources/lyrics_engine.swift b/Sources/lyrics_engine.swift index 9741a2c..85e4735 100644 --- a/Sources/lyrics_engine.swift +++ b/Sources/lyrics_engine.swift @@ -1,20 +1,28 @@ import Foundation import HTMLEntities -/// Looks for lyrics on the internet +// Given a track, attempts to fetch the lyrics from lyricswiki class LyricsEngine { + // URL of the API endpoint to use private let apiURL = "https://lyrics.wikia.com/api.php?action=lyrics&func=getSong&fmt=realjson" + + // 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'>(.+) Void) { var apiRequest = URLRequest(url: url) @@ -83,8 +92,7 @@ class LyricsEngine { task.resume() } - // Fetch the lyrics from the page and parse the page - + // Fetch the lyrics from the page and send it to the parser private func fetchLyricsFromPage(withURL url: URL, completionHandler: @escaping (String?) -> Void) { var pageRequest = URLRequest(url: url) @@ -107,10 +115,11 @@ class LyricsEngine { task.resume() } - // Parses the wiki to obtain the lyrics - + // 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.characters.count)) @@ -131,7 +140,6 @@ class LyricsEngine { } // Escapes the HTML entities - private func decodeLyrics(_ lyrics: String) -> String { let unescapedLyrics = lyrics.htmlUnescape() diff --git a/Sources/main.swift b/Sources/main.swift index 5c39cb5..9d46e92 100644 --- a/Sources/main.swift +++ b/Sources/main.swift @@ -1,7 +1,8 @@ import CommandLineKit import Foundation -func main() { +// Entry point of the application. This is the main executable +private func main() { let (flags, parser) = createParser() do { diff --git a/Sources/source_manager.swift b/Sources/source_manager.swift index e55cc8b..5ee1305 100644 --- a/Sources/source_manager.swift +++ b/Sources/source_manager.swift @@ -1,10 +1,12 @@ -/// Manages the different sources. Keeps track of them, lists and toggles +// Collect and manage the available and enabled source class SourceManager { + // List of sources enabled for the crurent platform private var availableSources: [String: Source] = [ "arguments": ArgumentsSource() ] + // Iterate over the sources until we find a track or run out of sources var currentTrack: Track? { for source in enabledSources { if let currentTrack = source.currentTrack { @@ -15,6 +17,7 @@ class SourceManager { return nil } + // Return the list of enabled sources based on the configuration var enabledSources: [Source] { // Checks the config and returns an array of sources based on the @@ -22,7 +25,7 @@ class SourceManager { var sources = [Source]() - if let sourceNames = Configuration.sharedInstance["enabled_sources"] as? [String] { + if let sourceNames = Configuration.shared["enabled_sources"] as? [String] { for sourceName in sourceNames { if let source = availableSources[sourceName] { sources.append(source) @@ -33,15 +36,15 @@ class SourceManager { return sources } + // Given a source name, it will enable it and add it to the enabled sources config func enable(sourceName: String) { } + // Given a source name, it will remove it from the enabled sources config func disable(sourceName: String) { } + // Given a source name, it removes any stored configuration and disables it func reset(sourceName: String) { } - - func getSources(sourceName: String) { - } } diff --git a/Sources/source_protocol.swift b/Sources/source_protocol.swift index ee9350c..0885994 100644 --- a/Sources/source_protocol.swift +++ b/Sources/source_protocol.swift @@ -1,3 +1,5 @@ +// All sources should comply with this protocol. The currentTrack computed +// property will return a track if the conditions are met protocol Source { var currentTrack: Track? { get } } diff --git a/Sources/track.swift b/Sources/track.swift index d2a9047..ead4359 100644 --- a/Sources/track.swift +++ b/Sources/track.swift @@ -1,6 +1,10 @@ -/// Contains the artist and name of a track +// Holds the name and artist of a track class Track { + + // The name of the track to search for let name: String + + // The name of the artist let artist: String init(withName trackName: String, andArtist trackArtist: String) { -- cgit