﻿@Imports System.IO
@Imports System.Net
@Imports System.Xml
@Imports Microsoft.VisualBasic

@Functions

'	ASP.NET Web Pages VB sample code for Copyscape Premium API
'	
'	Compatible with ASP.NET Web Pages 2.0 or later (with Razor View Engine)
'	
'	You may install, use, reproduce, modify and redistribute this code, with or without
'	modifications, subject to the general Terms and Conditions on the Copyscape website. 
'	
'	For any technical assistance please contact us via our website.
'	
'	07-May-2013: First version
'	
'	Copyscape (c) Indigo Stream Technologies 2013 - http://www.copyscape.com/
'
'
'	Instructions for use:
'	
'   1. Set the constants COPYSCAPE_USERNAME and COPYSCAPE_API_KEY below to your details.
'   2. Call the appropriate API function, following the examples below.
'   3. The API response is in XML, which in this sample code is parsed and returned as an XMLElement.
'   4. To run the examples provided, please set run_examples in the next line to true:

    Public Const run_examples As Boolean = False

'	Error handling:
'	
'	* If a call failed completely (e.g. HttpWebRequest failed to connect), functions return Nothing.
'	* If the API returned an error, the response XmlElement will contain an 'error' node.


'	A. Constants you need to change

	Public Const COPYSCAPE_USERNAME As String = "your-copyscape-username"
	Public Const COPYSCAPE_API_KEY As String = "your-copyscape-api-key"

	Public Const COPYSCAPE_API_URL As String = "http://www.copyscape.com/api/"


'	B. Functions for you to use (all accounts)

    Public Shared Function copyscape_api_example_search() As XmlElement
        Dim urlparams As New Dictionary(Of String, String)
        urlparams.Add( "x", "1" )
        Return copyscape_api_call( "csearch", urlparams )
    End Function

	Public Shared Function copyscape_api_url_search_internet( url As String, Optional full as Integer = 0 ) As XmlElement
		Return copyscape_api_url_search( url, full, "csearch" )
	End Function

	Public Shared Function copyscape_api_text_search_internet( text As String, encoding As String, Optional full as Integer = 0 ) As XmlElement
		Return copyscape_api_text_search( text, encoding, full, "csearch" )
	End Function

	Public Shared Function copyscape_api_check_balance() As XmlElement
		Return copyscape_api_call( "balance" )
	End Function


'	C. Functions for you to use (only accounts with private index enabled)

	Public Shared Function copyscape_api_url_search_private( url As String, Optional full as Integer = 0 ) As XmlElement
		Return copyscape_api_url_search( url, full, "psearch" )
	End Function
	
	Public Shared Function copyscape_api_url_search_internet_and_private( url As String, Optional full as Integer = 0 ) As XmlElement
		Return copyscape_api_url_search( url, full, "cpsearch" )
	End Function

	Public Shared Function copyscape_api_text_search_private( text As String, encoding As String, Optional full as Integer = 0 ) As XmlElement
		Return copyscape_api_text_search( text, encoding, full, "psearch" )
	End Function

	Public Shared Function copyscape_api_text_search_internet_and_private( text As String, encoding As String, Optional full as Integer = 0 ) As XmlElement
		Return copyscape_api_text_search( text, encoding, full, "cpsearch" )
	End Function

	Public Shared Function copyscape_api_url_add_to_private( url As String, Optional id As String = Nothing ) As XmlElement
		Dim urlparams As New Dictionary(Of String, String)
		urlparams.Add( "q", url )

		If id IsNot Nothing
			urlparams.Add( "i", id )
        End If

		Return copyscape_api_call( "pindexadd", urlparams )
	End Function
	
	Public Shared Function copyscape_api_text_add_to_private( text As String, encoding As String, Optional title As String = Nothing, Optional id As String = Nothing ) As XmlElement
		Dim urlparams As New Dictionary(Of String, String)
		urlparams.Add( "e", encoding )
		
		If title IsNot Nothing
			urlparams.Add( "a", title )
        End If

		If id IsNot Nothing
			urlparams.Add( "i", id )
        End If
			
		Return copyscape_api_call( "pindexadd", urlparams, text )
	End Function
	
	Public Shared Function copyscape_api_delete_from_private( handle As String ) As XmlElement
		Dim urlparams As New Dictionary(Of String, String)
		urlparams.Add( "h", handle )
		
		Return copyscape_api_call( "pindexdel", urlparams)
	End Function

	Public Shared Function wrap_title( title As String ) As HtmlString
		Return New HtmlString("<big style='margin-left:5%'><b>"+HttpContext.Current.Server.HtmlEncode(title)+":</b></big>")
	End Function

	Public Shared Function wrap_node( node As XmlNode ) As HtmlString
		Return New HtmlString("<div style='overflow:auto; max-height:300px; margin-left:5%; width:90%'><pre>" & node_recurse(node) & "</pre></div><br>" )
	End Function

	Private Shared Function node_recurse( node As XmlNode, Optional depth As Integer = 0 ) As String
        Dim ret As String

		If node Is Nothing
			Return ret
        End If

		If node.NodeType = XmlNodeType.Text
			ret += HttpContext.Current.Server.HtmlEncode(node.Value)
		Else
            ret += VbCrLf & New String(VbTab,depth) & HttpContext.Current.Server.HtmlEncode(node.Name) & ": "
        End If

		If node.HasChildNodes
            For i As Integer = 0 To node.ChildNodes.Count
				ret += node_recurse( node.ChildNodes.Item(i), depth+1 )
            Next
		End If

		Return ret
	End Function


