@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Security.Cryptography;

@@ -69,11 +68,11 @@ public static bool Match(this string value, string pattern)
public static string[] SplitIntoChunks(this string toSplit, int chunkSize)
{
if (string.IsNullOrEmpty(toSplit))
return new string[] { "" };
return new[] { "" };

int stringLength = toSplit.Length;

int chunksRequired = (int)Math.Ceiling((decimal)stringLength / (decimal)chunkSize);
var chunksRequired = (int)Math.Ceiling(stringLength / (decimal)chunkSize);
var stringArray = new string[chunksRequired];

int lengthRemaining = stringLength;
@@ -120,7 +119,7 @@ public static string Truncate(this string input, int length, string suffix)
public static string[] ToLineArray(this string input)
{
if (input == null) return new string[] { };
return System.Text.RegularExpressions.Regex.Split(input, "\r\n");
return Regex.Split(input, "\r\n");
}

/// <summary>
@@ -130,7 +129,7 @@ public static string[] ToLineArray(this string input)
/// <returns>Strongly-typed string list, each containing one line</returns>
public static List<string> ToLineList(this string input)
{
List<string> output = new List<string>();
var output = new List<string>();
output.AddRange(input.ToLineArray());
return output;
}
@@ -167,21 +166,16 @@ public static string StripPathFromFilename(this string filename)
public static string RemoveForbiddenCharacters(this string toUse)
{
var filename = toUse.StripPathFromFilename();
string[] forbidden_chars = { "&", "/", "\\", " " };
foreach (string s in forbidden_chars)
{
filename = filename.Replace(s, string.Empty);
}
return filename;
string[] forbiddenChars = { "&", "/", "\\", " " };
return forbiddenChars.Aggregate(filename, (current, s) => current.Replace(s, string.Empty));
}

public static string ToSaltedHash(this string toUse)
{
//TODO: Custom salt from config file
// TODO: Custom salt from config file
var transform = string.Concat("Salt", toUse);
byte[] result = new byte[transform.Length];
SHA1 sha = new SHA1CryptoServiceProvider();
result = sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes(transform));
byte[] result = sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes(transform));
return Convert.ToBase64String(result);
}
}
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SimpleChat.Utilities
{
@@ -10,13 +10,13 @@ namespace SimpleChat.App_Start

using Ninject;
using Ninject.Web.Common;
using SimpleChat.DataAccess;
using SimpleChat.RavenStore;
using DataAccess;
using RavenStore;
using Raven.Client;

public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
private static readonly Bootstrapper Bootstrapper = new Bootstrapper();

/// <summary>
/// Starts the application
@@ -25,15 +25,15 @@ public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
Bootstrapper.Initialize(CreateKernel);
}

/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
Bootstrapper.ShutDown();
}

