Skip to content

Commit

Permalink
Refactor much, search, gamelist
Browse files Browse the repository at this point in the history
  • Loading branch information
FreeApp2014 committed Apr 22, 2020
1 parent 152ac1e commit aeae699
Show file tree
Hide file tree
Showing 5 changed files with 205 additions and 101 deletions.
4 changes: 1 addition & 3 deletions Package.swift
Expand Up @@ -10,7 +10,6 @@ let package = Package(
.library(
name: "SwiftyCM",
targets: ["SwiftyCM"]),
//.executable(name: "SCMclient", targets: ["client"])
],
dependencies: [
.package(url: "https://github.com/IBM-Swift/SwiftyJSON", from: "17.0.5")
Expand All @@ -22,7 +21,6 @@ let package = Package(
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
.target(
name: "SwiftyCM",
dependencies: ["SwiftyJSON"]),
//.target(name: "client", dependencies: ["SwiftyCM"])
dependencies: ["SwiftyJSON"])
]
)
5 changes: 2 additions & 3 deletions README.md
Expand Up @@ -8,8 +8,7 @@ This library can be imported into your project using SPM:
```swift
.package(url:"https://github.com/FreeApp2014/SwiftyCM")
```
to your dependencies<br>
and `dependencies: ["SwiftyCM"]` in your main target.
to your package.dependencies and `dependencies: ["SwiftyCM"]` in your main target.

## Example usage

Expand Down Expand Up @@ -78,4 +77,4 @@ A struct containing information about looping:
* loopTypeDesc: String - the loop type string

## Thrown errors
jsonParseError, httpRequestError, objectNotFoundError, otherApiError, nestedError
jsonParseError, httpRequestError, objectNotFoundError, otherApiError,
135 changes: 40 additions & 95 deletions Sources/SwiftyCM/SwiftyCM.swift
Expand Up @@ -20,116 +20,61 @@ func performGetRequest(url: String) -> (URLResponse, Data)? {
}

