WikiCrawler/MediaWiki/Api.cs
/// <summary>
/// Uploads media from the local computer.
/// </summary>
/// <returns>Success</returns>
Uploads media from the local computer.
Uploads media from the local computer .
public bool UploadFromLocal(Article newpage, string path, string summary, bool bot = true)
        {
			if (!newpage.title.StartsWith("File:"))
			{
				newpage.title = "File:" + newpage.title;
			}
            Dictionary<string, string> data = new Dictionary<string, string>();
            data["format"] = "json";
            data["action"] = "upload";
            data["filename"] = newpage.title;
            data["token"] = GetCsrfToken();
            data["ignorewarnings"] = "1";
			data["summary"] = summary;
			data["comment"] = summary;
			if (bot) data["bot"] = "1";
            if (newpage.revisions != null && newpage.revisions.Length > 0)
            {
                data["text"] = newpage.revisions[0].text;
            }
            string filetype = MimeUtility.GetMimeFromExtension(Path.GetExtension(path));
			byte[] rawfile;
			using (BinaryReader reader = new BinaryReader(new FileStream(path, FileMode.Open)))
			{
				rawfile = reader.ReadBytes((int)reader.BaseStream.Length);
			}
			object[] dupes = GetDuplicateFiles(rawfile);
			if (dupes != null && dupes.Length > 0)
			{
				throw new DuplicateFileException(newpage.title, dupes);
			}
			string finalResponseJson;
			if (rawfile.Length > 104857600)
			{
				Console.WriteLine("Using chunked upload.");
				int chunkSize = 1024 * 1024;
				int fileOffset = 0;
				data["filesize"] = rawfile.Length.ToString();
				data["stash"] = "1";
				do
				{
					int thisChunkSize = Math.Min(chunkSize, rawfile.Length - fileOffset);
					data["offset"] = fileOffset.ToString();
					HttpWebRequest request = CreateApiRequest();
					Console.Write("0%");
					using (StreamReader read = new StreamReader(EasyWeb.Upload(request, data, newpage.title, filetype, "chunk",
						rawfile, fileOffset, thisChunkSize)))
					{
						string responseJson = read.ReadToEnd();
						Dictionary<string, object> response = (Dictionary<string, object>)new JavaScriptSerializer().DeserializeObject(responseJson);
						Dictionary<string, object> upload = (Dictionary<string, object>)response["upload"];
						string responseResult = (string)upload["result"];
						if (responseResult == "Success")
						{
							Console.WriteLine("\r100%");
							data["filekey"] = (string)upload["filekey"];
							break;
						}
						else if (responseResult == "Continue")
						{
							fileOffset = (int)upload["offset"];
							data["filekey"] = (string)upload["filekey"];
						}
						else
						{
							throw new WikimediaException("Chunked upload result was '" + responseResult + "'");
						}
						Console.Write("\r" + ((int)(100f * fileOffset / (float)rawfile.Length)).ToString() + "%");
					}
				}
				while (fileOffset < rawfile.Length);
				{
					data.Remove("filesize");
					data.Remove("stash");
					data.Remove("offset");
					HttpWebRequest request = CreateApiRequest();
					using (StreamReader read = new StreamReader(EasyWeb.Post(request, data)))
					{
						finalResponseJson = read.ReadToEnd();
					}
				}
			}
			else
			{
				bool retry;
				do
				{
					retry = false;
					try
					{
						HttpWebRequest request = CreateApiRequest();
						using (StreamReader read = new StreamReader(EasyWeb.Upload(request, data, newpage.title, filetype, "file", rawfile)))
						{
							finalResponseJson = read.ReadToEnd();
						}
					}
					catch (WebException e)
					{
						if (e.Status == WebExceptionStatus.ProtocolError
							&& ((HttpWebResponse)e.Response).StatusCode == HttpStatusCode.ServiceUnavailable)
						{
							System.Threading.Thread.Sleep(60000);
							retry = true;
							finalResponseJson = null; 
						}
						else
						{
							throw e;
						}
					}
				} while (retry);
			}
            Dictionary<string, object> finalResponse = (Dictionary<string, object>)new JavaScriptSerializer().DeserializeObject(finalResponseJson);
            if (finalResponse.ContainsKey("error"))
            {
				Dictionary<string, object> error = (Dictionary<string, object>)finalResponse["error"];
				if ((string)error["code"] == "verification-error")
				{
					object[] details = (object[])error["details"];
					if ((string)details[0] == "filetype-mime-mismatch")
					{
						string mime = (string)details[2];
						string actualExt = MimeUtility.GetExtensionFromMime(mime);
						newpage.title = Path.ChangeExtension(newpage.title, actualExt);
						return UploadFromLocal(newpage, path, summary, bot);
					}
				}
				throw new WikimediaException(error["code"] + ": " + error["info"]);
			}
            return true;
        }
