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.