//This struct is reserved for future use
public struct SCMRestrictedAPIClient {
public struct SCMClient {
private var apiKey: String;
public init (apiKey: String){
self.apiKey = apiKey;
}
}

//Represents a game object on SCM, typically received from the game endpoint
public struct Game {
public var id: String, title: String, songs: [PartialSongField];
public init(_ id: String) throws {
self.id = id;
guard let e = performGetRequest(url: "https://smashcustommusic.net/json/game/\(self.id)") else {
public static func gameList() throws -> [GameListGameField]{
var returnval: [GameListGameField] = [];
guard let http = performGetRequest(url: "https://smashcustommusic.net/json/gamelist") else {
throw SCMError.httpRequestError
}
let json = JSON(data: http.1);
guard let gameList = json["games"].array else {
throw SCMError.jsonParseError;
}
for game in gameList {
returnval.append(GameListGameField(id: String(game["game_id"].int!), title: game["game_name"].string!, songCount: UInt(game["song_count"].int!)));
}
return returnval;
}
public static func search (_ query: String) throws -> [SearchSongField]{
var returnval: [SearchSongField] = [];
guard let http = performGetRequest(url: "https://smashcustommusic.net/json/search?search=\(query.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!)") else {
throw SCMError.httpRequestError
};
let json = JSON(data: e.1);
}
let json = JSON(data: http.1);
guard let state = json["ok"].bool else {
throw SCMError.otherApiError
throw SCMError.jsonParseError;
}
if (!state){
throw SCMError.objectNotFoundError;
}
if (state != true){
if (json["error"].string! == "404") {
throw SCMError.objectNotFoundError
} else {
throw SCMError.otherApiError
}
guard let songs = json["songs"].array else {
throw SCMError.otherApiError;
}
self.title = json["game_name"].string!;
self.songs = [];
guard let songs = json["songs"].array else {return}
for song in songs{
let songo = PartialSongField(id: String(song["song_id"].int!),
for song in songs {
returnval.append(SearchSongField(
id: String(song["song_id"].int!),
title: song["song_name"].string!,
secLength: UInt(song["song_length"].string!)!,
uploader: song["song_uploader"].string!,
secLength: UInt(song["song_length"].string ?? "0")!,
uploader: song["song_uploader"].string ?? "Unknown",
canDownload: song["song_available"].int! == 1,
downloadCount: UInt(song["song_downloads"].string!)!);
self.songs.append(songo);
}
}
}

//Used for supplying Song object with information
public struct SongLoopInformation{
public var doesLoop: Bool, loopStart: UInt, loopTypeDesc: String;
}

//Enum containing file types that can be downloaded from the API
public enum SongFileType:String {
case brstm = "brstm", wav = "wav", bwav = "bwav";
}

//The struct for song information received from the game endpoint
public struct PartialSongField{
public var id: String, title: String, secLength: UInt, uploader: String, canDownload: Bool, downloadCount: UInt;
public func resolveSong() throws -> Song{ //Get full Song object for this PartialSong
do {
let e = try Song(self.id);
return e;
} catch {
throw SCMError.nestedError
downloadCount: UInt(song["song_downloads"].string ?? "0")!,
gameId: String(song["song_game_id"].int!)));
}
// substrs.remove(at: 0);
// for str in substrs {
// print(str);
// returnval = returnval.filter { a in a.title.lowercased().contains(str.lowercased())}
// }
return returnval;
}
}

//The struct for game information received from the song endpoint
public struct PartialGameField{
public var id: String, title: String;
public func resolveGame() throws -> Game{ //Get full Game object for this PartialGame
do{
let e = try Game(self.id);
return e;
} catch {
throw SCMError.nestedError;
};
}
}

public enum SCMError: Error{
case jsonParseError, httpRequestError, objectNotFoundError, otherApiError, nestedError
case jsonParseError, httpRequestError, objectNotFoundError, otherApiError
}

//Represents a song object on SCM, typically received from the song endpoint
public struct Song {
public var id: String, title: String, uploader: String, secLength: UInt, sampleRate: UInt, loop: SongLoopInformation, canDownload: Bool, downloadCount: UInt, game: PartialGameField;
public init (_ id: String) throws {
self.id = id;
guard let e = performGetRequest(url: "https://smashcustommusic.net/json/song/\(self.id)") else {
throw SCMError.httpRequestError
};
let json = JSON(data: e.1);
guard let state = json["ok"].bool else {
throw SCMError.otherApiError
}
if (state != true){
if (json["error"].string! == "404") {
throw SCMError.objectNotFoundError
} else {
throw SCMError.otherApiError
}
}
self.title = json["name"].string!;
self.uploader = json["uploader"].string!;
self.canDownload = json["available"].int! == 1;
self.sampleRate = UInt(json["sample_rate"].string!)!;
self.game = PartialGameField(id: String(json["game_id"].int!), title: json["game_name"].string!);
self.loop = SongLoopInformation(doesLoop: json["loop_type"].string! == "None", loopStart: UInt(json["start_loop_point"].string!)!, loopTypeDesc: json["loop_type"].string!);
self.secLength = UInt(json["length"].string!)!;
self.downloadCount = UInt(json["downloads"].string!)!;
}
// public func download(inFormat: SongFileType) -> Data?{ //Download the file in specified file type
//
// }
}
78 changes: 78 additions & 0 deletions Sources/SwiftyCM/game.swift
@@ -0,0 +1,78 @@
//
// Created by freeapp on 20.04.2020.
//

import Foundation
import SwiftyJSON

//Represents a game object on SCM, typically received from the game endpoint
public struct Game {
public let id: String, title: String, songCount: UInt;
public var songs: [PartialSongField];
public init(_ id: String) throws {
self.id = id;
guard let e = performGetRequest(url: "https://smashcustommusic.net/json/game/\(self.id)") else {
throw SCMError.httpRequestError
};
let json = JSON(data: e.1);
guard let state = json["ok"].bool else {
throw SCMError.otherApiError
}
if (state != true){
if (json["error"].string! == "404") {
throw SCMError.objectNotFoundError
} else {
throw SCMError.otherApiError
}
}
self.title = json["game_name"].string!;
self.songs = [];
self.songCount = UInt(json["track_count"].int!);
guard let songs = json["songs"].array else {return}
for song in songs{
let songo = PartialSongField(id: String(song["song_id"].int!),
title: song["song_name"].string!,
secLength: UInt(song["song_length"].string!)!,
uploader: song["song_uploader"].string!,
canDownload: song["song_available"].int! == 1,
downloadCount: UInt(song["song_downloads"].string!)!);
self.songs.append(songo);
}
}
}



//The struct for game information received from the song endpoint
public struct PartialGameField{
public let id: String, title: String;
public func resolveGame() throws -> Game{ //Get full Game object for this PartialGame
do{
let e = try Game(self.id);
return e;
} catch SCMError.httpRequestError {
throw SCMError.httpRequestError
} catch SCMError.objectNotFoundError {
throw SCMError.objectNotFoundError
} catch SCMError.otherApiError {
throw SCMError.otherApiError
}
}
}

//The struct for game information from gamelist
public struct GameListGameField {
public let id: String, title: String, songCount: UInt;
public func resolveGame() throws -> Game{ //Get full Game object for this PartialGame
do{
let e = try Game(self.id);
return e;
} catch SCMError.httpRequestError {
throw SCMError.httpRequestError
} catch SCMError.objectNotFoundError {
throw SCMError.objectNotFoundError
} catch SCMError.otherApiError {
throw SCMError.otherApiError
}
}
}
84 changes: 84 additions & 0 deletions Sources/SwiftyCM/song.swift
@@ -0,0 +1,84 @@
//
// Created by freeapp on 20.04.2020.
//
import Foundation
import SwiftyJSON

//Used for supplying Song object with information
public struct SongLoopInformation{
public var doesLoop: Bool, loopStart: UInt, loopTypeDesc: String;
}

//Enum containing file types that can be downloaded from the API
public enum SongFileType:String {
case brstm = "brstm", wav = "wav", bwav = "bwav";
}

//The struct for song information received from the game endpoint
public struct PartialSongField{
public let id: String, title: String, secLength: UInt, uploader: String, canDownload: Bool, downloadCount: UInt;
public func resolveSong() throws -> Song{ //Get full Song object for this PartialSong
do {
let e = try Song(self.id);
return e;
} catch SCMError.httpRequestError {
throw SCMError.httpRequestError
} catch SCMError.objectNotFoundError {
throw SCMError.objectNotFoundError
} catch SCMError.otherApiError {
throw SCMError.otherApiError
}
}
}
//The struct for song information received from the game endpoint
public struct SearchSongField{
public let id: String, title: String, secLength: UInt, uploader: String, canDownload: Bool, downloadCount: UInt, gameId: String;
public func resolveSong() throws -> Song{ //Get full Song object for this PartialSong
do {
let e = try Song(self.id);
return e;
} catch SCMError.httpRequestError {
throw SCMError.httpRequestError
} catch SCMError.objectNotFoundError {
throw SCMError.objectNotFoundError
} catch SCMError.otherApiError {
throw SCMError.otherApiError
}
}
}

//Represents a song object on SCM, typically received from the song endpoint
public struct Song {
public let id: String, title: String, uploader: String, secLength: UInt, sampleRate: UInt, loop: SongLoopInformation, canDownload: Bool, downloadCount: UInt, game: PartialGameField;
public init (_ id: String) throws {
self.id = id;
guard let e = performGetRequest(url: "https://smashcustommusic.net/json/song/\(self.id)") else {
throw SCMError.httpRequestError
};
let json = JSON(data: e.1);
guard let state = json["ok"].bool else {
throw SCMError.otherApiError
}
if (state != true){
if (json["error"].string! == "404") {
throw SCMError.objectNotFoundError
} else {
throw SCMError.otherApiError
}
}
self.title = json["name"].string!;
self.uploader = json["uploader"].string!;
self.canDownload = json["available"].int! == 1;
self.sampleRate = UInt(json["sample_rate"].string!)!;
self.game = PartialGameField(id: String(json["game_id"].int!), title: json["game_name"].string!);
self.loop = SongLoopInformation(doesLoop: json["loop_type"].string! != "None", loopStart: UInt(json["start_loop_point"].string!)!, loopTypeDesc: json["loop_type"].string!);
self.secLength = UInt(json["length"].string!)!;
self.downloadCount = UInt(json["downloads"].string!)!;
}
public func download(inFormat format: SongFileType) -> Data?{ //Download the file in specified file type
guard let data = performGetRequest(url: "https://smashcustommusic.net/\(format)/\(self.id)") else {
return nil
}
return data.1;
}
}

0 comments on commit aeae699

Please sign in to comment.