/// <summary>deletes an Atom entry object</summary> /// <param name="entry">The entry to be deleted </param> /// <param name="permanentDelete">Should the entry be archived or not</param> public void Delete(AtomEntry entry, bool permanentDelete) { Tracing.Assert(entry != null, "entry should not be null"); string eTag = null; if (entry == null) { throw new ArgumentNullException("entry"); } if (entry.ReadOnly) { throw new GDataRequestException("Can not update a read-only entry"); } Tracing.Assert(entry.EditUri != null, "Entry should have a valid edit URI"); ISupportsEtag eSource = entry as ISupportsEtag; if (eSource != null) { eTag = eSource.Etag; } if (entry.EditUri != null) { var uriString = entry.EditUri.Content + (permanentDelete ? "?delete=true" : string.Empty); Delete(new Uri(uriString), eTag); } else { throw new GDataRequestException("Invalid Entry object (no edit uri) to call Delete on"); } }
/// <summary> /// retrieves the resumable URI for the rest of the operation. This will initiate the /// communication with resumable upload server by posting against the starting URI /// </summary> /// <param name="resumableUploadUri"></param> /// <param name="authentication"></param> /// <param name="entry"></param> /// <returns>The uri to be used for the rest of the operation</returns> public Uri InitiateUpload(Uri resumableUploadUri, Authenticator authentication, AbstractEntry entry) { HttpWebRequest request = PrepareRequest(resumableUploadUri, authentication, entry.MediaSource.Name, entry.MediaSource.ContentType, entry.MediaSource.ContentLength); IVersionAware v = entry as IVersionAware; if (v != null) { // need to add the version header to the request request.Headers.Add(GDataGAuthRequestFactory.GDataVersion, v.ProtocolMajor.ToString() + "." + v.ProtocolMinor.ToString()); } ISupportsEtag e = entry as ISupportsEtag; if (e != null && Utilities.IsWeakETag(e) == false) { request.Headers.Add(GDataRequestFactory.IfMatch, e.Etag); } Stream outputStream = request.GetRequestStream(); entry.SaveToXml(outputStream); outputStream.Close(); /// this is the contenttype for the xml post request.ContentType = GDataRequestFactory.DefaultContentType; WebResponse response = request.GetResponse(); return(new Uri(response.Headers["Location"])); }
///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// /// <summary>protected virtual int SaveXmlAttributes(XmlWriter writer)</summary> /// <param name="writer">the XmlWriter to save to</param> ////////////////////////////////////////////////////////////////////// protected virtual void SaveXmlAttributes(XmlWriter writer) { //Tracing.Assert(writer != null, "writer should not be null"); if (writer == null) { throw new ArgumentNullException("writer"); } // this will save the base and language attributes, if we have them if (Utilities.IsPersistable(this.uriBase)) { //Lookup the prefix and then write the ISBN attribute. writer.WriteAttributeString("xml", "base", BaseNameTable.NSXml, this.Base.ToString()); } if (Utilities.IsPersistable(this.atomLanguageTag)) { writer.WriteAttributeString("xml", "lang", BaseNameTable.NSXml, this.Language); } ISupportsEtag se = this as ISupportsEtag; if (se != null && se.Etag != null) { writer.WriteAttributeString(BaseNameTable.gDataPrefix, BaseNameTable.XmlEtagAttribute, BaseNameTable.gNamespace, se.Etag); } // first go over all attributes foreach (IExtensionElementFactory ele in this.ExtensionElements) { XmlExtension x = ele as XmlExtension; // what we need to do here is: // go over all the attributes. look at all attributes that are namespace related // if the attribute is another default atomnamespace declaration, change it to some rnd prefix if (x != null) { if (x.Node.NodeType == XmlNodeType.Attribute) { ele.Save(writer); } } } AddOtherNamespaces(writer); // now just the non attributes foreach (IExtensionElementFactory ele in this.ExtensionElements) { XmlExtension x = ele as XmlExtension; if (x != null) { if (x.Node.NodeType == XmlNodeType.Attribute) { // skip the guy continue; } } ele.Save(writer); } }
/// <summary> /// returns a refreshed version of the entry you passed in, by going back to the server and /// requesting this resource again /// </summary> /// <example> /// The following code illustrates a possible use of /// the <c>Get</c> method: /// <code> /// YouTubeRequestSettings settings = new YouTubeRequestSettings("yourApp", "yourClient", "yourKey", "username", "pwd"); /// YouTubeRequest f = new YouTubeRequest(settings); /// Feed<Playlist> feed = f.GetPlaylistsFeed(null); /// Feed<Playlist> next = f.Get<Playlist>(feed, FeedRequestType.Next); /// </code> /// </example> /// <param name="entry">the entry to get again</param> /// <returns></returns> public Y Retrieve <Y>(Y entry) where Y : Entry, new() { if (entry == null) { throw new ArgumentNullException("entry was null"); } if (entry.AtomEntry == null) { throw new ArgumentNullException("entry.AtomEntry was null"); } string spec = entry.AtomEntry.SelfUri.ToString(); if (!String.IsNullOrEmpty(spec)) { FeedQuery q = new FeedQuery(spec); ISupportsEtag ise = entry.AtomEntry as ISupportsEtag; if (ise != null && ise.Etag != null) { q.Etag = ise.Etag; } return(Retrieve <Y>(q)); } return(null); }
/// <summary> /// tests an etag for weakness. returns TRUE for weak etags and for null strings /// </summary> /// <param name="ise">the element that supports an etag</param> /// <returns></returns> public static bool IsWeakETag(ISupportsEtag ise) { string eTag = null; if (ise != null) { eTag = ise.Etag; } return(IsWeakETag(eTag)); }
/// <summary> /// default constructor based on a gdatarequest object /// </summary> /// <param name="r"></param> public GDataReturnStream(IGDataRequest r) { this.innerStream = r.GetResponseStream(); ISupportsEtag ise = r as ISupportsEtag; if (ise != null) { this.etag = ise.Etag; } }
/// <summary>Parses the base attributes and puts the rest in extensions. /// This needs to happen AFTER known attributes are parsed.</summary> /// <param name="reader">correctly positioned xmlreader</param> /// <param name="baseObject">the base object to set the property on</param> /// <returns> true if an unknown attribute was found</returns> protected bool ParseBaseAttributes(XmlReader reader, AtomBase baseObject) { Tracing.Assert(reader != null, "reader should not be null"); if (reader == null) { throw new ArgumentNullException("reader"); } Tracing.Assert(baseObject != null, "baseObject should not be null"); if (baseObject == null) { throw new ArgumentNullException("baseObject"); } bool fRet = false; fRet = true; object localName = reader.LocalName; Tracing.TraceCall(); if (IsCurrentNameSpace(reader, BaseNameTable.NSXml)) { if (localName.Equals(_nameTable.Base)) { baseObject.Base = new AtomUri(reader.Value); fRet = false; } else if (localName.Equals(_nameTable.Language)) { baseObject.Language = Utilities.DecodedValue(reader.Value); fRet = false; } } else if (IsCurrentNameSpace(reader, BaseNameTable.gNamespace)) { ISupportsEtag se = baseObject as ISupportsEtag; if (se != null) { if (localName.Equals(_nameTable.ETag)) { se.Etag = reader.Value; fRet = false; } } } if (fRet == true) { Tracing.TraceInfo("Found an unknown attribute"); OnNewExtensionElement(reader, baseObject); } return(fRet); }
/// <summary>the basic interface. Take a URI and just get it</summary> /// <param name="queryUri">the URI to execute</param> /// <param name="ifModifiedSince">used to set a precondition date that /// indicates the feed should be returned only if it has been modified /// after the specified date. A value of DateTime.MinValue indicates no /// precondition.</param> /// <param name="etag">used to set a precondition etag that /// indicates the feed should be returned only if it has been modified </param> /// <param name="contentLength">returns the content length of the response</param> /// <returns> a webresponse object</returns> private Stream Query(Uri queryUri, DateTime ifModifiedSince, string etag, out long contentLength) { Tracing.TraceCall("Enter"); if (queryUri == null) { throw new System.ArgumentNullException("queryUri"); } contentLength = -1; IGDataRequest request = this.RequestFactory.CreateRequest(GDataRequestType.Query, queryUri); request.Credentials = this.Credentials; request.IfModifiedSince = ifModifiedSince; if (etag != null) { ISupportsEtag ise = request as ISupportsEtag; if (ise != null) { ise.Etag = etag; } } try { request.Execute(); } catch (Exception) { // Prevent connection leaks if (request.GetResponseStream() != null) { request.GetResponseStream().Close(); } throw; } // return the response GDataGAuthRequest gr = request as GDataGAuthRequest; if (gr != null) { contentLength = gr.ContentLength; } Tracing.TraceCall("Exit"); return(new GDataReturnStream(request)); }
/// <summary>Inserts an AtomBase entry against a Uri</summary> /// <param name="feedUri">the uri for the feed this object should be posted against</param> /// <param name="baseEntry">the entry to be inserted</param> /// <param name="type">the type of request to create</param> /// <param name="data">the async data payload</param> /// <returns> the response as a stream</returns> internal virtual Stream EntrySend(Uri feedUri, AtomBase baseEntry, GDataRequestType type, AsyncSendData data) { Tracing.Assert(feedUri != null, "feedUri should not be null"); if (feedUri == null) { throw new ArgumentNullException("feedUri"); } Tracing.Assert(baseEntry != null, "baseEntry should not be null"); if (baseEntry == null) { throw new ArgumentNullException("baseEntry"); } this.versionInfo.ImprintVersion(baseEntry); IGDataRequest request = this.RequestFactory.CreateRequest(type, feedUri); request.Credentials = this.Credentials; ISupportsEtag eTarget = request as ISupportsEtag; ISupportsEtag eSource = baseEntry as ISupportsEtag; if (eTarget != null && eSource != null) { eTarget.Etag = eSource.Etag; } request.ContentStore = baseEntry; request.IsBatch = type == GDataRequestType.Batch; if (data != null) { GDataGAuthRequest gr = request as GDataGAuthRequest; if (gr != null) { gr.AsyncData = data; } } Stream outputStream = request.GetRequestStream(); baseEntry.SaveToXml(outputStream); request.Execute(); outputStream.Close(); return(request.GetResponseStream()); }
/// <summary> /// returns a new feed based on the operation passed in. This is useful if you either do not use /// autopaging, or want to move to previous parts of the feed, or get a refresh of the current feed /// </summary> /// <example> /// The following code illustrates a possible use of /// the <c>Get</c> method: /// <code> /// YouTubeRequestSettings settings = new YouTubeRequestSettings("yourApp", "yourClient", "yourKey", "username", "pwd"); /// YouTubeRequest f = new YouTubeRequest(settings); /// Feed<Playlist> feed = f.GetPlaylistsFeed(null); /// Feed<Playlist> next = f.Get<Playlist>(feed, FeedRequestType.Next); /// </code> /// </example> /// <param name="feed">the original feed</param> /// <param name="operation">an requesttype to indicate what to retrieve</param> /// <returns></returns> public Feed <Y> Get <Y>(Feed <Y> feed, FeedRequestType operation) where Y : Entry, new() { Feed <Y> f = null; string spec = null; if (feed == null) { throw new ArgumentNullException("feed was null"); } if (feed.AtomFeed == null) { throw new ArgumentNullException("feed.AtomFeed was null"); } switch (operation) { case FeedRequestType.Next: spec = feed.AtomFeed.NextChunk; break; case FeedRequestType.Prev: spec = feed.AtomFeed.PrevChunk; break; case FeedRequestType.Refresh: spec = feed.AtomFeed.Self; break; } if (!String.IsNullOrEmpty(spec)) { FeedQuery q = new FeedQuery(spec); if (operation == FeedRequestType.Refresh) { ISupportsEtag ise = feed.AtomFeed as ISupportsEtag; if (ise != null && ise.Etag != null) { q.Etag = ise.Etag; } } f = PrepareFeed <Y>(q); } return(f); }
///<summary>Deletes an Atom entry when given a Uri</summary> ///<param name="uriTarget">The target Uri to call http delete against</param> ///<param name="eTag">The eTag of the item to delete. This parameter is used for strong /// concurrency support in protocol version 2 and up</param> public void Delete(Uri uriTarget, string eTag) { Tracing.Assert(uriTarget != null, "uri should not be null"); if (uriTarget == null) { throw new ArgumentNullException("uriTarget"); } Tracing.TraceMsg("Deleting entry: " + uriTarget.ToString()); IGDataRequest request = RequestFactory.CreateRequest(GDataRequestType.Delete, uriTarget); ISupportsEtag eTarget = request as ISupportsEtag; if (eTarget != null && eTag != null) { eTarget.Etag = eTag; } request.Credentials = Credentials; request.Execute(); IDisposable disp = request as IDisposable; disp.Dispose(); }
/// <summary> /// this is a helper function for to send binary data to a resource /// it is not worth running the other insert/saves through here, as this would involve /// double buffering/copying of the bytes /// </summary> /// <param name="targetUri"></param> /// <param name="inputStream"></param> /// <param name="type"></param> /// <param name="contentType">the contenttype to use in the request, if NULL is passed, factory default is used</param> /// <param name="slugHeader">the slugHeader to use in the request, if NULL is passed, factory default is used</param> /// <param name="etag">The http etag to pass into the request</param> /// <param name="data">The async data needed for notifications</param> /// <returns>Stream from the server response. You should close this stream explicitly.</returns> private Stream StreamSend(Uri targetUri, Stream inputStream, GDataRequestType type, string contentType, string slugHeader, string etag, AsyncSendData data) { Tracing.Assert(targetUri != null, "targetUri should not be null"); if (targetUri == null) { throw new ArgumentNullException("targetUri"); } if (inputStream == null) { Tracing.Assert(inputStream != null, "payload should not be null"); throw new ArgumentNullException("inputStream"); } if (type != GDataRequestType.Insert && type != GDataRequestType.Update) { Tracing.Assert(type != GDataRequestType.Insert && type != GDataRequestType.Update, "type needs to be insert or update"); throw new ArgumentNullException("type"); } IGDataRequest request = this.RequestFactory.CreateRequest(type, targetUri); request.Credentials = this.Credentials; if (data != null) { GDataGAuthRequest gr = request as GDataGAuthRequest; if (gr != null) { gr.AsyncData = data; } } // set the contenttype of the request if (contentType != null) { GDataRequest r = request as GDataRequest; if (r != null) { r.ContentType = contentType; } } if (slugHeader != null) { GDataRequest r = request as GDataRequest; if (r != null) { r.Slug = slugHeader; } } if (etag != null) { ISupportsEtag ise = request as ISupportsEtag; if (ise != null) { ise.Etag = etag; } } Stream outputStream = request.GetRequestStream(); WriteInputStreamToRequest(inputStream, outputStream); request.Execute(); outputStream.Close(); return(new GDataReturnStream(request)); }