/// <summary>
@@ -56,7 +56,7 @@ private static IKernel CreateKernel()
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IDocumentStore>().ToMethod((x) => MvcApplication.Store);
kernel.Bind<IDocumentStore>().ToMethod(x => SimpleChatApplication.Store);
kernel.Bind<ISimpleChatRepository>().To<RavenRepository>();
}
}
@@ -1,6 +1,6 @@
* {margin:0; padding:0}
body{ margin:0; padding: 0; background-color: #99b5e5; font-family: Calibri, Verdana, Sans-Serif; background-image:url(/Content/bg.png); background-repeat:repeat-x;}
h1 { margin: 3px; padding:0; color: #fff; font-family: @Lithos Pro,Serif;}
h1 { margin: 3px; padding:0; color: #fff; font-family: Serif;}
h2, h3{ margin: 3px; border-bottom: 1px solid #000; }

ol, ul, li {margin-left: 15px; }
@@ -1,25 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using SimpleChat.Models;
using SimpleChat.Utils;
using SimpleChat.DataAccess;
using SimpleChat.RavenStore;
using SimpleChat.ViewModels;
using System.Threading;

namespace SimpleChat.Controllers
{
public class ChatroomsController : Controller
{
private ISimpleChatRepository repository;
private readonly ISimpleChatRepository _repository;

public ChatroomsController(ISimpleChatRepository repository)
{
//repository = new RavenRepository(MvcApplication.Store);
this.repository = repository;
_repository = repository;
}

// GET: /Chatrooms/
@@ -32,34 +27,43 @@ public ActionResult Index()
[RemoveOldChatroomsFilter]
public RedirectResult Create(string name, string url)
{
if (name == string.Empty || name == null)
if (string.IsNullOrEmpty(name))
name = "Simple Chat";

if (!string.IsNullOrEmpty(url) && repository.CheckChatUrl(url))
if (!string.IsNullOrEmpty(url) && _repository.CheckChatUrl(url))
{
TempData["error"] = "This url is already in use";
return Redirect("/");
}

var chat = repository.CreateChatroom(name, url);
var chat = _repository.CreateChatroom(name, url);
return Redirect("/" + chat.Url);
}

[RemoveOldChatroomsFilter]
[ActionName("View")]
public ActionResult View_Method(string path)
public ActionResult ViewMethod(string path)
{
try
{
if (path == "Default")
return RedirectToAction("Index", "Chatrooms", new { id = 1 });

var chat = repository.FindByUrl(path);
var chat = _repository.FindByUrl(path);

repository.UpdateParticipant(chat.Id, Session.SessionID, "Big Nose");

var vm = new ChatroomViewModel { ActiveParticipants = repository.GetParticipants(chat.Id), CreatedOn = chat.CreatedOn, Id = chat.Id, LastActionOn = chat.LastActionOn, Messages = repository.FetchMessages(chat.Id), Name = chat.Name, Url = chat.Url };
vm.ParticipantName = "Big Nose";
_repository.UpdateParticipant(chat.Id, Session.SessionID, "Big Nose");
var name = _repository.GetParticipantName(chat.Id, Session.SessionID);
var vm = new ChatroomViewModel
{
ActiveParticipants = _repository.GetParticipants(chat.Id),
CreatedOn = chat.CreatedOn,
Id = chat.Id,
LastActionOn = chat.LastActionOn,
Messages = _repository.FetchMessages(chat.Id),
Name = chat.Name,
Url = chat.Url,
ParticipantName = name
};
return View(vm);
}
catch
@@ -70,8 +74,8 @@ public ActionResult View_Method(string path)

public ActionResult AddMessage(int id, string name, string message)
{
var chat = repository.FindByID(id);
string return_message = string.Empty;
var chat = _repository.FindByID(id);
string returnMessage;
if (message.Trim() != string.Empty)
{
var mess = new Message
@@ -82,47 +86,44 @@ public ActionResult AddMessage(int id, string name, string message)
SentOn = DateTime.Now,
Ip = "NotLogged"
};
repository.UpdateParticipant(chat.Id, Session.SessionID, name);
repository.AddMessage(mess);
return_message = "Message Received";
_repository.UpdateParticipant(chat.Id, Session.SessionID, name);
_repository.AddMessage(mess);
returnMessage = "Message Received";
}
else
{
return_message = "Ignoring Empty Message";
returnMessage = "Ignoring Empty Message";
}
if (Request.IsAjaxRequest())
{
return new ContentResult { Content = return_message };
}
else
{
TempData["message"] = return_message;
return Redirect("/" + chat.Url);
return new ContentResult { Content = returnMessage };
}
TempData["message"] = returnMessage;
return Redirect("/" + chat.Url);
}

public ViewResult FetchMessages(string chat_url, int last_m_id)
{
//var messages = Message.FetchFor(chat_id);
var messages = repository.FetchMessagesAfter(chat_url, last_m_id);
var messages = _repository.FetchMessagesAfter(chat_url, last_m_id);
//System.Threading.Thread.Sleep(3000); //Simulate a high latency connection
return View(messages);
}

public ActionResult Transcript(int id)
{
var chat = repository.FindByID(id);
var chat = _repository.FindByID(id);
Response.AddHeader("content-disposition", "attachment; filename=Transcript-" + chat.Name + ".html");
ViewData["chat"] = chat;
ViewData["messages"] = repository.FetchMessages(chat.Id);
ViewData["messages"] = _repository.FetchMessages(chat.Id);
return View();
}

public ActionResult Participants(string url, string name)
{
var chat = repository.FindByUrl(url);
repository.UpdateParticipant(chat.Id, Session.SessionID, name);
return View(repository.GetParticipants(chat.Id));
var chat = _repository.FindByUrl(url);
_repository.UpdateParticipant(chat.Id, Session.SessionID, name);
return View(_repository.GetParticipants(chat.Id));
}
}
}
@@ -1 +1 @@
<%@ Application Codebehind="Global.asax.cs" Inherits="SimpleChat.MvcApplication" Language="C#" %>
<%@ Application Codebehind="Global.asax.cs" Inherits="SimpleChat.SimpleChatApplication" Language="C#" %>
@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Raven.Client.Document;
@@ -11,7 +8,7 @@ namespace SimpleChat
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
// visit http://go.microsoft.com/?LinkId=9394801

public class MvcApplication : System.Web.HttpApplication
public class SimpleChatApplication : System.Web.HttpApplication
{
public static DocumentStore Store { get; set; }

@@ -53,17 +50,19 @@ protected void Application_Start()
RegisterRoutes(RouteTable.Routes);

Store = new DocumentStore
{
ConnectionStringName = "RavenDB",
};
Store.Conventions.IdentityPartsSeparator = "-";
{
ConnectionStringName = "RavenDB",
Conventions = {IdentityPartsSeparator = "-"},
};
Store.Initialize();
}

protected void Session_Start()
{
//this insures that session id is available.
// ReSharper disable UnusedVariable
var sid = Session.SessionID;
// ReSharper restore UnusedVariable
}
}
}
@@ -32,32 +32,32 @@
var f = $("#message-form");
var action = f.attr("action");
var sform = f.serialize();
SendingMessage();
sendingMessage();
$.ajax({
url: action,
success: function (response) { $("#message-sent").text(response).css('display', 'inline').show().delay(5000).fadeOut('slow'); },
data: sform,
type: "POST",
error: function () { $("#message-error").css('display', 'inline').show().delay(5000).fadeOut('slow'); },
complete: function () { MessageSent() }
complete: function () { messageSent(); }
});
return false;
});

