Commit c3b8b11e by Urvil Shah

Initial commit

parents
Pipeline #8018 failed with stages
in 11 seconds
Showing with 4650 additions and 0 deletions
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
build/
bld/
[Bb]in/
[Oo]bj/
# Visual Studio 2015 cache/options directory
.vs/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# Windows Azure Build Output
csx/
*.build.csdef
# Windows Store app package directory
AppPackages/
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
\ No newline at end of file
stages:
- build
- deploy
build_website:
stage: build
script:
- nuget restore .\Mobile.WYSIWYG.sln
- msbuild /p:Configuration=Release /p:OutDir=build\web .\Mobile.WYSIWYG\Mobile.WYSIWYG.csproj
artifacts:
expire_in: 6 weeks
paths:
- .\Mobile.-WYSIWYG\build\web\_PublishedWebsites\Mobile.WYSIWYG
when: always
deploy_web:
stage: deploy
script:
- Import-Module PSRemoteDeploy
- $servers = $env:DEPLOY_SERVERS -split ';'
- Copy-FilesToServers -Servers $servers -UserName $env:DEPLOY_USERNAME -Password $env:DEPLOY_PASSWORD -LocalPath ".\Mobile.-WYSIWYG\build\web\_PublishedWebsites\Mobile.WYSIWYG\*" -RemotePath "C:\adk-mobile\$env:CI_PROJECT_NAME\Mobile.-WYSIWYG\$env:CI_BUILD_ID"
- Set-IISPhysicalPaths -Servers $servers -UserName $env:DEPLOY_USERNAME -Password $env:DEPLOY_PASSWORD -IISSite "Mobile.WYSIWYG" -Path "c:\adk-mobile\$env:CI_PROJECT_NAME\Mobile.WYSIWYG\$env:CI_BUILD_ID"
when: manual
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Xml;
using System.Xml.Linq;
using Mobile.Search.Shared.Models;
using Serilog;
using ServiceStack;
namespace Mobile.Search.Providers
{
public class BidSystemProvider
{
private static string Md5(string input)
{
// step 1, calculate MD5 hash from input
MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
byte[] hash = md5.ComputeHash(inputBytes);
// step 2, convert byte array to hex string
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("X2"));
}
return sb.ToString();
}
public static string TestXml = @"<?xml version='1.0' encoding='UTF-8'?>
<request>
<email>
<list>{4}</list>
<recipient>{5}</recipient>
<domain>aol.com</domain>
<redirect><![CDATA[http://imp.d2s.adk-mobile.com/?event=bidsystem-click&quizid={0}&questionid={1}&userid={2}&sessionid={3}&url=]]></redirect>
<countrycode>US</countrycode>
<subid><![CDATA[d2s]]></subid>
</email>
</request>";
public static IEnumerable<Listing> GetListingsFromXml(string xml)
{
var xmlDoc = XDocument.Parse(xml).Root;
if (xmlDoc != null)
{
var entryElement = xmlDoc.Descendants().Where(x => x.Name.LocalName == "entry");
return xmlDoc.Elements("ResultSet")
.SelectMany(x => x.Elements("Listing"))
.Select(x => new Listing
{
Rank = 1,
Title = "",
Description = "description",
SiteHost = "siteHost",
BiddedListing = true,
ResultType = "resultType",
SiteLanguage = "en",
ListingLanguage = "en",
PhoneNumber = "",
ClickUrl = "clickurl",
FaviconUrl = "",
MerchRatingNumber = "0",
MerchRatingUrl = "https://s3.amazonaws.com/mobile.cdn/0_stars.png",
//MerchRating = "",
//LongTitle = "",
ImageUrl = "",
// === Yahoo! API Extensions Update 2017-10-11 === //
// 1. Callout Extensions
CalloutAnnotation = "",
// 2. Review Extensions
ReviewSource = "",
ReviewText = "",
// 3. 4th Line Annotations
Ad4thLine = "",
// 4. Top Ad Annotations
HasTopAdAnnotation = "",
TopAdDomain = "0",
TopAdClicks = "0",
// 5. Security Badge
SecurityProvider = "",
// 6. Brand Annotations
AdOfficialBrand = "",
// 7. Smart Annotations
SmartAdAnnotation = ""
});
}
return new List<Listing>();
}
public static void GetListings(string sessionId, string categoryId, string ip = null)
{
var url = "http://bs-d2s-list-80.ak-networks.com/searches?";
url = url.AddQueryParam("category-id", categoryId)
.AddQueryParam("objective-id", 1)
.AddQueryParam("count", 10)
.AddQueryParam("default-country", "US")
.AddQueryParam("affiliate-id", "844069")
.AddQueryParam("exclude-central-discounting", "true")
.AddQueryParam("mobile-listings", "true")
.AddQueryParam("ip", ip ?? "205.232.172.74");
var xml = url.GetXmlFromUrl(requestFilter: req =>
{
req.Timeout = (int)TimeSpan.FromSeconds(5).TotalMilliseconds;
});
GetListingsFromXml(xml);
}
private static Random rand = new Random();
static Tuple<string, decimal> GetClickUrlAndBidFromXml(string xml)
{
var xmlDoc = XDocument.Parse(xml).Root;
if (xmlDoc == null) return null;
var entryElement = xmlDoc.Descendants().FirstOrDefault(x => x.Name.LocalName == "entry");
if (entryElement == null) return null;
var clickUrlElement = entryElement
.Descendants().FirstOrDefault(x => x.Name.LocalName == "click-url");
var bidElement = entryElement.Descendants().FirstOrDefault(x => x.Name.LocalName == "price-chain")
.Descendants().FirstOrDefault();
decimal bid = 0;
if (bidElement != null && bidElement.Attribute("value") != null)
{
decimal.TryParse(bidElement.Attribute("value").Value, out bid);
}
return Tuple.Create(clickUrlElement.Value, bid);
}
public static string GetClickUrl(string clickId, string categoryId, string ip = null, string affiliateid = "844069")
{
try
{
var listingResults = new List<Tuple<string, decimal>>();
var url = "http://bs-d2s-list-80.ak-networks.com/searches?";
url = url.AddQueryParam("category-id", categoryId)
.AddQueryParam("objective-id", 1)
.AddQueryParam("count", 10)
.AddQueryParam("default-country", "US")
.AddQueryParam("affiliate-id", affiliateid)
.AddQueryParam("exclude-central-discounting", "true")
.AddQueryParam("mobile-listings", "true")
.AddQueryParam("ip", ip ?? "205.232.172.74");
var xml = url.GetXmlFromUrl(requestFilter: req =>
{
req.Timeout = (int) TimeSpan.FromSeconds(5).TotalMilliseconds;
});
listingResults.Add(GetClickUrlAndBidFromXml(xml));
//try again without mobile exclusive listings
url = "http://bs-d2s-list-80.ak-networks.com/searches?";
url = url.AddQueryParam("category-id", categoryId)
.AddQueryParam("objective-id", 1)
.AddQueryParam("count", 10)
.AddQueryParam("default-country", "US")
.AddQueryParam("exclude-central-discounting", "true")
.AddQueryParam("affiliate-id", affiliateid)
.AddQueryParam("ip", ip ?? "205.232.172.74");
xml = url.GetXmlFromUrl(requestFilter: req =>
{
req.Timeout = (int) TimeSpan.FromSeconds(5).TotalMilliseconds;
});
listingResults.Add(GetClickUrlAndBidFromXml(xml));
var result = listingResults.Where(x => x != null).Where(x => !string.IsNullOrEmpty(x.Item1))
.OrderByDescending(x => x.Item2)
.FirstOrDefault();
if (result == null)
return string.Empty;
var clickUrl = result.Item1;
if (clickUrl != null)
{
return clickUrl + "&txn=" + HttpUtility.UrlEncode(clickId);
}
return string.Empty;
}
catch (Exception x)
{
Log.Error(x, "Bid System sucks");
return string.Empty;
}
}
public static string GetResults(string quizId, string questionId, string userId, string sessionId, string listid)
{
var generateUser =Md5(Guid.NewGuid().ToString("N") + "@aol.com");
var bsXml = TestXml.Fmt(quizId, questionId, userId, sessionId, listid, generateUser);
var endpoint = "http://integrated.adstation.com/1.3/"
.AddQueryParam("cdomain", "click.email.horoscopedaily.email")
.AddQueryParam("idomain", "image.email.horoscopedaily.email")
.AddQueryParam("request", bsXml)
.AddQueryParam("nolsdb", 1)
.AddQueryParam("token", "729fcd8c7333e1455c865b8ecbc281c6");
var xml = endpoint.GetXmlFromUrl();
if (xml != null)
{
var index = xml.IndexOf("http://imp.d2s.adk-mobile.com/?event=bidsystem-click&quizid={0}&questionid={1}&userid={2}&sessionid={3}&url=".Fmt(quizId, questionId, userId, sessionId),
System.StringComparison.Ordinal);
if (index > 0)
{
var firstClickUrl = xml.Substring(index, xml.IndexOf("\"", index) - index);
return firstClickUrl;
}
}
return string.Empty;
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Xml.Linq;
using Mobile.Search.Shared;
using Mobile.Search.Shared.Models;
using ServiceStack;
namespace Mobile.Search.Providers
{
public class CouponsProvider
{
private static readonly List<string> UserAgents = new List<string>
{
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36",
"Mozilla/5.0 (Linux; U; Android 4.0.3; ko-kr; LG-L160L Build/IML74K) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30"
};
public static SearchResult GetListings(string query, string ip, int count)
{
var userAgent = UserAgents[1];
ip = ip ?? "1.2.3.4";
var url = MakeUrl(query, ip, userAgent, count);
var xml = GetXml(url, userAgent);
var listings = GetListingsFromXml(xml).ToList();
return new SearchResult
{
SearchId = Guid.NewGuid(),
Ip = ip,
UserAgent = userAgent,
SourceTag = null,
TypeTag = null,
Listings = listings,
ListingsCount = listings.Count(),
Query = query,
OriginalQuery = query
};
}
private static string MakeUrl(string query, string ip, string userAgent, int count)
{
var url = "http://rss.coupons.com/xmlserve.asp"
.AddQueryParam("publisher", "6782791018469226")
.AddQueryParam("q", query)
.AddQueryParam("sort", "relevance")
.AddQueryParam("radius", 50)
.AddQueryParam("limit", count)
.AddQueryParam("format", "xml")
.AddQueryParam("latlong", 1)
.AddQueryParam("co", "us")
.AddQueryParam("userip", ip)
.AddQueryParam("useragent", userAgent)
.AddQueryParam("v", 2);
return url;
}
private static string GetXml(string url, string userAgent)
{
try
{
return url.GetStringFromUrl(
requestFilter: req =>
{
req.Method = "GET";
req.KeepAlive = false;
req.UserAgent = userAgent;
req.Headers.Add("Accept-Encoding", "gzip,deflate");
req.Headers.Add("Cache-Control", "no-cache");
});
}
catch (WebException webEx)
{
//TODO: Log
if (webEx.IsBadRequest())
{
throw new Exception(webEx.GetResponseBody(), webEx);
}
throw;
}
return "";
}
public static IEnumerable<Listing> GetListingsFromXml(string xml)
{
var xmlDoc = XDocument.Parse(xml).Root;
if (xmlDoc != null)
{
var rank = 1;
return xmlDoc.Elements("results")
.SelectMany(x => x.Elements("result"))
.Select(x => new Listing
{
Rank = rank++,
Title = TryGetElementValue(x, "jobtitle"),
Description = TryGetElementValue(x, "snippet"),
SiteHost = TryGetSiteHostFromURL(x, "url"),
BiddedListing = true,
ResultType = default(string),
SiteLanguage = default(string),
ListingLanguage = default(string),
PhoneNumber = default(string),
ClickUrl = TryGetElementValue(x, "url")
});
}
return new List<Listing>();
}
private static string TryGetSiteHostFromURL(XElement element, string name)
{
var host = default(string);
var url = element.Element("url").Value;
if (url.Length > 0)
{
Uri uri = new Uri(url);
host = uri.Host;
}
return host;
}
private static string TryGetElementValue(XElement element, string name)
{
var e = element.Element(name);
return e != null ? e.Value : default(string);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Xml.Linq;
using Mobile.Search.Shared;
using Mobile.Search.Shared.Models;
using ServiceStack;
namespace Mobile.Search.Providers
{
public class IndeedProvider
{
private static readonly List<string> UserAgents = new List<string>
{
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36",
"Mozilla/5.0 (Linux; U; Android 4.0.3; ko-kr; LG-L160L Build/IML74K) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30"
};
public static SearchResult GetListings(string query, string ip, int count)
{
var userAgent = UserAgents[1];
ip = ip ?? "1.2.3.4";
var url = MakeUrl(query, ip, userAgent, count);
var xml = GetXml(url, userAgent);
var listings = GetListingsFromXml(xml).ToList();
return new SearchResult
{
SearchId = Guid.NewGuid(),
Ip = ip,
UserAgent = userAgent,
SourceTag = null,
TypeTag = null,
Listings = listings,
ListingsCount = listings.Count(),
Query = query,
OriginalQuery = query
};
}
private static string MakeUrl(string query, string ip, string userAgent, int count)
{
var url = "http://api.indeed.com/ads/apisearch"
.AddQueryParam("publisher", "6782791018469226")
.AddQueryParam("q", query)
.AddQueryParam("sort", "relevance")
.AddQueryParam("radius", 50)
.AddQueryParam("limit", count)
.AddQueryParam("format", "xml")
.AddQueryParam("latlong", 1)
.AddQueryParam("co", "us")
.AddQueryParam("userip", ip)
.AddQueryParam("useragent", userAgent)
.AddQueryParam("v", 2);
return url;
}
private static string GetXml(string url, string userAgent)
{
try
{
return url.GetStringFromUrl(
requestFilter: req =>
{
req.Method = "GET";
req.KeepAlive = false;
req.UserAgent = userAgent;
req.Headers.Add("Accept-Encoding", "gzip,deflate");
req.Headers.Add("Cache-Control", "no-cache");
});
}
catch (WebException webEx)
{
//TODO: Log
if (webEx.IsBadRequest())
{
throw new Exception(webEx.GetResponseBody(), webEx);
}
throw;
}
//return "";
}
public static IEnumerable<Listing> GetListingsFromXml(string xml)
{
var xmlDoc = XDocument.Parse(xml).Root;
if (xmlDoc != null)
{
var rank = 1;
return xmlDoc.Elements("results")
.SelectMany(x => x.Elements("result"))
.Select(x => new Listing
{
Rank = rank++,
Title = TryGetElementValue(x, "jobtitle"),
Description = TryGetElementValue(x, "snippet"),
SiteHost = TryGetSiteHostFromURL(x, "url"),
BiddedListing = true,
ResultType = default(string),
SiteLanguage = default(string),
ListingLanguage = default(string),
PhoneNumber = default(string),
ClickUrl = TryGetElementValue(x, "url")
});
}
return new List<Listing>();
}
private static string TryGetSiteHostFromURL(XElement element, string name)
{
var host = default(string);
var url = element.Element("url").Value;
if (url.Length > 0)
{
Uri uri = new Uri(url);
host = uri.Host;
}
return host;
}
private static string TryGetElementValue(XElement element, string name)
{
var e = element.Element(name);
return e != null ? e.Value : default(string);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{9657E007-68ED-4FD1-B218-D108E36C1FF6}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Mobile.Search.Providers</RootNamespace>
<AssemblyName>Mobile.Search.Providers</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Serilog, Version=2.0.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10, processorArchitecture=MSIL">
<HintPath>..\packages\Serilog.2.3.0\lib\net45\Serilog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="ServiceStack.Text, Version=4.5.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ServiceStack.Text.4.5.4\lib\net45\ServiceStack.Text.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="BidSystemProvider.cs" />
<Compile Include="TaboolaProvider.cs" />
<Compile Include="IndeedProvider.cs" />
<Compile Include="YahooProvider.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Mobile.Search.Shared\Mobile.Search.Shared.csproj">
<Project>{D1D3A9D0-BF28-4D93-8CC5-7E690F4B51B0}</Project>
<Name>Mobile.Search.Shared</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\OctoPack.3.4.6\tools\OctoPack.targets" Condition="Exists('..\packages\OctoPack.3.4.6\tools\OctoPack.targets')" />
<Target Name="EnsureOctoPackImported" BeforeTargets="BeforeBuild" Condition="'$(OctoPackImported)' == ''">
<Error Condition="!Exists('..\packages\OctoPack.3.4.6\tools\OctoPack.targets') And ('$(RunOctoPack)' != '' And $(RunOctoPack))" Text="You are trying to build with OctoPack, but the NuGet targets file that OctoPack depends on is not available on this computer. This is probably because the OctoPack package has not been committed to source control, or NuGet Package Restore is not enabled. Please enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" />
<Error Condition="Exists('..\packages\OctoPack.3.4.6\tools\OctoPack.targets') And ('$(RunOctoPack)' != '' And $(RunOctoPack))" Text="OctoPack cannot be run because NuGet packages were restored prior to the build running, and the targets file was unavailable when the build started. Please build the project again to include these packages in the build. You may also need to make sure that your build server does not delete packages prior to each build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
\ No newline at end of file
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Mobile.Search.Providers.Lib")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Mobile.Search.Providers.Lib")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("0397c864-0825-4fba-a846-8fb479ddae94")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Xml.Linq;
using Mobile.Search.Shared;
using Mobile.Search.Shared.Models;
using ServiceStack;
using System.Text.RegularExpressions;
namespace Mobile.Search.Providers
{
public class TaboolaProvider
{
private static readonly List<string> UserAgents = new List<string>
{
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36",
"Mozilla/5.0 (Linux; U; Android 4.0.3; ko-kr; LG-L160L Build/IML74K) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30"
};
public static SearchResult GetListings(string ip, int count, string sourceUrl, string userReferrer, string utmCampaign)
{
// Example: http://localhost:64292/search/template?templateKey=dynamic_css_taboola&keyword=best+buy+tv&debug=true&content_subtype=WeatherHeader&storeClickUrls=true&emailId=f1ff24b475da4d30af21925bc9562fb6&Ip=73.157.247.196
var userAgent = UserAgents[1];
// Make sure incoming IP is a valid one!
Match match = Regex.Match(ip, @"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}");
if (!match.Success)
{
ip = "";
}
var url = MakeUrl(count, sourceUrl, userReferrer, utmCampaign, ip);
var rawTaboolaJsonData = GetJson(url, userAgent);
var listings = GetListingsFromJson(rawTaboolaJsonData).ToList();
return new SearchResult
{
SearchId = Guid.NewGuid(),
Ip = ip,
UserAgent = userAgent,
SourceTag = null,
TypeTag = null,
Listings = listings,
ListingsCount = listings.Count(),
sourceUrl = sourceUrl,
userReferrer = userReferrer,
utmCampaign = utmCampaign
};
}
private static string MakeUrl(int count, string sourceUrl, string userReferrer, string utmCampaign, string ip)
{
var url = "http://taboola-api.rm-mobile.com/api/taboola/RecommendationsGet"
.AddQueryParam("appType", "mobile")
.AddQueryParam("placementRecCount", count) // Ex: 5
.AddQueryParam("placementOrganicType", "video")
.AddQueryParam("userSession", "init")
.AddQueryParam("sourceType", "search")
.AddQueryParam("sourceId", "214321562187")
.AddQueryParam("sourceUrl", sourceUrl) // Ex: www.google.com
.AddQueryParam("userReferrer", userReferrer) // Ex: Coupons
.AddQueryParam("utmCampaign", utmCampaign) // Ex: Coupons
.AddQueryParam("userRealIp", ip); // Ex: 1.2.3.4
return url;
}
private static string GetJson(string url, string userAgent)
{
try
{
return url.GetStringFromUrl(
requestFilter: req =>
{
req.Method = "GET";
req.KeepAlive = false;
req.UserAgent = userAgent;
req.Headers.Add("Accept-Encoding", "gzip,deflate");
req.Headers.Add("Cache-Control", "no-cache");
});
}
catch (WebException webEx)
{
//TODO: Log
if (webEx.IsBadRequest())
{
throw new Exception(webEx.GetResponseBody(), webEx);
}
throw;
}
//return "";
}
public static IEnumerable<Listing> GetListingsFromJson(string json)
{
var rank = 1;
var taboolaRequest = json.FromJson<TaboolaResponse>();
return taboolaRequest.list.Select(x => new Listing
{
Rank = rank++,
Title = x.name,
Description = x.description,
BiddedListing = true,
ResultType = default(string),
SiteHost = x.branding,
Categories = x.categories,
SiteLanguage = default(string),
ListingLanguage = default(string),
PhoneNumber = default(string),
ClickUrl = x.url,
ThumbnailImageUrl = x.thumbnail[0].url
});
}
private static string TryGetSiteHostFromURL(XElement element, string name)
{
var host = default(string);
var url = element.Element("url").Value;
if (url.Length > 0)
{
Uri uri = new Uri(url);
host = uri.Host;
}
return host;
}
private static string TryGetElementValue(XElement element, string name)
{
var e = element.Element(name);
return e != null ? e.Value : default(string);
}
}
public class TaboolaResponse
{
public string session { get; set; }
public string id { get; set; }
public string ui { get; set; }
public List<TaboolaResponseItem> list { get; set; }
}
public class TaboolaResponseItem
{
public List<TaboolaThumbnailUrl> thumbnail { get; set; }
public string description { get; set; }
public string type { get; set; }
public string name { get; set; }
public string created { get; set; }
public string branding { get; set; }
public string duration { get; set; }
public List<String> categories { get; set; }
public string views { get; set; }
public string itemId { get; set; }
public string origin { get; set; }
public string url { get; set; }
}
public class TaboolaThumbnailUrl
{
public string url { get; set; }
}
}
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Serilog" publicKeyToken="24c2f752a8e58a10" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
\ No newline at end of file

\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="OctoPack" version="3.4.6" targetFramework="net45" developmentDependency="true" />
<package id="Serilog" version="2.3.0" targetFramework="net45" />
<package id="ServiceStack.Text" version="4.5.4" targetFramework="net45" />
</packages>
\ No newline at end of file
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net;
using System.Text;
namespace Mobile.Search.Shared.Extensions
{
public static class QueryStringExtensions
{
public static string ToQueryString(this IDictionary<string, string> dict)
{
if (dict.Count == 0) return string.Empty;
var buffer = new StringBuilder();
int count = 0;
bool end = false;
foreach (var key in dict.Keys)
{
if (count == dict.Count - 1) end = true;
var value = dict[key];
// if there's amperstamp in the value then we must have to encode it
if (dict[key].Contains("&"))
{
value = WebUtility.UrlEncode(value);
}
if (end)
buffer.AppendFormat("{0}={1}", key, value);
else
buffer.AppendFormat("{0}={1}&", key, value);
count++;
}
return buffer.ToString();
}
public static Dictionary<string, string> ToDictionary(this NameValueCollection nvc)
{
return nvc.AllKeys.Where(q => !string.IsNullOrEmpty(q) && !string.IsNullOrEmpty(nvc[q])).ToDictionary(k => k, k => nvc[k]);
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace Mobile.Search.Shared.Helpers
{
// from https://gist.github.com/BravoTango86/2a085185c3b9bd8383a1f956600e515f
public static class Base32
{
private static readonly char[] DIGITS;
private static readonly int MASK;
private static readonly int SHIFT;
private static Dictionary<char, int> CHAR_MAP = new Dictionary<char, int>();
private const string SEPARATOR = "-";
static Base32()
{
DIGITS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567".ToCharArray();
MASK = DIGITS.Length - 1;
SHIFT = numberOfTrailingZeros(DIGITS.Length);
for (int i = 0; i < DIGITS.Length; i++) CHAR_MAP[DIGITS[i]] = i;
}
private static int numberOfTrailingZeros(int i)
{
// HD, Figure 5-14
int y;
if (i == 0) return 32;
int n = 31;
y = i << 16; if (y != 0) { n = n - 16; i = y; }
y = i << 8; if (y != 0) { n = n - 8; i = y; }
y = i << 4; if (y != 0) { n = n - 4; i = y; }
y = i << 2; if (y != 0) { n = n - 2; i = y; }
return n - (int)((uint)(i << 1) >> 31);
}
public static byte[] Decode(string encoded)
{
// Remove whitespace and separators
encoded = encoded.Trim().Replace(SEPARATOR, "");
// Remove padding. Note: the padding is used as hint to determine how many
// bits to decode from the last incomplete chunk (which is commented out
// below, so this may have been wrong to start with).
encoded = Regex.Replace(encoded, "[=]*$", "");
// Canonicalize to all upper case
encoded = encoded.ToUpper();
if (encoded.Length == 0)
{
return new byte[0];
}
int encodedLength = encoded.Length;
int outLength = encodedLength * SHIFT / 8;
byte[] result = new byte[outLength];
int buffer = 0;
int next = 0;
int bitsLeft = 0;
foreach (char c in encoded.ToCharArray())
{
if (!CHAR_MAP.ContainsKey(c))
{
throw new DecodingException("Illegal character: " + c);
}
buffer <<= SHIFT;
buffer |= CHAR_MAP[c] & MASK;
bitsLeft += SHIFT;
if (bitsLeft >= 8)
{
result[next++] = (byte)(buffer >> (bitsLeft - 8));
bitsLeft -= 8;
}
}
// We'll ignore leftover bits for now.
//
// if (next != outLength || bitsLeft >= SHIFT) {
// throw new DecodingException("Bits left: " + bitsLeft);
// }
return result;
}
public static string Encode(byte[] data, bool padOutput = true)
{
if (data.Length == 0)
{
return "";
}
// SHIFT is the number of bits per output character, so the length of the
// output is the length of the input multiplied by 8/SHIFT, rounded up.
if (data.Length >= (1 << 28))
{
// The computation below will fail, so don't do it.
throw new ArgumentOutOfRangeException("data");
}
int outputLength = (data.Length * 8 + SHIFT - 1) / SHIFT;
StringBuilder result = new StringBuilder(outputLength);
int buffer = data[0];
int next = 1;
int bitsLeft = 8;
while (bitsLeft > 0 || next < data.Length)
{
if (bitsLeft < SHIFT)
{
if (next < data.Length)
{
buffer <<= 8;
buffer |= (data[next++] & 0xff);
bitsLeft += 8;
}
else
{
int pad = SHIFT - bitsLeft;
buffer <<= pad;
bitsLeft += pad;
}
}
int index = MASK & (buffer >> (bitsLeft - SHIFT));
bitsLeft -= SHIFT;
result.Append(DIGITS[index]);
}
if (padOutput)
{
int padding = 8 - (result.Length % 8);
if (padding > 0) result.Append(new string('=', padding == 8 ? 0 : padding));
}
return result.ToString();
}
private class DecodingException : Exception
{
public DecodingException(string message) : base(message)
{
}
}
}
}
using System;
using System.IO;
using System.Security.Cryptography;
namespace Mobile.Search.Shared.Helpers
{
public class RijndaelHelper
{
public static byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
{
// Check arguments.
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException("plainText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("IV");
byte[] encrypted;
// Create an RijndaelManaged object
// with the specified key and IV.
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
// Return the encrypted bytes from the memory stream.
return encrypted;
}
public static string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
{
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("IV");
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an RijndaelManaged object
// with the specified key and IV.
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
}
}
\ No newline at end of file
namespace Mobile.Search.Shared
{
public interface IUrlHelper
{
}
public class SearchUrlHelper : IUrlHelper
{}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{D1D3A9D0-BF28-4D93-8CC5-7E690F4B51B0}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Mobile.Search.Shared</RootNamespace>
<AssemblyName>Mobile.Search.Shared</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Chronos, Version=0.0.153.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Chronos.0.0.153\lib\Chronos.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="RabbitMQ.Client, Version=3.5.0.0, Culture=neutral, PublicKeyToken=89e7d7c5feba84ce, processorArchitecture=MSIL">
<HintPath>..\packages\RabbitMQ.Client.3.5.0\lib\net40\RabbitMQ.Client.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Serilog, Version=2.0.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10, processorArchitecture=MSIL">
<HintPath>..\packages\Serilog.2.3.0\lib\net45\Serilog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="ServiceStack.Text, Version=4.5.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ServiceStack.Text.4.5.4\lib\net45\ServiceStack.Text.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Helpers\Base32.cs" />
<Compile Include="Helpers\RijndaelHelper.cs" />
<Compile Include="Helpers\YahooSourceTagHelper.cs" />
<Compile Include="IUrlHelper.cs" />
<Compile Include="Models\Listing.cs" />
<Compile Include="Models\SearchRequest.cs" />
<Compile Include="Models\SearchResult.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Extensions\QueryStringExtensions.cs" />
<Compile Include="QueueHelper.cs" />
<Compile Include="YahooTags.cs" />
<Compile Include="Tracker.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\OctoPack.3.4.6\tools\OctoPack.targets" Condition="Exists('..\packages\OctoPack.3.4.6\tools\OctoPack.targets')" />
<Target Name="EnsureOctoPackImported" BeforeTargets="BeforeBuild" Condition="'$(OctoPackImported)' == ''">
<Error Condition="!Exists('..\packages\OctoPack.3.4.6\tools\OctoPack.targets') And ('$(RunOctoPack)' != '' And $(RunOctoPack))" Text="You are trying to build with OctoPack, but the NuGet targets file that OctoPack depends on is not available on this computer. This is probably because the OctoPack package has not been committed to source control, or NuGet Package Restore is not enabled. Please enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" />
<Error Condition="Exists('..\packages\OctoPack.3.4.6\tools\OctoPack.targets') And ('$(RunOctoPack)' != '' And $(RunOctoPack))" Text="OctoPack cannot be run because NuGet packages were restored prior to the build running, and the targets file was unavailable when the build started. Please build the project again to include these packages in the build. You may also need to make sure that your build server does not delete packages prior to each build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
\ No newline at end of file
using System;
using System.Web;
using Serilog;
using System.Collections.Generic;
namespace Mobile.Search.Shared.Models
{
public class Listing
{
public int Rank { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string SiteHost { get; set; }
public bool BiddedListing { get; set; }
public string ResultType { get; set; }
public string SiteLanguage { get; set; }
public string ListingLanguage { get; set; }
public string PhoneNumber { get; set; }
public string ClickUrl { get; set; }
public string FaviconUrl { get; set; }
public string MerchRatingNumber { get; set; }
public string MerchRatingUrl { get; set; }
public string LongTitle { get; set; }
public string ThumbnailImageUrl { get; set; }
public string ImageUrl { get; set; }
public List<String> Categories { get; set; }
// === Yahoo! API Extensions Update 2017-10-11 === //
// 1. Callout Extensions
public string CalloutAnnotation { get; set; }
// 2. Review Extensions
public string ReviewSource { get; set; }
public string ReviewText { get; set; }
// 3. 4th Line Annotations
public string Ad4thLine { get; set; }
// 4. Top Ad Annotations
public string HasTopAdAnnotation { get; set; }
public string TopAdDomain { get; set; }
public string TopAdClicks { get; set; }
// 5. Security Badge
public string SecurityProvider { get; set; }
// 6. Brand Annotations
public string AdOfficialBrand { get; set; }
// 7. Smart Ad Annotations
public string SmartAdAnnotation { get; set; }
public List<SiteLink> SiteLinks { get; set; }
public string GetTitle()
{
if (string.IsNullOrEmpty(Title))
{
return string.Empty;
}
else
{
return Title;
}
}
public string GetAdvertiserUrl()
{
if (string.IsNullOrEmpty(ClickUrl))
{
return string.Empty;
}
try
{
var clickUri = new Uri(ClickUrl);
return HttpUtility.ParseQueryString(clickUri.Query).Get("u") ?? string.Empty;
}
catch (UriFormatException formatException)
{
Log.Error(formatException, "Not a valid url format {clickurl}", ClickUrl);
return string.Empty;
}
}
public class SiteLink
{
public string Text { get; set; }
public string Url { get; set; }
}
}
}
\ No newline at end of file
using System;
namespace Mobile.Search.Shared.Models
{
public class SearchRequest
{
public string Query { get; set; }
public string TypeTag { get; set; }
public string ServeUrl { get; set; }
public int BiddedResults { get; set; }
public int NonBiddedResults { get; set; }
public string UserAgent { get; set; }
public string Ip { get; set; }
public int SourceTagId { get; set; }
public string SourceTag { get; set; }
public DateTime Timestamp { get; set; }
public bool UseFakeUserAgent { get; set; }
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Mobile.Search.Shared.Models
{
public class PartialSearchResult : SearchResult
{
public int ListingNumber { get; set; }
}
public class SearchResult
{
public SearchResult()
{
// Default the ClickUrl func to return the click url
// with no modifications until we get a tracking link
ClickUrlFunc = listing => listing.ClickUrl;
}
public string Query { get; set; }
[IgnoreDataMember]
public IEnumerable<Listing> Listings { get; set; }
public int ListingsCount { get; set; }
public string Ip { get; set; }
public string UserAgent { get; set; }
public List<string> RelatedSearches { get; set; }
public string SourceTag { get; set; }
public string TypeTag { get; set; }
public Guid SearchId { get; set; }
public string OriginalQuery { get; set; }
public string sourceUrl { get; set; }
public string userReferrer { get; set; }
public string utmCampaign { get; set; }
[IgnoreDataMember]
public Func<Listing, string> ClickUrlFunc { get; set; }
public string NextUrl { get; set; }
}
}
\ No newline at end of file
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Mobile.Search.Shared")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Mobile.Search.Shared")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("9425f997-9106-49d1-b476-de8d6bf2c1d9")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
using System;
using System.Linq;
using System.Text;
using Chronos;
using Chronos.Configuration;
using RabbitMQ.Client;
namespace Mobile.Search.Shared
{
public interface IQueueHelper
{
void PublishMessage(string exchangeName,string routingKey, string messageType,string message);
}
public class QueueHelper : IQueueHelper, IDisposable
{
private readonly ConnectionFactory _connectionFactory;
private IConnection _rabbitConnection;
public QueueHelper(string rabbitConnStrKey)
{
var rabbitConnectionString = ConfigUtilities.GetRabbitMqConnectionString(rabbitConnStrKey);
_connectionFactory = new ConnectionFactory
{
HostName = rabbitConnectionString.Host,
Port = rabbitConnectionString.Port,
UserName = rabbitConnectionString.Username,
Password = rabbitConnectionString.Password,
};
_rabbitConnection = _connectionFactory.CreateConnection();
}
public void PublishMessage(string exchangeName, string routingKey, string messageType,string message)
{
PublishMessages(exchangeName, routingKey, messageType,new[] { message });
}
public void PublishMessages(string exchangeName, string routingKey, string messageType, string[] messages)
{
// unknown if this is needed or not, or what even happens if the connection isn't open
if (!_rabbitConnection.IsOpen)
{
_rabbitConnection = _connectionFactory.CreateConnection();
}
using (var channel = _rabbitConnection.CreateModel())
{
var basicProps = channel.CreateBasicProperties();
basicProps.ContentType = "application/json";
basicProps.MessageId = Guid.NewGuid().ToString("D");
basicProps.Type = messageType;
basicProps.SetPersistent(true);
var msgs = messages.Select(msg => Encoding.UTF8.GetBytes(msg));
foreach (var message in msgs)
{
basicProps.Timestamp = new AmqpTimestamp(DateTime.UtcNow.ToUnixTimestamp());
channel.BasicPublish(
exchange: exchangeName,
routingKey: routingKey,
basicProperties: basicProps,
body: message);
}
}
}
public void Dispose()
{
_rabbitConnection.Close();
}
}
}
\ No newline at end of file
using System.Collections.Generic;
namespace Mobile.Search.Shared
{
public class YahooTags
{
public static readonly Dictionary<int, string> SourceTagDictionary = new Dictionary<int, string>
{
{1, "adknowledge_mobile_2click_c_search" },
{2, "adknowledge_mobile_1click_c_search"},
{3, "adknowledge_d2s_gocomics_search"},
{4, "adknowledge_mobile_1click_search"},
{5, "adknowledge_mobile_2click_newsletter_search"},
{6, "adknowledge_mobile_1click_d_search"},
{7, "adknowledge_mobile_1click_e_search"},
{8, "adknowledge_mobile_2click_e_search"},
{9, "adknowledge_mobile_1click_f_search"},
{10, "adknowledge_mobile_2click_f_search"},
{11, "adknowledge_mobile_2click_d_search"},
{12, "adknowledge_mobile_2click_j_search"},
{13, "adknowledge_mobile_2click_k_search"},
{14, "adknowledge_mobile_1click_k_search"},
};
public static string CleanTypeTag(string typeTag)
{
return string.IsNullOrEmpty(typeTag)
? typeTag
: System.Net.WebUtility.UrlDecode(typeTag).Replace(" ", "+");
}
public static string GetSourceTag(int type)
{
if (SourceTagDictionary.ContainsKey(type))
{
return SourceTagDictionary[type];
}
else
{
// this shouldn't be the default, but i don't know what relies on this
// so won't change it
return SourceTagDictionary[2];
}
}
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Serilog" publicKeyToken="24c2f752a8e58a10" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Chronos" version="0.0.153" targetFramework="net45" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
<package id="OctoPack" version="3.4.6" targetFramework="net45" developmentDependency="true" />
<package id="RabbitMQ.Client" version="3.5.0" targetFramework="net45" />
<package id="Serilog" version="2.3.0" targetFramework="net45" />
<package id="ServiceStack.Text" version="4.5.4" targetFramework="net45" />
</packages>
\ No newline at end of file
using Mobile.Search.Providers;
using NUnit.Core;
using NUnit.Framework;
namespace Mobile.Search.Test
{
public class BidSystemTests
{
[NUnit.Framework.Test]
public void Testing()
{
var clickUrl = BidSystemProvider.GetClickUrl("iek", "123");
Assert.False(string.IsNullOrEmpty(clickUrl));
}
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\xunit.runner.visualstudio.2.0.0\build\net20\xunit.runner.visualstudio.props" Condition="Exists('..\packages\xunit.runner.visualstudio.2.0.0\build\net20\xunit.runner.visualstudio.props')" />
<Import Project="..\packages\xunit.core.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.props" Condition="Exists('..\packages\xunit.core.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{1FC65C87-CB03-4748-9CE3-213BFFD925EC}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Mobile.Search.Test</RootNamespace>
<AssemblyName>Mobile.Search.Test</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>0c5bf0e1</NuGetPackageImportStamp>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="nunit.core">
<HintPath>..\packages\NUnitTestAdapter.2.0.0\lib\nunit.core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nunit.core.interfaces">
<HintPath>..\packages\NUnitTestAdapter.2.0.0\lib\nunit.core.interfaces.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nunit.framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.3.5.0\lib\net45\nunit.framework.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nunit.util">
<HintPath>..\packages\NUnitTestAdapter.2.0.0\lib\nunit.util.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NUnit.VisualStudio.TestAdapter">
<HintPath>..\packages\NUnitTestAdapter.2.0.0\lib\NUnit.VisualStudio.TestAdapter.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="BidSystemTests.cs" />
<Compile Include="YahooProviderTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Mobile.Search.Providers.Lib\Mobile.Search.Providers.csproj">
<Project>{9657e007-68ed-4fd1-b218-d108e36c1ff6}</Project>
<Name>Mobile.Search.Providers</Name>
</ProjectReference>
<ProjectReference Include="..\Mobile.Search.Shared\Mobile.Search.Shared.csproj">
<Project>{D1D3A9D0-BF28-4D93-8CC5-7E690F4B51B0}</Project>
<Name>Mobile.Search.Shared</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\OctoPack.3.4.6\tools\OctoPack.targets" Condition="Exists('..\packages\OctoPack.3.4.6\tools\OctoPack.targets')" />
<Target Name="EnsureOctoPackImported" BeforeTargets="BeforeBuild" Condition="'$(OctoPackImported)' == ''">
<Error Condition="!Exists('..\packages\OctoPack.3.4.6\tools\OctoPack.targets') And ('$(RunOctoPack)' != '' And $(RunOctoPack))" Text="You are trying to build with OctoPack, but the NuGet targets file that OctoPack depends on is not available on this computer. This is probably because the OctoPack package has not been committed to source control, or NuGet Package Restore is not enabled. Please enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" />
<Error Condition="Exists('..\packages\OctoPack.3.4.6\tools\OctoPack.targets') And ('$(RunOctoPack)' != '' And $(RunOctoPack))" Text="OctoPack cannot be run because NuGet packages were restored prior to the build running, and the targets file was unavailable when the build started. Please build the project again to include these packages in the build. You may also need to make sure that your build server does not delete packages prior to each build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
\ No newline at end of file
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Mobile.Search.Test")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Mobile.Search.Test")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("6302364e-242c-4099-9412-d808982eaa77")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
using System.Linq;
using Mobile.Search.Providers;
using NUnit.Framework;
namespace Mobile.Search.Test
{
public class Tests
{
[Test]
public void CanGetListingsFromXml()
{
var xml =
@"<Results xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xsi:noNamespaceSchemaLocation=""http://dtd.overture.com/schema/affiliate/2.9/OvertureSearchResults.xsd"">
<ResultSet id=""searchResults"" numResults=""3"" plaCount=""0"">
<Listing rank=""1"" title=""Top 5 Cable Internet - New - Top 5 Cable Internet Picks"" description=""Compare Top Providers in Your Area!"" siteHost=""HighSpeedInternet.com/CableInternet"" biddedListing=""true"" resultType=""DB"" siteLang=""en_US"" listingLang=""en_US"">
<ClickUrl type=""body"">http://beap.gemini.yahoo.com/cbclk?pp=n1&amp;ap=1&amp;es=kDCsQf0GIS8P1K9Ayp4Nj0xdgJY.DQaQtBOHDkcuCA2zE1luwZtdFd.hoOA8ZvKl5YY636HwIRWNMp63KT2m6cni32gEOHYx1MSBsg06TKtFdlfPNJKaalIX9IDRfkDdWd.ERDhEnrcTNXPrvO8apoC0Vfi9vC2.wXWeUORCCZ3CaeA1jTlybKkoitrgevj4Ov8uX4fGc3EMLsbsxe_1KawPZ67ogjrmngL7CbmMqW1vdS_0zKNBb67DRQhY1.Ql.165D3_DXpVrNoctARm6_o6Gg2mxAtNChYqtt8uASaUxHW2u0uxCGyiNAppKV7Gc9dIrHnaXqEk_8oXma1NpmdmM.TBwqFTAGI.RWS6i07DZz89f44exC4pbGcq6s1jBB1s4Q_uWJnCrREfp_hPKRApRxwp5Xv82hb38i0q.JTjAbmaWz.YUtlwteEeG9Usj1SrnEgO0brtvy0ZzYXjbdJ4wkod5rN0dUF0WwW8PFyEPxojeUWejBqQWK7dYWMImZhWSjlfP2XjlhHNL9X8op377xA_dAU0PgX6XcurY0AyABorBG4OqQHkvucue_.NEvVYlLiuflzZK87nR_UhsB_X2kLKhNq7bk67fN8TybJI-&amp;bv=1.0.0</ClickUrl>
<Extensions>
<SiteLinks>
<SiteLink>
<Text>Internet Availability</Text>
<Url>
<AppNamespace>API</AppNamespace>
<K>10</K>
<Url>http://beap.gemini.yahoo.com/cbclk?pp=n1&amp;ap=1&amp;es=BOYEnhoGIS.nxyT1HPF2S4LPnGGvQa_ejzkIGewM2lweelno4VDmZQKV1E1CAQvROkEnYzMFWU4c.oykZLf8sncbcTn09RRytPnsPIx4lJRE8EtWezY1uVrlgyfyIuqZefnUKEkqLPw6US0k23xVwmsBxVavBkdcDlYgd2Q3V5JYCC4DWPN4bpiEX5gmrraN5DiLWlk9rVA4Q7B0vM4BV7rdbE72xX_VSnQubpT_6.jnTOHVhSx3P4HdvvKWLGak6gsSMQfG1.uPW2mSgSlHAS00O28DCrS7emyb9m_ctPYKM12JZ9WbIqvg7ECqB.LTthlxkItf2Q9kapJKwifEUTjRj9fhzdQvE_5xAiUVgzJwm_qxF262tRgh3hBWCEAt4GGsE8Try8oRkBEbpCq1FHua2zmtVS.MXkJM6vhbrTIZQOSN7Iy8j3YENmRrO9TqwMKhjw7Ppvj1p5x5iICd1YtL16KtMLE8nPUSHHJwNyLTiEIoq7nIh_Ai9CqAf7hLzdwFKqf7pJq.Jfxc7XadwLrhRTswJPqo_nFLeGJ5M5wOK1lEYfluLnnwiOSKim_hIgayMUh0SUXnyKnzg_CkD3EsTnc-&amp;bv=1.0.0</Url>
</Url>
</SiteLink>
<SiteLink>
<Text>Bundles</Text>
<Url>
<AppNamespace>API</AppNamespace>
<K>11</K>
<Url>http://beap.gemini.yahoo.com/cbclk?pp=n1&amp;ap=1&amp;es=X0SgZekGIS_owYCfy4t._9hK9wK.u.T938qBllq3lLRUbMsreVt5ZnKxMrb8QzOtbU03J73QhvbEW488ujkmJpzkOHnl4qXySKlTwEuG0fVl93QSXWhUu7cxN5IWw.roxAdsNVKJNvdN5oEdwTdjJUdjONgzOGYKO8L4Cmwb.N9CDtUnWNIPy.vp_SysuID9go1cIA11RPv.TOzTervXnwrMb.IRD5pUAVRaTLQ6PfMxk.UFft69AyW3o2XYarjImro4wLX_ZCri8yhkp5N9epjn829LphKo5oY4bA5PhEm5Mg0G7q5gTbrYDBKe.DdLssrSkETO10evpR9nSexmB3_STYOH6a4HLy0Mec5cu1R.DlLf1ZpbY4AvNxvnz2JqzRfhrVAWgFXmj6bZ2myltcNNB2bv6040zg3QSEyRtzrONcZG7UdvgYKSzp0xaSVSmj8e6MTyHqvW.__c8o7hNfhyGKy65D2_BIbv94JF.TkJfsUFwxwLM5WCeeH.vyA_.TLXllkEOIjMh9cABaqPV1ndLTKyyrETIK_t88fP2zAZlUXw3G30GU4JkHxw_PeWOJVC84M4tnyFvxYjXmvg&amp;bv=1.0.0</Url>
</Url>
</SiteLink>
<SiteLink>
<Text>Compare Providers</Text>
<Url>
<AppNamespace>API</AppNamespace>
<K>12</K>
<Url>http://beap.gemini.yahoo.com/cbclk?pp=n1&amp;ap=1&amp;es=hLD9OrYGIS.sfNThhpqIZ4NZmGl80_0VHBEsj.GrqvHeBBsgIhkYEbeV0F34yn.x7Ab7mkQcxb3YLkCBZBYdU59ZxAinbusd4uqUutq.VqA4oYnhK06l806tSht5TPaLrC8ockEXeSCsXw_S8gLXE7Gt9u7CFT9jnr.9Ylmk5p_ee9afmSNjs59KV05Rf.XZadhzDmB3ABUAqC6JEYYJNZn4qXOEJkUlRs6v3tGBGWkeOYCRvaqA9kmAfjaebdPt5VqtRJU3hFiCJflsWCqsc80BDjicHosJFzcZpfb7MdB13hA5Z37oWOk6UMR_stwtN_JKsl0LUQbKwo7bY9juJq7Miesl1M1eZxoJu28sjNVpkgUy7qk7qw7kjrMti5M1iy3Qbf9W1Yp7xeX8Bw9D6sxohGQFMekJrRnb0ybpik8x8MgQizWpwP34rz09_F6rUEZoDfNXYrYjQZOvhf8.owIUVHK4ljbY_kUdcc7lHHSCF9aG.TqsZvdIXsOoZGwLl2IMnb.gbEFQZmz6GODmPevjO_sC4WgOSzHK0pQ1zAXYZu9Rc5SOGg6Km6G0Qjk.CJezB85H67mkZuhIeD6w0eHBWRFmcc21mw--&amp;bv=1.0.0</Url>
</Url>
</SiteLink>
<SiteLink>
<Text>Deals</Text>
<Url>
<AppNamespace>API</AppNamespace>
<K>13</K>
<Url>http://beap.gemini.yahoo.com/cbclk?pp=n1&amp;ap=1&amp;es=DoT35WoGIS8OfAUWD1h8QVooFPng_0AxQNIaAen.TjNkX5Xast51qQwws6LqTLbt8.N0Ur6881wF6oabTkQgtSWLd0Q9ZXykYwUrxEAtQjRTYGdTVRhspL5ZLHE1jsKWnMlOy0f2_A0WK0bvF7C4_eqDDv3Lh0wuUCcHouN5tnEXkrYacI5zslSYW.U0ii4y.ugeaVLK2Sua5JNXkH.rR0II2vPJcoAPSF0aD9OYQrYSxw88X83XuzV9VgPigf.L9XW57VX40SYYxPZKYvVtkd.Ra.muSSQpCxsLB4ul9auxKRvd69.zn5JodJndGHdBnnmPr4SvakKiyp4kxJYWgqeWpHoHRfOm6P6IFlYz0I9uAFB0vWt1EuEAdICl.PM_0mvDkcIRDx5Wo3mr7ILXIy7kYoIjsQtLKCwZGUiD4GdQcKZxnw4nb5NZjsFaCfbA1tWOQwtrAP04cEwCrlYmOTHwOHioTLTN_xljqnqYY_ZbRNQ4tpHAcrDXNaZKzAvBWhoIojcd0iEzD4gws8UbUrOXzlyCRxtYXsumFbU8o3yr5zELETb3scWaCBIsH.g9urAKd4AnNThQfl_RLQ--&amp;bv=1.0.0</Url>
</Url>
</SiteLink>
</SiteLinks>
<SiteLinkLayoutSuggest>1:1,2;2:3,4</SiteLinkLayoutSuggest>
</Extensions>
</Listing>
<Listing rank=""2"" title=""DISH® TV + Internet = $35"" description=""$19.99 TV + $14.95 Internet - Your #1 TV Service Provider"" siteHost=""PlanetDISH.com/DISH-Deals"" biddedListing=""true"" resultType=""Broad"" siteLang=""en_US"" listingLang=""en_US"" phoneNumber=""1-855-978-3474"">
<ClickUrl type=""body"">http://40000170.r.msn.com/?ld=d30i7M55Mo6l5888s855xoKTVUCUw59sA9oX8PVfIiGAZQmO7AHZcAvRK2JWI5YgLvzVlEsgFUGOxgFjbOqlXFNyeMMmZZ8NHPL0xic8iPslRXqXbYJl7nH-q1UkgO88ejaRWeY-h5fOYxEDi_Hv70aEyaE3o&amp;u=https%3a%2f%2fplanetdish.com%2fdish-deals%2f%3futm_source%3dbing%26utm_medium%3dpd-dip-cpc%26utm_campaign%3dbing-ppc-dip-key-terms-tv-providers</ClickUrl>
<Extensions>
<SiteLinks>
<SiteLink>
<Text>DISH Vs. The Competition</Text>
<Url>
<AppNamespace>API</AppNamespace>
<K>5042</K>
<Url>http://40000170.r.msn.com/?ld=d3dx-F4Z3Xuwn1C7PEjRPtEjVUCUyqZ_-VP6oNSHkoLLztqzbtbQYfO2njIZIPOGHekUVNNQCTAiWPY__kVQO8gzuuvjxGoHK7E30ARwFbhuqA4G-PlsoSsN8UKZvmfuF86mD51r6r_34Zq2yZIPQvC0p6rns&amp;u=planetdish.com%2fdish-vs-directv%2f</Url>
</Url>
</SiteLink>
<SiteLink>
<Text>Join Without A Contract</Text>
<Url>
<AppNamespace>API</AppNamespace>
<K>5044</K>
<Url>http://40000170.r.msn.com/?ld=d3Vgf90820Tf5TfQgwxdpu3zVUCUxXCqcS7Ulto9HIPqhzzuRWtPHwUij4SAi4ReERKzuXDVMmVbKeBvZNfqppj4RhiL2elP06DHHNRLKV3xfLtDul6A5d6VsMzjrThStgw7ItVnAMJ-96N_8SOUUdQXx7u5I&amp;u=planetdish.com%2fflex-tv%2f</Url>
</Url>
</SiteLink>
</SiteLinks>
<SiteLinkLayoutSuggest>1:1,2</SiteLinkLayoutSuggest>
</Extensions>
</Listing>
<Listing rank=""3"" title=""$14.95 Cable Provider"" description=""Compare Internet Providers - Increase Your Internet Speed For Less!"" siteHost=""InternetNearMe.com/CableInternet"" biddedListing=""true"" resultType=""Exact"" siteLang=""en_US"" listingLang=""en_US"" phoneNumber="""">
<ClickUrl type=""body"">http://40032899.r.msn.com/?ld=d3BDMWrPdUtUA97l-DtPyvvzVUCUxvwgvEnu2hihLaLuDZ84qxBxSUo-qFujnZIlpYnb9LoFpfVPLUKslfCCDKrRd1g2BOpOLh16e69tEHHZkw0K0M2q-P49r9jEr5IRpg-kNgoGowZ63XcdsbDjRhfMANw_w&amp;u=InternetNearMe.com</ClickUrl>
</Listing>
<NextArgs>Keywords=cable%20internet%20service%20provider&amp;xargs=12KPjg1oZpy5a3vOHvKvjFT%5FXBhg9O0JCw5Is%5FWMQaRp8L%5FXd7EbEoO92ExpctD%2DFmzz7g&amp;hData=12KPjg1o1gls79vr2vdLnITuOGxl0EnJC0%2D8kfDJR5GtVc8HZpUuh3T5Px</NextArgs>
</ResultSet>
<NextArgs>Keywords=cable%20internet%20service%20provider&amp;xargs=12KPjg1oZpy5a3vOHvKvjFT%5FXBhg9O0JCw5Is%5FWMQaRp8L%5FXd7EbEoO92ExpctD%2DFmzz7g&amp;hData=12KPjg1o1gls79vr2vdLnITuOGxl0EnJC0%2D8kfDJR5GtVc8HZpUuh3T5Px</NextArgs>
</Results>";
var listings = YahooProvider.GetListingsFromXml(xml)
.ToList();
Assert.NotNull(listings);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Serilog" publicKeyToken="24c2f752a8e58a10" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" /></startup></configuration>
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NUnit" version="3.5.0" targetFramework="net45" />
<package id="NUnitTestAdapter" version="2.0.0" targetFramework="net45" />
<package id="OctoPack" version="3.4.6" targetFramework="net45" developmentDependency="true" />
</packages>
\ No newline at end of file
using System.Web;
using System.Web.Optimization;
namespace Mobile.Search.Web
{
public class BundleConfig
{
// For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.validate*"));
// Use the development version of Modernizr to develop with and learn from. Then, when you're
// ready for production, use the build tool at http://modernizr.com to pick only the tests you need.
bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
"~/Scripts/modernizr-*"));
bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
"~/Scripts/bootstrap.js",
"~/Scripts/respond.js"));
bundles.Add(new StyleBundle("~/Content/css").Include(
"~/Content/bootstrap.css",
"~/Content/site.css"));
}
}
}
using System.Web;
using System.Web.Mvc;
using Serilog;
namespace Mobile.Search.Web
{
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new LogExceptionFilter());
filters.Add(new HandleErrorAttribute());
}
}
public class LogExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
var exception = filterContext.Exception;
Log.Error(exception, "Unhandled Error in MobSearch");
}
}
}
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using Mobile.Search.Web.Models;
namespace Mobile.Search.Web
{
public class EmailService : IIdentityMessageService
{
public Task SendAsync(IdentityMessage message)
{
// Plug in your email service here to send an email.
return Task.FromResult(0);
}
}
public class SmsService : IIdentityMessageService
{
public Task SendAsync(IdentityMessage message)
{
// Plug in your SMS service here to send a text message.
return Task.FromResult(0);
}
}
// Configure the application user manager used in this application. UserManager is defined in ASP.NET Identity and is used by the application.
public class ApplicationUserManager : UserManager<ApplicationUser>
{
public ApplicationUserManager(IUserStore<ApplicationUser> store)
: base(store)
{
}
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
// Configure validation logic for usernames
manager.UserValidator = new UserValidator<ApplicationUser>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
// Configure validation logic for passwords
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
// Configure user lockout defaults
manager.UserLockoutEnabledByDefault = true;
manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
manager.MaxFailedAccessAttemptsBeforeLockout = 5;
// Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
// You can write your own provider and plug it in here.
manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<ApplicationUser>
{
MessageFormat = "Your security code is {0}"
});
manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<ApplicationUser>
{
Subject = "Security Code",
BodyFormat = "Your security code is {0}"
});
manager.EmailService = new EmailService();
manager.SmsService = new SmsService();
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider =
new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
}
return manager;
}
}
// Configure the application sign-in manager which is used in this application.
public class ApplicationSignInManager : SignInManager<ApplicationUser, string>
{
public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager)
: base(userManager, authenticationManager)
{
}
public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user)
{
return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager);
}
public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context)
{
return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace Mobile.Search.Web
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "SearchClick",
url: "SearchClick",
defaults: new {controller = "Search", action = "SearchClick"});
routes.MapRoute(
name: "Desktop",
url: "results/desktop/{action}",
defaults: new {controller = "Desktop", action = "json"});
// well should have thought this one through more
routes.MapRoute(
name: "SeperateSystems",
url: "results/{system}/{action}",
defaults: new {controller = "Results", action = "json"});
routes.MapRoute(
name: "wordcloud",
url: "wordcloud",
defaults: new {controller = "Home", action = "WordCloud"});
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
}
using System;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.Google;
using Owin;
using Mobile.Search.Web.Models;
namespace Mobile.Search.Web
{
public partial class Startup
{
// For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context, user manager and signin manager to use a single instance per request
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
// Configure the sign in cookie
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
// Enables the application to validate the security stamp when the user logs in.
// This is a security feature which is used when you change a password or add an external login to your account.
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));
// Enables the application to remember the second login verification factor such as phone or email.
// Once you check this option, your second step of verification during the login process will be remembered on the device where you logged in from.
// This is similar to the RememberMe option when you log in.
app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);
// Uncomment the following lines to enable logging in with third party login providers
//app.UseMicrosoftAccountAuthentication(
// clientId: "",
// clientSecret: "");
//app.UseTwitterAuthentication(
// consumerKey: "",
// consumerSecret: "");
//app.UseFacebookAuthentication(
// appId: "",
// appSecret: "");
//app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
//{
// ClientId = "",
// ClientSecret = ""
//});
}
}
}
\ No newline at end of file
.pagination {
display: inline-block;
padding-left: 0;
margin: 20px 0;
border-radius: 4px;
}
.pagination > li {
display: inline;
}
.pagination > li > a,
.pagination > li > span {
position: relative;
float: left;
padding: 6px 12px;
margin-left: -1px;
line-height: 1.428571429;
text-decoration: none;
background-color: #ffffff;
border: 1px solid #dddddd;
}
.pagination > li:first-child > a,
.pagination > li:first-child > span {
margin-left: 0;
border-bottom-left-radius: 4px;
border-top-left-radius: 4px;
}
.pagination > li:last-child > a,
.pagination > li:last-child > span {
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}
.pagination > li > a:hover,
.pagination > li > span:hover,
.pagination > li > a:focus,
.pagination > li > span:focus {
background-color: #eeeeee;
}
.pagination > .active > a,
.pagination > .active > span,
.pagination > .active > a:hover,
.pagination > .active > span:hover,
.pagination > .active > a:focus,
.pagination > .active > span:focus {
z-index: 2;
color: #ffffff;
cursor: default;
background-color: #428bca;
border-color: #428bca;
}
.pagination > .disabled > span,
.pagination > .disabled > a,
.pagination > .disabled > a:hover,
.pagination > .disabled > a:focus {
color: #999999;
cursor: not-allowed;
background-color: #ffffff;
border-color: #dddddd;
}
.pagination-lg > li > a,
.pagination-lg > li > span {
padding: 10px 16px;
font-size: 18px;
}
.pagination-lg > li:first-child > a,
.pagination-lg > li:first-child > span {
border-bottom-left-radius: 6px;
border-top-left-radius: 6px;
}
.pagination-lg > li:last-child > a,
.pagination-lg > li:last-child > span {
border-top-right-radius: 6px;
border-bottom-right-radius: 6px;
}
.pagination-sm > li > a,
.pagination-sm > li > span {
padding: 5px 10px;
font-size: 12px;
}
.pagination-sm > li:first-child > a,
.pagination-sm > li:first-child > span {
border-bottom-left-radius: 3px;
border-top-left-radius: 3px;
}
.pagination-sm > li:last-child > a,
.pagination-sm > li:last-child > span {
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
}
.pager {
padding-left: 0;
margin: 20px 0;
text-align: center;
list-style: none;
}
.pager:before,
.pager:after {
display: table;
content: " ";
}
.pager:after {
clear: both;
}
.pager:before,
.pager:after {
display: table;
content: " ";
}
.pager:after {
clear: both;
}
.pager li {
display: inline;
}
.pager li > a,
.pager li > span {
display: inline-block;
padding: 5px 14px;
background-color: #ffffff;
border: 1px solid #dddddd;
border-radius: 15px;
}
.pager li > a:hover,
.pager li > a:focus {
text-decoration: none;
background-color: #eeeeee;
}
.pager .next > a,
.pager .next > span {
float: right;
}
.pager .previous > a,
.pager .previous > span {
float: left;
}
.pager .disabled > a,
.pager .disabled > a:hover,
.pager .disabled > a:focus,
.pager .disabled > span {
color: #999999;
cursor: not-allowed;
background-color: #ffffff;
}
\ No newline at end of file
body {
padding-top: 50px;
padding-bottom: 20px;
}
/* Set padding to keep content from hitting the edges */
.body-content {
padding-left: 15px;
padding-right: 15px;
}
/* Override the default bootstrap behavior where horizontal description lists
will truncate terms that are too long to fit in the left column
*/
.dl-horizontal dt {
white-space: normal;
}
/* Set width on the form input elements since they're 100% wide by default */
input,
select,
textarea {
}
/* ordered list */
ol.round {
list-style-type: none;
padding-left: 0;
}
ol.round li {
margin: 25px 0;
padding-left: 45px;
}
ol.round li.zero {
background: url("../Images/orderedList0.png") no-repeat;
}
ol.round li.one {
background: url("../Images/orderedList1.png") no-repeat;
}
ol.round li.two {
background: url("../Images/orderedList2.png") no-repeat;
}
ol.round li.three {
background: url("../Images/orderedList3.png") no-repeat;
}
ol.round li.four {
background: url("../Images/orderedList4.png") no-repeat;
}
ol.round li.five {
background: url("../Images/orderedList5.png") no-repeat;
}
ol.round li.six {
background: url("../Images/orderedList6.png") no-repeat;
}
ol.round li.seven {
background: url("../Images/orderedList7.png") no-repeat;
}
ol.round li.eight {
background: url("../Images/orderedList8.png") no-repeat;
}
ol.round li.nine {
background: url("../Images/orderedList9.png") no-repeat;
}
/* login page */
#loginForm {
border-right: solid 2px #c8c8c8;
float: left;
width: 55%;
}
#loginForm .validation-error {
display: block;
margin-left: 15px;
}
#loginForm .validation-summary-errors ul {
margin: 0;
padding: 0;
}
#loginForm .validation-summary-errors li {
display: inline;
list-style: none;
margin: 0;
}
#loginForm input {
width: 250px;
}
#loginForm input[type="checkbox"],
#loginForm input[type="submit"],
#loginForm input[type="button"],
#loginForm button {
width: auto;
}
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
/* Generic pane rules */
body { margin: 0; -webkit-text-size-adjust: 100%; }
.page { left: 0; right: 0; top: 0; bottom: 0; }
.row, .col, .page { overflow: hidden; position: absolute; }
.row { left: 0; right: 0; }
.col { top: 0; bottom: 0; }
.scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.scroll-y { overflow-y: auto; -webkit-overflow-scrolling: touch; }
.fill, .pane { position: absolute; left: 0; top: 0; right: 0; bottom: 0; width: 100%; height: 100% }
.pane { display: none; }
/* Workaround: in landscape mode, IEMobile makes bottom toolbar overlap the page, so shorten the page by 75px to compensate */
.iemobile .page { bottom: -6px; }
@media screen and (orientation:landscape) { .iemobile .page { bottom: 75px; } }
\ No newline at end of file
@import url(http://fonts.googleapis.com/css?family=Oxygen);
#container br, #container br {
clear: both;
}
#container ul, #container li, #container ul, .adk_marketplace li {
margin: 0px;
padding: 0px;
}
.sl_break {
opacity: 0 !important;
width: 4em !important;
}
.adk_re_panel {
width: 790px;
margin: auto;
height: 100%;
background-color: #fcfcfc;
}
.adk_re_second_panel {
width: 360px;
margin: auto;
height: 100%;
}
.adk_re_second_keyword_subpanel{
padding: 5px;
}
.adk_re_second_keyword_div{
margin:20px 0px 0px 0px;
}
.adk_re_second_keyword_title{
background-color:steelblue;
color:black;
padding:8px 0px 8px 12px ;
}
.adk_re_second_keyword_list{
border:1px solid steelblue;
}
.adk_re_second_keyword_list_inner{
margin:10px;
padding-left:10px;
}
.adk_marketplace_second_term{
line-height:1.7em;
}
.adk_marketplace_second_term{
color:orange;
}
.adk_re_second_keyword_list_inner li {
list-style-type: none;
padding-left: 1em;
text-indent: -.7em;
}
.adk_re_second_keyword_list_inner li:before {
content: "• ";
font-size:140%;
position:relative;
top:3px;
color: steelblue; /* or whatever color you prefer */
}
.adk_re_primary {
width: 60%;
min-width:750px !important;
}
.adk_re_secondary {
width: 32%;
display: inline-flex;
padding-left: 12px;
font-family:arial;
}
.adk_re_head {
width: 100%;
height: 3em;
background-color: #696969;
}
.adk_re_logo_left {
width: 100%;
/*float: auto;*/
height: 100%;
display: inline-block;
margin: 0px !important;
text-align:center;
background-color: #696969;
border-bottom:2px solid #000;;
color:#fff;
font-family: 'Oxygen', sans-serif;
}
.adk_re_logo_text {
display: inline-block;
margin: 1em ;
color: #fff;
}
.adk_re_logo_left:before{
content: 'Sponsored Results';
font-family: 'Oxygen', sans-serif;
text-transform: uppercase;
position:relative;
font-size:90%;
}
.adk_re_results_tag {
font-family: 'Open Sans', sans-serif;
margin: 0px 0px;
padding:10px 2px;
display: block;
width:100%;
font-size: 80%;
color: #E95432 ;
background:url(//www.missomoms.com/wp-content/themes/jarida/images/top-shadow.png) no-repeat;
background-size: contain;
}
.adk_re_siteLink {
height:120px;
width: 100%;
border-bottom: 1px solid #ddd;
list-style-type: none;
list-style: none;
margin: 0px;
padding-left: 0;
clear: both;
z-index: 100;
cursor: pointer;
}
.adk_re_second_panel a{
text-decoration:none;
color:#000;
width:100%;
}
.adk_re_second_title{
font-size:12pt;
margin:0 0 5;
color:blue;
}
.adk_re_second_desc{
font-size:11pt;
margin:0 0 5;
color:green;
}
.adk_re_second_title_desc{
font-size:11pt;
display:block;
width:100% !important;
color: darkslategray;
}
.adk_re_second_siteLink {
display:block;
padding:20px 10px;
width: 99%;
border-bottom: 1px solid #ddd;
list-style-type: none;
list-style: none;
margin: 0px;
padding-left: 0;
clear: both;
z-index: 100;
cursor: pointer;
vertical-align:middle;
}
.adk_re_second_siteLink:hover {
background-color: #ddd;
transition: background-color .25s ease-in-out;
-moz-transition: background-color .25s ease-in-out;
-webkit-transition: background-color .25s ease-in-out;
}
.ie li.adk_re_siteLink {
margin-left: -1em;
width: 1095px;
}
a.adk_re_ahref {
color: #000 !important;
text-decoration: none !important;
cursor: pointer !important;
width: 100%;
height: auto;
display: block;
padding: 0px;
background: url(http://dyn.adknowledge.com/rec_engine/assets/arrow_n.gif) no-repeat 97.5% center;
transition: background-color .25s ease-in-out;
-moz-transition: background-color .25s ease-in-out;
-webkit-transition: background-color .25s ease-in-out;
}
a.adk_re_ahref:hover {
background-color: #f0f0f0;
}
.adk_re_index {
padding-top: .25em;
width: 1.5em;
height: 85%;
text-align: center;
display: inline-block;
float: left;
vertical-align: middle;
font-weight:normal;
font:60px arial;
color:#E95432;
}
.adk_re_title_desc {
font-family: 'Proxima Nova ExCn Lt' "times new roman" serif;
font-size:30px;
display: inline-block;
width: auto;
max-width: 9950px;
z-index: 2;
height: 95%;
}
.adk_re_arrow {
padding-top: .5em;
text-align: center;
display: inline-block;
float: right;
width: 1em;
height: 75%;
color: #e24802;
vertical-align: middle;
font-size: 200%;
z-index: 4;
}
.adk_re_title {
padding-top: .75em;
font-family: Proxima Nova ExCn Lt;
font-size: 30px;
text-transform: capitalize;
}
.adk_re_desc {
font-size: 13px;
font-family: Verdana, Geneva, sans-serif;
line-height: 20px;
}
.adk_re_link_table {
width: 100%;
}
@media screen and (max-width: 1250px) {
.adk_re_primary {
width: 100%;
display: inline-flex;
margin:auto;
min-width: 750px !important;
}
.adk_re_panel{
width:90%;
}
.adk_re_secondary {
width: 100%;
display: inline-flex;
margin: auto;
margin-top:20px;
min-width: 750px !important;
padding-left: 12px;
}
.adk_re_second_panel {
width: 90%;
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
namespace Mobile.Search.Web.Controllers
{
public class AccountController : Controller
{
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
return RedirectToLocal(returnUrl);
}
// If we got this far, something failed, redisplay form
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return View(model);
}
private ActionResult RedirectToLocal(string returnUrl)
{
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
}
public class LoginModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using Mobile.Search.Providers;
using Mobile.Search.Shared;
using Serilog;
namespace Mobile.Search.Web.Controllers
{
public class BidSystemController : Controller
{
// GET: BidSystem
public ActionResult Index()
{
return View();
}
public JsonResult ClickUrl(int? categoryId, string listId, string sessionId, string ip, string ua,
string quizId, string questionId, string answerId, string userId, string questionStackId, long? publisherId, string subPublisher, int? sequence)
{
var searchqueryid = Guid.NewGuid().ToString();
var affiliateid = default(string);
// override quiz ids quick hack
if (!string.IsNullOrEmpty(quizId) && (quizId == "137" || quizId == "103" || quizId == "134" || quizId == "140" || quizId == "141" || quizId == "10141"))
{
affiliateid = "844469";
}
else
{
affiliateid = "844069";
}
var clickUrl = BidSystemProvider.GetClickUrl(searchqueryid, categoryId.ToString(), ip, affiliateid);
try
{
Tracker.TrackBidSystemSearch(new Dictionary<string, string>
{
{"timestamp", DateTime.UtcNow.ToString("O")},
{"listid", listId},
{"searchqueryid", searchqueryid},
{"categoryid", categoryId.ToString()},
{"sessionid", sessionId},
{"affiliateid", affiliateid},
{"ip", ip},
{"ua", ua},
{"quizid", quizId},
{"questionid", questionId},
{"answerid", answerId},
{"userid", userId},
{"publisherid", string.Format("{0}", publisherId)},
{"subpublisher", subPublisher},
{"sequence", string.Format("{0}", sequence)},
{"questionstackid", questionStackId},
{"clickurl", clickUrl},
});
}
catch (Exception x)
{
Log.Error(x, "Error queueing bidsystem search");
}
return Json(new
{
clickUrl = clickUrl
}, JsonRequestBehavior.AllowGet);
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Mobile.Search.Providers;
using Mobile.Search.Shared;
using Mobile.Search.Shared.Models;
using Mobile.Search.Web.Extensions;
using Mobile.Search.Web.Helpers;
using ServiceStack;
namespace Mobile.Search.Web.Controllers
{
public class DesktopController : Controller
{
private static readonly SearchUrlHelper UrlHelper = new SearchUrlHelper();
// GET: Desktop
public JsonResult Json(string sourceTag, string query, string serveUrl = null, int resultCount = 5, string ip = null, string userAgent = null, string subpub = null, bool redirect = false)
{
var searchRequest = new SearchRequest
{
BiddedResults = resultCount,
Ip = ip ?? RequestHelper.GetIp(HttpContext),
NonBiddedResults = 0,
Query = query,
ServeUrl = serveUrl ?? UrlHelper.GetAuthority(Request) + "/search",
SourceTag = sourceTag,
TypeTag = "subpub:" + (subpub ?? "") + "_kw:" + query.Replace(" ", "+"),
UseFakeUserAgent = false,
UserAgent = userAgent ?? Request.UserAgent
};
var searchResult = YahooProvider.GetListings(searchRequest);
if (redirect)
{
searchRequest.ServeUrl = UrlHelper.GetAuthority(Request) + "/search/R";
}
searchResult.ClickUrlFunc = listing => Tracker.MakeTrackerUrl(searchRequest.ServeUrl,string.Empty,new Dictionary<string, string>(), listing, searchResult);
var listings = new List<Listing>();
foreach (var listing in searchResult.Listings)
{
listing.ClickUrl = searchResult.ClickUrlFunc(listing);
listings.Add(listing);
}
return Json(listings, JsonRequestBehavior.AllowGet);
}
}
}
\ No newline at end of file
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Web.Mvc;
using Serilog;
using ServiceStack;
namespace Mobile.Search.Web.Controllers
{
public class HomeController : Controller
{
public ActionResult Index(string q)
{
//http://localhost:64292/search/template?templateKey=clean&keyword=audi+a4&debug=true
var html = default(string);
if (!string.IsNullOrEmpty(q))
{
// Very weird issue here I haven't figured out
// basically this won't work if it's pointed at mobsearch.adk-mobile.com
// the urls work fine (you can copy paste them to your browser), but the results
// never show. I tried on each of the 3 load balanced boxes, and it all works on each individual box
// but on mobsearch it won't. To fix..this just runs the template gen and search on dartmob (staging server)
// this is a terrible solution but it works...for now..
var url = "http://mobsearch.dartmob.net/Search/Template"
.AddQueryParam("templateKey", "clean")
.AddQueryParam("keyword", q)
.AddQueryParam("c", 10)
.AddQueryParam("sourceTagOverride", "adknowledge_mobile_2click_newsletter_search");
ViewBag.Url = url;
try
{
var httpClient = new HttpClient();
var t = httpClient.GetStringAsync(url);
t.Wait();
html = t.Result;
ViewBag.ExceptionBody = "No Errors";
}
catch (WebException x)
{
var stream = x.Response.GetResponseStream();
if (stream != null)
{
var streamReader = new StreamReader(stream);
Log.Error(x, "Error in searching: {body}", streamReader.ReadToEnd());
}
}
catch (Exception x)
{
ViewBag.ExceptionBody = x.Message;
Log.Error(x, "Error in searching");
}
}
return View(new SearchPageViewModel { Html = html});
}
}
public class SearchPageViewModel
{
public string Html { get; set; }
public string PixelUrl { get; set; }
public string Query { get; set; }
}
}
\ No newline at end of file
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
using Chronos;
using Mobile.Search.Shared.Extensions;
using Mobile.Search.Web.Helpers;
using ServiceStack;
namespace Mobile.Search.Web.Controllers
{
public class InboxMobiController : Controller
{
// GET: InboxMobi
public ActionResult Index(string q, string src, string uuid, string userid, string product, string pubid, string description, string view)
{
var ip = Request["ip"] ?? RequestHelper.GetIp(HttpContext);
view = string.IsNullOrEmpty(view) ? "Index" : view;
var pixelUrl =
string.Format(
"http://imp.email.adk-mobile.com/install?event=WebclipOpen&uuid={0}&product={1}&pubid={2}&src={3}&view={4}",
uuid, product, pubid, src, view);
var qStringDict = Request.QueryString.ToDictionary();
qStringDict.AddOnlyIfDoesntExist("templateKey", "yahooclone");
qStringDict.AddOnlyIfDoesntExist("keyword", q);
qStringDict.AddOnlyIfDoesntExist("uuid", uuid);
qStringDict.AddOnlyIfDoesntExist("src", src);
qStringDict.AddOnlyIfDoesntExist("product", product);
qStringDict.AddOnlyIfDoesntExist("view", view);
qStringDict.AddOnlyIfDoesntExist("c", "3");
qStringDict.AddOnlyIfDoesntExist("nbr", "10");
qStringDict.AddOnlyIfDoesntExist("sourceTagOverride", "adknowledge_mobile_2click_newsletter_search");
qStringDict.AddOnlyIfDoesntExist("strongWords", "true");
qStringDict.AddOnlyIfDoesntExist("ip", ip);
var html = default(string);
if (!string.IsNullOrEmpty(q))
{
var typeTagSuffix = string.IsNullOrEmpty(description) ? "_webclip" : "_webclip-" + description;
qStringDict.AddOnlyIfDoesntExist("typeTagSuffix", typeTagSuffix);
var url = Url.Action("Template", "Search", new RouteValueDictionary(qStringDict.ToDictionary(x => x.Key, x => (object)x.Value)), "http");
html = url.GetStringFromUrl();
}
view = string.IsNullOrEmpty(view) ? "Index" : view;
return View(view,new SearchPageViewModel { Html = html, PixelUrl = pixelUrl, Query = q});
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Amazon;
using Amazon.Runtime;
using Chronos.AWS;
using Chronos.Configuration;
using Mobile.Search.Providers;
using Mobile.Search.Shared;
using Mobile.Search.Shared.Models;
using Mobile.Search.Web.Extensions;
using Mobile.Search.Web.Helpers;
using Mobile.Search.Web.Models;
using Newtonsoft.Json.Linq;
namespace Mobile.Search.Web.Controllers
{
public class KeywordBlockController : Controller
{
private readonly Dynamo _dynamoClient;
private static readonly string AwsAccessKey = ConfigUtilities.GetAppSetting("AWSAccessKey");
private static readonly string AwsSecretKey = ConfigUtilities.GetAppSetting("AWSSecretKey");
private static readonly IUrlHelper UrlHelper = new SearchUrlHelper();
public KeywordBlockController()
{
_dynamoClient = new Dynamo(new BasicAWSCredentials(AwsAccessKey, AwsSecretKey), RegionEndpoint.USWest2);
}
public ActionResult Results(string templateKey,string sourceTag, string typeTag, string query, int resultsCount = 5,string ip = null, string userAgent = null, string clickWrapper = null)
{
var searchRequest = new SearchRequest
{
BiddedResults = resultsCount,
Ip = ip ?? RequestHelper.GetIp(HttpContext),
NonBiddedResults = 0,
Query = query,
ServeUrl = UrlHelper.GetAuthority(Request) + "/search",
SourceTag = sourceTag,
TypeTag = typeTag,
UseFakeUserAgent = false,
UserAgent = userAgent ?? Request.UserAgent
};
var searchResult = YahooProvider.GetListings(searchRequest);
searchResult.ClickUrlFunc = listing => Tracker.MakeTrackerUrl(searchRequest.ServeUrl, clickWrapper ?? string.Empty, new Dictionary<string, string>(), listing, searchResult);
var listings = new List<Listing>();
foreach (var listing in searchResult.Listings)
{
listing.ClickUrl = searchResult.ClickUrlFunc(listing);
listings.Add(listing);
}
var json = _dynamoClient.Get("prd_2click_templates", "templateKey", templateKey);
if (string.IsNullOrEmpty(json))
{
return Json(new
{
Status = "Error",
Message = "Couldn't find a template with the key: " + templateKey
}, JsonRequestBehavior.AllowGet);
}
var jsonObject = JObject.Parse(json);
var html = (string)jsonObject["html"];
if (html != null)
{
var templateVars = new TemplateVariables
{
Keyword = query
};
PopulateTemplateVarsWithListings(searchResult.Listings.ToList(), searchResult.ClickUrlFunc, ref templateVars);
var renderedTemplate = Nustache.Core.Render.StringToString(html, templateVars);
return Content(renderedTemplate);
}
return HttpNotFound("Invalid Template");
}
private void PopulateTemplateVarsWithListings(List<Listing> listings, Func<Listing, string> clickUrlFunc, ref TemplateVariables templateVars)
{
if (listings.Count > 0)
{
templateVars.Listing1Title = listings[0].Title;
templateVars.Listing1Advertiser = listings[0].SiteHost;
templateVars.Listing1Description = listings[0].Description;
templateVars.Listing1ClickUrl = clickUrlFunc(listings[0]);
}
if (listings.Count > 1)
{
templateVars.Listing2Title = listings[1].Title;
templateVars.Listing2Advertiser = listings[1].SiteHost;
templateVars.Listing2Description = listings[1].Description;
templateVars.Listing2ClickUrl = clickUrlFunc(listings[1]);
}
if (listings.Count > 2)
{
templateVars.Listing3Title = listings[2].Title;
templateVars.Listing3Advertiser = listings[2].SiteHost;
templateVars.Listing3Description = listings[2].Description;
templateVars.Listing3ClickUrl = clickUrlFunc(listings[2]);
}
if (listings.Count > 3)
{
templateVars.Listing4Title = listings[3].Title;
templateVars.Listing4Advertiser = listings[3].SiteHost;
templateVars.Listing4Description = listings[3].Description;
templateVars.Listing4ClickUrl = clickUrlFunc(listings[3]);
}
if (listings.Count > 4)
{
templateVars.Listing5Title = listings[4].Title;
templateVars.Listing5Advertiser = listings[4].SiteHost;
templateVars.Listing5Description = listings[4].Description;
templateVars.Listing5ClickUrl = clickUrlFunc(listings[4]);
}
}
}
}
\ No newline at end of file
using System.Web.Mvc;
namespace Mobile.Search.Web.Controllers
{
public class PingController : Controller
{
// GET: Ping
public void Index()
{
Response.Write("Ok");
}
}
}
\ No newline at end of file
using System.Net;
using System.Web.Mvc;
using Mobile.Search.Web.Models;
namespace Mobile.Search.Web.Controllers
{
public class QuizController : Controller
{
// GET: Quiz
public ActionResult Index()
{
var clickWrapper = Request["clickWrapper"];
ViewBag.clickWrapper = WebUtility.UrlEncode(clickWrapper);
return View();
}
public ActionResult Marry()
{
var clickWrapper = Request["clickWrapper"];
ViewBag.clickWrapper = WebUtility.UrlEncode(clickWrapper);
return View();
}
public ActionResult Fake()
{
var clickWrapper = Request["clickWrapper"];
ViewBag.clickWrapper = WebUtility.UrlEncode(clickWrapper);
return View();
}
public ActionResult Stalker()
{
var clickWrapper = Request["clickWrapper"];
ViewBag.clickWrapper = WebUtility.UrlEncode(clickWrapper);
return View();
}
public ActionResult Stalker2(string clickWrapper)
{
ViewBag.clickWrapper = WebUtility.UrlEncode(clickWrapper);
return View("Stalker");
}
public ActionResult PerfectMatch()
{
var clickWrapper = Request["clickWrapper"];
ViewBag.clickWrapper = WebUtility.UrlEncode(clickWrapper);
return View();
}
public ActionResult Fitness2()
{
var clickWrapper = Request["clickWrapper"];
ViewBag.clickWrapper = WebUtility.UrlEncode(clickWrapper);
return View();
}
public ActionResult Image()
{
var clickWrapper = Request["clickWrapper"];
ViewBag.clickWrapper = WebUtility.UrlEncode(clickWrapper);
return View();
}
public ActionResult SeductionMaster()
{
var clickWrapper = Request["clickWrapper"];
ViewBag.clickWrapper = WebUtility.UrlEncode(clickWrapper);
return View();
}
public ActionResult Test()
{
var clickWrapper = Request["clickWrapper"];
ViewBag.clickWrapper = WebUtility.UrlEncode(clickWrapper);
return View();
}
public ActionResult MarryContent()
{
var clickWrapper = Request["clickWrapper"];
ViewBag.clickWrapper = WebUtility.UrlEncode(clickWrapper);
return View();
}
public ActionResult SpiritAnimal()
{
var clickWrapper = Request["clickWrapper"];
ViewBag.clickWrapper = WebUtility.UrlEncode(clickWrapper);
return View();
}
public ActionResult SpiritAnimalExpanded()
{
var clickWrapper = Request["clickWrapper"];
ViewBag.clickWrapper = WebUtility.UrlEncode(clickWrapper);
return View();
}
public ActionResult SpiritAnimal2()
{
var clickWrapper = Request["clickWrapper"];
ViewBag.clickWrapper = WebUtility.UrlEncode(clickWrapper);
return View();
}
public ActionResult SpiritAnimalContent()
{
var clickWrapper = Request["clickWrapper"];
ViewBag.clickWrapper = WebUtility.UrlEncode(clickWrapper);
return View();
}
public ActionResult Image2()
{
var clickWrapper = Request["clickWrapper"];
ViewBag.clickWrapper = WebUtility.UrlEncode(clickWrapper);
return View();
}
public ActionResult Fake2()
{
var clickWrapper = Request["clickWrapper"];
ViewBag.clickWrapper = WebUtility.UrlEncode(clickWrapper);
return View();
}
public ActionResult SeductionMaster2()
{
var clickWrapper = Request["clickWrapper"];
ViewBag.clickWrapper = WebUtility.UrlEncode(clickWrapper);
return View();
}
public ActionResult Career()
{
var clickWrapper = Request["clickWrapper"];
ViewBag.clickWrapper = WebUtility.UrlEncode(clickWrapper);
return View();
}
public ActionResult AirHead()
{
var clickWrapper = Request["clickWrapper"];
ViewBag.clickWrapper = WebUtility.UrlEncode(clickWrapper);
return View();
}
public ActionResult Vacation()
{
var clickWrapper = Request["clickWrapper"];
ViewBag.clickWrapper = WebUtility.UrlEncode(clickWrapper);
return View();
}
public ActionResult Cheat()
{
QuizQuestion aQuestion=new QuizQuestion();
aQuestion.QuestionOrder = 1;
aQuestion.QuestionText = "Caught him cheating before?";
aQuestion.IsTrigger = false;
aQuestion.TriggerKeyword = "";
var clickWrapper = Request["clickWrapper"];
ViewBag.clickWrapper = WebUtility.UrlEncode(clickWrapper);
return View();
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web.Mvc;
using Amazon;
using Amazon.Runtime;
using Chronos.AWS;
using Chronos.Configuration;
using Mobile.Search.Providers;
using Mobile.Search.Shared;
using Mobile.Search.Shared.Extensions;
using Mobile.Search.Shared.Models;
using Mobile.Search.Web.Extensions;
using Mobile.Search.Web.Helpers;
using Mobile.Search.Web.Models;
using Newtonsoft.Json.Linq;
namespace Mobile.Search.Web.Controllers
{
public class ResultsController : Controller
{
private static readonly IUrlHelper UrlHelper = new SearchUrlHelper();
private static readonly string AWSAccessKey = ConfigUtilities.GetAppSetting("AWSAccessKey");
private static readonly string AWSSecretKey = ConfigUtilities.GetAppSetting("AWSSecretKey");
// GET: /results/{system}/json
public ActionResult Json(JsonRequest resultsRequest)
{
var errorResponse = VerifyRequest(resultsRequest);
if (errorResponse != null)
{
return Json(errorResponse, JsonRequestBehavior.AllowGet);
}
var sourceTag = GetSourceTag(resultsRequest.System, resultsRequest.SourceTagId);
var typeTag = MakeD2STypeTag(resultsRequest.QuizId, resultsRequest.PubId, resultsRequest.SubPub,
resultsRequest.Keyword, resultsRequest.TypeTagSuffix);
var searchRequest = new SearchRequest
{
BiddedResults = 5,
Ip = resultsRequest.Ip ?? RequestHelper.GetIp(HttpContext),
NonBiddedResults = 0,
Query = resultsRequest.Keyword,
ServeUrl = UrlHelper.GetAuthority(Request) + "/search",
SourceTag = sourceTag,
Timestamp = DateTime.UtcNow,
UseFakeUserAgent = false,
TypeTag = typeTag,
UserAgent = resultsRequest.UserAgent ?? Request.UserAgent,
};
var searchResults = YahooProvider.GetListings(searchRequest);
var requestDict = Request.QueryString.ToDictionary();
var debug = requestDict["debug"];
bool isDebug = false;
if (!string.IsNullOrEmpty(debug) && debug == "true") isDebug = true;
Tracker.TrackSearch(searchRequest, searchResults, requestDict, isDebug);
searchResults.ClickUrlFunc = listing => Tracker.MakeTrackerUrl(searchRequest.ServeUrl,
resultsRequest.ClickWrapper, requestDict, listing, searchResults);
var templateVars = new TemplateVariables
{
Footer = "",
Hotspot = "",
Keyword = resultsRequest.Keyword,
};
PopulateTemplateVarsWithListings(searchResults.Listings.ToList(),
searchResults.ClickUrlFunc, ref templateVars);
var dynamoClient = new Dynamo(new BasicAWSCredentials(AWSAccessKey, AWSSecretKey), RegionEndpoint.USWest2);
var json = dynamoClient.Get("prd_2click_templates", "templateKey", resultsRequest.TemplateKey);
if (string.IsNullOrEmpty(json))
{
return Json(new
{
Status = "Error",
Message = "Couldn't find a template with the key: " + resultsRequest.TemplateKey
}, JsonRequestBehavior.AllowGet);
}
var jsonObject = JObject.Parse(json);
var html = (string)jsonObject["html"];
if (html != null)
{
var renderedTemplate = Nustache.Core.Render.StringToString(html, templateVars);
return Json(new
{
Status = "Success",
Html = renderedTemplate,
ResultsCount = searchResults.Listings != null && searchResults.Listings.Any()
? searchResults.Listings.Count()
: 0,
SourceTag = searchResults.SourceTag,
TypeTag = searchResults.TypeTag
}, JsonRequestBehavior.AllowGet);
}
return Json(new
{
Status = "Error",
Message = "No html found within the template: " + resultsRequest.TemplateKey
}, JsonRequestBehavior.AllowGet);
}
private string MakeD2STypeTag(int quizId, int pubId, string subPub, string keyword, string typeTagSuffix)
{
return string.Format("qu:{0}_pub:{1}_subpub:{2}_kw:{3}", quizId, pubId, subPub, keyword) + (typeTagSuffix ?? "");
}
private void PopulateTemplateVarsWithListings(List<Listing> listings, Func<Listing,string> clickUrlFunc, ref TemplateVariables templateVars)
{
if (listings.Count > 0)
{
templateVars.Listing1Title = listings[0].Title;
templateVars.Listing1Advertiser = listings[0].SiteHost;
templateVars.Listing1Description = listings[0].Description;
templateVars.Listing1ClickUrl = clickUrlFunc(listings[0]);
}
if (listings.Count > 1)
{
templateVars.Listing2Title = listings[1].Title;
templateVars.Listing2Advertiser = listings[1].SiteHost;
templateVars.Listing2Description = listings[1].Description;
templateVars.Listing2ClickUrl = clickUrlFunc(listings[1]);
}
if (listings.Count > 2)
{
templateVars.Listing3Title = listings[2].Title;
templateVars.Listing3Advertiser = listings[2].SiteHost;
templateVars.Listing3Description = listings[2].Description;
templateVars.Listing3ClickUrl = clickUrlFunc(listings[2]);
}
if (listings.Count > 3)
{
templateVars.Listing4Title = listings[3].Title;
templateVars.Listing4Advertiser = listings[3].SiteHost;
templateVars.Listing4Description = listings[3].Description;
templateVars.Listing4ClickUrl = clickUrlFunc(listings[3]);
}
if (listings.Count > 4)
{
templateVars.Listing5Title = listings[4].Title;
templateVars.Listing5Advertiser = listings[4].SiteHost;
templateVars.Listing5Description = listings[4].Description;
templateVars.Listing5ClickUrl = clickUrlFunc(listings[4]);
}
}
private string GetSourceTag(string system, int sourceTagid)
{
var st = SourceTagMappingHelper.Instance.GetSourceTagMappings(sourceTagid, system);
if (st == null || st.Status == 0)
{
return "adknowledge_search";
}
return st.SourceTag;
}
private object VerifyRequest(JsonRequest resultsRequest)
{
bool valid = true;
List<string> errorMessages = new List<string>();
if (resultsRequest.Keyword == default(string))
{
valid = false;
errorMessages.Add("Keyword parameter not specified");
}
if (resultsRequest.PubId == default(int))
{
valid = false;
errorMessages.Add("PubId parameter not specifiied");
}
if (resultsRequest.QuizId == default(int))
{
valid = false;
errorMessages.Add("QuizId parameter not specifiied");
}
if (resultsRequest.SourceTagId == default(int))
{
valid = false;
errorMessages.Add("SourceTagId parameter not specifiied");
}
if (resultsRequest.TemplateKey == default(string))
{
valid = false;
errorMessages.Add("TemplateKey parameter not specifiied");
}
if (resultsRequest.SubPub == default(string))
{
valid = false;
errorMessages.Add("SubPub parameter not specified");
}
if (!valid)
{
return new
{
Status = "Error",
Message = string.Join("\n", errorMessages)
};
}
return null;
}
}
/// <summary>
/// results/{system}/{outputFormat}
/// http://mobsearch.adk-mobile/results/d2s/json
/// </summary>
public class JsonRequest
{
public string System { get; set; }
[Required]
public string Keyword { get; set; }
[Required]
public int PubId { get; set; }
[Required]
public string SubPub { get; set; }
[Required]
public int SourceTagId { get; set; }
[Required]
public int QuizId { get; set; }
[Required]
public string TemplateKey { get; set; }
public string ClickWrapper { get; set; }
public string TypeTagSuffix { get; set; }
public string Ip { get; set; }
public string UserAgent { get; set; }
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc;
using Mobile.Search.Providers;
using Mobile.Search.Shared;
using Mobile.Search.Shared.Models;
using Mobile.Search.Web.Extensions;
using Mobile.Search.Web.Helpers;
using ServiceStack;
using Serilog;
namespace Mobile.Search.Web.Controllers
{
public class TestController : Controller
{
private static readonly IUrlHelper urlHelper = new SearchUrlHelper();
// GET: Test
public ActionResult CssTarget()
{
return View();
}
public ActionResult Debt(string quizId, string questionId, string userId, string sessionId)
{
return Redirect(BidSystemProvider.GetResults(quizId, questionId, userId, sessionId, "24044"));
}
public ActionResult BidSystemClick(string quizId, string questionId, string userId, string sessionId,
string listid)
{
return Redirect(BidSystemProvider.GetResults(quizId, questionId, userId, sessionId, listid));
}
public ActionResult TwoClickCustom(string keyword, string clickWrapper = null, string firstClickWrapper = null,
string footer = null, string templateKey = null)
{
clickWrapper = clickWrapper ?? "";
if (!footer.IsNullOrEmpty())
{
try
{
ViewBag.FooterHtml = Encoding.UTF8.GetString(Convert.FromBase64String(footer));
}
catch (Exception x)
{
Log.Error("Error " + x);
}
}
var req = new SearchRequest
{
BiddedResults = 5,
NonBiddedResults = 0,
Ip = RequestHelper.GetIp(HttpContext),
Query = HttpUtility.UrlDecode(keyword),
ServeUrl = urlHelper.GetAuthority(Request) + "/search",
SourceTagId = 1,
TypeTag = keyword,
UserAgent = Request.UserAgent,
Timestamp = DateTime.UtcNow,
// Always fake user agent for now
UseFakeUserAgent = true
};
var firstResult = YahooProvider.GetListings(req).Listings.FirstOrDefault();
var clickUrl = "/search/template?keyword=" + WebUtility.UrlEncode(keyword) +
"&templateKey=" + WebUtility.UrlEncode(templateKey) + "&subid=customtemplate&clickWrapper=" + WebUtility.UrlEncode(clickWrapper);
//firstClickWrapper = firstClickWrapper;
var result = new SearchResult
{
UserAgent = Request.UserAgent,
ClickUrlFunc = x => firstClickWrapper != null
? Regex.Replace(firstClickWrapper, "{URL}", WebUtility.UrlEncode(urlHelper.GetAuthority(Request) + x.ClickUrl))
: clickUrl,
Ip = RequestHelper.GetIp(HttpContext),
Listings = new List<Listing>
{
new Listing
{
BiddedListing = true,
ClickUrl = clickUrl,
Description = (firstResult != null) ? firstResult.Description : "No results could be found",
Rank = 1,
SiteHost = (firstResult != null) ? firstResult.SiteHost : "",
Title = (firstResult != null) ? firstResult.Title : "",
}
},
ListingsCount = 1,
};
return View("GoogleSingle", result);
}
public ActionResult TwoClickYahoo(string keyword, string clickWrapper = null, string firstClickWrapper = null, string footer = null)
{
clickWrapper = clickWrapper ?? "";
if (!footer.IsNullOrEmpty())
{
try
{
ViewBag.FooterHtml = Encoding.UTF8.GetString(Convert.FromBase64String(footer));
}
catch (Exception x)
{
Log.Error("Error " + x);
}
}
var req = new SearchRequest
{
BiddedResults = 5,
NonBiddedResults = 0,
Ip = RequestHelper.GetIp(HttpContext),
Query = HttpUtility.UrlDecode(keyword),
ServeUrl = urlHelper.GetAuthority(Request) + "/search",
SourceTagId = 1,
TypeTag = keyword,
UserAgent = Request.UserAgent,
Timestamp = DateTime.UtcNow,
// Always fake user agent for now
UseFakeUserAgent = true
};
var firstResult = YahooProvider.GetListings(req).Listings.FirstOrDefault();
var clickUrl = "/search/frame?keyword=" + WebUtility.UrlEncode(keyword) +
"&layout=google&subid=legal_2click&type=1&clickWrapper=" + WebUtility.UrlEncode(clickWrapper);
//firstClickWrapper = firstClickWrapper;
var result = new SearchResult
{
UserAgent = Request.UserAgent,
ClickUrlFunc = x => firstClickWrapper != null
? Regex.Replace(firstClickWrapper, "{URL}", WebUtility.UrlEncode(urlHelper.GetAuthority(Request) + x.ClickUrl))
: clickUrl,
Ip = RequestHelper.GetIp(HttpContext),
Listings = new List<Listing>
{
new Listing
{
BiddedListing = true,
ClickUrl = "/search/frame?keyword=" + WebUtility.UrlEncode(keyword) + "&layout=google&subid=legal_2click&type=1&clickWrapper=" + WebUtility.UrlEncode(clickWrapper),
Description = (firstResult != null) ? firstResult.Description : "No results could be found",
Rank = 1,
SiteHost = (firstResult != null) ? firstResult.SiteHost : "",
Title = (firstResult != null) ? firstResult.Title : "",
}
},
ListingsCount = 1,
};
return View("GoogleSingle", result);
}
public ActionResult Legal(string clickWrapper = null,string firstClickWrapper = null, string footer = null)
{
clickWrapper = clickWrapper ?? "";
if (!footer.IsNullOrEmpty())
{
try
{
ViewBag.FooterHtml = Encoding.UTF8.GetString(Convert.FromBase64String(footer));
}
catch (Exception x)
{
Log.Error("Error " + x);
}
}
var result = new SearchResult
{
UserAgent = Request.UserAgent,
ClickUrlFunc = x => Regex.Replace(firstClickWrapper, "{URL}", WebUtility.UrlEncode(urlHelper.GetAuthority(Request) + x.ClickUrl)),
Ip = RequestHelper.GetIp(HttpContext),
Listings = new List<Listing>
{
new Listing
{
BiddedListing = true,
ClickUrl = "/search/frame?keyword=personal%2Binjury%2Blawyer&layout=google&subid=legal_2click&type=1&clickWrapper=" + WebUtility.UrlEncode(clickWrapper),
Description = "Click and explore your options",
Rank = 1,
SiteHost = "Seeking Legal Advice?",
Title = "Get Help Finding An Attorney!",
}
},
ListingsCount = 1,
};
var secondClick = result.ClickUrlFunc(result.Listings.First());
return View("GoogleSingle", result);
}
public ActionResult CheckboxHack()
{
return View();
}
}
}
\ No newline at end of file
using System.Web.Mvc;
using Mobile.Search.Providers;
using Mobile.Search.Web.Helpers;
namespace Mobile.Search.Web.Controllers
{
public class UserStatsController : Controller
{
// GET: UserStats
public ActionResult Index(string uuid)
{
return Json(RedisHelper.GetLastKeywords(uuid), JsonRequestBehavior.AllowGet);
}
public ActionResult UserRelatedKeywords(string uuid)
{
var result = new
{
opens_related = KeywordBlockHelper.GetRelatedLastOpenedKeywords(uuid),
clicks_related = KeywordBlockHelper.GetRelatedLastClickedKeywords(uuid),
related = KeywordBlockHelper.GetKeywordsForUser(uuid)
};
return Json(result, JsonRequestBehavior.AllowGet);
}
public ActionResult RelatedKeywords(string keyword)
{
var result = new
{
related = YahooProvider.GetRelatedKeywords(keyword)
};
return Json(result, JsonRequestBehavior.AllowGet);
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
namespace Mobile.Search.Web.Controllers
{
public class WebClipController : Controller
{
private readonly HttpClient _httpClient;
public WebClipController()
{
_httpClient = new HttpClient();
}
// GET: WebClip
public async Task<ActionResult> Index(string uuid, string user_class,int? pubid,int? product, string src,string city, string state, string postal_code, string variation = "1")
{
uuid = WebUtility.UrlEncode(uuid);
user_class = WebUtility.UrlEncode(user_class);
src = WebUtility.UrlEncode(src);
city = WebUtility.UrlEncode(city);
state = WebUtility.UrlEncode(state);
postal_code = WebUtility.UrlEncode(postal_code);
variation = WebUtility.UrlEncode(variation);
var pixelUrl =
$"http://imp.email.adk-mobile.com/install?event=WebclipRedirect&uuid={uuid}&product={product}&pubid={pubid}&source={src}&variation={variation}&user_class={user_class}&city={city}&state={state}&postal_code={postal_code}";
await _httpClient.GetAsync(pixelUrl);
return Redirect("https://yahoo.com");
}
}
}
\ No newline at end of file
using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc;
using ServiceStack;
namespace Mobile.Search.Web.Extensions
{
public static class HtmlExtensions
{
public static HtmlString BoldQuery(this string text, string queryText)
{
var words = queryText.Split(new[] {' '})
.Select(x => x.ToLower())
.ToArray();
if (queryText.ContainsAny(words))
{
foreach (var word in words)
{
text = Regex.Replace(text, @"\b" + word + @"\b", delegate(Match match)
{
string v = match.ToString();
return "<strong>" + v + "</strong>";
},RegexOptions.IgnoreCase);
}
}
return new HtmlString(text);
}
public static HtmlString GetStateClass(this HtmlHelper helper, string activeKeyword, string keyword)
{
activeKeyword = activeKeyword.Replace(" ", "+");
keyword = keyword.Replace(" ", "+");
if (String.Equals(activeKeyword, keyword, StringComparison.CurrentCultureIgnoreCase))
{
return new HtmlString("active");
}
return new HtmlString("inactive");
}
}
}
\ No newline at end of file
using System;
using System.Web;
using Mobile.Search.Shared;
namespace Mobile.Search.Web.Extensions
{
public static class UrlHelperExtensions
{
public static string GetAuthority(this IUrlHelper urlHelper, HttpRequestBase request)
{
if (request != null && request.Url != null)
{
return request.Url.GetLeftPart(UriPartial.Authority);
}
return string.Empty;
}
}
}
\ No newline at end of file
using ImageMagick;
using System;
using System.IO;
#if netcore
using Microsoft.AspNetCore.Http;
#else
using System.Web;
#endif
namespace FroalaEditor
{
/// <summary>
/// File functionality.
/// </summary>
public static class File
{
/// <summary>
/// Content type string used in http multipart.
/// </summary>
public static string MultipartContentType = "multipart/form-data";
/// <summary>
/// File default options.
/// </summary>
public static FileOptions defaultOptions = new FileOptions();
/// <summary>
/// Check http request content type.
/// </summary>
/// <returns>true if content type is multipart.</returns>
public static bool CheckContentType(HttpContext httpContext)
{
bool isMultipart = httpContext.Request.ContentType.StartsWith(MultipartContentType);
return isMultipart;
}
/// <summary>
/// Uploads a file to disk.
/// </summary>
/// <param name="httpContext">The HttpContext object containing information about the request.</param>
/// <param name="fileRoute">Server route where the file will be uploaded. This route must be public to be accesed by the editor.</param>
/// <param name="options">File options.</param>
/// <returns>Object with link.</returns>
public static object Upload(HttpContext httpContext, string fileRoute, FileOptions options = null)
{
// Use default file options.
if (options == null)
{
options = defaultOptions;
}
if (!CheckContentType(httpContext))
{
throw new Exception("Invalid contentType. It must be " + MultipartContentType);
}
var httpRequest = httpContext.Request;
int filesCount = 0;
#if netcore
filesCount = httpRequest.Form.Files.Count;
#else
filesCount = httpRequest.Files.Count;
#endif
if (filesCount == 0)
{
throw new Exception("No file found");
}
// Get HTTP posted file based on the fieldname.
#if netcore
var file = httpRequest.Form.Files.GetFile(options.Fieldname);
#else
var file = httpRequest.Files.Get(options.Fieldname);
#endif
if (file == null)
{
throw new Exception("Fieldname is not correct. It must be: " + options.Fieldname);
}
// Generate Random name.
string extension = Utils.GetFileExtension(file.FileName);
string name = Utils.GenerateUniqueString() + "." + extension;
string link = fileRoute + name;
// Create directory if it doesn't exist.
FileInfo dir = new FileInfo(fileRoute);
dir.Directory.Create();
// Copy contents to memory stream.
Stream stream;
#if netcore
stream = new MemoryStream();
file.CopyTo(stream);
stream.Position = 0;
#else
stream = file.InputStream;
#endif
String serverPath = File.GetAbsoluteServerPath(link);
// Save file to disk.
Save(stream, serverPath, options);
// Check if the file is valid.
if (options.Validation != null && !options.Validation.Check(serverPath, file.ContentType))
{
// Delete file.
Delete(serverPath);
throw new Exception("File does not meet the validation.");
}
// Make sure it is compatible with ASP.NET Core.
return new { link = link.Replace("wwwroot/", "") };
}
/// <summary>
/// Get absolute server path.
/// </summary>
/// <param name="path">Relative path.</param>
/// <returns>Absolute path.</returns>
public static String GetAbsoluteServerPath(string path)
{
#if netcore
return path;
#else
return HttpContext.Current.Server.MapPath(path);
#endif
}
/// <summary>
/// Save an input file stream to disk.
/// </summary>
/// <param name="fileStream">Input file stream</param>
/// <param name="link">Server file path.</param>
/// <param name="options">File options.</param>
public static void Save(Stream fileStream, string filePath, FileOptions options)
{
if (options is ImageOptions && ((ImageOptions)options).ResizeGeometry != null)
{
// Resize file and save it..
MagickImage image = new MagickImage(fileStream);
image.Resize(((ImageOptions)options).ResizeGeometry);
image.Write(filePath);
}
else
{
// Save file to disk.
Console.WriteLine(filePath);
FileStream writerfileStream = System.IO.File.Create(filePath);
fileStream.CopyTo(writerfileStream);
writerfileStream.Dispose();
}
}
/// <summary>
/// Delete a file from disk.
/// </summary>
/// <param name="src">Server file path.</param>
public static void Delete(string filePath)
{
#if netcore
filePath = "wwwroot/" + filePath;
#else
filePath = File.GetAbsoluteServerPath(filePath);
#endif
// Will throw an exception if an error occurs.
if (System.IO.File.Exists(filePath))
{
System.IO.File.Delete(filePath);
}
}
}
}

namespace FroalaEditor
{
/// <summary>
/// File Options used for uploading.
/// </summary>
public class FileOptions
{
public static string FieldnameDefault = "file";
/// <summary>
/// Tag name that points to the file.
/// </summary>
public string Fieldname { get; set; }
/// <summary>
/// File validation.
/// </summary>
public FileValidation Validation { get; set; }
/// <summary>
/// Init default file upload settings.
/// </summary>
protected virtual void initDefault()
{
Validation = new FileValidation();
}
/// <summary>
/// Constructor.
/// </summary>
public FileOptions()
{
// Set default fieldname.
Fieldname = FieldnameDefault;
// Init default settings.
initDefault();
}
}
}
using System;
using System.Linq;
namespace FroalaEditor
{
/// <summary>
/// File Validation.
/// </summary>
public class FileValidation
{
/// <summary>
/// Allowed file validation default extensions.
/// </summary>
public static string[] AllowedFileExtsDefault = new string[] { "txt", "pdf", "doc" };
/// <summary>
/// Allowed file validation default mimetypes.
/// </summary>
public static string[] AllowedFileMimetypesDefault = new string[] { "text/plain", "application/msword", "application/x-pdf", "application/pdf" };
/// <summary>
/// Allowed validation extensions.
/// </summary>
protected string[] AllowedExts { get; set; }
/// <summary>
/// Allowed validation mimetypes.
/// </summary>
protected string[] AllowedMimeTypes { get; set; }
/// <summary>
/// Custom function used or validation.
/// </summary>
protected Func<string, string, bool> Function { get; set; }
/// <summary>
/// Init default file validation settings.
/// </summary>
protected virtual void initDefault()
{
AllowedExts = AllowedFileExtsDefault;
AllowedMimeTypes = AllowedFileMimetypesDefault;
}
/// <summary>
/// Constructor.
/// </summary>
public FileValidation()
{
initDefault();
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="allowedExts">Allowed validation file extensions.</param>
/// <param name="allowedMimeTypes">Allowed validation file mimetypes.</param>
public FileValidation(string[] allowedExts, string[] allowedMimeTypes)
{
initDefault();
if (allowedExts != null)
{
AllowedExts = allowedExts;
}
if (allowedMimeTypes != null)
{
AllowedMimeTypes = allowedMimeTypes;
}
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="function">Custom function used for validation.</param>
public FileValidation(Func<string, string, bool> function)
{
initDefault();
this.Function = function;
}
/// <summary>
/// Check if file is valid.
/// Use only the custom function if provided. Else check if the file has an allowed extension and mimetype.
/// </summary>
/// <param name="filePath">File path.</param>
/// <param name="mimeType">File mimetype.</param>
/// <returns></returns>
public bool Check(string filePath, string mimeType)
{
if (Function != null)
{
return Function(filePath, mimeType);
}
return AllowedExts.Contains(Utils.GetFileExtension(filePath)) && AllowedMimeTypes.Contains(mimeType.ToLower());
}
}
}
using System;
namespace FroalaEditor
{
}
<?xml version="1.0"?>
<package >
<metadata>
<id>FroalaEditorSDK</id>
<version>1.0.0</version>
<title>Froala WYSIWYG Editor SDK</title>
<authors>Froala Labs</authors>
<owners>Froala</owners>
<licenseUrl>https://github.com/froala/wysiwyg-editor-dotnet-sdk/blob/master/LICENSE</licenseUrl>
<projectUrl>https://github.com/froala/wysiwyg-editor-dotnet-sdk</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Ease server integration of the Froala WYSIWYG HTML Editor.</description>
<copyright>Copyright 2016</copyright>
<tags>froala wysiwyg html editor richt text editor image upload</tags>
<dependencies>
<group>
<dependency id="RouteMagic" version="1.1.0" />
</group>
<group targetFramework="net452">
<dependency id="Magick.NET-Q16-AnyCPU" version="7.0.3.502" />
</group>
<group targetFramework="netstandard1.3">
<dependency id="Magick.NET.Core-Q16" version="7.0.3.502" />
<dependency id="Newtonsoft.Json" version="9.0.1" />
<dependency id="Microsoft.AspNet.WebUtilities"/>
<dependency id="Microsoft.AspNetCore.Https" version="1.0.0" />
<dependency id="Microsoft.AspNet.StaticFiles" />
<dependency id="Microsoft.AspNetCore.Hosting" version="1.0.0" />
<dependency id="NETStandard.Library" version="1.6.1" />
</group>
</dependencies>
</metadata>
<files>
<file src="bin\Debug\net452\FroalaEditorSDK.dll" target="lib\net452\FroalaEditorSDK.dll" />
<file src="bin\Debug\netstandard1.3\FroalaEditorSDK.dll" target="lib\netstandard1.3\FroalaEditorSDK.dll" />
</files>
</package>
\ No newline at end of file
<%@ Application Codebehind="Global.asax.cs" Inherits="Mobile.Search.Web.MvcApplication" Language="C#" %>
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Mobile.Search.Web.Helpers;
using Serilog;
using Serilog.Events;
using StatsdClient;
namespace Mobile.Search.Web
{
public class MvcApplication : System.Web.HttpApplication
{
public static string InstanceId;
private static void ConfigureLogger()
{
InstanceId = GetInstanceId();
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Verbose()
//Sinks
.WriteTo.RollingFile(ConfigurationManager.AppSettings.Get("LogPath"))
.WriteTo.Seq("http://ec2-52-90-180-25.compute-1.amazonaws.com:5341", LogEventLevel.Verbose)
//Enrichers
.Enrich.WithProperty("AppName", "MobSearch Web")
#if DEBUG
.Enrich.WithProperty("Env", "dev")
#else
.Enrich.WithProperty("Env", "prd")
#endif
.Enrich.WithProperty("InstanceId", InstanceId)
.Enrich.WithEnvironmentUserName()
.Enrich.WithMachineName()
.CreateLogger();
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
ConfigureLogger();
JobScheduler.Start();
var prefix = "search." + Environment.MachineName + "." + GetInstanceId();
var metricsConfig = new MetricsConfig
{
StatsdServerName = ConfigurationManager.AppSettings["StatsDServer"],
Prefix = prefix
};
Metrics.Configure(metricsConfig);
Log.Information("Application Started");
}
protected void Application_BeginRequest()
{
HttpContext.Current.Items["Stopwatch"] = System.Diagnostics.Stopwatch.StartNew();
}
protected void Application_EndRequest()
{
try
{
if (InstanceId == "NotEc2")
return;
var endpoint = HttpContext.Current.Request.Url.AbsolutePath;
var sw = (System.Diagnostics.Stopwatch) HttpContext.Current.Items["Stopwatch"];
if (sw == null) return;
sw.Stop();
RedisHelper.AddRequestTime(endpoint, sw.Elapsed.TotalMilliseconds);
}
catch (Exception x)
{
Log.Error(x, "Error loading request time to redis");
}
}
static string GetInstanceId()
{
const string endpoint = "http://169.254.169.254/latest/meta-data/instance-id";
var client = new TimedWebClient() { Timeout = 500};
try
{
return client.DownloadString(endpoint);
}
catch
{
return "NotEc2";
}
}
protected void Application_Error(Object sender, EventArgs e)
{
var exception = Server.GetLastError().GetBaseException();
if (exception is HttpException)
{
var httpEx = exception as HttpException;
try
{
if (httpEx?.GetHttpCode() == 404)
{
return;
}
}
catch
{
Log.Error(exception, "Uncaught exception {ExceptionType}", exception.GetType().Name);
}
try
{
Log.Error(httpEx, "Unhandled HTTP Exception. Path={Path} QueryString={QueryString}", Request.Path,
Request.QueryString.AllKeys.Distinct().ToDictionary(x => x, x => Request.QueryString[x]));
}
catch (Exception x)
{
Log.Error(x, "Error logging exception {ex}", httpEx.Message);
}
}
else
{
Log.Error(exception, "Uncaught exception {ExceptionType}", exception.GetType().Name);
}
}
}
public class TimedWebClient : WebClient
{
// Timeout in milliseconds, default = 600,000 msec
public int Timeout { get; set; }
public TimedWebClient()
{
this.Timeout = 600000;
}
protected override WebRequest GetWebRequest(Uri address)
{
var objWebRequest = base.GetWebRequest(address);
objWebRequest.Timeout = this.Timeout;
return objWebRequest;
}
}
}
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
No preview for this file type
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
No preview for this file type
No preview for this file type
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment