Skip to content

Commit

Permalink
Adding Universal Markdown as the new markdown parser. Also adding all…
Browse files Browse the repository at this point in the history
… of the submit post logic and a ton of UI tweaks and bug fixes.
  • Loading branch information
QuinnDamerell committed Dec 4, 2015
1 parent a396c63 commit 67e1d74
Show file tree
Hide file tree
Showing 49 changed files with 2,213 additions and 1,155 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "UniversalMarkdown"]
path = UniversalMarkdown
url = https://github.com/QuinnDamerell/UniversalMarkdown
1 change: 1 addition & 0 deletions BaconBackend/BaconBackend.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@
<Compile Include="Managers\Background\MessageOfTheDayManager.cs" />
<Compile Include="Managers\NetworkManager.cs" />
<Compile Include="Managers\SettingsManager.cs" />
<Compile Include="Managers\DraftManager.cs" />
<Compile Include="Managers\SubredditManager.cs" />
<Compile Include="Managers\TelemetryManager.cs" />
<Compile Include="Managers\TileManager.cs" />
Expand Down
6 changes: 6 additions & 0 deletions BaconBackend/BaconManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ public event EventHandler<OnBackButtonArgs> OnBackButton
/// </summary>
public TileManager TileMan { get; }

/// <summary>
/// Used for draft management.
/// </summary>
public DraftManager DraftMan { get; }

/// <summary>
/// Holds a connection to the front end, a way for things back here to
/// interact with the front end.
Expand All @@ -143,6 +148,7 @@ public BaconManager(bool isBackgroundTask)
BackgroundMan = new BackgroundManager(this);
MotdMan = new MessageOfTheDayManager(this);
TileMan = new TileManager(this);
DraftMan = new DraftManager(this);

// Don't do this if we are a background task; it will
// call this when it is ready.
Expand Down
2 changes: 0 additions & 2 deletions BaconBackend/Collectors/SubredditCollector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -395,8 +395,6 @@ override protected void ApplyCommonFormatting(ref List<Post> posts)
if (!String.IsNullOrEmpty(post.Selftext))
{
post.Selftext = WebUtility.HtmlDecode(post.Selftext);
// Some times things are double escaped. So do it twice.
post.Selftext = WebUtility.HtmlDecode(post.Selftext);
}

// Don't show link flair on the front page
Expand Down
148 changes: 146 additions & 2 deletions BaconBackend/Helpers/MiscellaneousHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Windows.Graphics.Imaging;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;

namespace BaconBackend.Helpers
{
Expand All @@ -26,6 +33,31 @@ public class RedditContentContainer
public string Comment;
}

public enum SubmiteNewPostErrors
{
NONE,
UNKNOWN,
INVALID_OPTION,
BAD_CAPTCHA,
BAD_URL,
SUBREDDIT_NOEXIST,
SUBREDDIT_NOTALLOWED,
SUBREDDIT_REQUIRED,
NO_SELFS,
NO_LINKS,
IN_TIMEOUT,
RATELIMIT,
DOMAIN_BANNED,
ALREADY_SUB
}

public class SubmitNewPostResponse
{
public bool Success = false;
public string NewPostLink = String.Empty;
public SubmiteNewPostErrors RedditError = SubmiteNewPostErrors.NONE;
}

