StreamWriter failing to run after 1st iteration in for loop - c#

I'm having issues using StreamWriter to code a scraper for a current project i've got. The loop i've coded is below
I've debugged all the variables coming into the loop and everything is set as it should be. When i pass in a url and the range to search through based on an ID GET variable in the url it fails to write the second sourceCode string
Could someone be kind enough to tell me if i'm not flushing something or is there something else at work here??
I've wrecked my head trying to find the root cause but its proving very stubborn
using System;
using System.IO;
using System.Windows.Forms;
namespace Scraper
{
public partial class Form1 : Form
{
Scraper scraper = new Scraper();
private StreamWriter sw;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string url = textBox1.Text;
string[] urlBits = url.Split('.');
string[] domain = urlBits[2].Split('/');
string filepath = #"C:\Users\Herbaldinho\Desktop\"+urlBits[1]+"-"+domain[0];
string parentPath = #"C:\Users\Herbaldinho\Desktop\";
string newPath = Path.Combine(parentPath, filepath);
if (File.Exists(filepath))
{}
else
{
Directory.CreateDirectory(newPath);
}
DateTime today = DateTime.Today;
string curDate = String.Format("{0:ddd-MMM-dd-yyyy}", today);
string subPath = newPath + "\\" + curDate;
string newSubPath = Path.Combine(newPath, subPath);
if (File.Exists(subPath))
{ }
else
{
Directory.CreateDirectory(newSubPath);
}
string lower = textBox2.Text;
int lowerValue;
int.TryParse(lower, out lowerValue);
string upper = textBox3.Text;
int upperValue;
int.TryParse(upper, out upperValue);
int i;
for (i = lowerValue; i < upperValue; i++)
{
string filename = newSubPath+"\\Advert-"+i+".html";
string adPage = url + i;
bool write = scraper.UrlExists(adPage);
if (write)
{
string sourceCode = scraper.getSourceCode(adPage);
using (sw = new StreamWriter(filename))
{
sw.Write(sourceCode);
}
}
}
MessageBox.Show("Scrape Complete");
}
}
}
####This is the Scraper Object
using System.Net;
namespace Scraper
{
class Scraper
{
WebClient w = new WebClient();
public bool UrlExists(string url)
{
try
{
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "HEAD";
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
return (response.StatusCode == HttpStatusCode.OK);
}
catch
{
return false;
}
}
public string getSourceCode(string url)
{
string s = w.DownloadString(url);
return s;
}
}
}

Found the answer to the problem this morning
For anyone else having a similar problem, the try catch logic in the UrlExists method needs to close the response (response.Close())
From what i had understood it autoclosed but this is not the case
Hope this helps
Many thanks for the responses in helping me resolve this everyone

Related

VS 2019 Metadata Not Found and Value Can't Be Null Errors