function SendingMessage() {
function sendingMessage() {
$("#message").attr("disabled", "disabled");
$("#processing").show();
}
function MessageSent() {
function messageSent() {
$("#message").removeAttr("disabled");
$("#processing").hide();
}

function FindCurrentChatUrl() {
function findCurrentChatUrl() {
return window.location.pathname.replace("/", "");
}

function FindLastMessageId() {
function findLastMessageId() {
//var mid = $(".message:last").attr('id').replace("m-", "");
if ($(".message:last").length == 0) {
return -1;
@@ -69,13 +69,13 @@
}

//Periodical check for messages
var executing_fetch = false; //this variable insure that we only have one async request at a time
var executingFetch = false; //this variable insure that we only have one async request at a time
function fetchMessages() {
if (!executing_fetch) {
executing_fetch = true;
var fetch_action = "/Chatrooms/FetchMessages/" + FindCurrentChatUrl() + "/" + FindLastMessageId();
if (!executingFetch) {
executingFetch = true;
var fetchAction = "/Chatrooms/FetchMessages/" + findCurrentChatUrl() + "/" + findLastMessageId();
$.ajax({
url: fetch_action,
url: fetchAction,
success: function (response) {
$("#conversation").append(response);
if (response.length > 10) {
@@ -88,24 +88,24 @@
},
type: "GET",
error: function () { $("#message-error").css('display', 'inline').show().delay(5000).fadeOut('slow'); },
complete: function () { executing_fetch = false; } //let them know they can execute another request
complete: function () { executingFetch = false; } //let them know they can execute another request
});
}
}
//this actually sets the check for messages. We're going to check it once a second.
var periodicCheck = setInterval(fetchMessages, 1000); //actually we're not that worried about performance.

//Periodical for handling participants
var executing_particpants = false;
var executingParticpants = false;
function fetchParticipants() {
if (!executing_particpants) {
executing_particpants = true;
var url = "/Chatrooms/Participants/" + FindCurrentChatUrl() + "/" + $("#name").val();
if (!executingParticpants) {
executingParticpants = true;
var url = "/Chatrooms/Participants/" + findCurrentChatUrl() + "/" + $("#name").val();
$.ajax({
url: url,
success: function (response) { $("#participants").html(response); },
type: "GET",
complete: function () { executing_particpants = false }
complete: function () { executingParticpants = false; }
});
}
}

This file was deleted.

This file was deleted.

@@ -139,8 +139,6 @@
<DependentUpon>Web.config</DependentUpon>
</Content>
<Content Include="Views\Web.config" />
<Content Include="Scripts\jquery-1.4.4.js" />
<Content Include="Scripts\jquery-1.4.4-vsdoc.js" />
<Content Include="Scripts\jquery-1.4.4.min.js" />
</ItemGroup>
<ItemGroup>
@@ -1,8 +1,4 @@
using System;
using System.Diagnostics;
using System.Web.Mvc;
using System.Web.Routing;
using SimpleChat.Models;
using System.Web.Mvc;
using SimpleChat.DataAccess;

namespace SimpleChat.Utils
@@ -11,7 +7,7 @@ public class RemoveOldChatroomsFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var repository = System.Web.Mvc.DependencyResolver.Current.GetService<ISimpleChatRepository>();
var repository = DependencyResolver.Current.GetService<ISimpleChatRepository>();
repository.RemoveOldChatrooms();
}
}
@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Collections.Generic;
using SimpleChat.Models;

namespace SimpleChat.ViewModels
@@ -4,5 +4,5 @@
}
@foreach (var message in Model)
{
@Html.Partial("Message", message);
@Html.Partial("Message", message)
}
@@ -1,6 +1,6 @@
@model List<SimpleChat.Models.Participant>
@{ Layout = null; }
@{ Layout = null; }
@foreach (var p in Model)
{
<div class="participant">@p.Name</div>
}
}
@@ -22,7 +22,7 @@
{
<div class="message" id="m-@message.Id %>">
<h3>@message.Name</h3>
<div class="message-content">@message.Content)</div>
<div class="message-content">@message.Content</div>
<div class="message-time">@message.SentOn.ToShortTimeString()</div>
<a name="message-@message.Id"></a>
</div>
@@ -5,9 +5,6 @@
}

<script src="/scripts/View.js" type="text/javascript" ></script>


<!--<div id="chatroom-url"><strong>url:</strong> <a href="@Request.Url.ToString() %>">@Request.Url.ToString() </a></div>-->
<h2>@Model.Name</h2>

<p id="NoJavascriptMessages"><strong>Your browser seems to have javascript disabled. You will need to refresh the page to view any new messages.</strong></p>