Google Cell Tower Location API: Changed? - reverse-geocoding

For the last few months I've been finding the locations of cell towers as we use their cellid and areaid, based on the following code:
public class GoogleService
{
public GoogleCell GetCellInfo(string lac, string mnc, string mcc, string cellID)
{
try
{
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create("https://www.google.com/loc/json");
myReq.Method = "POST";
myReq.ContentType = "application/jsonrequest";
string postData = "{\"cell_towers\": [{\"location_area_code\": \"" + lac + "\", \"mobile_network_code\": \"" + mnc + "\", \"cell_id\": \"" + cellID + "\", \"mobile_country_code\": \"" + mcc + "\"}], \"version\": \"1.1.0\", \"request_address\": \"true\"}";
myReq.ContentLength = postData.Length;
StreamWriter stOut = new StreamWriter(myReq.GetRequestStream(), System.Text.Encoding.ASCII);
stOut.Write(postData);
stOut.Close();
HttpWebResponse webresponse;
webresponse = (HttpWebResponse)myReq.GetResponse();
Encoding enc = System.Text.Encoding.UTF8;
StreamReader loResponseStream = new StreamReader(webresponse.GetResponseStream(), enc);
string Response = loResponseStream.ReadToEnd();
loResponseStream.Close();
webresponse.Close();
GoogleCell Mycell = JsonConvert.DeserializeObject<GoogleCell>(Response);
return Mycell;
}
catch (Exception ex)
{
string strErr = ex.Message;
if (ex.InnerException != null)
{
strErr += ": " + ex.InnerException.Message;
}
MessageBox.Show(strErr);
return new GoogleCell();
}
}
}
public class GoogleCell
{
public GoogleCell() { }
public GoogleCell(string mnc, string mcc, string lac)
{
this.Mnc = mnc;
this.Mcc = mcc;
this.Lac = lac;
}
public string Mnc { get; set; }
public string Mcc { get; set; }
public string Lac { get; set; }
public string CellID { get; set; }
public Location location { get; set; }
public class Location
{
public Location() { }
public Location(string latitude, string longitude)
{
this.latitude = latitude;
this.longitude = longitude;
}
public string latitude { get; set; }
public string longitude { get; set; }
public Address address { get; set; }
public class Address
{
public Address() { }
public string country { get; set; }
public string country_code { get; set; }
public string city { get; set; }
public string region { get; set; }
public string street { get; set; }
public string street_number { get; set; }
public string postal_code { get; set; }
}
}
The code worked flawlessly until sometime between one and two weeks ago, when it started returning error 400: Bad Request when it does the GetRequestStream().
My code hasn't changed.
I can't find any record of the API's parameters changing.
What else could be going on? This uses Google Gears, which has been deprecated for a while now, but I can't find any doco on a replacement that finds cell towers.
any ideas?

I ended up kicking Google to the curb and using OpenCellID:
public CellTowerPOCO GetCellInfo_OpenCellID(string lac, string mnc, string mcc, string cellID)
{
try
{
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(string.Format("http://www.opencellid.org/cell/get?mcc={0}&mnc={1}&cellid={2}&lac={3}",mcc,mnc,cellID,lac));
HttpWebResponse webresponse;
webresponse = (HttpWebResponse)myReq.GetResponse();
//Encoding enc = System.Text.Encoding.UTF8;
StreamReader loResponseStream = new StreamReader(webresponse.GetResponseStream());
string Response = loResponseStream.ReadToEnd();
loResponseStream.Close();
webresponse.Close();
CellTowerPOCO Mycell = new CellTowerPOCO();
XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(Response);
Mycell.location.latitude = xdoc.ChildNodes[1].FirstChild.Attributes["lat"].Value;
Mycell.location.longitude = xdoc.ChildNodes[1].FirstChild.Attributes["lon"].Value;
Mycell.Mcc = mcc;
Mycell.CellID = cellID;
Mycell.Mnc = mnc;
//MessageBox.Show(xdoc.ChildNodes[0].InnerText);
return Mycell;
}
catch (Exception ex)
{
string strErr = ex.Message;
if (ex.InnerException != null)
{
strErr += ": " + ex.InnerException.Message;
}
MessageBox.Show(strErr);
return new CellTowerPOCO();
}
}

Related

is there a reason to serialize and then deserialize an object?

I have a SOAP web service that someone developed at my work place and i try to learn it and i came across a move in the code that i can't get my head around. can someone explain to me the logic behind it? why would someone want to serialize an object and a line after to deserialize it?
**this is the whole code: if someone has a way to improve the code it will be appreciated: **
using IRail.BLL.SAP;
using IRail.Entities.SAP.Report;
using IRail.WebAPI.Heplers;
using Logger;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Web.Script.Serialization;
using System.Web.Services;
namespace IRail.WebAPI
{
public class EventInfo
{
public string QMNUM { get; set; }
public string QMART { get; set; }
public string STATUS { get; set; }
public string MAHUT_CODE { get; set; }
public string MAHUT_TXT { get; set; }
public string START_DATE { get; set; }
public string START_TIME { get; set; }
public string END_DATE { get; set; }
public string END_TIME { get; set; }
public string ZQMNUM { get; set; }
public string QMTXT { get; set; }
public string IKUN { get; set; }
public string ZLONG { get; set; }
public string LAT { get; set; }
public string TPLNR { get; set; }
public string ZZKM_NUM { get; set; }
public string ZZTOKM_NUM { get; set; }
}
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[System.Web.Script.Services.ScriptService]
public class Events : System.Web.Services.WebService
{
public static readonly ILogger _logger = LogManager.GetLogger();
[WebMethod]
public string UpdateEvent(EventInfo eventInfo)
{
// create an instance of SapClient object an fill it with the input parameters,
// that passes by the url to the function using the eventInfo class.
SapClient SapArgs = new SapClient()
{
params_input = "",
QNUM = eventInfo.QMNUM,
QMART = eventInfo.QMART,
STATUS = eventInfo.STATUS,
MAHUT_CODE = eventInfo.MAHUT_CODE,
MAHUT_TXT = eventInfo.MAHUT_TXT,
START_DATE = eventInfo.START_DATE,
START_TIME = eventInfo.START_TIME,
END_DATE = eventInfo.END_DATE,
END_TIME = eventInfo.END_TIME,
ZQMNUM = eventInfo.ZQMNUM,
QMTXT = eventInfo.QMTXT,
IKUN = eventInfo.IKUN,
ZLONG = eventInfo.ZLONG,
LAT = eventInfo.LAT,
TPLNR = eventInfo.TPLNR,
ZZKM_NUM = eventInfo.ZZKM_NUM,
ZZTOKM_NUM = eventInfo.ZZTOKM_NUM,
ikunx = "",
ikuny = "",
operation_type = "",
returnZ = "",
returnM = "",
returnTrueCurves = "",
f = ""
};
string errorMsg = String.Empty;
string outputJson = String.Empty;
ApiHelper apiHelper = new ApiHelper();
try
{
// create an instance of JS Serializer.
var jss = new JavaScriptSerializer();
// serialize the object to convert it to json format.
JObject sapArgs = JObject.Parse(jss.Serialize(SapArgs));
// decerialize the object back from json format to pass the JSON string representation
// of the sapArgs object as the input to the callGPAsync method.
var dict = jss.Deserialize<Dictionary<string, string>>(sapArgs.ToString());
// create an instance of EventsEngine.
EventsEngine eventsEngine = new EventsEngine();
// assign the type of the event to the events object:
// check the event type.
SapArgs.operation_type = eventsEngine.CheckEventType(dict, ref errorMsg);
// assign the event type that has returned to the sapArgs object's operation_type parameter.
sapArgs["operation_type"] = SapArgs.operation_type; // "1";// set operation_type for test;
// if encountered an error return the content of it.
if (errorMsg != "") return "UpdateEvent ERROR: " + errorMsg;
_logger.Info($"Username: {Utils.GetUserName()}, UpdateEvent : {sapArgs.ToString()}, eventType :{SapArgs.operation_type}");
if (!string.IsNullOrWhiteSpace(apiHelper.getValueFromDict(dict, "IKUN")) && dict["IKUN"].ToString() == "Y")
{
var res = apiHelper.convertCoordiateWGSToITM(sapArgs).GetAwaiter().GetResult();
}
outputJson = apiHelper.callGPAsync(sapArgs).GetAwaiter().GetResult();
try
{
// if there is result from submitted job add operation_type
outputJson = outputJson.Replace("}", ", \"operation_type\" = \"" + SapArgs.operation_type + "\" }");
}
catch (Exception outputEx)
{
return "outputJson ERROR: " + outputEx;
}
var response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StringContent(outputJson, System.Text.Encoding.UTF8, "application/json");
return outputJson;
}
catch (Exception ex)
{
_logger.Error(" UpdateEvent ERROR : " + SapArgs.ToString() + ", eventType :" + SapArgs.operation_type + ", errorMsg :" + errorMsg);
_logger.Error(ex);
return "UpdateEvent ERROR: update failed on exception. please check logs.";
}
//0. check with documentation - what are the parameters - in sap document
//0. log -> input call
//1. properties input validation -
// A. all inputs are correct //2.4 in documents ---> function in BLL that does the validation
//2. if all ok - -- delete prev event
//3. call GP service to update new event
//4. return success + log reult
}
}
}
I did not try anything i just want to understand the logic.

In Model.State Validation is invalid

i trying to upload the multiple images using asp.netcore mvc. i made property of pic in which i save the url path of image. when compiler hits the Model.State it gives Validation invalid. i also created property image in which image url saved. that property type is IFORMFILE. i am using sql to save pic information and using model for code. when i check in model state i find the error message of pic field is required.
namespace ehouse.Controllers
{
public class AddPropertyRentController1 : Controller
{
Rentdb DB =new Rentdb();
private IWebHostEnvironment _IWebHostEnvironment;
public AddPropertyRentController1(IWebHostEnvironment IWebHostEnvironment)
{
_IWebHostEnvironment = IWebHostEnvironment;
}
public IActionResult aprent()
{
return View();
}
[HttpPost]
public IActionResult aprent([Bind] RentModel ar)
{
if (ar.imge1 != null)
{
string folder = "photos/photo/";
folder += ar.imge1.FileName + Guid.NewGuid().ToString();
ar.pic1 = folder;
string serverFolder = Path.Combine(_IWebHostEnvironment.WebRootPath, folder);
ar.imge1.CopyToAsync(new FileStream(serverFolder, FileMode.Create));
}
if (ar.imge2 != null)
{
string folder = "photos/photo/";
folder += ar.imge2.FileName + Guid.NewGuid().ToString();
ar.pic2 = folder;
string serverFolder = Path.Combine(_IWebHostEnvironment.WebRootPath, folder);
ar.imge2.CopyToAsync(new FileStream(serverFolder, FileMode.Create));
}
if (ar.imge3 != null)
{
string folder = "photos/photo/";
folder += ar.imge3.FileName + Guid.NewGuid().ToString();
ar.pic3 = folder;
string serverFolder = Path.Combine(_IWebHostEnvironment.WebRootPath, folder);
ar.imge3.CopyToAsync(new FileStream(serverFolder, FileMode.Create));
}
if (ar.imge4 != null)
{
string folder = "photos/photo/";
folder += ar.imge4.FileName + Guid.NewGuid().ToString();
ar.pic4 = folder;
string serverFolder = Path.Combine(_IWebHostEnvironment.WebRootPath, folder);
ar.imge4.CopyToAsync(new FileStream(serverFolder, FileMode.Create));
}
if (ar.imge5 != null)
{
string folder = "photos/photo/";
folder += ar.imge5.FileName + Guid.NewGuid().ToString();
ar.pic5 = folder;
string serverFolder = Path.Combine(_IWebHostEnvironment.WebRootPath, folder);
ar.imge5.CopyToAsync(new FileStream(serverFolder, FileMode.Create));
}
if (ar.imge6 != null)
{
string folder = "photos/photo/";
folder += ar.imge6.FileName + Guid.NewGuid().ToString();
ar.pic6 = folder;
string serverFolder = Path.Combine(_IWebHostEnvironment.WebRootPath, folder);
ar.imge6.CopyToAsync(new FileStream(serverFolder, FileMode.Create));
}
if (ar.imge7 != null)
{
string folder = "photos/photo/";
folder += ar.imge7.FileName + Guid.NewGuid().ToString();
ar.pic7 = folder;
string serverFolder = Path.Combine(_IWebHostEnvironment.WebRootPath, folder);
ar.imge7.CopyToAsync(new FileStream(serverFolder, FileMode.Create));
}
if (ar.imge8 != null)
{
string folder = "photos/photo/";
folder += ar.imge8.FileName + Guid.NewGuid().ToString();
ar.pic8 = folder;
string serverFolder = Path.Combine(_IWebHostEnvironment.WebRootPath, folder);
ar.imge8.CopyToAsync(new FileStream(serverFolder, FileMode.Create));
}
if (ar.imge9 != null)
{
string folder = "photos/photo/";
folder += ar.imge9.FileName + Guid.NewGuid().ToString();
ar.pic9 = folder;
string serverFolder = Path.Combine(_IWebHostEnvironment.WebRootPath, folder);
ar.imge9.CopyToAsync(new FileStream(serverFolder, FileMode.Create));
}
if (ar.imge10 != null)
{
string folder = "photos/photo/";
folder += ar.imge10.FileName + Guid.NewGuid().ToString();
ar.pic10 = folder;
string serverFolder = Path.Combine(_IWebHostEnvironment.WebRootPath, folder);
ar.imge10.CopyToAsync(new FileStream(serverFolder, FileMode.Create));
}
try
{
if (ModelState.IsValid)
{
string res = DB.Saverecord(ar);
string pics = DB.imagedb(ar);
TempData["msg"] = res;
}
}
catch (Exception ex)
{
TempData["msg"] = ex.Message;
}
return View();
}
}
}
RentModel
using System.ComponentModel.DataAnnotations;
namespace eHouse.Models
{
public class RentModel
{
public int id { get; set; }
public string tittle { get; set; }
public string price { get; set; }
public string descrip { get; set; }
public string areaUnit { get; set; }
public int area { get; set; }
public string province { get; set; }
public string city { get; set; }W
public string stadress { get; set; }
//public string features { get; set;}
public string bathroom { get; set; }
public string furnished { get; set; }
public string p_type { get; set; }
public string bedroom { get; set; }
public int p_id { get; set; }
[Required]
public string? pic1 { get; set; }
[Required]
public IFormFile imge1 { get; set; }
[Required]
public string? pic2 { get; set; }
public IFormFile imge2 { get; set; }
[Required]
public string? pic3 { get; set; }
public IFormFile imge3 { get; set; }
[Required]
public string? pic4 { get; set; }
public IFormFile imge4 { get; set; }
[Required]
public string? pic5 { get; set; }
public IFormFile imge5 { get; set; }
[Required]
public string? pic6 { get; set; }
public IFormFile imge6 { get; set; }
[Required]
public string? pic7 { get; set; }
[Required]
public IFormFile imge7 { get; set; }
[Required]
public string? pic8 { get; set; }
public IFormFile imge8 { get; set; }
[Required]
public string? pic9 { get; set; }
public IFormFile imge9 { get; set; }
[Required]
public string? pic10 { get; set; }
public IFormFile imge10 { get; set; }
public int r_id
{
get; set;
}
}
}

How to insert the file name in the database using Ado.Net? Instead of the file name null value is being inserted

How to insert the file name in the database using Ado.Net? Instead of the file name null value is being inserted
CONNECTION CODE-
public bool AddBooks(LibraryManagementModel LibraryObject)
{
SqlCommand cmd = new SqlCommand("AddBooks", connection);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#book_id", LibraryObject.Id);
cmd.Parameters.AddWithValue("#book_name", LibraryObject.Book_Name);
cmd.Parameters.AddWithValue("#author", LibraryObject.Author);
cmd.Parameters.AddWithValue("#publisher", LibraryObject.Publisher);
cmd.Parameters.AddWithValue("#date_of_publication", LibraryObject.Date_of_publication);
cmd.Parameters.AddWithValue("#year", LibraryObject.Year);
cmd.Parameters.AddWithValue("#category", LibraryObject.Category);
cmd.Parameters.AddWithValue("#price", LibraryObject.Price);
cmd.Parameters.AddWithValue("#image",LibraryObject.Image);
if (connection.State == ConnectionState.Closed)
connection.Open();
int i = cmd.ExecuteNonQuery();
connection.Close();
if (i > 1)
{
return true;
}
else
{
return false;
}
}
CONTROLLER CODE-
public ActionResult AddBooks(LibraryManagementModel LibraryObject)
{
string fileName = Path.GetFileNameWithoutExtension(LibraryObject.ImageFile.FileName);
string extension = Path.GetExtension(LibraryObject.ImageFile.FileName);
fileName = fileName + DateTime.Now.ToString("yymmssfff") + extension;
LibraryObject.Image = "~/Image/" + fileName;
fileName = Path.Combine(Server.MapPath("~/Image/"), fileName);
LibraryObject.ImageFile.SaveAs(fileName);
if (ModelState.IsValid == true)
{
BooksDB.AddBooks(LibraryObject);
ModelState.Clear();
ViewBag.AddMsg = "<script>('Data Saved')</script>";
return RedirectToAction("Index");
}
else
{
ViewBag.AddMsg = "<script>('something went wrong')</script>";
return RedirectToAction("Index");
}
return View();
}
MODEL CODE-
public class LibraryManagementModel
{
public int Id { get; set; }
[Required]
public string Book_Name { get; set; }
[Required]
public string Author { get; set; }
[Required]
public string Publisher { get; set; }
[Required]
[DataType(DataType.Date)]
public string Date_of_publication { get; set; }
[Required]
public string Year { get; set; }
public string Category { get; set; }
public string Price{ get; set; }
[DisplayName("Upload Book Image")]
public string Image { get; set; }
public HttpPostedFileBase ImageFile { get; set; }
}

C# - How to Upload large size video ( in GB ) to Amazon S3 bucket

I need to upload a large size video to Amazon S3 bucket.
I have a large size video and it
here is my class that i am using
public class CustomAmazon
{
public string tourName { get; set; }
public string driveName { get; set; }
public string tourID { get; set; }
public string driveID { get; set; }
public string key { get; set; }
public string bucketName { get; set; }
public string cloudFrontVideoUrl { get; set; }
public string amazonS3VideoUrl { get; set; }
public string filePath { get; set; }
}
and here is the Amazon Code for writing an object
static string WritingAnObject(CustomAmazon customAmazon)
{
try
{
var videoStream = new FileStream(customAmazon.filePath, FileMode.Open, FileAccess.Read);
// put a more complex object with some metadata and http headers.
string fileName = customAmazon.tourID + "/" + customAmazon.driveID + "/" + Guid.NewGuid() + "__" + Path.GetFileName(customAmazon.filePath);
PutObjectRequest titledRequest = new PutObjectRequest()
{
BucketName = customAmazon.bucketName,
Key = fileName,
InputStream = videoStream,
Timeout = new TimeSpan(4, 30, 30),
ContentType = "video/mov",
CannedACL = S3CannedACL.PublicRead
};
titledRequest.Metadata.Add("title", fileName);
titledRequest.Metadata.Add("drive", customAmazon.driveName);
client.PutObject(titledRequest);
Thread.Sleep(4000);
// Retrieve ACL for object
customAmazon.cloudFrontVideoUrl = customAmazon.cloudFrontVideoUrl + fileName;
customAmazon.key = fileName;
customAmazon.amazonS3VideoUrl = ReadConfig.AWSStorageUrl + fileName;
}
catch (AmazonS3Exception amazonS3Exception)
{
Logger.Write(amazonS3Exception.Message);
if (amazonS3Exception.ErrorCode != null &&
(amazonS3Exception.ErrorCode.Equals("InvalidAccessKeyId") ||
amazonS3Exception.ErrorCode.Equals("InvalidSecurity")))
{
Console.WriteLine("Please check the provided AWS Credentials.");
Console.WriteLine("If you haven't signed up for Amazon S3, please visit http://aws.amazon.com/s3");
}
else
{
Logger.Write(string.Format("An error occurred with the message '{0}' when writing an object", amazonS3Exception.Message));
}
}
return customAmazon.amazonS3VideoUrl;
}
I am getting error while uploading large size video, while in small size videos it is working fine.
Yes, I got the answer, I tried it using multicast and it is working fine, here is my solution
Here is my class
public class CustomAmazon
{
public string tourName { get; set; }
public string driveName { get; set; }
public string tourID { get; set; }
public string driveID { get; set; }
public string key { get; set; }
public string bucketName { get; set; }
public string cloudFrontVideoUrl { get; set; }
public string amazonS3VideoUrl { get; set; }
public string filePath { get; set; }
}
and here is my solution
I just call below method to upload large video file after connecting credentials
/// <summary>
/// Method used for DFI (website or API) users to upload a file on Amazon S3 storage
/// </summary>
/// <param name="customAmazon"></param>
/// <returns>CustomAmazon class object </returns>
public CustomAmazon UploadFiletoAmazonS3Storage(CustomAmazon customAmazon)
{
using (client = new AmazonS3Client(ReadConfig.AWSAccessKeyId, ReadConfig.AWSSecretKey, RegionEndpoint.USEast1))
{
Console.WriteLine("Writing an object");
WritingAnLargeObject(customAmazon);
}
return customAmazon;
}
public static string WritingAnLargeObject(CustomAmazon customAmazon)
{
// List to store upload part responses.
List<UploadPartResponse> uploadResponses = new List<UploadPartResponse>();
string fileName = string.Empty;
// Giving custom filename to original file
if (!string.IsNullOrEmpty(customAmazon.tourID) && (!string.IsNullOrEmpty(customAmazon.driveID)))
{
fileName = customAmazon.tourID + "/" + customAmazon.driveID + "/" + Guid.NewGuid() + "___" + Regex.Replace(Path.GetFileName(customAmazon.filePath), #"\s", "");
}
else
{
fileName = Guid.NewGuid() + "___" + Regex.Replace(Path.GetFileName(customAmazon.filePath), #"\s", "");
}
// 1. Initialize MultipartUploadRequest.
InitiateMultipartUploadRequest initiateRequest = new InitiateMultipartUploadRequest
{
BucketName = customAmazon.bucketName,
Key = fileName,
ContentType = "video/mov",
CannedACL = S3CannedACL.PublicRead
};
InitiateMultipartUploadResponse initResponse =
client.InitiateMultipartUpload(initiateRequest);
// 2. Upload video in small Parts of 5 MB.
long contentLength = new FileInfo(customAmazon.filePath).Length;
long partSize = 5 * (long)Math.Pow(2, 20); // 5 MB
try
{
long filePosition = 0;
for (int index = 1; filePosition < contentLength; index++)
{
UploadPartRequest uploadRequest = new UploadPartRequest
{
BucketName = customAmazon.bucketName,
Key = fileName,
UploadId = initResponse.UploadId,
PartNumber = index,
PartSize = partSize,
FilePosition = filePosition,
FilePath = customAmazon.filePath
};
// Upload part and add response to our list.
uploadResponses.Add(client.UploadPart(uploadRequest));
filePosition += partSize;
}
// Step 3: complete.
CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest
{
BucketName = customAmazon.bucketName,
Key = fileName,
UploadId = initResponse.UploadId,
//PartETags = new List<PartETag>(uploadResponses)
};
completeRequest.AddPartETags(uploadResponses);
customAmazon.key = fileName;
CompleteMultipartUploadResponse completeUploadResponse = client.CompleteMultipartUpload(completeRequest);
customAmazon.cloudFrontVideoUrl = customAmazon.cloudFrontVideoUrl + fileName;
customAmazon.amazonS3VideoUrl = ReadConfig.AWSStorageUrl + fileName;
}
catch (Exception exception)
{
Logger.Write(exception.Message);
Console.WriteLine("Exception occurred: {0}", exception.Message);
AbortMultipartUploadRequest abortMPURequest = new AbortMultipartUploadRequest
{
BucketName = customAmazon.bucketName,
Key = fileName,
UploadId = initResponse.UploadId
};
client.AbortMultipartUpload(abortMPURequest);
}
return fileName;
}
and Finally I uploaded the video into S3 bucket

How to filter audio podcasts from iTunes Search API?

By searching for podcasts with the iTunes API (http://www.apple.com/itunes/affiliates/resources/documentation/itunes-store-web-service-search-api.html) the result contains both audio and video podcasts. Is there any way to retrieve only audio podcasts from the API?
Thanks in advance :-)
From the documentation it doesn’t seem as if filtering audio and video podcasts is possible; however, you could loop through the resulting items and check whether each item is audio or video for filtering. You can do that be finding additional information from the RSS feed or by making another call to iTunes using the subscribePodcast url (see example).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Web.Script.Serialization;
using System.Xml.Linq;
using System.IO;
namespace ConsoleTest
{
class Program
{
static void Main(string[] args)
{
//Searching for Windows Weekly
string url = "https://itunes.apple.com/search?term=Windows%20Weekly&media=podcast&attibute=audio";
string json = FetchHTML(url);
JavaScriptSerializer s = new JavaScriptSerializer();
var result = s.Deserialize(json);
var audioOnly = new List();
foreach (var item in result.Results)
{
if (!IsVideo(item.TrackId))
{
audioOnly.Add(item);
}
}
foreach (var au in audioOnly)
{
Console.WriteLine(au.TrackName);
}
Console.ReadLine();
}
static bool IsVideo(string id)
{
string req = "https://buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/com.apple.jingle.app.finance.DirectAction/subscribePodcast?id=" + id + "&wasWarnedAboutPodcasts=true";
string xml = FetchHTML(req,true);
bool isVideo = false;
var re = XElement.Load(new StringReader(xml)).Elements("dict").Elements("dict");
bool next = false;
foreach (var e in re.Elements())
{
if (next)
{
//This is the is video value
isVideo = e.Name.LocalName.Trim().ToLower() == "true";
next = false;
break;
}
if (e.Value == "is-video")
{
next = true;
}
}
return isVideo;
}
static string FetchHTML(string url,bool doItAsITunes = false)
{
string htmlCode = "";
using (WebClient client = new WebClient())
{
if (doItAsITunes)
{
client.Headers.Add("user-agent", "iTunes/9.1.1");
}
htmlCode = client.DownloadString(url);
}
return htmlCode;
}
}
public class SearchResult
{
public SearchResult()
{
Results = new List();
}
public int ResultCount { set; get; }
public List Results { set; get; }
}
public class Item
{
public Item()
{
GenreIDs = new List();
Genres = new List();
}
public string WrapperType { set; get; }
public string Kind { set; get; }
public string ArtistID { set; get; }
public string CollectionID { set; get; }
public string TrackId { set; get; }
public string ArtistName { set; get; }
public string CollectionName { set; get; }
public string TrackName { set; get; }
public string CollectionCensoredName { set; get; }
public string TrackCensoredName { set; get; }
public string ArtistViewUrl { set; get; }
public string FeedUrl { set; get; }
public string TrackViewUrl { set; get; }
public string PreviewUrl { set; get; }
public string ArtworkUrl60 { set; get; }
public string ArtworkUrl100 { set; get; }
public float CollectionPrice { set; get; }
public float TrackPrice { set; get; }
public string CollectionExplicitness { set; get; }
public string TrackExplicitness { set; get; }
public string DiscCount { set; get; }
public string DiscNumber { set; get; }
public string TrackCount { set; get; }
public string TrackNumber { set; get; }
public string TrackTimeMillis { set; get; }
public string Country { set; get; }
public string Currency { set; get; }
public string PrimaryGenreName { set; get; }
public List GenreIDs { set; get; }
public List Genres { set; get; }
}
}
Yes. In regular serach you get everything:
https://itunes.apple.com/search?term=jack+johnson
But you can add some params to request for example (for your case)
&entity=song
So the request will be:
https://itunes.apple.com/search?term=jack+johnson&entity=song
For more look at Searching seaction in this docs