/// <summary> /// The route handler for the request, which selects the current themes /// and returns them as JSON. If the current theme for today does not /// exist, the app creates a new theme for today. /// </summary> /// <param name="context">The context containing the request and /// response.</param> public override void ProcessRequest(HttpContext context) { Theme currentTheme = null; ArrayList themes = new ArrayList(); DateTime today = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day); DateTime tomorrow = today.AddDays(1); // Select the historical list of themes PhotoHunt.model.PhotohuntContext db = new PhotoHunt.model.PhotohuntContext(); var themeQuery = from b in db.Themes where b.start < DateTime.Now orderby b.start descending select b; foreach (Theme t in themeQuery) { themes.Add(new JsonTheme(t)); if (t.start < tomorrow && t.start >= today) { currentTheme = t; } } // If no theme exists for today, create the "beautiful" theme and add it. if (currentTheme == null) { themes.Add(new JsonTheme(ThemesHelper.GenerateDefaultTheme())); } SendResponse(context, themes); }
/// <summary> /// This is the code behind for the database inspector. /// All of the data used in the view is retrieved here. /// </summary> protected void Page_Load(object sender, EventArgs e) { try { user = new User((JObject)JsonConvert.DeserializeObject( Session[Properties.Resources.CURRENT_USER_SESSION_KEY].ToString()) ); } catch (NullReferenceException nre) { // This is fine because the interface could be accessed by someone not logged in. // If you wanted to add the notion of an administrator, you could add it to the // User model and enforce it here. Debug.WriteLine("Could not get user: "******"clear"] != null) { db.Database.Delete(); Session[Properties.Resources.CURRENT_USER_SESSION_KEY] = null; } var themeQuery = from b in db.Themes orderby b.start descending select b; foreach (Theme t in themeQuery) { latestTheme = t; themes.Add(t); } var photoQuery = from p in db.Photos select p; foreach (Photo photo in photoQuery) { photos.Add(photo); } var userQuery = from u in db.Users orderby u.googleDisplayName select u; foreach (User dbUser in userQuery) { usersList.Add(dbUser); userCount++; } bool showEdges = Request.Params["edges"] != null; if (showEdges) { var edgeQuery = from edge in db.Edges select edge; foreach (DirectedUserToEdge du in edgeQuery) { edges.Add(du); } } }
/// <summary> /// Gets the current PhotoHunt theme for today. /// </summary> /// <returns>The current PhotoHunt theme on success; otherwise, returns null.</returns> static public Theme GetCurrentTheme() { // Select today's theme DateTime today = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day); DateTime tomorrow = today.AddDays(1); PhotoHunt.model.PhotohuntContext db = new PhotoHunt.model.PhotohuntContext(); return(db.Themes.First(theme => theme.start >= today && theme.start < tomorrow)); }
/// <summary> /// Gets the current PhotoHunt theme for today. /// </summary> /// <returns>The current PhotoHunt theme on success; otherwise, returns null.</returns> public static Theme GetCurrentTheme() { // Select today's theme DateTime today = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day); DateTime tomorrow = today.AddDays(1); PhotoHunt.model.PhotohuntContext db = new PhotoHunt.model.PhotohuntContext(); return db.Themes.First(theme => theme.start >= today && theme.start < tomorrow); }
/// <summary> /// Retrieves photos for the selected theme, user, or user's friends. /// </summary> /// <param name="hasThemeIdParam">Indicates photos should be scoped to a theme.</param> /// <param name="hasUserIdParam">Indicates photos should be scoped to a user.</param> /// <param name="isFriends">Indicates photos are to be retrieved for a user's friends. /// </param> /// <param name="userId">The PhotoHunt user id to retrieve photos or the user's friend's /// photos.</param> /// <param name="selectedTheme">The selected PhotoHunt theme.</param> /// <returns>A list of objects that can be returned as JSON.</returns> public static ArrayList GetPhotos(bool hasThemeIdParam, bool hasUserIdParam, bool isFriends, int userId, Theme selectedTheme) { // This will store JSONified representations of photo objects. ArrayList photos = new ArrayList(); if (hasThemeIdParam && hasUserIdParam) { // Return the photos for this user for this theme. PhotohuntContext db = new PhotohuntContext(); var query = from b in db.Photos where b.themeId.Equals(selectedTheme.id) && b.ownerUserId.Equals(userId) select b; if (isFriends) { query = from b in db.Photos where b.themeId.Equals(selectedTheme.id) && b.ownerUserId.Equals(userId) select b; } foreach (Photo photo in query) { photo.voted = !VotesHelper.CanVote(userId, photo.id); photos.Add(photo); } } else if (hasUserIdParam) { // Return this user's photos. PhotohuntContext db = new PhotohuntContext(); var query = from b in db.Photos where b.ownerUserId.Equals(userId) select b; foreach (Photo photo in query) { photos.Add(photo); } } else if (hasThemeIdParam) { // Return the photos for the current theme PhotohuntContext db = new PhotohuntContext(); var query = from b in db.Photos where b.themeId.Equals(selectedTheme.id) select b; foreach (Photo photo in query) { photos.Add(photo); } } return photos; }
/// <summary> /// Delete a user's photo. /// </summary> /// <param name="context">The context containing the request, response, and so on.</param> /// <param name="user">The PhotoHunt user deleting the photo.</param> /// <param name="photo">The Photo object to be deleted.</param> public static void DeletePhoto(HttpContext context, User user, Photo toDelete) { // User will be NULL if there isn't someone signed in. if (user == null || user.id != toDelete.ownerUserId) { context.Response.StatusCode = 401; context.Response.StatusDescription = "Unauthorized request."; return; } PhotohuntContext dbRemove = new PhotohuntContext(); dbRemove.Entry(toDelete).State = EntityState.Deleted; dbRemove.SaveChanges(); }
/// <summary> /// Creates friend edges within the model for each match between this user's visible people /// and others who already exist in the database. /// </summary> /// <param name="user">The user object to create friend edges for.</param> /// <param name="ps">The Google+ API client service.</param> /// <returns>None.</returns> public static void GenerateFriends(User user, PlusService ps) { // Get the PeopleFeed for the currently authenticated user using the Google+ API. PeopleResource.ListRequest lr = ps.People.List("me", PeopleResource.CollectionEnum.Visible); PeopleFeed pf = lr.Fetch(); PhotohuntContext db = new PhotohuntContext(); do { foreach (Person p in pf.Items) { // Check whether the friend has an account on PhotoHunt bool userExists = db.Users.Any(u => u.googleUserId.Equals(p.Id)); if (userExists) { // Check whether friend edge already exists. User friend = db.Users.First(f => f.googleUserId.Equals(p.Id)); bool edgeExists = db.Edges.Any(e => e.photohuntUserId == user.id && e.friendUserId == friend.id); // Only add new edges when the user exists on PhotoHunt and the edge doesn't // already exist if (!edgeExists && userExists && friend.id != user.id) { // Save the friend edges. DirectedUserToEdge fromFriendEdge = new DirectedUserToEdge(); fromFriendEdge.friendUserId = friend.id; fromFriendEdge.photohuntUserId = user.id; db.Edges.Add(fromFriendEdge); DirectedUserToEdge toFriendEdge = new DirectedUserToEdge(); toFriendEdge.friendUserId = user.id; toFriendEdge.photohuntUserId = friend.id; db.Edges.Add(toFriendEdge); db.SaveChanges(); } } } lr.PageToken = pf.NextPageToken; pf = lr.Fetch(); } while (pf.NextPageToken != null); }
/// <summary> /// Remove all of the friend edges associated with a PhotoHunt user. /// </summary> /// <param name="toRemove">The user whose friend edges will be removed.</param> public static void RemoveFriendEdges(User toRemove) { PhotohuntContext db = new PhotohuntContext(); // Remove this user's edges. var query = from b in db.Edges where b.photohuntUserId.Equals(toRemove.id) select b; foreach (var edge in query) { db.Entry(edge).State = EntityState.Deleted; } // Remove this user from friend edges. var friendEdgeQuery = from b in db.Edges where b.friendUserId.Equals(toRemove.id) select b; foreach (var edge in friendEdgeQuery) { db.Entry(edge).State = EntityState.Deleted; } db.Entry(toRemove).State = EntityState.Deleted; // Remove this user's photos var photosQuery = from b in db.Photos where b.ownerUserId.Equals(toRemove.id) select b; foreach (var photo in photosQuery) { // Remove votes for this photo. var photoVotesQuery = from b in db.Votes where b.photoId.Equals(photo.id) select b; foreach (var vote in photoVotesQuery) { db.Entry(vote).State = EntityState.Deleted; } // Remove the photo from the DB. db.Entry(photo).State = EntityState.Deleted; } db.SaveChanges(); }
/// <summary> /// Tests whether a user can vote on a photo. /// </summary> /// <param name="user">The PhotoHunt user who is voting.</param> /// <param name="photoId">The id of the PhotoHunt photo being voted on.</param> /// <returns>True if the user can vote on the photo; otherwise, returns false.</returns> public static bool CanVote(int userId, int photoId) { PhotohuntContext db = new PhotohuntContext(); // Protect against self-votes. if (db.Photos.Any(p => p.ownerUserId == userId && p.id == photoId)) { return false; } // Protect against duplicate votes. if (db.Votes.Any(v => v.ownerUserId == userId && v.photoId == photoId)) { return false; } return true; }
/// <summary> /// Adds a new theme to PhotoHunt. /// </summary> /// <param name="displayName">The name shown on the theme.</param> /// <param name="startDate">The starting date for the theme.</param> /// <returns></returns> public static Theme AddTheme(string displayName, DateTime startDate) { PhotoHunt.model.PhotohuntContext db = new PhotoHunt.model.PhotohuntContext(); Theme newTheme = new Theme(); newTheme.createdTime = DateTime.Now; System.Globalization.DateTimeFormatInfo mfi = new System.Globalization.DateTimeFormatInfo(); newTheme.created = mfi.GetMonthName(newTheme.createdTime.Month) + " " + newTheme.createdTime.Day + ", " + newTheme.createdTime.Year; newTheme.displayName = displayName; newTheme.start = startDate; newTheme.previewPhotoId = 0; db.Themes.Add(newTheme); db.SaveChanges(); return newTheme; }
/// <summary> /// Adds a new theme to PhotoHunt. /// </summary> /// <param name="displayName">The name shown on the theme.</param> /// <param name="startDate">The starting date for the theme.</param> /// <returns></returns> static public Theme AddTheme(string displayName, DateTime startDate) { PhotoHunt.model.PhotohuntContext db = new PhotoHunt.model.PhotohuntContext(); Theme newTheme = new Theme(); newTheme.createdTime = DateTime.Now; System.Globalization.DateTimeFormatInfo mfi = new System.Globalization.DateTimeFormatInfo(); newTheme.created = mfi.GetMonthName(newTheme.createdTime.Month) + " " + newTheme.createdTime.Day + ", " + newTheme.createdTime.Year; newTheme.displayName = displayName; newTheme.start = startDate; newTheme.previewPhotoId = 0; db.Themes.Add(newTheme); db.SaveChanges(); return(newTheme); }
/// <summary> /// Get a user's PhotoHunt friends. /// </summary> /// <param name="user">The user whose friend's are retrieved.</param> /// <returns>A list of the JsonUsers representing the selected user's friends.</returns> static public ArrayList GetFriends(User user) { // Find the edges, convert them into JsonUsers, and return as JSON. PhotoHunt.model.PhotohuntContext db = new PhotoHunt.model.PhotohuntContext(); var edgeQuery = from b in db.Edges where b.photohuntUserId.Equals(user.id) select b; ArrayList people = new ArrayList(); foreach (var edge in edgeQuery) { PhotoHunt.model.PhotohuntContext dbInner = new PhotoHunt.model.PhotohuntContext(); var friendQuery = from b in dbInner.Users where b.id.Equals(edge.friendUserId) select b; foreach (var friend in friendQuery) { people.Add(new JsonUser(friend)); } } return(people); }
/// <summary> /// Upvotes a photo and writes an app activity for the vote action. /// </summary> /// <param name="context">The request and response object with the user in session. /// </param> /// <returns>On success, returns the Photo object for the image voted on. On failure, /// returns null.</returns> public Photo DoVote(HttpContext context, int photoId) { User user = GetUser(context); // User will be NULL if there isn't someone signed in. if (user == null) { return null; } if (!CanVote(user.id, photoId)){ return null; } // Create the vote and increment the vote count for this photo. PhotohuntContext db = new PhotohuntContext(); Vote v = new Vote(); v.photoId = photoId; v.ownerUserId = user.id; db.Votes.Add(v); db.SaveChanges(); var photoQuery = from b in db.Photos where b.id == photoId select b; Photo voteTarget = null; foreach (Photo currPhoto in photoQuery) { voteTarget = currPhoto; } voteTarget.numVotes += 1; db.SaveChanges(); WriteGooglePlusVoteAppActivity(user, voteTarget); return voteTarget; }
/// <summary> /// Retrieves a theme given the parameter string for the theme. /// </summary> /// <param name="themeIdParam">The identifier for the theme.</param> /// <returns>The specified theme or will fallback to a new default theme.</returns> static public Theme GetSelectedTheme(string themeIdParam) { // Select the current theme if we haven't been passed a theme if (themeIdParam == null) { Theme t = ThemesHelper.GetCurrentTheme(); if (t != null) { return(t); } } else { // Retrieve the theme using the id from the request. int themeId = int.Parse(themeIdParam); PhotoHunt.model.PhotohuntContext dbthemes = new PhotoHunt.model.PhotohuntContext(); return(dbthemes.Themes.First(t => t.id == themeId)); } // Fallback to the default theme if no themes exist return(ThemesHelper.GenerateDefaultTheme()); }
/// <summary> /// Remove all of a user's votes from the PhotoHunt database. /// </summary> /// <param name="toRemove">The user whose votes will be removed.</param> public static void RemoveVotes(User toRemove) { PhotohuntContext db = new PhotohuntContext(); // Remove this user's votes and decrement vote count. var votesQuery = from b in db.Votes where b.ownerUserId == toRemove.id select b; foreach (var vote in votesQuery) { PhotohuntContext dbInner = new PhotohuntContext(); Photo voteTarget = dbInner.Photos.First(p => p.id == vote.photoId); voteTarget.numVotes -= 1; dbInner.SaveChanges(); db.Entry(vote).State = EntityState.Deleted; } db.SaveChanges(); }
/// <summary> /// Either: /// 1. Create a user for the given ID and credential /// 2. Or, update the existing user with the existing credential /// /// If 2, then ask Google for the user's public profile information to store. /// </summary> /// <param name="authState">The OAuth v2 state for authorizing the user.</param> /// <returns>A User object that represents the created user.</returns> public User SaveTokenForUser(IAuthorizationState authState) { // Set the auth state in a the superclass for the authorization call. _authState = authState; var provider = new WebServerClient(GoogleAuthenticationServer.Description); provider.ClientIdentifier = CLIENT_ID; provider.ClientSecret = CLIENT_SECRET; var authenticator = new OAuth2Authenticator<WebServerClient>( provider, GetAuthorization) { NoCaching = true }; ps = new PlusService(authenticator); Person me = ps.People.Get("me").Fetch(); // Load the user model from the DB if the user already exists. bool userExists = false; User user = new User(); PhotohuntContext db = new PhotohuntContext(); User existing = db.Users.FirstOrDefault(u => u.googleUserId.Equals(me.Id)); if (existing != null) { user = existing; userExists = true; } if (!userExists) { // Save the new user. user.googleAccessToken = authState.AccessToken; user.googleRefreshToken = authState.RefreshToken == null ? "" : authState.RefreshToken; user.googleExpiresIn = (int)(authState.AccessTokenExpirationUtc.Value - authState.AccessTokenIssueDateUtc.Value).TotalSeconds; user.googleExpiresAt = authState.AccessTokenExpirationUtc.Value; user.googleUserId = me.Id; user.googleDisplayName = me.DisplayName; user.googlePublicProfilePhotoUrl = me.Image.Url; user.googlePublicProfileUrl = me.Url; user.email = me.Emails == null ? "" : me.Emails[0].Value; db.Users.Add(user); db.SaveChanges(); db.Entry(user); // Use the FriendsHelper to generate this user's list of friends // who also use this app. PhotoHunt.utils.FriendsHelper.GenerateFriends(user, ps); } else { // Update the existing user's authorization state. Note that we aren't updating the // refresh token because it is only returned the first time the user authorizes the // app. user.googleAccessToken = authState.AccessToken; user.googleExpiresIn = (int)(authState.AccessTokenExpirationUtc.Value - authState.AccessTokenIssueDateUtc.Value).TotalSeconds; user.googleExpiresAt = authState.AccessTokenExpirationUtc.Value; db.SaveChanges(); } return user; }
/// <summary> /// Get a user's PhotoHunt friends. /// </summary> /// <param name="user">The user whose friend's are retrieved.</param> /// <returns>A list of the JsonUsers representing the selected user's friends.</returns> public static ArrayList GetFriends(User user) { // Find the edges, convert them into JsonUsers, and return as JSON. PhotoHunt.model.PhotohuntContext db = new PhotoHunt.model.PhotohuntContext(); var edgeQuery = from b in db.Edges where b.photohuntUserId.Equals(user.id) select b; ArrayList people = new ArrayList(); foreach (var edge in edgeQuery) { PhotoHunt.model.PhotohuntContext dbInner = new PhotoHunt.model.PhotohuntContext(); var friendQuery = from b in dbInner.Users where b.id.Equals(edge.friendUserId) select b; foreach (var friend in friendQuery) { people.Add(new JsonUser(friend)); } } return people; }
/// <summary> /// Retrieves a theme given the parameter string for the theme. /// </summary> /// <param name="themeIdParam">The identifier for the theme.</param> /// <returns>The specified theme or will fallback to a new default theme.</returns> public static Theme GetSelectedTheme(string themeIdParam) { // Select the current theme if we haven't been passed a theme if (themeIdParam == null) { Theme t = ThemesHelper.GetCurrentTheme(); if (t != null) { return t; } } else { // Retrieve the theme using the id from the request. int themeId = int.Parse(themeIdParam); PhotoHunt.model.PhotohuntContext dbthemes = new PhotoHunt.model.PhotohuntContext(); return dbthemes.Themes.First(t => t.id == themeId); } // Fallback to the default theme if no themes exist return ThemesHelper.GenerateDefaultTheme(); }
/// <summary> /// Processes and uploads a photo from the currently signed-in user to PhotoHunt. /// </summary> /// <param name="context">The HttpContext containing the request with an image in it. /// </param> /// <param name="user">The currently sign-in user.</param> /// <param name="themeId">The id for the theme that the photo will be added to.</param> /// <param name="themeDisplayName">The display name for the theme that the photo will be /// added to.</param> /// <returns>The Photo object representing the uploaded photo.</returns> public static Photo UploadPhoto(HttpContext context, User user, Theme selectedTheme) { // User will be NULL if there isn't someone signed in. if (user == null) { context.Response.StatusCode = 401; context.Response.StatusDescription = "Unauthorized request."; return null; } // path is uploads/theme/userid/filename HttpPostedFile upload = context.Request.Files["image"]; string path = context.Server.MapPath("..") + "\\uploads\\"; Directory.CreateDirectory(path); path += selectedTheme.displayName + "\\"; Directory.CreateDirectory(path); path += user.id + "\\"; Directory.CreateDirectory(path); path += upload.FileName; upload.SaveAs(path); string urlpath = "uploads/" + selectedTheme.displayName + "/" + user.id + "/" + upload.FileName; string thumbPath = ResizePhoto(path, urlpath, user, selectedTheme.displayName, upload); // Save the photo using EF Photo dbPhoto = new Photo(); dbPhoto.ownerUserId = user.id; dbPhoto.ownerDisplayName = user.googleDisplayName; dbPhoto.ownerProfileUrl = user.googlePublicProfileUrl; dbPhoto.ownerProfilePhoto = user.googlePublicProfilePhotoUrl; dbPhoto.themeId = selectedTheme.id; dbPhoto.themeDisplayName = selectedTheme.displayName; dbPhoto.numVotes = 0; dbPhoto.voted = false; dbPhoto.created = (long) dbPhoto.ConvertToUnixTimestamp(DateTime.Now); dbPhoto.fullsizeUrl = BASE_URL + urlpath; dbPhoto.thumbnailUrl = thumbPath; // Save to set the ID for the remaining members. PhotohuntContext db = new PhotohuntContext(); db.Photos.Add(dbPhoto); db.SaveChanges(); dbPhoto.photoContentUrl = BASE_URL + "photo.aspx?photoId=" + dbPhoto.id; // Set the default theme photo id to this one dbPhoto.voteCtaUrl = BASE_URL + "photo.aspx" + "?photoId=" + dbPhoto.id + "&action=vote"; db.SaveChanges(); // Set the uploaded photo to the preview for the theme. Theme dbTheme = db.Themes.First(theme => theme.id == selectedTheme.id); dbTheme.previewPhotoId = dbPhoto.id; db.SaveChanges(); return dbPhoto; }