Hi,

I'm not sure what the problem may be since I am using OAuth 2 and
sending the photo with metadata as multipart post. Anyway, I'm
attaching this *functioning-but-not-thoroughly-tested* code. Hope it
helps.

Eduardo Flores

        public static bool UploadPhoto(string filename, string
albumid="default")
        {
            if (albumid==null || albumid=="") albumid = "default";
            var binaryBytes = File.ReadAllBytes(filename);

            var atom = string.Format(
@"<entry xmlns='http://www.w3.org/2005/Atom'>
  <title>{0}</title>
  <summary></summary>
  <category scheme='http://schemas.google.com/g/2005#kind'
    term='http://schemas.google.com/photos/2007#photo'/>
</entry>",
         Path.GetFileName(filename));

            var dataBytes =
Encoding.Default.GetBytes(string.Format("Media multipart posting\n--
END_OF_PART\nContent-Type: application/atom+xml\n\n{0}\n--END_OF_PART
\nContent-Type: image/jpeg\n\n", atom));
            var trailBytes = Encoding.Default.GetBytes("\n--
END_OF_PART--");
            var totalBytes = dataBytes.Length + binaryBytes.Length +
trailBytes.Length;

            byte[] data = new byte[totalBytes];
            int i = 0, j = 0;
            for (; i < dataBytes.Length; i++)
                data[i] = dataBytes[i];
            for (; j < binaryBytes.Length; j++)
                data[i + j] = binaryBytes[j];
            for (int k = 0; k < trailBytes.Length; k++)
                data[i + j + k] = trailBytes[k];

            var resp = Request(
                "https://picasaweb.google.com/data/feed/api/user/
default/albumid/"+albumid+"/",
                data,
                contentType:"multipart/related; boundary=\"END_OF_PART
\""
            );

            return resp!=null;
        }


        private static Tuple<HttpStatusCode?, string> Request(string
url, byte[] data=null, string contentType="application/atom+xml",
Action<HttpWebRequest> OnPrepareRequest=null)
        {
            if (GetAccessToken==null || RefreshToken==null) throw new
ArgumentNullException("Function GetAccessToken.");
            //if (_user == null) throw new ArgumentNullException("User
not defined.");

            HttpWebRequest req = null;
            HttpWebResponse resp = null;
            Tuple<HttpStatusCode?, string> ret = null;

            Func<Stream,string> GetFullResponse = (stream) =>
            {
                var buffer = new byte[BUFFER_SIZE];
                var sb = new StringBuilder();
                int count;
                while ((count = stream.Read(buffer, 0, BUFFER_SIZE)) >
0)
                {
                    var chars=Encoding.UTF8.GetChars(buffer,0,count);
                    sb.Append(chars);
                }

                return sb.ToString();
            };

            var keepTrying = true;
            var retries = 0;
            while (keepTrying && retries < REQUEST_RETRIES)
            {
                try
                {
                    if (retries++ > 1)
Helper.LogMessage(string.Format("Reintentando {0}", retries));
                    req = (HttpWebRequest)WebRequest.Create(url);
                    req.Headers.Add("Authorization",
string.Format("OAuth {0}", GetAccessToken()));
                    req.Headers.Add("GData-Version", "2");
                    req.ContentType = contentType;
                    //Según
http://social.msdn.microsoft.com/forums/en-US/netfxnetcom/thread/faf9737d-5cb3-442b-bf9d-26341a204475/
                    //req.KeepAlive = false;  //Segun yo no funciono
                    req.Timeout = 30 * 60 * 1000; //30 minutos - y
esto sí funcionó
                    if (OnPrepareRequest != null)
                        OnPrepareRequest(req);
                    if (data != null)
                    {
                        req.Method = "POST";
                        req.ContentLength = data.Length;

                        //Según el mismo pero mas adelante
                        //req.SendChunked = true;

                        var stream = req.GetRequestStream();
                        int i = 0;
                        while (i < data.Length)
                        {
                            stream.Write(data, i, (data.Length - i) >
1024 ? 1024 : (data.Length - i));
                            i += 1024;
                            //Hace throttling para no abusar del ancho
de banda
                            // el Time es en milisegundos entre cada
write
                            if
(Properties.Settings.Default.ThrottleEnabled)
 
Thread.Sleep(Properties.Settings.Default.ThrottleTime);
                            //Thread.Sleep(25); //chk:throttle
                        }

                        stream.Close();
                    }

                    using (resp = (HttpWebResponse)req.GetResponse())
                    {
                        ret = new Tuple<HttpStatusCode?,
string>(resp.StatusCode, GetFullResponse(resp.GetResponseStream()));
                    }
                    keepTrying = false;
                }
                catch (WebException wex)
                {
                    string body="";

                    //Hay que ver en que otros casos se hace el Retry
                    if (wex.Response != null &&
((HttpWebResponse)wex.Response).StatusCode ==
HttpStatusCode.Forbidden)
                    {
                        Helper.LogMessage("Refreshing Token");
                        keepTrying = true;
                        RefreshToken();
                    }
                    else
                    {
                        //Nada mas mientras hacemos pruebas,
                        keepTrying = false;
                        if (wex.Response != null)
body=GetFullResponse(((HttpWebResponse)wex.Response).GetResponseStream());

                        //chk: Revisar donde se cacharia esta
excepcion, para reencolar tareas pero que no afecte a otros tipos de
request
                        //throw new PicasaWebException(wex.Message + "
status:" + wex.Status + " body:" + body, wex);
                        Helper.LogException(new
ApplicationException(wex.Message + " status:" + wex.Status + " body:"
+ body, wex));
                        ret = null;
                    }
                }
            }

            return ret;
        }

-- 
You received this message because you are subscribed to the Google Groups 
"Google Picasa Web Albums API" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-picasa-data-api?hl=en.

Reply via email to