public bool UploadFromLocal ( Article newpage , string path , string summary , bool bot = true ) { if ( ! newpage . title . StartsWith ( " " ) ) { newpage . title = " " + newpage . title ; } Dictionary < string , string > data = new Dictionary < string , string > ( ) ; data [ " " ] = " " ; data [ " " ] = " " ; data [ " " ] = newpage . title ; data [ " " ] = GetCsrfToken ( ) ; data [ " " ] = " " ; data [ " " ] = summary ; data [ " " ] = summary ; if ( bot ) data [ " " ] = " " ; if ( newpage . revisions != null && newpage . revisions . Length > 0 ) { data [ " " ] = newpage . revisions [ 0 ] . text ; } string filetype = MimeUtility . GetMimeFromExtension ( Path . GetExtension ( path ) ) ; byte [ ] rawfile ; using ( BinaryReader reader = new BinaryReader ( new FileStream ( path , FileMode . Open ) ) ) { rawfile = reader . ReadBytes ( ( int ) reader . BaseStream . Length ) ; } object [ ] dupes = GetDuplicateFiles ( rawfile ) ; if ( dupes != null && dupes . Length > 0 ) { throw new DuplicateFileException ( newpage . title , dupes ) ; } string finalResponseJson ; if ( rawfile . Length > 104857600 ) { Console . WriteLine ( " " ) ; int chunkSize = 1024 * 1024 ; int fileOffset = 0 ; data [ " " ] = rawfile . Length . ToString ( ) ; data [ " " ] = " " ; do { int thisChunkSize = Math . Min ( chunkSize , rawfile . Length - fileOffset ) ; data [ " " ] = fileOffset . ToString ( ) ; HttpWebRequest request = CreateApiRequest ( ) ; Console . Write ( " " ) ; using ( StreamReader read = new StreamReader ( EasyWeb . Upload ( request , data , newpage . title , filetype , " " , rawfile , fileOffset , thisChunkSize ) ) ) { string responseJson = read . ReadToEnd ( ) ; Dictionary < string , object > response = ( Dictionary < string , object > ) new JavaScriptSerializer ( ) . DeserializeObject ( responseJson ) ; Dictionary < string , object > upload = ( Dictionary < string , object > ) response [ " " ] ; string responseResult = ( string ) upload [ " " ] ; if ( responseResult == " " ) { Console . WriteLine ( " \r " ) ; data [ " " ] = ( string ) upload [ " " ] ; break ; } else if ( responseResult == " " ) { fileOffset = ( int ) upload [ " " ] ; data [ " " ] = ( string ) upload [ " " ] ; } else { throw new WikimediaException ( " " + responseResult + " " ) ; } Console . Write ( " \r " + ( ( int ) ( 100f * fileOffset / ( float ) rawfile . Length ) ) . ToString ( ) + " " ) ; } } while ( fileOffset < rawfile . Length ) ; { data . Remove ( " " ) ; data . Remove ( " " ) ; data . Remove ( " " ) ; HttpWebRequest request = CreateApiRequest ( ) ; using ( StreamReader read = new StreamReader ( EasyWeb . Post ( request , data ) ) ) { finalResponseJson = read . ReadToEnd ( ) ; } } } else { bool retry ; do { retry = false ; try { HttpWebRequest request = CreateApiRequest ( ) ; using ( StreamReader read = new StreamReader ( EasyWeb . Upload ( request , data , newpage . title , filetype , " " , rawfile ) ) ) { finalResponseJson = read . ReadToEnd ( ) ; } } catch ( WebException e ) { if ( e . Status == WebExceptionStatus . ProtocolError && ( ( HttpWebResponse ) e . Response ) . StatusCode == HttpStatusCode . ServiceUnavailable ) { System . Threading . Thread . Sleep ( 60000 ) ; retry = true ; finalResponseJson = null ; } else { throw e ; } } } while ( retry ) ; } Dictionary < string , object > finalResponse = ( Dictionary < string , object > ) new JavaScriptSerializer ( ) . DeserializeObject ( finalResponseJson ) ; if ( finalResponse . ContainsKey ( " " ) ) { Dictionary < string , object > error = ( Dictionary < string , object > ) finalResponse [ " " ] ; if ( ( string ) error [ " " ] == " " ) { object [ ] details = ( object [ ] ) error [ " " ] ; if ( ( string ) details [ 0 ] == " " ) { string mime = ( string ) details [ 2 ] ; string actualExt = MimeUtility . GetExtensionFromMime ( mime ) ; newpage . title = Path . ChangeExtension ( newpage . title , actualExt ) ; return UploadFromLocal ( newpage , path , summary , bot ) ; } } throw new WikimediaException ( error [ " " ] + " " + error [ " " ] ) ; } return true ; }
Uploads media from the local computer.
Uploads media from the local computer .
//Download stream //TODO: test me //TODO: error handling // do filenames need to be unique? // commit completed upload // single-part upload //Read response //HACK: suppress unassigned warning // attempt to automatically fix extension/mime mismatch
None
newpage
Article
path
string
summary
string
bot
bool