many changes

This commit is contained in:
Paul Schneider
2015-01-02 04:52:48 +01:00
parent c7f81699a4
commit 6809e3dfe2
49 changed files with 3429 additions and 215 deletions

View File

@ -3,6 +3,7 @@ VERSION=1.1
CONFIG=Debug
DESTDIR=build/web/$(CONFIG)
COPYUNCHANGED="false"
PREPRODHOST=lua.pschneider.fr
all: deploy
@ -14,7 +15,7 @@ deploy: ddir build
rm -rf $(DESTDIR)/obj
mv $(DESTDIR)/Web.config $(DESTDIR)/Web.config.new
rsync: rsync-preprod rsync-local
rsync: rsync-preprod
build:
xbuild /p:Configuration=$(CONFIG) /t:Build Yavsc.sln
@ -24,7 +25,7 @@ clean:
rm -rf $(DESTDIR)
rsync-preprod: deploy
rsync -ravu build/web/$(CONFIG)/ root@lua.localdomain:/srv/httpd/luapre
rsync -ravu build/web/$(CONFIG)/ root@$(PREPRODHOST):/srv/httpd/luapre
rsync-local:
rsync -ravu build/web/$(CONFIG)/ root@localhost:/srv/www/yavsc

View File

@ -46,7 +46,7 @@ namespace Yavsc.Controllers
public static Profile GetProfile (string user)
{
return new Profile (ProfileBase.Create (user));
return new Profile (ProfileBase.Create (user)) ;
}
@ -216,8 +216,10 @@ namespace Yavsc.Controllers
[HttpGet]
public ActionResult Profile(Profile model)
{
ViewData ["UserName"] = Membership.GetUser ().UserName;
model = GetProfile ((string) ViewData ["UserName"]);
string username = Membership.GetUser ().UserName;
ViewData ["UserName"] = username;
model = GetProfile (username);
model.RememberMe = FormsAuthentication.GetAuthCookie ( username, true )==null;
return View (model);
}
@ -280,9 +282,9 @@ namespace Yavsc.Controllers
HttpContext.Profile.SetPropertyValue (
"IBAN", model.IBAN);
HttpContext.Profile.Save ();
ViewData ["Message"] = "Profile enregistré.";
}
FormsAuthentication.SetAuthCookie (username, model.RememberMe);
ViewData ["Message"] = "Profile enregistré, cookie modifié.";
}
// HttpContext.Profile.SetPropertyValue("Avatar",Avatar);
return View (model);
}

View File

@ -19,10 +19,11 @@ namespace Yavsc.Controllers
/// </summary>
public class AdminController : Controller
{
[Authorize(Roles="Admin")]
public ActionResult Index(DataAccess model)
public ActionResult Index()
{
return View (model);
return View ();
}
[Authorize(Roles="Admin")]

View File

@ -48,7 +48,9 @@ namespace Yavsc.Controllers
if (string.IsNullOrEmpty (user)) {
return BlogList (pageIndex, pageSize);
} else {
MembershipUser u = Membership.GetUser (user, false);
MembershipUser u = null;
if (Membership.FindUsersByName (user) != null)
u= Membership.GetUser (user, false);
if (u == null) {
ModelState.AddModelError ("UserName",
string.Format ("Utilisateur inconu : {0}", user));
@ -58,6 +60,8 @@ namespace Yavsc.Controllers
return UserPosts (user, pageIndex, pageSize);
return UserPost (user, title);
}
}
}

View File

@ -1,44 +0,0 @@
using System;
using Yavsc;
using SalesCatalog;
using SalesCatalog.Model;
using System.Web.Routing;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Web.Http;
using System.Net.Http;
using System.Web;
using System.Linq;
using System.IO;
using System.Net;
using WorkFlowProvider;
using System.Web.Security;
using Yavsc.Model.WorkFlow;
using System.Reflection;
using System.Collections.Generic;
using Yavsc.Model.RolesAndMembers;
using Yavsc.Controllers;
using Yavsc.Formatters;
using System.Text;
using System.Web.Profile;
namespace Yavsc.ApiControllers
{
public class FormInputValue: IValueProvider<T>
{
#region IValueProvider implementation
public T GetValue ()
{
throw new NotImplementedException ();
}
#endregion
}
}

View File

