/// <summary> /// Get the request token using the consumer key and secret. Also initializes tokensecret /// </summary> private void GetRequestToken() { IDictionary <string, object> parameters = new Dictionary <string, object>(); foreach (var value in _requestTokenParameters) { parameters.Add(value); } Sign(RequestTokenMethod, RequestTokenUrl, parameters); string response = MakeRequest(RequestTokenMethod, RequestTokenUrl, null, parameters, null); if (!string.IsNullOrEmpty(response)) { response = NetworkHelper.UrlDecode(response); LOG.DebugFormat("Request token response: {0}", response); _requestTokenResponseParameters = NetworkHelper.ParseQueryString(response); string value; if (_requestTokenResponseParameters.TryGetValue(OAUTH_TOKEN_KEY, out value)) { Token = value; TokenSecret = _requestTokenResponseParameters[OAUTH_TOKEN_SECRET_KEY]; } } }
/// <summary> /// Read the Greenshot RSS feed, so we can use this information to check for updates /// </summary> /// <returns>List with RssFile(s)</returns> public static IList <RssFile> ReadRss() { XmlDocument rssDoc = new XmlDocument(); try { HttpWebRequest webRequest = NetworkHelper.CreateWebRequest(Rssfeed); XmlTextReader rssReader = new XmlTextReader(webRequest.GetResponse().GetResponseStream()); // Load the XML content into a XmlDocument rssDoc.Load(rssReader); } catch (Exception wE) { Log.WarnFormat("Problem reading RSS from {0}", Rssfeed); Log.Warn(wE.Message); return(null); } // Loop for the <rss> tag XmlNode nodeRss = null; for (int i = 0; i < rssDoc.ChildNodes.Count; i++) { // If it is the rss tag if (rssDoc.ChildNodes[i].Name == "rss") { // <rss> tag found nodeRss = rssDoc.ChildNodes[i]; } } if (nodeRss == null) { Log.Debug("No RSS Feed!"); return(null); } // Loop for the <channel> tag XmlNode nodeChannel = null; for (int i = 0; i < nodeRss.ChildNodes.Count; i++) { // If it is the channel tag if (nodeRss.ChildNodes[i].Name == "channel") { // <channel> tag found nodeChannel = nodeRss.ChildNodes[i]; } } if (nodeChannel == null) { Log.Debug("No channel in RSS feed!"); return(null); } IList <RssFile> rssFiles = new List <RssFile>(); // Loop for the <title>, <link>, <description> and all the other tags for (int i = 0; i < nodeChannel.ChildNodes.Count; i++) { // If it is the item tag, then it has children tags which we will add as items to the ListView if (nodeChannel.ChildNodes[i].Name != "item") { continue; } XmlNode nodeItem = nodeChannel.ChildNodes[i]; string link = nodeItem["link"]?.InnerText; string pubdate = nodeItem["pubDate"]?.InnerText; try { if (link == null) { continue; } Match match = Regex.Match(Uri.UnescapeDataString(link), @"^.*\/(Greenshot.+)\/download$"); if (!match.Success) { continue; } string file = match.Groups[1].Value; RssFile rssFile = new RssFile(file, pubdate, link); if (file.EndsWith(".exe") || file.EndsWith(".zip")) { string version = Regex.Replace(file, @".*[a-zA-Z_]\-", ""); version = version.Replace(@"\-[a-zA-Z]+.*", ""); version = Regex.Replace(version, @"\.exe$", ""); version = Regex.Replace(version, @"\.zip$", ""); version = Regex.Replace(version, @"RC[0-9]+", ""); if (version.Trim().Length > 0) { version = version.Replace('-', '.'); version = version.Replace(',', '.'); version = Regex.Replace(version, @"^[a-zA-Z_]*\.", ""); version = Regex.Replace(version, @"\.[a-zA-Z_]*$", ""); try { rssFile.Version = new Version(version); } catch (Exception) { Log.DebugFormat("Found invalid version {0} in file {1}", version, file); } } rssFiles.Add(rssFile); } } catch (Exception ex) { Log.WarnFormat("Couldn't read RSS entry for: {0}", nodeChannel["title"]?.InnerText); Log.Warn("Reason: ", ex); } } return(rssFiles); }
/// <summary> /// Read the Greenshot RSS feed, so we can use this information to check for updates /// </summary> /// <returns>Dictionary<string, Dictionary<string, RssFile>> with files and their RssFile "description"</returns> public static Dictionary <string, Dictionary <string, SourceforgeFile> > readRSS() { XmlDocument rssDoc = new XmlDocument(); try { HttpWebRequest webRequest = NetworkHelper.CreateWebRequest(RSSFEED); XmlTextReader rssReader = new XmlTextReader(webRequest.GetResponse().GetResponseStream()); // Load the XML content into a XmlDocument rssDoc.Load(rssReader); } catch (Exception wE) { LOG.WarnFormat("Problem reading RSS from {0}", RSSFEED); LOG.Warn(wE.Message); return(null); } // Loop for the <rss> tag XmlNode nodeRss = null; for (int i = 0; i < rssDoc.ChildNodes.Count; i++) { // If it is the rss tag if (rssDoc.ChildNodes[i].Name == "rss") { // <rss> tag found nodeRss = rssDoc.ChildNodes[i]; } } if (nodeRss == null) { LOG.Debug("No RSS Feed!"); return(null); } // Loop for the <channel> tag XmlNode nodeChannel = null; for (int i = 0; i < nodeRss.ChildNodes.Count; i++) { // If it is the channel tag if (nodeRss.ChildNodes[i].Name == "channel") { // <channel> tag found nodeChannel = nodeRss.ChildNodes[i]; } } if (nodeChannel == null) { LOG.Debug("No channel in RSS feed!"); return(null); } Dictionary <string, Dictionary <string, SourceforgeFile> > rssFiles = new Dictionary <string, Dictionary <string, SourceforgeFile> >(); // Loop for the <title>, <link>, <description> and all the other tags for (int i = 0; i < nodeChannel.ChildNodes.Count; i++) { // If it is the item tag, then it has children tags which we will add as items to the ListView if (nodeChannel.ChildNodes[i].Name == "item") { XmlNode nodeItem = nodeChannel.ChildNodes[i]; string sfLink = nodeItem["link"].InnerText; string pubdate = nodeItem["pubDate"].InnerText; try { Match match = Regex.Match(Uri.UnescapeDataString(sfLink), @"^http.*sourceforge.*\/projects\/([^\/]+)\/files\/([^\/]+)\/([^\/]+)\/(.+)\/download$"); if (match.Success) { string project = match.Groups[1].Value; string subdir = match.Groups[2].Value; string type = match.Groups[3].Value; string file = match.Groups[4].Value; // !!! Change this to the mirror !!! string mirror = "kent"; string directLink = Uri.EscapeUriString("http://" + mirror + ".dl.sourceforge.net/project/" + project + "/" + subdir + "/" + type + "/" + file); Dictionary <string, SourceforgeFile> filesForType; if (rssFiles.ContainsKey(type)) { filesForType = rssFiles[type]; } else { filesForType = new Dictionary <string, SourceforgeFile>(); rssFiles.Add(type, filesForType); } SourceforgeFile rssFile = new SourceforgeFile(file, pubdate, sfLink, directLink); if (file.EndsWith(".exe") || file.EndsWith(".zip")) { string version = Regex.Replace(file, @".*[a-zA-Z_]\-", ""); version = version.Replace(@"\-[a-zA-Z]+.*", ""); version = Regex.Replace(version, @"\.exe$", ""); version = Regex.Replace(version, @"\.zip$", ""); version = Regex.Replace(version, @"RC[0-9]+", ""); if (version.Trim().Length > 0) { version = version.Replace('-', '.'); version = version.Replace(',', '.'); version = Regex.Replace(version, @"^[a-zA-Z_]*\.", ""); version = Regex.Replace(version, @"\.[a-zA-Z_]*$", ""); try { rssFile.Version = new Version(version); } catch (Exception) { LOG.DebugFormat("Found invalid version {0} in file {1}", version, file); } } } else if (type.Equals("Translations")) { string culture = Regex.Replace(file, @"[a-zA-Z]+-(..-..)\.(xml|html)", "$1"); try { //CultureInfo cultureInfo = new CultureInfo(culture); rssFile.Language = culture; //cultureInfo.NativeName; } catch (Exception) { LOG.WarnFormat("Can't read the native name of the culture {0}", culture); } } filesForType.Add(file, rssFile); } } catch (Exception ex) { LOG.WarnFormat("Couldn't read RSS entry for: {0}", nodeChannel["title"].InnerText); LOG.Warn("Reason: ", ex); } } } return(rssFiles); }
/// <summary> /// This is using the HTTP HEAD Method to check if the RSS Feed is modified after the supplied date /// </summary> /// <param name="updateTime">DateTime</param> /// <returns>true if the feed is newer</returns> public static bool isRSSModifiedAfter(DateTime updateTime) { DateTime lastModified = NetworkHelper.GetLastModified(new Uri(RSSFEED)); return(updateTime.CompareTo(lastModified) < 0); }
/// <summary> /// Make the actual OAuth request, all oauth parameters are passed as header (default) and the others are placed in the url or post data. /// Any additional parameters added after the Sign call are not in the signature, this could be by design! /// </summary> /// <param name="method"></param> /// <param name="requestURL"></param> /// <param name="headers"></param> /// <param name="parameters"></param> /// <param name="postData">IBinaryParameter</param> /// <returns>Response from server</returns> private string MakeRequest(HTTPMethod method, string requestURL, IDictionary <string, string> headers, IDictionary <string, object> parameters, IBinaryContainer postData) { if (parameters == null) { throw new ArgumentNullException("parameters"); } IDictionary <string, object> requestParameters; // Add oAuth values as HTTP headers, if this is allowed StringBuilder authHeader = null; if (UseHTTPHeadersForAuthorization) { authHeader = new StringBuilder(); requestParameters = new Dictionary <string, object>(); foreach (string parameterKey in parameters.Keys) { if (parameterKey.StartsWith(OAUTH_PARAMETER_PREFIX)) { authHeader.AppendFormat(CultureInfo.InvariantCulture, "{0}=\"{1}\", ", parameterKey, UrlEncode3986(string.Format("{0}", parameters[parameterKey]))); } else if (!requestParameters.ContainsKey(parameterKey)) { requestParameters.Add(parameterKey, parameters[parameterKey]); } } // Remove trailing comma and space and add it to the headers if (authHeader.Length > 0) { authHeader.Remove(authHeader.Length - 2, 2); } } else { requestParameters = parameters; } if (HTTPMethod.GET == method || postData != null) { if (requestParameters.Count > 0) { // Add the parameters to the request requestURL += "?" + NetworkHelper.GenerateQueryParameters(requestParameters); } } // Create webrequest HttpWebRequest webRequest = NetworkHelper.CreateWebRequest(requestURL); webRequest.Method = method.ToString(); webRequest.ServicePoint.Expect100Continue = false; webRequest.UserAgent = _userAgent; webRequest.Timeout = 100000; if (UseHTTPHeadersForAuthorization && authHeader != null) { LOG.DebugFormat("Authorization: OAuth {0}", authHeader); webRequest.Headers.Add("Authorization: OAuth " + authHeader); } if (headers != null) { foreach (string key in headers.Keys) { webRequest.Headers.Add(key, headers[key]); } } if ((HTTPMethod.POST == method || HTTPMethod.PUT == method) && postData == null && requestParameters.Count > 0) { if (UseMultipartFormData) { NetworkHelper.WriteMultipartFormData(webRequest, requestParameters); } else { StringBuilder form = new StringBuilder(); foreach (string parameterKey in requestParameters.Keys) { if (parameters[parameterKey] is IBinaryContainer) { IBinaryContainer binaryParameter = parameters[parameterKey] as IBinaryContainer; form.AppendFormat(CultureInfo.InvariantCulture, "{0}={1}&", UrlEncode3986(parameterKey), UrlEncode3986(binaryParameter.ToBase64String(Base64FormattingOptions.None))); } else { form.AppendFormat(CultureInfo.InvariantCulture, "{0}={1}&", UrlEncode3986(parameterKey), UrlEncode3986(string.Format("{0}", parameters[parameterKey]))); } } // Remove trailing & if (form.Length > 0) { form.Remove(form.Length - 1, 1); } webRequest.ContentType = "application/x-www-form-urlencoded"; byte[] data = Encoding.UTF8.GetBytes(form.ToString()); using (var requestStream = webRequest.GetRequestStream()) { requestStream.Write(data, 0, data.Length); } } } else if (postData != null) { postData.Upload(webRequest); } else { webRequest.ContentLength = 0; } string responseData; try { responseData = NetworkHelper.GetResponse(webRequest); LOG.DebugFormat("Response: {0}", responseData); } catch (Exception ex) { LOG.Error("Couldn't retrieve response: ", ex); throw; } finally { webRequest = null; } return(responseData); }