deep-linking-sample/Apps/Wikipedia/WMF Framework/Remote Notifications/Model/WikimediaProject+RemoteNotifications.swift

276 lines
14 KiB
Swift
Raw Permalink Normal View History

import Foundation
extension WikimediaProject {
private static var commonsIdentifier: String {
return "commonswiki"
}
private static var wikidataIdentifier: String {
return "wikidatawiki"
}
private static var mediawikiIdentifier: String {
return "mediawikiwiki"
}
private static var wikispeciesIdentifier: String {
return "specieswiki"
}
private static var wikipediaLanguageSuffix: String {
return "wiki"
}
private static var wikibooksLanguageSuffix: String {
return "wikibooks"
}
private static var wiktionaryLanguageSuffix: String {
return "wiktionary"
}
private static var wikiquoteLanguageSuffix: String {
return "wikiquote"
}
private static var wikimediaLanguageSuffix: String {
return "wikimedia"
}
private static var wikisourceLanguageSuffix: String {
return "wikisource"
}
private static var wikinewsLanguageSuffix: String {
return "wikinews"
}
private static var wikiversityLanguageSuffix: String {
return "wikiversity"
}
private static var wikivoyageLanguageSuffix: String {
return "wikivoyage"
}
public var notificationsApiWikiIdentifier: String {
switch self {
case .wikipedia(let languageCode, _, _):
return languageCode + Self.wikipediaLanguageSuffix
case .commons:
return Self.commonsIdentifier
case .wikidata:
return Self.wikidataIdentifier
case .wikibooks(let languageCode, _):
return languageCode + Self.wikibooksLanguageSuffix
case .wiktionary(let languageCode, _):
return languageCode + Self.wiktionaryLanguageSuffix
case .wikiquote(let languageCode, _):
return languageCode + Self.wikiquoteLanguageSuffix
case .wikisource(let languageCode, _):
return languageCode + Self.wikisourceLanguageSuffix
case .wikinews(let languageCode, _):
return languageCode + Self.wikinewsLanguageSuffix
case .wikiversity(let languageCode, _):
return languageCode + Self.wikiversityLanguageSuffix
case .wikivoyage(let languageCode, _):
return languageCode + Self.wikivoyageLanguageSuffix
case .mediawiki:
return Self.mediawikiIdentifier
case .wikispecies:
return Self.wikispeciesIdentifier
}
}
private var projectName: String {
// TODO: This would be better as a generated mapping file from translatewiki's project translations (for example: https://translatewiki.net/wiki/Special:ExportTranslations?group=ext-wikimediaprojectnames&language=he&format=export-to-file)
// See https://phabricator.wikimedia.org/T297620
switch self {
case .wikipedia:
return CommonStrings.plainWikipediaName
case .wikibooks:
return WMFLocalizedString("project-name-wikibooks", value:"Wikibooks", comment: "Project name for Wikibooks.")
case .wiktionary:
return WMFLocalizedString("project-name-wiktionary", value:"Wiktionary", comment: "Project name for Wiktionary.")
case .wikiquote:
return WMFLocalizedString("project-name-wikiquote", value:"Wikiquote", comment: "Project name for Wikiquote.")
case .wikisource:
return WMFLocalizedString("project-name-wikisource", value:"Wikisource", comment: "Project name for Wikisource.")
case .wikinews:
return WMFLocalizedString("project-name-wikinews", value:"Wikinews", comment: "Project name for Wikinews.")
case .wikiversity:
return WMFLocalizedString("project-name-wikiversity", value:"Wikiversity", comment: "Project name for Wikiversity.")
case .wikivoyage:
return WMFLocalizedString("project-name-wikivoyage", value:"Wikivoyage", comment: "Project name for Wikivoyage.")
case .commons:
return WMFLocalizedString("project-name-wikimedia-commons", value:"Wikimedia Commons", comment: "Project name for Wikimedia Commons.")
case .wikidata:
return WMFLocalizedString("project-name-wikidata", value:"Wikidata", comment: "Project name for Wikidata.")
case .mediawiki:
return WMFLocalizedString("project-name-mediawiki", value:"MediaWiki", comment: "Project name for MediaWiki.")
case .wikispecies:
return WMFLocalizedString("project-name-wikispecies", value:"Wikispecies", comment: "Project name for Wikispecies.")
}
}
/// Returns formatted descriptive project name
/// - Parameters:
/// - shouldReturnCodedFormat: Boolean for if you want description in coded format for langauge projects ("EN-Wikipedia" vs "English Wikipedia"). This is ignored for commons and wikidata projects.
/// - Returns: Formatted descriptive project name
public func projectName(shouldReturnCodedFormat: Bool) -> String {
let createLanguageProjectNameBlock: (String, String, String, Bool) -> String = { (languageCode, localizedLanguageName, projectName, shouldReturnCodedFormat) in
let format = WMFLocalizedString("notifications-center-language-project-name-format", value: "%1$@ %2$@", comment: "Format used for the ordering of language project name descriptions. This description is inserted into the header text of notifications in Notifications Center. For example, \"English Wikipedia\". Use this format to reorder these words if necessary or insert additional connecting words. Parameters: %1$@ = localized language name (\"English\"), %2$@ = localized name for Wikipedia (\"Wikipedia\")")
if !shouldReturnCodedFormat {
return String.localizedStringWithFormat(format, localizedLanguageName, projectName)
} else {
let codedProjectName = "\(languageCode.localizedUppercase)-\(projectName)"
return codedProjectName
}
}
switch self {
case .wikipedia(let languageCode, let localizedLanguageName, _):
return createLanguageProjectNameBlock(languageCode, localizedLanguageName, projectName, shouldReturnCodedFormat)
case .commons:
return projectName
case .wikidata:
return projectName
case .wikibooks(let languageCode, let localizedLanguageName):
return createLanguageProjectNameBlock(languageCode, localizedLanguageName, projectName, shouldReturnCodedFormat)
case .wiktionary(let languageCode, let localizedLanguageName):
return createLanguageProjectNameBlock(languageCode, localizedLanguageName, projectName, shouldReturnCodedFormat)
case .wikiquote(let languageCode, let localizedLanguageName):
return createLanguageProjectNameBlock(languageCode, localizedLanguageName, projectName, shouldReturnCodedFormat)
case .wikisource(let languageCode, let localizedLanguageName):
return createLanguageProjectNameBlock(languageCode, localizedLanguageName, projectName, shouldReturnCodedFormat)
case .wikinews(let languageCode, let localizedLanguageName):
return createLanguageProjectNameBlock(languageCode, localizedLanguageName, projectName, shouldReturnCodedFormat)
case .wikiversity(let languageCode, let localizedLanguageName):
return createLanguageProjectNameBlock(languageCode, localizedLanguageName, projectName, shouldReturnCodedFormat)
case .wikivoyage(let languageCode, let localizedLanguageName):
return createLanguageProjectNameBlock(languageCode, localizedLanguageName, projectName, shouldReturnCodedFormat)
case .mediawiki:
return projectName
case .wikispecies:
return projectName
}
}
public var languageVariantCode: String? {
switch self {
case .wikipedia(_, _, let languageVariantCode):
return languageVariantCode
default:
return nil
}
}
func mediaWikiAPIURL(configuration: Configuration, queryParameters: RemoteNotificationsAPIController.Query.Parameters?) -> URL? {
switch self {
case .commons:
return configuration.commonsAPIURLComponents(with: queryParameters).url
case .wikidata:
return configuration.wikidataAPIURLComponents(with: queryParameters).url
case .wikipedia(let languageCode, _, _):
return configuration.mediaWikiAPIURLForLanguageCode(languageCode, queryParameters: queryParameters).url
case .wikibooks(let languageCode, _):
return configuration.mediaWikiAPIURLForLanguageCode(languageCode, siteDomain: Configuration.Domain.wikibooks, queryParameters: queryParameters).url
case .wiktionary(let languageCode, _):
return configuration.mediaWikiAPIURLForLanguageCode(languageCode, siteDomain: Configuration.Domain.wiktionary, queryParameters: queryParameters).url
case .wikiquote(let languageCode, _):
return configuration.mediaWikiAPIURLForLanguageCode(languageCode, siteDomain: Configuration.Domain.wikiquote, queryParameters: queryParameters).url
case .wikisource(let languageCode, _):
return configuration.mediaWikiAPIURLForLanguageCode(languageCode, siteDomain: Configuration.Domain.wikisource, queryParameters: queryParameters).url
case .wikinews(let languageCode, _):
return configuration.mediaWikiAPIURLForLanguageCode(languageCode, siteDomain: Configuration.Domain.wikinews, queryParameters: queryParameters).url
case .wikiversity(let languageCode, _):
return configuration.mediaWikiAPIURLForLanguageCode(languageCode, siteDomain: Configuration.Domain.wikiversity, queryParameters: queryParameters).url
case .wikivoyage(let languageCode, _):
return configuration.mediaWikiAPIURLForLanguageCode(languageCode, siteDomain: Configuration.Domain.wikivoyage, queryParameters: queryParameters).url
case .mediawiki:
return configuration.mediaWikiAPIURLForHost(Configuration.Domain.mediaWiki, with: queryParameters).url
case .wikispecies:
return configuration.mediaWikiAPIURLForHost(Configuration.Domain.wikispecies, with: queryParameters).url
}
}
private static func projectForLanguageSuffix(suffix: String, language: MWKLanguageLink?) -> WikimediaProject? {
guard let language = language else {
return nil
}
switch suffix {
case Self.wikipediaLanguageSuffix:
return .wikipedia(language.languageCode, language.localizedName, language.languageVariantCode)
case Self.wikibooksLanguageSuffix:
return .wikibooks(language.languageCode, language.localizedName)
case Self.wiktionaryLanguageSuffix:
return .wiktionary(language.languageCode, language.localizedName)
case Self.wikiquoteLanguageSuffix:
return .wikiquote(language.languageCode, language.localizedName)
case Self.wikisourceLanguageSuffix:
return .wikisource(language.languageCode, language.localizedName)
case Self.wikinewsLanguageSuffix:
return .wikinews(language.languageCode, language.localizedName)
case Self.wikiversityLanguageSuffix:
return .wikiversity(language.languageCode, language.localizedName)
case Self.wikivoyageLanguageSuffix:
return .wikivoyage(language.languageCode, language.localizedName)
default:
return nil
}
}
/// Initializes WikimediaProject with wiki identifier recognize by the MediaWiki Notifications API
/// - Parameters:
/// - notificationsApiIdentifier: The API identifier used by the MediaWiki Notifications API. (e.g. "enwiki", "commonswiki", "wikidatawiki", etc.)
/// - languageLinkController: Included to validate project against a list of languages that the app recognizes. This also associates extra metadata to language enum associated value, like localizedName and languageVariantCode.
public init?(notificationsApiIdentifier: String, languageLinkController: MWKLanguageLinkController) {
switch notificationsApiIdentifier {
case Self.commonsIdentifier:
self = .commons
case Self.wikidataIdentifier:
self = .wikidata
case Self.wikispeciesIdentifier:
self = .wikispecies
case Self.mediawikiIdentifier:
self = .mediawiki
default:
let suffixes = [Self.wikipediaLanguageSuffix, Self.wikibooksLanguageSuffix, Self.wiktionaryLanguageSuffix, Self.wikiquoteLanguageSuffix, Self.wikimediaLanguageSuffix, Self.wikisourceLanguageSuffix, Self.wikinewsLanguageSuffix, Self.wikiversityLanguageSuffix, Self.wikivoyageLanguageSuffix]
var project: WikimediaProject?
for suffix in suffixes {
let strippedIdentifier = notificationsApiIdentifier.hasSuffix(suffix) ? String(notificationsApiIdentifier.dropLast(suffix.count)) : notificationsApiIdentifier
// confirm it is a recognized language
let recognizedLanguage = languageLinkController.allLanguages.first { languageLink in
languageLink.languageCode == strippedIdentifier
}
project = Self.projectForLanguageSuffix(suffix: suffix, language: recognizedLanguage)
if project != nil {
break
}
}
guard let project = project else {
return nil
}
self = project
}
}
}