@ -30,6 +30,11 @@ namespace Yavsc.Controllers
wfmgr = new WorkFlowManager ();
}
public ActionResult Index ()
{
return View ();
}
[Authorize]
public ActionResult Estimates ()
{

View File

@ -22,79 +22,125 @@ 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 string getPeopleUri = "https://www.googleapis.com/plus/v1/people";
private string getCalListUri = "https://www.googleapis.com/calendar/v3/users/me/calendarList";
private string getCalEntriesUri = "https://developers.google.com/google-apps/calendar/v3/reference/events/list";
private string CLIENT_ID="325408689282-6bekh7p3guj4k0f3301a6frf025cnrk1.apps.googleusercontent.com";
private string CLIENT_ID = "325408689282-6bekh7p3guj4k0f3301a6frf025cnrk1.apps.googleusercontent.com";
private string CLIENT_SECRET = "MaxYcvJJCs2gDGvaELZbzwfL";
private string CLIENT_SECRET="MaxYcvJJCs2gDGvaELZbzwfL";
string [] SCOPES = {
"openid" ,
string[] SCOPES = {
"openid",
"profile",
"email"
} ;
};
string tokenUri = "https://accounts.google.com/o/oauth2/token";
string authUri = "https://accounts.google.com/o/oauth2/auth";
string tokenUri = "https://accounts.google.com/o/oauth2/token";
string authUri = "https://accounts.google.com/o/oauth2/auth";
public void Login(string returnUrl)
private string SetSessionSate ()
{
Random rand = new Random ();
string state = "security_token" + rand.Next (100000).ToString () + rand.Next (100000).ToString ();
Session ["state"] = state;
return state;
}
public void Login (string returnUrl)
{
if (string.IsNullOrWhiteSpace (returnUrl))
returnUrl = "/";
Random rand = new Random ();
string state = "security_token"+rand.Next (100000).ToString()+rand.Next (100000).ToString();
Session ["state"] = state;
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}&access_type=offline&include_granted_scopes=false",
CLIENT_ID, redirectUri, string.Join("%20",SCOPES), state);
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 ());
WebRequest wr = WebRequest.Create(authUri+"?"+prms);
GetAuthResponse (prms);
}
private void GetAuthResponse (string prms)
{
WebRequest wr = WebRequest.Create (authUri + "?" + prms);
wr.Method = "GET";
// Get the response.
WebResponse response = wr.GetResponse();
string resQuery = response.ResponseUri.Query;
string cont = HttpUtility.ParseQueryString(resQuery)["continue"];
Response.Redirect (cont);
WebResponse response = wr.GetResponse ();
string resQuery = response.ResponseUri.Query;
string cont = HttpUtility.ParseQueryString (resQuery) ["continue"];
Response.Redirect (cont);
}
[Authorize]
public void GetCalAuth ()
{
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);
}
[HttpGet]
public ActionResult Auth()
[Authorize]
public ActionResult CalAuth ()
{
string redirectUri = Request.Url.Scheme + "://" + Request.Url.Authority + "/Google/CalAuth";
AuthToken gat = GetToken (TokenPostDataFromCode(redirectUri, GetCodeFromRequest()));
if (gat == null) {
return View ("Auth");
}
SaveToken (gat);
HttpContext.Profile.SetPropertyValue ("gcalapi", true);
string returnUrl = (string)Session ["returnUrl"];
Session ["returnUrl"]=null;
return Redirect (returnUrl);
}
string returnUrl = (string) Session ["returnUrl"];
string redirectUri = Request.Url.Scheme + "://" + Request.Url.Authority + "/Google/Auth";
/// <summary>
/// Saves the token.
/// This calls the Profile.Save() method.
/// It should be called immediatly after getting the token from Google, in
/// order to save a descent value as expiration date.
/// </summary>
/// <param name="gat">Gat.</param>
private void SaveToken(AuthToken gat)
{
HttpContext.Profile.SetPropertyValue ("gtoken", gat.access_token);
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.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 View();
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) {
if (state != null && string.Compare ((string)Session ["state"], state) != 0) {
ViewData ["Message"] =
LocalizedText.ResourceManager.GetString("invalid request state");
return View();
LocalizedText.ResourceManager.GetString ("invalid request state");
return null;
}
return 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));
private AuthToken GetToken (string postdata)
{
Byte[] bytes = System.Text.Encoding.UTF8.GetBytes (postdata);
HttpWebRequest webreq = WebRequest.CreateHttp (tokenUri);
webreq.Method = "POST";
@ -103,45 +149,71 @@ namespace Yavsc.Controllers
webreq.ContentLength = bytes.Length;
using (Stream dataStream = webreq.GetRequestStream ()) {
dataStream.Write (bytes, 0, bytes.Length);
};
}
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 ();
AuthToken gat = JsonConvert.DeserializeObject<AuthToken>(responseStr);
Session ["GoogleAuthToken"] = gat;
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<People> (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;
return Redirect (returnUrl);
}
// else create the account
regmod.Email = accEmail;
regmod.UserName = me.displayName;
Session ["me"] = me;
return Auth(regmod);
}
}
}
gat = JsonConvert.DeserializeObject<AuthToken> (responseStr);
}
}
}
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()));
if (gat == null) {
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<People> (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;
return Redirect (returnUrl);
}
// else create the account
regmod.Email = accEmail;
regmod.UserName = me.displayName;
Session ["me"] = me;
Session ["GoogleAuthToken"] = gat;
return Auth (regmod);
}
}
}
}
/// <summary>
@ -149,7 +221,7 @@ namespace Yavsc.Controllers
/// </summary>
/// <param name="regmod">Regmod.</param>
[HttpPost]
public ActionResult Auth(SignIn regmod)
public ActionResult Auth (SignIn regmod)
{
if (ModelState.IsValid) {
if (Membership.GetUser (regmod.UserName) != null) {
@ -188,7 +260,6 @@ namespace Yavsc.Controllers
FormsAuthentication.SetAuthCookie (regmod.UserName, true);
HttpContext.Profile.Initialize (regmod.UserName, true);
HttpContext.Profile.SetPropertyValue ("gtoken", gat.access_token);
HttpContext.Profile.SetPropertyValue ("Name", me.displayName);
// TODO use image
if (me.image != null) {
@ -197,11 +268,12 @@ namespace Yavsc.Controllers
if (me.placesLived != null) {
People.Place pplace = me.placesLived.Where (x => x.primary).First ();
if (pplace != null)
HttpContext.Profile.SetPropertyValue ("Address", pplace.value);
HttpContext.Profile.SetPropertyValue ("CityAndState", pplace.value);
}
if (me.url != null)
HttpContext.Profile.SetPropertyValue ("WebSite", me.url);
HttpContext.Profile.Save ();
SaveToken (gat);
// already done in SaveToken: HttpContext.Profile.Save ();
return Redirect (returnUrl);
}
ViewData ["returnUrl"] = returnUrl;
@ -209,10 +281,111 @@ namespace Yavsc.Controllers
return View (regmod);
}
public void ChooseCalendar()
private string GetFreshGoogleCredential (ProfileBase pr)
{
throw new NotImplementedException();
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;
}
[Authorize]
[HttpGet]
public ActionResult ChooseCalendar (string returnUrl)
{
Session ["ChooseCalReturnUrl"] = returnUrl;
bool hasCalAuth = (bool)HttpContext.Profile.GetPropertyValue ("gcalapi");
if (!hasCalAuth) {
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";
using (WebResponse resp = webreq.GetResponse ()) {
using (Stream respstream = resp.GetResponseStream ()) {
using (StreamReader readresp = new StreamReader (respstream, Encoding.UTF8)) {
string responseStr = readresp.ReadToEnd ();
CalendarList res = JsonConvert.DeserializeObject<CalendarList> (responseStr);
ViewData ["json"] = responseStr;
return View (res);
}
}
}
}
[HttpPost]
[Authorize]
public ActionResult SetCalendar (string calchoice)
{
HttpContext.Profile.SetPropertyValue ("gcalid", calchoice);
HttpContext.Profile.Save ();
string returnUrl = (string) Session ["ChooseCalReturnUrl"];
if (returnUrl != null) {
Session ["ChooseCalReturnUrl"] = null;
return Redirect (returnUrl);
}
return Redirect ("/");
}
[Authorize]
[HttpGet]
public ActionResult DateQuery()
{
return View (new AskForADate ());
}
[Authorize]
[HttpPost]
public ActionResult DateQuery(AskForADate model)
{
if (ModelState.IsValid) {
if (model.MinDate < DateTime.Now) {
ModelState.AddModelError ("MinTime", "This first date must be in the future.");
return View (model);
}
if (model.MinDate > model.MaxDate) {
ModelState.AddModelError ("MinTime", "This first date must be lower than the second one.");
return View (model);
}
ProfileBase upr = ProfileBase.Create (model.UserName);
if (upr == null) {
ModelState.AddModelError ("UserName", "Non existent user");
return View (model);
}
HttpWebRequest webreq = WebRequest.CreateHttp (getCalEntriesUri);
webreq.Headers.Add (HttpRequestHeader.Authorization, GetFreshGoogleCredential(upr));
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)) {
string responseStr = readresp.ReadToEnd ();
CalendarList res = JsonConvert.DeserializeObject<CalendarList> (responseStr);
ViewData ["json"] = responseStr;
return View (res);
}
}
}
}
return View (model);
}
}
}
}