'	D. Functions used internally

	Private Shared Function copyscape_api_url_search( url As String, Optional full as Integer = 0, Optional operation As String = "csearch") As XmlElement
		Dim urlparams As New Dictionary(Of String, String)
		urlparams.Add( "q", url )

		If full <> 0
			urlparams.Add( "c", full.ToString() )
        End If

		Return copyscape_api_call( operation, urlparams )
	End Function
	
	Private Shared Function copyscape_api_text_search( text As String, encoding As String, Optional full as Integer = 0, Optional operation As String = "csearch" ) As XmlElement
		Dim urlparams As New Dictionary(Of String, String)
		urlparams.Add( "e", encoding )

		If full <> 0
			urlparams.Add( "c", full.ToString() )
        End If

		Return copyscape_api_call( operation, urlparams, text )
	End Function

	Private Shared Function copyscape_api_call( operation As String, Optional urlparams As Dictionary(Of String, String) = Nothing, Optional postdata As String = Nothing ) As XmlElement
		Dim url As String = COPYSCAPE_API_URL + "?u=" + HttpUtility.UrlEncode(COPYSCAPE_USERNAME) +
			"&k=" + HttpUtility.UrlEncode(COPYSCAPE_API_KEY) + "&o=" + HttpUtility.UrlEncode(operation)

		If urlparams IsNot Nothing
			For Each kvp As KeyValuePair(Of String, String) In urlparams
				url += ( "&" + HttpUtility.UrlEncode(kvp.Key) + "=" + HttpUtility.UrlEncode(kvp.Value) )
            Next
		End If

		Dim uri As New Uri(url)
		Dim output As New String(Nothing)

        Dim request As HttpWebRequest = DirectCast( HttpWebRequest.Create(uri), HttpWebRequest )

        If postdata Is Nothing
            request.Method = WebRequestMethods.Http.Get
        Else
			request.Method = WebRequestMethods.Http.Post
        End If
		request.ContentType = "application/x-www-form-urlencoded"

		If postdata IsNot Nothing
			Dim writer As New StreamWriter(request.GetRequestStream(), System.Text.Encoding.UTF8)
			writer.Write(postdata)
			writer.Close()
		End If

		Dim response As HttpWebResponse = DirectCast( request.GetResponse(), HttpWebResponse )
        Dim reader As New StreamReader(response.GetResponseStream())
		output = reader.ReadToEnd()
		response.Close()

		If output.Length > 0
			Dim doc As New XmlDocument()
			doc.LoadXml(output)
            Return doc.SelectSingleNode("/*")
		End If 
		
		Return Nothing
	End Function
    
End Functions

@Code