Building a cross-platform App with Xamarin Forms (Most Recent Version).
These are my errors:
Metadata file 'C:\Users\sethb\source\repos\App\App\App\bin\Debug\netstandard2.0\ref\App.dll' could not be found. On File CSC, Line 1.
Value Cannot be null on File NewTicket.xaml, Line 1.
I have tried many solutions to solve this problem, such as:
Updating my Nuget Packages (including Xamarin and the Net Standard Library).
Updating Visual Studio 2019.
Various combinations of clean, empty bin/obj/nugget cache, restart app, build individual solutions, re-build entire project.
Comment out the Xamarin code I was working on when this error occurred.
Adjusting Configuration Manager for different platforms / build / deploy combinations
Uninstall and re-install the Net Standard Library.
I even tried deleting the offending page and re-building it from scratch.
Obviously, the core issue for problem #1 is that key files aren't making it into my netstandard2.0 file, but I have no idea why. Hopefully, solving that will also fix the "Value Cannot be Null" error.
I have noticed when I look up "NETStandard.Library" in my list of installed apps, the arrow symbol marking it as installed doesn't pop up. But when I click on it, it says version 2.0.3 is already installed. Strange.
I think the issue is deeper in the build order of my Project, but I'll add in the pages I was working on when this error occurred. Maybe you will find something I have missed.
Let me know if there's anything else I can provide on my end to help resolve this problem. I can't launch my emulators until this is fixed. Client is waiting on their new app and I'm dead in the proverbial water.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
using System.Net.Http.Headers;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using App.Classes;
using Xamarin.Essentials;
using App.Tickets_Module;
using App.Dashboard_Module;
using App.PO_Module;
namespace App.Tickets_Module
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class NewTicket : ContentPage
{
public List<Company> CompanyNames { get; set; }
public string Client_Name = null;
public int Client_Index;
public string Client_Id = null;
public string NewTicketPriority = null;
public NewTicket()
{
InitializeComponent();
/*
* CONSIDER: adding in a web link so they can click the ticket and go to Bento.
*/
string email = App.UserEmail;
//New Company List
List<Company> CompanyNames = new List<Company>();
//Send Open Ticket API Query
NewTicketAsync(email, CompanyNames);
}
//Check for empty fields...
private async void SendNewTicket(string email, string CheckTitle, string CheckPhone, string CheckDescription, string ClientId, string TicketPriority)
{
//Get Client Id
//Client_Id = CompanyNames[Client_Index].Id;
string Email = email;
string Pass = LoadAPIKey().Result;
string TicketClient = Client_Name;
string TicketClientId = ClientId;
string TicketPhone = CheckPhone;
string ThisPriority = TicketPriority;
//Add Backslashes
string TicketTitle = CheckTitle;
TicketTitle = TicketTitle.Replace("'", "''");
string TicketDescription = CheckDescription;
TicketDescription = TicketDescription.Replace("'", "''");
//POST URL BELOW
string url = "https://domain/tickets/new_ticket_sub.php?";
//POST REQUEST
using (HttpClient client = new HttpClient())
{
//JSON Content
string content = "{'" + Email + "',*&'" + Pass + "',*&'" + TicketClient
+ "',*&'" + TicketTitle + "',*&'" + TicketPhone
+ "',*&'" + TicketDescription + "',*&'"+ TicketClientId + "',*&'" + ThisPriority + "'}";
//Prep JSON Message
var JSON = JsonConvert.SerializeObject(content);
var POSTdata = new StringContent(JSON.ToString(), Encoding.UTF8, "application/json");
POSTdata.Headers.ContentType = new MediaTypeHeaderValue("application/json");
//Send JSON Message
var response = await client.PostAsync(url, POSTdata);
var status = response.StatusCode.ToString();
//Await Response
var responseString = await response.Content.ReadAsStringAsync();
//Convert JSON Object into Usable Array
var message = (JsonConvert.DeserializeObject<TestMessage>(responseString)).Message;
if (message == "Email Not Found.")
{
//New Response
string newMessage = "Email does not exist. Please register a bento account for this email address.";
//Print Response
restMessage.Text = newMessage;
restMessage.IsVisible = true;
}
else if (message == "Connection Failed.")
{
//New Response
string newMessage = "Connection failed. Please contact support.";
//Print Response
restMessage.Text = newMessage;
restMessage.IsVisible = true;
}
else if (message == "API Login Error.")
{
//New Response
string newMessage = "Internal key failure, please contact support.";
//Print Response
restMessage.Text = newMessage;
restMessage.IsVisible = true;
}
else if (message == "Submission Failed.")
{
//New Response
string newMessage = "Internal ticket error, please contact support.";
//Print Response
restMessage.Text = newMessage;
restMessage.IsVisible = true;
}
else if (message == "Submission Succeeded.")
{
//Send user to Dashboard
await Navigation.PushAsync(new TicketsPage());
}
}
}
private async void NewTicketAsync(string email, List<Company> CompanyNames)
{
string Email = email;
string Pass = LoadAPIKey().Result;
//POST URL BELOW
string url = "https://domain/tickets/new_ticket_page.php?";
//POST REQUEST
using (HttpClient client = new HttpClient())
{
//JSON Content
string content = "{'" + Email + "','" + Pass + "'}";
//Prep JSON Message
var JSON = JsonConvert.SerializeObject(content);
var POSTdata = new StringContent(JSON.ToString(), Encoding.UTF8, "application/json");
POSTdata.Headers.ContentType = new MediaTypeHeaderValue("application/json");
//Send JSON Message
var response = await client.PostAsync(url, POSTdata);
var status = response.StatusCode.ToString();
//Await Response
var responseJSON = await response.Content.ReadAsStringAsync();
//Convert JSON Object into Usable Array
var ParsedTickets = JsonConvert.DeserializeObject<List<Company>>(responseJSON);
var length = ParsedTickets.Count();
//Load array into individual Tickets
for (int i = 0; i < length; i++)
{
var companyModel = new Company
{
Company_Name = ParsedTickets[i].Company_Name,
Id = ParsedTickets[i].Id
};
CompanyNames.Add(companyModel);
}
//Load Ticket List
//OpenTickets = (JsonConvert.DeserializeObject<List<Ticket>>(responseJSON));
//Load into new Tickets List
NewTicketCompany.ItemsSource = CompanyNames;
}
}
private async Task<string> LoadAPIKey()
{
string api_key = "";
//Load API KEY
try
{
api_key = await SecureStorage.GetAsync("api_key");
}
catch (Exception)
{
// Possible that device doesn't support secure storage on device.
}
return api_key;
}
private void NewTicketCompany_SelectedIndexChanged(object sender, EventArgs e)
{
Picker NewTicketCompany = sender as Picker;
int selectedIndex = NewTicketCompany.SelectedIndex;
Client_Name = NewTicketCompany.Items[selectedIndex];
}
private void SubmitNewTicket_Clicked(object sender, EventArgs e)
{
string CheckTitle = NewTicketTitle.Text;
string CheckPhone = NewTicketPhone.Text;
string CheckDescription = NewTicketDescription.Text;
string ClientId = ThisClientId.Text;
string TicketPriority = NewTicketPriority;
if (Client_Name == null || CheckTitle == null || CheckPhone == null || CheckDescription == null || ClientId == null)
{
restMessage.Text = "Please fill out all form fields";
}
else
{
string email = App.UserEmail;
SendNewTicket(email, CheckTitle, CheckPhone, CheckDescription, ClientId, TicketPriority);
}
}
//NAVIGATION METHODS
private void Home_link_Clicked(object sender, EventArgs e)
{
Navigation.PushAsync(new Dashboard());
}
private void User_profile_Clicked(object sender, EventArgs e)
{
Navigation.PushAsync(new User());
}
private void Clients_profile_Clicked(object sender, EventArgs e)
{
Navigation.PushAsync(new Clients());
}
private void Tickets_list_Clicked(object sender, EventArgs e)
{
Navigation.PushAsync(new TicketsPage());
}
private void Orders_list_Clicked(object sender, EventArgs e)
{
Navigation.PushAsync(new OrdersPage());
}
/* private void TicketPriorityPicker_SelectedIndexChanged(object sender, EventArgs e)
{
var picker = (Picker)sender;
int selectedIndex = picker.SelectedIndex;
if (selectedIndex != -1)
{
NewTicketPriority = (string)picker.ItemsSource[selectedIndex];
}
}
*/
}
}

