Created
August 2, 2021 20:13
-
-
Save SLaks/91d18f078bc5316727f8f59a3e1eebc4 to your computer and use it in GitHub Desktop.
ShulCloud Import Script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Run this in LINQPad, and add a reference to my https://github.com/ShomreiTorah/Libraries/tree/master/ShomreiTorah.Common | |
const string domain = "<TODO: insert domain here>"; | |
static readonly Regex parseId = new Regex(@"action=edit_addresses&id=(\d+)"); | |
static readonly Regex findSccsrf = new Regex(@"<input type=""hidden"" name=""sccsrf"" value=""(\w+)""/>"); | |
bool dryRun = false; | |
async Task Main() { | |
var cookies = new CookieContainer(); | |
cookies.Add(new Cookie("login_13530095", "TODO: Insert Cookie") { Domain = domain }); | |
cookies.Add(new Cookie("PHPSESSID", "TODO: Insert Cookie") { Domain = domain }); | |
cookies.Add(new Cookie("cookiesession1", "TODO: Insert Cookie") { Domain = domain }); | |
using (var httpHandler = new HttpClientHandler { CookieContainer = cookies }) | |
using (var http = new HttpClient(httpHandler) { BaseAddress = new Uri("https://" + domain) }) | |
using (var reader = DB.OpenFile($@"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}\TODO\ Members.xlsx").ExecuteReader("SELECT * FROM [Sheet1$]")) { | |
string GetCsrfToken() { | |
var responseMessage = http.GetAsync("/admin/settings.php?action=edit").GetAwaiter().GetResult(); | |
string response = responseMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult(); | |
return findSccsrf.Match(response).Groups[1].Value; | |
} | |
string SendRequest(string path, HttpContent content) { | |
if (dryRun) { | |
return @" | |
action=edit_addresses&id=99999 | |
<input type=""hidden"" name=""sccsrf"" value=""XSRF123ABC""/>"; | |
} | |
var responseMessage = http.PostAsync(path, content).GetAwaiter().GetResult(); | |
string response = responseMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult(); | |
if (response.Contains("Security Error")) throw new Exception($"Security Error from {path}"); | |
return response; | |
} | |
while (reader.Read()) { | |
var lastName = reader.GetField<string>("Last Name"); | |
var hisName = reader.GetField<string>("His Name"); | |
var herName = reader.GetField<string>("Her Name"); | |
if (lastName == null) { | |
Console.WriteLine($"Skipping {lastName}, {hisName} & {herName} due to nulls"); | |
continue; | |
} | |
Console.Write($"Entering {lastName}, {hisName} & {herName}... "); | |
// TODO: Update this logic to match your needs & IDs | |
var type = reader.GetField<string>("Membership status")?.Trim(); | |
var isFriend = type == "Friend of Shul"; | |
var isRecurring = type == "recurring"; | |
var tags = new List<string>() { "977784" }; | |
if (isRecurring) tags.Add("977794"); | |
if (type.StartsWith("paid")) tags.Add("980759"); | |
if (isFriend) tags.Add("980760"); | |
var response = SendRequest($"/admin/members.php?action=add", new FormUrlEncodedContent(ToPairs(new string[][]{ | |
new []{"sccsrf", GetCsrfToken()}, | |
new []{"action", "save_account"}, | |
new []{"redirect", "/admin/members.php?action=edit_addresses"}, | |
new []{"id", "0"}, | |
new []{"info[account_type_id]", isFriend ? "155871" : "155869"}, | |
new []{"info[is_account_name_overridden]", "N"}, | |
new []{"info[name]", $"{lastName}, {hisName} & {herName}"}, | |
new []{"info[is_active]", "Y"}, | |
new []{"switch_adults", "no"}, | |
new []{"adult1[first_name]",hisName}, | |
new []{"adult1[last_name]", lastName}, | |
new []{"adult1[member_type]", "120856"}, | |
new []{"adult1_gender[gender]", "M"}, | |
new []{"adult1[email]", reader.GetField<string>("Husband Email")}, | |
new []{"adult1[tribe]", "0"}, | |
new []{"adult1_tags", tags.Join(",")}, | |
new []{"adult1_perms[]", "11"}, | |
new []{"adult1_perms[]", "12"}, | |
new []{"adult1_perms[]", "10"}, | |
new []{"adult2[first_name]", herName}, | |
new []{"adult2[last_name]", lastName}, | |
new []{"adult2[member_type]", "120856"}, | |
new []{"adult2_gender[gender]", "F"}, | |
new []{"adult2[email]", reader.GetField<string>("Wife Email")}, | |
new []{"adult2[tribe]", "0"}, | |
new []{"adult2_tags", tags.Join(",")}, | |
new []{"adult2_perms[]", "11"}, | |
new []{"adult2_perms[]", "12"}, | |
new []{"adult2_perms[]", "10"}, | |
new []{"children[clone][delete]", "N"}, | |
new []{"children[clone][member_type]", "120857"}, | |
new []{"children_gender[clone][gender]", "custom"}, | |
new []{"children[clone][tribe]", "0"}, | |
new []{"other[marital_status_id]", "2"}, | |
new []{"info[account_billing_type_id]", "0"}, | |
new []{"loaded_multiselects", "Y"}, | |
new []{"unloaded_multiselects", "Y"}, | |
}))); | |
string id = parseId.Match(response).Groups[1].Value; | |
Console.Write($"ID: {id}... "); | |
SendRequest($"/admin/members.php?action=edit_addresses&id={id}", new FormUrlEncodedContent(ToPairs(new string[][]{ | |
new [] {"sccsrf", GetCsrfToken()}, | |
new [] {"action", "save_addresses"}, | |
new [] {"id", id}, | |
new [] {"site_account_default_address", "new_1"}, | |
new [] {"site_account_default_billing_address", "new_1"}, | |
new [] {"site_account_addresses[new][1][delete]", "N"}, | |
new [] {"site_account_addresses[new][1][short_name]", "Home"}, | |
new [] {"site_account_addresses[new][1][is_mail_name_overridden]", "N"}, | |
new [] {"site_account_addresses[new][1][mail_name]", $"{hisName} {lastName}"}, | |
new [] {"site_account_addresses[new][1][address]", reader.GetField<string>("Address")}, | |
new [] {"site_account_addresses[new][1][address2]"," "}, | |
new [] {"site_account_addresses[new][1][city]", reader.GetField<string>("City")}, | |
new [] {"use_state_select", "true"}, | |
new [] {"site_account_addresses[new][1][state]", reader.GetField<string>("State")}, | |
new [] {"site_account_addresses[new][1][zip]", reader.GetField<object>("Zip")?.ToString()}, | |
new [] {"site_account_addresses[new][1][country]", "USA"}, | |
new [] {"site_account_addresses[new][1][phone]"," "}, | |
new [] {"site_account_addresses[new][1][annual_default_start_month]", "00"}, | |
new [] {"site_account_addresses[new][1][annual_default_billing_start_month]", "00"}, | |
new [] {"info[update_phone_with_address]", "Y"}, | |
new [] {"loaded_multiselects", "Y"}, | |
new [] {"unloaded_multiselects", "Y"}, | |
}))); | |
Console.WriteLine("Done!"); | |
//if (!dryRun) break; | |
} | |
} | |
} | |
static IEnumerable<KeyValuePair<string, string>> ToPairs(string[][] pairs) { | |
return pairs.Where(a => a != null && a[1] != null).Select(p => new KeyValuePair<string, string>(p[0], p[1])); | |
} | |
// Define other methods and classes here | |
} static class Extensions { | |
public static T GetField<T>(this IDataRecord reader, string name) { | |
if (reader.IsDBNull(reader.GetOrdinal(name))) return default(T); | |
return (T)reader[name]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment