/// <summary> /// Delete the specified image /// </summary> /// <param name="filePath"></param> /// <param name="fileName"></param> public override void DeleteImage(string filePath, string key) { DeleteObjectRequest request = new DeleteObjectRequest(); request.WithBucketName("images.climbfind.com" + filePath) .WithKey(key); using (var client = Amazon.AWSClientFactory.CreateAmazonS3Client(Stgs.AWSAccessKey, Stgs.AWSSecretKey, S3Config)) { // simple object put using (DeleteObjectResponse response = client.DeleteObject(request)) { //-- Do a little bit of tracing string headersString = string.Empty; WebHeaderCollection headers = response.Headers; foreach (string h in headers.Keys) { headersString += string.Format("Response Header: {0}, Value: {1}", h, headers.Get(h)); } CfTrace.Information(TraceCode.DeletingImage, headersString); } } }
/// <summary> /// Called from authenticated facebook client 'accounts.climbfind.com' and the mobile app /// </summary> /// <param name="email"></param> /// <param name="fullName"></param> /// <param name="password"></param> /// <param name="nationality"></param> /// <param name="isMale"></param> /// <param name="facebookID"></param> /// <param name="facebookToken"></param> /// <param name="signUpOrigin"></param> /// <returns></returns> public Profile CreateUser(string email, string fullName, string password, byte nationality, bool isMale, long?facebookID, string facebookToken, string signUpOrigin) { try { bool detailsValid = true; //-- todo, perform some sort of validation on incoming details if (detailsValid) { MembershipCreateStatus createStatus; var mUser = Membership.CreateUser(email, password, email, null, null, true, null, out createStatus); if (createStatus != MembershipCreateStatus.Success) { throw new MembershipCreateUserException(createStatus); } else { var userID = new Guid(mUser.ProviderUserKey.ToString()); var user = CreateProfile(new Profile() { ID = userID, CountryID = nationality, Email = email, FullName = fullName, IsMale = isMale, FacebookID = facebookID, FacebookToken = facebookToken, PrivacyAllowNewConversations = true, PrivacyShowFeed = true, PrivacyShowHistory = true, PrivacyPostsDefaultIsPublic = true, PrivacyShowInSearch = true, PrivacyShowOnPartnerSites = true }); var traceMsg = string.Format("{0} created an account via {1}", fullName, signUpOrigin); if (facebookID.HasValue) { traceMsg += " w fbid: " + facebookID.Value.ToString(); } CfTrace.Information(TraceCode.UserCreateAccount, traceMsg); MailMan.SendAppEvent(TraceCode.UserCreateAccount, traceMsg, email, userID, "*****@*****.**", true); try { if (facebookID.HasValue) { var originalImgUrl = string.Format("http://graph.facebook.com/{0}/picture?type=large", facebookID.Value); using (Stream imgStream = new ImageDownloader().DownloadImageAsStream(originalImgUrl)) { //-- Note this function automatically updates the user object in the database SaveProfileAvatarPicFrom3rdPartSource(imgStream, user); } } } catch (Exception ex) { CfTrace.Error(ex); } return(user); } } else { throw new Exception("Sign up detail invalid from origin: " + signUpOrigin); } } catch (Exception ex) //-- extra logging / safety as we really don't want this code to screw up and if it does be better know about it! { if (!ex.Message.Contains("form required for an e-mail address") && !ex.Message.Contains("username is already in use")) { CfTrace.Error(ex); } throw ex; } }
/// <summary> /// Used: /// 1) In the case when the facebook ID does not match a profile, but the user is signed in to facebook (we check if we can connect the accounts) /// 2) When the user logs in with their CF3 email/password to a client (Accounts Server, PG Site, CF4, Mobile App) for the first time /// </summary> public Profile GetUserByEmailAndCreateCf4ProfileIfNotExists(string email) { var profile = profileRepo.GetProfileByEmail(email); if (profile == null) { var cf3Profile = new cf.DataAccess.cf3.ClimberProfileDA().GetClimberProfile(email); if (cf3Profile != default(Cf3Profile)) { var idStr = cf3Profile.ID.ToString(); string userName = idStr.Substring(idStr.Length - 9, 8); profile = new Profile() { ID = cf3Profile.ID, CountryID = byte.Parse(cf3Profile.Nationality.ToString()), DisplayNameTypeID = 0, Email = email, FullName = cf3Profile.FullName, IsMale = cf3Profile.IsMale.Value, NickName = cf3Profile.NickName, UserName = userName, ContactNumber = cf3Profile.ContractPhoneNumber, PrivacyAllowNewConversations = true, PrivacyShowFeed = true, PrivacyShowHistory = true, PrivacyPostsDefaultIsPublic = true, PrivacyShowInSearch = true, PrivacyShowOnPartnerSites = true }; profileRepo.Create(profile); var traceMsg = string.Format("{0} upgraded cf3 account", cf3Profile.FullName); CfTrace.Information(TraceCode.UserCreateAccount, traceMsg); MailMan.SendAppEvent(TraceCode.UserCreateAccount, traceMsg, email, cf3Profile.ID, "*****@*****.**", true); try { var originalImgUrl = GetCf3ProfilePicFullSizeUrl(cf3Profile.ID, cf3Profile.ProfilePictureFile); if (!string.IsNullOrWhiteSpace(originalImgUrl)) { using (Stream imgStream = new ImageDownloader().DownloadImageAsStream(originalImgUrl)) { if (imgStream == null) { throw new ArgumentException("Cf3 image stream is null for: " + originalImgUrl); } if (profile == null) { throw new ArgumentException("Profile is null..."); } //-- Note this function automatically updates the user object in the database SaveProfileAvatarPicFrom3rdPartSource(imgStream, profile); } } } catch (Exception ex) { CfTrace.Error(ex); } } } return(profile); }
/// <summary> /// /// </summary> /// <param name="dto"></param> public void ProcessPartnerCallWorkItem(PartnerCallAlertWorkItem dto) { IfNullThrowArgumentExceptionAndClearMsg(dto, "Cannot process PartnerCallAlertWorkItem, dto object is null.", ""); var pc = pcRepo.GetByID(dto.PartnerCallID); IfNullThrowArgumentExceptionAndClearMsg(pc, "Cannot process PartnerCallAlertWorkItem[{0}], PartnerCall is null.", dto.ToJson()); var post = new PostRepository().GetByID(pc.ID); if (post == null) { pcRepo.Delete(pc.ID); return; } //-- If they've deleted the post, let's not send out anything and delete the original call... var place = AppLookups.GetCacheIndexEntry(pc.PlaceID); //if (place == null) //-- Maybe we tried to read when //{ // //} IfNullThrowArgumentExceptionAndClearMsg(place, "Cannot process PartnerCallAlertWorkItem[{0}] for place[{1}], Place is null.", pc.ID, pc.PlaceID); var by = CfPerfCache.GetClimber(pc.UserID); IfNullThrowArgumentExceptionAndClearMsg(by, "Cannot process PartnerCallAlertWorkItem[{0}] for byUser[{1}], User is null.", pc.ID, pc.UserID); PCNWorkItem pcnWi = new PartnerCallNotificationWorkItem() { ID = Guid.NewGuid(), CreatedUtc = DateTime.UtcNow, CountryID = place.CountryID, OnBehalfOfUserID = by.ID, PartnerCallID = pc.ID, PlaceID = pc.PlaceID }; var alerts = new List <Alert>(); var msg = string.Format("<a href='/climber/{0}'>{1}</a> posted a <a href='/partner-call/{2}'>PartnerCall™</a> for <a href='{3}'>{4}</a>", by.ID, by.DisplayName, pc.ID, place.SlugUrl, place.Name); var deduciblePlaces = CfPerfCache.GetGeoDeduciblePlaces(place); var subscriptionsByUsers = pcsRepo.GetSubscriptionsForPlaces(deduciblePlaces.Select(p => p.ID).ToList()) .Where(s => s.UserID != pc.UserID).GroupBy(s => s.UserID); //-- We only want to create one Alert per user for a single partner call foreach (var subsUserSet in subscriptionsByUsers) { try { var subscribedUser = CfPerfCache.GetClimber(subsUserSet.Key); if (subscribedUser == null) { throw new ArgumentException(string.Format("Cannot process partner call subscription alerts for user[{0}] as user is null", subsUserSet.Key)); } var matchingSubs = new List <PCSubscription>(); foreach (var sub in subsUserSet) { if (sub.PlaceID == place.ID || !sub.ExactMatchOnly) //-- Here we make sure we don't include subscription with ExactMatchOnly chosen { //-- Make sure we match on Indoor/Outdoor preferences if ((sub.ForIndoor && pc.ForIndoor) || (sub.ForOutdoor && pc.ForOutdoor)) { matchingSubs.Add(sub); } } } if (matchingSubs.Count > 0) { var alert = new Alert() { ID = Guid.NewGuid(), Utc = DateTime.UtcNow, TypeID = (byte)AlertType.PartnerCall, PostID = pc.ID, UserID = subscribedUser.ID, Message = msg }; alert.ByFeed = true; //-- Here we always put partner calls in the alert feed (unless at a later date we decide to change this). //-- Default notifications bool sendEmail = false; bool sendMobilePush = false; int count = 1; string subscriptionPlaces = string.Empty; foreach (var sub in matchingSubs) { if (sub.EmailRealTime) { sendEmail = true; } if (sub.MobileRealTime) { sendMobilePush = true; } var p = AppLookups.GetCacheIndexEntry(sub.PlaceID); if (count == 1) { subscriptionPlaces = p.Name; } else if (count == matchingSubs.Count) { alert.Message += string.Format(" & {0}", p.Name); } else { alert.Message += string.Format(", {0}", p.Name); } count++; } if (matchingSubs.Count == 1) { alert.Message += ", <i>matching subscription for " + subscriptionPlaces + ".</i>"; } else { alert.Message += ", <i>matching subscriptions for " + subscriptionPlaces + ".</i>"; } if (sendEmail) { MailMan.SendPartnerCallEmail(subscribedUser, by, place, pc, subscriptionPlaces); alert.ByEmail = true; } //if (sendMobilePush) //{ //SendAlertByMobilePush(alert); // alert.ByMobile = true; //} alerts.Add(alert); } } catch (Exception ex) // Here we have a try catch incase it fails for one user we can try and still process the others { CfTrace.Error(ex); } } pcnWi.NotificationsSent = alerts.Count(); pcnWi.ProcessedUtc = DateTime.UtcNow; pcWRepo.Create(pcnWi); //-- We have to check this again to see if they delete the post while we were processing var postagain = new PostRepository().GetByID(pc.ID); if (postagain != null) { new AlertRepository().Create(alerts); } CfTrace.Information(TraceCode.PartnerCallNofiticatonWorkItemProcess, "Processed {4} <a href='/climber/{0}'>{1}'s</a> <a href='/partner-call/{2}'>PartnerCall™</a> for {3}.", by.ID, by.DisplayName, pc.ID, place.Name, alerts.Count); }