[smuxi] [Engine] Initial JsonMessageBuffer implementation
- From: Mirco M. M. Bauer <mmmbauer src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [smuxi] [Engine] Initial JsonMessageBuffer implementation
- Date: Fri, 28 Feb 2014 20:23:55 +0000 (UTC)
commit 8b9e03ae5f18a43a33a61b60a9e195e4b737f3c7
Author: Mirco Bauer <meebey meebey net>
Date: Mon Feb 27 02:10:51 2012 +0100
[Engine] Initial JsonMessageBuffer implementation
src/Engine-Tests/JsonMessageBufferTests.cs | 49 ++++++
src/Engine/MessageBuffers/JsonMessageBuffer.cs | 195 ++++++++++++++++++++++++
src/Engine/Messages/Dto/MessageDtoModelV1.cs | 63 +++++++-
3 files changed, 303 insertions(+), 4 deletions(-)
---
diff --git a/src/Engine-Tests/JsonMessageBufferTests.cs b/src/Engine-Tests/JsonMessageBufferTests.cs
new file mode 100644
index 0000000..24d23bf
--- /dev/null
+++ b/src/Engine-Tests/JsonMessageBufferTests.cs
@@ -0,0 +1,49 @@
+// Smuxi - Smart MUltipleXed Irc
+//
+// Copyright (c) 2012 Mirco Bauer <meebey meebey net>
+//
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System;
+using System.IO;
+using NUnit.Framework;
+using Smuxi.Common;
+
+namespace Smuxi.Engine
+{
+ [TestFixture]
+ public class JsonMessageBufferTests : MessageBufferTestsBase
+ {
+ protected override IMessageBuffer CreateBuffer()
+ {
+ var dbPath = Path.Combine(Platform.GetBuffersPath("testuser"),
+ "testprot");
+ dbPath = Path.Combine(dbPath, "testnet");
+ dbPath = Path.Combine(dbPath, "testchat.v1.json");
+ if (Directory.Exists(dbPath)) {
+ Directory.Delete(dbPath, true);
+ }
+
+ return OpenBuffer();
+ }
+
+ protected override IMessageBuffer OpenBuffer()
+ {
+ return new JsonMessageBuffer("testuser", "testprot", "testnet", "testchat");
+ }
+
+ }
+}
diff --git a/src/Engine/MessageBuffers/JsonMessageBuffer.cs b/src/Engine/MessageBuffers/JsonMessageBuffer.cs
new file mode 100644
index 0000000..d1d4975
--- /dev/null
+++ b/src/Engine/MessageBuffers/JsonMessageBuffer.cs
@@ -0,0 +1,195 @@
+// Smuxi - Smart MUltipleXed Irc
+//
+// Copyright (c) 2012 Mirco Bauer <meebey meebey net>
+//
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System;
+using System.IO;
+using System.Text;
+using System.Collections.Generic;
+using ServiceStack.Text;
+using Smuxi.Engine.Dto;
+
+namespace Smuxi.Engine
+{
+ public class JsonMessageBuffer : MessageBufferBase
+ {
+#if LOG4NET
+ static readonly log4net.ILog f_Logger =
log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+#endif
+ int DefaultMaxChunkSize { get; set; }
+ int MaxChunkSize { get; set; }
+ string ChunkBasePath { get; set; }
+ Int64 FirstChunkOffset { get; set; }
+ Int64 CurrentChunkOffset { get; set; }
+ string CurrentChunkPath { get; set; }
+ List<MessageDtoModelV1> CurrentChunk { get; set; }
+
+ public override int Count {
+ get {
+ return (int) CurrentChunkOffset + CurrentChunk.Count;
+ }
+ }
+
+ public override MessageModel this[int index] {
+ get {
+ throw new NotImplementedException();
+ }
+ set {
+ throw new NotImplementedException();
+ }
+ }
+
+ public JsonMessageBuffer(string sessionUsername, string protocol,
+ string networkId, string chatId) :
+ base(sessionUsername, protocol, networkId, chatId)
+ {
+ DefaultMaxChunkSize = 1000;
+ MaxChunkSize = DefaultMaxChunkSize;
+ ChunkBasePath = GetBufferPath() + ".v1.json";
+ ScanChunks();
+ CurrentChunk = new List<MessageDtoModelV1>(MaxChunkSize);
+ }
+
+ string GetChunkFileName(Int64 index)
+ {
+ return null;
+ }
+
+ void ScanChunks()
+ {
+ if (!Directory.Exists(ChunkBasePath)) {
+ Directory.CreateDirectory(ChunkBasePath);
+ }
+ foreach (var filename in Directory.GetFiles(ChunkBasePath, "*.json")) {
+ var strNumber = filename.Substring(0, filename.IndexOf("."));
+ var strStartNumber = strNumber.Split('-')[0];
+ var strEndNumber = strNumber.Split('-')[1];
+ var intStartNumber = 0L;
+ var intEndNumber = 0L;
+ // find first chunk
+ Int64.TryParse(strStartNumber, out intStartNumber);
+ if (intStartNumber < FirstChunkOffset) {
+ FirstChunkOffset = intStartNumber;
+ }
+ // find current (newest) chunk
+ if (intStartNumber > CurrentChunkOffset) {
+ CurrentChunkOffset = intStartNumber;
+ MaxChunkSize = (int) (intEndNumber - intStartNumber + 1L);
+ }
+ }
+ RefreshCurrentChunkPath();
+ }
+
+ void RefreshCurrentChunkPath()
+ {
+ CurrentChunkPath = Path.Combine(
+ ChunkBasePath,
+ String.Format(
+ "{0}-{1}.json",
+ CurrentChunkOffset,
+ CurrentChunkOffset + MaxChunkSize - 1
+ )
+ );
+ }
+
+ void NextChunk()
+ {
+ Flush();
+ var chunk = new List<MessageDtoModelV1>(MaxChunkSize);
+ CurrentChunk = chunk;
+ CurrentChunkOffset += MaxChunkSize;
+ RefreshCurrentChunkPath();
+ }
+
+ void SerializeChunk(List<MessageDtoModelV1> chunk, TextWriter writer)
+ {
+ JsonSerializer.SerializeToWriter(chunk, writer);
+ }
+
+ List<MessageDtoModelV1> DeserializeChunk(Stream chunkStream)
+ {
+ return JsonSerializer.DeserializeFromStream<List<MessageDtoModelV1>>(chunkStream);
+ }
+
+ public override void Add(MessageModel item)
+ {
+ var chunk = CurrentChunk;
+ if (chunk.Count >= MaxChunkSize) {
+ NextChunk();
+ chunk = CurrentChunk;
+ }
+ chunk.Add(new MessageDtoModelV1(item));
+ }
+
+ public override void Clear()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override bool Contains(MessageModel item)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override void CopyTo(MessageModel[] array, int arrayIndex)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override bool Remove(MessageModel item)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override IEnumerator<MessageModel> GetEnumerator()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override int IndexOf(MessageModel item)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override void Insert(int index, MessageModel item)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override void RemoveAt(int index)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override void Flush()
+ {
+ // TODO: use compression?
+ lock (CurrentChunk) {
+ using (var writer = File.OpenWrite(CurrentChunkPath))
+ using (var textWriter = new StreamWriter(writer, Encoding.UTF8)) {
+ SerializeChunk(CurrentChunk, textWriter);
+ }
+ }
+ }
+
+ public override void Dispose()
+ {
+ Flush();
+ }
+ }
+}
diff --git a/src/Engine/Messages/Dto/MessageDtoModelV1.cs b/src/Engine/Messages/Dto/MessageDtoModelV1.cs
index aa6598d..35ce83f 100644
--- a/src/Engine/Messages/Dto/MessageDtoModelV1.cs
+++ b/src/Engine/Messages/Dto/MessageDtoModelV1.cs
@@ -28,6 +28,25 @@ namespace Smuxi.Engine.Dto
public List<MessagePartDtoModelV1> MessageParts { get; set; }
public MessageType MessageType { get; set; }
+ public MessageDtoModelV1()
+ {
+ }
+
+ public MessageDtoModelV1(MessageModel msg)
+ {
+ if (msg == null) {
+ throw new ArgumentNullException("msg");
+ }
+
+ TimeStamp = msg.TimeStamp;
+ MessageType = msg.MessageType;
+ MessageParts = new List<MessagePartDtoModelV1>(msg.MessageParts.Count);
+ foreach (var msgPart in msg.MessageParts) {
+ var dtoPart = new MessagePartDtoModelV1(msgPart);
+ MessageParts.Add(dtoPart);
+ }
+ }
+
public MessageModel ToMessage()
{
var msg = new MessageModel() {
@@ -50,9 +69,11 @@ namespace Smuxi.Engine.Dto
break;
case "URL":
var urlPart = new UrlMessagePartModel() {
- Url = msgPart.Url,
- Protocol = msgPart.Protocol
+ Url = msgPart.Url
};
+ if (msgPart.Protocol.HasValue) {
+ urlPart.Protocol = msgPart.Protocol.Value;
+ }
part = urlPart;
break;
case "Image":
@@ -87,10 +108,44 @@ namespace Smuxi.Engine.Dto
public string Text { get; set; }
// UrlMessagePartModel
public string Url { get; set; }
- public UrlProtocol Protocol { get; set; }
+ public UrlProtocol? Protocol { get; set; }
// ImageMessagePartModel
public string ImageFileName { get; set; }
public string AlternativeText { get; set; }
+
+ public MessagePartDtoModelV1()
+ {
+ }
+
+ public MessagePartDtoModelV1(MessagePartModel part)
+ {
+ if (part == null) {
+ throw new ArgumentNullException("part");
+ }
+
+ IsHighlight = part.IsHighlight;
+ if (part is TextMessagePartModel) {
+ var textPart = (TextMessagePartModel) part;
+ Type = "Text";
+ ForegroundColor = textPart.ForegroundColor;
+ BackgroundColor = textPart.BackgroundColor;
+ Underline = textPart.Underline;
+ Bold = textPart.Bold;
+ Italic = textPart.Italic;
+ Text = textPart.Text;
+ }
+ if (part is UrlMessagePartModel) {
+ var urlPart = (UrlMessagePartModel) part;
+ Type = "URL";
+ Url = urlPart.Url;
+ Protocol = urlPart.Protocol;
+ }
+ if (part is ImageMessagePartModel) {
+ var imagePart = (ImageMessagePartModel) part;
+ Type = "Image";
+ ImageFileName = imagePart.ImageFileName;
+ AlternativeText = imagePart.AlternativeText;
+ }
+ }
}
}
-
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]