public class MiscellaneousHelper
{
/// <summary>
Expand Down Expand Up @@ -140,6 +172,118 @@ public static async Task<bool> SaveOrHideRedditItem(BaconManager baconMan, strin
return wasSuccess;
}

/// <summary>
/// Submits a new reddit post
/// </summary>
public static async Task<SubmitNewPostResponse> SubmitNewPost(BaconManager baconMan, string title, string urlOrText, string subredditDisplayName, bool isSelfText, bool sendRepliesToInbox)
{
if (!baconMan.UserMan.IsUserSignedIn)
{
baconMan.MessageMan.ShowSigninMessage("submit a new post");
return new SubmitNewPostResponse(){ Success = false };
}

try
{
// Make the data
List<KeyValuePair<string, string>> data = new List<KeyValuePair<string, string>>();
data.Add(new KeyValuePair<string, string>("kind", isSelfText ? "self" : "link"));
data.Add(new KeyValuePair<string, string>("sr", subredditDisplayName));
data.Add(new KeyValuePair<string, string>("sendreplies", sendRepliesToInbox ? "true" : "false"));
if (isSelfText)
{
data.Add(new KeyValuePair<string, string>("text", urlOrText));
}
else
{
data.Add(new KeyValuePair<string, string>("url", urlOrText));
}
data.Add(new KeyValuePair<string, string>("title", title));

// Make the call
string jsonResponse = await baconMan.NetworkMan.MakeRedditPostRequest("/api/submit/", data);

// Try to see if we can find the word redirect and if we can find the subreddit url
string responseLower = jsonResponse.ToLower();
if (responseLower.Contains("redirect") && responseLower.Contains($"://www.reddit.com/r/{subredditDisplayName}/comments/"))
{
// Success, try to parse out the new post link
int startOfLink = responseLower.IndexOf($"://www.reddit.com/r/{subredditDisplayName}/comments/");
if(startOfLink == -1)
{
return new SubmitNewPostResponse() { Success = false };
}

int endofLink = responseLower.IndexOf('"', startOfLink);
if (endofLink == -1)
{
return new SubmitNewPostResponse() { Success = false };
}

// Try to get the link
string link = "https" + jsonResponse.Substring(startOfLink, endofLink - startOfLink);

// Return
return new SubmitNewPostResponse() { Success = true, NewPostLink = link};
}
else
{
// We have a reddit error. Try to figure out what it is.
for(int i = 0; i < Enum.GetNames(typeof(SubmiteNewPostErrors)).Length; i++)
{
string enumName = Enum.GetName(typeof(SubmiteNewPostErrors), i).ToLower(); ;
if (responseLower.Contains(enumName))
{
baconMan.TelemetryMan.ReportUnExpectedEvent("MisHelper", "failed to submit post; error: "+ enumName);
baconMan.MessageMan.DebugDia("failed to submit post; error: "+ enumName);
return new SubmitNewPostResponse() { Success = false, RedditError = (SubmiteNewPostErrors)i};
}
}

baconMan.TelemetryMan.ReportUnExpectedEvent("MisHelper", "failed to submit post; unknown reddit error: ");
baconMan.MessageMan.DebugDia("failed to submit post; unknown reddit error");
return new SubmitNewPostResponse() { Success = false, RedditError = SubmiteNewPostErrors.UNKNOWN };
}
}
catch (Exception e)
{
baconMan.TelemetryMan.ReportUnExpectedEvent("MisHelper", "failed to submit post", e);
baconMan.MessageMan.DebugDia("failed to submit post", e);
return new SubmitNewPostResponse() { Success = false };
}
}

/// <summary>
/// Uploads a image file to imgur.
/// </summary>
/// <param name="baconMan"></param>
/// <param name="image"></param>
/// <returns></returns>
public static string UploadImageToImgur(BaconManager baconMan, FileRandomAccessStream imageStream)
{
//try
//{
// // Make the data
// List<KeyValuePair<string, string>> data = new List<KeyValuePair<string, string>>();
// data.Add(new KeyValuePair<string, string>("key", "1a507266cc9ac194b56e2700a67185e4"));
// data.Add(new KeyValuePair<string, string>("title", "1a507266cc9ac194b56e2700a67185e4"));

// // Read the image from the stream and base64 encode it.
// Stream str = imageStream.AsStream();
// byte[] imageData = new byte[str.Length];
// await str.ReadAsync(imageData, 0, (int)str.Length);
// data.Add(new KeyValuePair<string, string>("image", WebUtility.UrlEncode(Convert.ToBase64String(imageData))));
// string repsonse = await baconMan.NetworkMan.MakePostRequest("https://api.imgur.com/2/upload.json", data);
//}
//catch (Exception e)
//{
// baconMan.TelemetryMan.ReportUnExpectedEvent("MisHelper", "failed to submit post", e);
// baconMan.MessageMan.DebugDia("failed to submit post", e);
// return new SubmitNewPostResponse() { Success = false };
//}
throw new NotImplementedException("This function isn't complete!");
}


/// <summary>
/// Attempts to parse out a reddit object from a reddit data object.
Expand Down Expand Up @@ -278,7 +422,7 @@ public static RedditContentContainer TryToFindRedditContentInLink(string url)
containter.Type = RedditContentType.Comment;
}
}
}
}
}
}
}
Expand All @@ -301,7 +445,7 @@ private static int FindNextUrlBreak(string url, int startingPos)
public static Color GetComplementaryColor(Color source)
{
Color inputColor = source;
// If RGB values are close to each other by a diff less than 10%, then if RGB values are lighter side,
// If RGB values are close to each other by a diff less than 10%, then if RGB values are lighter side,
// decrease the blue by 50% (eventually it will increase in conversion below), if RBB values are on darker
// side, decrease yellow by about 50% (it will increase in conversion)
byte avgColorValue = (byte)((source.R + source.G + source.B) / 3);
Expand Down
122 changes: 122 additions & 0 deletions BaconBackend/Managers/DraftManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;

namespace BaconBackend.Managers
{
/// <summary>
/// Used to contain data for post draft
/// </summary>
public class PostSubmissionDraftData
{
public string Title;
public string UrlOrText;
public string Subreddit;
public bool isSelfText;
}

public class DraftManager
{
const string c_postDraftFile = "PostSubmissionDraft.json";

BaconManager m_baconMan;

public DraftManager(BaconManager baconMan)
{
m_baconMan = baconMan;
}

/// <summary>
/// Returns if we have a draft file or not.
/// </summary>
/// <returns></returns>
public async Task<bool> HasPostSubmitDraft()
{
StorageFolder folder = Windows.Storage.ApplicationData.Current.LocalFolder;
IStorageItem file = await folder.TryGetItemAsync(c_postDraftFile);
return file != null;
}

/// <summary>
/// Saves a current post to the draft file.
/// </summary>
/// <param name="title"></param>
/// <param name="urlOrText"></param>
/// <param name="isSelfText"></param>
/// <param name="subreddit"></param>
public async Task<bool> SavePostSubmissionDraft(PostSubmissionDraftData data)
{
try
{
// Get the folder and file.
StorageFolder folder = Windows.Storage.ApplicationData.Current.LocalFolder;
StorageFile file = await folder.CreateFileAsync(c_postDraftFile, CreationCollisionOption.ReplaceExisting);

// Serialize the data
string fileData = JsonConvert.SerializeObject(data);

// Write to the file
await Windows.Storage.FileIO.WriteTextAsync(file, fileData);
}
catch(Exception e)
{
m_baconMan.MessageMan.DebugDia("failed to write draft", e);
m_baconMan.TelemetryMan.ReportUnExpectedEvent(this, "FailedToWriteDraftFile",e);
return false;
}
return true;
}

/// <summary>
/// Returns the current submission post draft
/// </summary>
/// <returns></returns>
public async Task<PostSubmissionDraftData> GetPostSubmissionDraft()
{
try
{
// Get the folder and file.
StorageFolder folder = Windows.Storage.ApplicationData.Current.LocalFolder;
StorageFile file = await folder.CreateFileAsync(c_postDraftFile, CreationCollisionOption.OpenIfExists);

// Check that is exists.
if(file == null)
{
return null;
}

// Get the data
string fileData = await Windows.Storage.FileIO.ReadTextAsync(file);

// Deseralize the data
return JsonConvert.DeserializeObject<PostSubmissionDraftData>(fileData);
}
catch (Exception e)
{
m_baconMan.MessageMan.DebugDia("failed to read draft", e);
m_baconMan.TelemetryMan.ReportUnExpectedEvent(this, "FailedToReadDraftFile", e);
return null;
}
}

/// <summary>
/// Deletes an existing draft
/// </summary>
public async void DiscardPostSubmissionDraft()
{
if(await HasPostSubmitDraft())
{
StorageFolder folder = Windows.Storage.ApplicationData.Current.LocalFolder;
StorageFile file = await folder.GetFileAsync(c_postDraftFile);
if (file != null)
{
await file.DeleteAsync();
}
}
}
}
}
4 changes: 2 additions & 2 deletions BaconBackend/Managers/SubredditManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ public async Task<Subreddit> GetSubredditFromWebByDisplayName(string displayName
}

// Format the subreddit
foundSubreddit.Description = WebUtility.HtmlDecode(WebUtility.HtmlDecode(foundSubreddit.Description));
foundSubreddit.Description = WebUtility.HtmlDecode(foundSubreddit.Description);
}