Why is my StreamReader string empty when referenced outside of the containing class?

I'm using a StreamReader to fill a string up with data from a web response. This works just fine, and can be accessed inside the class. (WebResponseEventArgs) When I try to access it elsewhere however, it returns an empty string. Not null, just an empty string.
WebResponseEventArgs class:
public class WebResponseEventArgs : EventArgs
{
public WebAsync WebAsyncObject;
public string ErrorMessage;
public JArray ValidationErrors;
public JArray Data;
public string ResponseString;
public string Test;
public StreamReader reader;
public WebResponseEventArgs(WebAsync webAsync)
{
Test = "Hello!";
WebAsyncObject = webAsync;
Stream responseStream = WebAsyncObject.requestState.webResponse.GetResponseStream ();
reader = new StreamReader (responseStream);
ResponseString = reader.ReadToEnd ();
if(ResponseString != "")
{
try {
Debug.Log (ResponseString);
Data = JArray.Parse (ResponseString);
}
catch(JsonReaderException e)
{
Data = JArray.Parse ("[" + ResponseString + "]");
}
if(Data.Contains ("errors"))
{
ValidationErrors = (JArray) Data["errors"];
}
Debug.Log (Data[1]);
}
}
public bool HasErrors()
{
if(ErrorMessage != null)
{
return true;
}
else return false;
}
}
As you can see I'm logging the string in the debugger, and it shows me the complete response string, verifying that it does work inside this class. When the variable is called from anywhere else however, it returns an empty string. I spent the past 2 hours Googling and hoping someone else had stumbled upon this issue before, but I couldn't find anything.
Here is the event handler that tries to access the string:
public void OnGetAllResource(WebResponseEventArgs e)
{
//Check for errors
if(e.HasErrors())
{
Debug.Log (e.ErrorMessage);
return;
}
//Debug.Log (r);
//Test our resource inherited class
else
{
//string string2 = Shift.Instance.getAll ();
//string string3 = Shift.Instance.getAll ();
//Start composing our list
Debug.Log (e.Test);
Debug.Log (e.ResponseString);
Debug.Log(e.Test) works fine, Debug.Log(e.ResponseString) returns an empty string.
I hope someone can help me with this, it's been causing me a major headache :)

Problems with Xml parsing using C#

I am developing my first windows App and I am facing some Problems while parsing an Xml,the code is as shown below
public void TimeParsing(string lat, string lon)
{
string urlbeg = "http://api.geonames.org/timezone?lat=";
string urlmid = "&lng=";
string urlend = "&username=dheeraj_kumar";
WebClient downloader = new WebClient();
Uri uri = new Uri(urlbeg + lat + urlmid + lon + urlend, UriKind.Absolute);
downloader.DownloadStringCompleted += new DownloadStringCompletedEventHandler(TimeDownloaded);
//downloader.DownloadStringCompleted += new DownloadStringCompletedEventHandler(TimeDownloaded);
downloader.DownloadStringAsync(uri);
}
private void TimeDownloaded(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Result == null || e.Error != null)
{
MessageBox.Show("Invalid");
}
else
{
XDocument document = XDocument.Parse(e.Result);
var data1 = from query in document.Descendants("geoname")
select new Country
{
CurrentTime = (string)query.Element("time"),
};
foreach (var d in data1)
{
time = d.CurrentTime;
MessageBox.Show(d.CurrentTime);
// country = d.CountryName;
}
}
}
The problem is that the Delegate TimeDownloaded is not being called. I used the same technique is parse a different URL and it was done easily but its not working in this case.Kindly Help me as I am pretty new to this field.
Thanks in advance.
Theres a few misses regarding fetching the nodes
The output is geonames/timezone/time, it's corrected below, also testable using the method DownloadStringTaskAsync instead
[TestClass]
public class UnitTest1
{
[TestMethod]
public async Task TestMethod1()
{
await TimeParsing("-33.8674869", "151.20699020000006");
}
public async Task TimeParsing(string lat, string lon)
{
var urlbeg = "http://api.geonames.org/timezone?lat=";
var urlmid = "&lng=";
var urlend = "&username=dheeraj_kumar";
var downloader = new WebClient();
var uri = new Uri(urlbeg + lat + urlmid + lon + urlend, UriKind.Absolute);
downloader.DownloadStringCompleted += TimeDownloaded;
var test = await downloader.DownloadStringTaskAsync(uri);
Console.WriteLine(test);
}
private void TimeDownloaded(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Result == null || e.Error != null)
{
Console.WriteLine("Invalid");
}
else
{
var document = XDocument.Parse(e.Result);
var data1 = from query in document.Descendants("timezone")
select new Country
{
CurrentTime = (string)query.Element("time"),
};
foreach (var d in data1)
{
Console.WriteLine(d.CurrentTime);
}
}
}
}
internal class Country
{
public string CurrentTime { get; set; }
}
}
you can use the below mentioned code.
Uri uri = new Uri(urlbeg + lat + urlmid + lon + urlend, UriKind.Absolute);
HttpWebRequest WebReq = (HttpWebRequest)WebRequest.Create(uri);
//This time, our method is GET.
WebReq.Method = "GET";
//From here on, it's all the same as above.
HttpWebResponse WebResp = (HttpWebResponse)WebReq.GetResponse();
//Now, we read the response (the string), and output it.
Stream Answer = WebResp.GetResponseStream();
StreamReader _Answer = new StreamReader(Answer);
string s = _Answer.ReadToEnd();
XDocument document = XDocument.Parse(s);
var data1 = from query in document.Descendants("geoname")
select new Country
{
CurrentTime = (string)query.Element("time"),
};
foreach (var d in data1)
{
time = d.CurrentTime;
MessageBox.Show(d.CurrentTime);
// country = d.CountryName;
}
for Windows Phone 8 you have to implement the getResponse Method.
public static System.Threading.Tasks.Task<System.Net.WebResponse> GetResponseAsync(this System.Net.WebRequest wr)
{
return Task<System.Net.WebResponse>.Factory.FromAsync(wr.BeginGetResponse, wr.EndGetResponse, null);
}