View File

@ -30,7 +30,7 @@ namespace Yavsc.ApiControllers
DateTime Creation { get; set; }
string Status { get; set; }
long OrderId { get; set; }
FormInputValue [] Details { get; set; }
Object [] Details { get; set; }
}
}

View File

@ -25,19 +25,28 @@ namespace Yavsc
"Blog",
"Blog/{user}/{title}",
new { controller = "Blogs", action = "Index", user=UrlParameter.Optional, title = UrlParameter.Optional }
);
); /*
routes.MapRoute (
"Blogs",
"Blogs/{action}/{user}/{title}",
new { controller = "Blogs", action = "Index", user=UrlParameter.Optional, title = UrlParameter.Optional}
);
);*/ /*
routes.MapRoute (
"Home",
"Home/Index",
new { controller = "Blogs", action = "Index", user="paul", title = "Documentation" }
);*/
/*routes.MapRoute (
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);*/
routes.MapRoute (
"Default",
"{controller}/{action}/{user}",
new { controller = "Home", action = "Index", user="" }
"{controller}/{action}/{user}/{title}",
new { controller = "Blogs", action = "Index", user="paul", title = "Documentation"}
);
}
protected void Application_Start ()

View File

@ -8,14 +8,16 @@ using System.Web.Mvc.Ajax;
using System.Net.Mail;
using Yavsc;
using System.Globalization;
using Yavsc.Model;
namespace Yavsc
namespace Yavsc.Helpers
{
public class T
{
public static string GetString(string msgid)
public static string GetString(string msg)
{
return Mono.Unix.Catalog.GetString (msgid);
string tr = LocalizedText.ResourceManager.GetString (msg.Replace (" ", "_"));
return tr==null?msg:tr;
}
}
}

View File

@ -2,8 +2,9 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<asp:ContentPlaceHolder id="init" runat="server">
<% Page.Title = Page.Title + " - " + YavscHelpers.SiteName; %>
</asp:ContentPlaceHolder>
<% ViewState["orgtitle"] = T.GetString(Page.Title); %>
<% Page.Title = ViewState["orgtitle"] + " - " + YavscHelpers.SiteName; %>
<head runat="server">
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
@ -16,7 +17,9 @@
<body>
<header>
<asp:ContentPlaceHolder ID="overHeaderOne" runat="server">
<h1><a href="<%= Html.Encode(Request.Url.AbsoluteUri.ToString()) %>"><%= Page.Title %></a></h1>
<h1><a href="<%= Html.Encode(Request.Url.AbsoluteUri.ToString()) %>"> <%=ViewState["orgtitle"]%> </a> -
<a href="<%=Request.Url.Scheme + "://" + Request.Url.Authority%>"><%= YavscHelpers.SiteName %></a>
</h1>
</asp:ContentPlaceHolder>
<asp:ContentPlaceHolder ID="header" runat="server"></asp:ContentPlaceHolder>
<% if (ViewData["Error"]!=null) { %>
@ -29,32 +32,36 @@
<%= Html.Encode(ViewData["Message"]) %>
</div>
<% } %>
</header>
<main>
<asp:ContentPlaceHolder ID="MainContent" runat="server">
</asp:ContentPlaceHolder>
</main>
<aside>
<asp:ContentPlaceHolder ID="MASContent" runat="server">
</asp:ContentPlaceHolder>
<div id="login">
<% if (Membership.GetUser()==null) { %>
<%= Html.ActionLink( YavscHelpers.SiteName, "Index", "Home" ,null, new { @class="actionlink" } ) %>
<%= Html.ActionLink( YavscHelpers.SiteName, "Index", "Home" ,null, new { @class="actionlink" } ) %>
<span class="hidcom"> Page d'accueil </span>
<%= Html.ActionLink("Login", "Login", "Account", new { returnUrl=Request.Url.PathAndQuery }, new { @class="actionlink" } ) %>
<%= Html.ActionLink("Login", "Login", "Account", new { returnUrl=Request.Url.PathAndQuery }, new { @class="actionlink" } ) %>
<span class="hidcom">Pour pouvoir poster ou commenter</span>
<a href="<%=Request.Url.Scheme + "://" + Request.Url.Authority + "/Google/Login"%>?returnUrl=<%=ViewData["returnUrl"]%>" class="actionlink">
<img src="/images/sign-in-with-google.png" style="max-height:1.5em; max-width:6em;" alt="Google sign in">
<img src="/images/sign-in-with-google-s.png" style="max-height:1.5em; max-width:6em;" alt="Google sign in">
</a>
<span class="hidcom">S'authentifier avec son compte Google+</span>
<% } else { %>
<%= Html.ActionLink(HttpContext.Current.User.Identity.Name, "Profile", "Account", null, new { @class="actionlink" }) %>
<%= Html.ActionLink(HttpContext.Current.User.Identity.Name, "Profile", "Account", null, new { @class="actionlink" }) %>
<span class="hidcom"> &Eacute;dition de votre profile </span>
@ <%= Html.ActionLink( YavscHelpers.SiteName, "Index", "Home" ,null, new { @class="actionlink" }) %>
@ <%= Html.ActionLink( YavscHelpers.SiteName, "Index", "Home" ,null, new { @class="actionlink" }) %>
<span class="hidcom"> Page d'accueil </span>
<a href="/Blogs/Post" class="actionlink">Poster </a>
<a href="/Blogs/Post" class="actionlink">Poster</a>
<span class="hidcom"> &Eacute;dition d'un nouveau billet </span>
<%= Html.ActionLink( "Deconnexion", "Logout", "Account", new { returnUrl=Request.Url.PathAndQuery }, new { @class="actionlink" }) %>
<%= Html.ActionLink( "Deconnexion", "Logout", "Account", new { returnUrl=Request.Url.PathAndQuery }, new { @class="actionlink" }) %>
<% } %>
</div>
</aside>

29
web/Scripts/GruntFile.js Normal file
View File