return foundSubreddit;
Expand Down Expand Up @@ -408,7 +408,7 @@ private void SetSubreddits(List<Subreddit> subreddits)
subreddit.IsFavorite = FavoriteSubreddits.ContainsKey(subreddit.Id);

// Escape the description, we need to do it twice because sometimes it is double escaped.
subreddit.Description = WebUtility.HtmlDecode(WebUtility.HtmlDecode(subreddit.Description));
subreddit.Description = WebUtility.HtmlDecode(subreddit.Description);

// Do a simple inert sort, account for favorites
bool wasAdded = false;
Expand Down
1 change: 1 addition & 0 deletions BaconBackend/Managers/TileManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public async Task<bool> CreateSubredditTile(Subreddit subreddit)
tile.VisualElements.ShowNameOnSquare150x150Logo = true;
tile.VisualElements.ShowNameOnSquare310x310Logo = true;
tile.VisualElements.ShowNameOnWide310x150Logo = true;
tile.RoamingEnabled = true;

// Request the create.
return await tile.RequestCreateAsync();
Expand Down
3 changes: 2 additions & 1 deletion BaconBackend/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"Microsoft.ApplicationInsights.PersistenceChannel": "1.2.3",
"Microsoft.ApplicationInsights.WindowsApps": "1.1.0",
"Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0",
"Newtonsoft.Json": "7.0.1"
"Newtonsoft.Json": "7.0.1",
"WriteableBitmapEx": "1.5.0"
},
"frameworks": {
"uap10.0": {}
Expand Down
Loading

0 comments on commit 67e1d74

Please sign in to comment.