// // BookDetailsModel.swift // WolneLektury // // Created by Pawel Dabrowski on 30/05/2018. // Copyright © 2018 Fundacja Nowoczesna Polska. All rights reserved. // import UIKit import RealmSwift protocol BookBase { var simple_thumb: String { get set } var title: String { get set } func getAuthor() -> String } extension BookBase{ // returns image url func getCoverThumbUrl() -> URL?{ if simple_thumb.count > 0{ var str = simple_thumb if (!str.contains(Config.MEDIA_URL) && !str.contains(Config.MEDIA_URL_HTTPS)) { str = Config.MEDIA_URL + str } return str.getUrl() } return nil } func getAttributedAuthorAndTitle(titleFont: UIFont, descFont: UIFont) -> NSAttributedString{ let titleAttributedText = NSMutableAttributedString(attributedString: NSAttributedString(string: getAuthor() + "\n", font: titleFont)) titleAttributedText.append(NSAttributedString(string: title, font: descFont)) return titleAttributedText } } class BookDetailsModel: Object, BookBase, Decodable, NSCopying { @objc dynamic var title: String = "" @objc dynamic var simple_thumb: String = "" var genres = List() var kinds = List() @objc dynamic var url: String = "" var media = List() @objc dynamic var simple_cover: String = "" var epochs = List() var authors = List() @objc dynamic var pdf: String = "" @objc dynamic var epub: String = "" @objc dynamic var fragmentTitle = "" @objc dynamic var fragmentHtml = "" @objc dynamic var audio_length: String = "" @objc dynamic var cover_color: String = "" //additional @objc dynamic var currentChapter = 0 @objc dynamic var totalChapters = 0 @objc dynamic var currentAudioChapter = 0 @objc dynamic var totalAudioChapters = 0 @objc dynamic var slug = "" private var privateBgColor: UIColor? var bgColor: UIColor{ get { if let privateBgColor = privateBgColor { return privateBgColor } privateBgColor = UIColor(hex: cover_color) return privateBgColor! } set { privateBgColor = newValue } } override class func primaryKey() -> String? { return "slug" } private enum BookDetailsModelCodingKeys: String, CodingKey { case title case simple_thumb case genres case kinds case url case media case simple_cover case epochs case authors case pdf case epub case fragment_data case audio_length case cover_color } convenience init(title: String, simple_thumb: String, url: String, simple_cover: String, pdf: String, epub: String, audio_length: String, cover_color: String, genres: [CategoryModel], kinds: [CategoryModel], media: [MediaModel], epochs: [CategoryModel], authors: [CategoryModel], fragmentTitle: String, fragmentHtml: String, slug: String) { self.init() self.title = title self.simple_thumb = simple_thumb self.url = url self.simple_cover = simple_cover self.pdf = pdf self.epub = epub self.audio_length = audio_length self.cover_color = cover_color self.fragmentHtml = fragmentHtml self.fragmentTitle = fragmentTitle self.slug = slug self.genres = List() self.kinds = List() self.epochs = List() self.authors = List() self.media = List() self.genres.append(objectsIn: genres) self.kinds.append(objectsIn: kinds) self.epochs.append(objectsIn: epochs) self.authors.append(objectsIn: authors) self.media.append(objectsIn: media) } convenience required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: BookDetailsModelCodingKeys.self) let title = try container.decode(String.self, forKey: .title) let simple_thumb = try container.decode(String.self, forKey: .simple_thumb) let url = try container.decode(String.self, forKey: .url) let simple_cover = try container.decode(String.self, forKey: .simple_cover) let pdf = try container.decode(String.self, forKey: .pdf) let epub = try container.decode(String.self, forKey: .epub) let audio_length = try container.decode(String.self, forKey: .audio_length) let cover_color = try container.decode(String.self, forKey: .cover_color) let genres = try container.decodeIfPresent([CategoryModel].self, forKey: .genres) let kinds = try container.decodeIfPresent([CategoryModel].self, forKey: .kinds) let epochs = try container.decodeIfPresent([CategoryModel].self, forKey: .epochs) let authors = try container.decodeIfPresent([CategoryModel].self, forKey: .authors) let media = try container.decodeIfPresent([MediaModel].self, forKey: .media) let fragment_data = try container.decodeIfPresent(FragmentModel.self, forKey: .fragment_data) let genresArray = genres ?? [] let kindsArray = kinds ?? [] let mediaArray = media ?? [] let epochsArray = epochs ?? [] let authorsArray = authors ?? [] self.init(title: title, simple_thumb: simple_thumb, url: url, simple_cover: simple_cover, pdf: pdf, epub: epub, audio_length: audio_length, cover_color: cover_color, genres: genresArray, kinds: kindsArray, media: mediaArray, epochs: epochsArray, authors: authorsArray, fragmentTitle: fragment_data?.title ?? "", fragmentHtml: fragment_data?.html ?? "", slug: "") } func getAuthor() -> String { return authors.map({$0.name}).joined(separator: ", ") } func getGenres() -> String { return genres.map({$0.name}).joined(separator: ", ") } func getKinds() -> String { return kinds.map({$0.name}).joined(separator: ", ") } func getEpochs() -> String { return epochs.map({$0.name}).joined(separator: ", ") } func getAudiobookMediaModels() -> [MediaModel] { var mediaModels = [MediaModel]() for mediaFile in media { if mediaFile.type == "mp3" { mediaModels.append(mediaFile) } } return mediaModels; } func getAudiobookFilesUrls() -> [String] { return getAudiobookMediaModels().map({$0.url}) } func checkIfAllAudiobookFilesAreDownloaded() -> Bool{ guard slug.count > 0 else {return false} let audiobookUrls = getAudiobookFilesUrls() for url in audiobookUrls{ if !NSObject.audiobookExists(audioBookUrlString: url, bookSlug: slug) { return false } } return true } func copy(with zone: NSZone? = nil) -> Any { var genresArray = [CategoryModel]() var kindsArray = [CategoryModel]() var epochsArray = [CategoryModel]() var authorsArray = [CategoryModel]() var mediaArray = [MediaModel]() for object in genres{ genresArray.append(object.copy() as! CategoryModel) } for object in kinds{ kindsArray.append(object.copy() as! CategoryModel) } for object in epochs{ epochsArray.append(object.copy() as! CategoryModel) } for object in authors{ authorsArray.append(object.copy() as! CategoryModel) } for object in media{ mediaArray.append(object.copy() as! MediaModel) } let model = BookDetailsModel(title: title, simple_thumb: simple_thumb, url: url, simple_cover: simple_cover, pdf: pdf, epub: epub, audio_length: audio_length, cover_color: cover_color, genres: genresArray, kinds: kindsArray, media: mediaArray, epochs: epochsArray, authors: authorsArray, fragmentTitle: fragmentTitle, fragmentHtml: fragmentHtml, slug: slug) if currentChapter > 0 { model.currentChapter = currentChapter } if currentAudioChapter > 0 { model.currentAudioChapter = currentAudioChapter } if totalAudioChapters > 0 { model.totalAudioChapters = totalAudioChapters } if totalChapters > 0 { model.totalAudioChapters = totalAudioChapters } return model } func setInitialAudiobookChaptersValuesIfNeeded() { if totalAudioChapters == 0 && currentAudioChapter == 0 { DatabaseManager.shared.updateCurrentChapters(bookDetailsModel: self, currentChapter: nil, totalChapters: nil, currentAudioChapter: 0, totalAudioChapters: getAudiobookFilesUrls().count) } } }