/// <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; }
private void DeSerialisationFixes(StreamingContext like_i_could_care) { // Turn our download path into a fully qualified URL. download_path = KSAPI.ExpandPath(download_path).ToString(); log.DebugFormat("Download path is {0}", download_path); }
public override object ReadJson( JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer ) { return(KSAPI.ExpandPath(reader.Value.ToString())); }
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); }
/// <summary> /// Returns the path to the mod's home on KerbalStuff /// </summary> /// <returns>The home.</returns> internal Uri KSHome() { return(KSAPI.ExpandPath(String.Format("/mod/{0}/{1}", id, name))); }
internal string KSHome() { Uri path = KSAPI.ExpandPath(String.Format("/mod/{0}/{1}", id, name)); return(Uri.EscapeUriString(path.ToString())); }