@ -0,0 +1,29 @@
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
meta: {
banner : '/*!\n' +
' * <%= pkg.title %> v<%= pkg.version %> - <%= pkg.description %>\n' +
' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %> - <%= pkg.homepage %>\n' +
' * License: <%= pkg.license %>\n' +
' */\n\n'
},
uglify: {
options : {
banner : '<%= meta.banner %>',
report: 'gzip'
},
dist: {
files: {
'jquery.timepicker.min.js': ['jquery.timepicker.js']
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.registerTask('default', ['uglify']);
};

221
web/Scripts/jquery.mousewheel.js Executable file
View File

@ -0,0 +1,221 @@
/*! Copyright (c) 2013 Brandon Aaron (http://brandon.aaron.sh)
* Licensed under the MIT License (LICENSE.txt).
*
* Version: 3.1.12
*
* Requires: jQuery 1.2.2+
*/
(function (factory) {
if ( typeof define === 'function' && define.amd ) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node/CommonJS style for Browserify
module.exports = factory;
} else {
// Browser globals
factory(jQuery);
}
}(function ($) {
var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
slice = Array.prototype.slice,
nullLowestDeltaTimeout, lowestDelta;
if ( $.event.fixHooks ) {
for ( var i = toFix.length; i; ) {
$.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
}
}
var special = $.event.special.mousewheel = {
version: '3.1.12',
setup: function() {
if ( this.addEventListener ) {
for ( var i = toBind.length; i; ) {
this.addEventListener( toBind[--i], handler, false );
}
} else {
this.onmousewheel = handler;
}
// Store the line height and page height for this particular element
$.data(this, 'mousewheel-line-height', special.getLineHeight(this));
$.data(this, 'mousewheel-page-height', special.getPageHeight(this));
},
teardown: function() {
if ( this.removeEventListener ) {
for ( var i = toBind.length; i; ) {
this.removeEventListener( toBind[--i], handler, false );
}
} else {
this.onmousewheel = null;
}
// Clean up the data we added to the element
$.removeData(this, 'mousewheel-line-height');
$.removeData(this, 'mousewheel-page-height');
},
getLineHeight: function(elem) {
var $elem = $(elem),
$parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent']();
if (!$parent.length) {
$parent = $('body');
}
return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16;
},
getPageHeight: function(elem) {
return $(elem).height();
},
settings: {
adjustOldDeltas: true, // see shouldAdjustOldDeltas() below
normalizeOffset: true // calls getBoundingClientRect for each event
}
};
$.fn.extend({
mousewheel: function(fn) {
return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');
},
unmousewheel: function(fn) {
return this.unbind('mousewheel', fn);
}
});
function handler(event) {
var orgEvent = event || window.event,
args = slice.call(arguments, 1),
delta = 0,
deltaX = 0,
deltaY = 0,
absDelta = 0,
offsetX = 0,
offsetY = 0;
event = $.event.fix(orgEvent);
event.type = 'mousewheel';
// Old school scrollwheel delta
if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; }
if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; }
if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; }
if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }
// Firefox < 17 horizontal scrolling related to DOMMouseScroll event
if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
deltaX = deltaY * -1;
deltaY = 0;
}
// Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
delta = deltaY === 0 ? deltaX : deltaY;
// New school wheel delta (wheel event)
if ( 'deltaY' in orgEvent ) {
deltaY = orgEvent.deltaY * -1;
delta = deltaY;
}
if ( 'deltaX' in orgEvent ) {
deltaX = orgEvent.deltaX;
if ( deltaY === 0 ) { delta = deltaX * -1; }
}
// No change actually happened, no reason to go any further
if ( deltaY === 0 && deltaX === 0 ) { return; }
// Need to convert lines and pages to pixels if we aren't already in pixels
// There are three delta modes:
// * deltaMode 0 is by pixels, nothing to do
// * deltaMode 1 is by lines
// * deltaMode 2 is by pages
if ( orgEvent.deltaMode === 1 ) {
var lineHeight = $.data(this, 'mousewheel-line-height');
delta *= lineHeight;
deltaY *= lineHeight;
deltaX *= lineHeight;
} else if ( orgEvent.deltaMode === 2 ) {
var pageHeight = $.data(this, 'mousewheel-page-height');
delta *= pageHeight;
deltaY *= pageHeight;
deltaX *= pageHeight;
}
// Store lowest absolute delta to normalize the delta values
absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );
if ( !lowestDelta || absDelta < lowestDelta ) {
lowestDelta = absDelta;
// Adjust older deltas if necessary
if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
lowestDelta /= 40;
}
}
// Adjust older deltas if necessary
if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
// Divide all the things by 40!
delta /= 40;
deltaX /= 40;
deltaY /= 40;
}
// Get a whole, normalized value for the deltas
delta = Math[ delta >= 1 ? 'floor' : 'ceil' ](delta / lowestDelta);
deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);
// Normalise offsetX and offsetY properties
if ( special.settings.normalizeOffset && this.getBoundingClientRect ) {
var boundingRect = this.getBoundingClientRect();
offsetX = event.clientX - boundingRect.left;
offsetY = event.clientY - boundingRect.top;
}
// Add information to the event object
event.deltaX = deltaX;
event.deltaY = deltaY;
event.deltaFactor = lowestDelta;
event.offsetX = offsetX;
event.offsetY = offsetY;
// Go ahead and set deltaMode to 0 since we converted to pixels
// Although this is a little odd since we overwrite the deltaX/Y
// properties with normalized deltas.
event.deltaMode = 0;
// Add event and delta to the front of the arguments
args.unshift(event, delta, deltaX, deltaY);
// Clearout lowestDelta after sometime to better
// handle multiple device types that give different
// a different lowestDelta
// Ex: trackpad = 3 and mouse wheel = 120
if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);
return ($.event.dispatch || $.event.handle).apply(this, args);
}
function nullLowestDelta() {
lowestDelta = null;
}
function shouldAdjustOldDeltas(orgEvent, absDelta) {
// If this is an older event and the delta is divisable by 120,
// then we are assuming that the browser is treating this as an
// older mouse wheel event and that we should divide the deltas
// by 40 to try and get a more usable deltaFactor.
// Side note, this actually impacts the reported scroll distance
// in older browsers and can cause scrolling to be slower than native.
// Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;
}
}));

File diff suppressed because it is too large Load Diff

7
web/Scripts/jquery.timepicker.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1225
web/Theme/jquery-ui.css vendored Normal file

File diff suppressed because it is too large Load Diff

7
web/Theme/jquery-ui.min.css vendored Normal file

File diff suppressed because one or more lines are too long

72
web/Theme/jquery.timepicker.css Executable file
View File

