diff --git a/Makefile b/Makefile index f26de73a..815600cf 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ VERSION=1.1 CONFIG=Debug DESTDIR=build/web/$(CONFIG) COPYUNCHANGED="false" -PREPRODHOST=yavsc.pschneider.fr +PREPRODHOST=yavsc.localdomain all: deploy @@ -27,6 +27,9 @@ clean: rsync-preprod: deploy rsync -ravu build/web/$(CONFIG)/ root@$(PREPRODHOST):/srv/www/yavsc +rsync-prod: deploy + rsync -ravu build/web/$(CONFIG)/ root@$(PREPRODHOST):/srv/www/lua + rsync-local: rsync -ravu build/web/$(CONFIG)/ root@localhost:/srv/www/yavsc diff --git a/SalesCatalog/Model/Catalog.cs b/SalesCatalog/Model/Catalog.cs index b29e9dbd..2fb41aaa 100644 --- a/SalesCatalog/Model/Catalog.cs +++ b/SalesCatalog/Model/Catalog.cs @@ -44,7 +44,7 @@ namespace SalesCatalog.Model Brand b = this.GetBrand (brandName); if (b == null) return false; - //assert(Brands.Length>0); + //ASSERT Brands.Length>0; List nb = new List (Brands); nb.Remove (b); Brands = nb.ToArray (); diff --git a/SalesCatalog/SalesCatalog.csproj b/SalesCatalog/SalesCatalog.csproj index a2e9aaa8..f8755f82 100644 --- a/SalesCatalog/SalesCatalog.csproj +++ b/SalesCatalog/SalesCatalog.csproj @@ -9,7 +9,6 @@ Library SalesCatalog SalesCatalog - v4.5 true diff --git a/WebControls/ResultPages.cs b/WebControls/ResultPages.cs index c1a9c8b2..79e9b402 100644 --- a/WebControls/ResultPages.cs +++ b/WebControls/ResultPages.cs @@ -89,7 +89,7 @@ namespace Yavsc.WebControls protected override void RenderContents (HtmlTextWriter writer) { - if (ResultCount > 0) { + if (ResultCount > 0 && ResultCount > ResultsPerPage ) { writer.WriteEncodedText (Text); int pageCount = ((ResultCount-1) / ResultsPerPage) + 1; for (int pi = (CurrentPage < 5) ? 0 : CurrentPage - 5; pi < pageCount && pi < CurrentPage + 5; pi++) { @@ -105,9 +105,10 @@ namespace Yavsc.WebControls writer.RenderEndTag (); writer.Write (" "); } - writer.Write ("("+ResultCount.ToString()+" resultat(s))"); - } else { - writer.Write ("(Pas de resultat)"); + writer.Write (ResultCount.ToString () + " resultat"); + if (ResultCount>1) writer.Write("s"); + } else if ( ResultCount == 0 ) { + writer.Write ("Pas de resultat"); } } } diff --git a/web/Admin/DataManager.cs b/web/Admin/DataManager.cs index a6700980..17870d58 100644 --- a/web/Admin/DataManager.cs +++ b/web/Admin/DataManager.cs @@ -13,13 +13,12 @@ namespace Yavsc.Admin { da = datac; } - public Export CreateBackup () { Environment.SetEnvironmentVariable("PGPASSWORD", da.Password); - Export e = new Export (); string fileName = da.BackupPrefix + "-" + DateTime.Now.ToString ("yyyyMMddhhmmss")+".tar"; FileInfo ofi = new FileInfo (fileName); + Export e = new Export (); e.FileName = ofi.FullName; /* Exec ("pg_dump", string.Format ( @@ -65,10 +64,12 @@ namespace Yavsc.Admin */ return t; } + public TaskOutput CreateDb () { return Restore ("freshinstall", false); } + public Export TagBackup (string filename, string [] tags) { /* FileInfo fi = new FileInfo (filename); diff --git a/web/Controllers/AccountController.cs b/web/Controllers/AccountController.cs index 4895643a..353130ad 100644 --- a/web/Controllers/AccountController.cs +++ b/web/Controllers/AccountController.cs @@ -229,19 +229,21 @@ namespace Yavsc.Controllers { string username = Membership.GetUser ().UserName; ViewData ["UserName"] = username; - if (AvatarFile != null) { - + if (AvatarFile == null) { + // do not update avatar to null since + // it's not in the model. + } + else { + // if said valid, move as avatar file + // else invalidate the model if (AvatarFile.ContentType == "image/png") { string avdir = Server.MapPath (AvatarDir); string avpath = Path.Combine (avdir, username + ".png"); AvatarFile.SaveAs (avpath); - string avuri = avpath.Substring ( - AppDomain.CurrentDomain.BaseDirectory.Length); - avuri = avuri.Replace (" ", "+"); - avuri = Request.Url.Scheme + "://" + Request.Url.Authority + "/" + avuri; - HttpContext.Profile.SetPropertyValue ("avatar", avuri); - HttpContext.Profile.Save (); - model.avatar = avuri; + model.avatar = + Path.Combine(AvatarDir.Substring(1),username)+".png"; + + } else ModelState.AddModelError ("Avatar", string.Format ("Image type {0} is not supported (suported formats : {1})", diff --git a/web/Controllers/AdminController.cs b/web/Controllers/AdminController.cs index eff21665..4141c6b3 100644 --- a/web/Controllers/AdminController.cs +++ b/web/Controllers/AdminController.cs @@ -178,7 +178,7 @@ namespace Yavsc.Controllers Roles.AddUserToRole (model.UserName, adminRoleName); ViewData ["Message"] = model.UserName + " was added to the role '" + adminRoleName + "'"; } else { - // assert (Roles.RoleExists (adminRoleName)) + // ASSERT (Roles.RoleExists (adminRoleName)) string [] admins = Roles.GetUsersInRole (adminRoleName); if (admins.Length > 0) { if (! admins.Contains (Membership.GetUser ().UserName)) { diff --git a/web/Controllers/BlogsController.cs b/web/Controllers/BlogsController.cs index 2431e929..d95df3b4 100644 --- a/web/Controllers/BlogsController.cs +++ b/web/Controllers/BlogsController.cs @@ -239,9 +239,8 @@ namespace Yavsc.Controllers public ActionResult Avatar (string user) { ProfileBase pr = ProfileBase.Create (user); - string avpath = (string) pr.GetPropertyValue ("avatar"); - if (avpath == null) { + if (avpath==null) { FileInfo fia = new FileInfo (Server.MapPath (defaultAvatar)); return File (fia.OpenRead (), defaultAvatarMimetype); } diff --git a/web/Controllers/GoogleController.cs b/web/Controllers/GoogleController.cs index 77dfd475..e6a3ae83 100644 --- a/web/Controllers/GoogleController.cs +++ b/web/Controllers/GoogleController.cs @@ -1,48 +1,27 @@ using System; using System.Collections.Generic; +using System.Configuration; +using System.IO; using System.Linq; -using System.Web; +using System.Net; +using System.Text; using System.Threading; -using System.Web.Mvc; -using System.Configuration; using System.Threading.Tasks; -using System.Text; +using System.Web; +using System.Web.Mvc; +using System.Web.Profile; +using System.Web.Security; using Mono.Security.Protocol.Tls; -using System.Net; -using System.IO; -using Yavsc.Model; using Newtonsoft.Json; +using Yavsc.Model; using Yavsc.Model.Google; using Yavsc.Model.RolesAndMembers; -using System.Web.Security; -using System.Web.Profile; +using Yavsc.Helpers.Google; namespace Yavsc.Controllers { - public class GoogleController : Controller { - // datetime format : yyyy-mm-ddTHH:MM:ss - // 2015-01-01T10:00:00-07:00 - private string API_KEY="AIzaSyBV_LQHb22nGgjNvFzZwnQHjao3Q7IewRw"; - - private static string getPeopleUri = "https://www.googleapis.com/plus/v1/people"; - private static string getCalListUri = "https://www.googleapis.com/calendar/v3/users/me/calendarList"; - private static string getCalEntriesUri = "https://www.googleapis.com/calendar/v3/calendars/{0}/events"; - - private static string CLIENT_ID = "325408689282-6bekh7p3guj4k0f3301a6frf025cnrk1.apps.googleusercontent.com"; - private static string CLIENT_SECRET = "MaxYcvJJCs2gDGvaELZbzwfL"; - - private static string[] SCOPES = { - "openid", - "profile", - "email" - }; - - private static string tokenUri = "https://accounts.google.com/o/oauth2/token"; - private static string authUri = "https://accounts.google.com/o/oauth2/auth"; - private static string dateFormat = "yyyy-MM-ddTHH:mm:ss"; - private string timeZone = "+02:00"; private string SetSessionSate () { @@ -52,63 +31,50 @@ namespace Yavsc.Controllers return state; } - public void Login (string returnUrl) - { - if (string.IsNullOrWhiteSpace (returnUrl)) - returnUrl = "/"; - Session ["returnUrl"] = returnUrl; - - string redirectUri = Request.Url.Scheme + "://" + Request.Url.Authority + "/Google/Auth"; - string scope = string.Join ("%20", SCOPES); - - string prms = String.Format ("response_type=code&client_id={0}&redirect_uri={1}&scope={2}&state={3}&include_granted_scopes=false", - CLIENT_ID, redirectUri, scope, SetSessionSate ()); - - GetAuthResponse (prms); + private string AuthGRU { + get { + return Request.Url.Scheme + "://" + + Request.Url.Authority + "/Google/Auth"; + } } - private void GetAuthResponse (string prms) - { - string cont = null; - WebRequest wr = WebRequest.Create (authUri + "?" + prms); - wr.Method = "GET"; - using ( - WebResponse response = wr.GetResponse ()) { - string resQuery = response.ResponseUri.Query; - cont = HttpUtility.ParseQueryString (resQuery) ["continue"]; - response.Close (); - + private string CalendarGRU { + get { + return Request.Url.Scheme + "://" + + Request.Url.Authority + "/Google/CalAuth"; } - wr.Abort (); - - Response.Redirect (cont); } - [Authorize] - public void GetCalAuth () + public void Login (string returnUrl) { - string redirectUri = Request.Url.Scheme + "://" + Request.Url.Authority + "/Google/CalAuth"; - string scope = string.Join ("%20", SCOPES); - scope += "%20https://www.googleapis.com/auth/calendar"; - string prms = String.Format ("response_type=code&client_id={0}&redirect_uri={1}&scope={2}&state={3}&include_granted_scopes=false&access_type=offline", - CLIENT_ID, redirectUri, scope, SetSessionSate ()); - Session ["calasked"] = true; - GetAuthResponse (prms); + if (string.IsNullOrWhiteSpace (returnUrl)) + returnUrl = "/"; + Session ["returnUrl"] = returnUrl; + OAuth2 oa = new OAuth2 (AuthGRU); + oa.Login (Response, SetSessionSate ()); } [HttpGet] [Authorize] + /// + /// Called after the Google authorizations screen, + /// we assume that Session contains a redirectUrl entry + /// + /// The auth. public ActionResult CalAuth () { - string redirectUri = Request.Url.Scheme + "://" + Request.Url.Authority + "/Google/CalAuth"; - AuthToken gat = GetToken (TokenPostDataFromCode(redirectUri, GetCodeFromRequest())); + string msg; + OAuth2 oa = new OAuth2 (CalendarGRU); + + AuthToken gat = oa.GetToken (Request, (string)Session ["state"], out msg); if (gat == null) { + ViewData ["Message"] = msg; return View ("Auth"); } SaveToken (gat); HttpContext.Profile.SetPropertyValue ("gcalapi", true); string returnUrl = (string)Session ["returnUrl"]; - Session ["returnUrl"]=null; + Session ["returnUrl"] = null; return Redirect (returnUrl); } @@ -119,130 +85,50 @@ namespace Yavsc.Controllers /// order to save a descent value as expiration date. /// /// Gat. - private void SaveToken(AuthToken gat) + private void SaveToken (AuthToken gat) { HttpContext.Profile.SetPropertyValue ("gtoken", gat.access_token); - if (gat.refresh_token!=null) + if (gat.refresh_token != null) HttpContext.Profile.SetPropertyValue ("grefreshtoken", gat.refresh_token); HttpContext.Profile.SetPropertyValue ("gtokentype", gat.token_type); - HttpContext.Profile.SetPropertyValue ("gtokenexpir", DateTime.Now.AddSeconds(gat.expires_in)); + HttpContext.Profile.SetPropertyValue ("gtokenexpir", DateTime.Now.AddSeconds (gat.expires_in)); HttpContext.Profile.Save (); } - private string GetCodeFromRequest() - { - string code = Request.Params ["code"]; - string error = Request.Params ["error"]; - if (error != null) { - ViewData ["Message"] = - string.Format (LocalizedText.Google_error, - LocalizedText.ResourceManager.GetString (error)); - return null; - } - string state = Request.Params ["state"]; - if (state != null && string.Compare ((string)Session ["state"], state) != 0) { - ViewData ["Message"] = - LocalizedText.ResourceManager.GetString ("invalid request state"); - return null; - } - return code; - } - private AuthToken GetToken (string postdata) - { - Byte[] bytes = System.Text.Encoding.UTF8.GetBytes (postdata); - HttpWebRequest webreq = WebRequest.CreateHttp (tokenUri); - webreq.KeepAlive = false; - webreq.Timeout = 5000; - webreq.Proxy = null; - // Not implemented: webreq.ServicePoint.ConnectionLeaseTimeout = 5000; - webreq.ServicePoint.MaxIdleTime = 5000; - webreq.Method = "POST"; - webreq.Accept = "application/json"; - webreq.ContentType = "application/x-www-form-urlencoded"; - webreq.ContentLength = bytes.Length; - using (Stream dataStream = webreq.GetRequestStream ()) { - dataStream.Write (bytes, 0, bytes.Length); - dataStream.Close (); - } - AuthToken gat =null; - using (WebResponse response = webreq.GetResponse ()) { - using (Stream responseStream = response.GetResponseStream ()) { - using (StreamReader readStream = new StreamReader (responseStream, Encoding.UTF8)) { - string responseStr = readStream.ReadToEnd (); - gat = JsonConvert.DeserializeObject (responseStr); - readStream.Close (); - } - responseStream.Close (); - } - response.Close(); - } - webreq.Abort (); - - return gat; - } - - private string TokenPostDataFromCode(string redirectUri, string code) - { - string postdata = - string.Format ( - "redirect_uri={0}&client_id={1}&client_secret={2}&code={3}&grant_type=authorization_code", - HttpUtility.UrlEncode (redirectUri), - HttpUtility.UrlEncode (CLIENT_ID), - HttpUtility.UrlEncode (CLIENT_SECRET), - HttpUtility.UrlEncode (code)); - return postdata; - } [HttpGet] public ActionResult Auth () { - string redirectUri = Request.Url.Scheme + "://" + Request.Url.Authority + "/Google/Auth"; - AuthToken gat = GetToken (TokenPostDataFromCode( redirectUri, GetCodeFromRequest())); + string msg; + OAuth2 oa = new OAuth2 (AuthGRU); + AuthToken gat = oa.GetToken (Request, (string)Session ["state"], out msg); if (gat == null) { + ViewData ["Message"] = msg; return View (); } string returnUrl = (string)Session ["returnUrl"]; - SignIn regmod = new SignIn (); - HttpWebRequest webreppro = WebRequest.CreateHttp (getPeopleUri + "/me"); - webreppro.ContentType = "application/http"; - webreppro.Headers.Add (HttpRequestHeader.Authorization, gat.token_type + " " + gat.access_token); - webreppro.Method = "GET"; - using (WebResponse proresp = webreppro.GetResponse ()) { - using (Stream prresponseStream = proresp.GetResponseStream ()) { - using (StreamReader readproresp = new StreamReader (prresponseStream, Encoding.UTF8)) { - string prresponseStr = readproresp.ReadToEnd (); - People me = JsonConvert.DeserializeObject (prresponseStr); - // TODO use me.id to retreive an existing user - string accEmail = me.emails.Where (x => x.type == "account").First ().value; - MembershipUserCollection mbrs = Membership.FindUsersByEmail (accEmail); - if (mbrs.Count == 1) { - // TODO check the google id - // just set this user as logged on - FormsAuthentication.SetAuthCookie (me.displayName, true); - Session ["returnUrl"] = null; - prresponseStream.Close (); - proresp.Close (); - webreppro.Abort (); - return Redirect (returnUrl); - } - // else create the account - regmod.Email = accEmail; - regmod.UserName = me.displayName; - Session ["me"] = me; - Session ["GoogleAuthToken"] = gat; - webreppro.Abort (); - - } - prresponseStream.Close (); - } - proresp.Close (); - } - webreppro.Abort (); + People me = PeopleApi.GetMe (gat); + // TODO use me.id to retreive an existing user + string accEmail = me.emails.Where (x => x.type == "account").First ().value; + MembershipUserCollection mbrs = Membership.FindUsersByEmail (accEmail); + if (mbrs.Count == 1) { + // TODO check the google id + // just set this user as logged on + FormsAuthentication.SetAuthCookie (me.displayName, true); + Session ["returnUrl"] = null; + + return Redirect (returnUrl); + } + // else create the account + regmod.Email = accEmail; + regmod.UserName = me.displayName; + Session ["me"] = me; + Session ["GoogleAuthToken"] = gat; return Auth (regmod); } @@ -311,22 +197,12 @@ namespace Yavsc.Controllers return View (regmod); } - private string GetFreshGoogleCredential (ProfileBase pr) + + [Authorize] + [HttpGet] + ActionResult PushPos () { - string token = (string) pr.GetPropertyValue ("gtoken"); - string token_type = (string) pr.GetPropertyValue ("gtokentype"); - DateTime token_exp = (DateTime) pr.GetPropertyValue ("gtokenexpir"); - if (token_exp < DateTime.Now) { - string refresh_token = (string) pr.GetPropertyValue ("grefreshtoken"); - AuthToken gat = GetToken( - string.Format("grant_type=refresh_token&client_id={0}&client_secret={1}&refresh_token={2}", - CLIENT_ID, CLIENT_SECRET, refresh_token)); - token = gat.access_token; - pr.SetPropertyValue ("gtoken", token); - pr.Save (); - // assert gat.token_type == token_type - } - return token_type + " " + token; + return View (); } [Authorize] @@ -336,29 +212,15 @@ namespace Yavsc.Controllers Session ["ChooseCalReturnUrl"] = returnUrl; bool hasCalAuth = (bool)HttpContext.Profile.GetPropertyValue ("gcalapi"); if (!hasCalAuth) { - Session["returnUrl"] = Request.Url.Scheme + "://" + Request.Url.Authority + "/Google/ChooseCalendar"; + Session ["returnUrl"] = Request.Url.Scheme + "://" + Request.Url.Authority + "/Google/ChooseCalendar"; return RedirectToAction ("GetCalAuth"); } - - string cred = GetFreshGoogleCredential (HttpContext.Profile); - - HttpWebRequest webreq = WebRequest.CreateHttp (getCalListUri); - webreq.Headers.Add (HttpRequestHeader.Authorization, cred); - webreq.Method = "GET"; - webreq.ContentType = "application/http"; - CalendarList res = null; - using (WebResponse resp = webreq.GetResponse ()) { - using (Stream respstream = resp.GetResponseStream ()) { - using (StreamReader readresp = new StreamReader (respstream, Encoding.UTF8)) { - string responseStr = readresp.ReadToEnd (); - res = JsonConvert.DeserializeObject (responseStr); - ViewData ["json"] = responseStr; - } - } - resp.Close (); - } - webreq.Abort (); - return View (res); + string cred = OAuth2.GetFreshGoogleCredential (HttpContext.Profile); + string json; + Calendar c = new Calendar (); + CalendarList cl = c.GetCalendars (cred, out json); + ViewData ["json"] = json; + return View (cl); } [HttpPost] @@ -368,7 +230,7 @@ namespace Yavsc.Controllers HttpContext.Profile.SetPropertyValue ("gcalid", calchoice); HttpContext.Profile.Save (); - string returnUrl = (string) Session ["ChooseCalReturnUrl"]; + string returnUrl = (string)Session ["ChooseCalReturnUrl"]; if (returnUrl != null) { Session ["ChooseCalReturnUrl"] = null; return Redirect (returnUrl); @@ -378,14 +240,14 @@ namespace Yavsc.Controllers [Authorize] [HttpGet] - public ActionResult DateQuery() + public ActionResult DateQuery () { return View (new AskForADate ()); } [Authorize] [HttpPost] - public ActionResult DateQuery(AskForADate model) + public ActionResult DateQuery (AskForADate model) { if (ModelState.IsValid) { if (model.MinDate < DateTime.Now) { @@ -397,14 +259,14 @@ namespace Yavsc.Controllers return View (model); } var muc = Membership.FindUsersByName (model.UserName); - if (muc.Count==0) { + if (muc.Count == 0) { ModelState.AddModelError ("UserName", "Non existent user"); return View (model); } ProfileBase upr = ProfileBase.Create (model.UserName); - string calid = (string) upr.GetPropertyValue ("gcalid"); - if (string.IsNullOrWhiteSpace(calid)) { + string calid = (string)upr.GetPropertyValue ("gcalid"); + if (string.IsNullOrWhiteSpace (calid)) { ModelState.AddModelError ("UserName", "L'utilisateur n'a pas de calendrier Google associé."); return View (model); } @@ -415,52 +277,17 @@ namespace Yavsc.Controllers DateTime maxdate = model.MaxDate; maxdate = maxdate.AddHours (int.Parse (model.MaxTime.Substring (0, 2))); maxdate = maxdate.AddMinutes (int.Parse (model.MaxTime.Substring (3, 2))); - string uri = string.Format ( - getCalEntriesUri, HttpUtility.UrlEncode(calid)) + - string.Format ("?orderBy=startTime&singleEvents=true&timeMin={0}&timeMax={1}&key="+API_KEY, - HttpUtility.UrlEncode(mindate.ToString (dateFormat)+timeZone) , - HttpUtility.UrlEncode(maxdate.ToString (dateFormat)+timeZone) ); - HttpWebRequest webreq = WebRequest.CreateHttp (uri); - string cred = GetFreshGoogleCredential (upr); - webreq.Headers.Add (HttpRequestHeader.Authorization, cred); - webreq.Method = "GET"; - webreq.ContentType = "application/http"; - CalendarEntryList res = null; + Calendar c = new Calendar (); + CalendarEntryList res; + string responseStr; try { - using (WebResponse resp = webreq.GetResponse ()) { - using (Stream respstream = resp.GetResponseStream ()) { - using (StreamReader readresp = new StreamReader (respstream, Encoding.UTF8)) { - string responseStr = readresp.ReadToEnd (); - try { - ViewData ["json"] = responseStr; - res = JsonConvert.DeserializeObject (responseStr); - } - catch (JsonReaderException ex) { - respstream.Close (); - resp.Close (); - webreq.Abort (); - return View ("JsonReaderError", new JsonReaderError() {Text= responseStr, Excepx = ex}); - } - } - respstream.Close (); - } - resp.Close (); - } - } - catch (WebException ex) - { - string message; - using (var stream = ex.Response.GetResponseStream()) - using (var reader = new StreamReader(stream)) - { - message = reader.ReadToEnd(); - } - webreq.Abort (); - return View ("JsonReaderError", new JsonReaderError() {Text= message, Excepx = ex}); - + res = c.GetCalendar (calid, mindate, maxdate, upr, out responseStr); + } catch (GoogleErrorException ex) { + ViewData ["Title"] = ex.Title; + ViewData ["Content"] = ex.Content; + return View ("GoogleErrorMessage", ex); } - webreq.Abort (); return View (res); } return View (model); diff --git a/web/Helpers/BBCodeHelper.cs b/web/Helpers/BBCodeHelper.cs index a2c01756..456e0bef 100644 --- a/web/Helpers/BBCodeHelper.cs +++ b/web/Helpers/BBCodeHelper.cs @@ -130,7 +130,7 @@ namespace Yavsc.Helpers for (int i = 1; i<=m1; i++) { string t1 = toc [i, 0, 0]; - // assert t1 != null + // ASSERT t1 != null ttb.AppendFormat ("{0}) {1}
\n", i, t1); for (int j = 1; j <= m2; j++) { diff --git a/web/Helpers/Google/ApiClient.cs b/web/Helpers/Google/ApiClient.cs new file mode 100644 index 00000000..9d7808c7 --- /dev/null +++ b/web/Helpers/Google/ApiClient.cs @@ -0,0 +1,58 @@ +// +// Manager.cs +// +// Author: +// Paul Schneider +// +// Copyright (c) 2015 Paul Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +using System; +using Yavsc.Helpers; +using System.Web.Profile; +using Yavsc.Model.Google; +using System.Net; +using System.IO; +using System.Text; +using Newtonsoft.Json; + +namespace Yavsc.Helpers.Google +{ + + public class ApiClient + { + protected static string CLIENT_ID = "325408689282-6bekh7p3guj4k0f3301a6frf025cnrk1.apps.googleusercontent.com"; + protected static string CLIENT_SECRET = "MaxYcvJJCs2gDGvaELZbzwfL"; + protected static string API_KEY="AIzaSyBV_LQHb22nGgjNvFzZwnQHjao3Q7IewRw"; + /* // to use in descendence + * + protected static string getPeopleUri = "https://www.googleapis.com/plus/v1/people"; + private static string authUri = "https://accounts.google.com/o/oauth2/auth"; + */ + + protected static string scopeTracks = "https://www.googleapis.com/auth/tracks"; + protected static string scopeCalendar = "https://www.googleapis.com/auth/calendar"; + protected static string[] scopeOpenid = { + "openid", + "profile", + "email" + }; + + // private static string dateFormat = "yyyy-MM-ddTHH:mm:ss"; + + + } + +} diff --git a/web/Helpers/Google/Calendar.cs b/web/Helpers/Google/Calendar.cs new file mode 100644 index 00000000..4badd376 --- /dev/null +++ b/web/Helpers/Google/Calendar.cs @@ -0,0 +1,103 @@ +// +// Calendar.cs +// +// Author: +// Paul Schneider +// +// Copyright (c) 2015 Paul Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +using System; +using Yavsc.Helpers; +using System.Web.Profile; +using Yavsc.Model.Google; +using System.Net; +using System.IO; +using System.Text; +using Newtonsoft.Json; +using System.Web; + +namespace Yavsc.Helpers.Google +{ + public class Calendar: ApiClient + { + protected static string getCalListUri = "https://www.googleapis.com/calendar/v3/users/me/calendarList"; + protected static string getCalEntriesUri = "https://www.googleapis.com/calendar/v3/calendars/{0}/events"; + + private static string dateFormat = "yyyy-MM-ddTHH:mm:ss"; + private string timeZone = "+01:00"; + + public CalendarList GetCalendars (string cred, out string json) + { + CalendarList res = null; + HttpWebRequest webreq = WebRequest.CreateHttp (getCalListUri); + webreq.Headers.Add (HttpRequestHeader.Authorization, cred); + webreq.Method = "GET"; + webreq.ContentType = "application/http"; + using (WebResponse resp = webreq.GetResponse ()) { + using (Stream respstream = resp.GetResponseStream ()) { + using (StreamReader readresp = new StreamReader (respstream, Encoding.UTF8)) { + json = readresp.ReadToEnd (); + res = JsonConvert.DeserializeObject (json); + } + } + resp.Close (); + } + webreq.Abort (); + return res; + } + + public CalendarEntryList GetCalendar (string calid, DateTime mindate, DateTime maxdate, ProfileBase upr, out string responseStr) + { + string uri = string.Format ( + getCalEntriesUri, HttpUtility.UrlEncode (calid)) + + string.Format ("?orderBy=startTime&singleEvents=true&timeMin={0}&timeMax={1}&key=" + API_KEY, + HttpUtility.UrlEncode (mindate.ToString (dateFormat) + timeZone), + HttpUtility.UrlEncode (maxdate.ToString (dateFormat) + timeZone)); + + HttpWebRequest webreq = WebRequest.CreateHttp (uri); + string cred = OAuth2.GetFreshGoogleCredential (upr); + webreq.Headers.Add (HttpRequestHeader.Authorization, cred); + webreq.Method = "GET"; + webreq.ContentType = "application/http"; + CalendarEntryList res = null; + try { + using (WebResponse resp = webreq.GetResponse ()) { + using (Stream respstream = resp.GetResponseStream ()) { + using (StreamReader readresp = new StreamReader (respstream, Encoding.UTF8)) { + responseStr = readresp.ReadToEnd (); + try { + res = JsonConvert.DeserializeObject (responseStr); + } catch (JsonReaderException ex) { + respstream.Close (); + resp.Close (); + webreq.Abort (); + throw new GoogleErrorException(ex,responseStr); + } + } + respstream.Close (); + } + resp.Close (); + } + } catch (WebException ex) { + webreq.Abort (); + throw new GoogleErrorException (ex); + } + webreq.Abort (); + return res; + } + } + +} diff --git a/web/Helpers/Google/Entity.cs b/web/Helpers/Google/Entity.cs new file mode 100644 index 00000000..c592b92d --- /dev/null +++ b/web/Helpers/Google/Entity.cs @@ -0,0 +1,48 @@ +// +// Entity.cs +// +// Author: +// Paul Schneider +// +// Copyright (c) 2015 Paul Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +using System; +using Yavsc.Helpers; +using System.Web.Profile; +using Yavsc.Model.Google; +using System.Net; +using System.IO; +using System.Text; +using Newtonsoft.Json; + +namespace Yavsc.Helpers.Google +{ + public class Entity + { + public string ID; + public string Name; + + /// + /// The type: + // AUTOMOBILE: A car or passenger vehicle. + // TRUCK: A truck or cargo vehicle. + // WATERCRAFT: A boat or other waterborne vehicle. + // PERSON: A person. + /// + public string Type; + } + +} diff --git a/yavscModel/Google/JsonReaderError.cs b/web/Helpers/Google/EntityQuery.cs similarity index 73% rename from yavscModel/Google/JsonReaderError.cs rename to web/Helpers/Google/EntityQuery.cs index 34c5d661..7059216b 100644 --- a/yavscModel/Google/JsonReaderError.cs +++ b/web/Helpers/Google/EntityQuery.cs @@ -1,5 +1,5 @@ -// -// JsonReaderError.cs +// +// EntityQuery.cs // // Author: // Paul Schneider @@ -18,14 +18,21 @@ // // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see . + using System; +using Yavsc.Helpers; +using System.Web.Profile; +using Yavsc.Model.Google; +using System.Net; +using System.IO; +using System.Text; +using Newtonsoft.Json; -namespace Yavsc.Model.Google +namespace Yavsc.Helpers.Google { - public class JsonReaderError - { - public string Text { get; set; } - public Exception Excepx { get; set; } + + public class EntityQuery { + public string [] EntityIds; + public string MinId; } } - diff --git a/web/Helpers/Google/MapTracks.cs b/web/Helpers/Google/MapTracks.cs new file mode 100644 index 00000000..2aaf89b7 --- /dev/null +++ b/web/Helpers/Google/MapTracks.cs @@ -0,0 +1,65 @@ +// +// Google.cs +// +// Author: +// Paul Schneider +// +// Copyright (c) 2015 Paul Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +using System; +using Yavsc.Helpers; +using System.Web.Profile; +using Yavsc.Model.Google; +using System.Net; +using System.IO; +using System.Text; +using Newtonsoft.Json; + +namespace Yavsc.Helpers.Google +{ + + public class MapTracks:ApiClient { + protected static string googleMapTracksPath = "https://www.googleapis.com/tracks/v1/"; + // entities/[create|list|delete] + // collections/[list|create|[add|remove]entities|delete] + // crumbs/[record|getrecent|gethistory|report|summarize|getlocationinfo|delete + + + // entities/[create|list|delete] + // collections/[list|create|[add|remove]entities|delete] + // crumbs/[record|getrecent|gethistory|report|summarize|getlocationinfo|delete + + + static string [] CreateEntity( Entity[] entities ) { + string [] ans = null; + using (SimpleJsonPostMethod< Entity[] ,string []> wr = + new SimpleJsonPostMethod< Entity[] ,string[]> (googleMapTracksPath + "entities/create")) + { + ans = wr.Invoke (entities); + } + return ans; + } + static Entity[] ListEntities (EntityQuery eq) + { + Entity [] ans = null; + using (SimpleJsonPostMethod wr = + new SimpleJsonPostMethod (googleMapTracksPath + "entities/create")) + { + ans = wr.Invoke (eq); + } + return ans; + } + } +} diff --git a/web/Helpers/Google/OAuth2.cs b/web/Helpers/Google/OAuth2.cs new file mode 100644 index 00000000..7f01d100 --- /dev/null +++ b/web/Helpers/Google/OAuth2.cs @@ -0,0 +1,217 @@ +// +// OAuth2.cs +// +// Author: +// Paul Schneider +// +// Copyright (c) 2015 Paul Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +using System; +using System.IO; +using System.Net; +using System.Text; +using Newtonsoft.Json; +using Yavsc.Model.Google; +using System.Web.Profile; +using System.Web; +using Yavsc.Model; + +namespace Yavsc.Helpers.Google +{ + + public class PeopleApi: ApiClient + { + private static string getPeopleUri = "https://www.googleapis.com/plus/v1/people"; + + public static People GetMe (AuthToken gat) + { + People me; + HttpWebRequest webreppro = WebRequest.CreateHttp (getPeopleUri + "/me"); + webreppro.ContentType = "application/http"; + webreppro.Headers.Add (HttpRequestHeader.Authorization, gat.token_type + " " + gat.access_token); + webreppro.Method = "GET"; + using (WebResponse proresp = webreppro.GetResponse ()) { + using (Stream prresponseStream = proresp.GetResponseStream ()) { + using (StreamReader readproresp = new StreamReader (prresponseStream, Encoding.UTF8)) { + string prresponseStr = readproresp.ReadToEnd (); + me = JsonConvert.DeserializeObject (prresponseStr); + } + prresponseStream.Close (); + } + proresp.Close (); + } + webreppro.Abort (); + return me; + } + } + + public class OAuth2:ApiClient + { + protected static string tokenUri = "https://accounts.google.com/o/oauth2/token"; + protected static string authUri = "https://accounts.google.com/o/oauth2/auth"; + + public string RedirectUri { get; set; } + + public OAuth2 (string redirectUri) + { + RedirectUri = redirectUri; + } + + /// + /// Login with Google + /// by redirecting the specified http web response bresp, + /// and using the specified session state. + /// + /// Bresp. + /// State. + public void Login (HttpResponseBase bresp, string state) + { + string scope = string.Join ("%20", scopeOpenid); + + string prms = String.Format ("response_type=code&client_id={0}&redirect_uri={1}&scope={2}&state={3}&include_granted_scopes=false", + CLIENT_ID, RedirectUri, scope, state); + GetAuthResponse (bresp, prms); + } + + public void GetCalAuth (HttpResponseBase bresp, string state) + { + string scope = string.Join ("%20", scopeOpenid); + scope = string.Join ("%20", scopeCalendar); + string prms = String.Format ("response_type=code&client_id={0}&redirect_uri={1}&scope={2}&state={3}&include_granted_scopes=false&access_type=offline", + CLIENT_ID, RedirectUri, scope, state); + GetAuthResponse (bresp, prms); + } + + private void GetAuthResponse (HttpResponseBase bresp, string prms) + { + string cont = null; + WebRequest wr = WebRequest.Create (authUri + "?" + prms); + wr.Method = "GET"; + using ( + WebResponse response = wr.GetResponse ()) { + string resQuery = response.ResponseUri.Query; + cont = HttpUtility.ParseQueryString (resQuery) ["continue"]; + response.Close (); + } + wr.Abort (); + bresp.Redirect (cont); + } + + /// + /// Builds the post data, from code given + /// by Google in the request parameters, + /// and using the given redirectUri. + /// This request body is used to get a new + /// OAuth2 token from Google, it is Url encoded. + /// + /// The post data from code. + /// Redirect URI. + /// Code. + public static string TokenPostDataFromCode (string redirectUri, string code) + { + string postdata = + string.Format ( + "redirect_uri={0}&client_id={1}&client_secret={2}&code={3}&grant_type=authorization_code", + HttpUtility.UrlEncode (redirectUri), + HttpUtility.UrlEncode (CLIENT_ID), + HttpUtility.UrlEncode (CLIENT_SECRET), + HttpUtility.UrlEncode (code)); + return postdata; + } + + public AuthToken GetToken (HttpRequestBase rq, string state, out string message) + { + string code = OAuth2.GetCodeFromRequest (rq, state, out message); + string postdata = OAuth2.TokenPostDataFromCode (RedirectUri, code); + return GetTokenPosting (postdata); + } + + [Obsolete ("Use GetToken instead.")] + public static AuthToken GetTokenFromBody (string postdata) + { + throw new NotImplementedException (); + } + + internal static AuthToken GetTokenPosting (string postdata) + { + HttpWebRequest webreq = WebRequest.CreateHttp (tokenUri); + webreq.Method = "POST"; + webreq.Accept = "application/json"; + webreq.ContentType = "application/x-www-form-urlencoded"; + Byte[] bytes = System.Text.Encoding.UTF8.GetBytes (postdata); + webreq.ContentLength = bytes.Length; + + using (Stream dataStream = webreq.GetRequestStream ()) { + dataStream.Write (bytes, 0, bytes.Length); + dataStream.Close (); + } + + AuthToken gat = null; + using (WebResponse response = webreq.GetResponse ()) { + using (Stream responseStream = response.GetResponseStream ()) { + using (StreamReader readStream = new StreamReader (responseStream, Encoding.UTF8)) { + string responseStr = readStream.ReadToEnd (); + gat = JsonConvert.DeserializeObject (responseStr); + readStream.Close (); + } + responseStream.Close (); + } + response.Close (); + } + webreq.Abort (); + return gat; + } + + public static string GetCodeFromRequest (HttpRequestBase rq, string state, out string message) + { + message = ""; + string code = rq.Params ["code"]; + string error = rq.Params ["error"]; + if (error != null) { + message = + string.Format (LocalizedText.Google_error, + LocalizedText.ResourceManager.GetString (error)); + return null; + } + string rqstate = rq.Params ["state"]; + if (state != null && string.Compare (rqstate, state) != 0) { + message = + LocalizedText.ResourceManager.GetString ("invalid request state"); + return null; + } + return code; + } + + public static string GetFreshGoogleCredential (ProfileBase pr) + { + string token = (string)pr.GetPropertyValue ("gtoken"); + string token_type = (string)pr.GetPropertyValue ("gtokentype"); + DateTime token_exp = (DateTime)pr.GetPropertyValue ("gtokenexpir"); + if (token_exp < DateTime.Now) { + string refresh_token = (string)pr.GetPropertyValue ("grefreshtoken"); + AuthToken gat = OAuth2.GetTokenPosting ( + string.Format ("grant_type=refresh_token&client_id={0}&client_secret={1}&refresh_token={2}", + CLIENT_ID, CLIENT_SECRET, refresh_token)); + token = gat.access_token; + pr.SetPropertyValue ("gtoken", token); + pr.Save (); + // ASSERT gat.token_type == pr.GetPropertyValue("token_type") + } + return token_type + " " + token; + } + + } +} + diff --git a/web/Helpers/SimpleJsonPostMethod.cs b/web/Helpers/SimpleJsonPostMethod.cs new file mode 100644 index 00000000..a28bd7c6 --- /dev/null +++ b/web/Helpers/SimpleJsonPostMethod.cs @@ -0,0 +1,91 @@ +// +// PostJson.cs +// +// Author: +// Paul Schneider +// +// Copyright (c) 2015 Paul Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +using System; +using System.Net; +using System.Text; +using System.IO; +using Newtonsoft.Json; + +namespace Yavsc.Helpers +{ + public class SimpleJsonPostMethod: IDisposable + { + internal HttpWebRequest request = null; + internal HttpWebRequest Request { get { return request; } } + + string CharSet { + get { return Request.TransferEncoding; } + set { Request.TransferEncoding=value;} + } + string Method { get { return Request.Method; } } + + public string Path { + get{ return Request.RequestUri.ToString(); } + } + + public void SetCredential(string cred) { + Request.Headers.Add(HttpRequestHeader.Authorization,cred); + } + + public SimpleJsonPostMethod (string pathToMethod) + { + // ASSERT Request == null + request = WebRequest.CreateHttp (pathToMethod); + + Request.Method = "POST"; + Request.Accept = "application/json"; + Request.ContentType = "application/json"; + Request.TransferEncoding = "UTF-8"; + } + + public TAnswer Invoke(TQuery query) + { + Byte[] bytes = System.Text.Encoding.UTF8.GetBytes (JsonConvert.SerializeObject(query)); + Request.ContentLength = bytes.Length; + + using (Stream dataStream = Request.GetRequestStream ()) { + dataStream.Write (bytes, 0, bytes.Length); + dataStream.Close (); + } + TAnswer ans = default (TAnswer); + using (WebResponse response = Request.GetResponse ()) { + using (Stream responseStream = response.GetResponseStream ()) { + using (StreamReader readStream = new StreamReader (responseStream, Encoding.UTF8)) { + string responseStr = readStream.ReadToEnd (); + ans = JsonConvert.DeserializeObject (responseStr); + readStream.Close (); + } + responseStream.Close (); + } + response.Close(); + } + return ans; + } + + #region IDisposable implementation + public void Dispose () + { + if (Request != null) Request.Abort (); + } + #endregion + } +} + diff --git a/web/Models/App.master b/web/Models/App.master index f6a4555d..1ce0c8bf 100644 --- a/web/Models/App.master +++ b/web/Models/App.master @@ -68,7 +68,7 @@
<% foreach ( string link in Yavsc.ThanksHelper.Links()) { %> -
<%= link %>
+ <%= link %> <% } %>
diff --git a/web/Views/Account/Profile.aspx b/web/Views/Account/Profile.aspx index d85baf87..da4064cf 100644 --- a/web/Views/Account/Profile.aspx +++ b/web/Views/Account/Profile.aspx @@ -52,7 +52,7 @@ <%= Html.TextBox("BlogTitle") %> <%= Html.ValidationMessage("BlogTitle", "*") %> -Avatar +Avatar : "<%=Model.avatar%>" <%= Html.ValidationMessage("AvatarFile", "*") %> diff --git a/web/Views/Google/GoogleErrorMessage.aspx b/web/Views/Google/GoogleErrorMessage.aspx new file mode 100644 index 00000000..37b6a9e3 --- /dev/null +++ b/web/Views/Google/GoogleErrorMessage.aspx @@ -0,0 +1,12 @@ +<%@ Page Title="Google error message" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + +

