summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeroen Walter <jeroen@enormkansloos.nl>2012-08-04 20:21:29 +0200
committerJeroen Walter <jeroen@enormkansloos.nl>2012-08-04 20:21:29 +0200
commit25571d3846b3a6dba728e437f65b6e99db7f1c95 (patch)
tree74c36ae2630fcee46d453d49a669eb8b0b8c3710
parent05cff6f167f97568e8df58154b97f5cdbde1728f (diff)
downloadComicRackWeb-25571d3846b3a6dba728e437f65b6e99db7f1c95.zip
ComicRackWeb-25571d3846b3a6dba728e437f65b6e99db7f1c95.tar.gz
ComicRackWeb-25571d3846b3a6dba728e437f65b6e99db7f1c95.tar.bz2
- extended the web api interface
- ComicBook properties can now be set via the web api
-rw-r--r--ComicRackWebViewer/BCRSettings.cs82
-rw-r--r--ComicRackWebViewer/ComicRackWebViewer.csproj1
-rw-r--r--ComicRackWebViewer/Entities.cs14
-rw-r--r--ComicRackWebViewer/Modules/API.cs15
-rw-r--r--ComicRackWebViewer/Modules/BCRModule.cs165
-rw-r--r--ComicRackWebViewer/Program.py2
6 files changed, 249 insertions, 30 deletions
diff --git a/ComicRackWebViewer/BCRSettings.cs b/ComicRackWebViewer/BCRSettings.cs
new file mode 100644
index 0000000..b845815
--- /dev/null
+++ b/ComicRackWebViewer/BCRSettings.cs
@@ -0,0 +1,82 @@
+using System.Collections.Generic;
+using System.IO;
+using System.IO.IsolatedStorage;
+using System;
+using System.Xml.Serialization;
+
+namespace ComicRackWebViewer
+{
+ public class BCRSettings
+ {
+ private const string DIRECTORY = "ComicRack BCR";
+ private const string SETTINGS_FILE = "settings.xml";
+
+ public bool open_current_comic_at_launch { get; set; }
+ public bool open_next_comic { get; set; }
+ public int page_fit_mode { get; set; } // 1: Fit width, 2: Full page
+ public int zoom_on_tap { get; set; } // 0: off, 1: singletap, 2: doubletap
+ public int toggle_paging_bar { get; set; } // 0: off, 1: singletap, 2: doubletap
+ public bool use_page_turn_drag { get; set; }
+ public int page_turn_drag_threshold { get; set; }
+ public bool use_page_change_area { get; set; }
+ public int page_change_area_width { get; set; }
+
+
+ public BCRSettings()
+ {
+ open_current_comic_at_launch = true;
+ open_next_comic = true;
+ page_fit_mode = 1;
+ zoom_on_tap = 1;
+ toggle_paging_bar = 2;
+ use_page_turn_drag = true;
+ page_turn_drag_threshold = 75;
+ use_page_change_area = true;
+ page_change_area_width = 50;
+ }
+
+
+ public static string GetFilePath()
+ {
+ string folder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), DIRECTORY);
+ if (!Directory.Exists(folder))
+ {
+ Directory.CreateDirectory(folder);
+ }
+
+ string filepath = folder + "\\" + SETTINGS_FILE;
+ return filepath;
+ }
+
+ public static BCRSettings Load()
+ {
+ string filepath = GetFilePath();
+ if (!File.Exists(filepath))
+ {
+ BCRSettings settings = new BCRSettings();
+ settings.Save();
+ return settings;
+ }
+ else
+ {
+ XmlSerializer deserializer = new XmlSerializer(typeof(BCRSettings));
+ TextReader textReader = new StreamReader(filepath);
+
+ BCRSettings settings = (BCRSettings)deserializer.Deserialize(textReader);
+ textReader.Close();
+ return settings;
+ }
+ }
+
+ public void Save()
+ {
+ string filepath = GetFilePath();
+
+ XmlSerializer serializer = new XmlSerializer(this.GetType());
+ StreamWriter writer = new StreamWriter(filepath);
+ serializer.Serialize(writer.BaseStream, this);
+ }
+
+
+ }
+}
diff --git a/ComicRackWebViewer/ComicRackWebViewer.csproj b/ComicRackWebViewer/ComicRackWebViewer.csproj
index dd70e0e..75e93fd 100644
--- a/ComicRackWebViewer/ComicRackWebViewer.csproj
+++ b/ComicRackWebViewer/ComicRackWebViewer.csproj
@@ -112,6 +112,7 @@
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="BCRSettings.cs" />
<Compile Include="Bootstrapper.cs" />
<Compile Include="Modules\API.cs" />
<Compile Include="Modules\BCRModule.cs" />
diff --git a/ComicRackWebViewer/Entities.cs b/ComicRackWebViewer/Entities.cs
index 585b492..1be8818 100644
--- a/ComicRackWebViewer/Entities.cs
+++ b/ComicRackWebViewer/Entities.cs
@@ -7,6 +7,20 @@ using cYo.Projects.ComicRack.Engine.Database;
namespace ComicRackWebViewer
{
+ /*
+ public class BCRSettings {
+ public bool open_current_comic_at_launch { get; set; }
+ public bool open_next_comic { get; set; }
+ public int page_fit_mode { get; set; }
+ public int zoom_on_tap { get; set; }
+ public int toggle_paging_bar { get; set; }
+ public bool use_page_turn_drag { get; set; }
+ public int page_turn_drag_threshold { get; set; }
+ public bool use_page_change_area { get; set; }
+ public int page_change_area_width { get; set; }
+ }
+ */
+
// (Smart/Folder/Item) list
public class ComicList
diff --git a/ComicRackWebViewer/Modules/API.cs b/ComicRackWebViewer/Modules/API.cs
index 58dd58f..e775275 100644
--- a/ComicRackWebViewer/Modules/API.cs
+++ b/ComicRackWebViewer/Modules/API.cs
@@ -47,7 +47,6 @@ namespace ComicRackWebViewer
}
return new BooksList
{
- //Comics = context.ApplyODataUriFilter(list.GetBooks().Select(x => x.ToComic())).Cast<Comic>(),
Comics = list.GetBooks().Select(x => x.ToComic()),
Id = id
};
@@ -203,6 +202,20 @@ namespace ComicRackWebViewer
return null;
}
}
+
+ public static ComicBook GetComicBook(Guid id)
+ {
+ try
+ {
+ var comic = GetComics().First(x => x.Id == id);
+ return comic;
+ }
+ catch(Exception e)
+ {
+ //MessageBox.Show(e.ToString());
+ return null;
+ }
+ }
public static IQueryable<ComicBook> GetComics()
{
diff --git a/ComicRackWebViewer/Modules/BCRModule.cs b/ComicRackWebViewer/Modules/BCRModule.cs
index 7c6193e..d1755bf 100644
--- a/ComicRackWebViewer/Modules/BCRModule.cs
+++ b/ComicRackWebViewer/Modules/BCRModule.cs
@@ -6,34 +6,52 @@ using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
+using System.Reflection;
+using System.Diagnostics;
using cYo.Common;
using cYo.Projects.ComicRack.Engine;
using cYo.Projects.ComicRack.Engine.IO.Provider;
using cYo.Projects.ComicRack.Viewer;
using Nancy;
using Nancy.OData;
+using Nancy.ModelBinding;
+using Nancy.Responses;
-
-
namespace ComicRackWebViewer
{
+ public static class BCRExtensions
+ {
+ public static Response AsError(this IResponseFormatter formatter, HttpStatusCode statusCode, string message)
+ {
+ return new Response
+ {
+ StatusCode = statusCode,
+ ContentType = "text/plain",
+ Contents = stream => (new StreamWriter(stream) { AutoFlush = true }).Write(message)
+ };
+ }
+ }
+
public class BCRModule : NancyModule
{
public BCRModule()
: base("/BCR")
{
- Get["/"] = x => View["BCR.cshtml"];
+ Get["/"] = x => { return Response.AsRedirect("/viewer/index.html", RedirectResponse.RedirectType.Permanent); };
Get["/Lists"] = x => {
+
int depth = Request.Query.depth.HasValue ? int.Parse(Request.Query.depth) : -1;
return Response.AsOData(Program.Database.ComicLists.Select(c => c.ToComicList(depth)));
};
+
Get["/Lists/{id}"] = x => {
- IEnumerable<ComicList> list = Program.Database.ComicLists.Where(c => c.Id == new Guid(x.id)).Select(c => c.ToComicList());
+ int depth = Request.Query.depth.HasValue ? int.Parse(Request.Query.depth) : -1;
+ IEnumerable<ComicList> list = Program.Database.ComicLists.Where(c => c.Id == new Guid(x.id)).Select(c => c.ToComicList(depth));
if (list.Count() == 0)
{
- return HttpStatusCode.NotFound;
+ return Response.AsError(HttpStatusCode.NotFound, "List not found");
}
try
@@ -42,36 +60,44 @@ namespace ComicRackWebViewer
}
catch(Exception e)
{
- MessageBox.Show(e.ToString());
- return HttpStatusCode.InsufficientStorage;
+ return Response.AsError(HttpStatusCode.InsufficientStorage, e.ToString());
}
};
+ // For OData compatibility, count should be $count, but I don't know how to parse the $ with Nancy....
+ Get["/Lists/{id}/Comics/count"] = x => {
+ return Response.AsText(Context.ApplyODataUriFilter(API.GetIssuesOfListFromId(new Guid(x.id), Context).Comics).Count().ToString());
+ };
+
+ // Return the comics of the specified list using OData to filter the comic properties and the list paging.
Get["/Lists/{id}/Comics"] = x => {
-
+ bool wantsCount = Request.Query["$inlinecount"].HasValue;
+
try
{
return Response.AsOData(API.GetIssuesOfListFromId(new Guid(x.id), Context).Comics);
}
catch(Exception e)
{
- MessageBox.Show(e.ToString());
- return HttpStatusCode.InsufficientStorage;
+ return Response.AsError(HttpStatusCode.InsufficientStorage, e.ToString());
}
};
+ // Return the comicbook info as an OData filtered bag of properties.
Get["/Comics/{id}"] = x => {
Comic comic = API.GetComic(new Guid(x.id));
if (comic == null)
{
- return HttpStatusCode.NotFound;
+ return Response.AsError(HttpStatusCode.NotFound, "Comic not found");
}
return Response.AsOData(new List<Comic> { comic });
};
-
+
+
+ // Retrieve the specified page as a jpg file with the specified dimensions.
Get["/Comics/{id}/Pages/{page}"] = x => {
int width = Request.Query.width.HasValue ? int.Parse(Request.Query.width) : -1;
@@ -80,25 +106,108 @@ namespace ComicRackWebViewer
return API.GetPageImage(new Guid(x.id), int.Parse(x.page), width, height, Response);
};
-// Get["/views/{view}/(?<all>.*)"] = Render;
-
- }
-
- /*
- private Response Render(dynamic parameters) {
- String result = "View: " + parameters.view + "<br/>";
- foreach (var other in ((string)parameters.all).Split('/'))
- result += other + "<br/>";
-
- foreach (var name in Request.Query)
- result += name + ": " + Request.Query[name] + "<br/>";
+ // Get one property.
+ Get["/Comics/{id}/{property}"] = x => {
+ Comic comic = API.GetComic(new Guid(x.id));
+ if (comic == null)
+ {
+ return Response.AsError(HttpStatusCode.NotFound, "Comic not found");
+ }
- return result;
+ try
+ {
+ PropertyInfo property = comic.GetType().GetProperty(x.property);
+ object value = property.GetValue(comic, null);
+
+ return Response.AsJson(value);
+ }
+ catch(Exception e)
+ {
+ return Response.AsError(HttpStatusCode.NotFound, "Comic property not found");
+ }
+ };
+
+ // Update properties of the specified comicbook.
+ Put["/Comics/{id}"] = x => {
+
+ // Get the ComicBook entry from the library, so we can change it.
+ ComicBook book = API.GetComicBook(x.id);
+ if (book == null)
+ {
+ return Response.AsError(HttpStatusCode.NotFound, "Comic not found");
+ }
+
+ // Convert form values to temporary ComicBook object.
+ ComicBook info = this.Bind<ComicBook>();
+
+ IEnumerable<string> keys = Request.Form.GetDynamicMemberNames();
+
+ // This also triggers the update of the ComicRack application.
+ book.CopyDataFrom(info, keys);
+
+ return HttpStatusCode.OK;
+ };
+
+ // Update one property
+ Put["/Comics/{id}/{property}"] = x => {
+
+ // Convert form values to temporary Comic object.
+ string info = this.Bind<string>();
+
+
+ // Now get the ComicBook entry from the library, so we can change it.
+ ComicBook book = API.GetComicBook(x.id);
+ if (book == null)
+ {
+ return Response.AsError(HttpStatusCode.NotFound, "Comic not found");
+ }
+
+ // Setting one of these values also triggers the update of the ComicRack application.
+ book.SetValue(x.property, info);
+
+
+ return HttpStatusCode.OK;
+ };
+
+ // Get the BCR settings.
+ Get["/Settings"] = x => {
+ BCRSettings settings = BCRSettings.Load();
+ return Response.AsJson(settings, HttpStatusCode.OK);
+ };
+
+ // Update the BCR settings.
+ Put["/Settings"] = x => {
+
+ BCRSettings settings = this.Bind<BCRSettings>();
+ settings.Save();
+ return HttpStatusCode.OK;
+ };
+
+ Get["/Series"] = x => {
+ try
+ {
+ return Response.AsOData(API.GetSeries(), HttpStatusCode.OK);
+ }
+ catch(Exception e)
+ {
+ return Response.AsError(HttpStatusCode.BadRequest, e.ToString());
+ }
+ };
+
+
+ Get["/Publishers"] = x => {
+ try
+ {
+ return Response.AsOData(API.GetPublishers(), HttpStatusCode.OK);
+ }
+ catch(Exception e)
+ {
+ return Response.AsError(HttpStatusCode.BadRequest, e.ToString());
+ }
+ };
+
}
- */
-
}
-
}
diff --git a/ComicRackWebViewer/Program.py b/ComicRackWebViewer/Program.py
index 05fa984..cb0ecdb 100644
--- a/ComicRackWebViewer/Program.py
+++ b/ComicRackWebViewer/Program.py
@@ -16,7 +16,7 @@ def ComicRackWebViewer(books):
#@Name ComicRack Web (Startup)
#@Hook Startup
-#@Enabled false
+#@Enabled true
#@Image nancy.jpg
#@Description ComicRack Web (Startup)
def ComicRackWebViewerStartup():