@ -0,0 +1,72 @@
.ui-timepicker-wrapper {
overflow-y: auto;
height: 150px;
width: 6.5em;
background: #fff;
border: 1px solid #ddd;
-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);
-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);
box-shadow:0 5px 10px rgba(0,0,0,0.2);
outline: none;
z-index: 10001;
margin: 0;
}
.ui-timepicker-wrapper.ui-timepicker-with-duration {
width: 13em;
}
.ui-timepicker-wrapper.ui-timepicker-with-duration.ui-timepicker-step-30,
.ui-timepicker-wrapper.ui-timepicker-with-duration.ui-timepicker-step-60 {
width: 11em;
}
.ui-timepicker-list {
margin: 0;
padding: 0;
list-style: none;
}
.ui-timepicker-duration {
margin-left: 5px; color: #888;
}
.ui-timepicker-list:hover .ui-timepicker-duration {
color: #888;
}
.ui-timepicker-list li {
padding: 3px 0 3px 5px;
cursor: pointer;
white-space: nowrap;
color: #000;
list-style: none;
margin: 0;
}
.ui-timepicker-list:hover .ui-timepicker-selected {
background: #fff; color: #000;
}
li.ui-timepicker-selected,
.ui-timepicker-list li:hover,
.ui-timepicker-list .ui-timepicker-selected:hover {
background: #1980EC; color: #fff;
}
li.ui-timepicker-selected .ui-timepicker-duration,
.ui-timepicker-list li:hover .ui-timepicker-duration {
color: #ccc;
}
.ui-timepicker-list li.ui-timepicker-disabled,
.ui-timepicker-list li.ui-timepicker-disabled:hover,
.ui-timepicker-list li.ui-timepicker-selected.ui-timepicker-disabled {
color: #888;
cursor: default;
}
.ui-timepicker-list li.ui-timepicker-disabled:hover,
.ui-timepicker-list li.ui-timepicker-selected.ui-timepicker-disabled {
background: #f2f2f2;
}

View File

@ -14,18 +14,20 @@ main {
margin:.5em;
}
aside div {
display: block;
background-color: rgba(32,16,16,0.5);
margin: 0.7em;
float: left;
margin:.5em;
}
aside {background-color: rgba(32,16,16,0.8);
padding: 1em; margin: 0.5em;
border-radius:25px; border: solid 1px #000060;
float: right;
}
video,img {
max-width:100%;
max-height:75%;
position:relative;
top:4px;
}
.panel { max-width: 17em;
max-height:30em; border:solid green 1px;}
footer {
position:fixed;
@ -87,6 +89,7 @@ label {
.blogtitle {
display:inline;
}
.contenu {
padding-left: 20px;
}
@ -146,7 +149,7 @@ padding-left: 20px;
}
.hidcom {
display:none; position:fixed; z-index:-1;
display:none; position:fixed; z-index:2;
padding:5px; margin:5px;
background-color: rgba(0,0,40,.8);
}
@ -162,14 +165,12 @@ padding-left: 20px;
}
@media all and (max-width: 640px) {
aside {
float: none;
}
footer img {
max-height: 1em;
}
footer a {
font-size: xx-small;
}
body { margin-bottom:1em; }
body { margin-bottom:1em; font-size: smaller; }
}

View File