WCF Streaming File Transfer ON .NET 4

I need a good example on WCF Streaming File Transfer.
I have found several and tried them but the posts are old and I am wokding on .net 4 and IIS 7 so there are some problems.
Can you gives me a good and up-to-date example on that.
The following answers detail using a few techniques for a posting binary data to a restful service.
Post binary data to a RESTful application
What is a good way to transfer binary data to a HTTP REST API service?
Bad idea to transfer large payload using web services?
The following code is a sample of how you could write a RESTful WCF service and is by no means complete but does give you an indication on where you could start.
Sample Service, note that this is NOT production ready code.
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class FileService
{
private IncomingWebRequestContext m_Request;
private OutgoingWebResponseContext m_Response;
[WebGet(UriTemplate = "{appName}/{id}?action={action}")]
public Stream GetFile(string appName, string id, string action)
{
var repository = new FileRepository();
var response = WebOperationContext.Current.OutgoingResponse;
var result = repository.GetById(int.Parse(id));
if (action != null && action.Equals("download", StringComparison.InvariantCultureIgnoreCase))
{
response.Headers.Add("Content-Disposition", string.Format("attachment; filename={0}", result.Name));
}
response.Headers.Add(HttpResponseHeader.ContentType, result.ContentType);
response.Headers.Add("X-Filename", result.Name);
return result.Content;
}
[WebInvoke(UriTemplate = "{appName}", Method = "POST")]
public void Save(string appName, Stream fileContent)
{
try
{
if (WebOperationContext.Current == null) throw new InvalidOperationException("WebOperationContext is null.");
m_Request = WebOperationContext.Current.IncomingRequest;
m_Response = WebOperationContext.Current.OutgoingResponse;
var file = CreateFileResource(fileContent, appName);
if (!FileIsValid(file)) throw new WebFaultException(HttpStatusCode.BadRequest);
SaveFile(file);
SetStatusAsCreated(file);
}
catch (Exception ex)
{
if (ex.GetType() == typeof(WebFaultException)) throw;
if (ex.GetType().IsGenericType && ex.GetType().GetGenericTypeDefinition() == typeof(WebFaultException<>)) throw;
throw new WebFaultException<string>("An unexpected error occurred.", HttpStatusCode.InternalServerError);
}
}
private FileResource CreateFileResource(Stream fileContent, string appName)
{
var result = new FileResource();
fileContent.CopyTo(result.Content);
result.ApplicationName = appName;
result.Name = m_Request.Headers["X-Filename"];
result.Location = #"C:\SomeFolder\" + result.Name;
result.ContentType = m_Request.Headers[HttpRequestHeader.ContentType] ?? this.GetContentType(result.Name);
result.DateUploaded = DateTime.Now;
return result;
}
private string GetContentType(string filename)
{
// this should be replaced with some form of logic to determine the correct file content type (I.E., use registry, extension, xml file, etc.,)
return "application/octet-stream";
}
private bool FileIsValid(FileResource file)
{
var validator = new FileResourceValidator();
var clientHash = m_Request.Headers[HttpRequestHeader.ContentMd5];
return validator.IsValid(file, clientHash);
}
private void SaveFile(FileResource file)
{
// This will persist the meta data about the file to a database (I.E., size, filename, file location, etc)
new FileRepository().AddFile(file);
}
private void SetStatusAsCreated(FileResource file)
{
var location = new Uri(m_Request.UriTemplateMatch.RequestUri.AbsoluteUri + "/" + file.Id);
m_Response.SetStatusAsCreated(location);
}
}
Sample Client, note that this is NOT production ready code.
// *********************************
// Sample Client
// *********************************
private void UploadButton_Click(object sender, EventArgs e)
{
var uri = "http://dev-fileservice/SampleApplication"
var fullFilename = #"C:\somefile.txt";
var fileContent = File.ReadAllBytes(fullFilename);
using (var webClient = new WebClient())
{
try
{
webClient.Proxy = null;
webClient.Headers.Add(HttpRequestHeader.ContentMd5, this.CalculateFileHash());
webClient.Headers.Add("X-DaysToKeep", DurationNumericUpDown.Value.ToString());
webClient.Headers.Add("X-Filename", Path.GetFileName(fullFilename));
webClient.UploadData(uri, "POST", fileContent);
var fileUri = webClient.ResponseHeaders[HttpResponseHeader.Location];
Console.WriteLine("File can be downloaded at" + fileUri);
}
catch (Exception ex)
{
var exception = ex.Message;
}
}
}
private string CalculateFileHash()
{
var hash = MD5.Create().ComputeHash(File.ReadAllBytes(#"C:\somefile.txt"));
var sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("x2"));
}
return sb.ToString();
}
private void DownloadFile()
{
var uri = "http://dev-fileservice/SampleApplication/1" // this is the URL returned by the Restful file service
using (var webClient = new WebClient())
{
try
{
webClient.Proxy = null;
var fileContent = webClient.DownloadData(uri);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}

How to connect to Mailman mailing list using .Net

I have to develop a .Net application in which i have to add or remove a user from Mailman mailing list.My Question is whether there is any .Net connector or Dll to connect to mailman mailing list using .Net.
Edit (9/21/14): I have just released a NuGet package for manipulating most aspects of a Mailman v2 list via HTTP calls. https://www.nuget.org/packages/MailmanSharp/
I'm not aware of any existing component to do this, but since the Mailman interface is all on the web, you can "control" it with HttpWebRequest; I recently wrote a small app which can retrieve the subscriber list, subscribe/unsubscribe people, and set individual flags like moderate/nomail/etc. It takes a little poking around in the source of the Mailman pages to see what variables need to be set in the POST, and some trial and error. I suggest setting up a temp Mailman list just to play with.
In order to do most of this, you'll need a persistent CookieContainer that you can hook up to your different HttpWebRequests; the first call is a POST to the admin page with the admin password to set the session cookie that gives you access to the other pages.
Some of the POSTs are regular application/x-www-form-urlencoded types, but some are also multipart/form-data. For the latter, I found some very helpful code at http://www.briangrinstead.com/blog/multipart-form-post-in-c I had to make a couple of changes so that I could pass in my CookieContainer
Here's some sample code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;
using System.Data;
using System.Threading;
namespace UpdateListserv
{
class Program
{
static void Main(string[] args)
{
try
{
File.Delete(_logFilename);
Log(String.Format("Starting: {0}", DateTime.Now));
Login();
var roster = GetSubscribers();
Unsubscribe(roster);
string members = GetMemberEmails();
Subscribe(members);
Unmoderate("foo#example.com");
Log("Done");
}
catch(Exception e)
{
Log(e.Message);
}
}
private static void Unmoderate(string email)
{
Log("Unmoderating " + email);
email = email.Replace("#", "%40");
_vars.Clear();
_vars["user"] = email;
_vars[email + "_nomail"] = "off";
_vars[email + "_nodupes"] = "on";
_vars[email + "_plain"] = "on";
_vars[email + "_language"] = "en";
_vars["setmemberopts_btn"] = "Submit Your Changes";
FormUpload.MultipartFormDataPost(_adminUrl + _membersPage, "foobar", _vars, _cookies);
}
private static CookieContainer _cookies = new CookieContainer();
private static string _adminUrl = "http://mylist.com/admin.cgi/listname";
private static string _rosterUrl = "http://mylist.com/roster.cgi/listname";
private static string _pw = "myPassword";
private static string _adminEmail = "foo#example.com";
private static Dictionary<string, object> _vars = new Dictionary<string, object>();
private static string _addPage = "/members/add";
private static string _removePage = "/members/remove";
private static string _membersPage = "/members";
private static string _logFilename = "Update Listserv.log";
private static void Log(string message)
{
Console.WriteLine(message);
using (var log = File.AppendText(_logFilename))
log.WriteLine(message);
}
private static void Subscribe(string members)
{
// members is a list of email addresses separated by \n
Log("Subscribing everyone");
_vars.Clear();
_vars["subscribees"] = members;
_vars["subscribe_or_invite"] = 0;
_vars["send_welcome_msg_to_this_batch"] = 0;
_vars["send_notifications_to_list_owner"] = 0;
FormUpload.MultipartFormDataPost(_adminUrl + _addPage, "foobar", _vars, _cookies);
}
private static string GetMemberEmails()
{
// This method retrieves a list of emails to be
// subscribed from an external source
// and returns them as a string with \n in between.
}
private static void Unsubscribe(string roster)
{
// roster is a list of email addresses separated by \n
Log("Unsubscribing everybody");
_vars.Clear();
_vars["unsubscribees"] = roster;
_vars["send_unsub_ack_to_this_batch"] = 0;
_vars["send_unsub_notifications_to_list_owner"] = 0;
FormUpload.MultipartFormDataPost(_adminUrl + _removePage, "foobar", _vars, _cookies);
}
private static string GetSubscribers()
{
// returns a list of email addresses subscribed to the list,
// separated by \n
Log("Getting subscriber list");
var req = GetWebRequest(_rosterUrl);
req.Method = "post";
_vars.Clear();
_vars["roster-email"] = _adminEmail;
_vars["roster-pw"] = _pw;
var rosterLines = GetResponseString(req).Split('\n').Where(l => l.StartsWith("<li>"));
Log(String.Format("Got {0} subscribers", rosterLines.Count()));
var roster = new List<string>();
var regex = new Regex("<a.*>(.*)</a>");
foreach (var line in rosterLines)
{
roster.Add(regex.Match(line).Groups[1].Value.Replace(" at ", "#"));
}
return String.Join("\n", roster);
}
private static void Login()
{
Log("Logging in to list admin panel");
var req = GetWebRequest(_adminUrl);
req.Method = "post";
_vars["adminpw"] = _pw;
SetPostVars(req);
req.GetResponse();
}
private static HttpWebRequest GetWebRequest(string url)
{
var result = HttpWebRequest.Create(url) as HttpWebRequest;
result.AllowAutoRedirect = true;
result.CookieContainer = _cookies;
result.ContentType = "application/x-www-form-urlencoded";
return result;
}
private static string GetResponseString(HttpWebRequest req)
{
using (var res = req.GetResponse())
using (var stream = res.GetResponseStream())
using (var sr = new StreamReader(stream))
{
return sr.ReadToEnd();
}
}
private static void SetPostVars(HttpWebRequest req)
{
var list = _vars.Select(v => String.Format("{0}={1}", v.Key, v.Value));
using (var stream = req.GetRequestStream())
using (var writer = new StreamWriter(stream))
{
writer.Write(String.Join("&", list));
}
}
}
}

Categories