/// <summary> /// Fetch le things from le KerbalStuff. /// Returns a JObject that should be a fully formed CKAN file. /// </summary> internal static JObject KerbalStuff(JObject orig_metadata, string remote_id, NetFileCache cache) { // Look up our mod on KS by its ID. KSMod ks = KSAPI.Mod(Convert.ToInt32(remote_id)); KSVersion latest = ks.Latest(); Version version = latest.friendly_version; log.DebugFormat("Mod: {0} {1}", ks.name, version); // Find the latest download. string filename = latest.Download((string) orig_metadata["identifier"], cache); JObject metadata = MetadataFromFileOrDefault(filename, orig_metadata); // Check if we should auto-inflate. string kref = (string)metadata[expand_token]; if (kref == (string)orig_metadata[expand_token] || kref == "#/ckan/kerbalstuff") { log.InfoFormat("Inflating from KerbalStuff... {0}", metadata[expand_token]); ks.InflateMetadata(metadata, filename, latest); metadata.Remove(expand_token); } else { log.WarnFormat("Not inflating metadata for {0}", orig_metadata["identifier"]); } return metadata; }
public void KSHome() { var ks = new CKAN.NetKAN.KSMod {name = "foo bar", id = 123}; // KSHome no longer escapes URLs. Assert.AreEqual("https://kerbalstuff.com/mod/123/foo bar", ks.KSHome().ToString()); }
public void KSHome() { var ks = new CKAN.NetKAN.KSMod { name = "foo bar", id = 123 }; // KSHome no longer escapes URLs. Assert.AreEqual("https://kerbalstuff.com/mod/123/foo bar", ks.KSHome().ToString()); }
public static CKAN.NetKAN.KSMod test_ksmod() { var ksmod = new CKAN.NetKAN.KSMod { license = "CC-BY", name = "Dogecoin Flag", short_description = "Such test. Very unit. Wow.", author = "pjf", versions = new KSVersion[1] }; ksmod.versions[0] = new KSVersion { friendly_version = new Version("0.25"), download_path = new Uri("http://example.com/") }; return(ksmod); }
public static CKAN.NetKAN.KSMod test_ksmod() { var ksmod = new CKAN.NetKAN.KSMod { license = "CC-BY", name = "Dogecoin Flag", short_description = "Such test. Very unit. Wow.", author = "pjf", versions = new KSVersion[1] }; ksmod.versions[0] = new KSVersion { friendly_version = new Version("0.25"), download_path = new Uri("http://example.com/") }; return ksmod; }
// GH #199: Don't pre-fill KSP version fields if we see a ksp_min/max public void KSP_Version_Inflate_199() { JObject metadata = JObject.Parse(TestData.DogeCoinFlag_101()); // Add our own field, and remove existing ones. metadata["ksp_version_min"] = "0.23.5"; metadata["ksp_version"] = null; metadata["ksp_version_max"] = null; // Sanity check: make sure we don't have a ksp_version field to begin with. Assert.AreEqual(null, (string)metadata["ksp_version"]); CKAN.NetKAN.KSMod ksmod = test_ksmod(); ksmod.InflateMetadata(metadata, TestData.DogeCoinFlagZip(), ksmod.versions[0]); // Make sure min is still there, and the rest unharmed. Assert.AreEqual(null, (string)metadata["ksp_version"]); Assert.AreEqual(null, (string)metadata["ksp_version_max"]); Assert.AreEqual("0.23.5", (string)metadata["ksp_version_min"]); }
private const string version_token = "$vref"; // It'd be nice if we could have repeated $krefs. public static int Main(string[] args) { BasicConfigurator.Configure(); LogManager.GetRepository().Threshold = Level.Error; var user = new ConsoleUser(false); var options = new CmdLineOptions(); Parser.Default.ParseArgumentsStrict(args, options); if (options.Verbose) { LogManager.GetRepository().Threshold = Level.Info; } else if (options.Debug) { LogManager.GetRepository().Threshold = Level.Debug; } if (options.NetUserAgent != null) { Net.UserAgentString = options.NetUserAgent; } if (options.File == null) { log.Fatal("Usage: netkan [--verbose|--debug] [--prerelease] [--outputdir=...] <filename>"); return(EXIT_BADOPT); } NetFileCache cache = FindCache(options, new KSPManager(user), user); log.InfoFormat("Processing {0}", options.File); JObject json = JsonFromFile(options.File); NetKanRemote remote = FindRemote(json); JObject metadata; switch (remote.source) { case "kerbalstuff": metadata = KerbalStuff(json, remote.id, cache); break; case "jenkins": metadata = Jenkins(json, remote.id, cache); break; case "github": if (options.GitHubToken != null) { GithubAPI.SetCredentials(options.GitHubToken); } metadata = GitHub(json, remote.id, options.PreRelease, cache); break; case "http": metadata = HTTP(json, remote.id, cache, user); break; default: log.FatalFormat("Unknown remote source: {0}", remote.source); return(EXIT_ERROR); } if (metadata == null) { log.Error("There was an error, aborting"); return(EXIT_ERROR); } // Make sure that at the very least this validates against our own // internal model. CkanModule mod = CkanModule.FromJson(metadata.ToString()); // Make sure our identifiers match. if (mod.identifier != (string)json["identifier"]) { log.FatalFormat("Error: Have metadata for {0}, but wanted {1}", mod.identifier, json["identifier"]); return(EXIT_ERROR); } // Find our cached file, we'll need it later. string file = cache.GetCachedZip(mod.download); if (file == null) { log.FatalFormat("Error: Unable to find {0} in the cache", mod.identifier); return(EXIT_ERROR); } // Make sure this would actually generate an install try { ModuleInstaller.FindInstallableFiles(mod, file, null); } catch (BadMetadataKraken kraken) { log.FatalFormat("Error: Bad metadata for {0}: {1}", kraken.module, kraken.Message); return(EXIT_ERROR); } // Now inflate our original metadata from AVC, if we have it. // The reason we inflate our metadata and not the module is that in the module we can't // tell if there's been an override of the version fields or not. foreach (string vref in vrefs(metadata)) { log.DebugFormat("Expanding vref {0}", vref); if (vref.StartsWith("#/ckan/ksp-avc")) { // HTTP has already included the KSP-AVC data as it needs it earlier in the process if (remote.source != "http") { var versionRemote = FindVersionRemote(metadata, vref); try { AVC avc = AVC.FromZipFile(mod, file, versionRemote.id); // TODO check why the AVC file can be null... if (avc != null) { avc.InflateMetadata(metadata, null, null); } } catch (JsonReaderException) { user.RaiseMessage("Bad embedded KSP-AVC file for {0}, halting.", mod); return(EXIT_ERROR); } } } if (vref.StartsWith("#/ckan/kerbalstuff")) { log.DebugFormat("Kerbalstuff vref: {0}", vref); Match match = Regex.Match(vref, @"^#/ckan/([^/]+)/(.+)"); if (!match.Success) { // TODO: Have a proper kraken class! user.RaiseMessage("Cannot find remote and ID in vref: {0}, halting.", vref); return(EXIT_ERROR); } string remote_id = match.Groups [2].ToString(); log.DebugFormat("Kerbalstuff id : {0}", remote_id); try { KSMod ks = KSAPI.Mod(Convert.ToInt32(remote_id)); if (ks != null) { KSVersion version = new KSVersion(); version.friendly_version = mod.version; ks.InflateMetadata(metadata, file, version); } } catch (JsonReaderException) { user.RaiseMessage("Cannot find remote and ID in vref: {0}, halting.", vref); return(EXIT_ERROR); } } } // Fix our version string, if required. metadata = FixVersionStrings(metadata); // Re-inflate our mod, in case our vref or FixVersionString routines have // altered it at all. mod = CkanModule.FromJson(metadata.ToString()); // All done! Write it out! var version_filename = mod.version.ToString().Replace(':', '-'); string final_path = Path.Combine(options.OutputDir, string.Format("{0}-{1}.ckan", mod.identifier, version_filename)); log.InfoFormat("Writing final metadata to {0}", final_path); StringBuilder sb = new StringBuilder(); StringWriter sw = new StringWriter(sb); using (JsonTextWriter writer = new JsonTextWriter(sw)) { writer.Formatting = Formatting.Indented; writer.Indentation = 4; writer.IndentChar = ' '; JsonSerializer serializer = new JsonSerializer(); serializer.Serialize(writer, metadata); } File.WriteAllText(final_path, sw + Environment.NewLine); return(EXIT_OK); }
// GH #214: Make sure we pick up the right version public void KS_Version_Select_214() { CKAN.NetKAN.KSMod mod = KSAPI.Mod(TestData.KS_CustomAsteroids_string()); Assert.AreEqual(711, mod.Latest().id, "GH #214 - Select default_version_id"); }