@ -1,6 +1,4 @@
<%@ Page Title="Comptes utilisateur - Index" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %>
<asp:Content ContentPlaceHolderID="header" ID="headerContent" runat="server">
<h2>Comptes utilisteur</h2>
</asp:Content>
<%@ Page Title="Comptes utilisateur" Language="C#" Inherits="System.Web.Mvc.ViewPage<DataAccess>" MasterPageFile="~/Models/App.master" %>
<asp:Content ContentPlaceHolderID="MainContent" ID="MainContentContent" runat="server">
</asp:Content>
Pas de contenu :-(
</asp:Content>

View File

@ -11,7 +11,7 @@
<%= Html.Password( "Password" ) %>
<%= Html.ValidationMessage("Password", "*") %><br/>
<label for="RememberMe">Se souvenir du mot de passe:</label>
<%= Html.LabelFor(model => model.RememberMe) %>
<%= Html.CheckBox("RememberMe") %>
<%= Html.ValidationMessage("RememberMe", "") %><br/>
<%= Html.Hidden("returnUrl",ViewData["returnUrl"]) %>

View File

@ -56,10 +56,10 @@ Avatar </td><td> <img class="avatar" src="<%=Model.avatar%>" alt=""/>
<input type="file" id="AvatarFile" name="AvatarFile"/>
<%= Html.ValidationMessage("AvatarFile", "*") %></td></tr>
<tr><td align="right">
<%= Html.LabelFor(model => model.GoogleCalendar) %>
<%= Html.LabelFor(model => model.GoogleCalendar) %>:
</td>
<td>
<td> <%= Html.Encode(Model.GoogleCalendar) %>
<%= Html.ActionLink("Choisir l'agenda","ChooseCalendar","Google",new { returnUrl= Request.Url.AbsolutePath }, new { @class="actionlink" }) %>
</td>
</tr>
</table>

View File

@ -1,4 +1,18 @@
<%@ Page Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage<DataAccess>" %>
<%@ Page Title="Admin" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="MainContentContent" ContentPlaceHolderID="MainContent" runat="server">
<div class="panel">
<ul><li>
<%= Html.ActionLink("Backups","Backups") %>
</li>
<li><%= Html.ActionLink("Restaurations", "Restore") %></li>
<li><%= Html.ActionLink("Create backup","CreateBackup") %></li>
<li><%= Html.ActionLink("Remove user", "RemoveUser") %></li>
<li><%= Html.ActionLink("Remove role", "RemoveRoleQuery") %></li>
<li><%= Html.ActionLink("User list", "UserList") %></li>
<li><%= Html.ActionLink("Role list", "RoleList") %></li>
</ul>
</div>
</asp:Content>

View File

@ -1,4 +1,4 @@
<%@ Page Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage<DataAccess>" %>
<%@ Page Title="Restore" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage<DataAccess>" %>
<asp:Content ID="MainContentContent" ContentPlaceHolderID="MainContent" runat="server">
<%= Html.ValidationSummary("Restore a database backup") %>
<% using (Html.BeginForm("Restore","Admin")) { %>

View File

@ -0,0 +1,9 @@
<%@ Page Title="Back office" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="MainContentContent" ContentPlaceHolderID="MainContent" runat="server">
</asp:Content>
<asp:Content ID="MASContentContent" ContentPlaceHolderID="MASContent" runat="server">
<ul><li>
<%= Html.ActionLink("Catalog","Catalog","FrontOffice" ) %>
</li></ul>
</asp:Content>

View File

@ -1,14 +1,9 @@
<%@ Page Title="Billets utilisateurs" Language="C#" Inherits="System.Web.Mvc.ViewPage<BlogEntryCollection>" MasterPageFile="~/Models/App.master"%>
<%@ Register Assembly="Yavsc.WebControls" TagPrefix="yavsc" Namespace="Yavsc.WebControls" %>
<asp:Content ContentPlaceHolderID="init" ID="init1" runat="server">
<% Title = ((string) ((Profile)ViewData["BlogUserProfile"]).BlogTitle)+" - "+YavscHelpers.SiteName ; %>
</asp:Content>
<asp:Content ContentPlaceHolderID="overHeaderOne" ID="header1" runat="server">
<h1 class="blogtitle"><a href="/Blog/<%=ViewData["BlogUser"]%>">
<img class="avatar" src="/Blogs/Avatar?user=<%=ViewData["BlogUser"]%>" alt="ViewData["BlogUser"]"/>
<%=ViewData["BlogTitle"]%></a> - <a href="/"> <%= YavscHelpers.SiteName %> </a> </h1>
<% Title = ((string) ((Profile)ViewData["BlogUserProfile"]).BlogTitle) ; %>
</asp:Content>
<asp:Content ContentPlaceHolderID="MainContent" ID="MainContentContent" runat="server">
<%
foreach (BlogEntry e in this.Model) { %>

View File

@ -4,7 +4,6 @@
<script type="text/javascript" src="<%=Url.Content("~/Scripts/jquery-2.1.1.js")%>"></script>
<script type="text/javascript" src="<%=Url.Content("~/Scripts/jquery.tablesorter.js")%>"></script>
<script type="text/javascript" src="<%=Url.Content("~/Scripts/jquery.validate.js")%>"></script>
<script type="text/javascript" src="<%=Url.Content("~/Scripts/jquery.validate.unobtrusive.js")%>"></script>
<link rel="stylesheet" href="<%=Url.Content("~/Theme/dark/style.css")%>" type="text/css" media="print, projection, screen" />
</asp:Content>

View File

@ -0,0 +1,11 @@
<%@ Page Title="Front office" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="MainContentContent" ContentPlaceHolderID="MainContent" runat="server">
</asp:Content>
<asp:Content ID="MASContentContent" ContentPlaceHolderID="MASContent" runat="server">
<ul><li>
<%= Html.ActionLink("Catalog","Catalog" ) %>
</li><li>
<%= Html.ActionLink("Estimates","Estimates" ) %>
</li></ul>
</asp:Content>

View File

@ -1,5 +0,0 @@
<%@ Page Title="Catalog" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %>
<asp:Content ContentPlaceHolderID="MainContent" ID="MainContentContent" runat="server">
</asp:Content>

View File

@ -0,0 +1,14 @@
<%@ Page Title="Google calendar usage" Language="C#" Inherits="System.Web.Mvc.ViewPage<CalendarList>" MasterPageFile="~/Models/App.master" %>
<asp:Content ContentPlaceHolderID="MainContent" ID="MainContentContent" runat="server">
<% using ( Html.BeginForm("SetCalendar","Google") ) { %>
<% foreach (CalendarListEntry e in Model.items.Where(x=>x.accessRole=="owner")) { %>
<input type="radio" name="calchoice" id="calchoice" value="<%=e.id%>" >
<%=Html.Encode(e.summary)%> <br>
<i><%=Html.Encode(e.description)%></i> <br>
<% } %>
<input type="submit">
<% } %>
</asp:Content>

View File

@ -0,0 +1,91 @@
<%@ Page Title="Date search" Language="C#" Inherits="System.Web.Mvc.ViewPage<AskForADate>" MasterPageFile="~/Models/App.master" %>
<asp:Content ContentPlaceHolderID="head" ID="headContent" runat="server">
<script type="text/javascript" src="/Scripts/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="/Scripts/jquery.timepicker.js"></script>
<script type="text/javascript" src="/Scripts/jquery.mousewheel.js"></script>
<link rel="stylesheet" type="text/css" href="/Theme/jquery.timepicker.css" />
<script type="text/javascript" src="/Scripts/jquery-ui.js"></script>
<link rel="stylesheet" href="/Theme/jquery-ui.css">
<style>
.ui-icon .ui-icon-circle-triangle-e {
background-image: url(/images/ui-bg_flechg.png);
}
.ui-datepicker-next .ui-corner-all {
background-image: url(/images/ui-bg_flechd.png);
}
</style>
<script>
$.widget( "ui.timespinner", $.ui.spinner, {
options: {
// seconds
step: 60 * 1000,
// hours
page: 60
},
_parse: function( value ) {
if ( typeof value === "string" ) {
// already a timestamp
if ( Number( value ) == value ) {
return Number( value );
}
return +Globalize.parseDate( value );
}
return value;
},
_format: function( value ) {
return Globalize.format( new Date(value), "t" );
}
});
</script>
</asp:Content>
<asp:Content ContentPlaceHolderID="MainContent" ID="MainContentContent" runat="server">
<% using ( Html.BeginForm("DateQuery","Google") ) { %>
<p>Période de recherche:</p>
<p>
<%= Html.LabelFor(model=>model.MinDate) %>:<br>
Le <input type="text" id="MinDate">
à
<input type="text" id="MinTime" class="time"/>
<%= Html.ValidationMessageFor(model=>model.MinDate) %>
</p>
<p>
<%= Html.LabelFor(model=>model.MaxDate) %>:<br>
Le <input type="text" id="MaxDate">
à
<input type="text" id="MaxTime" class="time"/>
<%= Html.ValidationMessageFor(model=>model.MaxDate) %>
</p>
<p>
Durée minimale : <input type="text" id="Duration" />
</p>
<script>
$(function() {
$('#MinTime').timepicker({ 'scrollDefault': 'now' });
$('#MaxTime').timepicker({ 'scrollDefault': 'now' });
$( "#MinDate" ).datepicker();
$( "#MaxDate" ).datepicker();
$( "#Duration" ).timespinner();
});
</script>
<input type="submit">
<% } %>
<pre><%= Html.Encode(ViewData["json"]) %></pre>
</asp:Content>

View File

@ -5,7 +5,7 @@
« Voir le monde comme un rêve est un bon point de vue. Quand on fait un cauchemar, on se réveille et on se dit que ce nétait quun rêve. Il est dit que le monde où nous vivons nen diffère en rien ».
<br/><a href="http://unefenetresurlemonde.over-blog.com/article-34325590.html">Ghost Dog, la Voie du samouraï</a>
</p><div>
<%= Html.ActionLink("Les blogs","Index","Blogs") %>
<%= Html.ActionLink("Les blogs","Index","Blogs",null, new { @class="actionlink" }) %>
</div>
</asp:Content>

View File

@ -21,7 +21,6 @@
</controls>
<namespaces>
<add namespace="SalesCatalog.Model" />
<add namespace="Yavsc.Model" />
<add namespace="Yavsc.Helpers" />
<add namespace="Yavsc.Admin" />
<add namespace="Yavsc.CatExts" />
@ -29,6 +28,7 @@
<add namespace="Yavsc.Model.Admin" />
<add namespace="Yavsc.Model.Blogs" />
<add namespace="Yavsc.Model.WorkFlow" />
<add namespace="Yavsc.Model.Google" />
</namespaces>
</pages>
</system.web>

View File

@ -115,6 +115,7 @@ http://msdn2.microsoft.com/en-us/library/b5ysx397.aspx
<add namespace="System.Linq" />
<add namespace="System.Collections.Generic" />
<add namespace="Yavsc.Helpers" />
<add namespace="Yavsc.Model" />
</namespaces>
</pages>
<authorization>
@ -132,7 +133,7 @@ http://msdn2.microsoft.com/en-us/library/b5ysx397.aspx
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</httpModules>
<httpRuntime maxRequestLength="52428800" />
<trace enabled="false" localOnly="true" pageOutput="false" requestLimit="10" traceMode="SortByTime" />
<trace enabled="false" localOnly="true" pageOutput="true" requestLimit="10" traceMode="SortByTime" />
<globalization requestEncoding="utf-8" responseEncoding="utf-8" culture="auto" uiCulture="auto" enableClientBasedCulture="true" />
<membership defaultProvider="NpgsqlMembershipProvider" userIsOnlineTimeWindow="1">
<providers>
@ -179,6 +180,8 @@ http://msdn2.microsoft.com/en-us/library/b5ysx397.aspx
<add name="gtokentype" />
<add name="gtokenexpir" />
<add name="avatar" />
<add name="gcalapi" />
<add name="gcalid" />
</properties>
</profile>
<blog defaultProvider="NpgsqlBlogProvider">

View File

@ -117,6 +117,7 @@
<Folder Include="App_GlobalResources\" />
<Folder Include="Views\Google\" />
<Folder Include="Settings\" />
<Folder Include="Views\BackOffice\" />
</ItemGroup>
<ItemGroup>
<Compile Include="Controllers\HomeController.cs" />
@ -153,7 +154,6 @@
<Compile Include="Formatters\SimpleFormatter.cs" />
<Compile Include="ValidateAjaxAttribute.cs" />
<Compile Include="Controllers\IOrderInfo.cs" />
<Compile Include="Controllers\FormInputValue.cs" />
<Compile Include="Controllers\IValueProvider.cs" />
<Compile Include="Controllers\GoogleController.cs" />
<Compile Include="Controllers\ModuleController.cs" />
@ -213,7 +213,6 @@
<Content Include="Views\Admin\AddRole.aspx" />
<Content Include="Views\Admin\UserList.aspx" />
<Content Include="Views\Admin\RemoveRoleQuery.aspx" />
<Content Include="Views\Admin\RemoveUserQuery.aspx" />
<Content Include="Views\Admin\RoleList.aspx" />
<Content Include="Views\Admin\CreateBackup.aspx" />
<Content Include="Views\Admin\BackupCreated.aspx" />
@ -243,7 +242,6 @@
<Content Include="instdbws.sql" />
<Content Include="Views\FrontOffice\Writting.ascx" />
<Content Include="packages.config" />
<Content Include="Views\Google\Calendar.aspx" />
<Content Include="Views\Google\Login.aspx" />
<Content Include="Scripts\jquery-2.1.1-vsdoc.js" />
<Content Include="Scripts\jquery-2.1.1.js" />
@ -255,6 +253,19 @@
<Content Include="Scripts\rangyinputs-jquery-1.1.2.js" />
<Content Include="images\sign-in-with-google.png" />
<Content Include="Views\Account\Unregister.aspx" />
<Content Include="Views\Google\ChooseCalendar.aspx" />
<Content Include="Views\Google\DateQuery.aspx" />
<Content Include="Scripts\GruntFile.js" />
<Content Include="Scripts\jquery.timepicker.js" />
<Content Include="Scripts\jquery.timepicker.min.js" />
<Content Include="Theme\jquery.timepicker.css" />
<Content Include="Theme\jquery-ui.css" />
<Content Include="Theme\jquery-ui.min.css" />
<Content Include="Scripts\jquery.mousewheel.js" />
<Content Include="Views\Admin\RemoveUser.aspx" />
<Content Include="Views\FrontOffice\Index.aspx" />
<Content Include="Views\BackOffice\Index.aspx" />
<Content Include="images\sign-in-with-google-s.png" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -255,6 +255,7 @@ CREATE TABLE profiledata
gcalid character varying(255),
gtokenexpir timestamp with time zone, -- Google access token expiration date
avatar character varying(512), -- url for an avatar
gcalapi boolean NOT NULL DEFAULT false, -- true when user authorized to use its Google calendar
CONSTRAINT fkprofiles2 FOREIGN KEY (uniqueid)
REFERENCES profiles (uniqueid) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE
@ -298,6 +299,9 @@ CREATE TABLE profiles
lastactivitydate timestamp with time zone,
lastupdateddate timestamp with time zone,
CONSTRAINT profiles_pkey PRIMARY KEY (uniqueid),
CONSTRAINT fk_profileusers FOREIGN KEY (username, applicationname)
REFERENCES users (username, applicationname) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT pkprofiles UNIQUE (username, applicationname)
)
WITH (

View File

@ -0,0 +1,48 @@
//
// AskForADate.cs
//
// Author:
// Paul Schneider <paulschneider@free.fr>
//
// Copyright (c) 2014 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 <http://www.gnu.org/licenses/>.
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace Yavsc.Model.Google
{
public class AskForADate
{
public AskForADate ()
{
MinDate = MaxDate = DateTime.Now.AddMinutes (5);
}
[Display(Name="MinDate",ResourceType=typeof(LocalizedText))]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public DateTime MinDate { get; set; }
[Display(Name="MaxDate",ResourceType=typeof(LocalizedText))]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public DateTime MaxDate { get; set; }
[Display(Name="Consultant",ResourceType=typeof(LocalizedText))]
public string UserName { get; set; }
}
}

View File

@ -34,24 +34,6 @@ using Yavsc.Model;
namespace Yavsc.Model.Google
{
/*
"url": "https://plus.google.com/111395572362177872801",
"image": {
"url": "https://lh6.googleusercontent.com/-JqDVMPqafdA/AAAAAAAAAAI/AAAAAAAAADY/FamseW6_nl4/photo.jpg?sz=50",
"isDefault": false
},
"placesLived": [
{
"value": "Suresnes, France",
"primary": true
}
],
"isPlusUser": true,
"language": "fr",
"circledByCount": 0,
"verified": false
}
*/
public class AuthToken {
public string access_token { get; set; }

View File

@ -0,0 +1,45 @@
//
// CalendarList.cs
//
// Author:
// Paul Schneider <paulschneider@free.fr>
//
// Copyright (c) 2014 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 <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading;
using System.Web.Mvc;
using System.Configuration;
using System.Threading.Tasks;
using System.Text;
using System.Net;
using System.IO;
using Yavsc.Model;
namespace Yavsc.Model.Google
{
public class CalendarList {
public string kind { get; set;}
public string etag { get; set; }
public string nextSyncToken { get; set; }
public CalendarListEntry[] items { get; set; }
}
}

View File

@ -0,0 +1,65 @@
//
// CalendarListEntry.cs
//
// Author:
// Paul Schneider <paulschneider@free.fr>
//
// Copyright (c) 2014 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 <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading;
using System.Web.Mvc;
using System.Configuration;
using System.Threading.Tasks;
using System.Text;
using System.Net;
using System.IO;
using Yavsc.Model;
namespace Yavsc.Model.Google
{
public class CalendarListEntry {
public string kind { get; set;}
public string etag { get; set; }
public string id { get; set; }
public string summary { get; set; }
public string description { get; set; }
public string timeZone { get; set; }
public string colorId { get; set; }
public string backgroundColor { get; set; }
public string foregroundColor { get; set; }
public bool selected { get; set; }
public bool primary { get; set; }
public string accessRole { get; set; }
public class Reminder {
public string method { get; set; }
public int minutes { get; set; }
}
public Reminder[] defaultReminders { get; set; }
/* "notificationSettings": { "notifications":
[ { "type": "eventCreation", "method": "email" },
{ "type": "eventChange", "method": "email" },
{ "type": "eventCancellation", "method": "email" },
{ "type": "eventResponse", "method": "email" } ] }, "primary": true },
*/
}
}

View File

@ -34,6 +34,7 @@ using Yavsc.Model;
namespace Yavsc.Model.Google
{
public class People {
public string kind { get; set; }
public string etag { get; set; }

View File

@ -106,6 +106,12 @@ namespace Yavsc.Model {
}
}
public static string Remember_me {
get {
return ResourceManager.GetString("Remember_me", resourceCulture);
}
}
public static string Title {
get {
return ResourceManager.GetString("Title", resourceCulture);
@ -136,6 +142,18 @@ namespace Yavsc.Model {
}
}
public static string Date_search {
get {
return ResourceManager.GetString("Date_search", resourceCulture);
}
}
public static string Google_calendar {
get {
return ResourceManager.GetString("Google_calendar", resourceCulture);
}
}
public static string Description {
get {
return ResourceManager.GetString("Description", resourceCulture);
@ -154,16 +172,34 @@ namespace Yavsc.Model {
}
}
public static string MinDate {
get {
return ResourceManager.GetString("MinDate", resourceCulture);
}
}
public static string Tex_version {
get {
return ResourceManager.GetString("Tex_version", resourceCulture);
}
}
public static string Consultant {
get {
return ResourceManager.GetString("Consultant", resourceCulture);
}
}
public static string Count {
get {
return ResourceManager.GetString("Count", resourceCulture);
}
}
public static string MaxDate {
get {
return ResourceManager.GetString("MaxDate", resourceCulture);
}
}
}
}

View File

@ -33,4 +33,10 @@
<data name="Google_error"><value>Erreur Google : {0}</value></data>
<data name="access_denied"><value>Accès refusé</value></data>
<data name="UserName"><value>Nom d'utilisateur</value></data>
<data name="Google_calendar"><value>Agenda Google</value></data>
<data name="Consultant"><value>Consultant</value></data>
<data name="MinDate"><value>Date minimale du rendez-vous</value></data>
<data name="MaxDate"><value>Date maximale du rendez-vous</value></data>
<data name="Date_search"><value>Recherche d'une date pour rendez-vous</value></data>
<data name="Remember_me"><value>Se souvenir du mot de passe</value></data>
</root>

View File

@ -33,4 +33,10 @@
<data name="Google_error"><value>Google error : {0}</value></data>
<data name="access_denied"><value>Access denied</value></data>
<data name="UserName"><value>User name</value></data>
</root>
<data name="Google_calendar"><value>Google calendar</value></data>
<data name="Consultant"><value>Consultant</value></data>
<data name="MinDate"><value>Minimal date for the rendez-vous</value></data>
<data name="MaxDate"><value>Maximal date for the rendez-vous</value></data>
<data name="Date_search"><value>Date search for a rendez-vous</value></data>
<data name="Remember_me"><value>Remember me</value></data>
</root>

View File

@ -16,7 +16,7 @@ namespace Yavsc.Model.RolesAndMembers
[RegularExpression("([a-z]|[A-Z]|[-_.~#{}`'\\^])+")]
public string Password { get; set; }
[Display(Name = "Se souvenir du mot de passe")]
[Display(Name = "Remember_me",ResourceType=typeof(LocalizedText))]
public bool RememberMe { get; set; }
}
}

View File

@ -3,6 +3,7 @@ using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web.Profile;
using System.Web.Security;
using System.Web;
namespace Yavsc.Model.RolesAndMembers
{
@ -78,7 +79,7 @@ namespace Yavsc.Model.RolesAndMembers
[DisplayName ("Clé RIB")]
public int BankedKey { get; set; }
[Display(Name="Google Calendar")]
[Display(Name="Google_calendar",ResourceType=typeof(LocalizedText))]
public string GoogleCalendar { get; set; }
public bool IsBankable { get {
@ -107,6 +108,8 @@ namespace Yavsc.Model.RolesAndMembers
{
}
public bool RememberMe { get; set; }
public Profile (ProfileBase profile)
{
object b = profile.GetPropertyValue ("BlogVisible");
@ -163,6 +166,8 @@ namespace Yavsc.Model.RolesAndMembers
s = profile.GetPropertyValue ("BankedKey");
BankedKey = (s == null) ? 0 : (s is DBNull)? 0 : (int)s;
s = profile.GetPropertyValue ("gcalid");
GoogleCalendar = (s is DBNull)? null : (string) s;
}
}
}

View File

@ -88,6 +88,9 @@
<Compile Include="Google\People.cs" />
<Compile Include="Google\AuthToken.cs" />
<Compile Include="Google\SignIn.cs" />
<Compile Include="Google\CalendarList.cs" />
<Compile Include="Google\CalendarListEntry.cs" />
<Compile Include="Google\AskForADate.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>