'   E. Some examples of use

	If run_examples = True
        Dim exampletext As String = "We hold these truths to be self-evident, that all men are created equal, that they are endowed by their "&
		"Creator with certain unalienable rights, that among these are Life, Liberty, and the pursuit of Happiness. That to "&
		"secure these rights, Governments are instituted among Men, deriving their just powers from the consent of the "&
		"governed. That whenever any Form of Government becomes destructive of these ends, it is the Right of the People to "&
		"alter or to abolish it, and to institute new Government, laying its foundation on such principles and organizing "&
		"its powers in such form, as to them shall seem most likely to effect their Safety and Happiness. Prudence, indeed, "&
		"will dictate that Governments long established should not be changed for light and transient causes; and "&
		"accordingly all experience hath shown, that mankind are more disposed to suffer, while evils are sufferable, than "&
		"to right themselves by abolishing the forms to which they are accustomed. But when a long train of abuses and "&
		"usurpations, pursuing invariably the same Object evinces a design to reduce them under absolute Despotism, it is "&
		"their right, it is their duty, to throw off such Government, and to provide new Guards for their future security. "&
		"Such has been the patient sufferance of these Colonies; and such is now the necessity which constrains them to "&
		"alter their former Systems of Government. The history of the present King of Great Britain is a history of "&
		"repeated injuries and usurpations, all having in direct object the establishment of an absolute Tyranny over these "&
		"States. To prove this, let Facts be submitted to a candid world. He has refused his Assent to Laws, the most "&
		"wholesome and necessary for the public good. "&
		"We, therefore, the Representatives of the United States of America, in General Congress, Assembled, "&
		"appealing to the Supreme Judge of the world for the rectitude of our intentions, do, in the Name, and by Authority "&
		"of the good People of these Colonies, solemnly publish and declare, That these United Colonies are, and of Right "&
		"ought to be free and independent states; that they are Absolved from all Allegiance to the British Crown, and that "&
		"all political connection between them and the State of Great Britain, is and ought to be totally dissolved; and "&
		"that as Free and Independent States, they have full Power to levy War, conclude Peace, contract Alliances, "&
		"establish Commerce, and to do all other Acts and Things which Independent States may of right do. And for the "&
		"support of this Declaration, with a firm reliance on the Protection of Divine Providence, we mutually pledge to "&
		"each other our Lives, our Fortunes, and our sacred Honor."

		@wrap_title( "Response for a simple URL Internet search" )
		@wrap_node( copyscape_api_url_search_internet("http://www.copyscape.com/example.html") )

		@wrap_title( "Response for a URL Internet search with full comparisons for the first two results" )
		@wrap_node( copyscape_api_url_search_internet("http://www.copyscape.com/example.html", 2) )

		@wrap_title( "Response for a simple text Internet search" )
		@wrap_node( copyscape_api_text_search_internet(exampletext, "ISO-8859-1") )
		
		@wrap_title( "Response for a text Internet search with full comparisons for the first two results" )
		@wrap_node( copyscape_api_text_search_internet(exampletext, "ISO-8859-1", 2) )

		@wrap_title( "Response for a check balance request" )
		@wrap_node( copyscape_api_check_balance() )
	
		@wrap_title( "Response for a URL add to private index request" )
		@wrap_node( copyscape_api_url_add_to_private("http://www.copyscape.com/example.html") )
	
		@wrap_title( "Response for a text add to private index request" )
		Dim response As XmlElement = copyscape_api_text_add_to_private( exampletext, "ISO-8859-1", "Extract from Declaration of Independence", "EXAMPLE_1234" )
		@wrap_node( response )

		Dim handle As String = Nothing
        If (response IsNot Nothing) And (response.GetElementsByTagName("handle").Count > 0)
            handle = response.GetElementsByTagName("handle").Item(0).InnerText
        End If

		@wrap_title( "Response for a URL private index search" )
		@wrap_node( copyscape_api_url_search_private("http://www.copyscape.com/example.html") )

		@wrap_title( "Response for a delete from private index request" )
		@wrap_node( copyscape_api_delete_from_private(handle) )

		@wrap_title( "Response for a text search of both Internet and private index with full comparisons for the first result (of each type)" )
		@wrap_node( copyscape_api_text_search_internet_and_private(exampletext, "ISO-8859-1", 1) )

	End If

End Code