<%= Html.Encode(Model.Title)%>

+ +
+ 
+ <%= Html.Encode(Model.Content) %>
+ 
+ +
+ diff --git a/web/Views/Google/JsonReaderError.aspx b/web/Views/Google/JsonReaderError.aspx deleted file mode 100644 index eb2d162e..00000000 --- a/web/Views/Google/JsonReaderError.aspx +++ /dev/null @@ -1,12 +0,0 @@ -<%@ Page Title="Json reader error" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> - - -

<%= Html.Encode(Model.Excepx.Message)%>

- -
- 
- <%= Html.Encode(Model.Text) %>
- 
- -
- diff --git a/web/Web.csproj b/web/Web.csproj index 45778c95..ebd7d4fc 100644 --- a/web/Web.csproj +++ b/web/Web.csproj @@ -118,6 +118,7 @@ + @@ -164,6 +165,13 @@ + + + + + + + @@ -261,7 +269,6 @@ - @@ -621,6 +628,7 @@ + @@ -637,14 +645,12 @@ - TextTemplatingFilePreprocessor Estim.cs - @@ -677,4 +683,8 @@ NpgsqlWorkflow + + + + diff --git a/yavscModel/Google/GoogleErrorMessage.cs b/yavscModel/Google/GoogleErrorMessage.cs new file mode 100644 index 00000000..48ef7dfd --- /dev/null +++ b/yavscModel/Google/GoogleErrorMessage.cs @@ -0,0 +1,50 @@ +// +// JsonReaderError.cs +// +// Author: +// Paul Schneider +// +// Copyright (c) 2015 Paul Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +using System; +using System.Net; +using System.IO; +using Newtonsoft.Json; + +namespace Yavsc.Model.Google +{ + public class GoogleErrorException : Exception + { + public string Title { get; set; } + public string Content { get; set; } + + public GoogleErrorException (WebException ex) { + // ASSERT ex != null; + Title = ex.Message; + + using (var stream = ex.Response.GetResponseStream()) + using (var reader = new StreamReader(stream)) + { + Content = reader.ReadToEnd(); + } + } + public GoogleErrorException(JsonReaderException ex, string message) { + Content = message; + Title = ex.Message; + } + } + +} + diff --git a/yavscModel/IModule.cs b/yavscModel/IModule.cs index 926b71b4..63eb140d 100644 --- a/yavscModel/IModule.cs +++ b/yavscModel/IModule.cs @@ -22,12 +22,5 @@ namespace Yavsc.Model void Uninstall(IDbConnection cnx,bool removeConfig); void Initialize (string name, NameValueCollection config); } - public interface IRenderer { - // Should set ViewData["Message|Author|Body"] - object Get(Controller c); - string Template { get; } - string Name { get; set; } - } - } diff --git a/yavscModel/IRenderer.cs b/yavscModel/IRenderer.cs new file mode 100644 index 00000000..ce5237e8 --- /dev/null +++ b/yavscModel/IRenderer.cs @@ -0,0 +1,37 @@ +// +// IRenderer.cs +// +// Author: +// Paul Schneider +// +// Copyright (c) 2015 Paul Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +using System; +using System.Configuration; +using System.Collections.Specialized; +using System.Data; +using System.Web.Mvc; + +namespace Yavsc.Model +{ + public interface IRenderer { + // Should set ViewData["Message|Author|Body"] + // and return an ActionResult + object Get(Controller c); + string Name { get; set; } + } + +} diff --git a/yavscModel/ITagHandler.cs b/yavscModel/ITagHandler.cs new file mode 100644 index 00000000..df39329b --- /dev/null +++ b/yavscModel/ITagHandler.cs @@ -0,0 +1,41 @@ +// +// ITagHandler.cs +// +// Author: +// Paul Schneider +// +// Copyright (c) 2015 Paul Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +using System; +using System.Configuration; +using System.Collections.Specialized; +using System.Data; +using System.Web.Mvc; + +namespace Yavsc.Model +{ + + public interface ITagHandler { + // Should set ViewData["Tags"] with + // an array of rendered tags + + void Backup(); + void Restore(); + void Invoke(); + string Name { get; set; } + + } +} diff --git a/yavscModel/IViewRenderer.cs b/yavscModel/IViewRenderer.cs new file mode 100644 index 00000000..d164c814 --- /dev/null +++ b/yavscModel/IViewRenderer.cs @@ -0,0 +1,42 @@ +// +// IViewRenderer.cs +// +// Author: +// Paul Schneider +// +// Copyright (c) 2015 Paul Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +using System; +using System.Configuration; +using System.Collections.Specialized; +using System.Data; +using System.Web.Mvc; + +namespace Yavsc.Model +{ + + public interface IViewRenderer : IRenderer { + + // IRenderer.Get() Should set ViewData["Message|Author|Body"] + // and return an ActionResult + /// + /// Gets the template route part + /// + /// The template. + string Template { get; } + } + +} diff --git a/yavscModel/ViewRenderer.cs b/yavscModel/ViewRenderer.cs new file mode 100644 index 00000000..cd47712c --- /dev/null +++ b/yavscModel/ViewRenderer.cs @@ -0,0 +1,54 @@ +// +// ViewRenderer.cs +// +// Author: +// Paul Schneider +// +// Copyright (c) 2015 Paul Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +using System; +using System.Configuration; +using System.Collections.Specialized; +using System.Data; +using System.Web.Mvc; + +namespace Yavsc.Model +{ + + public abstract class ViewRenderer : IViewRenderer { + #region IRenderer implementation + public object Get (Controller c) + { + return Name; + } + public string Template { + get { + return "Tag.aspx"; + } + } + public string Name { + get { + throw new NotImplementedException (); + } + set { + throw new NotImplementedException (); + } + } + #endregion + + } + +} diff --git a/yavscModel/YavscModel.csproj b/yavscModel/YavscModel.csproj index 87f29fb4..9c589977 100644 --- a/yavscModel/YavscModel.csproj +++ b/yavscModel/YavscModel.csproj @@ -37,6 +37,9 @@ + + + @@ -91,8 +94,12 @@ - + + + + +