diff --git a/.gitignore b/.gitignore index 36d54d4d..94909cfd 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,11 @@ dist bower_components node_modules svg +web/Web.config.prod +web/Web.config.dev + .nuget .gitignore web/bfiles +web/App_Themes/style.totem.css diff --git a/ChangeLog b/ChangeLog index 6a9ce1d2..161629d2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,30 @@ -2015-10-24 Paul Schneider +2015-11-17 Paul Schneider - * Makefile: restores the server reload after rsync call + * Makefile: adds nuget targets -2015-10-09 Paul Schneider +2015-11-14 Paul Schneider - * Makefile: reloads config after each rsync call + * Makefile: Fixes the `clean` target + + * README.md: WIP Skills + +2015-11-11 Paul Schneider + + * README.md: \n @ EOF + + * Yavsc.sln: remove the `booking` project from the solution + + * Edit.aspx: cleaning + +2015-11-08 Paul Schneider + + * README.md: Adds a TODO list + + * Yavsc.sln: do not build the MVC 5.1 project, that does not + run under mono. + + * ChangeLog: this file should not be maintained as a git + respository legacy file + + * .gitignore: this file should not be maintained under git diff --git a/Makefile b/Makefile index 2bd59221..3b37e8c7 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,6 @@ deploy: ddir build xbuild /p:Configuration=$(CONFIG) /p:SkipCopyUnchangedFiles=$(COPYUNCHANGED) /p:DeployDir=../$(LDYDESTDIR) /t:Deploy web/Web.csproj mv $(LDYDESTDIR)/Web.config $(LDYDESTDIR)/Web.config.new - rsync_% : HOST = $(HOST_$@) rsync_% : DESTDIR = $(DESTDIR_$@) @@ -44,7 +43,7 @@ build: xbuild /p:Configuration=$(CONFIG) /t:Build Yavsc.sln clean: - xbuild /t:Clean + xbuild /p:Configuration=$(CONFIG) /t:Clean Yavsc.sln find -name "StyleCop.Cache" -exec rm {} \; distclean: clean @@ -73,4 +72,8 @@ rsync_pre: rsync_prod: +nuget_restore: + for prj in ITContentProvider NpgsqlBlogProvider NpgsqlContentProvider NpgsqlMRPProviders Presta SalesCatalog TestAPI web WebControls yavscclient yavscModel; do nuget restore "$${prj}/packages.config" -SolutionDirectory . ; done +nuget_update: + for prj in ITContentProvider NpgsqlBlogProvider NpgsqlContentProvider NpgsqlMRPProviders Presta SalesCatalog TestAPI web WebControls yavscclient yavscModel; do nuget update "$${prj}/packages.config" ; done diff --git a/NpgsqlBlogProvider/ChangeLog b/NpgsqlBlogProvider/ChangeLog index 3b47b23f..073ce25d 100644 --- a/NpgsqlBlogProvider/ChangeLog +++ b/NpgsqlBlogProvider/ChangeLog @@ -1,31 +1,20 @@ -2015-11-04 Paul Schneider +2015-11-14 Paul Schneider - * NpgsqlBlogProvider.cs: Implements the note + * NpgsqlBlogProvider.cs: Bill ranking, and delivering hidden + content to owner -2015-10-19 Paul Schneider +2015-11-11 Paul Schneider - * NpgsqlTagInfo.cs: Fixes the photo retreival + * NpgsqlBlogProvider.cs: refactoring -2015-10-17 Paul Schneider +2015-11-06 Paul Schneider - * NpgsqlTagInfo.cs: - * NpgsqlBlogProvider.cs: + * NpgsqlBlogProvider.cs: refactorisation, to render Tags and + Circles on each entry type. + Fixes the `Find` Method using the `MatchTag` search flag -2015-10-17 Paul Schneider + * NpgsqlBlogProvider.csproj: cleanning - * NpgsqlTagInfo.cs: - * NpgsqlBlogProvider.cs: - * NpgsqlBlogProvider.csproj: - -2015-10-17 Paul Schneider - - * NpgsqlBlogProvider.cs: - -2015-10-13 Paul Schneider - - * NpgsqlBlogProvider.cs: implements the tag methods on db - -2015-10-10 Paul Schneider - - * NpgsqlBlogProvider.cs: + * ChangeLog: + * NpgsqlTagInfo.cs: diff --git a/NpgsqlBlogProvider/NpgsqlBlogProvider.cs b/NpgsqlBlogProvider/NpgsqlBlogProvider.cs index fd3c179f..53f9fb78 100644 --- a/NpgsqlBlogProvider/NpgsqlBlogProvider.cs +++ b/NpgsqlBlogProvider/NpgsqlBlogProvider.cs @@ -5,7 +5,6 @@ using Npgsql; using System.Collections.Generic; using Yavsc.Model.Blogs; using Yavsc.Model.Circles; -using System.Web.Mvc; using NpgsqlTypes; using System.Linq; @@ -22,34 +21,29 @@ namespace Npgsql.Web.Blog #region implemented abstract members of BlogProvider + public override void UpdatePost (BlogEntry be) + { + // TODO Tags and rate should not be ignored + UpdatePost (be.Id, be.Title, be.Content, be.Visible, be.AllowedCircles); + } + /// /// Note the specified postid and note. /// /// Postid. - /// Note. - public override void Note (long postid, int note) + /// rate. + public override void Rate (long postid, int rate) { using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) using (NpgsqlCommand cmd = cnx.CreateCommand ()) { - cmd.CommandText = "update blogs set note = :note where _id = :pid)"; - cmd.Parameters.AddWithValue ("note", note); + cmd.CommandText = "update blog set rate = :rate where _id = :pid"; + cmd.Parameters.AddWithValue ("rate", rate); cmd.Parameters.AddWithValue ("pid", postid); cnx.Open (); cmd.ExecuteNonQuery (); cnx.Close (); } } - - /// - /// Gets the tag info. - /// - /// The tag info. - /// Tagname. - public override TagInfo GetTagInfo (string tagname) - { - return new NpgsqlTagInfo (connectionString, tagname); - } - /// /// Tag the specified post by identifier /// using the given tag. @@ -153,11 +147,13 @@ namespace Npgsql.Web.Blog cmd.CommandText = "update blog set modified=:now," + " title = :title," + - " bcontent=:content, " + + " bcontent = :content, " + " visible = :visible " + "where _id = :id"; cmd.Parameters.AddWithValue ("now", now); cmd.Parameters.AddWithValue ("title", title); + if (content == null) + content = ""; cmd.Parameters.AddWithValue ("content", content); cmd.Parameters.AddWithValue ("visible", visible); cmd.Parameters.AddWithValue ("id", postid); @@ -295,7 +291,8 @@ namespace Npgsql.Web.Blog BlogEntry be = null; using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) using (NpgsqlCommand cmd = cnx.CreateCommand ()) { - cmd.CommandText = "select username, title, bcontent, modified, posted, visible, photo from blog " + + cmd.CommandText = "select username, title, bcontent, modified, " + + "posted, visible, photo, rate from blog " + "where applicationname = :appname and _id = :id"; cmd.Parameters.AddWithValue ("appname", applicationName); cmd.Parameters.AddWithValue ("id", postid); @@ -309,6 +306,7 @@ namespace Npgsql.Web.Blog be.Modified = rdr.GetDateTime (rdr.GetOrdinal ("modified")); be.Posted = rdr.GetDateTime (rdr.GetOrdinal ("posted")); be.Visible = rdr.GetBoolean (rdr.GetOrdinal ("visible")); + be.Rate = rdr.GetInt32 (rdr.GetOrdinal ("rate")); int oph = rdr.GetOrdinal ("photo"); if (!rdr.IsDBNull (oph)) be.Photo = rdr.GetString (oph); @@ -351,8 +349,8 @@ namespace Npgsql.Web.Blog UUTBlogEntryCollection bec = new UUTBlogEntryCollection (username, title); using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) { using (NpgsqlCommand cmd = cnx.CreateCommand ()) { - cmd.CommandText = "select _id,bcontent,modified,posted,visible,photo from blog " + - "where applicationname = :appname and username = :username and title = :title"; + cmd.CommandText = "select _id,bcontent,modified,posted,visible,photo,rate from blog " + + "where applicationname = :appname and username = :username and title = :title order by rate desc"; cmd.Parameters.AddWithValue ("appname", NpgsqlDbType.Varchar, applicationName); cmd.Parameters.AddWithValue ("username", NpgsqlDbType.Varchar, username); cmd.Parameters.AddWithValue ("title", NpgsqlDbType.Varchar, title); @@ -367,12 +365,14 @@ namespace Npgsql.Web.Blog be.Modified = rdr.GetDateTime (rdr.GetOrdinal ("modified")); be.Posted = rdr.GetDateTime (rdr.GetOrdinal ("posted")); be.Visible = rdr.GetBoolean (rdr.GetOrdinal ("visible")); + be.Rate = rdr.GetInt32 (rdr.GetOrdinal ("rate")); be.Id = rdr.GetInt64 (rdr.GetOrdinal ("_id")); { int oph = rdr.GetOrdinal ("photo"); if (!rdr.IsDBNull (oph)) be.Photo = rdr.GetString (oph); } + bec.Add (be); } rdr.Close (); @@ -380,30 +380,13 @@ namespace Npgsql.Web.Blog } if (bec.Count != 0) { - using (NpgsqlCommand cmdtags = cnx.CreateCommand ()) { - long pid = 0; - cmdtags.CommandText = "select tag.name from tag,tagged where tag._id = tagged.tagid and tagged.postid = :postid"; - cmdtags.Parameters.AddWithValue ("postid", NpgsqlTypes.NpgsqlDbType.Bigint, pid); - cmdtags.Prepare (); - foreach (BlogEntry be in bec) { - List tags = new List (); - cmdtags.Parameters ["postid"].Value = be.Id; - using (NpgsqlDataReader rdrt = cmdtags.ExecuteReader ()) { - while (rdrt.Read ()) { - tags.Add (rdrt.GetString (0)); - } - } - be.Tags = tags.ToArray (); - } - } - if (bec != null) - Populate (bec); + Populate (bec); } } return bec; } - private void SetCirclesOn (BlogEntry be) + private void SetCirclesOn (BasePost be) { List circles = new List (); using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) @@ -510,7 +493,7 @@ namespace Npgsql.Web.Blog } } - private void SetTagsOn (BlogEntry be) + private void SetTagsOn (BasePost be) { List tags = new List (); using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) @@ -534,7 +517,7 @@ namespace Npgsql.Web.Blog Populate (be); } - private void Populate (BlogEntry be) + private void Populate (BasePost be) { SetTagsOn (be); SetCirclesOn (be); @@ -556,7 +539,7 @@ namespace Npgsql.Web.Blog if (title == null) throw new ArgumentNullException ("title"); if (content == null) - throw new ArgumentNullException ("content"); + content = ""; using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) { using (NpgsqlCommand cmd = cnx.CreateCommand ()) { cmd.CommandText = "insert into blog (title,bcontent,modified,posted,visible,username,applicationname)" + @@ -589,9 +572,13 @@ namespace Npgsql.Web.Blog using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) { cnx.Open (); using (NpgsqlCommand cmd = cnx.CreateCommand ()) { - cmd.CommandText = "update blog set photo = :photo where _id = :pid"; + if (photo == null) + cmd.CommandText = "update blog set photo = NULL where _id = :pid"; + else { + cmd.CommandText = "update blog set photo = :photo where _id = :pid"; + cmd.Parameters.AddWithValue ("photo", photo); + } cmd.Parameters.AddWithValue ("pid", pid); - cmd.Parameters.AddWithValue ("photo", photo); cmd.ExecuteNonQuery (); } cnx.Close (); @@ -607,6 +594,7 @@ namespace Npgsql.Web.Blog cmd.Parameters.AddWithValue ("pid", pid); cmd.ExecuteNonQuery (); } + if (circles != null) if (circles.Length > 0) using (NpgsqlCommand cmd = cnx.CreateCommand ()) { cmd.CommandText = "insert into blog_access (post_id,circle_id) values (:pid,:cid)"; @@ -640,7 +628,7 @@ namespace Npgsql.Web.Blog using (NpgsqlCommand cmd = cnx.CreateCommand ()) { if (readersName != null) { cmd.CommandText = "select _id, title,bcontent, modified," + - "posted,username,visible,photo " + + "posted,username,visible,photo,rate " + "from blog b left outer join " + "(select count(*)>0 acc, a.post_id pid " + "from blog_access a," + @@ -652,29 +640,29 @@ namespace Npgsql.Web.Blog cmd.Parameters.AddWithValue ("uname", readersName); } else { cmd.CommandText = "select _id, title,bcontent,modified," + - "posted,username,visible,photo " + + "posted,username,visible,photo,rate " + "from blog b left outer join " + "(select count(*)>0 acc, a.post_id pid " + "from blog_access a" + " group by a.post_id) ma on (ma.pid = b._id)" + " where " + - " ma.acc IS NULL and " + + " ( ma.acc IS NULL and " + " b.Visible IS TRUE and " + - " applicationname = :appname"; + " applicationname = :appname ) "; } cmd.Parameters.AddWithValue ("appname", applicationName); if (pattern != null) { if ((searchflags & FindBlogEntryFlags.MatchTag) > 0) { cmd.CommandText += - "AND EXISTS (SELECT tag._id FROM public.tag, public.tagged WHERE " + - "public.tag._id = public.tagged.tagid " + - "AND public.tagged.postid = a.post_id " + - "public.tag.name like :tagname) "; + " AND EXISTS (SELECT tag._id FROM tag, tagged \n" + + " WHERE tag._id = tagged.tagid \n" + + " AND tagged.postid = b._id \n" + + " AND tag.name like :tagname) \n"; cmd.Parameters.AddWithValue ("tagname", pattern); } if ((searchflags & FindBlogEntryFlags.MatchContent) > 0) { - cmd.CommandText += " and bcontent like :bcontent"; + cmd.CommandText += " and bcontent like :bcontent \n"; cmd.Parameters.AddWithValue ("bcontent", pattern); } if ((searchflags & FindBlogEntryFlags.MatchTitle) > 0) { @@ -682,15 +670,16 @@ namespace Npgsql.Web.Blog cmd.Parameters.AddWithValue ("title", pattern); } if ((searchflags & FindBlogEntryFlags.MatchUserName) > 0) { - cmd.CommandText += " and username like :username"; + cmd.CommandText += " and username like :username \n"; cmd.Parameters.AddWithValue ("username", pattern); } } - if ((searchflags & FindBlogEntryFlags.MatchInvisible) == 0) { - cmd.CommandText += " and visible = true"; + if (((searchflags & FindBlogEntryFlags.MatchInvisible) == 0) && + (readersName == null) ) { + cmd.CommandText += " and visible = true \n"; } - cmd.CommandText += " order by posted desc"; + cmd.CommandText += " order by rate desc"; cnx.Open (); using (NpgsqlDataReader rdr = cmd.ExecuteReader ()) { // pageIndex became one based @@ -706,6 +695,7 @@ namespace Npgsql.Web.Blog be.Posted = rdr.GetDateTime (rdr.GetOrdinal ("posted")); be.Modified = rdr.GetDateTime (rdr.GetOrdinal ("modified")); be.Visible = rdr.GetBoolean (rdr.GetOrdinal ("visible")); + be.Rate = rdr.GetInt32 (rdr.GetOrdinal ("rate")); { int oph = rdr.GetOrdinal ("photo"); if (!rdr.IsDBNull (oph)) @@ -779,11 +769,14 @@ namespace Npgsql.Web.Blog be.Posted = rdr.GetDateTime (rdr.GetOrdinal ("posted")); be.Modified = rdr.GetDateTime (rdr.GetOrdinal ("modified")); be.Visible = true; // because of sql code used + be.Rate = rdr.GetInt32(rdr.GetOrdinal("rate")); { int oph = rdr.GetOrdinal ("photo"); if (!rdr.IsDBNull (oph)) be.Photo = rdr.GetString (oph); } + SetTagsOn (be); + SetCirclesOn (be); c.Add (be); } totalRecords++; diff --git a/NpgsqlBlogProvider/NpgsqlBlogProvider.csproj b/NpgsqlBlogProvider/NpgsqlBlogProvider.csproj index 22b1b709..82c92432 100644 --- a/NpgsqlBlogProvider/NpgsqlBlogProvider.csproj +++ b/NpgsqlBlogProvider/NpgsqlBlogProvider.csproj @@ -34,7 +34,6 @@ - @@ -44,7 +43,6 @@ - ..\packages\Npgsql.3.0.3\lib\net45\Npgsql.dll diff --git a/NpgsqlBlogProvider/NpgsqlTagInfo.cs b/NpgsqlBlogProvider/NpgsqlTagInfo.cs deleted file mode 100644 index 6685b582..00000000 --- a/NpgsqlBlogProvider/NpgsqlTagInfo.cs +++ /dev/null @@ -1,104 +0,0 @@ -// -// NpgsqlTagInfo.cs -// -// Author: -// Paul Schneider -// -// Copyright (c) 2015 GNU GPL -// -// 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.Model.Blogs; -using System.Collections.Generic; - -namespace Npgsql.Web.Blog -{ - /// - /// Npgsql tag info. - /// - public class NpgsqlTagInfo: TagInfo - { - /// - /// Initializes a new instance of the class. - /// - /// Connection string. - /// Tagname. - public NpgsqlTagInfo (string connectionString, string tagname): base(tagname) - { - titles = new List(); - using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) - using (NpgsqlCommand cmd = cnx.CreateCommand ()) { - cmd.CommandText = - "SELECT \n" + - " blog.username, \n" + - " blog.posted, \n" + - " blog.modified, \n" + - " blog.title, \n" + - " blog.bcontent, \n" + - " blog.visible, \n" + - " blog._id, \n" + - " blog.photo, \n" + - " tag.name\n" + - "FROM \n" + - " public.blog, \n" + - " public.tagged, \n" + - " public.tag\n" + - "WHERE \n" + - " tagged.postid = blog._id AND \n" + - " tag._id = tagged.tagid AND \n" + - " blog.visible = TRUE AND \n" + - " public.tag.name = :name"; - cmd.Parameters.AddWithValue ("name", tagname); - cnx.Open (); - using (NpgsqlDataReader rdr = cmd.ExecuteReader ()) { - while (rdr.Read ()) { - bool truncated; - int oph = rdr.GetOrdinal ("photo"); - string photo = null; - if (!rdr.IsDBNull (oph)) - photo = rdr.GetString (oph); - var pi = new BasePostInfo { - Title = rdr.GetString(3), - Author = rdr.GetString (0), - Id = rdr.GetInt64 (6), - Intro = MarkdownHelper.MarkdownIntro ( - rdr.GetString (4), - out truncated), - Visible = rdr.GetBoolean(5), - Photo = photo, - Modified = rdr.GetDateTime(2), - Posted = rdr.GetDateTime(1) - }; - titles.Add (pi); - } - } - } - } - - List titles; - - #region implemented abstract members of TagInfo - /// - /// Gets the titles. - /// - /// The titles. - public override System.Collections.Generic.IEnumerable Titles { - get { - return titles; - } - } - #endregion - } -} - diff --git a/NpgsqlContentProvider/ChangeLog b/NpgsqlContentProvider/ChangeLog index 925ef31f..c7cae7ea 100644 --- a/NpgsqlContentProvider/ChangeLog +++ b/NpgsqlContentProvider/ChangeLog @@ -1,9 +1,19 @@ -2015-10-30 Paul Schneider +2015-11-17 Paul Schneider - * NpgsqlContentProvider.cs: refactoring: a dedicated name - space for the catalog + * NpgsqlSkillProvider.cs: User's skills profile object now + implements an `Id` property, + in order to be rated, perhaps ranked in a near future. It's + implemented as the legay profile id. -2015-10-28 Paul Schneider +2015-11-17 Paul Schneider - * NpgsqlCircleProvider.cs: Restores circles edition + * NpgsqlSkillProvider.cs: implements a skill provider + + * NpgsqlContentProvider.csproj: Imports the + `NpgsqlSkillProvider` class + +2015-11-08 Paul Schneider + + * ChangeLog: this file should not be maintained as a git + respository legacy file diff --git a/NpgsqlContentProvider/NpgsqlContentProvider.csproj b/NpgsqlContentProvider/NpgsqlContentProvider.csproj index 591692b4..9b443b14 100644 --- a/NpgsqlContentProvider/NpgsqlContentProvider.csproj +++ b/NpgsqlContentProvider/NpgsqlContentProvider.csproj @@ -48,6 +48,7 @@ + diff --git a/NpgsqlMRPProviders/ChangeLog b/NpgsqlMRPProviders/ChangeLog index b9136c47..62c1c1c4 100644 --- a/NpgsqlMRPProviders/ChangeLog +++ b/NpgsqlMRPProviders/ChangeLog @@ -1,3 +1,12 @@ +2015-11-11 Paul Schneider + + * NpgsqlProfileProvider.cs: return the default value in the + targeted Type, in case of DBNull + +2015-11-06 Paul Schneider + + * NpgsqlProfileProvider.cs: nicer code + 2015-11-04 Paul Schneider * NpgsqlProfileProvider.cs: diff --git a/NpgsqlMRPProviders/NpgsqlProfileProvider.cs b/NpgsqlMRPProviders/NpgsqlProfileProvider.cs index b0e45456..b0a53d25 100644 --- a/NpgsqlMRPProviders/NpgsqlProfileProvider.cs +++ b/NpgsqlMRPProviders/NpgsqlProfileProvider.cs @@ -206,7 +206,7 @@ namespace Npgsql.Web cmd.CommandText = "SELECT * from profiledata, profiles where " + "profiledata.uniqueid = profiles.uniqueid " + "and profiles.username = @username " + - "and profiles.applicationname = @appname"; + "and profiles.applicationname = @appname "; cmd.Parameters.AddWithValue ("@username", username); cmd.Parameters.AddWithValue ("@appname", applicationName); cnx.Open (); @@ -216,7 +216,8 @@ namespace Npgsql.Web foreach (SettingsProperty p in collection) { SettingsPropertyValue v = new SettingsPropertyValue (p); int o = r.GetOrdinal (p.Name.ToLower ()); - v.PropertyValue = r.GetValue (o); + var obj = r.GetValue (o); + v.PropertyValue = (obj is DBNull) ? GetDefaultValue (p) : obj; c.Add (v); } } else { diff --git a/README.md b/README.md index 7c897da6..6076279d 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,22 @@ yavsc ===== [doc-fr](http://yavsc.pschneider.fr/Blogs/UserPost/paul/Documentation) + +# TODO FIRST + +1) Implement a Skills provider + +2) Create an `UserCardControl` + with quick access for users to his chat and the circle membership, and for admins to his roles, a blogentry count, and a link to the booking system + +3) Api refatoring: + + Concerning the blog entry edition, we only need Two methods: + + * ```long PostFile(long id)```, + used for creation when the given id is 0, in which case, the entry id created is returned. + Otherwise, used for import in the post spécified by its id, in which case, 0 is returned. + * `long Post(BlogEntry be)`, used to create or update a given or not + blog entry content. the returned value is the entry id at creation, or 0. + +4) UI themes diff --git a/TestAPI/ChangeLog b/TestAPI/ChangeLog index 1ffa62c9..9c11fcf8 100644 --- a/TestAPI/ChangeLog +++ b/TestAPI/ChangeLog @@ -1,3 +1,7 @@ +2015-11-14 Paul Schneider + + * TestAPI.csproj: nothing to view + 2015-11-04 Paul Schneider * test-domain-TestAPI.config: diff --git a/TestAPI/TestAPI.csproj b/TestAPI/TestAPI.csproj index 0668c673..a3b0eeef 100644 --- a/TestAPI/TestAPI.csproj +++ b/TestAPI/TestAPI.csproj @@ -79,6 +79,11 @@ nunit + + + nuget-core + + @@ -96,10 +101,6 @@ {68F5B80A-616E-4C3C-91A0-828AA40000BD} YavscModel - - {77044C92-D2F1-45BD-80DD-AA25B311B027} - Web - {C6E9E91B-97D3-48D9-8AA7-05356929E162} NpgsqlBlogProvider @@ -116,6 +117,10 @@ {90BF2234-7252-4CD5-B2A4-17501B19279B} SalesCatalog + + {77044C92-D2F1-45BD-80DD-AA25B311B027} + Web + diff --git a/WebControls/ChangeLog b/WebControls/ChangeLog index 0289448f..ab0aaaf5 100644 --- a/WebControls/ChangeLog +++ b/WebControls/ChangeLog @@ -1,3 +1,14 @@ +2015-11-17 Paul Schneider + + * RateControl.cs: refactorization + +2015-11-14 Paul Schneider + + * RateControl.cs: Uses its data model, and moves to the + general name space. + + * WebControls.csproj: Implements a server side rating control + 2015-10-13 Paul Schneider * ResultPages.cs: A multi-pages result meta info when one page diff --git a/WebControls/WebControls.csproj b/WebControls/WebControls.csproj index c4d0721b..9a4b4a0c 100644 --- a/WebControls/WebControls.csproj +++ b/WebControls/WebControls.csproj @@ -47,6 +47,7 @@ + diff --git a/Yavsc.sln b/Yavsc.sln index 92b16c03..c958fc27 100644 --- a/Yavsc.sln +++ b/Yavsc.sln @@ -27,7 +27,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ProjectSection(SolutionItems) = preProject LICENSE = LICENSE Makefile = Makefile - noavatar.xcf = noavatar.xcf README.md = README.md EndProjectSection EndProject diff --git a/booking/Admin/DataManager.cs b/booking/Admin/DataManager.cs new file mode 100644 index 00000000..33b8a71d --- /dev/null +++ b/booking/Admin/DataManager.cs @@ -0,0 +1,157 @@ +using System; +using System.Diagnostics; +using System.IO; +using Yavsc.Model.Admin; +using Npgsql.Web.Blog; +using System.Resources; +using System.Reflection; + +namespace Yavsc.Admin +{ + /// + /// Data manager. + /// + public class DataManager + { + DataAccess da; + /// + /// Initializes a new instance of the class. + /// + /// Datac. + public DataManager (DataAccess datac) + { + da = datac; + } + /// + /// Creates the backup. + /// + /// The backup. + public Export CreateBackup () + { + Environment.SetEnvironmentVariable("PGPASSWORD", da.Password); + 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 ( + "-wb -Z3 -f {0} -Ft -h {1} -U {2} -p {3} {4}", + fileName, da.Host, da.Dbuser, da.Port, da.Dbname ),e); + */ + Exec ("pg_dump", string.Format ( + "-f {0} -Ft -h {1} -U {2} -p {3} {4}", + fileName, da.Host, da.DbUser, da.Port, da.DbName ),e); + return e; + } + + private void Exec(string name, string args, TaskOutput output) + { + ProcessStartInfo Pinfo = + new ProcessStartInfo (name,args); + Pinfo.RedirectStandardError = true; + Pinfo.RedirectStandardOutput = true; + Pinfo.CreateNoWindow = true; + Pinfo.UseShellExecute = false; + using (Process p = new Process ()) { + p.EnableRaisingEvents = true; + p.StartInfo = Pinfo; + p.Start (); + p.WaitForExit (); + output.Error = p.StandardError.ReadToEnd (); + output.Message = p.StandardOutput.ReadToEnd (); + output.ExitCode = p.ExitCode; + p.Close (); + } + } + /// + /// Restore the specified fileName and dataOnly. + /// + /// File name. + /// If set to true data only. + public TaskOutput Restore (string fileName, bool dataOnly) + { + Environment.SetEnvironmentVariable("PGPASSWORD", da.Password); + var t = new TaskOutput (); + Exec ("pg_restore", (dataOnly?"-a ":"")+string.Format ( + "-1 -Ft -O -h {0} -U {1} -p {2} -d {3} {4}", + da.Host, da.DbUser, da.Port, da.DbName, fileName ),t); + /* + Exec ("pg_restore", (dataOnly?"-a ":"")+string.Format ( + "-1 -w -Fd -O -h {0} -U {1} -p {2} -d {3} {4}", + da.Host, da.Dbuser, da.Port, da.Dbname, fileName ),t); + */ + return t; + } + /// + /// Creates the db. + /// + /// The db. + public TaskOutput CreateDb () + { + TaskOutput res = new TaskOutput (); + + string sql; + try { + Assembly a = System.Reflection.Assembly.GetExecutingAssembly(); + using (Stream sqlStream = a.GetManifestResourceStream("Yavsc.instdbws.sql")) + { + try { using (StreamReader srdr = new StreamReader (sqlStream)) { + sql = srdr.ReadToEnd (); + using (var cnx = new Npgsql.NpgsqlConnection (da.ConnectionString)) { + using (var cmd = cnx.CreateCommand ()) { + cmd.CommandText = sql; + cnx.Open(); + cmd.ExecuteNonQuery(); + cnx.Close(); + } + } + } } catch (Exception exg) { + res.ExitCode = 1; + res.Error = + string.Format ("Exception of type {0} occred retrieving the script", + exg.GetType ().Name); + res.Message = exg.Message; + } + } + } + catch (Exception ex) { + res.ExitCode = 1; + res.Error = + string.Format ("Exception of type {0} occured during the script execution", + ex.GetType ().Name); + res.Message = ex.Message; + } + + return res; + } + /// + /// Tags the backup. + /// + /// The backup. + /// Filename. + /// Tags. + public Export TagBackup (string filename, string [] tags) + { + /* FileInfo fi = new FileInfo (filename); + using (FileStream s = fi.OpenWrite ()) { + + } */ + throw new NotImplementedException (); + } + /// + /// Tags the restore. + /// + /// The restore. + /// File name. + public TaskOutput TagRestore (string fileName) + { + Environment.SetEnvironmentVariable ("PGPASSWORD", da.Password); + var t = new TaskOutput (); + Exec ("pg_restore", string.Format ( + "-a -w -Fd -O -h {0} -U {1} -p {2} -d {3} {4}", + da.Host, da.DbUser, da.Port, da.DbName, fileName ),t); + return t; + } + } +} + diff --git a/booking/Admin/Export.cs b/booking/Admin/Export.cs new file mode 100644 index 00000000..e2120f43 --- /dev/null +++ b/booking/Admin/Export.cs @@ -0,0 +1,24 @@ +using System; +using System.ComponentModel; + +namespace Yavsc.Model.Admin +{ + /// + /// Export. + /// + public class Export: TaskOutput + { + /// + /// Initializes a new instance of the class. + /// + public Export () + { + } + /// + /// Gets or sets the name of the file. + /// + /// The name of the file. + public string FileName { get; set; } + } +} + diff --git a/booking/ApiControllers/AccountController.cs b/booking/ApiControllers/AccountController.cs new file mode 100644 index 00000000..397113b0 --- /dev/null +++ b/booking/ApiControllers/AccountController.cs @@ -0,0 +1,116 @@ +// +// AccountController.cs +// +// Author: +// Paul Schneider +// +// Copyright (c) 2015 GNU GPL +// +// 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.Web.Http; +using System.Net.Http; +using Yavsc.Model.RolesAndMembers; +using System.Web.Security; +using System.Web.Profile; +using Yavsc.Helpers; +using System.Collections.Specialized; + +namespace Yavsc.ApiControllers +{ + /// + /// Account controller. + /// + public class AccountController : YavscController + { + + /// + /// Register the specified model. + /// + /// Model. + [Authorize ()] + [ValidateAjaxAttribute] + public HttpResponseMessage Register ([FromBody] RegisterClientModel model) + { + + if (ModelState.IsValid) { + if (model.IsApprouved) + if (!Roles.IsUserInRole ("Admin")) + if (!Roles.IsUserInRole ("FrontOffice")) { + ModelState.AddModelError ("Register", + "Since you're not member of Admin or FrontOffice groups, " + + "you cannot ask for a pre-approuved registration"); + return DefaultResponse (); + } + MembershipCreateStatus mcs; + var user = Membership.CreateUser ( + model.UserName, + model.Password, + model.Email, + model.Question, + model.Answer, + model.IsApprouved, + out mcs); + switch (mcs) { + case MembershipCreateStatus.DuplicateEmail: + ModelState.AddModelError ("Email", "Cette adresse e-mail correspond " + + "à un compte utilisateur existant"); + break; + case MembershipCreateStatus.DuplicateUserName: + ModelState.AddModelError ("UserName", "Ce nom d'utilisateur est " + + "déjà enregistré"); + break; + case MembershipCreateStatus.Success: + if (!model.IsApprouved) + Url.SendActivationMessage (user); + ProfileBase prtu = ProfileBase.Create (model.UserName); + prtu.SetPropertyValue ("Name", model.Name); + prtu.SetPropertyValue ("Address", model.Address); + prtu.SetPropertyValue ("CityAndState", model.CityAndState); + prtu.SetPropertyValue ("Mobile", model.Mobile); + prtu.SetPropertyValue ("Phone", model.Phone); + prtu.SetPropertyValue ("ZipCode", model.ZipCode); + break; + default: + break; + } + } + return DefaultResponse (); + } + + /// + /// Resets the password. + /// + /// Model. + [ValidateAjax] + public void ResetPassword (LostPasswordModel model) + { + StringDictionary errors; + MembershipUser user; + YavscHelpers.ValidatePasswordReset (model, out errors, out user); + foreach (string key in errors.Keys) + ModelState.AddModelError (key, errors [key]); + if (user != null && ModelState.IsValid) + Url.SendActivationMessage (user); + } + + [ValidateAjax] + [Authorize(Roles="Admin")] + public void AddUserToRole(UserRole model) + { + Roles.AddUserToRole (model.UserName, model.Role); + } + + } +} diff --git a/booking/ApiControllers/AuthorizationDenied.cs b/booking/ApiControllers/AuthorizationDenied.cs new file mode 100644 index 00000000..2193e6aa --- /dev/null +++ b/booking/ApiControllers/AuthorizationDenied.cs @@ -0,0 +1,55 @@ +// +// AuthorizationDenied.cs +// +// Author: +// Paul Schneider +// +// Copyright (c) 2015 GNU GPL +// +// 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.Collections.Generic; +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Web.Http; +using System.Web.Profile; +using System.Web.Security; +using Yavsc.Formatters; +using Yavsc.Helpers; +using Yavsc.Model; +using Yavsc.Model.FrontOffice; +using Yavsc.Model.RolesAndMembers; +using Yavsc.Model.WorkFlow; +using System.IO; + +namespace Yavsc.ApiControllers +{ + + /// + /// Authorization denied. + /// + public class AuthorizationDenied : HttpRequestException { + + /// + /// Initializes a new instance of the Yavsc.ApiControllers.AuthorizationDenied class. + /// + /// Message. + public AuthorizationDenied(string msg) : base(msg) + { + } + } + +} diff --git a/booking/ApiControllers/BasketController.cs b/booking/ApiControllers/BasketController.cs new file mode 100644 index 00000000..b31cc91d --- /dev/null +++ b/booking/ApiControllers/BasketController.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Security; +using System.Web.Http; +using Yavsc.Model.WorkFlow; +using System.Collections.Specialized; +using Yavsc.Model.FrontOffice; + +namespace Yavsc.ApiControllers +{ + /// + /// Basket controller. + /// Maintains a collection of articles + /// qualified with name value pairs + /// + public class BasketController : ApiController + { + /// + /// The wfmgr. + /// + protected WorkFlowManager wfmgr = null; + + /// + /// Initialize the specified controllerContext. + /// + /// Controller context. + protected override void Initialize (System.Web.Http.Controllers.HttpControllerContext controllerContext) + { + base.Initialize (controllerContext); + wfmgr = new WorkFlowManager (); + } + + /// + /// Gets the current basket, creates a new one, if it doesn't exist. + /// + /// The current basket. + protected CommandSet CurrentBasket { + get { + CommandSet b = wfmgr.GetCommands (Membership.GetUser ().UserName); + if (b == null) b = new CommandSet (); + return b; + } + } + + /// + /// Create the specified basket item using specified command parameters. + /// + /// Command parameters. + [Authorize] + public long Create(NameValueCollection cmdParams) + { + // HttpContext.Current.Request.Files + Command cmd = new Command(cmdParams, HttpContext.Current.Request.Files); + CurrentBasket.Add (cmd); + return cmd.Id; + } + + /// + /// Read the specified basket item. + /// + /// Itemid. + [Authorize] + Command Read(long itemid){ + return CurrentBasket[itemid]; + } + + /// + /// Update the specified item parameter using the specified value. + /// + /// Item identifier. + /// Parameter name. + /// Value. + [Authorize] + public void UpdateParam(long itemid, string param, string value) + { + CurrentBasket [itemid].Parameters [param] = value; + } + + /// + /// Delete the specified item. + /// + /// Item identifier. + [Authorize] + public void Delete(long itemid) + { + CurrentBasket.Remove (itemid); + } + + } +} \ No newline at end of file diff --git a/booking/ApiControllers/BlogsController.cs b/booking/ApiControllers/BlogsController.cs new file mode 100644 index 00000000..82ad69f4 --- /dev/null +++ b/booking/ApiControllers/BlogsController.cs @@ -0,0 +1,256 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Security; +using System.Web.Http; +using Npgsql.Web.Blog; +using Yavsc.Model.Blogs; +using System.IO; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using System.Diagnostics; +using Yavsc.Formatters; +using Yavsc.Model; + +namespace Yavsc.ApiControllers +{ + /// + /// Blogs API controller. + /// + public class BlogsController : YavscController + { + /// + /// Tag the specified model. + /// + /// Model. + [Authorize, + AcceptVerbs ("POST")] + public void Tag (PostTag model) { + if (ModelState.IsValid) { + BlogManager.GetForEditing (model.PostId); + BlogManager.Tag (model.PostId, model.Tag); + } + } + static string [] officalTags = new string[] { "Artistes", "Accueil", "Événements", "Mentions légales", "Admin", "Web" } ; + /// + /// Tags the specified pattern. + /// + /// Pattern. + [ValidateAjaxAttribute] + public IEnumerable Tags(string pattern) + { + return officalTags; + } + + /// + /// Untag the specified model. + /// + /// Model. + [Authorize, + AcceptVerbs ("POST")] + public void Untag (PostTag model) { + if (ModelState.IsValid) { + BlogManager.GetForEditing (model.PostId); + BlogManager.Untag (model.PostId, model.Tag); + } + } + + /// + /// Removes the post. + /// + /// User. + /// Title. + [Authorize, ValidateAjaxAttribute, HttpPost] + public void RemoveTitle(string user, string title) { + if (Membership.GetUser ().UserName != user) + if (!Roles.IsUserInRole("Admin")) + throw new AuthorizationDenied (user); + BlogManager.RemoveTitle (user, title); + } + + /// + /// Removes the tag. + /// + /// Tagid. + [Authorize, ValidateAjaxAttribute, HttpPost] + public void RemoveTag([FromBody] long tagid) { + + throw new NotImplementedException (); + } + + /// + /// The allowed media types. + /// + protected string[] allowedMediaTypes = { + "text/plain", + "text/x-tex", + "text/html", + "image/png", + "image/gif", + "image/jpeg", + "image/x-xcf", + "application/pdf", + "application/vnd.openxmlformats-officedocument.wordprocessingml.document" + }; + + /// + /// Posts the file. + /// + /// The file. + [Authorize, HttpPost] + public async Task PostFile(long id) { + if (!(Request.Content.Headers.ContentType.MediaType=="multipart/form-data")) + throw new HttpRequestException ("not a multipart/form-data request"); + BlogEntry be = BlogManager.GetPost (id); + if (be.Author != Membership.GetUser ().UserName) + throw new AuthorizationDenied ("b"+id); + string root = HttpContext.Current.Server.MapPath("~/bfiles/"+id); + DirectoryInfo di = new DirectoryInfo (root); + if (!di.Exists) di.Create (); + + var provider = new MultipartFormDataStreamProvider(root); + try + { + // Read the form data. + await Request.Content.ReadAsMultipartAsync(provider) ; + var invalidChars = Path.GetInvalidFileNameChars(); + foreach (var f in provider.FileData) { + string filename = f.LocalFileName; + string orgname = f.Headers.ContentDisposition.FileName; + Trace.WriteLine(filename); + string nicename = HttpUtility.UrlDecode(orgname) ; + if (orgname.StartsWith("\"") && orgname.EndsWith("\"") && orgname.Length > 2) + nicename = orgname.Substring(1,orgname.Length-2); + nicename = new string (nicename.Where( x=> !invalidChars.Contains(x)).ToArray()); + nicename = nicename.Replace(' ','_'); + var dest = Path.Combine(root,nicename); + var fi = new FileInfo(dest); + if (fi.Exists) fi.Delete(); + File.Move(filename, fi.FullName); + } + + return Request.CreateResponse(HttpStatusCode.OK); + } + catch (System.Exception e) + { + return Request.CreateResponse(HttpStatusCode.InternalServerError, e); + } + } + + /// + /// Create the specified blog entry. + /// + /// Bp. + [Authorize, HttpPost] + public long Create (BasePost bp) + { + return BlogManager.Post (User.Identity.Name, bp.Title, "", bp.Visible, null); + } + + [Authorize, HttpPost] + public void Note (long id, int note) + { + if (note < 0 || note > 100) + throw new ArgumentException ("0<=note<=100"); + BlogManager.Note (id, note); + } + /// + /// Searchs the file. + /// + /// The file. + /// Postid. + /// Terms. + [HttpGet] + public async Task SearchFile(long id, string terms) { + throw new NotImplementedException (); + } + + /// + /// Sets the photo. + /// + /// Identifier. + /// Photo. + [Authorize, HttpPost, ValidateAjaxAttribute] + public void SetPhoto(long id, [FromBody] string photo) + { + BlogManager.Provider.UpdatePostPhoto (id, photo); + } + + /// + /// Import the specified id. + /// + /// Identifier. + [Authorize, HttpPost, ValidateAjaxAttribute] + public async Task Import(long id) { + if (!(Request.Content.Headers.ContentType.MediaType=="multipart/form-data")) + throw new HttpRequestException ("not a multipart/form-data request"); + BlogEntry be = BlogManager.GetPost (id); + if (be.Author != Membership.GetUser ().UserName) + throw new AuthorizationDenied ("post: "+id); + string root = HttpContext.Current.Server.MapPath("~/bfiles/"+id); + DirectoryInfo di = new DirectoryInfo (root); + if (!di.Exists) di.Create (); + var provider = new MultipartFormDataStreamProvider(root); + try + { + // Read the form data. + //IEnumerable data = + await Request.Content.ReadAsMultipartAsync(provider) ; + + var invalidChars = Path.GetInvalidFileNameChars(); + List bodies = new List(); + + foreach (var f in provider.FileData) { + string filename = f.LocalFileName; + + string nicename= f.Headers.ContentDisposition.FileName; + var filtered = new string (nicename.Where( x=> !invalidChars.Contains(x)).ToArray()); + + FileInfo fi = new FileInfo(filtered); + FileInfo fo = new FileInfo(filtered+".md"); + FileInfo fp = new FileInfo (Path.Combine(root,filename)); + if (fi.Exists) fi.Delete(); + fp.MoveTo(fi.FullName); + // TODO Get the mime type + using (Process p = new Process ()) { + p.StartInfo.WorkingDirectory = root; + p.StartInfo = new ProcessStartInfo (); + p.StartInfo.UseShellExecute = false; + p.StartInfo.FileName = "/usr/bin/pandoc"; + p.StartInfo.Arguments = + string.Format (" -o '{0}' -t markdown '{1}'", + fo.FullName, + fi.FullName); + p.StartInfo.RedirectStandardError = true; + p.StartInfo.RedirectStandardOutput = true; + p.Start (); + p.WaitForExit (); + if (p.ExitCode != 0) { + return Request.CreateResponse (HttpStatusCode.InternalServerError, + "# Import failed with exit code: " + p.ExitCode + "---\n" + + LocalizedText.ImportException + "---\n" + + p.StandardError.ReadToEnd() + "---\n" + + p.StandardOutput.ReadToEnd() + ); + } + } + bodies.Add(fo.OpenText().ReadToEnd()); + + + fi.Delete(); + fo.Delete(); + } + + return Request.CreateResponse(HttpStatusCode.OK,string.Join("\n---\n",bodies),new SimpleFormatter("text/plain")); + + } + catch (System.Exception e) + { + return Request.CreateResponse(HttpStatusCode.InternalServerError, e); + } + } + } +} + diff --git a/booking/ApiControllers/CalendarController.cs b/booking/ApiControllers/CalendarController.cs new file mode 100644 index 00000000..686c7730 --- /dev/null +++ b/booking/ApiControllers/CalendarController.cs @@ -0,0 +1,204 @@ +// +// CalendarController.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.Web.Http; +using Yavsc.Model.RolesAndMembers; +using System.Web.Security; +using Yavsc.Model.Google; +using Yavsc.Helpers; +using System.Web.Profile; +using Yavsc.Model.Circles; +using Yavsc.Model.Calendar; +using System.Web.Http.Routing; + + +namespace Yavsc.ApiControllers +{ + /// + /// Night flash controller. + /// + public class CalendarController: ApiController + { + YaEvent[] getTestList() + { + return new YaEvent[] { + new YaEvent () { + Description = "Test Descr", + Title = "Night club special bubble party", + Location = new Position () { + Longitude = 0, + Latitude = 0 + } + }, + new YaEvent () { + Title = "Test2", + Photo = "http://bla/im.png", + Location = new Position () { + Longitude = 0, + Latitude = 0 + } + }, + new YaEvent () { + Description = "Test Descr", + Title = "Night club special bubble party", + Location = new Position () { + Longitude = 0, + Latitude = 0 + } + }, + new YaEvent () { + Title = "Test2", + Photo = "http://bla/im.png", + Location = new Position () { + Longitude = 0, + Latitude = 0 + } + } + }; + } + + /// + /// List events according the specified search arguments. + /// + /// Arguments. + [ValidateAjaxAttribute] + [HttpGet] + public YaEvent[] List ([FromUri] PositionAndKeyphrase args) + { + return getTestList(); + } + + /// + /// Provider the specified ProviderId. + /// + /// Provider identifier. + [HttpGet] + public ProviderPublicInfo ProviderInfo ([FromUri] string ProviderId) + { + return new ProviderPublicInfo () { + DisplayName = "Yavsc clubing", + WebPage = "http://yavsc.pschneider.fr/", + Calendar = new Schedule () { + Period = Periodicity.ThreeM, + WeekDays = new OpenDay[] { new OpenDay () { Day = WeekDay.Saturday, + Start = new TimeSpan(18,00,00), + End = new TimeSpan(2,00,00) + } }, + Validity = new Period[] { new Period() { + Start = new DateTime(2015,5,29), + End = new DateTime(2015,5,30)} } + }, + Description = "Yavsc Entertainment Production, Yet another private party", + LogoImgLocator = "http://yavsc.pschneider.fr/favicon.png", + Location = new Position () { Longitude = 0, Latitude = 0 }, + LocationType = "Salle des fêtes" + }; + } + + /// + /// Posts the image. + /// + /// The image. + /// NF prov identifier. + public string PostImage([FromUri] string NFProvId) + { + return null; + } + + /// + /// Posts the event. + /// + /// The event identifier. + /// Ev. + public int PostEvent ([FromBody] ProvidedEvent ev) + { + throw new NotImplementedException(); + + } + + /// + /// Registers with push notifications enabled. + /// + /// Model. + [ValidateAjax] + public void RegisterWithPushNotifications(GCMRegisterModel model) + { + if (ModelState.IsValid) { + MembershipCreateStatus mcs; + var user = Membership.CreateUser ( + model.UserName, + model.Password, + model.Email, + null, + null, + false, + out mcs); + switch (mcs) { + case MembershipCreateStatus.DuplicateEmail: + ModelState.AddModelError ("Email", "Cette adresse e-mail correspond " + + "à un compte utilisateur existant"); + break; + case MembershipCreateStatus.DuplicateUserName: + ModelState.AddModelError ("Author", "Ce nom d'utilisateur est " + + "déjà enregistré"); + break; + case MembershipCreateStatus.Success: + Url.SendActivationMessage (user); + // TODO set registration id + throw new NotImplementedException (); + } + } + } + + /// + /// Sets the registration identifier. + /// + /// Registration identifier. + [Authorize] + public void SetRegistrationId(string registrationId) + { + // TODO set registration id + setRegistrationId (Membership.GetUser ().UserName, registrationId); + } + + private void setRegistrationId(string username, string regid) { + ProfileBase pr = ProfileBase.Create(username); + pr.SetPropertyValue ("gregid", regid); + } + + /// + /// Notifies the event. + /// + /// Evpub. + public MessageWithPayloadResponse NotifyEvent(EventPub evpub) { + SimpleJsonPostMethod,MessageWithPayloadResponse> r = + new SimpleJsonPostMethod,MessageWithPayloadResponse>( + "https://gcm-http.googleapis.com/gcm/send"); + using (r) { + var msg = new MessageWithPayload () { data = new YaEvent[] { (YaEvent)evpub } }; + msg.to = string.Join (" ", Circle.Union (evpub.Circles)); + return r.Invoke (msg); + } + } + } +} + + diff --git a/booking/ApiControllers/CircleController.cs b/booking/ApiControllers/CircleController.cs new file mode 100644 index 00000000..da7f7092 --- /dev/null +++ b/booking/ApiControllers/CircleController.cs @@ -0,0 +1,138 @@ +// +// CircleController.cs +// +// Author: +// Paul Schneider +// +// Copyright (c) 2015 GNU GPL +// +// 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.Web.Http; +using Yavsc.Model.RolesAndMembers; +using System.Collections.Generic; +using Yavsc.Model.Circles; +using System.Web.Security; +using System.Collections.Specialized; +using Yavsc.Model; + +namespace Yavsc.ApiControllers +{ + + /// + /// Circle controller. + /// + public class CircleController : ApiController + { + + /// + /// Create the specified circle. + /// + /// Model. + [Authorize, + AcceptVerbs ("POST")] + public long Create(Circle model) + { + string user = Membership.GetUser ().UserName; + return CircleManager.DefaultProvider.Create (user, model.Title, model.Members); + } + + /// + /// Add the specified users to the circle. + /// + /// Circle Identifier. + /// username. + [Authorize, + AcceptVerbs ("POST")] + public void Add(long id, string username) + { + checkIsOwner (CircleManager.DefaultProvider.Get (id)); + CircleManager.DefaultProvider.AddMember (id, username); + } + + + /// + /// Delete the circle specified by id. + /// + /// Identifier. + [Authorize, + AcceptVerbs ("GET")] + public void Delete(long id) + { + checkIsOwner (CircleManager.DefaultProvider.Get (id)); + CircleManager.DefaultProvider.Delete (id); + } + + + /// + /// Removes the user from circle. + /// + /// Identifier. + /// Username. + [Authorize, + AcceptVerbs ("GET")] + public void RemoveUserFromCircle(long id, string username) + { + checkIsOwner (CircleManager.DefaultProvider.Get(id)); + CircleManager.DefaultProvider.RemoveMembership (id,username); + } + + private void checkIsOwner(CircleBase c) + { + string user = Membership.GetUser ().UserName; + if (c.Owner != user) + throw new AccessViolationException ("You're not owner of this circle"); + } + + /// + /// Get the circle specified id. + /// + /// Identifier. + [Authorize, + AcceptVerbs ("GET")] + public Circle Get(long id) + { + var c = CircleManager.DefaultProvider.GetMembers (id); + checkIsOwner (c); + return c; + } + + /// + /// List the circles + /// + [Authorize, + AcceptVerbs ("GET")] + public IEnumerable List() + { + string user = Membership.GetUser ().UserName; + return CircleManager.DefaultProvider.List (user); + } + + /// + /// List the circles + /// + [Authorize, + AcceptVerbs ("POST")] + public void Update(CircleBase circle) + { + string user = Membership.GetUser ().UserName; + CircleBase current = CircleManager.DefaultProvider.Get (circle.Id); + if (current.Owner != user) + throw new AuthorizationDenied ("Your not owner of circle at id "+circle.Id); + CircleManager.DefaultProvider.UpdateCircle (circle); + } + + } +} + diff --git a/booking/ApiControllers/FrontOfficeController.cs b/booking/ApiControllers/FrontOfficeController.cs new file mode 100644 index 00000000..a2079981 --- /dev/null +++ b/booking/ApiControllers/FrontOfficeController.cs @@ -0,0 +1,195 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Web.Http; +using System.Web.Profile; +using System.Web.Security; +using Yavsc.Formatters; +using Yavsc.Helpers; +using Yavsc.Model; +using Yavsc.Model.FrontOffice; +using Yavsc.Model.RolesAndMembers; +using Yavsc.Model.WorkFlow; +using System.IO; +using Yavsc.Model.FrontOffice.Catalog; + +namespace Yavsc.ApiControllers +{ + + + /// + /// Front office controller. + /// + public class FrontOfficeController : ApiController + { + /// + /// The wfmgr. + /// + protected WorkFlowManager wfmgr = null; + + /// + /// Initialize the specified controllerContext. + /// + /// Controller context. + protected override void Initialize (System.Web.Http.Controllers.HttpControllerContext controllerContext) + { + base.Initialize (controllerContext); + wfmgr = new WorkFlowManager (); + } + + /// + /// Catalog this instance. + /// + [AcceptVerbs ("GET")] + public Catalog Catalog () + { + Catalog c = CatalogManager.GetCatalog (); + return c; + } + + /// + /// Gets the product categorie. + /// + /// The product categorie. + /// Brand name. + /// Prod categorie. + [AcceptVerbs ("GET")] + public ProductCategory GetProductCategorie (string brandName, string prodCategorie) + { + return CatalogManager.GetCatalog ().GetBrand (brandName).GetProductCategory (prodCategorie); + } + + + /// + /// Gets the estimate. + /// + /// The estimate. + /// Estimate Id. + [Authorize] + [HttpGet] + public Estimate GetEstimate (long id) + { + Estimate est = wfmgr.ContentProvider.Get (id); + string username = Membership.GetUser ().UserName; + if (est.Client != username) + if (!Roles.IsUserInRole("Admin")) + if (!Roles.IsUserInRole("FrontOffice")) + throw new AuthorizationDenied ( + string.Format ( + "Auth denied to eid {1} for:{2}", + id, username)); + return est; + } + + /// + /// Gets the estim tex. + /// + /// The estim tex. + /// Estimate id. + [AcceptVerbs ("GET")] + public HttpResponseMessage EstimateToTex (long id) + { + string texest = estimateToTex (id); + if (texest == null) + throw new InvalidOperationException ( + "Not an estimate"); + HttpResponseMessage result = new HttpResponseMessage () { + Content = new ObjectContent (typeof(string), + texest, + new SimpleFormatter ("text/x-tex")) + }; + result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue ("attachment") { + FileName = "estimate-" + id.ToString () + ".tex" + }; + return result; + } + + private string estimateToTex (long estimid) + { + Yavsc.templates.Estim tmpe = new Yavsc.templates.Estim (); + Estimate e = wfmgr.GetEstimate (estimid); + tmpe.Session = new Dictionary (); + tmpe.Session.Add ("estim", e); + Profile prpro = new Profile (ProfileBase.Create (e.Responsible)); + if (!prpro.HasBankAccount) + throw new TemplateException ("NotBankable:" + e.Responsible); + if (!prpro.HasPostalAddress) + throw new TemplateException ("NoPostalAddress:" + e.Responsible); + + Profile prcli = new Profile (ProfileBase.Create (e.Client)); + if (!prcli.IsBillable) + throw new TemplateException ("NotBillable:" + e.Client); + + + tmpe.Session.Add ("from", prpro); + tmpe.Session.Add ("to", prcli); + tmpe.Session.Add ("efrom", Membership.GetUser (e.Responsible).Email); + tmpe.Session.Add ("eto", Membership.GetUser (e.Client).Email); + tmpe.Init (); + return tmpe.TransformText (); + } + + /// + /// Gets the estimate in pdf format from tex generation. + /// + /// The to pdf. + /// Estimid. + [AcceptVerbs("GET")] + public HttpResponseMessage EstimateToPdf (long id) + { + string texest = null; + try { + texest = estimateToTex (id); + } catch (TemplateException ex) { + return new HttpResponseMessage (HttpStatusCode.OK) { Content = + new ObjectContent (typeof(string), + ex.Message, new ErrorHtmlFormatter (HttpStatusCode.NotAcceptable, + LocalizedText.DocTemplateException + )) + }; + } catch (Exception ex) { + return new HttpResponseMessage (HttpStatusCode.OK) { Content = + new ObjectContent (typeof(string), + ex.Message, new ErrorHtmlFormatter (HttpStatusCode.InternalServerError, + LocalizedText.DocTemplateException)) + }; + } + if (texest == null) + return new HttpResponseMessage (HttpStatusCode.OK) { Content = + new ObjectContent (typeof(string), "Not an estimation id:" + id, + new ErrorHtmlFormatter (HttpStatusCode.NotFound, + LocalizedText.Estimate_not_found)) + }; + + var memPdf = new MemoryStream (); + try { + new TexToPdfFormatter ().WriteToStream ( + typeof(string), texest, memPdf,null); + } + catch (FormatterException ex) { + return new HttpResponseMessage (HttpStatusCode.OK) { Content = + new ObjectContent (typeof(string), ex.Message+"\n\n"+ex.Output+"\n\n"+ex.Error, + new ErrorHtmlFormatter (HttpStatusCode.InternalServerError, + LocalizedText.InternalServerError)) + }; + } + + var result = new HttpResponseMessage(HttpStatusCode.OK) + { + Content = new ByteArrayContent(memPdf.GetBuffer()) + }; + + result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue ("attachment") { + FileName = String.Format ( + "Estimation-{0}.pdf", + id) + }; + + return result; + } + + } +} + diff --git a/booking/ApiControllers/GCMController.cs b/booking/ApiControllers/GCMController.cs new file mode 100644 index 00000000..69e992b8 --- /dev/null +++ b/booking/ApiControllers/GCMController.cs @@ -0,0 +1,33 @@ +// +// GCMController.cs +// +// Author: +// Paul Schneider +// +// Copyright (c) 2015 GNU GPL +// +// 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.Web.Http; + +namespace Yavsc.ApiControllers +{ + public class GCMController : ApiController + { + public GCMController () + { + } + } +} + diff --git a/booking/ApiControllers/PaypalController.cs b/booking/ApiControllers/PaypalController.cs new file mode 100644 index 00000000..be5953c7 --- /dev/null +++ b/booking/ApiControllers/PaypalController.cs @@ -0,0 +1,77 @@ +// +// PaypalApiController.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.Web.Http; + + +using PayPal; +using System.Collections.Generic; +using PayPal.OpenIdConnect; +using PayPal.Manager; +using PayPal.PayPalAPIInterfaceService; +using PayPal.PayPalAPIInterfaceService.Model; + +namespace Yavsc.ApiControllers +{ + /// + /// Paypal API controller. + /// + public class PaypalController: ApiController + { + PayPalAPIInterfaceServiceService service = null; + /// + /// Initialize the specified controllerContext. + /// + /// Controller context. + protected override void Initialize (System.Web.Http.Controllers.HttpControllerContext controllerContext) + { + base.Initialize (controllerContext); + // Get the config properties from PayPal.Api.ConfigManager + // Create the Classic SDK service instance to use. + service = new PayPalAPIInterfaceServiceService(ConfigManager.Instance.GetProperties()); + } + /// + /// Search the specified str. + /// + /// str. + public BMCreateButtonResponseType Create(string str) + { + BMCreateButtonRequestType btcrerqu = new BMCreateButtonRequestType (); + BMCreateButtonReq btcrerq = new BMCreateButtonReq (); + btcrerq.BMCreateButtonRequest = btcrerqu; + BMCreateButtonResponseType btcrere = service.BMCreateButton (btcrerq); + return btcrere; + } + /// + /// Search the specified str. + /// + /// String. + public BMButtonSearchResponseType Search(string str) + { + BMButtonSearchReq req = new BMButtonSearchReq (); + req.BMButtonSearchRequest = new BMButtonSearchRequestType (); + + return service.BMButtonSearch (req); + } + } + +} + diff --git a/booking/ApiControllers/WorkFlowController.cs b/booking/ApiControllers/WorkFlowController.cs new file mode 100644 index 00000000..ca0cf435 --- /dev/null +++ b/booking/ApiControllers/WorkFlowController.cs @@ -0,0 +1,182 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Web; +using System.Web.Security; +using Yavsc; +using Yavsc.Model.WorkFlow; +using System.Web.Http; +using Yavsc.Model.RolesAndMembers; +using Yavsc.Helpers; +using Yavsc.Model; +using System.Web.Http.Controllers; + +namespace Yavsc.ApiControllers +{ + /// + /// Work flow controller. + /// + public class WorkFlowController : ApiController + { + string adminRoleName="Admin"; + /// + /// The wfmgr. + /// + protected WorkFlowManager wfmgr = null; + /// + /// Initialize the specified controllerContext. + /// + /// Controller context. + protected override void Initialize (HttpControllerContext controllerContext) + { + // TODO move it in a module initialization + base.Initialize (controllerContext); + if (!Roles.RoleExists (adminRoleName)) { + Roles.CreateRole (adminRoleName); + } + wfmgr = new WorkFlowManager (); + } + + /// + /// Creates the estimate. + /// + /// The estimate. + /// Title. + /// Client. + /// Description. + [HttpGet] + [Authorize] + public Estimate CreateEstimate (string title,string client,string description) + { + return wfmgr.CreateEstimate ( + Membership.GetUser().UserName,client,title,description); + } + + + + /// + /// Register the specified userModel. + /// + /// User model. + [HttpGet] + [ValidateAjax] + [Authorize(Roles="Admin,FrontOffice")] + public void Register([FromBody] RegisterModel userModel) + { + if (ModelState.IsValid) { + MembershipCreateStatus mcs; + var user = Membership.CreateUser ( + userModel.UserName, + userModel.Password, + userModel.Email, + null, + null, + userModel.IsApprouved, + out mcs); + switch (mcs) { + case MembershipCreateStatus.DuplicateEmail: + ModelState.AddModelError ("Email", + string.Format(LocalizedText.DuplicateEmail,userModel.UserName) ); + return ; + case MembershipCreateStatus.DuplicateUserName: + ModelState.AddModelError ("Author", + string.Format(LocalizedText.DuplicateUserName,userModel.Email)); + return ; + case MembershipCreateStatus.Success: + if (!userModel.IsApprouved) + + Url.SendActivationMessage (user); + return; + default: + throw new InvalidOperationException (string.Format("Unexpected user creation code :{0}",mcs)); + } + } + } + + /// + /// Drops the writting. + /// + /// Wrid. + [HttpGet] + [Authorize] + public void DropWritting(long wrid) + { + wfmgr.DropWritting (wrid); + } + + /// + /// Drops the estimate. + /// + /// Estid. + [HttpGet] + [Authorize] + public void DropEstimate(long estid) + { + string username = Membership.GetUser().UserName; + Estimate e = wfmgr.GetEstimate (estid); + if (e == null) + throw new InvalidOperationException("not an estimate id:"+estid); + if (username != e.Responsible + && !Roles.IsUserInRole ("FrontOffice")) + throw new UnauthorizedAccessException ("You're not allowed to drop this estimate"); + + wfmgr.DropEstimate (estid); + } + + /// + /// Index this instance. + /// + [HttpGet] + [Authorize] + public object Index() + { + // TODO inform user on its roles and alerts + string username = Membership.GetUser ().UserName; + return new { test=string.Format("Hello {0}!",username) }; + } + + /// + /// Updates the writting. + /// + /// The writting. + /// Wr. + [Authorize] + [AcceptVerbs("POST")] + [ValidateAjax] + public HttpResponseMessage UpdateWritting([FromBody] Writting wr) + { + wfmgr.UpdateWritting (wr); + return Request.CreateResponse (System.Net.HttpStatusCode.OK,"WrittingUpdated:"+wr.Id); + } + + /// + /// Adds the specified imputation to the given estimation by estimation id. + /// + /// Estimation identifier + /// Imputation to add + [AcceptVerbs("POST")] + [Authorize] + [ValidateAjax] + public HttpResponseMessage Write ([FromUri] long estid, [FromBody] Writting wr) { + if (estid <= 0) { + ModelState.AddModelError ("EstimationId", "Spécifier un identifiant d'estimation valide"); + return Request.CreateResponse (System.Net.HttpStatusCode.BadRequest, + ValidateAjaxAttribute.GetErrorModelObject (ModelState)); + } + try { + return Request.CreateResponse(System.Net.HttpStatusCode.OK, + wfmgr.Write(estid, wr.Description, + wr.UnitaryCost, wr.Count, wr.ProductReference)); + } + catch (Exception ex) { + return Request.CreateResponse ( + System.Net.HttpStatusCode.InternalServerError, + "Internal server error:" + ex.Message + "\n" + ex.StackTrace); + + } + } + } + + +} diff --git a/booking/ApiControllers/YavscController.cs b/booking/ApiControllers/YavscController.cs new file mode 100644 index 00000000..76b9b471 --- /dev/null +++ b/booking/ApiControllers/YavscController.cs @@ -0,0 +1,71 @@ +// +// YavscApiController.cs +// +// Author: +// Paul Schneider +// +// Copyright (c) 2015 GNU GPL +// +// 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.Web.Http; +using System.Net.Http; +using System.Web.Profile; + +namespace Yavsc.ApiControllers +{ + /// + /// Yavsc controller. + /// + public class YavscController : ApiController + { + /// + /// Initializes a new instance of the class. + /// + public YavscController () + { + } + /// + /// Auth. + /// + public class Auth { + public string Id { get; set; } + } + /// + /// Allows the cookies. + /// + /// Model. + public void AllowCookies (Auth model) + { + // TODO check Auth when existing + if (model.Id != null) { + ProfileBase pr = ProfileBase.Create (model.Id); + pr.SetPropertyValue ("allowcookies", true); + pr.Save (); + } + } + /// + /// Defaults the response. + /// + /// The response. + protected HttpResponseMessage DefaultResponse() + { + return ModelState.IsValid ? + Request.CreateResponse (System.Net.HttpStatusCode.OK) : + Request.CreateResponse (System.Net.HttpStatusCode.BadRequest, + ValidateAjaxAttribute.GetErrorModelObject (ModelState)); + } + } +} + diff --git a/booking/CatExts/WebCatalogExtensions.cs b/booking/CatExts/WebCatalogExtensions.cs new file mode 100644 index 00000000..24f0b583 --- /dev/null +++ b/booking/CatExts/WebCatalogExtensions.cs @@ -0,0 +1,94 @@ +using System; +using System.Web; +using System.Text; +using System.Web.Mvc; +using System.Web.Routing; +using Yavsc.Model.FrontOffice; +using System.Web.Mvc.Html; +using Yavsc.Model.FrontOffice.Catalog; + +namespace Yavsc.CatExts +{ + /// + /// Web catalog extensions. + /// + public static class WebCatalogExtensions + { + /// + /// Commands the form. + /// + /// The form. + /// Helper. + /// Position. + /// Atc. + public static string CommandForm(this HtmlHelper helper, Product pos,string atc="Add to backet") { + StringBuilder sb = new StringBuilder (); + sb.Append (helper.ValidationSummary ()); + TagBuilder ft = new TagBuilder ("form"); + ft.Attributes.Add("action","/FrontOffice/Command"); + ft.Attributes.Add("method","post"); + ft.Attributes.Add("enctype","multipart/form-data"); + TagBuilder fieldset = new TagBuilder ("fieldset"); + + TagBuilder legend = new TagBuilder ("legend"); + legend.SetInnerText (pos.Name); + TagBuilder para = new TagBuilder ("p"); + + StringBuilder sbfc = new StringBuilder (); + if (pos.CommandForm != null) + foreach (FormElement e in pos.CommandForm.Items) { + sbfc.Append (e.ToHtml ()); + sbfc.Append ("
\n"); + } + sbfc.Append ( + string.Format( + "
\n", + atc + )); + + sbfc.Append (helper.Hidden ("ref", pos.Reference)); + para.InnerHtml = sbfc.ToString (); + fieldset.InnerHtml = legend.ToString ()+"\n"+para.ToString (); + ft.InnerHtml = fieldset.ToString (); + sb.Append (ft.ToString ()); + return sb.ToString (); + } + /// + /// Commands the form. + /// + /// The form. + /// Helper. + /// Position. + /// Atc. + public static string CommandForm(this HtmlHelper helper, Product pos,string atc="Add to backet") { + StringBuilder sb = new StringBuilder (); + sb.Append (helper.ValidationSummary ()); + TagBuilder ft = new TagBuilder ("form"); + ft.Attributes.Add("action","/FrontOffice/Command"); + ft.Attributes.Add("method","post"); + ft.Attributes.Add("enctype","multipart/form-data"); + TagBuilder fieldset = new TagBuilder ("fieldset"); + + TagBuilder legend = new TagBuilder ("legend"); + legend.SetInnerText (pos.Name); + TagBuilder para = new TagBuilder ("p"); + + StringBuilder sbfc = new StringBuilder (); + if (pos.CommandForm != null) + foreach (FormElement e in pos.CommandForm.Items) { + sbfc.Append (e.ToHtml ()); + sbfc.Append ("
\n"); + } + sbfc.Append ( + string.Format( + "
\n",atc)); + sbfc.Append (helper.Hidden ("ref", pos.Reference)); + para.InnerHtml = sbfc.ToString (); + fieldset.InnerHtml = legend.ToString ()+"\n"+para.ToString (); + ft.InnerHtml = fieldset.ToString (); + sb.Append (ft.ToString ()); + return sb.ToString (); + } + } +} + diff --git a/booking/Catalog.xml b/booking/Catalog.xml new file mode 100644 index 00000000..80fd456d --- /dev/null +++ b/booking/Catalog.xml @@ -0,0 +1,86 @@ + + + + + psc + Votre logiciel, efficace, sûr, et sur mesure + + /App_Themes/images/logoDev.png + + + + + + Conseil, conception logicielle + ccl + + + Aide au choix technologiques + tout un art + conseil + + + Conceptualisation de projet + Consolidation d'un niveau logique de projet, spécifications détaillées + concept + + + + + Développement et maintenance + ntic + + + Développement + Votre appli développée en cycles courts + dev + + + Maintenance + Correction des anomalies, réalisation des évolutions, prévision des besoins + main + + + + + + /Commande + + + Entrez un commentaire : + + + comment + Commentaire + + + Choisissez le type d'intervention souhaité: + + + ad + + + + + 0 + + + testarray[] + xxxxxxxxxx + + + testarray[] + + + + + + + + \ No newline at end of file diff --git a/booking/ChangeLog b/booking/ChangeLog new file mode 100644 index 00000000..aeb736a6 --- /dev/null +++ b/booking/ChangeLog @@ -0,0 +1,4 @@ +2015-11-08 Paul Schneider + + * booking.csproj: Removes the system.Core reference + diff --git a/booking/Controllers/AccountController.cs b/booking/Controllers/AccountController.cs new file mode 100644 index 00000000..53ed2338 --- /dev/null +++ b/booking/Controllers/AccountController.cs @@ -0,0 +1,419 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Mail; +using System.Web; +using System.Web.Configuration; +using System.Web.Profile; +using System.Web.Security; +using Yavsc; +using Yavsc.Model.RolesAndMembers; +using Yavsc.Helpers; +using System.Web.Mvc; +using Yavsc.Model.Circles; +using System.Collections.Specialized; +using System.Text; +using System.Net; +using System.Configuration; +using Yavsc.Model; + +namespace Yavsc.Controllers +{ + /// + /// Account controller. + /// + public class AccountController : Controller + { + /// + /// Avatar the specified user. + /// + /// User. + [AcceptVerbs (HttpVerbs.Get)] + public ActionResult Avatar (string id) + { + string avatarLocation = Url.AvatarUrl (id); + WebRequest wr = WebRequest.Create (avatarLocation); + FileContentResult res; + using (WebResponse resp = wr.GetResponse ()) { + using (Stream str = resp.GetResponseStream ()) { + byte[] content = new byte[str.Length]; + str.Read (content, 0, (int)str.Length); + res = File (content, resp.ContentType); + wr.Abort (); + return res; + } + } + } + + + /// + /// Index this instance. + /// + public ActionResult Index () + { + return View (); + } + + // TODO [ValidateAntiForgeryToken] + /// + /// Does login. + /// + /// The login. + /// Model. + /// Return URL. + [HttpPost,ValidateAntiForgeryToken] + public ActionResult Login (LoginModel model, string returnUrl) + { + if (ModelState.IsValid) { + if (Membership.ValidateUser (model.UserName, model.Password)) { + FormsAuthentication.SetAuthCookie (model.UserName, model.RememberMe); + if (returnUrl != null) + return Redirect (returnUrl); + else + return View ("Index"); + } else { + ModelState.AddModelError ("UserName", "The user name or password provided is incorrect."); + } + } + ViewData ["returnUrl"] = returnUrl; + return View (model); + } + + + /// + /// Login the specified returnUrl. + /// + /// Return URL. + [HttpGet] + public ActionResult Login (string returnUrl) + { + ViewData ["returnUrl"] = returnUrl; + return View (); + } + + /// + /// Gets the registration form. + /// + /// The register. + /// Model. + /// Return URL. + public ActionResult GetRegister(RegisterViewModel model, string returnUrl) + { + ViewData ["returnUrl"] = returnUrl; + return View ("Register",model); + } + + /// + /// Register the specified model and returnUrl. + /// + /// Model. + /// Return URL. + [HttpPost] + public ActionResult Register (RegisterViewModel model, string returnUrl) + { + ViewData ["returnUrl"] = returnUrl; + + if (ModelState.IsValid) { + if (model.ConfirmPassword != model.Password) { + ModelState.AddModelError ("ConfirmPassword", "Veuillez confirmer votre mot de passe"); + return View (model); + } + + MembershipCreateStatus mcs; + var user = Membership.CreateUser ( + model.UserName, + model.Password, + model.Email, + null, + null, + false, + out mcs); + switch (mcs) { + case MembershipCreateStatus.DuplicateEmail: + ModelState.AddModelError ("Email", "Cette adresse e-mail correspond " + + "à un compte utilisateur existant"); + return View (model); + case MembershipCreateStatus.DuplicateUserName: + ModelState.AddModelError ("UserName", "Ce nom d'utilisateur est " + + "déjà enregistré"); + return View (model); + case MembershipCreateStatus.Success: + Url.SendActivationMessage (user); + ViewData ["username"] = user.UserName; + ViewData ["email"] = user.Email; + return View ("RegistrationPending"); + default: + ViewData ["Error"] = "Une erreur inattendue s'est produite" + + "a l'enregistrement de votre compte utilisateur" + + string.Format ("({0}).", mcs.ToString ()) + + "Veuillez pardonner la gêne" + + "occasionnée"; + return View (model); + } + + } + return View (model); + } + + /// + /// Changes the password success. + /// + /// The password success. + public ActionResult ChangePasswordSuccess () + { + return View (); + } + + + /// + /// Changes the password. + /// + /// The password. + [HttpGet] + [Authorize] + public ActionResult ChangePassword () + { + return View (); + } + + /// + /// Unregister the specified id and confirmed. + /// + /// Identifier. + /// If set to true confirmed. + [Authorize] + public ActionResult Unregister (string id, bool confirmed = false) + { + ViewData ["UserName"] = id; + if (!confirmed) + return View (); + string logged = this.User.Identity.Name; + if (logged != id) + if (!Roles.IsUserInRole ("Admin")) + throw new Exception ("Unregister another user"); + + Membership.DeleteUser ( + Membership.GetUser ().UserName); + return RedirectToAction ("Index", "Home"); + } + + + /// + /// Changes the password. + /// + /// The password. + /// Model. + [Authorize] + [HttpPost] + public ActionResult ChangePassword (ChangePasswordModel model) + { + if (ModelState.IsValid) { + + // ChangePassword will throw an exception rather + // than return false in certain failure scenarios. + bool changePasswordSucceeded = false; + try { + MembershipUserCollection users = + Membership.FindUsersByName (model.Username); + if (users.Count > 0) { + MembershipUser user = Membership.GetUser (model.Username, true); + + changePasswordSucceeded = user.ChangePassword (model.OldPassword, model.NewPassword); + } else { + changePasswordSucceeded = false; + ModelState.AddModelError ("Username", "The user name not found."); + } + } catch (Exception ex) { + ViewData ["Error"] = ex.ToString (); + } + + if (changePasswordSucceeded) { + return RedirectToAction ("ChangePasswordSuccess"); + } else { + ModelState.AddModelError ("Password", "The current password is incorrect or the new password is invalid."); + } + } + + // If we got this far, something failed, redisplay form + return View (model); + } + + + /// + /// Profile the specified id. + /// + /// Identifier. + [Authorize] + [HttpGet] + public ActionResult Profile (string id) + { + if (id == null) + id = Membership.GetUser ().UserName; + ViewData ["UserName"] = id; + ProfileEdition model = new ProfileEdition (ProfileBase.Create (id)); + model.RememberMe = FormsAuthentication.GetAuthCookie (id, true) == null; + return View (model); + } + + + + /// + /// Profile the specified id, model and AvatarFile. + /// + /// Identifier. + /// Model. + /// Avatar file. + [Authorize] + [HttpPost] + public ActionResult Profile (string id, ProfileEdition model, HttpPostedFileBase AvatarFile) + { + string logdu = User.Identity.Name; + if (string.IsNullOrWhiteSpace (id)) { + if (string.IsNullOrWhiteSpace (model.UserName)) { + model.UserName = logdu; + return View (model); + } else { + id = logdu; + } + } + ViewData ["UserName"] = id; + bool editsTheUserName = model.NewUserName!=null&&(string.Compare(id,model.NewUserName)!=0); + // Checks authorisation + if (logdu!=id) + if (!Roles.IsUserInRole ("Admin")) + if (!Roles.IsUserInRole ("FrontOffice")) + throw new UnauthorizedAccessException ("Your are not authorized to modify this profile"); + // checks availability of a new username + if (editsTheUserName) + if (!UserManager.IsAvailable (model.NewUserName)) + ModelState.AddModelError ("UserName", + string.Format ( + LocalizedText.DuplicateUserName, + model.NewUserName + )); + if (AvatarFile != null) { + // if said valid, move as avatar file + // else invalidate the model + if (AvatarFile.ContentType == "image/png") { + string avdir = Server.MapPath (YavscHelpers.AvatarDir); + var di = new DirectoryInfo (avdir); + if (!di.Exists) + di.Create (); + string avpath = Path.Combine (avdir, id + ".png"); + AvatarFile.SaveAs (avpath); + model.avatar = Url.Content( YavscHelpers.AvatarDir + "/" + id + ".png"); + } else + ModelState.AddModelError ("Avatar", + string.Format ("Image type {0} is not supported (suported formats : {1})", + AvatarFile.ContentType, "image/png")); + } + if (ModelState.IsValid) { + ProfileBase prf = ProfileBase .Create (id); + prf.SetPropertyValue ("Name", model.Name); + prf.SetPropertyValue ("BlogVisible", model.BlogVisible); + prf.SetPropertyValue ("BlogTitle", model.BlogTitle); + if (AvatarFile != null) { + prf.SetPropertyValue ("Avatar", model.avatar); + } else { + var av = prf.GetPropertyValue ("Avatar"); + if (av != null) + model.avatar = av as string; + } + prf.SetPropertyValue ("Address", model.Address); + prf.SetPropertyValue ("CityAndState", model.CityAndState); + prf.SetPropertyValue ("Country", model.Country); + prf.SetPropertyValue ("ZipCode", model.ZipCode); + prf.SetPropertyValue ("WebSite", model.WebSite); + prf.SetPropertyValue ("Name", model.Name); + prf.SetPropertyValue ("Phone", model.Phone); + prf.SetPropertyValue ("Mobile", model.Mobile); + prf.SetPropertyValue ("BankCode", model.BankCode); + prf.SetPropertyValue ("IBAN", model.IBAN); + prf.SetPropertyValue ("BIC", model.BIC); + prf.SetPropertyValue ("WicketCode", model.WicketCode); + prf.SetPropertyValue ("AccountNumber", model.AccountNumber); + prf.SetPropertyValue ("BankedKey", model.BankedKey); + prf.SetPropertyValue ("gcalid", model.GoogleCalendar); + prf.Save (); + + if (editsTheUserName) { + UserManager.ChangeName (id, model.NewUserName); + FormsAuthentication.SetAuthCookie (model.NewUserName, model.RememberMe); + model.UserName = model.NewUserName; + } + YavscHelpers.Notify(ViewData, "Profile enregistré"+((editsTheUserName)?", nom public inclu.":"")); + } + return View (model); + } + /// + /// Circles this instance. + /// + [Authorize] + public ActionResult Circles () + { + string user = Membership.GetUser ().UserName; + ViewData["Circles"] = CircleManager.DefaultProvider.List (user); + return View (); + } + + /// + /// Logout the specified returnUrl. + /// + /// Return URL. + [Authorize] + public ActionResult Logout (string returnUrl) + { + FormsAuthentication.SignOut (); + return Redirect (returnUrl); + } + + /// + /// Losts the password. + /// + /// The password. + /// Model. + public ActionResult ResetPassword(LostPasswordModel model) + { + if (Request.HttpMethod == "POST") { + StringDictionary errors; + MembershipUser user; + YavscHelpers.ValidatePasswordReset (model, out errors, out user); + foreach (string key in errors.Keys) + ModelState.AddModelError (key, errors [key]); + + if (user != null && ModelState.IsValid) + Url.SendActivationMessage (user); + } + return View (model); + } + + /// + /// Validate the specified id and key. + /// + /// Identifier. + /// Key. + [HttpGet] + public ActionResult Validate (string id, string key) + { + MembershipUser u = Membership.GetUser (id, false); + if (u == null) { + YavscHelpers.Notify( ViewData, + string.Format ("Cet utilisateur n'existe pas ({0})", id)); + } else if (u.ProviderUserKey.ToString () == key) { + if (u.IsApproved) { + YavscHelpers.Notify( ViewData, + string.Format ("Votre compte ({0}) est déjà validé.", id)); + } else { + u.IsApproved = true; + Membership.UpdateUser (u); + YavscHelpers.Notify( ViewData, + string.Format ("La création de votre compte ({0}) est validée.", id)); + } + } else + YavscHelpers.Notify( ViewData, "La clé utilisée pour valider ce compte est incorrecte" ); + return View (); + } + + } +} diff --git a/booking/Controllers/AdminController.cs b/booking/Controllers/AdminController.cs new file mode 100644 index 00000000..ab8175c1 --- /dev/null +++ b/booking/Controllers/AdminController.cs @@ -0,0 +1,324 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using System.Web.Security; +using Yavsc.Model.RolesAndMembers; +using Yavsc.Model.Admin; +using Yavsc.Admin; +using System.IO; +using Yavsc.Model; +using Yavsc.Helpers; + +namespace Yavsc.Controllers +{ + /// + /// Admin controller. + /// Only Admin members should be allowed to use it. + /// + public class AdminController : Controller + { + /// + /// Index this instance. + /// + public ActionResult Index() + { + // FIXME do this in a new installation script. + if (!Roles.RoleExists (_adminRoleName)) { + Roles.CreateRole (_adminRoleName); + YavscHelpers.Notify (ViewData, _adminRoleName + " " + LocalizedText.role_created); + } + return View (); + } + /// + /// Inits the db. + /// In order this action succeds, + /// there must not exist any administrator, + /// nor Admin group. + /// + /// The db. + /// Datac. + /// Do init. + public ActionResult InitDb(DataAccess datac, string doInit) + { + if (doInit=="on") { + if (ModelState.IsValid) { + datac.BackupPrefix = Server.MapPath (datac.BackupPrefix); + DataManager mgr = new DataManager (datac); + TaskOutput tcdb = mgr.CreateDb (); + ViewData ["DbName"] = datac.DbName; + ViewData ["DbUser"] = datac.DbUser; + ViewData ["Host"] = datac.Host; + ViewData ["Port"] = datac.Port; + return View ("Created", tcdb); + } + } + return View (); + } + /// + /// Backups the specified model. + /// + /// Model. + [Authorize(Roles="Admin")] + public ActionResult Backups(DataAccess model) + { + return View (model); + } + /// + /// Creates the backup. + /// + /// The backup. + /// Datac. + [Authorize(Roles="Admin")] + public ActionResult CreateBackup(DataAccess datac) + { + if (datac != null) { + if (ModelState.IsValid) { + if (string.IsNullOrEmpty (datac.Password)) + ModelState.AddModelError ("Password", "Invalid passord"); + datac.BackupPrefix = Server.MapPath (datac.BackupPrefix); + DataManager ex = new DataManager (datac); + Export e = ex.CreateBackup (); + if (e.ExitCode > 0) + ModelState.AddModelError ("Password", "Operation Failed"); + return View ("BackupCreated", e); + } + } else { + datac = new DataAccess (); + } + return View (datac); + } + /// + /// Creates the user backup. + /// + /// The user backup. + /// Datac. + /// Username. + [Authorize(Roles="Admin")] + public ActionResult CreateUserBackup(DataAccess datac,string username) + { + throw new NotImplementedException(); + } + /// + /// Upgrade the specified datac. + /// + /// Datac. + [Authorize(Roles="Admin")] + public ActionResult Upgrade(DataAccess datac) { + throw new NotImplementedException(); + } + /// + /// Restore the specified datac, backupName and dataOnly. + /// + /// Datac. + /// Backup name. + /// If set to true data only. + [Authorize(Roles="Admin")] + public ActionResult Restore(DataAccess datac,string backupName,bool dataOnly=true) + { + ViewData ["BackupName"] = backupName; + if (ModelState.IsValid) { + // TODO BETTER + datac.BackupPrefix = Server.MapPath (datac.BackupPrefix); + DataManager mgr = new DataManager (datac); + ViewData ["BackupName"] = backupName; + ViewData ["DataOnly"] = dataOnly; + + TaskOutput t = mgr.Restore ( + Path.Combine(new FileInfo(datac.BackupPrefix).DirectoryName, + backupName),dataOnly); + return View ("Restored", t); + } + BuildBackupList (datac); + return View (datac); + } + private void BuildBackupList(DataAccess datac) + { + // build ViewData ["Backups"]; + string bckd=Server.MapPath (datac.BackupPrefix); + DirectoryInfo di = new DirectoryInfo (new FileInfo(bckd).DirectoryName); + List bks = new List (); + foreach (FileInfo ti in di.GetFiles("*.tar")) + bks.Add (ti.Name); + ViewData ["Backups"] = bks.ToArray (); + } + /// + /// Removes from role. + /// + /// The from role. + /// Username. + /// Rolename. + /// Return URL. + [Authorize(Roles="Admin")] + public ActionResult RemoveFromRole(string username, string rolename, string returnUrl) + { + Roles.RemoveUserFromRole(username,rolename); + return Redirect(returnUrl); + } + /// + /// Removes the user. + /// + /// The user. + /// Username. + /// Submitbutton. + [Authorize(Roles="Admin")] + public ActionResult RemoveUser (string username, string submitbutton) + { + ViewData ["usertoremove"] = username; + if (submitbutton == "Supprimer") { + Membership.DeleteUser (username); + YavscHelpers.Notify(ViewData, string.Format("utilisateur \"{0}\" supprimé",username)); + ViewData ["usertoremove"] = null; + } + return View (); + } + /// + /// Removes the role. + /// + /// The role. + /// Rolename. + /// Submitbutton. + [Authorize(Roles="Admin")] + public ActionResult RemoveRole (string rolename, string submitbutton) + { + if (submitbutton == "Supprimer") + { + Roles.DeleteRole(rolename); + } + return RedirectToAction("RoleList"); + } + /// + /// Removes the role query. + /// + /// The role query. + /// Rolename. + [Authorize(Roles="Admin")] + public ActionResult RemoveRoleQuery(string rolename) + { + ViewData["roletoremove"] = rolename; + return View (); + } + /// + /// Removes the user query. + /// + /// The user query. + /// Username. + [Authorize(Roles="Admin")] + public ActionResult RemoveUserQuery(string username) + { + ViewData["usertoremove"] = username; + return UserList(); + } + + + //TODO no more than pageSize results per page + /// + /// User list. + /// + /// The list. + [Authorize()] + public ActionResult UserList () + { + MembershipUserCollection c = Membership.GetAllUsers (); + return View (c); + } + [Authorize()] + public ActionResult UsersInRole (string rolename) + { + if (rolename == null) + rolename = "Admin"; + ViewData ["RoleName"] = rolename; + ViewData ["Roles"] = Roles.GetAllRoles (); + ViewData ["UsersInRole"] = Roles.GetUsersInRole (rolename); + return View (); + } + + [Authorize()] + public ActionResult UserRoles (string username) + { + ViewData ["AllRoles"] = Roles.GetAllRoles (); + if (username == null) + username = User.Identity.Name; + ViewData ["UserName"] = username; + ViewData ["UsersRoles"] = Roles.GetRolesForUser (username); + return View (); + } + /// + /// a form to add a role + /// + /// The role. + [Authorize(Roles="Admin"),HttpGet] + public ActionResult AddRole () + { + return View (); + } + + /// + /// Add a new role. + /// + /// The add role. + /// Rolename. + [Authorize(Roles="Admin"),HttpPost] + public ActionResult AddRole (string rolename) + { + Roles.CreateRole(rolename); + YavscHelpers.Notify(ViewData, LocalizedText.role_created+ " : "+rolename); + return View (); + } + + /// + /// Shows the roles list. + /// + /// The list. + [Authorize()] + public ActionResult RoleList () + { + return View (Roles.GetAllRoles ()); + } + + private const string _adminRoleName = "Admin"; + + /// + /// Assing the Admin role to the specified user in model. + /// + /// Model. + [Authorize()] + public ActionResult Admin (NewAdminModel model) + { + // ASSERT (Roles.RoleExists (adminRoleName)) + string [] admins = Roles.GetUsersInRole (_adminRoleName); + string currentUser = Membership.GetUser ().UserName; + List users = new List (); + foreach (MembershipUser u in Membership.GetAllUsers ()) { + var i = new SelectListItem (); + i.Text = string.Format ("{0} <{1}>", u.UserName, u.Email); + i.Value = u.UserName; + users.Add (i); + } + ViewData ["admins"] = admins; + ViewData ["useritems"] = users; + if (ModelState.IsValid) { + Roles.AddUserToRole (model.UserName, _adminRoleName); + YavscHelpers.Notify(ViewData, model.UserName + " "+LocalizedText.was_added_to_the_role+" '" + _adminRoleName + "'"); + } else { + if (admins.Length > 0) { + if (! admins.Contains (Membership.GetUser ().UserName)) { + ModelState.Remove("UserName"); + ModelState.AddModelError("UserName",LocalizedText.younotadmin+"!"); + return View ("Index"); + } + } else { + // No admin, gives the Admin Role to the current user + Roles.AddUserToRole (currentUser, _adminRoleName); + admins = new string[] { currentUser }; + YavscHelpers.Notify(ViewData, string.Format ( + LocalizedText.was_added_to_the_empty_role, + currentUser, _adminRoleName)); + } + } + return View (model); + } + } +} + diff --git a/booking/Controllers/BackOfficeController.cs b/booking/Controllers/BackOfficeController.cs new file mode 100644 index 00000000..882a61a2 --- /dev/null +++ b/booking/Controllers/BackOfficeController.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using Yavsc.Admin; + + +namespace Yavsc.Controllers +{ + /// + /// Back office controller. + /// + public class BackOfficeController : Controller + { + /// + /// Index this instance. + /// + [Authorize(Roles="Admin,Providers")] + public ActionResult Index() + { + return View (); + } + } +} diff --git a/booking/Controllers/BlogsController.cs b/booking/Controllers/BlogsController.cs new file mode 100644 index 00000000..2306ce3c --- /dev/null +++ b/booking/Controllers/BlogsController.cs @@ -0,0 +1,412 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.IO; +using System.Linq; +using System.Net.Mime; +using System.Runtime.Serialization.Formatters.Binary; +using System.Web; +using System.Web.Configuration; +using System.Web.Profile; +using System.Web.Security; +using Npgsql.Web.Blog; +using Yavsc; +using Yavsc.Model; +using Yavsc.Model.Blogs; +using Yavsc.ApiControllers; +using Yavsc.Model.RolesAndMembers; +using System.Net; +using System.Web.Mvc; +using Yavsc.Model.Circles; +using Yavsc.Helpers; + +namespace Yavsc.Controllers +{ + /// + /// Blogs controller. + /// + public class BlogsController : Controller + { + private string sitename = + WebConfigurationManager.AppSettings ["Name"]; + + /// + /// Index the specified title, pageIndex and pageSize. + /// + /// Title. + /// Page index. + /// Page size. + public ActionResult Index (string title, int pageIndex = 0, int pageSize = 10) + { + if (title != null) + return Title (title, pageIndex, pageSize); + + return BlogList (pageIndex, pageSize); + } + /// + /// Chooses the media. + /// + /// The media. + /// Identifier. + public ActionResult ChooseMedia(long postid) + { + return View (); + } + + /// + /// Blogs the list. + /// + /// The list. + /// Page index. + /// Page size. + public ActionResult BlogList (int pageIndex = 0, int pageSize = 10) + { + int totalRecords; + var bs = BlogManager.LastPosts (pageIndex, pageSize, out totalRecords); + ViewData ["ResultCount"] = totalRecords; + ViewData ["PageSize"] = pageSize; + ViewData ["PageIndex"] = pageIndex; + var bec = new BlogEntryCollection (bs); + return View ("Index", bec ); + } + + + /// + /// Title the specified title, pageIndex and pageSize. + /// + /// Title. + /// Page index. + /// Page size. + /// + [HttpGet] + public ActionResult Title (string title, int pageIndex = 0, int pageSize = 10) + { + int recordCount; + MembershipUser u = Membership.GetUser (); + string username = u == null ? null : u.UserName; + FindBlogEntryFlags sf = FindBlogEntryFlags.MatchTitle; + BlogEntryCollection c = + BlogManager.FindPost (username, title, sf, pageIndex, pageSize, out recordCount); + var utc = new UTBlogEntryCollection (title); + utc.AddRange (c); + ViewData ["RecordCount"] = recordCount; + ViewData ["PageIndex"] = pageIndex; + ViewData ["PageSize"] = pageSize; + return View ("Title", utc); + } + + /// + /// Users the posts. + /// + /// The posts. + /// User. + /// Page index. + /// Page size. + [HttpGet] + public ActionResult UserPosts (string user, string title=null, int pageIndex = 0, int pageSize = 10) + { + if (title != null) return UserPost (user, title, pageIndex, pageSize); + int recordcount=0; + MembershipUser u = Membership.GetUser (); + FindBlogEntryFlags sf = FindBlogEntryFlags.MatchUserName; + ViewData ["SiteName"] = sitename; + ViewData ["BlogUser"] = user; + string readersName = null; + ViewData ["PageIndex"] = pageIndex; + ViewData ["pageSize"] = pageSize; + // displays invisible items when the logged user is also the author + if (u != null) { + if (u.UserName == user || Roles.IsUserInRole ("Admin")) + sf |= FindBlogEntryFlags.MatchInvisible; + readersName = u.UserName; + if (user == null) + user = u.UserName; + } + // find entries + BlogEntryCollection c = + BlogManager.FindPost (readersName, user, sf, pageIndex, pageSize, out recordcount); + // Get author's meta data + var pr = ProfileBase.Create (user); + if (pr != null) { + Profile bupr = new Profile (pr); + ViewData ["BlogUserProfile"] = bupr; + + // Inform of listing meta data + ViewData ["BlogTitle"] = bupr.BlogTitle; + ViewData ["Avatar"] = bupr.avatar; + } + ViewData ["RecordCount"] = recordcount; + UUBlogEntryCollection uuc = new UUBlogEntryCollection (user, c); + return View ("UserPosts", uuc); + } + + /// + /// Removes the comment. + /// + /// The comment. + /// Cmtid. + [Authorize(Roles="Blogger")] + public ActionResult RemoveComment (long cmtid) + { + long postid = BlogManager.RemoveComment (cmtid); + return GetPost (postid); + } + + /// + /// Gets the post. + /// + /// The post. + /// Postid. + public ActionResult GetPost (long postid) + { + ViewData ["id"] = postid; + BlogEntry e = BlogManager.GetForReading (postid); + UUTBlogEntryCollection c = new UUTBlogEntryCollection (e.Author,e.Title); + c.Add (e); + ViewData ["user"] = c.Author; + ViewData ["title"] = c.Title; + Profile pr = new Profile (ProfileBase.Create (c.Author)); + if (pr == null) + // the owner's profile must exist + // in order to publish its bills + return View ("NotAuthorized"); + ViewData ["BlogUserProfile"] = pr; + ViewData ["Avatar"] = pr.avatar; + ViewData ["BlogTitle"] = pr.BlogTitle; + return View ("UserPost",c); + } + + /// + /// Users the post. + /// Assume that : + /// * bec.Count > O + /// * bec.All(x=>x.Author == bec[0].Author) ; + /// + /// The post. + /// Bec. + private ActionResult UserPost (UUTBlogEntryCollection bec) + { + if (ModelState.IsValid) + if (bec.Count > 0) { + Profile pr = new Profile (ProfileBase.Create (bec.Author)); + if (pr == null) + // the owner's profile must exist + // in order to publish its bills + // This should'nt occur, as long as + // a profile must exist for each one of + // existing user record in data base + // and each post is deleted with user deletion + // a post => an author => a profile + throw new Exception("Unexpected error retreiving author's profile"); + ViewData ["BlogUserProfile"] = pr; + ViewData ["Avatar"] = pr.avatar; + ViewData ["BlogTitle"] = pr.BlogTitle; + MembershipUser u = Membership.GetUser (); + + ViewData ["Author"] = bec.Author; + if (!pr.BlogVisible) { + // only deliver to admins or owner + if (u == null) + return View ("NotAuthorized"); + else { + if (u.UserName != bec.Author) + if (!Roles.IsUserInRole (u.UserName, "Admin")) + return View ("NotAuthorized"); + } + } + if (u == null || (u.UserName != bec.Author) && !Roles.IsUserInRole (u.UserName, "Admin")) { + // Filer on allowed posts + BlogEntryCollection filtered = bec.FilterFor((u == null)?null : u.UserName); + UUTBlogEntryCollection nbec = new UUTBlogEntryCollection (bec.Author, bec.Title); + nbec.AddRange (filtered); + View ("UserPost",nbec); + } + } + return View ("UserPost",bec); + } + + /// + /// Users the post. + /// + /// The post. + /// User. + /// Title. + /// Page index. + /// Page size. + public ActionResult UserPost (string user, string title, int pageIndex = 0, int pageSize = 10) + { + ViewData ["user"] = user; + ViewData ["title"] = title; + ViewData ["PageIndex"] = pageIndex; + ViewData ["pageSize"] = pageSize; + var pb = ProfileBase.Create (user); + if (pb == null) + // the owner's profile must exist + // in order to publish its bills + return View ("NotAuthorized"); + Profile pr = new Profile (pb); + ViewData ["BlogUserProfile"] = pr; + ViewData ["Avatar"] = pr.avatar; + ViewData ["BlogTitle"] = pr.BlogTitle; + UUTBlogEntryCollection c = new UUTBlogEntryCollection (user, title); + c.AddRange ( BlogManager.FilterOnReadAccess (BlogManager.GetPost (user, title))); + return View ("UserPost",c); + } + + /// + /// Post the specified title. + /// + /// Title. + [Authorize(Roles="Blogger")] + public ActionResult Post (string title) + { + string un = Membership.GetUser ().UserName; + if (String.IsNullOrEmpty (title)) + title = ""; + ViewData ["SiteName"] = sitename; + ViewData ["Author"] = un; + ViewData ["AllowedCircles"] = CircleManager.DefaultProvider.List (un) + .Select (x => new SelectListItem { + Value = x.Id.ToString(), + Text = x.Title + }); + + return View ("Edit", new BlogEntry { Title = title, Author = un }); + } + + /// + /// Validates the edit. + /// + /// The edit. + /// Model. + [Authorize(Roles="Blogger")] + public ActionResult ValidateEdit (BlogEntry model) + { + ViewData ["SiteName"] = sitename; + ViewData ["Author"] = Membership.GetUser ().UserName; + if (ModelState.IsValid) { + if (model.Id != 0) { + // ensures rights to update + BlogManager.GetForEditing (model.Id, true); + BlogManager.UpdatePost (model.Id, model.Title, model.Content, model.Visible, model.AllowedCircles); + + } + else + model.Id = BlogManager.Post (model.Author, model.Title, model.Content, model.Visible, model.AllowedCircles); + if (model.Photo != null) + BlogManager.UpdatePostPhoto (model.Id, model.Photo); + return RedirectToAction ("Title", new { title = model.Title }); + } + ViewData ["AllowedCircles"] = + CircleManager.DefaultProvider.List ( + Membership.GetUser ().UserName).Select (x => new SelectListItem { + Value = x.Id.ToString(), + Text = x.Title, + Selected = model.AllowedCircles.Contains (x.Id) + }); + return View ("Edit", model); + } + + /// + /// Edit the specified bill + /// + /// Identifier. + [Authorize(Roles="Blogger")] + public ActionResult Edit (long postid) + { + + BlogEntry e = BlogManager.GetForEditing (postid); + string user = Membership.GetUser ().UserName; + Profile pr = new Profile (ProfileBase.Create(e.Author)); + ViewData ["BlogTitle"] = pr.BlogTitle; + ViewData ["LOGIN"] = user; + ViewData ["Id"] = postid; + // Populates the circles combo items + + if (e.AllowedCircles == null) + e.AllowedCircles = new long[0]; + + ViewData ["AllowedCircles"] = + CircleManager.DefaultProvider.List ( + Membership.GetUser ().UserName).Select (x => new SelectListItem { + Value = x.Id.ToString(), + Text = x.Title, + Selected = e.AllowedCircles.Contains (x.Id) + }); + return View (e); + } + + /// + /// Comment the specified model. + /// + /// Model. + [Authorize] + public ActionResult Comment (Comment model) + { + string username = Membership.GetUser ().UserName; + ViewData ["SiteName"] = sitename; + if (ModelState.IsValid) { + BlogManager.Comment (username, model.PostId, model.CommentText, model.Visible); + return GetPost (model.PostId); + } + return GetPost (model.PostId); + } + + /// + /// Remove the specified blog entry, by its author and title, + /// using returnUrl as the URL to return to, + /// and confirm as a proof you really know what you do. + /// + /// Title. + /// User. + /// Return URL. + /// If set to true confirm. + [Authorize(Roles="Blogger")] + public ActionResult RemoveTitle (string user, string title, string returnUrl, bool confirm = false) + { + if (returnUrl == null) + if (Request.UrlReferrer != null) + returnUrl = Request.UrlReferrer.AbsoluteUri; + ViewData ["returnUrl"] = returnUrl; + ViewData ["Author"] = user; + ViewData ["Title"] = title; + + if (Membership.GetUser ().UserName != user) + if (!Roles.IsUserInRole("Admin")) + throw new AuthorizationDenied (user); + if (!confirm) + return View ("RemoveTitle"); + BlogManager.RemoveTitle (user, title); + if (returnUrl == null) + RedirectToAction ("Index", new { user = user }); + return Redirect (returnUrl); + } + + /// + /// Removes the post. + /// + /// The post. + /// Identifier. + /// Return URL. + /// If set to true confirm. + [Authorize(Roles="Blogger")] + public ActionResult RemovePost (long postid, string returnUrl, bool confirm = false) + { + // ensures the access control + BlogEntry e = BlogManager.GetForEditing (postid); + if (e == null) + return new HttpNotFoundResult ("post id "+postid.ToString()); + ViewData ["id"] = postid; + ViewData ["returnUrl"] = string.IsNullOrWhiteSpace(returnUrl)? + Request.UrlReferrer.AbsoluteUri.ToString(): returnUrl; + // TODO: cleaner way to disallow deletion + if (!confirm) + return View ("RemovePost",e); + BlogManager.RemovePost (postid); + if (string.IsNullOrWhiteSpace(returnUrl)) + return RedirectToAction ("Index"); + return Redirect (returnUrl); + } + } +} + diff --git a/booking/Controllers/FileSystemController.cs b/booking/Controllers/FileSystemController.cs new file mode 100644 index 00000000..2dac4b11 --- /dev/null +++ b/booking/Controllers/FileSystemController.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using System.IO; +using System.Web.Security; +using System.Text.RegularExpressions; +using Yavsc.Model.FileSystem; + +namespace Yavsc.Controllers +{ + /// + /// File system controller. + /// + + public class FileSystemController : Controller + { + + /// + /// Initialize the specified requestContext. + /// + /// Request context. + [Authorize] + protected override void Initialize (System.Web.Routing.RequestContext requestContext) + { + base.Initialize (requestContext); + } + + /// + /// Index this instance. + /// + [Authorize] + public ActionResult Index (string user, string filename) + { + WebFileSystemManager fsmgr = new WebFileSystemManager (); + var files = fsmgr.GetFiles (user,filename); + return View (files); + } + + /// + /// Post the specified id. + /// + /// Identifier. + public ActionResult Post (string id) + { + return View (); + } + + /// + /// Details the specified user and filename. + /// + /// User. + /// Filename. + public ActionResult Details (string user, string filename) + { + WebFileSystemManager fsmgr = new WebFileSystemManager (); + FileInfo fi = fsmgr.FileInfo (filename); + + ViewData ["filename"] = filename; + // TODO : ensure that we use the default port for + // the used sheme + ViewData ["url"] = Url.Content("~/users/"+user+"/"+filename); + return View (fi); + } + } +} \ No newline at end of file diff --git a/booking/Controllers/FrontOfficeController.cs b/booking/Controllers/FrontOfficeController.cs new file mode 100644 index 00000000..1886e892 --- /dev/null +++ b/booking/Controllers/FrontOfficeController.cs @@ -0,0 +1,263 @@ +using System; +using Yavsc; +using System.Web.Mvc; +using System.Web; +using System.Text.RegularExpressions; +using System.IO; +using Yavsc.Controllers; +using System.Collections.Generic; +using Yavsc.Model; +using Yavsc.Model.WorkFlow; +using System.Web.Security; +using System.Threading; +using Yavsc.Model.FrontOffice; +using Yavsc.Model.FileSystem; +using Yavsc.Model.Calendar; +using System.Configuration; +using Yavsc.Helpers; +using Yavsc.Model.FrontOffice.Catalog; + +namespace Yavsc.Controllers +{ + /// + /// Front office controller. + /// Access granted to all + /// + public class FrontOfficeController : Controller + { + /// + /// The wfmgr. + /// + protected WorkFlowManager wfmgr = null; + + /// + /// Initialize the specified requestContext. + /// + /// Request context. + protected override void Initialize (System.Web.Routing.RequestContext requestContext) + { + base.Initialize (requestContext); + wfmgr = new WorkFlowManager (); + } + + /// + /// Index this instance. + /// + public ActionResult Index () + { + return View (); + } + /// + /// Pub the Event + /// + /// The pub. + /// Model. + public ActionResult EventPub (EventPub model) + { + return View (model); + } + /// + /// Estimates this instance. + /// + [Authorize] + public ActionResult Estimates (string client) + { + var u = Membership.GetUser (); + if (u == null) // There was no redirection to any login page + throw new ConfigurationErrorsException ("no redirection to any login page"); + + string username = u.UserName; + Estimate [] estims = wfmgr.GetUserEstimates (username); + ViewData ["UserName"] = username; + ViewData ["ResponsibleCount"] = + Array.FindAll ( + estims, + x => x.Responsible == username).Length; + ViewData ["ClientCount"] = + Array.FindAll ( + estims, + x => x.Client == username).Length; + return View (estims); + } + + + /// + /// Estimate the specified id. + /// + /// Identifier. + public ActionResult Get (long id) + { + Estimate f = wfmgr.GetEstimate (id); + if (f == null) { + ModelState.AddModelError ("Id", "Wrong Id"); + return View (new Estimate () { Id=id } ); + } + return View (f); + } + + /// + /// Estimate the specified model and submit. + /// + /// Model. + /// Submit. + [Authorize] + public ActionResult Estimate (Estimate model, string submit) + { + string username = Membership.GetUser().UserName; + // Obsolete, set in master page + ViewData ["WebApiBase"] = Url.Content(Yavsc.WebApiConfig.UrlPrefixRelative); + ViewData ["WABASEWF"] = ViewData ["WebApiBase"] + "/WorkFlow"; + if (submit == null) { + if (model.Id > 0) { + Estimate f = wfmgr.GetEstimate (model.Id); + if (f == null) { + ModelState.AddModelError ("Id", "Wrong Id"); + return View (model); + } + model = f; + ModelState.Clear (); + if (username != model.Responsible + && username != model.Client + && !Roles.IsUserInRole ("FrontOffice")) + throw new UnauthorizedAccessException ("You're not allowed to view this estimate"); + } else if (model.Id == 0) { + if (string.IsNullOrWhiteSpace(model.Responsible)) + model.Responsible = username; + } + } else { + + if (model.Id == 0) // if (submit == "Create") + if (string.IsNullOrWhiteSpace (model.Responsible)) + model.Responsible = username; + if (username != model.Responsible + && !Roles.IsUserInRole ("FrontOffice")) + throw new UnauthorizedAccessException ("You're not allowed to modify this estimate"); + + if (ModelState.IsValid) { + if (model.Id == 0) + model = wfmgr.CreateEstimate ( + username, + model.Client, model.Title, model.Description); + else { + wfmgr.UpdateEstimate (model); + model = wfmgr.GetEstimate (model.Id); + } + } + } + return View (model); + } + + /// + /// Catalog this instance. + /// + [AcceptVerbs ("GET")] + public ActionResult Catalog () + { + return View ( + CatalogManager.GetCatalog () + ); + } + + /// + /// Catalog this instance. + /// + [AcceptVerbs ("GET")] + public ActionResult Brand (string id) + { + Catalog c = CatalogManager.GetCatalog (); + ViewData ["BrandName"] = id; + return View (c.GetBrand (id)); + } + + /// + /// get the product category + /// + /// The category object. + /// Brand id. + /// Product category Id. + [AcceptVerbs ("GET")] + public ActionResult ProductCategory (string brandid, string pcid) + { + ViewData ["BrandId"] = brandid; + ViewData ["ProductCategoryId"] = pcid; + + var cat = CatalogManager.GetCatalog (); + if (cat == null) + throw new Exception ("No catalog"); + var brand = cat.GetBrand (brandid); + if (brand == null) + throw new Exception ("Not a brand id: "+brandid); + var pcat = brand.GetProductCategory (pcid); + if (pcat == null) + throw new Exception ("Not a product category id in this brand: " + pcid); + return View (pcat); + } + + /// + /// Product the specified id, pc and pref. + /// + /// Identifier. + /// Pc. + /// Preference. + [AcceptVerbs ("GET")] + public ActionResult Product (string id, string pc, string pref) + { + Product p = null; + ViewData ["BrandName"] = id; + ViewData ["ProdCatRef"] = pc; + ViewData ["ProdRef"] = pref; + Catalog cat = CatalogManager.GetCatalog (); + if (cat == null) { + YavscHelpers.Notify(ViewData, "Catalog introuvable"); + ViewData ["RefType"] = "Catalog"; + return View ("ReferenceNotFound"); + } + Brand b = cat.GetBrand (id); + if (b == null) { + ViewData ["RefType"] = "Brand"; + return View ("ReferenceNotFound"); + } + ProductCategory pcat = b.GetProductCategory (pc); + if (pcat == null) { + ViewData ["RefType"] = "ProductCategory"; + return View ("ReferenceNotFound"); + } + ViewData ["ProdCatName"] = pcat.Name; + p = pcat.GetProduct (pref); + if (p.CommandForm == null) + p.CommandForm = b.DefaultForm; + + return View ((p is Service) ? "Service" : "Product", p); + } + + /// + /// Basket this instance. + /// + [Authorize] + public ActionResult Basket () + { + return View (wfmgr.GetCommands (Membership.GetUser ().UserName)); + } + + /// + /// Command the specified collection. + /// + /// Collection. + [HttpPost] + [Authorize] + public ActionResult Command (FormCollection collection) + { + try { + // Add specified product command to the basket, + // saves it in db + new Command(collection,HttpContext.Request.Files); + YavscHelpers.Notify(ViewData, LocalizedText.Item_added_to_basket); + return View (collection); + } catch (Exception e) { + YavscHelpers.Notify(ViewData,"Exception:" + e.Message); + return View (collection); + } + } + + } +} diff --git a/booking/Controllers/GoogleController.cs b/booking/Controllers/GoogleController.cs new file mode 100644 index 00000000..332016d0 --- /dev/null +++ b/booking/Controllers/GoogleController.cs @@ -0,0 +1,367 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Web; +using System.Web.Mvc; +using System.Web.Profile; +using System.Web.Security; +using Newtonsoft.Json; +using Yavsc.Model; +using Yavsc.Model.Google; +using Yavsc.Model.RolesAndMembers; +using Yavsc.Helpers.Google; +using Yavsc.Model.Calendar; +using Yavsc.Helpers; + +namespace Yavsc.Controllers +{ + /// + /// Google controller. + /// + public class GoogleController : Controller + { + /// + /// Index this instance. + /// + public ActionResult Index() + { + return View (); + } + + private string SetSessionSate () + { + string state = "security_token"; + Random rand = new Random (); + for (int l = 0; l < 32; l++) { + int r = rand.Next (62); + char c; + if (r < 10) { + c = (char)('0' + r); + } else if (r < 36) { + r -= 10; + c = (char) ('a' + r); + } else { + r -= 36; + c = (char) ('A' + r); + } + state += c; + } + Session ["state"] = state; + return state; + } + + private string AuthGRU { + get { + return Request.Url.Scheme + "://" + + Request.Url.Authority + "/Google/Auth"; + } + } + + private string CalendarGRU { + get { + return Request.Url.Scheme + "://" + + Request.Url.Authority + "/Google/CalAuth"; + } + } + /// + /// Login the specified returnUrl. + /// + /// Return URL. + public void Login (string returnUrl) + { + if (string.IsNullOrWhiteSpace (returnUrl)) + returnUrl = "/"; + Session ["returnUrl"] = returnUrl; + OAuth2 oa = new OAuth2 (AuthGRU,clientId,clientSecret); + oa.Login (Response, SetSessionSate ()); + } + private string clientId = ConfigurationManager.AppSettings ["GOOGLE_CLIENT_ID"]; + private string clientSecret = ConfigurationManager.AppSettings ["GOOGLE_CLIENT_SECRET"]; + private string clientApiKey = ConfigurationManager.AppSettings ["GOOGLE_API_KEY"]; + /// + /// Gets the cal auth. + /// + /// Return URL. + public void GetCalAuth (string returnUrl) + { + if (string.IsNullOrWhiteSpace (returnUrl)) + returnUrl = "/"; + Session ["returnUrl"] = returnUrl; + OAuth2 oa = new OAuth2 (CalendarGRU,clientId,clientSecret); + oa.GetCalendarScope (Response, SetSessionSate ()); + } + + /// + /// Called after the Google authorizations screen, + /// we assume that Session contains a redirectUrl entry + /// + /// The auth. + [HttpGet] + [Authorize] + public ActionResult CalAuth () + { + string msg; + OAuth2 oa = new OAuth2 (CalendarGRU,clientId,clientSecret); + + AuthToken gat = oa.GetToken (Request, (string) Session ["state"], out msg); + if (gat == null) { + YavscHelpers.Notify(ViewData, msg); + return View ("Auth"); + } + SaveToken (HttpContext.Profile,gat); + HttpContext.Profile.SetPropertyValue ("gcalapi", true); + string returnUrl = (string) Session ["returnUrl"]; + Session ["returnUrl"] = null; + return Redirect (returnUrl); + } + + /// + /// 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. + /// + /// Gat. + private void SaveToken (ProfileBase pr, AuthToken gat) + { + pr.SetPropertyValue ("gtoken", gat.access_token); + if (gat.refresh_token != null) + pr.SetPropertyValue ("grefreshtoken", gat.refresh_token); + pr.SetPropertyValue ("gtokentype", gat.token_type); + pr.SetPropertyValue ("gtokenexpir", DateTime.Now.AddSeconds (gat.expires_in)); + pr.Save (); + } + + /// + /// Auth this instance. + /// + [HttpGet] + public ActionResult Auth () + { + string msg; + OAuth2 oa = new OAuth2 (AuthGRU,clientId,clientSecret); + AuthToken gat = oa.GetToken (Request, (string)Session ["state"], out msg); + if (gat == null) { + YavscHelpers.Notify(ViewData, msg); + return View (); + } + string returnUrl = (string)Session ["returnUrl"]; + SignIn regmod = new SignIn (); + + 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 + foreach (MembershipUser u in mbrs) { + string username = u.UserName; + FormsAuthentication.SetAuthCookie (username, true); + /* var upr = ProfileBase.Create (username); + SaveToken (upr,gat); */ + } + 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); + } + + /// + /// Creates an account using the Google authentification. + /// + /// Regmod. + [HttpPost] + public ActionResult Auth (SignIn regmod) + { + if (ModelState.IsValid) { + if (Membership.GetUser (regmod.UserName) != null) { + ModelState.AddModelError ("UserName", "This user name already is in use"); + return View (); + } + string returnUrl = (string) Session ["returnUrl"]; + AuthToken gat = (AuthToken) Session ["GoogleAuthToken"]; + People me = (People)Session ["me"]; + if (gat == null || me == null) + throw new InvalidDataException (); + + Random rand = new Random (); + string passwd = rand.Next (100000).ToString () + rand.Next (100000).ToString (); + + MembershipCreateStatus mcs; + Membership.CreateUser ( + regmod.UserName, + passwd, + regmod.Email, + null, + null, + true, + out mcs); + switch (mcs) { + case MembershipCreateStatus.DuplicateEmail: + ModelState.AddModelError ("Email", "Cette adresse e-mail correspond " + + "à un compte utilisateur existant"); + return View (regmod); + case MembershipCreateStatus.DuplicateUserName: + ModelState.AddModelError ("UserName", "Ce nom d'utilisateur est " + + "déjà enregistré"); + return View (regmod); + case MembershipCreateStatus.Success: + Membership.ValidateUser (regmod.UserName, passwd); + FormsAuthentication.SetAuthCookie (regmod.UserName, true); + + HttpContext.Profile.Initialize (regmod.UserName, true); + HttpContext.Profile.SetPropertyValue ("Name", me.displayName); + // TODO use image + if (me.image != null) { + HttpContext.Profile.SetPropertyValue ("Avatar", me.image.url); + } + if (me.placesLived != null) { + People.Place pplace = me.placesLived.Where (x => x.primary).First (); + if (pplace != null) + HttpContext.Profile.SetPropertyValue ("CityAndState", pplace.value); + } + if (me.url != null) + HttpContext.Profile.SetPropertyValue ("WebSite", me.url); + // Will be done in SaveToken: HttpContext.Profile.Save (); + SaveToken (HttpContext.Profile, gat); + Session ["returnUrl"] = null; + return Redirect (returnUrl); + } + ViewData ["returnUrl"] = returnUrl; + } + return View (regmod); + } + + + [Authorize] + [HttpGet] + ActionResult PushPos () + { + return View (); + } + + /// + /// Chooses the calendar. + /// + /// The calendar. + /// Return URL. + [Authorize] + [HttpGet] + public ActionResult ChooseCalendar (string returnUrl) + { + if (returnUrl != null) { + Session ["chooseCalReturnUrl"] = returnUrl; + return RedirectToAction ("GetCalAuth", + new { + returnUrl = Url.Action ("ChooseCalendar") // "ChooseCalendar?returnUrl="+HttpUtility.UrlEncode(returnUrl) + }); + } + string cred = OAuth2.GetFreshGoogleCredential (HttpContext.Profile); + CalendarApi c = new CalendarApi (clientApiKey); + CalendarList cl = c.GetCalendars (cred); + ViewData ["returnUrl"] = Session ["chooseCalReturnUrl"]; + return View (cl); + } + + /// + /// Sets the calendar. + /// + /// The calendar. + /// Calchoice. + /// return Url. + [HttpPost] + [Authorize] + public ActionResult SetCalendar (string calchoice,string returnUrl) + { + HttpContext.Profile.SetPropertyValue ("gcalid", calchoice); + HttpContext.Profile.Save (); + + if (returnUrl != null) { + return Redirect (returnUrl); + } + return Redirect ("/"); + } + + /// + /// Dates the query. + /// + /// The query. + [Authorize,HttpGet] + public ActionResult Book () + { + var model = new BookQuery (); + model.StartDate = DateTime.Now; + model.EndDate = model.StartDate.AddDays(2); + model.StartHour = DateTime.Now.ToString("HH:mm"); + model.EndHour = DateTime.Now.AddHours(1).ToString("HH:mm"); + return View (model); + } + + /// + /// Dates the query. + /// + /// The query. + /// Model. + [Authorize,HttpPost] + public ActionResult Book (BookQuery model) + { + if (ModelState.IsValid) { + DateTime mindate = DateTime.Now; + if (model.StartDate.Date < mindate.Date){ + ModelState.AddModelError ("StartDate", LocalizedText.FillInAFutureDate); + } + if (model.EndDate < model.StartDate) + ModelState.AddModelError ("EndDate", LocalizedText.StartDateAfterEndDate); + + var muc = Membership.FindUsersByName (model.Person); + if (muc.Count == 0) { + ModelState.AddModelError ("Person", LocalizedText.Non_existent_user); + } + if (!Roles.IsUserInRole (model.Role)) { + ModelState.AddModelError ("Role", LocalizedText.UserNotInThisRole); + } + ProfileBase upr = ProfileBase.Create (model.Person); + var gcalid = upr.GetPropertyValue ("gcalid"); + if (gcalid is DBNull) + ModelState.AddModelError ("Person", LocalizedText.No_calendar_for_this_user); + if (ModelState.IsValid) { + string calid = (string) gcalid; + DateTime maxdate = model.EndDate; + CalendarApi c = new CalendarApi (clientApiKey); + CalendarEventList events; + try { + string creds = OAuth2.GetFreshGoogleCredential (upr); + events = c.GetCalendar (calid, mindate, maxdate, creds); + YavscHelpers.Notify (ViewData, "Google calendar API call success"); + } catch (WebException ex) { + string response; + using (var stream = ex.Response.GetResponseStream()) + using (var reader = new StreamReader(stream)) + { + response = reader.ReadToEnd(); + } + YavscHelpers.Notify (ViewData, + string.Format( + "Google calendar API exception {0} : {1}
{2}
", + ex.Status.ToString(), + ex.Message, + response)); + } + } + } + return View (model); + } + } +} diff --git a/booking/Controllers/HomeController.cs b/booking/Controllers/HomeController.cs new file mode 100644 index 00000000..80e58123 --- /dev/null +++ b/booking/Controllers/HomeController.cs @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Net.Mail; +using System.Web; +using System.Web.Configuration; +using System.Reflection; +using System.Resources; +using Yavsc.Model; +using Npgsql.Web; +using Npgsql.Web.Blog; +using Yavsc.Helpers; +using Yavsc; +using System.Web.Mvc; +using Yavsc.Model.Blogs; +using System.Web.Security; +using System.Web.Profile; + +namespace Yavsc.Controllers +{ + /// + /// Home controller. + /// + public class HomeController : Controller + { + + /// + /// Lists the referenced assemblies. + /// + /// The info. + public ActionResult AssemblyInfo() + { + Assembly[] aslist = { + GetType ().Assembly, + typeof(ITCPNpgsqlProvider).Assembly, + typeof(NpgsqlMembershipProvider).Assembly, + typeof(NpgsqlContentProvider).Assembly, + typeof(NpgsqlBlogProvider).Assembly + }; + + List asnlist = new List (); + foreach (Assembly asse in aslist) { + foreach (AssemblyName an in asse.GetReferencedAssemblies ()) { + if (asnlist.All(x=> string.Compare(x.Name,an.Name)!=0)) + asnlist.Add (an); + } + } + asnlist.Sort (delegate(AssemblyName x, AssemblyName y) { + return string.Compare (x.Name, y.Name); + }); + return View (asnlist.ToArray()) ; + } + + private static string owneremail = null; + /// + /// Gets or sets the owner email. + /// + /// The owner email. + public static string OwnerEmail { + get { + if (owneremail == null) + owneremail = WebConfigurationManager.AppSettings.Get ("OwnerEMail"); + return owneremail; + } + set { + owneremail = value; + } + } + /// + /// Index this instance. + /// + public ActionResult Index () + { + if (Session.IsNewSession) { + string uid = (!Request.IsAuthenticated) ? Request.AnonymousID : User.Identity.Name; + ProfileBase pr = + ProfileBase.Create (uid); + bool ac = (bool) pr.GetPropertyValue ("allowcookies"); + if (!ac) + YavscHelpers.Notify (ViewData, LocalizedText.ThisSiteUsesCookies, + "function(){Yavsc.ajax(\"/Yavsc/AllowCookies\", { id:'"+uid+"' });}", + LocalizedText.I_understood); + } + + foreach (string tagname in new string[] {"Accueil","Événements","Mentions légales"}) + { + TagInfo ti = BlogManager.GetTagInfo (tagname); + // TODO specialyze BlogEntry creating a PhotoEntry + ViewData [tagname] = ti; + } + return View (); + } + /// + /// Credits this instance. + /// + public ActionResult Credits () + { + return View (); + } + + /// + /// Contact the specified email, reason and body. + /// + /// Email. + /// Reason. + /// Body. + public ActionResult Contact (string email, string reason, string body) + { + if (email==null) + ModelState.AddModelError("email","Enter your email"); + + if (reason==null) + ModelState.AddModelError("reason","Please, fill in a reason"); + + if (body==null) + ModelState.AddModelError("body","Please, fill in a body"); + if (!ModelState.IsValid) + return View (); + + // requires valid owner and admin email? + if (OwnerEmail == null) + throw new Exception ("No site owner!"); + + using (System.Net.Mail.MailMessage msg = new MailMessage(email,OwnerEmail,"[Contact] "+reason,body)) + { + msg.CC.Add(new MailAddress(YavscHelpers.Admail)); + using (System.Net.Mail.SmtpClient sc = new SmtpClient()) + { + sc.Send (msg); + YavscHelpers.Notify(ViewData, LocalizedText.Message_sent); + return View (new { email=email, reason="", body="" }); + } + } + } + + } +} diff --git a/booking/Controllers/ModuleController.cs b/booking/Controllers/ModuleController.cs new file mode 100644 index 00000000..4aae72c1 --- /dev/null +++ b/booking/Controllers/ModuleController.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using Yavsc.Model; +using System.Configuration; + +namespace Yavsc.Controllers +{ + /// + /// Module controller. + /// + public class ModuleController : Controller + { + /// + /// Initialize the specified requestContext. + /// + /// Request context. + protected override void Initialize (System.Web.Routing.RequestContext requestContext) + { + base.Initialize (requestContext); + ConfigurationManager.GetSection ("ymodules"); + + } + + // List modules = new List (); + /// + /// Index this instance. + /// + public ActionResult Index() + { + return View (); + } + } +} diff --git a/booking/Formatters/ErrorHtmlFormatter.cs b/booking/Formatters/ErrorHtmlFormatter.cs new file mode 100644 index 00000000..9e1fbe8c --- /dev/null +++ b/booking/Formatters/ErrorHtmlFormatter.cs @@ -0,0 +1,95 @@ +// +// ErrorHtmlFormatter.cs +// +// Author: +// paul <${AuthorEmail}> +// +// Copyright (c) 2015 paul +// +// 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.Http.Formatting; +using System.Net.Http.Headers; +using System.Collections.Generic; +using System.IO; +using System.Net.Http; +using System.Web.Mvc; +using System.Net; +using MarkdownDeep; +using Yavsc.Helpers; +using Yavsc.Model.Blogs; + +namespace Yavsc.Formatters +{ + /// + /// Formats a given error message to respond + /// in case of error, and in an html format + /// + public class ErrorHtmlFormatter:SimpleFormatter { + + /// + /// Gets or sets the title. + /// + /// The title. + public string Title { get ; set; } + /// + /// Gets or sets the error code. + /// + /// The error code. + public HttpStatusCode ErrorCode { get ; set; } + + string doctype=""; + /// + /// Initializes a new instance of the class. + /// + /// Error code. + /// Title. + public ErrorHtmlFormatter + (HttpStatusCode errorCode, string title):base("text/html") + { + ErrorCode = errorCode; + Title = title; + + } + + public override void WriteToStream (Type type, object value, Stream stream, HttpContent content) + { + // TODO create a type containing T4 parameters, and generate from them + using (var writer = new StreamWriter(stream)) + { + string message = value as string; + TagBuilder doc = new TagBuilder ("html"); + TagBuilder body = new TagBuilder ("body"); + TagBuilder h1 = new TagBuilder ("h1"); + TagBuilder p = new TagBuilder ("p"); + TagBuilder head = new TagBuilder ("head"); + head.InnerHtml = "" + + "" + + ""; + p.InnerHtml = MarkdownHelper.Markdown(message).ToHtmlString(); + h1.InnerHtml = MvcHtmlString.Create (Title).ToHtmlString(); + body.InnerHtml = h1.ToString()+p.ToString (); + doc.InnerHtml = head.ToString()+"\n"+body.ToString (); + writer.WriteLine (doctype); + writer.Write (doc.ToString()); + } + + } + + } +} diff --git a/booking/Formatters/EstimToPdfFormatter.MSAN.cs b/booking/Formatters/EstimToPdfFormatter.MSAN.cs new file mode 100644 index 00000000..87339dfc --- /dev/null +++ b/booking/Formatters/EstimToPdfFormatter.MSAN.cs @@ -0,0 +1,138 @@ +// +// EstimToPdfFormatter.cs +// +// Author: +// Paul Schneider +// +// 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 . + +#if MicrosoftAspNetMvc + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Web; +using System.Web.Profile; +using Yavsc.Model.RolesAndMembers; +using Yavsc.Model.WorkFlow; +using System.Net.Http.Formatting; +using System.Net.Http.Headers; + +namespace Yavsc.Formatters +{ + /// + /// Estim to pdf formatter. + /// + public class EstimToPdfFormatter: BufferedMediaTypeFormatter + { + /// + /// Initializes a new instance of the class. + /// + public EstimToPdfFormatter () + { + SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/pdf")); + } + /// + /// Determines whether this instance can read type the specified type. + /// + /// true if this instance can read type the specified type; otherwise, false. + /// Type. + public override bool CanReadType(Type type) + { + return false; + } + /// + /// Determines whether this instance can write type the specified type. + /// + /// true if this instance can write type the specified type; otherwise, false. + /// Type. + public override bool CanWriteType(System.Type type) + { + if (type == typeof(Estimate)) + { + return true; + } + else + { + Type enumerableType = typeof(IEnumerable); + return enumerableType.IsAssignableFrom(type); + } + } + public override void WriteToStream (Type type, object value, Stream writeStream, System.Net.Http.HttpContent content) + { + + // TODO create a type containing generation parameters, including a template path, and generate from them + + Yavsc.templates.Estim tmpe = new Yavsc.templates.Estim(); + tmpe.Session = new Dictionary(); + Estimate e = value as Estimate; + tmpe.Session.Add ("estim", e); + + Profile prpro = new Profile (ProfileBase.Create (e.Responsible)); + + var pbc = ProfileBase.Create (e.Client); + Profile prcli = new Profile (pbc); + + if (!prpro.HasBankAccount || !prcli.IsBillable) + throw new Exception("account number for provider, or client not billable."); + + tmpe.Session.Add ("from", prpro); + tmpe.Session.Add ("to", prcli); + tmpe.Init (); + + string contentStr = tmpe.TransformText (); + + string name = string.Format ("tmpestimtex-{0}", e.Id); + string fullname = Path.Combine ( + HttpRuntime.CodegenDir, name); + FileInfo fi = new FileInfo(fullname + ".tex"); + FileInfo fo = new FileInfo(fullname + ".pdf"); + using (StreamWriter sw = new StreamWriter (fi.FullName)) + { + sw.Write (contentStr); + } + using (Process p = new Process ()) { + p.StartInfo.WorkingDirectory = HttpRuntime.CodegenDir; + p.StartInfo = new ProcessStartInfo (); + p.StartInfo.UseShellExecute = false; + p.StartInfo.FileName = "/usr/bin/texi2pdf"; + p.StartInfo.Arguments = + string.Format ("--batch --build-dir={2} -o {0} {1}", + fo.FullName, + fi.FullName,HttpRuntime.CodegenDir); + p.Start (); + p.WaitForExit (); + if (p.ExitCode != 0) + throw new Exception ("Pdf generation failed with exit code:" + p.ExitCode); + } + + using (StreamReader sr = new StreamReader (fo.FullName)) { + byte[] buffer = File.ReadAllBytes (fo.FullName); + writeStream.Write(buffer,0,buffer.Length); + } + fi.Delete(); + fo.Delete(); + + } + + + } +} + + + +#endif diff --git a/booking/Formatters/EstimToPdfFormatter.cs b/booking/Formatters/EstimToPdfFormatter.cs new file mode 100644 index 00000000..3d4a7143 --- /dev/null +++ b/booking/Formatters/EstimToPdfFormatter.cs @@ -0,0 +1,134 @@ +// +// EstimToPdfFormatter.cs +// +// Author: +// Paul Schneider +// +// 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 . +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Net.Http; +using System.Net.Http.Formatting; +using System.Net.Http.Headers; +using System.Web; +using System.Web.Profile; +using Yavsc.Model.RolesAndMembers; +using Yavsc.Model.WorkFlow; + +namespace Yavsc.Formatters +{ + /// + /// Estim to pdf formatter. + /// + public class EstimToPdfFormatter: BufferedMediaTypeFormatter + { + /// + /// Initializes a new instance of the class. + /// + public EstimToPdfFormatter () + { + SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/pdf")); + } + /// + /// Determines whether this instance can read type the specified type. + /// + /// true if this instance can read type the specified type; otherwise, false. + /// Type. + public override bool CanReadType(Type type) + { + return false; + } + /// + /// Determines whether this instance can write type the specified type. + /// + /// true if this instance can write type the specified type; otherwise, false. + /// Type. + public override bool CanWriteType(System.Type type) + { + if (type == typeof(Estimate)) + { + return true; + } + else + { + Type enumerableType = typeof(IEnumerable); + return enumerableType.IsAssignableFrom(type); + } + } + + public override void WriteToStream (Type type, object value, Stream stream, HttpContent content) + { + + // TODO create a type containing generation parameters, including a template path, and generate from them + + Yavsc.templates.Estim tmpe = new Yavsc.templates.Estim(); + tmpe.Session = new Dictionary(); + Estimate e = value as Estimate; + tmpe.Session.Add ("estim", e); + + Profile prpro = new Profile (ProfileBase.Create (e.Responsible)); + + var pbc = ProfileBase.Create (e.Client); + Profile prcli = new Profile (pbc); + + if (!prpro.HasBankAccount || !prcli.IsBillable) + throw new Exception("account number for provider, or client not billable."); + + tmpe.Session.Add ("from", prpro); + tmpe.Session.Add ("to", prcli); + tmpe.Init (); + + string contentStr = tmpe.TransformText (); + + string name = string.Format ("tmpestimtex-{0}", e.Id); + string fullname = Path.Combine ( + HttpRuntime.CodegenDir, name); + FileInfo fi = new FileInfo(fullname + ".tex"); + FileInfo fo = new FileInfo(fullname + ".pdf"); + using (StreamWriter sw = new StreamWriter (fi.FullName)) + { + sw.Write (contentStr); + } + using (Process p = new Process ()) { + p.StartInfo.WorkingDirectory = HttpRuntime.CodegenDir; + p.StartInfo = new ProcessStartInfo (); + p.StartInfo.UseShellExecute = false; + p.StartInfo.FileName = "/usr/bin/texi2pdf"; + p.StartInfo.Arguments = + string.Format ("--batch --build-dir={2} -o {0} {1}", + fo.FullName, + fi.FullName,HttpRuntime.CodegenDir); + p.Start (); + p.WaitForExit (); + if (p.ExitCode != 0) + throw new Exception ("Pdf generation failed with exit code:" + p.ExitCode); + } + + using (StreamReader sr = new StreamReader (fo.FullName)) { + byte[] buffer = File.ReadAllBytes (fo.FullName); + stream.Write(buffer,0,buffer.Length); + } + fi.Delete(); + fo.Delete(); + + } + + + } +} + diff --git a/booking/Formatters/FormatterException.cs b/booking/Formatters/FormatterException.cs new file mode 100644 index 00000000..08725d8e --- /dev/null +++ b/booking/Formatters/FormatterException.cs @@ -0,0 +1,57 @@ +// +// TexToPdfFormatter.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.Http.Formatting; +using System.Net.Http.Headers; +using System.Collections.Generic; +using System.IO; +using System.Web; +using System.Diagnostics; +using System.Net.Http; +using Yavsc.Helpers; + +namespace Yavsc.Formatters +{ + /// + /// Formatter exception. + /// + public class FormatterException : Exception + { + /// + /// Initializes a new instance of the class. + /// + /// Message. + public FormatterException(string message):base(message) + { + } + /// + /// Initializes a new instance of the class. + /// + /// Message. + /// Inner exception. + public FormatterException(string message,Exception innerException):base(message,innerException) + { + } + + public string Output { get; set; } + public string Error { get; set; } + } +} diff --git a/booking/Formatters/RssFeedsFormatter.cs b/booking/Formatters/RssFeedsFormatter.cs new file mode 100644 index 00000000..076b7b9c --- /dev/null +++ b/booking/Formatters/RssFeedsFormatter.cs @@ -0,0 +1,100 @@ +// +// RssFormatter.cs +// +// Author: +// paul <${AuthorEmail}> +// +// Copyright (c) 2015 paul +// +// 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.Http.Formatting; +using System.Net.Http.Headers; +using System.Collections.Generic; +using System.IO; +using System.Net.Http; +using System.Web.Mvc; +using System.Net; +using Yavsc.Model; +using System.Text; + +namespace Yavsc.Formatters +{ + /// + /// Rss feeds formatter. + /// + public class RssFeedsFormatter:SimpleFormatter + { + string doctype = ""; + /// + /// Initializes a new instance of the class. + /// + public RssFeedsFormatter + () : base ("application/rss+xml") + { + } + + private const string dateformat = "ddd, dd MMM yyyy HH:mm:ss K"; + public override void WriteToStream (Type type, object value, Stream stream, HttpContent content) + { + RssFeedsChannel feeds = value as RssFeedsChannel; + using (var writer = new StreamWriter (stream)) { + TagBuilder rss = new TagBuilder ("rss"); + rss.Attributes.Add ("version", "2.0"); + TagBuilder channel = new TagBuilder ("channel"); + TagBuilder title = new TagBuilder ("title"); + TagBuilder description = new TagBuilder ("description"); + TagBuilder lastBuildDate = new TagBuilder ("lastBuildDate"); + TagBuilder link = new TagBuilder ("link"); + + title.InnerHtml = MvcHtmlString.Create (feeds.Title).ToHtmlString (); + description.InnerHtml = MvcHtmlString.Create (feeds.Description).ToHtmlString (); + lastBuildDate.InnerHtml = MvcHtmlString.Create (feeds.LastBuildDate.ToString (dateformat)).ToHtmlString (); + link.InnerHtml = MvcHtmlString.Create (feeds.Link).ToHtmlString (); + StringBuilder sb = new StringBuilder (); + foreach (RssFeedsEntry e in feeds.Entries) { + TagBuilder item = new TagBuilder ("item"); + TagBuilder ititle = new TagBuilder ("title"); + ititle.InnerHtml = e.Title; + + TagBuilder idescription = new TagBuilder ("description"); + idescription.InnerHtml = MvcHtmlString.Create (e.Description).ToHtmlString (); + TagBuilder ipubDate = new TagBuilder ("pubDate"); + ipubDate.InnerHtml = MvcHtmlString.Create ( + e.PubDate.ToString (dateformat)).ToHtmlString (); + + TagBuilder ilink = new TagBuilder ("link"); + ilink.InnerHtml = MvcHtmlString.Create (e.Link).ToHtmlString (); + + item.InnerHtml = ititle.ToString () + "\n" + + idescription.ToString () + "\n" + + ipubDate.ToString () + "\n" + + ilink.ToString () + "\n"; + + sb.Append (item.ToString () + "\n"); + } + channel.InnerHtml = title.ToString () + "\n" + + description.ToString () + "\n" + + lastBuildDate.ToString () + "\n" + + link.ToString () + "\n" + + sb.ToString () + "\n"; + rss.InnerHtml = channel.ToString (); + writer.WriteLine (doctype); + writer.Write (rss.ToString ()); + } + } + } + +} diff --git a/booking/Formatters/SimpleFormatter.cs b/booking/Formatters/SimpleFormatter.cs new file mode 100644 index 00000000..cf6701f7 --- /dev/null +++ b/booking/Formatters/SimpleFormatter.cs @@ -0,0 +1,84 @@ +// +// TexFormatter.cs +// +// Author: +// Paul Schneider +// +// 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 . +using System; +using System.Net.Http.Formatting; +using System.Net.Http.Headers; +using System.Collections.Generic; +using System.IO; +using System.Net.Http; +using System.Web.Mvc; +using System.Net; + +namespace Yavsc.Formatters +{ + /// + /// Simple formatter. + /// + public class SimpleFormatter : BufferedMediaTypeFormatter + { + /// + /// Initializes a new instance of the class. + /// + /// Mimetype. + public SimpleFormatter (string mimetype) + { + SupportedMediaTypes.Add(new MediaTypeHeaderValue(mimetype)); + } + /// + /// Determines whether this instance can write type the specified type. + /// + /// true if this instance can write type the specified type; otherwise, false. + /// Type. + public override bool CanWriteType(System.Type type) + { + if (type == typeof(string)) + { + return true; + } + else + { + Type enumerableType = typeof(IEnumerable); + return enumerableType.IsAssignableFrom(type); + } + } + /// + /// Determines whether this instance can read type the specified type. + /// + /// true if this instance can read type the specified type; otherwise, false. + /// Type. + public override bool CanReadType(Type type) + { + return false; + } + + + public override void WriteToStream (Type type, object value, Stream writeStream, HttpContent content) + { + using (var writer = new StreamWriter(writeStream)) + { + string doc = value as string; + writer.Write (doc); + } + + } + } +} + diff --git a/booking/Formatters/TexToPdfFormatter.cs b/booking/Formatters/TexToPdfFormatter.cs new file mode 100644 index 00000000..f627d2cf --- /dev/null +++ b/booking/Formatters/TexToPdfFormatter.cs @@ -0,0 +1,137 @@ +// +// TexToPdfFormatter.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.Http.Formatting; +using System.Net.Http.Headers; +using System.Collections.Generic; +using System.IO; +using System.Web; +using System.Diagnostics; +using System.Net.Http; +using Yavsc.Helpers; + +namespace Yavsc.Formatters +{ + /// + /// Tex to pdf formatter. + /// + public class TexToPdfFormatter: BufferedMediaTypeFormatter + { + /// + /// Initializes a new instance of the class. + /// + public TexToPdfFormatter () + { + SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/pdf")); + } + /// + /// Determines whether this instance can read type the specified type. + /// + /// true if this instance can read type the specified type; otherwise, false. + /// Type. + public override bool CanReadType(Type type) + { + return false; + } + /// + /// Determines whether this instance can write type the specified type. + /// + /// true if this instance can write type the specified type; otherwise, false. + /// Type. + public override bool CanWriteType(System.Type type) + { + if (type == typeof(string)) + { + return true; + } + else + { + Type enumerableType = typeof(IEnumerable); + return enumerableType.IsAssignableFrom(type); + } + } + /// + /// Writes to stream. + /// + /// Type. + /// Value. + /// Stream. + /// Content headers. + /// + public override void WriteToStream (Type type, object value, Stream stream, HttpContent content) + { + + string temp = Path.GetTempPath (); + string cntStr = value as string; + string name = "tmpdoc-"+Guid.NewGuid().ToString(); + string fullname = Path.Combine (temp, name); + FileInfo fi = new FileInfo(fullname + ".tex"); + FileInfo fo = null; + using (StreamWriter sw = new StreamWriter (fi.OpenWrite())) + { + sw.Write (cntStr); + sw.Close (); + } + + using (Process p = new Process ()) { + + Directory.SetCurrentDirectory (temp); + + p.StartInfo.WorkingDirectory = temp; + p.StartInfo = new ProcessStartInfo (); + p.StartInfo.UseShellExecute = false; + p.StartInfo.FileName = "texi2pdf"; + p.StartInfo.Arguments = + string.Format ("--batch {0}", + fi.FullName); + p.StartInfo.RedirectStandardOutput = true; + p.StartInfo.RedirectStandardError = true; + + p.Start (); + p.WaitForExit (); + + if (p.ExitCode != 0) { + var ex = new FormatterException ("Pdf generation failed with exit code:" + p.ExitCode); + ex.Output = p.StandardOutput.ReadToEnd ()+"\nCWD:"+temp; + ex.Error = p.StandardError.ReadToEnd (); + throw ex; + } + fo = new FileInfo(name + ".pdf"); + } + + byte[] buffer = File.ReadAllBytes (fo.Name); + stream.Write(buffer,0,buffer.Length); + if (content.Headers != null) + SetFileName(content.Headers, value.GetHashCode ().ToString ()); + } + + /// + /// Sets the name of the file. + /// + /// Content headers. + /// Basename. + public static void SetFileName(HttpContentHeaders contentHeaders, string basename) { + contentHeaders.ContentDisposition = new ContentDispositionHeaderValue ("attachment") { + FileName = "doc-" + basename + ".pdf" + }; + } + } +} diff --git a/booking/Global.asax b/booking/Global.asax new file mode 100644 index 00000000..569f561d --- /dev/null +++ b/booking/Global.asax @@ -0,0 +1 @@ +<%@ Application Inherits="Yavsc.MvcApplication" %> diff --git a/booking/Global.asax.cs b/booking/Global.asax.cs new file mode 100644 index 00000000..c5681ea6 --- /dev/null +++ b/booking/Global.asax.cs @@ -0,0 +1,132 @@ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Routing; +using Yavsc.Formatters; +using Yavsc.Model.FrontOffice; +using System.Web.SessionState; +using System.Web.Mvc; +using System.Web.Http; +using System.Web.WebPages.Scope; +using System.Reflection; +using System.Web.Configuration; + +namespace Yavsc +{ + + /// + /// Mvc application. + /// + public class MvcApplication : System.Web.HttpApplication + { + + /// + /// Registers the routes. + /// + /// Routes. + public static void RegisterRoutes (RouteCollection routes) + { + // Should be FrontOffice in a POS, + string defaultController = + WebConfigurationManager.AppSettings ["DefaultController"]; + if (defaultController == null) + defaultController = "Home"; + routes.IgnoreRoute ("{resource}.axd/{*pathInfo}"); // not used + routes.IgnoreRoute ("Scripts/{*pathInfo}"); // web user side scripts + routes.IgnoreRoute ("App_Theme/{*pathInfo}"); // sites themes + routes.IgnoreRoute ("users/{*pathInfo}"); // user's files + routes.IgnoreRoute ("avatars/{*pathInfo}"); // user's avatar + routes.IgnoreRoute ("bfiles/{*pathInfo}"); // Blog files + routes.IgnoreRoute ("xmldoc/{*pathInfo}"); // xml doc + routes.IgnoreRoute ("htmldoc/{*pathInfo}"); // html doc + routes.IgnoreRoute ("fonts/{*pathInfo}"); // fonts + routes.IgnoreRoute ("favicon.ico"); // favorite icon + routes.IgnoreRoute ("favicon.png"); // favorite icon + routes.IgnoreRoute ("robots.txt"); // for search engine robots + routes.MapRoute ( + "Titles", + "title/{title}", + new { controller = "Blogs", action = "Index", + title=UrlParameter.Optional } + ); + routes.MapRoute ( + "Blogs", + "blog/{user}", + new { controller = "Blogs", + action = "UserPosts", + user="Paul Schneider" } + ); + + routes.MapRoute ( + "BlogByTitle", + "by/{user}/{title}/{id}", + new { controller = "Blogs", + action = "UserPosts", + user="Paul Schneider", + title=UrlParameter.Optional, + id=UrlParameter.Optional } + ); + routes.MapRoute ( + "BlogById", + "b/{action}/{postid}", + new { controller = "Blogs", action = "Index", + postid=UrlParameter.Optional } + ); + routes.MapRoute ( + "BackCompat", + "Blogs/{action}/{user}/{title}", + new { controller = "Blogs", action = "Index", user = UrlParameter.Optional, title = UrlParameter.Optional } + ); + + routes.MapRoute ( + "Default", + "{controller}/{action}/{id}", + new { controller = "Home", action = "Index", id = UrlParameter.Optional } + ); + + } + + /// + /// Starts the Application. + /// + protected void Application_Start () + { + AreaRegistration.RegisterAllAreas (); + WebApiConfig.Register (GlobalConfiguration.Configuration); + RegisterRoutes (RouteTable.Routes); + } + + /// + /// Applications the post authorize request. + /// + protected void Application_PostAuthorizeRequest() + { + if (IsWebApiRequest()) + { + HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required); + } + } + + private bool IsWebApiRequest() + { + return HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.StartsWith(WebApiConfig.UrlPrefixRelative); + } + + /// + /// begins a request against this application. + /// + protected void Application_BeginRequest() + { + var ob = typeof( + AspNetRequestScopeStorageProvider).Assembly.GetType( + "System.Web.WebPages.WebPageHttpModule").GetProperty + ("AppStartExecuteCompleted", + BindingFlags.NonPublic | BindingFlags.Static); + ob.SetValue(null, true, null); + + } + } +} + diff --git a/booking/Helpers/Google/ApiClient.cs b/booking/Helpers/Google/ApiClient.cs new file mode 100644 index 00000000..6c4ca425 --- /dev/null +++ b/booking/Helpers/Google/ApiClient.cs @@ -0,0 +1,78 @@ +// +// 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 +{ + /// + /// Google base API client. + /// This class implements the identification values for a Google Api, + /// and provides some scope values. + /// + public class ApiClient + { + /// + /// The CLIENT Id. + /// + public static string CLIENT_ID { get ; set ; } + + /// + /// The CLIENt SECREt + /// + public static string CLIENT_SECRET { get ; set ; } + + /// + /// The API KEY. + /// + public static string API_KEY { get ; set ; } + /* // 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"; + */ + /// + /// The Map tracks scope . + /// + protected static string scopeTracks = "https://www.googleapis.com/auth/tracks"; + /// + /// The calendar scope. + /// + protected static string scopeCalendar = "https://www.googleapis.com/auth/calendar"; + + /// + /// The scope openid. + /// + protected static string[] scopeOpenid = { + "openid", + "profile", + "email" + }; + } + +} diff --git a/booking/Helpers/Google/CalendarApi.cs b/booking/Helpers/Google/CalendarApi.cs new file mode 100644 index 00000000..116a54af --- /dev/null +++ b/booking/Helpers/Google/CalendarApi.cs @@ -0,0 +1,138 @@ +// +// 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; +using Yavsc.Model; + +namespace Yavsc.Helpers.Google +{ + /// + /// Google Calendar API client. + /// + public class CalendarApi : ApiClient + { + public CalendarApi(string apiKey) + { + API_KEY = apiKey; + } + /// + /// The get cal list URI. + /// + protected static string getCalListUri = "https://www.googleapis.com/calendar/v3/users/me/calendarList"; + /// + /// The get cal entries URI. + /// + protected static string getCalEntriesUri = "https://www.googleapis.com/calendar/v3/calendars/{0}/events"; + + /// + /// The date format. + /// + private static string dateFormat = "yyyy-MM-ddTHH:mm:ss"; + + /// + /// The time zone. TODO Fixme with machine time zone + /// + private string timeZone = "+01:00"; + + /// + /// Gets the calendar list. + /// + /// The calendars. + /// Cred. + public CalendarList GetCalendars (string cred) + { + 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 ()) { + var cr = new Newtonsoft.Json.JsonSerializer (); + using (var rdr = new StreamReader (respstream)) + res = (CalendarList) cr.Deserialize (rdr, typeof(CalendarList)); + } + resp.Close (); + } + webreq.Abort (); + return res; + } + + /// + /// Gets a calendar. + /// + /// The calendar. + /// Calid. + /// Mindate. + /// Maxdate. + /// Upr. + public CalendarEventList GetCalendar (string calid, DateTime mindate, DateTime maxdate,string cred) + { + if (string.IsNullOrWhiteSpace (calid)) + throw new Exception ("the calendar identifier is not specified"); + + 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); + var cr = new Newtonsoft.Json.JsonSerializer (); + webreq.Headers.Add (HttpRequestHeader.Authorization, cred); + webreq.Method = "GET"; + webreq.ContentType = "application/http"; + CalendarEventList res = null; + try { + using (WebResponse resp = webreq.GetResponse ()) { + using (Stream respstream = resp.GetResponseStream ()) { + try { + using (var rdr = new StreamReader(respstream)) { + res = (CalendarEventList) + cr.Deserialize(rdr,typeof(CalendarEventList)); + } + } catch (Exception ) { + respstream.Close (); + resp.Close (); + webreq.Abort (); + throw ; + } + } + resp.Close (); + } + } catch (WebException ) { + webreq.Abort (); + throw; + } + webreq.Abort (); + return res; + } + + } +} diff --git a/booking/Helpers/Google/Entity.cs b/booking/Helpers/Google/Entity.cs new file mode 100644 index 00000000..73ee123f --- /dev/null +++ b/booking/Helpers/Google/Entity.cs @@ -0,0 +1,56 @@ +// +// 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 +{ + /// + /// Entity. + /// + public class Entity + { + /// + /// The I. + /// + public string ID; + /// + /// The name. + /// + 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/booking/Helpers/Google/EntityQuery.cs b/booking/Helpers/Google/EntityQuery.cs new file mode 100644 index 00000000..9b393e7f --- /dev/null +++ b/booking/Helpers/Google/EntityQuery.cs @@ -0,0 +1,46 @@ +// +// EntityQuery.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 +{ + /// + /// Entity query. + /// + public class EntityQuery { + /// + /// The entity identifiers. + /// + public string [] EntityIds; + /// + /// The minimum identifier. + /// + public string MinId; + } +} diff --git a/booking/Helpers/Google/MapTracks.cs b/booking/Helpers/Google/MapTracks.cs new file mode 100644 index 00000000..388e40c2 --- /dev/null +++ b/booking/Helpers/Google/MapTracks.cs @@ -0,0 +1,81 @@ +// +// 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 +{ + /// + /// Google Map tracks Api client. + /// + public class MapTracks:ApiClient { + + /// + /// The google map tracks path (uri of the service). + /// + 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 + + /// + /// Creates the entity. + /// + /// The entity. + /// Entities. + public 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; + } + + /// + /// Lists the entities. + /// + /// The entities. + /// Eq. + 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/booking/Helpers/Google/OAuth2.cs b/booking/Helpers/Google/OAuth2.cs new file mode 100644 index 00000000..305ab412 --- /dev/null +++ b/booking/Helpers/Google/OAuth2.cs @@ -0,0 +1,250 @@ +// +// 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; +using Yavsc.Helpers.Google; + +namespace Yavsc.Helpers.Google +{ + + /// + /// Google O auth2 client. + /// + public class OAuth2 : ApiClient + { + /// + /// The URI used to get tokens. + /// + protected static string tokenUri = "https://accounts.google.com/o/oauth2/token"; + + /// + /// The URI used to get authorized to. + /// + protected static string authUri = "https://accounts.google.com/o/oauth2/auth"; + + /// + /// Gets or sets the redirect URI sent to Google. + /// + /// The redirect URI. + public string RedirectUri { get; set; } + + /// + /// Initializes a new instance of the class. + /// + /// Redirect URI. + public OAuth2 (string redirectUri, string clientId, string clientSecret) + { + RedirectUri = redirectUri; + CLIENT_ID = clientId; + CLIENT_SECRET = clientSecret; + } + + /// + /// 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&approval_prompt=force", + CLIENT_ID, RedirectUri, scope, state); + GetAuthResponse (bresp, prms); + } + + /// + /// Gets the cal authorization. + /// + /// Bresp. + /// State. + public void GetCalendarScope (HttpResponseBase bresp, string state) + { + string prms = String.Format ("response_type=code&client_id={0}&redirect_uri={1}&scope={2}&state={3}&include_granted_scopes=true&access_type=offline&approval_prompt=force", + CLIENT_ID, RedirectUri, scopeCalendar, 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; + } + + /// + /// Gets the Google Authorization token. + /// + /// The token. + /// Rq. + /// State. + /// Message. + 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); + } + + internal static AuthToken GetTokenPosting (string postdata) + { + var cr = new Newtonsoft.Json.JsonSerializer (); + 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 ()) { + gat = (AuthToken) cr.Deserialize (new StreamReader (responseStream),typeof(AuthToken)); + responseStream.Close (); + } + response.Close (); + } + webreq.Abort (); + return gat; + } + + /// + /// Gets the code from the Google request. + /// + /// The code from request. + /// Rq. + /// State. + /// Message. + 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; + } + + /// + /// Invalid O auth2 refresh token. + /// + public class InvalidOAuth2RefreshToken: Exception + { + /// + /// Initializes a new instance of the class. + /// + /// Message. + public InvalidOAuth2RefreshToken(string message):base(message) + { + } + /// + /// Initializes a new instance of the class. + /// + /// Message. + /// Inner exception. + public InvalidOAuth2RefreshToken(string message,Exception innerException):base(message,innerException) + { + } + } + + /// + /// Gets fresh google credential. + /// + /// The fresh google credential. + /// Pr. + 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) { + object ort = pr.GetPropertyValue ("grefreshtoken"); + if (ort is DBNull || string.IsNullOrWhiteSpace((string)ort)) { + throw new InvalidOAuth2RefreshToken ("Google"); + } + string refresh_token = ort as string; + 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("gtokentype") + } + return token_type + " " + token; + } + + } +} + diff --git a/booking/Helpers/Google/PeopleApi.cs b/booking/Helpers/Google/PeopleApi.cs new file mode 100644 index 00000000..15a3e12e --- /dev/null +++ b/booking/Helpers/Google/PeopleApi.cs @@ -0,0 +1,69 @@ +// +// PeopleApi.cs +// +// Author: +// Paul Schneider +// +// Copyright (c) 2015 GNU GPL +// +// 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; +using Yavsc.Helpers.Google; + +namespace Yavsc.Helpers.Google +{ + /// + /// Google People API. + /// + public class PeopleApi: ApiClient + { + private static string getPeopleUri = "https://www.googleapis.com/plus/v1/people"; + + /// + /// Gets the People object associated to the given Google Access Token + /// + /// The me. + /// The Google Access Token object class. + public static People GetMe (AuthToken gat) + { + People me; + var cr = new Newtonsoft.Json.JsonSerializer (); + 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 (var rdr = new StreamReader (prresponseStream)) { + me = (People)cr.Deserialize (new StreamReader (prresponseStream),typeof(People)); + } + prresponseStream.Close (); + } + proresp.Close (); + } + webreppro.Abort (); + return me; + } + } + +} diff --git a/booking/Helpers/SimpleJsonPostMethod.cs b/booking/Helpers/SimpleJsonPostMethod.cs new file mode 100644 index 00000000..511c7cab --- /dev/null +++ b/booking/Helpers/SimpleJsonPostMethod.cs @@ -0,0 +1,110 @@ +// +// 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; + +namespace Yavsc.Helpers +{ + /// + /// Simple json post method. + /// + 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; } } + /// + /// Gets the path. + /// + /// The path. + public string Path { + get{ return Request.RequestUri.ToString(); } + } + /// + /// Sets the credential. + /// + /// Cred. + public void SetCredential(string cred) { + Request.Headers.Set(HttpRequestHeader.Authorization,cred); + } + + /// + /// Initializes a new instance of the Yavsc.Helpers.SimpleJsonPostMethod class. + /// + /// Path to method. + 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"; + } + /// + /// Invoke the specified query. + /// + /// Query. + public TAnswer Invoke(TQuery query) + { + + // DataContractJsonSerializer serquery = new DataContractJsonSerializer (typeof(TQuery)); + // DataContractJsonSerializer seransw = new DataContractJsonSerializer (typeof(TAnswer)); + var cr = new Newtonsoft.Json.JsonSerializer (); + using (MemoryStream streamQuery = new MemoryStream ()) { + using (StreamWriter swr = new StreamWriter (streamQuery)) { + cr.Serialize (swr, query); + } + } + + TAnswer ans = default (TAnswer); + using (WebResponse response = Request.GetResponse ()) { + using (Stream responseStream = response.GetResponseStream ()) { + using (var rdr = new StreamReader (responseStream)) { + ans = (TAnswer)cr.Deserialize (rdr, typeof(TAnswer)); + } + } + response.Close(); + } + return ans; + } + + #region IDisposable implementation + + /// + /// Releases all resource used by the Yavsc.Helpers.SimpleJsonPostMethod object. + /// + public void Dispose () + { + if (Request != null) Request.Abort (); + } + #endregion + } +} + diff --git a/booking/Helpers/T.cs b/booking/Helpers/T.cs new file mode 100644 index 00000000..36428a98 --- /dev/null +++ b/booking/Helpers/T.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Configuration; +using System.Web.Mvc; +using System.Web.Mvc.Ajax; +using System.Net.Mail; +using Yavsc; +using System.Globalization; +using Yavsc.Model; + +namespace Yavsc.Helpers +{ + /// + /// T. + /// + public static class T + { + + /// + /// Gets the string. + /// + /// The string. + /// Message. + public static string GetString(string msg) + { + string tr = LocalizedText.ResourceManager.GetString (msg.Replace (" ", "_")); + return tr==null?msg:tr; + } + /// + /// Translate the specified helper and text. + /// + /// Helper. + /// Text. + public static IHtmlString Translate(this HtmlHelper helper, string text) + { + // Just call the other one, to avoid having two copies (we don't use the HtmlHelper). + return new MvcHtmlString(helper.Encode(GetString(text))); + } + + } +} diff --git a/booking/Helpers/TemplateException.cs b/booking/Helpers/TemplateException.cs new file mode 100644 index 00000000..fe8b1357 --- /dev/null +++ b/booking/Helpers/TemplateException.cs @@ -0,0 +1,15 @@ +using System; + +namespace Yavsc.Helpers +{ + class TemplateException : Exception + { + public TemplateException(string message):base(message) + { + } + public TemplateException(string message,Exception innerException):base(message,innerException) + { + } + } +} + diff --git a/booking/Helpers/ThanksHelper.cs b/booking/Helpers/ThanksHelper.cs new file mode 100644 index 00000000..6b47711b --- /dev/null +++ b/booking/Helpers/ThanksHelper.cs @@ -0,0 +1,63 @@ +using System; +using System.Configuration; +using System.Collections.Generic; +using System.Web.Mvc; +using System.Linq.Expressions; +using Yavsc.Model.Circles; + +namespace Yavsc.Helpers +{ + /// + /// Link. + /// + public class Link { + /// + /// Gets or sets the text. + /// + /// The text. + public string Text { get; set; } + /// + /// Gets or sets the URL. + /// + /// The URL. + public string Url { get; set; } + /// + /// Gets or sets the image. + /// + /// The image. + public string Image { get; set; } + } + + /// + /// Thanks helper. + /// + public static class ThanksHelper { + + static private ThanksConfigurationSection configurationSection=null; + /// + /// Gets the configuration section. + /// + /// The configuration section. + static public ThanksConfigurationSection ConfigurationSection { + get { + if (configurationSection==null) + configurationSection = (ThanksConfigurationSection) ConfigurationManager.GetSection ("system.web/thanks"); + return configurationSection; + } + } + /// + /// Html code for each entry + /// + public static Link[] Thanks (this HtmlHelper helper) + { + List result = new List() ; + if (ConfigurationSection == null) return result.ToArray(); + if (ConfigurationSection.To == null) return result.ToArray(); + foreach (ThanksConfigurationElement e in ConfigurationSection.To) + result.Add( new Link { Url = e.Url, Image=e.Image, Text = e.Name }); + return result.ToArray(); + } + + } + +} diff --git a/booking/Helpers/YavscAjaxHelper.cs b/booking/Helpers/YavscAjaxHelper.cs new file mode 100644 index 00000000..83487ba6 --- /dev/null +++ b/booking/Helpers/YavscAjaxHelper.cs @@ -0,0 +1,64 @@ +// +// YavscAjaxHelper.cs +// +// Author: +// Paul Schneider +// +// Copyright (c) 2015 GNU GPL +// +// 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.Web.Mvc; +using System.Collections.Generic; +using Yavsc.Model.Messaging; + +namespace Yavsc.Helpers +{ + /// + /// Yavsc ajax helper. + /// + public static class YavscAjaxHelper + { + /// + /// Notify the specified helper, message and click_action. + /// + /// Helper. + /// Message. + /// Click action. + public static void Notify(this AjaxHelper helper, string message, string click_action=null) { + + if (helper.ViewData ["Notifications"] == null) + helper.ViewData ["Notifications"] = new List (); + (helper.ViewData ["Notifications"] as List).Add ( + new Notification { body = QuoteJavascriptString(message), + click_action = click_action } ) ; + } + + /// + /// Quotes the javascript string. + /// + /// The javascript string. + /// String. + public static string QuoteJavascriptString(string str) + { + str = str.Replace ("\n", "\\n"); + if (str.Contains ("'")) + if (str.Contains ("\"")) + return "'" + str.Replace ("'", "\\'") + "'"; + else + return "\"" + str + "\""; + return "'" + str + "'"; + } + } +} diff --git a/booking/Helpers/YavscHelpers.cs b/booking/Helpers/YavscHelpers.cs new file mode 100644 index 00000000..ea00a02b --- /dev/null +++ b/booking/Helpers/YavscHelpers.cs @@ -0,0 +1,345 @@ +using System; +using System.Web; +using System.Configuration; +using System.Web.Security; +using System.IO; +using System.Web.Configuration; +using System.Net.Mail; +using Yavsc.Model.RolesAndMembers; +using System.Collections.Generic; +using System.Collections.Specialized; +using Yavsc.Model.Circles; +using System.Web.UI; +using System.Linq.Expressions; +using System.Web.Profile; +using System.Web.Script.Serialization; +using System.Web.Mvc; +using System.Text.RegularExpressions; +using Yavsc.Model.Messaging; + +namespace Yavsc.Helpers +{ + + /// + /// Yavsc helpers. + /// + public static class YavscHelpers + { + + + private static string siteName = null; + /// + /// Gets the name of the site. + /// + /// The name of the site. + public static string SiteName { + get { + if (siteName == null) + siteName = WebConfigurationManager.AppSettings ["Name"]; + return siteName; + } + } + // Administrator email + private static string admail = + WebConfigurationManager.AppSettings ["AdminEmail"]; + /// + /// Gets the Administrator email. + /// + /// The admail. + public static string Admail { + get { + return admail; + } + } + + /// + /// Sends the activation message. + /// + /// Helper. + /// User. + public static void SendActivationMessage(this System.Web.Http.Routing.UrlHelper helper, MembershipUser user) + { + SendActivationMessage (helper.Route("Default", new { controller="Account", + action = "Validate", + key=user.ProviderUserKey.ToString(), id = user.UserName } ) + , WebConfigurationManager.AppSettings ["RegistrationMessage"], + user); + } + /// + /// Sends the activation message. + /// + /// Helper. + /// User. + public static void SendActivationMessage(this System.Web.Mvc.UrlHelper helper, MembershipUser user) + { + SendActivationMessage ( + string.Format("{2}://{3}/Account/Validate/{1}?key={0}", + user.ProviderUserKey.ToString(), user.UserName , + helper.RequestContext.HttpContext.Request.Url.Scheme, + helper.RequestContext.HttpContext.Request.Url.Authority + ) + , WebConfigurationManager.AppSettings ["RegistrationMessage"], + user); + } + + /// + /// Sends the activation message. + /// + /// Validation URL. + /// Registration message. + /// User. + public static void SendActivationMessage(string validationUrl, string registrationMessage, MembershipUser user) { + FileInfo fi = new FileInfo ( + HttpContext.Current.Server.MapPath (registrationMessage)); + if (!fi.Exists) { + throw new Exception( + string.Format ( + "Erreur inattendue (pas de corps de message " + + "à envoyer pour le message de confirmation ({0}))", + registrationMessage)); + } + + using (StreamReader sr = fi.OpenText ()) { + string body = sr.ReadToEnd (); + body = body.Replace ("<%SiteName%>", YavscHelpers.SiteName); + body = body.Replace ("<%UserName%>", user.UserName); + body = body.Replace ("<%UserActivatonUrl%>", validationUrl); + + using (MailMessage msg = new MailMessage ( + Admail, user.Email, + string.Format ("Validation de votre compte {0}", YavscHelpers.SiteName), + body)) { + using (SmtpClient sc = new SmtpClient ()) { + sc.Send (msg); + } + } + + } + } + + /// + /// Validates the password reset. + /// + /// Model. + /// Errors. + /// User. + public static void ValidatePasswordReset(LostPasswordModel model, out StringDictionary errors, out MembershipUser user) + { + MembershipUserCollection users = null; + errors = new StringDictionary (); + user = null; + if (!string.IsNullOrEmpty (model.UserName)) { + users = + Membership.FindUsersByName (model.UserName); + if (users.Count < 1) { + errors.Add ("UserName", "User name not found"); + return ; + } + if (users.Count != 1) { + errors.Add ("UserName", "Found more than one user!(sic)"); + return ; + } + } + if (!string.IsNullOrEmpty (model.Email)) { + users = + Membership.FindUsersByEmail (model.Email); + if (users.Count < 1) { + errors.Add ( "Email", "Email not found"); + return ; + } + if (users.Count != 1) { + errors.Add ("Email", "Found more than one user!(sic)"); + return ; + } + } + if (users==null) + return; + // Assert users.Count == 1 + foreach (MembershipUser u in users) user = u; + } + /// + /// Avatars the URL. + /// + /// The URL. + /// Helper. + /// Username. + public static string AvatarUrl (this System.Web.Mvc.UrlHelper helper, string username) { + if (username == null) return null; + ProfileBase pr = ProfileBase.Create (username); + object avpath = null; + if (pr != null) avpath = pr.GetPropertyValue("Avatar"); + if (avpath == null || avpath is DBNull) + return DefaultAvatar==null?"/bfiles/"+username+".png":DefaultAvatar; + string avatarLocation = avpath as string; + if (avatarLocation.StartsWith ("~/")) { + avatarLocation = helper.RouteUrl("Default", avatarLocation); + } + return avatarLocation; + + } + + private static string avatarDir = "~/avatars"; + private static string defaultAvatar = null; + private static string defaultAvatarMimetype = null; + public static string DefaultAvatar { + get { + if (defaultAvatar == null) + GetAvatarConfig (); + return defaultAvatar; + } + } + public static string AvatarDir { + get { + return avatarDir; + } + } + /// + /// Initializes a new instance of the class. + /// + private static void GetAvatarConfig () + { + string[] defaultAvatarSpec = ConfigurationManager.AppSettings.Get ("DefaultAvatar").Split (';'); + if (defaultAvatarSpec.Length != 2) + throw new ConfigurationErrorsException ("the DefaultAvatar spec should be found as ; "); + defaultAvatar = defaultAvatarSpec [0]; + defaultAvatarMimetype = defaultAvatarSpec [1]; + } + + /// + /// Javas the script. + /// + /// The script. + /// Html. + /// Object. + public static string JavaScript(this System.Web.Mvc.HtmlHelper html, object obj) + { + return JavaScript (obj); + } + /// + /// Javas the script. + /// + /// The script. + /// Object. + public static string JavaScript(object obj) + { + JavaScriptSerializer serializer = new JavaScriptSerializer(); + return serializer.Serialize(obj); + } + + public static void Notify(ViewDataDictionary ViewData, string message, string click_action=null, string clickActionName="Ok") { + Notify(ViewData, new Notification { body = YavscAjaxHelper.QuoteJavascriptString(message), + click_action = click_action, click_action_name = YavscAjaxHelper.QuoteJavascriptString(clickActionName)} ) ; + } + + public static void Notify(ViewDataDictionary ViewData, Notification note) { + if (ViewData ["Notifications"] == null) + ViewData ["Notifications"] = new List (); + (ViewData ["Notifications"] as List).Add ( + note ) ; + } + /// + /// Files the list. + /// + /// The list. + /// Html. + /// Path. + /// Patterns. + public static IHtmlString FileList(this System.Web.Mvc.HtmlHelper html, string path, string [] patterns = null) { + StringWriter str = new StringWriter(); + HtmlTextWriter writter = new HtmlTextWriter (str); + DirectoryInfo di = new DirectoryInfo (HttpContext.Current.Server.MapPath(path)); + if (!di.Exists) + return new System.Web.Mvc.MvcHtmlString (""); + var files = new List (); + if (patterns == null) + patterns = new string[] { "*" }; + var url = new System.Web.Mvc.UrlHelper(html.ViewContext.RequestContext, + html.RouteCollection); + + foreach (string pattern in patterns) + files.AddRange( + di.EnumerateFiles ( + pattern, + SearchOption.TopDirectoryOnly)); + writter.RenderBeginTag ("table"); + writter.RenderBeginTag ("tr"); + writter.RenderBeginTag ("td"); + writter.Write (html.Translate ("Name")); + writter.RenderEndTag (); + writter.RenderBeginTag ("td"); + writter.Write (html.Translate ("Created")); + writter.RenderEndTag (); + writter.RenderBeginTag ("td"); + writter.Write (html.Translate ("Modified")); + writter.RenderEndTag (); + writter.RenderEndTag (); + foreach (FileInfo fi in files) { + writter.RenderBeginTag ("tr"); + writter.RenderBeginTag ("td"); + writter.AddAttribute ("href", url.Content(path+"/"+fi.Name)); + writter.RenderBeginTag ("a"); + writter.Write (fi.Name); + writter.RenderEndTag (); + writter.RenderEndTag (); + writter.RenderBeginTag ("td"); + writter.Write (fi.LastWriteTime.ToString ("U")); + writter.RenderEndTag (); + writter.RenderBeginTag ("td"); + writter.Write (fi.CreationTime.ToString("U")); + writter.RenderEndTag (); + writter.RenderEndTag (); + } + writter.RenderEndTag (); + return new System.Web.Mvc.MvcHtmlString (str.ToString ()); + } + + /// + /// Renders the page links. + /// + /// The page links. + /// Helper. + /// Result count. + /// Page size. + /// Page index. + public static IHtmlString RenderPageLinks ( + this HtmlHelper helper, + int PageIndex, int PageSize, int ResultCount, + string args="?PageIndex={0}", + string pagesLabel="Pages: ", string singlePage="", + string none="néant" + ) + { + StringWriter strwr = new StringWriter (); + HtmlTextWriter writer = new HtmlTextWriter(strwr); + + if (ResultCount > 0 && ResultCount > PageSize ) { + int pageCount = ((ResultCount-1) / PageSize) + 1; + if ( pageCount > 1 ) { + writer.WriteEncodedText (pagesLabel); + for (int pi = (PageIndex < 5) ? 0 : PageIndex - 5; pi < pageCount && pi < PageIndex + 5; pi++) { + if (PageIndex == pi) + writer.RenderBeginTag ("b"); + else { + writer.AddAttribute (HtmlTextWriterAttribute.Href, + string.Format (args, pi)); + writer.RenderBeginTag ("a"); + } + writer.Write (pi + 1); + writer.RenderEndTag (); + writer.Write (" "); + } + } + else { + writer.Write (singlePage); + } + } + if (ResultCount == 0) { + writer.WriteEncodedText(none); + } + return new MvcHtmlString(strwr.ToString()); + } + + + } +} + diff --git a/booking/Models/App.master b/booking/Models/App.master new file mode 100644 index 00000000..0e2e44c2 --- /dev/null +++ b/booking/Models/App.master @@ -0,0 +1,92 @@ +<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %> + + +<% ViewState["orgtitle"] = Html.Translate(Page.Title); %> +<% Page.Title = ViewState["orgtitle"] + " - " + YavscHelpers.SiteName; %> + + + + + +" /> +" /> +" /> +" /> +" /> + + + + + + + + + + + + +
+ +

"> +<%=ViewState["orgtitle"]%> +- "><%= YavscHelpers.SiteName %> +

+
+ +
+<% if (ViewData ["Notifications"]!=null) { %> + +<% } %> +
+ +
+ + +
+ + + + + diff --git a/booking/Models/AppAdmin.master b/booking/Models/AppAdmin.master new file mode 100644 index 00000000..40944eb8 --- /dev/null +++ b/booking/Models/AppAdmin.master @@ -0,0 +1,107 @@ +<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %> + + +<% ViewState["orgtitle"] = Html.Translate(Page.Title); %> +<% Page.Title = ViewState["orgtitle"] + " - " + YavscHelpers.SiteName; %> + + + + + +" /> +" /> +" /> +" /> +" /> + + + + + + + + + +<%=Ajax.GlobalizationScript()%> + + + + + + +
+ +

"> +<%=ViewState["orgtitle"]%> +- "><%= YavscHelpers.SiteName %> +

+
+ +
+<% if (ViewData ["Notifications"]!=null) { %> + +<% } %> +
+ +
+ + +
+ + + + + diff --git a/booking/Models/NoLogin.master b/booking/Models/NoLogin.master new file mode 100644 index 00000000..0e88e45a --- /dev/null +++ b/booking/Models/NoLogin.master @@ -0,0 +1,69 @@ +<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %> + + +<% ViewState["orgtitle"] = Html.Translate(Page.Title); %> +<% Page.Title = ViewState["orgtitle"] + " - " + YavscHelpers.SiteName; %> + + + + + +" /> +" /> +" /> +" /> +" /> + + + + + + + + + + + + +
+ +

"> +<%=ViewState["orgtitle"]%> +- "><%= YavscHelpers.SiteName %> +

+
+ +
+<% if (ViewData ["Notifications"]!=null) { %> + +<% } %> +
+
+ + +
+ + + + + diff --git a/booking/RegistrationMail.txt b/booking/RegistrationMail.txt new file mode 100644 index 00000000..90e5bec0 --- /dev/null +++ b/booking/RegistrationMail.txt @@ -0,0 +1,9 @@ + +Votre compte <%SiteName%> a été créé, votre nom d'utilisateur +est <%UserName%>. + +Pour l'activer, veuillez suivre le lien suivant : + +<%UserActivatonUrl%> + +Merci d'avoir créé un compte utilisateur. diff --git a/booking/Settings/ModuleConfigurationElement.cs b/booking/Settings/ModuleConfigurationElement.cs new file mode 100644 index 00000000..aeb4c166 --- /dev/null +++ b/booking/Settings/ModuleConfigurationElement.cs @@ -0,0 +1,62 @@ +// +// ModuleConfigurationElement.cs +// +// Author: +// Paul Schneider +// +// 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 . +using System; +using System.Configuration; + +namespace Yavsc.Settings +{ + /// + /// Module configuration element. (NOTUSED) + /// + public class ModuleConfigurationElement : ConfigurationElement + { + /// + /// Initializes a new instance of the class. + /// + public ModuleConfigurationElement () + { + } + /// + /// Gets or sets the name of the module. + /// + /// The name. + [ConfigurationProperty("name", IsKey=true, IsRequired=true)] + public string Name { + get { + return (string) base ["name"]; + } + set { base ["name"] = value; } + } + /// + /// Gets or sets the name of the class. + /// + /// The name of the class. + [ConfigurationProperty("name", IsKey=true, IsRequired=true)] + public string ClassName { + get { + return (string) base ["classname"]; + } + set { base ["classname"] = value; } + } + + } +} + diff --git a/booking/Settings/ModuleConfigurationElementCollection.cs b/booking/Settings/ModuleConfigurationElementCollection.cs new file mode 100644 index 00000000..ec33c853 --- /dev/null +++ b/booking/Settings/ModuleConfigurationElementCollection.cs @@ -0,0 +1,60 @@ +// +// ModuleConfigurationElementCollection.cs +// +// Author: +// Paul Schneider +// +// 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 . +using System; +using System.Configuration; + +namespace Yavsc.Settings +{ + /// + /// Module configuration element collection. + /// + public class ModuleConfigurationElementCollection : ConfigurationElementCollection + { + /// + /// Initializes a new instance of the class. + /// + public ModuleConfigurationElementCollection () + { + } + + #region implemented abstract members of ConfigurationElementCollection + /// + /// Creates the new element. + /// + /// The new element. + protected override ConfigurationElement CreateNewElement () + { + throw new NotImplementedException (); + } + /// + /// Gets the element key. + /// + /// The element key. + /// Element. + protected override object GetElementKey (ConfigurationElement element) + { + throw new NotImplementedException (); + } + + #endregion + } +} + diff --git a/booking/Settings/ModulesConfigurationSection.cs b/booking/Settings/ModulesConfigurationSection.cs new file mode 100644 index 00000000..221739d8 --- /dev/null +++ b/booking/Settings/ModulesConfigurationSection.cs @@ -0,0 +1,40 @@ +// +// ModulesConfigurationSection.cs +// +// Author: +// Paul Schneider +// +// 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 . +using System; +using System.Configuration; + +namespace Yavsc.Settings +{ + /// + /// Modules configuration section. + /// This class is not yet used ... + /// + public class ModulesConfigurationSection : ConfigurationSection + { + /// + /// Initializes a new instance of the class. + /// + public ModulesConfigurationSection () + { + } + } +} + diff --git a/booking/Settings/ThanksConfigurationCollection.cs b/booking/Settings/ThanksConfigurationCollection.cs new file mode 100644 index 00000000..426969bf --- /dev/null +++ b/booking/Settings/ThanksConfigurationCollection.cs @@ -0,0 +1,41 @@ +using System; +using System.Configuration; + +namespace Yavsc +{ + /// + /// Thanks configuration collection. + /// Imlements the configuration, + /// providing the thanks collection + /// + public class ThanksConfigurationCollection : ConfigurationElementCollection + { + /// + /// Gets the element key. + /// + /// The element key. + /// Element. + protected override object GetElementKey (ConfigurationElement element) + { + return ((ThanksConfigurationElement) element).Name; + } + /// + /// Creates the new element. + /// + /// The new element. + protected override ConfigurationElement CreateNewElement () + { + return new ThanksConfigurationElement(); + } + /// + /// Gets the element. + /// + /// The element. + /// Name. + public ThanksConfigurationElement GetElement (string name) + { + return this.BaseGet(name) as ThanksConfigurationElement; + } + } +} + diff --git a/booking/Settings/ThanksConfigurationElement.cs b/booking/Settings/ThanksConfigurationElement.cs new file mode 100644 index 00000000..44b8e883 --- /dev/null +++ b/booking/Settings/ThanksConfigurationElement.cs @@ -0,0 +1,61 @@ +using System; +using System.Configuration; + +namespace Yavsc +{ + /// + /// Thanks configuration element. + /// + public class ThanksConfigurationElement : ConfigurationElement + { + /// + /// Gets or sets the name. + /// + /// The name. + [ConfigurationProperty("name", IsKey=true, IsRequired=true)] + public string Name { + get { + return (string) base ["name"]; + } + set { base ["name"] = value; } + } + /// + /// Gets or sets the URL. + /// + /// The URL. + [ConfigurationProperty("url")] + public string Url { + get { + return (string) base ["url"]; + } + set { base ["url"] = value; } + } + /// + /// Gets or sets the image. + /// + /// The image. + [ConfigurationProperty("image")] + public string Image { + get { + return (string) base ["image"]; + } + set { base ["image"] = value; } + } + + /// + /// Gets or sets the display. + /// + /// + /// The displaied text when no image is provided and we + /// don't want use the name attribute. + /// + [ConfigurationProperty("display")] + public string Display { + get { + return (string) base ["display"]; + } + set { base ["display"] = value; } + } + } +} + diff --git a/booking/Settings/ThanksConfigurationSection.cs b/booking/Settings/ThanksConfigurationSection.cs new file mode 100644 index 00000000..7e205f72 --- /dev/null +++ b/booking/Settings/ThanksConfigurationSection.cs @@ -0,0 +1,52 @@ +using System; +using System.Configuration; + +namespace Yavsc +{ + /// + /// Thanks configuration section. + /// + public class ThanksConfigurationSection : ConfigurationSection + { + /// + /// Gets or sets to. + /// + /// To. + [ConfigurationProperty("to")] + public ThanksConfigurationCollection To { + get { + return (ThanksConfigurationCollection) this["to"]; + } + set { + this ["to"] = value; + } + } + /// + /// Gets or sets the html class. + /// + /// The html class. + [ConfigurationProperty("html_class")] + public string HtmlClass { + get { + return (string)this ["html_class"]; + } + set { + this ["html_class"] = value; + } + } + /// + /// Gets or sets the title format. + /// + /// The title format. + [ConfigurationProperty("title_format")] + public string TitleFormat { + get { + return (string)this ["title_format"]; + } + set { + this ["title_format"] = value; + } + } + } +} + diff --git a/booking/ValidateAjaxAttribute.cs b/booking/ValidateAjaxAttribute.cs new file mode 100644 index 00000000..391b3d4d --- /dev/null +++ b/booking/ValidateAjaxAttribute.cs @@ -0,0 +1,72 @@ +// +// ValidateAjaxAttribute.cs +// +// Author: +// Paul Schneider +// +// 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 . +using System; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Web.Http.Filters; +using System.Web.Http.ModelBinding; + +namespace Yavsc +{ + /// + /// Validate ajax attribute. + /// + public class ValidateAjaxAttribute : ActionFilterAttribute + { + /// + /// Gets the error model object. + /// + /// The error model object. + /// Model state. + public static object GetErrorModelObject(ModelStateDictionary modelState) { + var errorModel = + from x in modelState.Keys + where modelState[x].Errors.Count > 0 + select new + { + // FIXME why not directly underscores? + key = x.Replace(".","_"), + errors = modelState[x].Errors. + Select(y => y.ErrorMessage). + ToArray() + }; + return errorModel; + + } + /// + /// Raises the action executed event. + /// + /// Action executed context. + public override void OnActionExecuted (HttpActionExecutedContext actionExecutedContext) + { + var modelState = actionExecutedContext.ActionContext.ModelState; + + if (!modelState.IsValid) + { + actionExecutedContext.Response = + actionExecutedContext.Request.CreateResponse (System.Net.HttpStatusCode.BadRequest, + ValidateAjaxAttribute.GetErrorModelObject (modelState)); + } + } + } +} + diff --git a/booking/Views/Account/ChangePassword.aspx b/booking/Views/Account/ChangePassword.aspx new file mode 100644 index 00000000..fd46b38b --- /dev/null +++ b/booking/Views/Account/ChangePassword.aspx @@ -0,0 +1,22 @@ +<%@ Page Title="Change your Password" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + +<%= Html.ValidationSummary("Modification de mot de passe") %> +<% using(Html.BeginForm("ChangePassword", "Account")) { %> + +<%= Html.TextBox( "UserName" ) %> +<%= Html.ValidationMessage("UserName", "*") %>
+ + <%= Html.Password( "OldPassword" ) %> +<%= Html.ValidationMessage("OldPassword", "*") %>
+ + <%= Html.Password( "NewPassword" ) %> +<%= Html.ValidationMessage("NewPassword", "*") %>
+ + <%= Html.Password( "ConfirmPassword" ) %> +<%= Html.ValidationMessage("ConfirmPassword", "*") %> + +<% } %> + +
+ + diff --git a/booking/Views/Account/ChangePasswordSuccess.aspx b/booking/Views/Account/ChangePasswordSuccess.aspx new file mode 100644 index 00000000..ce22f4fd --- /dev/null +++ b/booking/Views/Account/ChangePasswordSuccess.aspx @@ -0,0 +1,6 @@ +<%@ Page Title="Successfully changed your password" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + +
+<%= Html.ActionLink("Register","Register")%>
+
<%= Html.ActionLink("ChangePassword","ChangePassword")%>
+
diff --git a/booking/Views/Account/Circles.aspx b/booking/Views/Account/Circles.aspx new file mode 100644 index 00000000..e1f46398 --- /dev/null +++ b/booking/Views/Account/Circles.aspx @@ -0,0 +1,74 @@ +<%@ Page Title="Circles" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> +<%@ Register Assembly="Yavsc.WebControls" TagPrefix="yavsc" Namespace="Yavsc.WebControls" %> + + + + + + + + + + + + + +<% int lc=0; + foreach (var ci in (IEnumerable) ViewData["Circles"]) { lc++; %> +row" id="c_<%=ci.Id%>"> + + + +<% } %> + +
<%=Html.Translate("Title")%> +
<%=ci.Title%>" + class="btnremovecircle actionlink" cid="<%=ci.Id%>"/> +
+ + + +
+ + + + + diff --git a/booking/Views/Account/Index.aspx b/booking/Views/Account/Index.aspx new file mode 100644 index 00000000..1d76ed12 --- /dev/null +++ b/booking/Views/Account/Index.aspx @@ -0,0 +1,4 @@ +<%@ Page Title="Comptes utilisateur" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + +Pas de contenu :-( + diff --git a/booking/Views/Account/Login.aspx b/booking/Views/Account/Login.aspx new file mode 100644 index 00000000..54990dd6 --- /dev/null +++ b/booking/Views/Account/Login.aspx @@ -0,0 +1,32 @@ +<%@ Page Title="Login" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/NoLogin.master" %> + +
+<%= Html.ValidationSummary("Ouverture de session") %> +<% using(Html.BeginForm("Login", "Account")) %> +<% { %> +<%= Html.LabelFor(model => model.UserName) %> +<%= Html.TextBox( "UserName" ) %> +<%= Html.ValidationMessage("UserName", "*") %>
+ +<%= Html.LabelFor(model => model.Password) %> +<%= Html.Password( "Password" ) %> +<%= Html.ValidationMessage("Password", "*") %>
+ +<%= Html.LabelFor(model => model.RememberMe) %> +<%= Html.CheckBox("RememberMe") %> +<%= Html.ValidationMessage("RememberMe", "") %>
+<%= Html.Hidden("returnUrl",ViewData["returnUrl"]) %> +<%= Html.AntiForgeryToken() %> + + +<% } %>
+
+<%= Html.ActionLink("S'enregistrer","GetRegister",new {returnUrl=ViewData["returnUrl"]}, new { @class="actionlink" }) %> +
+ +
\ No newline at end of file diff --git a/booking/Views/Account/Profile.aspx b/booking/Views/Account/Profile.aspx new file mode 100644 index 00000000..b6ba4bae --- /dev/null +++ b/booking/Views/Account/Profile.aspx @@ -0,0 +1,140 @@ +<%@ Page Title="Profile_edition" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + + +<% Title = ViewData["UserName"] + " : " +Html.Translate("Profile_edition"); %> + + + + + <%= Html.ValidationSummary() %> +<% using(Html.BeginForm("Profile", "Account", FormMethod.Post, new { enctype = "multipart/form-data" })) %> +<% { %> + + <%= Html.Hidden("UserName",ViewData["ProfileUserName"]) %> + +
Informations publiques + + +<%= Html.LabelFor(model => model.NewUserName) %> : +<%= Html.TextBox("NewUserName") %> +<%= Html.ValidationMessage("NewUserName", "*") %> +
+ +<%= Html.LabelFor(model => model.WebSite) %> : +<%= Html.TextBox("WebSite") %> +<%= Html.ValidationMessage("WebSite", "*") %> +
+ +Avatar : avatar + + +<%= Html.ValidationMessage("AvatarFile", "*") %> + +
+
Informations administratives +<%= Html.LabelFor(model => model.Name) %> : +<%= Html.TextBox("Name") %> +<%= Html.ValidationMessage("Name", "*") %> +
+
Blog +
+<%= Html.LabelFor(model => model.BlogVisible) %> : +<%= Html.CheckBox("BlogVisible") %> +<%= Html.ValidationMessage("BlogVisible", "*") %> +
+ +<%= Html.LabelFor(model => model.BlogTitle) %> : +<%= Html.TextBox("BlogTitle") %> +<%= Html.ValidationMessage("BlogTitle", "*") %> +
+
+ +
Contact +
+<%= Html.LabelFor(model => model.Phone) %> +<%= Html.TextBox("Phone") %> +<%= Html.ValidationMessage("Phone", "*") %> +
+<%= Html.LabelFor(model => model.Mobile) %> +<%= Html.TextBox("Mobile") %> +<%= Html.ValidationMessage("Mobile", "*") %> +
+<%= Html.LabelFor(model => model.Address) %> +<%= Html.TextBox("Address") %> +<%= Html.ValidationMessage("Address", "*") %> +
+<%= Html.LabelFor(model => model.CityAndState) %> +<%= Html.TextBox("CityAndState") %> +<%= Html.ValidationMessage("CityAndState", "*") %> +
+<%= Html.LabelFor(model => model.ZipCode) %> +<%= Html.TextBox("ZipCode") %> +<%= Html.ValidationMessage("ZipCode", "*") %> +
+<%= Html.LabelFor(model => model.Country) %> +<%= Html.TextBox("Country") %> +<%= Html.ValidationMessage("Country", "*") %> +
+
+
Disponibilité +
+ <%= Html.LabelFor(model => model.GoogleCalendar) %> : + + <%= Html.Encode(Model.GoogleCalendar) %> + <%= Html.ActionLink("Choisir l'agenda","ChooseCalendar","Google",new { returnUrl= Request.Url.AbsolutePath }, new { @class="actionlink" }) %> +
+
Informations de facturation + +
+<%= Html.LabelFor(model => model.BankCode) %> : +<%= Html.TextBox("BankCode") %> +<%= Html.ValidationMessage("BankCode", "*") %> +
+ +<%= Html.LabelFor(model => model.WicketCode) %> : +<%= Html.TextBox("WicketCode") %> +<%= Html.ValidationMessage("WicketCode", "*") %> +
+ +<%= Html.LabelFor(model => model.AccountNumber) %> : +<%= Html.TextBox("AccountNumber") %> +<%= Html.ValidationMessage("AccountNumber", "*") %> +
+<%= Html.LabelFor(model => model.BankedKey) %> : +<%= Html.TextBox("BankedKey") %> +<%= Html.ValidationMessage("BankedKey", "*") %> +
+<%= Html.LabelFor(model => model.BIC) %> : +<%= Html.TextBox("BIC") %> +<%= Html.ValidationMessage("BIC", "*") %> +
+<%= Html.LabelFor(model => model.IBAN) %> : +<%= Html.TextBox("IBAN") %> +<%= Html.ValidationMessage("IBAN", "*") %> +
+
+ + +<% } %> + + + +
+ diff --git a/booking/Views/Account/Register.ascx b/booking/Views/Account/Register.ascx new file mode 100644 index 00000000..d0d0f61c --- /dev/null +++ b/booking/Views/Account/Register.ascx @@ -0,0 +1,73 @@ +<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> +<%= Html.ValidationSummary() %> +<% using(Html.BeginForm("Register")) %> +<% { %> +

Nouvel utilisateur

+* + + + + + + + + + + + + + + + + + + + +
+<%= Html.LabelFor(model => model.Name) %> + +<%= Html.TextBox( "Name" ) %> +<%= Html.ValidationMessage("Name", "*", new { @id="Err_ur_Name", @class="error" }) %>
+<%= Html.LabelFor(model => model.UserName) %> + +<%= Html.TextBox( "UserName" ) %> +<%= Html.ValidationMessage("UserName", "*", new { @id="Err_ur_UserName", @class="error" }) %>
+<%= Html.LabelFor(model => model.Password) %> + +<%= Html.Password( "Password" ) %> +<%= Html.ValidationMessage("Password", "*", new { @id="Err_ur_Password", @class="error" }) %> +
+<%= Html.LabelFor(model => model.Email) %> + +<%= Html.TextBox( "Email" ) %> +<%= Html.ValidationMessage("Email", "*", new { @id="Err_ur_Email", @class="error" }) %> +
+<%= Html.LabelFor(model => model.Address) %> + +<%= Html.TextBox( "Address" ) %> +<%= Html.ValidationMessage("Address", "*", new { @id="Err_ur_Address", @class="error" }) %>
+<%= Html.LabelFor(model => model.CityAndState) %> + +<%= Html.TextBox( "CityAndState" ) %> +<%= Html.ValidationMessage("CityAndState", "*", new { @id="Err_ur_CityAndState", @class="error" }) %> + + +
+<%= Html.LabelFor(model => model.ZipCode) %> + +<%= Html.TextBox( "ZipCode" ) %> +<%= Html.ValidationMessage("ZipCode", "*", new { @id="Err_ur_ZipCode", @class="error" }) %>
+<%= Html.LabelFor(model => model.Phone) %> + +<%= Html.TextBox( "Phone" ) %> +<%= Html.ValidationMessage("Phone", "*", new { @id="Err_ur_Phone", @class="error" }) %>
+<%= Html.LabelFor(model => model.Mobile) %> + +<%= Html.TextBox( "Mobile" ) %> +<%= Html.ValidationMessage("Mobile", "*", new { @id="Err_ur_Mobile", @class="error" }) %>
+ +<% } %> + + + + diff --git a/booking/Views/Account/Register.aspx b/booking/Views/Account/Register.aspx new file mode 100644 index 00000000..90d45436 --- /dev/null +++ b/booking/Views/Account/Register.aspx @@ -0,0 +1,39 @@ +<%@ Page Title="Register" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + +<%= Html.ValidationSummary() %> +<% using(Html.BeginForm("Register", "Account")) %> +<% { %> + + + + + +
+<%= Html.LabelFor(model => model.UserName) %> + +<%= Html.TextBox( "UserName" ) %> +<%= Html.ValidationMessage("UserName", "*") %>
+<%= Html.LabelFor(model => model.Password) %> + +<%= Html.Password( "Password" ) %> +<%= Html.ValidationMessage("Password", "*") %> +
+<%= Html.LabelFor(model => model.ConfirmPassword) %> + + <%= Html.Password( "ConfirmPassword" ) %> +<%= Html.ValidationMessage("ConfirmPassword", "*") %> +
+<%= Html.LabelFor(model => model.Email) %> + +<%= Html.TextBox( "Email" ) %> +<%= Html.ValidationMessage("Email", "*") %> +
+
+<%= Html.Hidden("returnUrl",ViewData["returnUrl"]) %> + + +<% } %> +
+ + diff --git a/booking/Views/Account/RegistrationPending.aspx b/booking/Views/Account/RegistrationPending.aspx new file mode 100644 index 00000000..f5e01246 --- /dev/null +++ b/booking/Views/Account/RegistrationPending.aspx @@ -0,0 +1,13 @@ +<%@ Page Title="Comptes utilisateur" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + +Votre compte utilisateur +<%= Html.Encode(YavscHelpers.SiteName) %> +a été créé, un e-mail de validation de votre compte a été envoyé a l'adresse fournie:
+<<%= Html.Encode(ViewData["email"]) %>>.
+Vous devriez le recevoir rapidement.
+Pour valider votre compte, suivez le lien indiqué dans cet e-mail. + +
diff --git a/booking/Views/Account/ResetPassword.aspx b/booking/Views/Account/ResetPassword.aspx new file mode 100644 index 00000000..7970c614 --- /dev/null +++ b/booking/Views/Account/ResetPassword.aspx @@ -0,0 +1,23 @@ +<%@ Page Title="Reset your Password" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + +<%= Html.ValidationSummary("Modification de mot de passe") %> + +<% using(Html.BeginForm("ResetPassword", "Account")) { %> +Enter one of the following :
+
  • + +<%= Html.TextBox( "UserName" ) %> +<%= Html.ValidationMessage("UserName", "*") %>
  • +
  • + +<%= Html.TextBox( "Email" ) %> +<%= Html.ValidationMessage("Email", "*") %> +
  • +
+Then, hit the following button: +
+A message will be sent to you, containning a link that you'll can use to reset your password. +<% } %> +
+ + diff --git a/booking/Views/Account/Unregister.aspx b/booking/Views/Account/Unregister.aspx new file mode 100644 index 00000000..ba7e7541 --- /dev/null +++ b/booking/Views/Account/Unregister.aspx @@ -0,0 +1,12 @@ + +<%@ Page Title="Unregister" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + +Warning: This will delete all of your data here, your profile, your posts and other data. +<% using(Html.BeginForm("Unregister", "Account")) { %> + + <%=Html.CheckBox("confirmed")%> + + <%= Html.Hidden("UserName") %> + <% } %> + diff --git a/booking/Views/Account/Validate.aspx b/booking/Views/Account/Validate.aspx new file mode 100644 index 00000000..a5975bd6 --- /dev/null +++ b/booking/Views/Account/Validate.aspx @@ -0,0 +1,2 @@ +<%@ Page Title="Comptes utilisateur - Validation" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + diff --git a/booking/Views/Admin/AddRole.aspx b/booking/Views/Admin/AddRole.aspx new file mode 100644 index 00000000..ded10055 --- /dev/null +++ b/booking/Views/Admin/AddRole.aspx @@ -0,0 +1,15 @@ +<%@ Page Title="Ajout d'un role" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/AppAdmin.master" %> + + +<%= Html.ValidationSummary() %> +<% using(Html.BeginForm()) + { %> +Nom du rôle : +<%= Html.TextBox( "RoleName" ) %> +<%= Html.ValidationMessage("RoleName", "*") %>
+ +<% } %> +<%= Html.Partial("AddMemberToRole")%> +
+ + diff --git a/booking/Views/Admin/AddUserToRole.ascx b/booking/Views/Admin/AddUserToRole.ascx new file mode 100644 index 00000000..0b69946e --- /dev/null +++ b/booking/Views/Admin/AddUserToRole.ascx @@ -0,0 +1,14 @@ +<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> +<%= Html.ValidationSummary() %> +<% using(Ajax.BeginForm("AddUserToRole", "Admin", new AjaxOptions() { UpdateTargetId = "roleaddedresult" })) + { %> +
+
+ +<%= Html.ValidationMessage("UserName", "*") %>
+ + +<%= Html.ValidationMessage("RoleName", "*") %>
+<%= Ajax.ActionLink("AddUserToRole", "AddUserToRole", new { RoleName = "Admin" } , new AjaxOptions() { UpdateTargetId = "roleaddedresult" }) %> +
+<% } %> \ No newline at end of file diff --git a/booking/Views/Admin/Admin.aspx b/booking/Views/Admin/Admin.aspx new file mode 100644 index 00000000..aec1c763 --- /dev/null +++ b/booking/Views/Admin/Admin.aspx @@ -0,0 +1,31 @@ +<%@ Page Title="Liste des administrateurs" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/AppAdmin.master" %> + + +
+ + +<% foreach (string u in (string[])ViewData["admins"]) { %> + + +<% } %> +
+<%= u %> <%= Html.ActionLink("Remove","RemoveFromRole",new { username = u, rolename="Admin", returnUrl = Request.Url.PathAndQuery })%> +
+
+
+

Ajout d'un administrateur +

+

<%= Html.ValidationSummary() %>

+ +<% using ( Html.BeginForm("Admin", "Admin") ) { %> + +<%= Html.LabelFor(model => model.UserName) %> : +<%= Html.DropDownListFor(model => model.UserName, (List)ViewData["useritems"] ) %> +<%= Html.ValidationMessage("UserName", "*") %> + + + <% } %> + +
+
+ diff --git a/booking/Views/Admin/BackupCreated.aspx b/booking/Views/Admin/BackupCreated.aspx new file mode 100644 index 00000000..88e00d26 --- /dev/null +++ b/booking/Views/Admin/BackupCreated.aspx @@ -0,0 +1,7 @@ +<%@ Page Title="Backup created" Language="C#" MasterPageFile="~/Models/AppAdmin.master" Inherits="System.Web.Mvc.ViewPage" %> + +

Error message

<%= Html.Encode(Model.Error) %>
+

Message

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

File name

<%= Html.Encode(Model.FileName) %>
+

Exit Code

<%= Html.Encode(Model.ExitCode) %>
+
diff --git a/booking/Views/Admin/Backups.aspx b/booking/Views/Admin/Backups.aspx new file mode 100644 index 00000000..b74298a6 --- /dev/null +++ b/booking/Views/Admin/Backups.aspx @@ -0,0 +1,6 @@ +<%@ Page Language="C#" MasterPageFile="~/Models/AppAdmin.master" Inherits="System.Web.Mvc.ViewPage" %> + + +<%=Html.ActionLink("Create a database backup", "CreateBackup")%>
+<%=Html.ActionLink("Restaurations", "Restore")%>
+
diff --git a/booking/Views/Admin/CreateBackup.aspx b/booking/Views/Admin/CreateBackup.aspx new file mode 100644 index 00000000..04cc7b2f --- /dev/null +++ b/booking/Views/Admin/CreateBackup.aspx @@ -0,0 +1,23 @@ +<%@ Page Title="Backup creation" Language="C#" MasterPageFile="~/Models/AppAdmin.master" Inherits="System.Web.Mvc.ViewPage" %> + +<%= Html.ValidationSummary("CreateBackup","Admin") %> +<% using (Html.BeginForm("CreateBackup")) { %> + +<%= Html.LabelFor(model => model.Host) %>: +<%= Html.TextBox( "Host" ) %> +<%= Html.ValidationMessage("Host", "*") %>
+<%= Html.LabelFor(model => model.Port) %>: +<%= Html.TextBox( "Port" ) %> +<%= Html.ValidationMessage("Port", "*") %>
+<%= Html.LabelFor(model => model.DbName) %>: +<%= Html.TextBox( "DbName" ) %> +<%= Html.ValidationMessage("DbName", "*") %>
+<%= Html.LabelFor(model => model.DbUser) %>: +<%= Html.TextBox( "DbUser" ) %> +<%= Html.ValidationMessage("DbUser", "*") %>
+<%= Html.LabelFor(model => model.Password) %>: +<%= Html.Password( "Password" ) %> +<%= Html.ValidationMessage("Password", "*") %>
+ +<% } %> +
diff --git a/booking/Views/Admin/Created.aspx b/booking/Views/Admin/Created.aspx new file mode 100644 index 00000000..33bdcedd --- /dev/null +++ b/booking/Views/Admin/Created.aspx @@ -0,0 +1,12 @@ +<%@ Page Title="Db init" Language="C#" MasterPageFile="~/Models/NoLogin.master" Inherits="System.Web.Mvc.ViewPage" %> + +

Initialisation de la base de données

+

Error message

<%= Html.Encode(Model.Error) %>
+

Message

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

Exit Code

<%= Html.Encode(Model.ExitCode) %>
+
Acces à la base de donnée +<%= Html.Encode(ViewData["DbName"]) %>
+<%= Html.Encode(ViewData["DbUser"]) %>
+<%= Html.Encode(ViewData["Host"]) %>
+
+
diff --git a/booking/Views/Admin/Index.aspx b/booking/Views/Admin/Index.aspx new file mode 100644 index 00000000..62a71ac0 --- /dev/null +++ b/booking/Views/Admin/Index.aspx @@ -0,0 +1,4 @@ +<%@ Page Title="Administration" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/AppAdmin.master" %> + + + diff --git a/booking/Views/Admin/InitDb.aspx b/booking/Views/Admin/InitDb.aspx new file mode 100644 index 00000000..47d4431b --- /dev/null +++ b/booking/Views/Admin/InitDb.aspx @@ -0,0 +1,23 @@ +<%@ Page Title="Init db" Language="C#" MasterPageFile="~/Models/NoLogin.master" Inherits="System.Web.Mvc.ViewPage" %> + +<%= Html.ValidationSummary("Init a new data base") %> +<% using (Html.BeginForm("InitDb","Admin")) { %> +<%= Html.LabelFor(model => model.Host) %>: +<%= Html.TextBox( "Host" ) %> +<%= Html.ValidationMessage("Host", "*") %>
+<%= Html.LabelFor(model => model.Port) %>: +<%= Html.TextBox( "Port" ) %> +<%= Html.ValidationMessage("Port", "*") %>
+<%= Html.LabelFor(model => model.DbName) %>: +<%= Html.TextBox( "DbName" ) %> +<%= Html.ValidationMessage("DbName", "*") %>
+<%= Html.LabelFor(model => model.DbUser) %>: +<%= Html.TextBox( "DbUser" ) %> +<%= Html.ValidationMessage("DbUser", "*") %>
+<%= Html.LabelFor(model => model.Password) %>: +<%= Html.Password( "Password" ) %> +<%= Html.ValidationMessage("Password", "*") %>
+ + +<% } %> +
diff --git a/booking/Views/Admin/RemoveRole.aspx b/booking/Views/Admin/RemoveRole.aspx new file mode 100644 index 00000000..73c1f659 --- /dev/null +++ b/booking/Views/Admin/RemoveRole.aspx @@ -0,0 +1,17 @@ +<%@ Page Title="User removal" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/AppAdmin.master" %> + +
+<%= Html.ValidationSummary() %> +<% using ( Html.BeginForm("RemoveRole","Admin") ) { %> +Supprimer le rôle +<%= Html.Encode( ViewData["roletoremove"] ) %> ? +
+"/> + + +<% } %> +
+ +
+ + diff --git a/booking/Views/Admin/RemoveUser.aspx b/booking/Views/Admin/RemoveUser.aspx new file mode 100644 index 00000000..f810e4f9 --- /dev/null +++ b/booking/Views/Admin/RemoveUser.aspx @@ -0,0 +1,18 @@ +<%@ Page Title="User removal" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/AppAdmin.master" %> + +
+ +<%= Html.ValidationSummary() %> +<% using ( Html.BeginForm("RemoveUser","Admin") ) { %> +Supprimer l'utilisateur +<%= Html.Encode( ViewData["usertoremove"] ) %> ? +
+"/> + + +<% } %> +
+ +
+ + diff --git a/booking/Views/Admin/Restore.aspx b/booking/Views/Admin/Restore.aspx new file mode 100644 index 00000000..ee2d34ca --- /dev/null +++ b/booking/Views/Admin/Restore.aspx @@ -0,0 +1,37 @@ +<%@ Page Title="Restore" Language="C#" MasterPageFile="~/Models/AppAdmin.master" Inherits="System.Web.Mvc.ViewPage" %> + +<%= Html.ValidationSummary("Restore a database backup") %> +<% using (Html.BeginForm("Restore","Admin")) { %> + +<% string [] bcfiles = (string[]) ViewData["Backups"]; %> + + +<%= Html.CheckBox("dataOnly")%> + +<%= Html.LabelFor(model => model.Host) %>: +<%= Html.TextBox( "Host" ) %> +<%= Html.ValidationMessage("Host", "*") %>
+<%= Html.LabelFor(model => model.Port) %>: +<%= Html.TextBox( "Port" ) %> +<%= Html.ValidationMessage("Port", "*") %>
+<%= Html.LabelFor(model => model.DbName) %>: +<%= Html.TextBox( "DbName" ) %> +<%= Html.ValidationMessage("DbName", "*") %>
+<%= Html.LabelFor(model => model.DbUser) %>: +<%= Html.TextBox( "DbUser" ) %> +<%= Html.ValidationMessage("DbUser", "*") %>
+<%= Html.LabelFor(model => model.Password) %>: +<%= Html.Password( "Password" ) %> +<%= Html.ValidationMessage("Password", "*") %>
+ + +<% } %> +
diff --git a/booking/Views/Admin/Restored.aspx b/booking/Views/Admin/Restored.aspx new file mode 100644 index 00000000..877a5d74 --- /dev/null +++ b/booking/Views/Admin/Restored.aspx @@ -0,0 +1,8 @@ +<%@ Page Language="C#" MasterPageFile="~/Models/AppAdmin.master" Inherits="System.Web.Mvc.ViewPage" %> + +

<%=Html.Encode(ViewData["BackupName"])%> Restauration

+

Error message

<%= Html.Encode(Model.Error) %>
+

Message

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

Exit Code

<%= Html.Encode(Model.ExitCode) %>
+ +
diff --git a/booking/Views/Admin/RoleList.aspx b/booking/Views/Admin/RoleList.aspx new file mode 100644 index 00000000..8706a1dc --- /dev/null +++ b/booking/Views/Admin/RoleList.aspx @@ -0,0 +1,20 @@ +<%@ Page Title="Liste des rôles" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/AppAdmin.master" %> + + + +Roles: +
    + <%foreach (string rolename in (string[]) Model){ %> + +
  • <%=Html.ActionLink(rolename,"UsersInRole", new { rolename = rolename }, new { @class="actionlink" } )%> <% if (Roles.IsUserInRole("Admin")) { %> + <%= Html.ActionLink("Supprimer","RemoveRole", new { rolename = rolename }, new { @class="actionlink" } ) %> +<% } %>
  • + <% } %> + +
+ <% if (Roles.IsUserInRole("Admin")) { %> + <%= Html.ActionLink("Ajouter un rôle","AddRole", null, new { @class="actionlink" } ) %> +<% } %> +
+ + diff --git a/booking/Views/Admin/UserList.aspx b/booking/Views/Admin/UserList.aspx new file mode 100644 index 00000000..c329ef09 --- /dev/null +++ b/booking/Views/Admin/UserList.aspx @@ -0,0 +1,16 @@ +<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/AppAdmin.master" %> + + <% Page.Title = LocalizedText.User_List; %> + + +
    + <%foreach (MembershipUser user in Model){ %> +
  • <%=user.UserName%> (created <%=user.CreationDate.ToString("D")%>) <%=user.Email%> <%=(user.IsApproved)?"":"("+LocalizedText.Not_Approuved+")"%> <%=user.IsOnline?LocalizedText.Online:LocalizedText.Offline%> +<% if (Roles.IsUserInRole("Admin")) { %> + <%= Html.ActionLink(LocalizedText.Remove,"RemoveUser", new { username = user.UserName }, new { @class="actionlink" } ) %> +<% } %> +
  • <% }%> +
+ +
+ diff --git a/booking/Views/Admin/UsersInRole.aspx b/booking/Views/Admin/UsersInRole.aspx new file mode 100644 index 00000000..bc48b6ed --- /dev/null +++ b/booking/Views/Admin/UsersInRole.aspx @@ -0,0 +1,21 @@ +<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" Title="UsersInRoleOf" MasterPageFile="~/Models/AppAdmin.master" %> + +<% ViewState["orgtitle"] = "Liste des utilisateurs assumant le rôle " + Html.Encode(ViewData["RoleName"]); %> +<% Page.Title = "Liste des utilisateurs assumant le rôle " + Html.Encode(ViewData["RoleName"]) + " - " + YavscHelpers.SiteName; %> + + + +

"> +<%=ViewState["orgtitle"]%> +- "><%= YavscHelpers.SiteName %> +

+
+ + <%foreach (string username in (string[]) ViewData["UsersInRole"]){ %> + <%= username %> + <% } %> + + + +<%= Html.Partial("AddUserToRole") %> + \ No newline at end of file diff --git a/booking/Views/BackOffice/Index.aspx b/booking/Views/BackOffice/Index.aspx new file mode 100644 index 00000000..66563f3f --- /dev/null +++ b/booking/Views/BackOffice/Index.aspx @@ -0,0 +1,9 @@ +<%@ Page Title="Back office" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + + + + +
  • + <%= Html.ActionLink("Catalog","Catalog","FrontOffice" ) %> +
+
diff --git a/web/Views/Blogs/ChooseMedia.aspx b/booking/Views/Blogs/ChooseMedia.aspx similarity index 100% rename from web/Views/Blogs/ChooseMedia.aspx rename to booking/Views/Blogs/ChooseMedia.aspx diff --git a/booking/Views/Blogs/Edit.aspx b/booking/Views/Blogs/Edit.aspx new file mode 100644 index 00000000..b6513414 --- /dev/null +++ b/booking/Views/Blogs/Edit.aspx @@ -0,0 +1,243 @@ +<%@ Page Title="Bill_edition" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> +<%@ Register Assembly="Yavsc.WebControls" TagPrefix="yavsc" Namespace="Yavsc.WebControls" %> + + + + + + + + + + + + + +<% using(Html.BeginForm("ValidateEdit","Blogs")) { %> +
+Contrôle d'accès au Billet +<%= Html.LabelFor(model => model.Visible) %> : <%= Html.CheckBox( "Visible" ) %> +Note: Si un ou plusieurs cercles sont séléctionnés ici, + le billet ne sera visible qu'aux membres de ces cercles. +<%= Html.ValidationMessage("Visible", "*") %> +<%= Html.LabelFor(model => model.AllowedCircles) %> +<%= Html.ListBox("AllowedCircles") %> +<%= Html.ValidationMessage("AllowedCircles", "*") %> +
+ +<%=Html.Translate("View_source")%> + + + +<% } %> + +
+
+Attacher des fichiers + + + +
+
+ + +photo + + +

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

+
+<%=Html.Markdown(Model.Content,"/bfiles/"+Model.Id+"/")%> +
+

Fichiers attachées

+ +<%= Html.FileList("~/bfiles/"+Model.Id) %> + +
+ + + + + + + + + +
\ No newline at end of file diff --git a/booking/Views/Blogs/Index.aspx b/booking/Views/Blogs/Index.aspx new file mode 100644 index 00000000..67e0ad52 --- /dev/null +++ b/booking/Views/Blogs/Index.aspx @@ -0,0 +1,18 @@ +<%@ Page Title="Articles" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" EnableTheming="True" StylesheetTheme="dark" %> +<%@ Register Assembly="Yavsc.WebControls" TagPrefix="yavsc" Namespace="Yavsc.WebControls" %> + + +
+<% foreach (var g in Model.GroupByTitle()) { %> +
+

" class="usertitleref"><%=Html.Encode(g.Key)%>

+<% foreach (var p in g) { %> +
+

<%= Html.Markdown(p.Intro,"/bfiles/"+p.Id+"/") %>

+ <%= Html.Partial("PostActions",p)%> +
<% } %> +
+ <% } %> +
+ <%= Html.RenderPageLinks((int)ViewData["PageIndex"],(int)ViewData["PageSize"],(int)ViewData["ResultCount"])%> +
diff --git a/web/Views/Blogs/NotAuthorized.aspx b/booking/Views/Blogs/NotAuthorized.aspx similarity index 100% rename from web/Views/Blogs/NotAuthorized.aspx rename to booking/Views/Blogs/NotAuthorized.aspx diff --git a/booking/Views/Blogs/PostActions.ascx b/booking/Views/Blogs/PostActions.ascx new file mode 100644 index 00000000..befcdb55 --- /dev/null +++ b/booking/Views/Blogs/PostActions.ascx @@ -0,0 +1,26 @@ +<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> + diff --git a/booking/Views/Blogs/RemovePost.aspx b/booking/Views/Blogs/RemovePost.aspx new file mode 100644 index 00000000..dbcfaa76 --- /dev/null +++ b/booking/Views/Blogs/RemovePost.aspx @@ -0,0 +1,20 @@ +<%@ Page Title="Bill_removal" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + + +<%= Html.ValidationSummary() %> +<% using (Html.BeginForm("RemovePost","Blogs",new {postid=Model.Id})) { %> + +<%= Html.LabelFor(model => model.Title) %> : +<%= Html.TextBox( "Title" ) %> +<%= Html.ValidationMessage("Title", "*") %>
+Identifiant du post : <%= Model.Id %>
+<%= Html.Markdown(Model.Content) %> + +<%= Html.CheckBox( "confirm" ) %> +<%= Html.ValidationMessage("confirm", "*") %> +<%= Html.Hidden("returnUrl") %> + + <% } %> + +
diff --git a/booking/Views/Blogs/RemoveTitle.aspx b/booking/Views/Blogs/RemoveTitle.aspx new file mode 100644 index 00000000..2aeee4ff --- /dev/null +++ b/booking/Views/Blogs/RemoveTitle.aspx @@ -0,0 +1,22 @@ +<%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + + +<%= Html.ValidationSummary() %> +<% using (Html.BeginForm("RemoveTitle","Blogs")) { %> + +<%= Html.LabelFor(model => model.Titles) %> : +<%= Html.TextBox( "Titles" ) %> +<%= Html.ValidationMessage("Titles", "*") %>
+<%= Html.Hidden("Author") %> + +<%= Html.CheckBox( "confirm" ) %> +<%= Html.ValidationMessage("AgreeToRemove", "*") %> + +<%= Html.Hidden("returnUrl") %> + + <% } %> + +
+ + diff --git a/booking/Views/Blogs/TagControl.ascx b/booking/Views/Blogs/TagControl.ascx new file mode 100644 index 00000000..cbaca288 --- /dev/null +++ b/booking/Views/Blogs/TagControl.ascx @@ -0,0 +1,47 @@ +<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> +

+<% if (Model.Tags != null) { +foreach ( var tagname in Model.Tags) { %> +<%=tagname%> <% +%><% } } %> +

+<% if (Membership.GetUser()!=null) { %> +<% if (Membership.GetUser().UserName==Model.Author || Roles.IsUserInRole("Admin")) +{ // grant all permissions: to choose a given set of tags, also create some new tags %> + +<%=Html.Translate("DoTag")%> + +
+
+Associer des tags au billet + + + + +"> +
+
+ +<% } %> +<% } %> diff --git a/booking/Views/Blogs/TagPanel.ascx b/booking/Views/Blogs/TagPanel.ascx new file mode 100644 index 00000000..1525e29f --- /dev/null +++ b/booking/Views/Blogs/TagPanel.ascx @@ -0,0 +1,12 @@ +<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> +
+<%=Html.Encode(Model.Name)%> +<% foreach (var t in Model.Titles) { %> +"> +placard +<%= Html.Markdown(t.Title,"/bfiles/"+t.Id+"/")%> +
+

<%= Html.Markdown(t.Intro,"/bfiles/"+t.Id+"/") %>

+
+<% } %> +
\ No newline at end of file diff --git a/booking/Views/Blogs/Title.aspx b/booking/Views/Blogs/Title.aspx new file mode 100644 index 00000000..4fb1912f --- /dev/null +++ b/booking/Views/Blogs/Title.aspx @@ -0,0 +1,34 @@ +<%@ Page Title="Titre" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master"%> +<%@ Register Assembly="Yavsc.WebControls" TagPrefix="yavsc" Namespace="Yavsc.WebControls" %> + +<% Title = Model.Title + " - " + YavscHelpers.SiteName; %> + + + +

+<%=Html.ActionLink(Model.Title, "Title", new{title=Model.Title}, null)%> +- "><%= YavscHelpers.SiteName %> +

+
+ + +<% foreach (BlogEntry e in this.Model) { %> +
+<% if (e.Photo!=null) { %><% } %> +<%= Html.Markdown(e.Content,"/bfiles/"+e.Id+"/") %> +<%= Html.Partial("PostActions",e)%> +
+<% } %> +<% +if (((int) ViewData["RecordCount"]) > ((int) ViewData["PageSize"])) { + rp1.ResultCount = (int) ViewData["RecordCount"]; + rp1.PageIndex = (int) ViewData["PageIndex"]; + rp1.PageSize = (int) ViewData["PageSize"]; +%> +<% } %> +
diff --git a/booking/Views/Blogs/TitleNotFound.aspx b/booking/Views/Blogs/TitleNotFound.aspx new file mode 100644 index 00000000..1162746d --- /dev/null +++ b/booking/Views/Blogs/TitleNotFound.aspx @@ -0,0 +1,5 @@ +<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master"%> + +Pas d'article trouvé ici: <<%= Html.Encode(ViewData["BlogUser"]) %>/<%= Html.Encode(ViewData["PostTitle"]) %>> +
<%= Html.ActionLink("Poster?","Post/", new { user = ViewData["BlogUser"], title = ViewData["PostTitle"]}, new { @class="actionlink" }) %> +
diff --git a/booking/Views/Blogs/UserPost.aspx b/booking/Views/Blogs/UserPost.aspx new file mode 100644 index 00000000..aea9c74d --- /dev/null +++ b/booking/Views/Blogs/UserPost.aspx @@ -0,0 +1,41 @@ +<%@ Page Title="Billet" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master"%> + +<% Title = Model.Title+ " - " + ViewData ["BlogTitle"] ; %> + + + +<% if (!string.IsNullOrEmpty((string)ViewData["Avatar"])) { %> +" id="avatar"> +" /> + +<% } %> +

+"> +<%=Model.Title%> + + - <%= Html.ActionLink((string)ViewData ["BlogTitle"] ,"UserPosts",new{user=Model.Author}, null) %> + - +"><%= YavscHelpers.SiteName %> +

+
+ + +<% foreach (var be in Model) { %> +
+<% if (be.Photo != null) { %> + <%=be.Title%> +<% } %> + +<%= Html.Markdown(be.Content,"/bfiles/"+be.Id+"/") %> + <%= Html.Partial("PostActions",be)%> + <% string username = Membership.GetUser()==null ? null : Membership.GetUser().UserName; %> + <% foreach (var c in (Comment[]) BlogManager.GetComments(be.Id)) { %> +
+" alt="<%=c.From%>"/> +<%= Html.Markdown(c.CommentText) %> + <% if (Model.Author == username || c.From == username ) { %> + <%= Html.ActionLink("Supprimer","RemoveComment", new { cmtid = c.Id } , new { @class="actionlink" })%> + <% } %> +
<% } %> +
<% } %> +
diff --git a/booking/Views/Blogs/UserPosts.aspx b/booking/Views/Blogs/UserPosts.aspx new file mode 100644 index 00000000..c22d1570 --- /dev/null +++ b/booking/Views/Blogs/UserPosts.aspx @@ -0,0 +1,48 @@ +<%@ Page Title="Blog" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master"%> +<%@ Register Assembly="Yavsc.WebControls" TagPrefix="yavsc" Namespace="Yavsc.WebControls" %> + +<% Title = (string) ViewData ["BlogTitle"] ; %> + + + + +<% if (!string.IsNullOrEmpty((string)ViewData["Avatar"])) { %> +" id="avatar"> +" /> + +<% } %> +

+"> +<%=Html.Encode(ViewData["BlogTitle"])%> +- "><%= YavscHelpers.SiteName %> +

+
+ + +<% foreach (BlogEntry e in this.Model) { %> +
+

" class="usertitleref"> +<%=Html.Markdown(e.Title)%>

+<% bool truncated = false; %> +<%= Html.MarkdownToHtmlIntro(out truncated, e.Content,"/bfiles/"+e.Id+"/") %> +<% if (truncated) { %> +"> + <%=Html.Translate("ReadMore")%> + <% } %> +<%= Html.Partial("PostActions",e)%> +
+<% } %> + + + +
diff --git a/booking/Views/FileSystem/Create.aspx b/booking/Views/FileSystem/Create.aspx new file mode 100644 index 00000000..7f8ef9d5 --- /dev/null +++ b/booking/Views/FileSystem/Create.aspx @@ -0,0 +1,20 @@ +<%@ Page Title="File posting" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + + +<% using(Html.BeginForm("Create", "FileSystem", FormMethod.Post, new { enctype = "multipart/form-data" })) { %> +
+ + + <%= Html.ValidationMessage("AFile") %> + +
+ + + +
+ + +
+ <% } %> +
diff --git a/booking/Views/FileSystem/Delete.aspx b/booking/Views/FileSystem/Delete.aspx new file mode 100644 index 00000000..b8c893bb --- /dev/null +++ b/booking/Views/FileSystem/Delete.aspx @@ -0,0 +1,3 @@ +<%@ Page Title="File System - File removal" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + + diff --git a/booking/Views/FileSystem/Details.aspx b/booking/Views/FileSystem/Details.aspx new file mode 100644 index 00000000..3fd36c33 --- /dev/null +++ b/booking/Views/FileSystem/Details.aspx @@ -0,0 +1,11 @@ +<%@ Page Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + +<%= Model.Name %>
+Création : +<%= Model.CreationTime %>
+Dérnière modification : +<%= Model.LastWriteTime %>
+Dernier accès : +<%= Model.LastAccessTime %>
+Lien permanent : "><%= ViewData["url"] %> +
diff --git a/booking/Views/FileSystem/Edit.aspx b/booking/Views/FileSystem/Edit.aspx new file mode 100644 index 00000000..b4de16ff --- /dev/null +++ b/booking/Views/FileSystem/Edit.aspx @@ -0,0 +1,5 @@ +<%@ Page Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + +<%= Html.ActionLink("Delete","FileSystem") %> +<%= Html.ActionLink("Rename","FileSystem") %> + diff --git a/booking/Views/FileSystem/Index.aspx b/booking/Views/FileSystem/Index.aspx new file mode 100644 index 00000000..05c9aac0 --- /dev/null +++ b/booking/Views/FileSystem/Index.aspx @@ -0,0 +1,12 @@ +<%@ Page Title="Files" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + +

Index +

+
    +<% foreach (System.IO.FileInfo fi in Model) { %> +
  • <%= Html.ActionLink(fi.Name,"Details",new {id = fi.Name}) %>
  • +<% } %> +
+ +<%= Html.ActionLink("Ajouter des fichiers","Create") %> +
diff --git a/booking/Views/FrontOffice/Basket.aspx b/booking/Views/FrontOffice/Basket.aspx new file mode 100644 index 00000000..72841343 --- /dev/null +++ b/booking/Views/FrontOffice/Basket.aspx @@ -0,0 +1,38 @@ +<%@ Page Title="Basket" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + + + +<% Title = Title +" "+ Model.Count+" article(s)"; %> + + + + +<% if (Model.Count>0) { %> +
    +<% foreach (Command cmd in Model.Values) { %> +
  • + <%= cmd.Id %> + <%= cmd.CreationDate %> + + <%= cmd.Status %> + <%= cmd.ProductRef %> +
      + <% if (cmd.Parameters!=null) + foreach (string key in cmd.Parameters.Keys) { %> +
    • <%=key%>: <%=cmd.Parameters[key]%>
    • + <% } %> +
    +
  • +<% } %> +
+<% } %> + +
+ + +
  • + <%= Html.ActionLink("Catalog","Catalog" ) %> +
  • + <%= Html.ActionLink("Estimates","Estimates" ) %> +
+
\ No newline at end of file diff --git a/booking/Views/FrontOffice/Brand.aspx b/booking/Views/FrontOffice/Brand.aspx new file mode 100644 index 00000000..86e8bde4 --- /dev/null +++ b/booking/Views/FrontOffice/Brand.aspx @@ -0,0 +1,31 @@ +<%@ Page Title="Catalog" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + +

<% if (Model.Logo!=null) { %> + <%=Model.Logo.Alt%> + <% } %> + <%=Html.Encode(Model.Name)%>

+

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

+
+ +<% foreach (ProductCategory pc in Model.Categories ) { %> +
+

<%= Html.ActionLink( pc.Name, "ProductCategory", new { id = Model.Name, pc = pc.Reference }, new { @class="actionlink" } ) %>

+
+ + <% foreach (Product p in pc.Products ) { %> +
+

<%= Html.ActionLink( p.Name, "Product", new { id = Model.Name, pc = pc.Reference , pref = p.Reference }, new { @class="actionlink" } ) %>

+

+ <%= p.Description %> + <% if (p.Images !=null) + foreach (ProductImage i in p.Images ) { %> + <%=i.Alt%> + <% } %> +

+
+<% } %> +<% } %> + + +
diff --git a/booking/Views/FrontOffice/Catalog.aspx b/booking/Views/FrontOffice/Catalog.aspx new file mode 100644 index 00000000..4c1be629 --- /dev/null +++ b/booking/Views/FrontOffice/Catalog.aspx @@ -0,0 +1,28 @@ +<%@ Page Title="Catalog" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + +<% foreach (Brand b in Model.Brands ) { %>
+

<%= Html.ActionLink( b.Name, "Brand", new { id = b.Name }, new { @class="actionlink" } ) %>

+

<%= Html.Encode( b.Slogan ) %>

+ <% foreach (ProductCategory pc in b.Categories ) { %> +
+

<%= Html.ActionLink( pc.Name, "ProductCategory", new { brandid= b.Name, pcid = pc.Reference }, new { @class="actionlink" } ) %>

+
+ + <% foreach (Product p in pc.Products ) { %> +
+

<%= Html.ActionLink( p.Name, "Product", new { id = b.Name, pc = pc.Reference , pref = p.Reference }, new { @class="actionlink" } ) %>

+

+ <%= p.Description %> + <% if (p.Images !=null) + foreach (ProductImage i in p.Images ) { %> + <%=i.Alt%> + <% } %> +

+
+<% } %> +<% } %> +
<% } %> +
+ + diff --git a/booking/Views/FrontOffice/Command.aspx b/booking/Views/FrontOffice/Command.aspx new file mode 100644 index 00000000..9f7cae32 --- /dev/null +++ b/booking/Views/FrontOffice/Command.aspx @@ -0,0 +1,13 @@ +<%@ Page Title="Commande" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + + + <%= Html.ActionLink("Votre panier","Basket","FrontOffice" ) %> + + + +
  • + <%= Html.ActionLink("Catalog","Catalog" ) %> +
  • + <%= Html.ActionLink("Estimates","Estimates" ) %> +
+
\ No newline at end of file diff --git a/booking/Views/FrontOffice/Estimate.aspx b/booking/Views/FrontOffice/Estimate.aspx new file mode 100644 index 00000000..1c2a3a90 --- /dev/null +++ b/booking/Views/FrontOffice/Estimate.aspx @@ -0,0 +1,357 @@ +<%@ Page Title="Devis" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> +<%@ Register Assembly="Yavsc.WebControls" TagPrefix="yavsc" Namespace="Yavsc.WebControls" %> + + + + + + +<%= Html.ValidationSummary("Devis") %> + +<% using (Html.BeginForm("Estimate","FrontOffice")) { %> +<%= Html.LabelFor(model => model.Title) %>:<%= Html.TextBox( "Title" ) %> +<%= Html.ValidationMessage("Title", "*") %> +
+<%= Html.Hidden ("Responsible") %> + +<%= Html.LabelFor(model => model.Client) %>: + + <% Client.Value = Model.Client ; %> + + + + <%= Html.ValidationMessage("Client", "*") %> +
+<%= Html.LabelFor(model => model.Description) %>:<%=Html.TextArea( "Description") %> +<%= Html.ValidationMessage("Description", "*") %> +
+<%= Html.Hidden( "Id" ) %> +
+<% if (Model.Id==0) { %> + +<% } else { %> + +<% } %> + + <% if (Model.Id>0) { %> + + + + + + + + + + + +<% int lc=0; + if (Model.Lines!=null) + foreach (Writting wr in Model.Lines) { lc++; %> +row" id="wr<%=wr.Id%>"> + + + + + + +<% } %> + +
<%=Yavsc.Model.LocalizedText.Description%><%=Yavsc.Model.LocalizedText.Product_reference%><%=Yavsc.Model.LocalizedText.Count%><%=Yavsc.Model.LocalizedText.Unitary_cost%>
<%=wr.Description%><%=wr.ProductReference%><%=wr.Count%><%=wr.UnitaryCost%> + +
+<% } %> +<% } %> + +
+ + + + + + + + \ No newline at end of file diff --git a/booking/Views/FrontOffice/Estimates.aspx b/booking/Views/FrontOffice/Estimates.aspx new file mode 100644 index 00000000..daaaeef0 --- /dev/null +++ b/booking/Views/FrontOffice/Estimates.aspx @@ -0,0 +1,24 @@ +<%@ Page Title="My estimates" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage>" %> + +<% if (((int)ViewData["ResponsibleCount"])>0) { %> +
+Les estimations que vous avez faites (<%=ViewData["ResponsibleCount"]%>):
+<% +foreach (Estimate estim in Model) { + if (string.Compare(estim.Responsible,(string) ViewData["UserName"])==0) { %> + + <%= Html.ActionLink("Titre:"+estim.Title+" Client:"+estim.Client,"Estimate",new{id=estim.Id}) %> +
+ <% }}%> +
+<% } %> +<% if (((int)ViewData["ClientCount"])>0) { %> +
+ Vos estimations en tant que client + (<%=ViewData["ClientCount"]%>):
+ <% foreach (Estimate estim in Model) { %> + <%= Html.ActionLink("Titre:"+estim.Title+" Responsable:"+estim.Responsible,"Estimate",new{id=estim.Id}) %> +
<% } %> +
+ <% } %> +
diff --git a/booking/Views/FrontOffice/EventPub.aspx b/booking/Views/FrontOffice/EventPub.aspx new file mode 100644 index 00000000..7b8ca523 --- /dev/null +++ b/booking/Views/FrontOffice/EventPub.aspx @@ -0,0 +1,20 @@ +<%@ Page Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + + + +<% using (Html.BeginForm()) { %> + +<%= Html.LabelFor(model => model.Title) %>: <%=Model.Title%>
+<%= Html.LabelFor(model => model.Description) %>: <%=Model.Description%>
+<%= Html.LabelFor(model => model.Location) %>: <%=Model.Location%>
+<%= Html.LabelFor(model => model.StartDate) %>: <%=Model.StartDate%>
+<%= Html.LabelFor(model => model.EndDate) %>: <%=Model.EndDate%>
+<%= Html.LabelFor(model => model.Circles) %>: <%=Model.Circles%>
+<%= Html.LabelFor(model => model.ImgLocator) %>: <%=Model.ImgLocator%>
+<%= Html.LabelFor(model => model.EventWebPage) %>: <%=Model.EventWebPage%>
+<%= Html.LabelFor(model => model.ProviderName) %>: <%=Model.ProviderName%>
+<%= Html.LabelFor(model => model.Comment) %>: <%=Model.Comment%>
+ +<% } %> + +
\ No newline at end of file diff --git a/booking/Views/FrontOffice/Index.aspx b/booking/Views/FrontOffice/Index.aspx new file mode 100644 index 00000000..42ce313e --- /dev/null +++ b/booking/Views/FrontOffice/Index.aspx @@ -0,0 +1,11 @@ +<%@ Page Title="Front office" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + + + + +
  • + <%= Html.ActionLink("Catalog","Catalog" ) %> +
  • + <%= Html.ActionLink("Estimates","Estimates" ) %> +
+
diff --git a/booking/Views/FrontOffice/Product.aspx b/booking/Views/FrontOffice/Product.aspx new file mode 100644 index 00000000..0182890f --- /dev/null +++ b/booking/Views/FrontOffice/Product.aspx @@ -0,0 +1,33 @@ +<%@ Page Title="Catalog" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + +<% Title = Model.Name; %> + + + +<%= Html.Encode(Model.Reference) %> + + +
+

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

+<% if (Model.Images!=null) foreach (ProductImage i in Model.Images) { %> +<%=i.Alt%> +<% } %> +<% if (Model.UnitaryPrice !=null) { %> +Prix unitaire : <%= Html.Encode(Model.UnitaryPrice.Quantity.ToString())%> +<%= Html.Encode(Model.UnitaryPrice.Unit.Name)%> +<% } else { %> Gratuit! <% } %> +
+
+ +<%= Html.CommandForm(Model,"Ajouter au panier") %> + +<% if (Model.CommandValidityDates!=null) { %> +Offre valable du <%= Model.CommandValidityDates.StartDate.ToString("dd/MM/yyyy") %> au +<%= Model.CommandValidityDates.EndDate.ToString("dd/MM/yyyy") %>. +<% } %> + +
+
diff --git a/booking/Views/FrontOffice/ProductCategory.aspx b/booking/Views/FrontOffice/ProductCategory.aspx new file mode 100644 index 00000000..de875d71 --- /dev/null +++ b/booking/Views/FrontOffice/ProductCategory.aspx @@ -0,0 +1,20 @@ +<%@ Page Title="Catalog" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + +<% foreach (Product p in Model.Products ) { %> + +

<%= Html.ActionLink( p.Name, "Product", new { id = ViewData["BrandId"], pc = Model.Reference , pref = p.Reference }, new { @class="actionlink" } ) %>

+ +

+ <%= p.Description %> + <% if (p.Images !=null) + foreach (ProductImage i in p.Images ) { %> + <%=i.Alt%> + <% } %> +

+ + + <% } %> + + +
diff --git a/booking/Views/FrontOffice/ReferenceNotFound.aspx b/booking/Views/FrontOffice/ReferenceNotFound.aspx new file mode 100644 index 00000000..51855ace --- /dev/null +++ b/booking/Views/FrontOffice/ReferenceNotFound.aspx @@ -0,0 +1,5 @@ +<%@ Page Title="Référence absente au catalogue" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + + + + diff --git a/booking/Views/FrontOffice/Service.aspx b/booking/Views/FrontOffice/Service.aspx new file mode 100644 index 00000000..34a787be --- /dev/null +++ b/booking/Views/FrontOffice/Service.aspx @@ -0,0 +1,31 @@ +<%@ Page Title="Catalog" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + +<% Title = ViewData ["BrandName"] + " " + Model.Name; %> + + +

<%=ViewData ["ProdCatName"]%> - <%= Html.ActionLink( Model.Name, "Product", new { id = ViewData ["BrandName"], pc = ViewData ["ProdCatRef"] , pref = Model.Reference } ) %>

+ +
+ +
+

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

+<% if (Model.Images!=null) foreach (ProductImage i in Model.Images) { %> +<%=i.Alt%> +<% } %> +<% if (Model.HourPrice !=null) { %> +Prix horaire de la prestation : +<%= Html.Encode(Model.HourPrice.Quantity.ToString())%> +<%= Html.Encode(Model.HourPrice.Unit.Name)%> +<% } %> +
+ +
+<%= Html.CommandForm(Model,"Ajouter au panier") %> + +<% if (Model.CommandValidityDates!=null) { %> +Offre valable du <%= Model.CommandValidityDates.StartDate.ToString("dd/MM/yyyy") %> au +<%= Model.CommandValidityDates.EndDate.ToString("dd/MM/yyyy") %>. +<% } %> + +
+
diff --git a/booking/Views/FrontOffice/Writting.ascx b/booking/Views/FrontOffice/Writting.ascx new file mode 100644 index 00000000..f7efe79c --- /dev/null +++ b/booking/Views/FrontOffice/Writting.ascx @@ -0,0 +1,25 @@ +<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> + +<%= Html.ValidationSummary("Ligne de devis") %> +<% using (Html.BeginForm("Write","WorkFlow")) { %> +
+<%= Html.Hidden( "Id" ) %> + +<%= Html.LabelFor(model => model.Description) %>:<%= Html.TextArea( "Description" ) %> +<%= Html.ValidationMessage("Description", "*", new { @id="Err_wr_Description", @class="error" }) %> +
+<%= Html.LabelFor(model => model.ProductReference) %>:<%= Html.TextBox( "ProductReference" ) %> +<%= Html.ValidationMessage("ProductReference", "*", new { @id="Err_wr_ProductReference", @class="error" }) %> +
+<%= Html.LabelFor(model => model.UnitaryCost) %>:<%= Html.TextBox( "UnitaryCost" ) %> +<%= Html.ValidationMessage("UnitaryCost", "", new { @id="Err_wr_UnitaryCost", @class="error" }) %> +
+<%= Html.LabelFor(model => model.Count) %>:<%= Html.TextBox( "Count" ) %> +<%= Html.ValidationMessage("Count", "", new { @id="Err_wr_Count" , @class="error"}) %> + +
+<% } %> + + + + diff --git a/booking/Views/Google/Auth.aspx b/booking/Views/Google/Auth.aspx new file mode 100644 index 00000000..48f10005 --- /dev/null +++ b/booking/Views/Google/Auth.aspx @@ -0,0 +1,6 @@ +<%@ Page Title="Catalog" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + +AccessToken : <%= Session["AccessToken"] %> +Target in error : <%= ViewData["TargetNameError"] %> + diff --git a/booking/Views/Google/Book.aspx b/booking/Views/Google/Book.aspx new file mode 100644 index 00000000..22683cce --- /dev/null +++ b/booking/Views/Google/Book.aspx @@ -0,0 +1,65 @@ +<%@ Page Title="Booking" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + + + + + + + + + + + + +<% using ( Html.BeginForm("Book","Google") ) { %> +
Date d'intervention : +Intervention souhaitée entre le + "> + <%= Html.ValidationMessageFor( model=>model.StartDate ) %> +et le + "> + <%= Html.ValidationMessageFor(model=>model.EndDate) %> +
+ Heure et durée d'intervention souhaitée +<%= Html.LabelFor(model=>model.StartHour) %> + + <%= Html.ValidationMessageFor(model=>model.StartHour) %> + +<%= Html.LabelFor(model=>model.EndHour) %> + + <%= Html.ValidationMessageFor(model=>model.EndHour) %> +
+
+Intervenant + <%= Html.LabelFor(model=>model.Role) %>: + <%= Html.TextBoxFor(model=>model.Role) %> + <%= Html.ValidationMessageFor(model=>model.Role) %> +
+ <%= Html.LabelFor(model=>model.Person) %>: + <%= Html.TextBoxFor(model=>model.Person) %> + <%= Html.ValidationMessageFor(model=>model.Person) %> +
+ + + +<% } %> +
diff --git a/booking/Views/Google/CalAuth.aspx b/booking/Views/Google/CalAuth.aspx new file mode 100644 index 00000000..7825a886 --- /dev/null +++ b/booking/Views/Google/CalAuth.aspx @@ -0,0 +1,5 @@ +<%@ Page Title="Catalog" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + + + diff --git a/booking/Views/Google/ChooseADate.aspx b/booking/Views/Google/ChooseADate.aspx new file mode 100644 index 00000000..63e3053a --- /dev/null +++ b/booking/Views/Google/ChooseADate.aspx @@ -0,0 +1,13 @@ +<%@ Page Title="Google calendar usage" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + + +<% using ( Html.BeginForm("ChooseAStartingDate","Google") ) { %> +<% foreach (Period e in Model.Values) { %> + +<% } %> +"> + +<% } %> + + diff --git a/booking/Views/Google/ChooseCalendar.aspx b/booking/Views/Google/ChooseCalendar.aspx new file mode 100644 index 00000000..9be76b57 --- /dev/null +++ b/booking/Views/Google/ChooseCalendar.aspx @@ -0,0 +1,17 @@ +<%@ Page Title="Google calendar usage" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + + +<% using ( Html.BeginForm("SetCalendar","Google") ) { %> + +
+<% foreach (CalendarListEntry e in Model.items.Where(x=>x.accessRole=="owner")) { %> + +
+<% } %> +"> + +<% } %> + +
diff --git a/booking/Views/Google/Index.aspx b/booking/Views/Google/Index.aspx new file mode 100644 index 00000000..93794753 --- /dev/null +++ b/booking/Views/Google/Index.aspx @@ -0,0 +1,4 @@ +<%@ Page Title="Google interface" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + + diff --git a/booking/Views/Google/OtherWebException.aspx b/booking/Views/Google/OtherWebException.aspx new file mode 100644 index 00000000..985fa792 --- /dev/null +++ b/booking/Views/Google/OtherWebException.aspx @@ -0,0 +1,9 @@ +<%@ 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/booking/Views/Home/AssemblyInfo.aspx b/booking/Views/Home/AssemblyInfo.aspx new file mode 100644 index 00000000..fabbd382 --- /dev/null +++ b/booking/Views/Home/AssemblyInfo.aspx @@ -0,0 +1,19 @@ +<%@ Page Title="Assemblies" Language="C#" Inherits="System.Web.Mvc.ViewPage>" MasterPageFile="~/Models/App.master"%> + +
+

+Running assembly : +<%= GetType().Assembly.FullName %>

+
+
+

+Assemblies referenced in this application : +

+
    +<% foreach (System.Reflection.AssemblyName item in Model) { %> +
  • <%= item.FullName %>
  • +<% } %> +
+
+
+ diff --git a/booking/Views/Home/Contact.aspx b/booking/Views/Home/Contact.aspx new file mode 100644 index 00000000..0c30f7cc --- /dev/null +++ b/booking/Views/Home/Contact.aspx @@ -0,0 +1,37 @@ +<%@ Page Title="Contact" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + + +
+

+Directeur :
+Adresse postale :
+Tél. : +33
+Tél. : +33
+SIREN :
+SIRET :
+Activité Principalement Exercée (APE) :
+

+<% using (Html.BeginForm("Contact", "Home")) { %> +
+Message +

+<%= Html.Label("email") %>: +<%= Html.ValidationMessage("email") %>
+<%= Html.TextBox("email") %> +

+

+<%= Html.Label("reason") %>: +<%= Html.ValidationMessage("reason") %>
+<%= Html.TextBox("reason") %> +

+

+<%= Html.Label("body") %>: +<%= Html.ValidationMessage("body") %>
+<%= Html.TextArea("body") %> +

+
+"> + +<% } %> +
+
\ No newline at end of file diff --git a/booking/Views/Home/Credits.aspx b/booking/Views/Home/Credits.aspx new file mode 100644 index 00000000..d9bd9381 --- /dev/null +++ b/booking/Views/Home/Credits.aspx @@ -0,0 +1,5 @@ +<%@ Page Title="Credits" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + + +
Icons made by Vectorgraphit from www.flaticon.com is licensed by CC BY 3.0
+
diff --git a/booking/Views/Home/Index.aspx b/booking/Views/Home/Index.aspx new file mode 100644 index 00000000..7e24cb2f --- /dev/null +++ b/booking/Views/Home/Index.aspx @@ -0,0 +1,16 @@ +<%@ Page Title="Home" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master"%> + +<%= Html.Partial("TagPanel",ViewData["Accueil"]) %> +<%= Html.Partial("TagPanel",ViewData["Événements"]) %> +<%= Html.Partial("TagPanel",ViewData["Mentions légales"]) %> + + + +
+<%= Html.ActionLink("Les articles", "Index", "Blogs") %> +<%= Html.ActionLink("Contact", "Contact", "Home", null, new { @class="actionlink" }) %> +<%= Html.ActionLink("Credits", "Credits", "Home", null, new { @class="actionlink" }) %> +<%= Html.ActionLink("Version des librairies", "AssemblyInfo", "Home", null, new { @class="actionlink" }) %> +
+
+ diff --git a/booking/Views/Home/TagPanel.ascx b/booking/Views/Home/TagPanel.ascx new file mode 100644 index 00000000..450c3739 --- /dev/null +++ b/booking/Views/Home/TagPanel.ascx @@ -0,0 +1,13 @@ +<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> +
+

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

+<% foreach (var t in Model.Titles) { %> + +<% } %> +
diff --git a/booking/Views/Web.config b/booking/Views/Web.config new file mode 100644 index 00000000..db86717b --- /dev/null +++ b/booking/Views/Web.config @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/booking/Views/WorkFlow/Index.aspx b/booking/Views/WorkFlow/Index.aspx new file mode 100644 index 00000000..a70bbb42 --- /dev/null +++ b/booking/Views/WorkFlow/Index.aspx @@ -0,0 +1,9 @@ +<%@ Page Title="Workflow" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master"%> + + +
+<%= Html.ActionLink("blogs","Index","WorkFlow") %> +
+ +
+ diff --git a/booking/Views/WorkFlow/NewProject.aspx b/booking/Views/WorkFlow/NewProject.aspx new file mode 100644 index 00000000..00167a19 --- /dev/null +++ b/booking/Views/WorkFlow/NewProject.aspx @@ -0,0 +1,20 @@ +<%@ Page Title="Nouveau projet" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + +
+<%= Html.ValidationSummary("Nouveau projet") %> +<% using ( Html.BeginForm("NewProject", "WorkFlow") ) { %> +<%= Html.LabelFor(model => model.Name) %> : +<%= Html.TextBox( "Name" ) %> +<%= Html.ValidationMessage("Name", "*") %>
+<%= Html.LabelFor(model => model.Manager) %> : +<%= Html.TextBox( "Manager" ) %> +<%= Html.ValidationMessage("Manager", "*") %>
+<%= Html.LabelFor(model => model.Description) %> : +<%= Html.TextBox( "Description" ) %> +<%= Html.ValidationMessage("Description", "*") %>
+ +<% } %> +
+
+ + diff --git a/booking/Web.config b/booking/Web.config new file mode 100644 index 00000000..ac56993e --- /dev/null +++ b/booking/Web.config @@ -0,0 +1,269 @@ + + + + + + +
+ +
+
+
+
+ + + +
+ +
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/booking/WebApiConfig.cs b/booking/WebApiConfig.cs new file mode 100644 index 00000000..1f01b584 --- /dev/null +++ b/booking/WebApiConfig.cs @@ -0,0 +1,66 @@ +// +// WebApiConfig.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.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using System.Web.Routing; +using Yavsc.Formatters; +using Yavsc.Model.FrontOffice; +using System.Web.Http; + +namespace Yavsc +{ + /// + /// Web API config. + /// + public static class WebApiConfig + { + /// + /// Gets the URL prefix. + /// + /// The URL prefix. + public static string UrlPrefix { get { return "api"; } } + + /// + /// Gets the URL prefix relative. + /// + /// The URL prefix relative. + public static string UrlPrefixRelative { get { return "~/api"; } } + + /// + /// Register the specified config. + /// + /// Config. + public static void Register(HttpConfiguration config) + { + config.Routes.MapHttpRoute( + name: "DefaultApi", + routeTemplate: WebApiConfig.UrlPrefix + "/{controller}/{action}/{id}", + defaults: new { action="Index", id = RouteParameter.Optional } + ); + } + } + +} diff --git a/booking/booking.csproj b/booking/booking.csproj new file mode 100644 index 00000000..748ed188 --- /dev/null +++ b/booking/booking.csproj @@ -0,0 +1,295 @@ + + + + Debug + AnyCPU + {349C5851-65DF-11DA-9384-00065B846F21};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 8.0.30703 + 2.0 + {8B39864D-D427-41EC-939B-BA23FBAEE396} + Library + booking + booking + v4.5 + + + true + full + false + bin + DEBUG; + prompt + 4 + false + + + full + true + bin + prompt + 4 + false + + + + + + + + + + + + + + + + ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll + + + ..\packages\Microsoft.AspNet.Mvc.5.2.0\lib\net45\System.Web.Mvc.dll + + + + ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll + + + ..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll + + + ..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll + + + ..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll + + + ..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll + + + ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll + + + ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll + + + ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll + + + ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll + + + + ..\web\lib\MarkdownDeep.dll + + + + ..\packages\PayPalCoreSDK.1.6.3\lib\net45\PayPalCoreSDK.dll + + + ..\packages\PayPalButtonManagerSDK.2.9.109\lib\net20\PayPalButtonManagerSDK.dll + + + ..\packages\PayPal.1.6.0\lib\net45\PayPal.dll + + + ..\packages\PayPalAdaptiveAccountsSDK.2.8.110\lib\net20\PayPalAdaptiveAccountsSDK.dll + + + ..\packages\Npgsql.3.0.3\lib\net45\Npgsql.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Global.asax + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ..\..\web\templates\Estim.tt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {68F5B80A-616E-4C3C-91A0-828AA40000BD} + YavscModel + + + {C6E9E91B-97D3-48D9-8AA7-05356929E162} + NpgsqlBlogProvider + + + {821FF72D-9F4B-4A2C-B95C-7B965291F119} + NpgsqlContentProvider + + + {BBA7175D-7F92-4278-96FC-84C495A2B5A6} + NpgsqlMRPProviders + + + {9D7D892E-9B77-4713-892D-C26E1E944119} + ITContentProvider + + + {90BF2234-7252-4CD5-B2A4-17501B19279B} + SalesCatalog + + + + + TextTemplatingFilePreprocessor + Estim.cs + + + \ No newline at end of file diff --git a/booking/packages.config b/booking/packages.config new file mode 100644 index 00000000..88ed482a --- /dev/null +++ b/booking/packages.config @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/booking/robots.txt b/booking/robots.txt new file mode 100644 index 00000000..9c664a25 --- /dev/null +++ b/booking/robots.txt @@ -0,0 +1,7 @@ + +User-agent: * +Disallow: /Google/Login +Disallow: /Account/Login +Disallow: /Admin/ +Disallow: /App_Themes/ +Disallow: /Scripts/ diff --git a/booking/templates/Estim.cs b/booking/templates/Estim.cs new file mode 100644 index 00000000..3c973e6f --- /dev/null +++ b/booking/templates/Estim.cs @@ -0,0 +1,1033 @@ +// ------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Mono Runtime Version: 4.0.30319.17020 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ + +namespace Yavsc.templates { + using System.Linq; + using System.Text; + using System.Collections.Generic; + using Yavsc.Model.WorkFlow; + using Yavsc.Model.RolesAndMembers; + using System; + + + public partial class Estim : EstimBase { + + private Estimate _estimField; + public Estimate estim { + get { + return this._estimField; + } + } + private Profile _fromField; + public Profile from { + get { + return this._fromField; + } + } + private Profile _toField; + public Profile to { + get { + return this._toField; + } + } + private String _efromField; + public String efrom { + get { + return this._efromField; + } + } + private String _etoField; + public String eto { + get { + return this._etoField; + } + } + + + public virtual string TransformText() { + this.GenerationEnvironment = null; + + #line 10 "" + this.Write("\n"); + + #line default + #line hidden + + #line 16 "" + this.Write("\n\\documentclass[french,11pt]{article}\n\\usepackage{babel}\n\\usepackage[T1]{fontenc}\n\\usepackage[utf8]{inputenc}\n\\usepackage[a4paper]{geometry}\n\\usepackage{units}\n\\usepackage{bera}\n\\usepackage{graphicx}\n\\usepackage{fancyhdr}\n\\usepackage{fp}\n\n\\def\\TVA{20} % Taux de la TVA\n\n\\def\\TotalHT{0}\n\\def\\TotalTVA{0}\n\n\\newcommand{\\AjouterService}[3]{% Arguments : Désignation, quantité, prix\n \\FPround{\\prix}{#3}{2}\n \\FPeval{\\montant}{#2 * #3}\n \\FPround{\\montant}{\\montant}{2}\n \\FPadd{\\TotalHT}{\\TotalHT}{\\montant}\n \n \\eaddto\\ListeProduits{#1 & \\prix & #2 & \\montant \\cr}\n}\n\n\n\\newcommand{\\AfficheResultat}{%\n \\ListeProduits\n \n \\FPeval{\\TotalTVA}{\\TotalHT * \\TVA / 100}\n \\FPadd{\\TotalTTC}{\\TotalHT}{\\TotalTVA}\n \\FPround{\\TotalHT}{\\TotalHT}{2}\n \\FPround{\\TotalTVA}{\\TotalTVA}{2}\n \\FPround{\\TotalTTC}{\\TotalTTC}{2}\n \\global\\let\\TotalHT\\TotalHT\n \\global\\let\\TotalTVA\\TotalTVA\n \\global\\let\\TotalTTC\\TotalTTC\n \n\n \\cr \n \\hline\n \\textbf{Total} & & & \\TotalHT\n}\n\n\\newcommand*\\eaddto[2]{% version développée de \\addto\n \\edef\\tmp{#2}%\n \\expandafter\\addto\n \\expandafter#1%\n \\expandafter{\\tmp}%\n}\n\n\\newcommand{\\ListeProduits}{}\n\n\n\n\n%%%%%%%%%%%%%%%%%%%%% A MODIFIER DANS LA FACTURE %%%%%%%%%%%%%%%%%%%%%\n\n\\def\\FactureNum {"); + + #line default + #line hidden + + #line 75 "" + this.Write(this.ToStringHelper.ToStringWithCulture( estim.Id.ToString() )); + + #line default + #line hidden + + #line 75 "" + this.Write("} % Numéro de facture\n\\def\\FactureAcquittee {non} % Facture acquittée : oui/non\n\\def\\FactureLieu {"); + + #line default + #line hidden + + #line 77 "" + this.Write(this.ToStringHelper.ToStringWithCulture( from.CityAndState )); + + #line default + #line hidden + + #line 77 "" + this.Write("} % Lieu de l'édition de la facture\n\\def\\FactureObjet {Facture : "); + + #line default + #line hidden + + #line 78 "" + this.Write(this.ToStringHelper.ToStringWithCulture( estim.Title )); + + #line default + #line hidden + + #line 78 "" + this.Write("} % Objet du document\n% Description de la facture\n\\def\\FactureDescr {%\n "); + + #line default + #line hidden + + #line 81 "" + this.Write(this.ToStringHelper.ToStringWithCulture( estim.Description )); + + #line default + #line hidden + + #line 81 "" + this.Write("\n}\n\n% Infos Client\n\\def\\ClientNom{"); + + #line default + #line hidden + + #line 85 "" + this.Write(this.ToStringHelper.ToStringWithCulture( to.Name )); + + #line default + #line hidden + + #line 85 "" + this.Write("} % Nom du client\n\\def\\ClientAdresse{% % Adresse du client\n "); + + #line default + #line hidden + + #line 87 "" + if (!string.IsNullOrWhiteSpace(to.Address)) { + + #line default + #line hidden + + #line 88 "" + this.Write(" "); + + #line default + #line hidden + + #line 88 "" + this.Write(this.ToStringHelper.ToStringWithCulture( to.Address )); + + #line default + #line hidden + + #line 88 "" + this.Write("\\\\\n "); + + #line default + #line hidden + + #line 89 "" + } + + #line default + #line hidden + + #line 90 "" + this.Write(" "); + + #line default + #line hidden + + #line 90 "" + if (!string.IsNullOrWhiteSpace(to.ZipCode)) { + + #line default + #line hidden + + #line 91 "" + this.Write(" "); + + #line default + #line hidden + + #line 91 "" + this.Write(this.ToStringHelper.ToStringWithCulture( to.ZipCode )); + + #line default + #line hidden + + #line 91 "" + this.Write(" "); + + #line default + #line hidden + + #line 91 "" + } + + #line default + #line hidden + + #line 92 "" + this.Write(" "); + + #line default + #line hidden + + #line 92 "" + if (!string.IsNullOrWhiteSpace(to.ZipCode)) { + + #line default + #line hidden + + #line 93 "" + this.Write(" "); + + #line default + #line hidden + + #line 93 "" + this.Write(this.ToStringHelper.ToStringWithCulture( to.CityAndState )); + + #line default + #line hidden + + #line 93 "" + this.Write("\\\\ "); + + #line default + #line hidden + + #line 93 "" + } + + #line default + #line hidden + + #line 94 "" + this.Write(" \n"); + + #line default + #line hidden + + #line 95 "" + if (!string.IsNullOrWhiteSpace(to.Phone)) { + + #line default + #line hidden + + #line 96 "" + this.Write(" Téléphone fixe: "); + + #line default + #line hidden + + #line 96 "" + this.Write(this.ToStringHelper.ToStringWithCulture( to.Phone )); + + #line default + #line hidden + + #line 96 "" + this.Write("\\\\\n"); + + #line default + #line hidden + + #line 97 "" + } + + #line default + #line hidden + + #line 98 "" + if (!string.IsNullOrWhiteSpace(to.Mobile)) { + + #line default + #line hidden + + #line 99 "" + this.Write(" Mobile: "); + + #line default + #line hidden + + #line 99 "" + this.Write(this.ToStringHelper.ToStringWithCulture( to.Mobile )); + + #line default + #line hidden + + #line 99 "" + this.Write("\\\\\n"); + + #line default + #line hidden + + #line 100 "" + } + + #line default + #line hidden + + #line 101 "" + this.Write(" "); + + #line default + #line hidden + + #line 101 "" + if (!string.IsNullOrWhiteSpace(eto)) { + + #line default + #line hidden + + #line 102 "" + this.Write(" E-mail: "); + + #line default + #line hidden + + #line 102 "" + this.Write(this.ToStringHelper.ToStringWithCulture( eto )); + + #line default + #line hidden + + #line 102 "" + } + + #line default + #line hidden + + #line 103 "" + this.Write("}\n\n% Liste des produits facturés : Désignation, prix\n\n "); + + #line default + #line hidden + + #line 107 "" + foreach (Writting wr in estim.Lines) { + + #line default + #line hidden + + #line 108 "" + this.Write("\\AjouterService {"); + + #line default + #line hidden + + #line 108 "" + this.Write(this.ToStringHelper.ToStringWithCulture(wr.Description)); + + #line default + #line hidden + + #line 108 "" + this.Write(" "); + + #line default + #line hidden + + #line 108 "" + if (!string.IsNullOrWhiteSpace(wr.ProductReference)) { + + #line default + #line hidden + + #line 109 "" + this.Write(" ("); + + #line default + #line hidden + + #line 109 "" + this.Write(this.ToStringHelper.ToStringWithCulture(wr.ProductReference)); + + #line default + #line hidden + + #line 109 "" + this.Write(")"); + + #line default + #line hidden + + #line 109 "" + } + + #line default + #line hidden + + #line 110 "" + this.Write("} {"); + + #line default + #line hidden + + #line 110 "" + this.Write(this.ToStringHelper.ToStringWithCulture(wr.Count)); + + #line default + #line hidden + + #line 110 "" + this.Write("} {"); + + #line default + #line hidden + + #line 110 "" + this.Write(this.ToStringHelper.ToStringWithCulture(wr.UnitaryCost)); + + #line default + #line hidden + + #line 110 "" + this.Write("} \n "); + + #line default + #line hidden + + #line 111 "" + } + + #line default + #line hidden + + #line 112 "" + this.Write("\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n\\geometry{verbose,tmargin=4em,bmargin=8em,lmargin=6em,rmargin=6em}\n\\setlength{\\parindent}{0pt}\n\\setlength{\\parskip}{1ex plus 0.5ex minus 0.2ex}\n\n\\thispagestyle{fancy}\n\\pagestyle{fancy}\n\\setlength{\\parindent}{0pt}\n\n\\renewcommand{\\headrulewidth}{0pt}\n\\cfoot{\n "); + + #line default + #line hidden + + #line 125 "" + if (!string.IsNullOrWhiteSpace(from.Name)) { + + #line default + #line hidden + + #line 126 "" + this.Write(this.ToStringHelper.ToStringWithCulture( from.Name )); + + #line default + #line hidden + + #line 126 "" + } + + #line default + #line hidden + + #line 127 "" + this.Write(" "); + + #line default + #line hidden + + #line 127 "" + if (!string.IsNullOrWhiteSpace(from.Address)) { + + #line default + #line hidden + + #line 128 "" + this.Write(" - "); + + #line default + #line hidden + + #line 128 "" + this.Write(this.ToStringHelper.ToStringWithCulture( from.Address )); + + #line default + #line hidden + + #line 128 "" + } + + #line default + #line hidden + + #line 129 "" + this.Write(" \n "); + + #line default + #line hidden + + #line 130 "" + if (!string.IsNullOrWhiteSpace(from.CityAndState)) { + + #line default + #line hidden + + #line 131 "" + this.Write(" - "); + + #line default + #line hidden + + #line 131 "" + this.Write(this.ToStringHelper.ToStringWithCulture( from.CityAndState )); + + #line default + #line hidden + + #line 131 "" + } + + #line default + #line hidden + + #line 132 "" + this.Write(" \\newline\n \\small{\n "); + + #line default + #line hidden + + #line 134 "" + if (!string.IsNullOrWhiteSpace(efrom)) { + + #line default + #line hidden + + #line 135 "" + this.Write("E-mail: "); + + #line default + #line hidden + + #line 135 "" + this.Write(this.ToStringHelper.ToStringWithCulture( efrom )); + + #line default + #line hidden + + #line 135 "" + } + + #line default + #line hidden + + #line 136 "" + this.Write(" "); + + #line default + #line hidden + + #line 136 "" + if (!string.IsNullOrWhiteSpace(from.Mobile)) { + + #line default + #line hidden + + #line 137 "" + this.Write(" - Téléphone mobile: "); + + #line default + #line hidden + + #line 137 "" + this.Write(this.ToStringHelper.ToStringWithCulture( from.Mobile )); + + #line default + #line hidden + + #line 137 "" + } + + #line default + #line hidden + + #line 138 "" + this.Write(" "); + + #line default + #line hidden + + #line 138 "" + if (!string.IsNullOrWhiteSpace(from.Phone)) { + + #line default + #line hidden + + #line 139 "" + this.Write(" - Téléphone fixe: "); + + #line default + #line hidden + + #line 139 "" + this.Write(this.ToStringHelper.ToStringWithCulture( from.Phone )); + + #line default + #line hidden + + #line 139 "" + } + + #line default + #line hidden + + #line 140 "" + this.Write(" }\n}\n\n\\begin{document}\n\n% Logo de la société\n%\\includegraphics{logo.jpg}\n\n% Nom et adresse de la société\n"); + + #line default + #line hidden + + #line 149 "" + this.Write(this.ToStringHelper.ToStringWithCulture( from.Name )); + + #line default + #line hidden + + #line 149 "" + this.Write("\\\\\n"); + + #line default + #line hidden + + #line 150 "" + this.Write(this.ToStringHelper.ToStringWithCulture( from.Address )); + + #line default + #line hidden + + #line 150 "" + this.Write("\\\\\n"); + + #line default + #line hidden + + #line 151 "" + this.Write(this.ToStringHelper.ToStringWithCulture(from.ZipCode )); + + #line default + #line hidden + + #line 151 "" + this.Write(" "); + + #line default + #line hidden + + #line 151 "" + this.Write(this.ToStringHelper.ToStringWithCulture(from.CityAndState)); + + #line default + #line hidden + + #line 151 "" + this.Write("\\\\\n\nFacture n°\\FactureNum\n\n\n{\\addtolength{\\leftskip}{10.5cm} %in ERT\n \\textbf{\\ClientNom} \\\\\n \\ClientAdresse \\\\\n\n} %in ERT\n\n\n\\hspace*{10.5cm}\n\\FactureLieu, le \\today\n\n~\\\\~\\\\\n\n\\textbf{Objet : \\FactureObjet \\\\}\n\n\\textnormal{\\FactureDescr}\n\n~\\\\\n\n\\begin{center}\n \\begin{tabular}{lrrr}\n \\textbf{Désignation ~~~~~~} & \\textbf{Prix unitaire} & \\textbf{Quantité} & \\textbf{Montant (EUR)} \\\\\n \\hline\n \\AfficheResultat{}\n \\end{tabular}\n\\end{center}\n\n\\begin{flushright}\n\\textit{Auto entreprise en franchise de TVA}\\\\\n\n\\end{flushright}\n~\\\\\n\n\\ifthenelse{\\equal{\\FactureAcquittee}{oui}}{\n Facture acquittée.\n}{\n\n À régler par chèque ou par virement bancaire :\n\n \\begin{center}\n \\begin{tabular}{|c c c c|}\n "); + + #line default + #line hidden + + #line 196 "" + if (!string.IsNullOrWhiteSpace(from.BankCode) && !string.IsNullOrWhiteSpace(from.WicketCode) + && !string.IsNullOrWhiteSpace(from.AccountNumber) ) { + + #line default + #line hidden + + #line 198 "" + this.Write(" \\hline \\textbf{Code banque} & \\textbf{Code guichet} & \\textbf{N° de Compte} & \\textbf{Clé RIB} \\\\\n "); + + #line default + #line hidden + + #line 199 "" + this.Write(this.ToStringHelper.ToStringWithCulture( from.BankCode )); + + #line default + #line hidden + + #line 199 "" + this.Write(" & "); + + #line default + #line hidden + + #line 199 "" + this.Write(this.ToStringHelper.ToStringWithCulture( from.WicketCode )); + + #line default + #line hidden + + #line 199 "" + this.Write(" & "); + + #line default + #line hidden + + #line 199 "" + this.Write(this.ToStringHelper.ToStringWithCulture(from.AccountNumber )); + + #line default + #line hidden + + #line 199 "" + this.Write(" & "); + + #line default + #line hidden + + #line 199 "" + this.Write(this.ToStringHelper.ToStringWithCulture(from.BankedKey)); + + #line default + #line hidden + + #line 199 "" + this.Write(" \\\\\n "); + + #line default + #line hidden + + #line 200 "" + } + if (!string.IsNullOrWhiteSpace(from.IBAN) && !string.IsNullOrWhiteSpace(from.BIC)) { + + #line default + #line hidden + + #line 202 "" + this.Write(" \\hline \\textbf{IBAN N°} & \\multicolumn{3}{|l|}{ "); + + #line default + #line hidden + + #line 202 "" + this.Write(this.ToStringHelper.ToStringWithCulture( from.IBAN )); + + #line default + #line hidden + + #line 202 "" + this.Write(" } \\\\\n \\hline \\textbf{Code BIC} & \\multicolumn{3}{|l|}{ "); + + #line default + #line hidden + + #line 203 "" + this.Write(this.ToStringHelper.ToStringWithCulture( from.BIC )); + + #line default + #line hidden + + #line 203 "" + this.Write(" }\n "); + + #line default + #line hidden + + #line 204 "" + } + + #line default + #line hidden + + #line 205 "" + this.Write(" \\\\\n \\hline\n \\end{tabular}\n \\end{center}\n}\n\\end{document}\n"); + + #line default + #line hidden + return this.GenerationEnvironment.ToString(); + } + + public virtual void Initialize() { + if ((this.Errors.HasErrors == false)) { + bool _estimAcquired = false; + if (((this.Session != null) && this.Session.ContainsKey("estim"))) { + object data = this.Session["estim"]; + if (typeof(Estimate).IsAssignableFrom(data.GetType())) { + this._estimField = ((Estimate)(data)); + _estimAcquired = true; + } + else { + this.Error("The type 'Estimate' of the parameter 'estim' did not match the type passed to the template"); + } + } + if ((_estimAcquired == false)) { + object data = System.Runtime.Remoting.Messaging.CallContext.LogicalGetData("estim"); + if ((data != null)) { + if (typeof(Estimate).IsAssignableFrom(data.GetType())) { + this._estimField = ((Estimate)(data)); + _estimAcquired = true; + } + else { + this.Error("The type 'Estimate' of the parameter 'estim' did not match the type passed to the template"); + } + } + } + bool _fromAcquired = false; + if (((this.Session != null) && this.Session.ContainsKey("from"))) { + object data = this.Session["from"]; + if (typeof(Profile).IsAssignableFrom(data.GetType())) { + this._fromField = ((Profile)(data)); + _fromAcquired = true; + } + else { + this.Error("The type 'Profile' of the parameter 'from' did not match the type passed to the template"); + } + } + if ((_fromAcquired == false)) { + object data = System.Runtime.Remoting.Messaging.CallContext.LogicalGetData("from"); + if ((data != null)) { + if (typeof(Profile).IsAssignableFrom(data.GetType())) { + this._fromField = ((Profile)(data)); + _fromAcquired = true; + } + else { + this.Error("The type 'Profile' of the parameter 'from' did not match the type passed to the template"); + } + } + } + bool _toAcquired = false; + if (((this.Session != null) && this.Session.ContainsKey("to"))) { + object data = this.Session["to"]; + if (typeof(Profile).IsAssignableFrom(data.GetType())) { + this._toField = ((Profile)(data)); + _toAcquired = true; + } + else { + this.Error("The type 'Profile' of the parameter 'to' did not match the type passed to the template"); + } + } + if ((_toAcquired == false)) { + object data = System.Runtime.Remoting.Messaging.CallContext.LogicalGetData("to"); + if ((data != null)) { + if (typeof(Profile).IsAssignableFrom(data.GetType())) { + this._toField = ((Profile)(data)); + _toAcquired = true; + } + else { + this.Error("The type 'Profile' of the parameter 'to' did not match the type passed to the template"); + } + } + } + bool _efromAcquired = false; + if (((this.Session != null) && this.Session.ContainsKey("efrom"))) { + object data = this.Session["efrom"]; + if (typeof(String).IsAssignableFrom(data.GetType())) { + this._efromField = ((String)(data)); + _efromAcquired = true; + } + else { + this.Error("The type 'String' of the parameter 'efrom' did not match the type passed to the template"); + } + } + if ((_efromAcquired == false)) { + object data = System.Runtime.Remoting.Messaging.CallContext.LogicalGetData("efrom"); + if ((data != null)) { + if (typeof(String).IsAssignableFrom(data.GetType())) { + this._efromField = ((String)(data)); + _efromAcquired = true; + } + else { + this.Error("The type 'String' of the parameter 'efrom' did not match the type passed to the template"); + } + } + } + bool _etoAcquired = false; + if (((this.Session != null) && this.Session.ContainsKey("eto"))) { + object data = this.Session["eto"]; + if (typeof(String).IsAssignableFrom(data.GetType())) { + this._etoField = ((String)(data)); + _etoAcquired = true; + } + else { + this.Error("The type 'String' of the parameter 'eto' did not match the type passed to the template"); + } + } + if ((_etoAcquired == false)) { + object data = System.Runtime.Remoting.Messaging.CallContext.LogicalGetData("eto"); + if ((data != null)) { + if (typeof(String).IsAssignableFrom(data.GetType())) { + this._etoField = ((String)(data)); + _etoAcquired = true; + } + else { + this.Error("The type 'String' of the parameter 'eto' did not match the type passed to the template"); + } + } + } + } + + } + } + + public class EstimBase { + + private global::System.Text.StringBuilder builder; + + private global::System.Collections.Generic.IDictionary session; + + private global::System.CodeDom.Compiler.CompilerErrorCollection errors; + + private string currentIndent = string.Empty; + + private global::System.Collections.Generic.Stack indents; + + private ToStringInstanceHelper _toStringHelper = new ToStringInstanceHelper(); + + public virtual global::System.Collections.Generic.IDictionary Session { + get { + return this.session; + } + set { + this.session = value; + } + } + + public global::System.Text.StringBuilder GenerationEnvironment { + get { + if ((this.builder == null)) { + this.builder = new global::System.Text.StringBuilder(); + } + return this.builder; + } + set { + this.builder = value; + } + } + + protected global::System.CodeDom.Compiler.CompilerErrorCollection Errors { + get { + if ((this.errors == null)) { + this.errors = new global::System.CodeDom.Compiler.CompilerErrorCollection(); + } + return this.errors; + } + } + + public string CurrentIndent { + get { + return this.currentIndent; + } + } + + private global::System.Collections.Generic.Stack Indents { + get { + if ((this.indents == null)) { + this.indents = new global::System.Collections.Generic.Stack(); + } + return this.indents; + } + } + + public ToStringInstanceHelper ToStringHelper { + get { + return this._toStringHelper; + } + } + + public void Error(string message) { + this.Errors.Add(new global::System.CodeDom.Compiler.CompilerError(null, -1, -1, null, message)); + } + + public void Warning(string message) { + global::System.CodeDom.Compiler.CompilerError val = new global::System.CodeDom.Compiler.CompilerError(null, -1, -1, null, message); + val.IsWarning = true; + this.Errors.Add(val); + } + + public string PopIndent() { + if ((this.Indents.Count == 0)) { + return string.Empty; + } + int lastPos = (this.currentIndent.Length - this.Indents.Pop()); + string last = this.currentIndent.Substring(lastPos); + this.currentIndent = this.currentIndent.Substring(0, lastPos); + return last; + } + + public void PushIndent(string indent) { + this.Indents.Push(indent.Length); + this.currentIndent = (this.currentIndent + indent); + } + + public void ClearIndent() { + this.currentIndent = string.Empty; + this.Indents.Clear(); + } + + public void Write(string textToAppend) { + this.GenerationEnvironment.Append(textToAppend); + } + + public void Write(string format, params object[] args) { + this.GenerationEnvironment.AppendFormat(format, args); + } + + public void WriteLine(string textToAppend) { + this.GenerationEnvironment.Append(this.currentIndent); + this.GenerationEnvironment.AppendLine(textToAppend); + } + + public void WriteLine(string format, params object[] args) { + this.GenerationEnvironment.Append(this.currentIndent); + this.GenerationEnvironment.AppendFormat(format, args); + this.GenerationEnvironment.AppendLine(); + } + + public class ToStringInstanceHelper { + + private global::System.IFormatProvider formatProvider = global::System.Globalization.CultureInfo.InvariantCulture; + + public global::System.IFormatProvider FormatProvider { + get { + return this.formatProvider; + } + set { + if ((value != null)) { + this.formatProvider = value; + } + } + } + + public string ToStringWithCulture(object objectToConvert) { + if ((objectToConvert == null)) { + throw new global::System.ArgumentNullException("objectToConvert"); + } + global::System.Type type = objectToConvert.GetType(); + global::System.Type iConvertibleType = typeof(global::System.IConvertible); + if (iConvertibleType.IsAssignableFrom(type)) { + return ((global::System.IConvertible)(objectToConvert)).ToString(this.formatProvider); + } + global::System.Reflection.MethodInfo methInfo = type.GetMethod("ToString", new global::System.Type[] { + iConvertibleType}); + if ((methInfo != null)) { + return ((string)(methInfo.Invoke(objectToConvert, new object[] { + this.formatProvider}))); + } + return objectToConvert.ToString(); + } + } + } +} diff --git a/booking/templates/Estim.tt b/booking/templates/Estim.tt new file mode 100644 index 00000000..3629333e --- /dev/null +++ b/booking/templates/Estim.tt @@ -0,0 +1,197 @@ +<#@ template language="C#" #> +<#@ output extension=".tex" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="$(SolutionDir)/web/bin/YavscModel.dll" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="Yavsc.Model.WorkFlow" #> +<#@ import namespace="Yavsc.Model.RolesAndMembers" #> + +<#@ parameter type="Estimate" name="estim" #> +<#@ parameter type="Profile" name="from" #> +<#@ parameter type="Profile" name="to" #> +<#@ parameter type="String" name="efrom" #> +<#@ parameter type="String" name="eto" #> + +\documentclass[french,11pt]{article} +\usepackage{babel} +\usepackage[T1]{fontenc} +\usepackage[utf8]{inputenc} +\usepackage[a4paper]{geometry} +\usepackage{units} +\usepackage{bera} +\usepackage{graphicx} +\usepackage{fancyhdr} +\usepackage{fp} + +\def\TVA{20} % Taux de la TVA + +\def\TotalHT{0} +\def\TotalTVA{0} + +\newcommand{\AjouterService}[3]{% Arguments : Désignation, quantité, prix + \FPround{\prix}{#3}{2} + \FPeval{\montant}{#2 * #3} + \FPround{\montant}{\montant}{2} + \FPadd{\TotalHT}{\TotalHT}{\montant} + + \eaddto\ListeProduits{#1 & \prix & #2 & \montant \cr} +} + + +\newcommand{\AfficheResultat}{% + \ListeProduits + + \FPeval{\TotalTVA}{\TotalHT * \TVA / 100} + \FPadd{\TotalTTC}{\TotalHT}{\TotalTVA} + \FPround{\TotalHT}{\TotalHT}{2} + \FPround{\TotalTVA}{\TotalTVA}{2} + \FPround{\TotalTTC}{\TotalTTC}{2} + \global\let\TotalHT\TotalHT + \global\let\TotalTVA\TotalTVA + \global\let\TotalTTC\TotalTTC + + + \cr + \hline + \textbf{Total} & & & \TotalHT +} + +\newcommand*\eaddto[2]{% version développée de \addto + \edef\tmp{#2}% + \expandafter\addto + \expandafter#1% + \expandafter{\tmp}% +} + +\newcommand{\ListeProduits}{} + + + + +%%%%%%%%%%%%%%%%%%%%% A MODIFIER DANS LA FACTURE %%%%%%%%%%%%%%%%%%%%% + +\def\FactureNum {<#= estim.Id.ToString() #>} % Numéro de facture +\def\FactureAcquittee {non} % Facture acquittée : oui/non +\def\FactureLieu {<#= from.CityAndState #>} % Lieu de l'édition de la facture +\def\FactureObjet {Facture : <#= estim.Title #>} % Objet du document +% Description de la facture +\def\FactureDescr {% + <#= estim.Description #> +} + +% Infos Client +\def\ClientNom{<#= to.Name #>} % Nom du client +\def\ClientAdresse{% % Adresse du client + <# if (!string.IsNullOrWhiteSpace(to.Address)) { #> + <#= to.Address #>\\ + <# } #> <# if (!string.IsNullOrWhiteSpace(to.ZipCode)) { #> + <#= to.ZipCode #> <# } #> <# if (!string.IsNullOrWhiteSpace(to.ZipCode)) { #> + <#= to.CityAndState #>\\ <# } #> +<# if (!string.IsNullOrWhiteSpace(to.Phone)) { #> + Téléphone fixe: <#= to.Phone #>\\ +<# } #> +<# if (!string.IsNullOrWhiteSpace(to.Mobile)) { #> + Mobile: <#= to.Mobile #>\\ +<# } #> + <# if (!string.IsNullOrWhiteSpace(eto)) { #> + E-mail: <#= eto #><# } #> +} + +% Liste des produits facturés : Désignation, prix + + <# foreach (Writting wr in estim.Lines) { #> +\AjouterService {<#=wr.Description#> <# if (!string.IsNullOrWhiteSpace(wr.ProductReference)) { #> + (<#=wr.ProductReference#>)<# } #>} {<#=wr.Count#>} {<#=wr.UnitaryCost#>} + <# } #> + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\geometry{verbose,tmargin=4em,bmargin=8em,lmargin=6em,rmargin=6em} +\setlength{\parindent}{0pt} +\setlength{\parskip}{1ex plus 0.5ex minus 0.2ex} + +\thispagestyle{fancy} +\pagestyle{fancy} +\setlength{\parindent}{0pt} + +\renewcommand{\headrulewidth}{0pt} +\cfoot{ + <# if (!string.IsNullOrWhiteSpace(from.Name)) { #><#= from.Name #><# } #> + <# if (!string.IsNullOrWhiteSpace(from.Address)) { #> - <#= from.Address #><# } #> + <# if (!string.IsNullOrWhiteSpace(from.CityAndState)) { #> - <#= from.CityAndState #><# } #> \newline + \small{ + <# if (!string.IsNullOrWhiteSpace(efrom)) { #>E-mail: <#= efrom #><# } #> + <# if (!string.IsNullOrWhiteSpace(from.Mobile)) { #> - Téléphone mobile: <#= from.Mobile #><# } #> + <# if (!string.IsNullOrWhiteSpace(from.Phone)) { #> - Téléphone fixe: <#= from.Phone #><# } #> + } +} + +\begin{document} + +% Logo de la société +%\includegraphics{logo.jpg} + +% Nom et adresse de la société +<#= from.Name #>\\ +<#= from.Address #>\\ +<#=from.ZipCode #> <#=from.CityAndState#>\\ + +Facture n°\FactureNum + + +{\addtolength{\leftskip}{10.5cm} %in ERT + \textbf{\ClientNom} \\ + \ClientAdresse \\ + +} %in ERT + + +\hspace*{10.5cm} +\FactureLieu, le \today + +~\\~\\ + +\textbf{Objet : \FactureObjet \\} + +\textnormal{\FactureDescr} + +~\\ + +\begin{center} + \begin{tabular}{lrrr} + \textbf{Désignation ~~~~~~} & \textbf{Prix unitaire} & \textbf{Quantité} & \textbf{Montant (EUR)} \\ + \hline + \AfficheResultat{} + \end{tabular} +\end{center} + +\begin{flushright} +\textit{Auto entreprise en franchise de TVA}\\ + +\end{flushright} +~\\ + +\ifthenelse{\equal{\FactureAcquittee}{oui}}{ + Facture acquittée. +}{ + + À régler par chèque ou par virement bancaire : + + \begin{center} + \begin{tabular}{|c c c c|} + <# if (!string.IsNullOrWhiteSpace(from.BankCode) && !string.IsNullOrWhiteSpace(from.WicketCode) + && !string.IsNullOrWhiteSpace(from.AccountNumber) ) { #> + \hline \textbf{Code banque} & \textbf{Code guichet} & \textbf{N° de Compte} & \textbf{Clé RIB} \\ + <#= from.BankCode #> & <#= from.WicketCode #> & <#=from.AccountNumber #> & <#=from.BankedKey#> \\ + <# } + if (!string.IsNullOrWhiteSpace(from.IBAN) && !string.IsNullOrWhiteSpace(from.BIC)) { #> + \hline \textbf{IBAN N°} & \multicolumn{3}{|l|}{ <#= from.IBAN #> } \\ + \hline \textbf{Code BIC} & \multicolumn{3}{|l|}{ <#= from.BIC #> } + <# } #> \\ + \hline + \end{tabular} + \end{center} +} +\end{document} diff --git a/booking/templates/TexEstimInit.cs b/booking/templates/TexEstimInit.cs new file mode 100644 index 00000000..72a3f9fd --- /dev/null +++ b/booking/templates/TexEstimInit.cs @@ -0,0 +1,36 @@ +// +// TexEstimInit.cs +// +// Author: +// Paul Schneider +// +// 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 . +using System; + +namespace Yavsc.templates +{ + public partial class Estim + { + /// + /// Inits this instance. + /// + public void Init () + { + this.Initialize(); + } + } +} + diff --git a/booking/web.config b/booking/web.config new file mode 100644 index 00000000..00baa9d2 --- /dev/null +++ b/booking/web.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/totem-banner.xxs.xcf b/totem-banner.xxs.xcf deleted file mode 100644 index d07a0c0f..00000000 Binary files a/totem-banner.xxs.xcf and /dev/null differ diff --git a/totem.xcf b/totem.xcf deleted file mode 100644 index ea4a62a3..00000000 Binary files a/totem.xcf and /dev/null differ diff --git a/web/ApiControllers/AccountController.cs b/web/ApiControllers/AccountController.cs index f2523aa8..397113b0 100644 --- a/web/ApiControllers/AccountController.cs +++ b/web/ApiControllers/AccountController.cs @@ -104,5 +104,13 @@ namespace Yavsc.ApiControllers if (user != null && ModelState.IsValid) Url.SendActivationMessage (user); } + + [ValidateAjax] + [Authorize(Roles="Admin")] + public void AddUserToRole(UserRole model) + { + Roles.AddUserToRole (model.UserName, model.Role); + } + } } diff --git a/web/ApiControllers/BlogsController.cs b/web/ApiControllers/BlogsController.cs index 81615953..5290f2c0 100644 --- a/web/ApiControllers/BlogsController.cs +++ b/web/ApiControllers/BlogsController.cs @@ -14,6 +14,9 @@ using System.Diagnostics; using Yavsc.Formatters; using Yavsc.Model; + + + namespace Yavsc.ApiControllers { /// @@ -143,19 +146,45 @@ namespace Yavsc.ApiControllers /// /// Create the specified blog entry. /// - /// Bp. + /// Bp. [Authorize, HttpPost] - public long Create (BasePost bp) + public long Post (BlogEntry be) { - return BlogManager.Post (User.Identity.Name, bp.Title, "", bp.Visible, null); + if (be.Id == 0) + return BlogManager.Post (User.Identity.Name, be.Title, + be.Content, be.Visible,be.AllowedCircles ); + else + BlogManager.UpdatePost (be); + return 0; + } + /// + /// Blog entry rating. + /// + public class BlogEntryRating { + /// + /// Gets or sets the post identifier. + /// + /// The post identifier. + public long Id { get; set; } + /// + /// Gets or sets the rate. + /// + /// The rate. + public int Rate { get; set; } } - [Authorize, HttpPost] - public void Note (long id, int note) + /// + /// Rate the specified model. + /// + /// Model. + [Authorize(Roles="Moderator"), HttpPost, ValidateAjax] + public void Rate (BlogEntryRating model) { - if (note < 0 || note > 100) - throw new ArgumentException ("0<=note<=100"); - BlogManager.Note (id, note); + if (model.Rate < 0 || model.Rate > 100) + ModelState.AddModelError ("Rate", "0<=Rate<=100"); + else { + BlogManager.Rate (model.Id, model.Rate); + } } /// /// Searchs the file. @@ -176,7 +205,7 @@ namespace Yavsc.ApiControllers [Authorize, HttpPost, ValidateAjaxAttribute] public void SetPhoto(long id, [FromBody] string photo) { - BlogManager.Provider.UpdatePostPhoto (id, photo); + BlogManager.UpdatePostPhoto (id, photo); } /// diff --git a/web/ApiControllers/FrontOfficeController.cs b/web/ApiControllers/FrontOfficeController.cs index a2079981..2b13ba51 100644 --- a/web/ApiControllers/FrontOfficeController.cs +++ b/web/ApiControllers/FrontOfficeController.cs @@ -22,7 +22,7 @@ namespace Yavsc.ApiControllers /// /// Front office controller. /// - public class FrontOfficeController : ApiController + public class FrontOfficeController : YavscController { /// /// The wfmgr. diff --git a/web/ApiControllers/GCMController.cs b/web/ApiControllers/GCMController.cs index 69e992b8..722fee79 100644 --- a/web/ApiControllers/GCMController.cs +++ b/web/ApiControllers/GCMController.cs @@ -23,8 +23,14 @@ using System.Web.Http; namespace Yavsc.ApiControllers { + /// + /// GCM controller. + /// public class GCMController : ApiController { + /// + /// Initializes a new instance of the class. + /// public GCMController () { } diff --git a/web/ApiControllers/YavscController.cs b/web/ApiControllers/YavscController.cs index ab43ed44..76b9b471 100644 --- a/web/ApiControllers/YavscController.cs +++ b/web/ApiControllers/YavscController.cs @@ -25,15 +25,27 @@ using System.Web.Profile; namespace Yavsc.ApiControllers { + /// + /// Yavsc controller. + /// public class YavscController : ApiController { + /// + /// Initializes a new instance of the class. + /// public YavscController () { } + /// + /// Auth. + /// public class Auth { public string Id { get; set; } } - + /// + /// Allows the cookies. + /// + /// Model. public void AllowCookies (Auth model) { // TODO check Auth when existing @@ -43,7 +55,10 @@ namespace Yavsc.ApiControllers pr.Save (); } } - + /// + /// Defaults the response. + /// + /// The response. protected HttpResponseMessage DefaultResponse() { return ModelState.IsValid ? diff --git a/web/App_Data/Sql/instdbws.sql b/web/App_Data/Sql/instdbws.sql index 5ce9cdab..647ab8d6 100644 --- a/web/App_Data/Sql/instdbws.sql +++ b/web/App_Data/Sql/instdbws.sql @@ -123,6 +123,7 @@ CREATE TABLE profiledata gcalapi boolean NOT NULL DEFAULT false, gregid character varying(1024), -- Google Cloud Message registration identifier allowcookies boolean NOT NULL DEFAULT false, + uitheme character varying(64), CONSTRAINT fkprofiles2 FOREIGN KEY (uniqueid) REFERENCES profiles (uniqueid) MATCH SIMPLE ON UPDATE CASCADE ON DELETE CASCADE @@ -176,7 +177,7 @@ CREATE TABLE blog visible boolean NOT NULL, _id bigserial NOT NULL, photo character varying(512), -- a photo url, supposed to be the main photo... - note integer NOT NULL DEFAULT 50, -- a global note for this entry, between 0 and 100 + rate integer NOT NULL DEFAULT 50, -- a global note for this entry, between 0 and 100 CONSTRAINT blog_pkey PRIMARY KEY (_id), CONSTRAINT bloguser FOREIGN KEY (applicationname, username) REFERENCES users (applicationname, username) MATCH SIMPLE diff --git a/web/App_Themes/dark/images/ui-bg_glass_20_555555_1x400.png b/web/App_Themes/dark/images/ui-bg_glass_20_555555_1x400.png index 6ffeab9d..ea805f98 100644 Binary files a/web/App_Themes/dark/images/ui-bg_glass_20_555555_1x400.png and b/web/App_Themes/dark/images/ui-bg_glass_20_555555_1x400.png differ diff --git a/web/App_Themes/dark/images/ui-bg_glass_40_0078a3_1x400.png b/web/App_Themes/dark/images/ui-bg_glass_40_0078a3_1x400.png index dc5a6bf5..58fdcfe7 100644 Binary files a/web/App_Themes/dark/images/ui-bg_glass_40_0078a3_1x400.png and b/web/App_Themes/dark/images/ui-bg_glass_40_0078a3_1x400.png differ diff --git a/web/App_Themes/dark/images/ui-bg_glass_40_ffc73d_1x400.png b/web/App_Themes/dark/images/ui-bg_glass_40_ffc73d_1x400.png index 72a035d5..05575c0f 100644 Binary files a/web/App_Themes/dark/images/ui-bg_glass_40_ffc73d_1x400.png and b/web/App_Themes/dark/images/ui-bg_glass_40_ffc73d_1x400.png differ diff --git a/web/App_Themes/dark/images/ui-bg_gloss-wave_25_333333_500x100.png b/web/App_Themes/dark/images/ui-bg_gloss-wave_25_333333_500x100.png index 670b844f..fa9479fd 100644 Binary files a/web/App_Themes/dark/images/ui-bg_gloss-wave_25_333333_500x100.png and b/web/App_Themes/dark/images/ui-bg_gloss-wave_25_333333_500x100.png differ diff --git a/web/App_Themes/dark/images/ui-bg_highlight-soft_80_eeeeee_1x100.png b/web/App_Themes/dark/images/ui-bg_highlight-soft_80_eeeeee_1x100.png index cce32824..e1adedd1 100644 Binary files a/web/App_Themes/dark/images/ui-bg_highlight-soft_80_eeeeee_1x100.png and b/web/App_Themes/dark/images/ui-bg_highlight-soft_80_eeeeee_1x100.png differ diff --git a/web/App_Themes/dark/images/ui-bg_inset-soft_25_000000_1x100.png b/web/App_Themes/dark/images/ui-bg_inset-soft_25_000000_1x100.png index b9f22318..242f12ba 100644 Binary files a/web/App_Themes/dark/images/ui-bg_inset-soft_25_000000_1x100.png and b/web/App_Themes/dark/images/ui-bg_inset-soft_25_000000_1x100.png differ diff --git a/web/App_Themes/dark/images/ui-bg_inset-soft_30_f58400_1x100.png b/web/App_Themes/dark/images/ui-bg_inset-soft_30_f58400_1x100.png index 6db83f8e..d91945b4 100644 Binary files a/web/App_Themes/dark/images/ui-bg_inset-soft_30_f58400_1x100.png and b/web/App_Themes/dark/images/ui-bg_inset-soft_30_f58400_1x100.png differ diff --git a/web/App_Themes/dark/images/ui-icons_222222_256x240.png b/web/App_Themes/dark/images/ui-icons_222222_256x240.png index e9c8e16a..8a188cb6 100644 Binary files a/web/App_Themes/dark/images/ui-icons_222222_256x240.png and b/web/App_Themes/dark/images/ui-icons_222222_256x240.png differ diff --git a/web/App_Themes/dark/images/ui-icons_4b8e0b_256x240.png b/web/App_Themes/dark/images/ui-icons_4b8e0b_256x240.png index 3b237fba..512a87b7 100644 Binary files a/web/App_Themes/dark/images/ui-icons_4b8e0b_256x240.png and b/web/App_Themes/dark/images/ui-icons_4b8e0b_256x240.png differ diff --git a/web/App_Themes/dark/images/ui-icons_a83300_256x240.png b/web/App_Themes/dark/images/ui-icons_a83300_256x240.png index 4e7008e0..c3008c6a 100644 Binary files a/web/App_Themes/dark/images/ui-icons_a83300_256x240.png and b/web/App_Themes/dark/images/ui-icons_a83300_256x240.png differ diff --git a/web/App_Themes/dark/images/ui-icons_cccccc_256x240.png b/web/App_Themes/dark/images/ui-icons_cccccc_256x240.png index 9fdc41a9..d5a2d82e 100644 Binary files a/web/App_Themes/dark/images/ui-icons_cccccc_256x240.png and b/web/App_Themes/dark/images/ui-icons_cccccc_256x240.png differ diff --git a/web/App_Themes/dark/images/ui-icons_ffffff_256x240.png b/web/App_Themes/dark/images/ui-icons_ffffff_256x240.png index 4d66f596..6126c4e3 100644 Binary files a/web/App_Themes/dark/images/ui-icons_ffffff_256x240.png and b/web/App_Themes/dark/images/ui-icons_ffffff_256x240.png differ diff --git a/web/App_Themes/images/star-939235_1280.xxs.jpg b/web/App_Themes/images/star-939235_1280.xxs.jpg index 9ddad28f..ac2772a2 100644 Binary files a/web/App_Themes/images/star-939235_1280.xxs.jpg and b/web/App_Themes/images/star-939235_1280.xxs.jpg differ diff --git a/web/App_Themes/images/ui-bg_glass_20_555555_1x400.png b/web/App_Themes/images/ui-bg_glass_20_555555_1x400.png index 6ffeab9d..ea805f98 100644 Binary files a/web/App_Themes/images/ui-bg_glass_20_555555_1x400.png and b/web/App_Themes/images/ui-bg_glass_20_555555_1x400.png differ diff --git a/web/App_Themes/images/ui-bg_glass_40_0078a3_1x400.png b/web/App_Themes/images/ui-bg_glass_40_0078a3_1x400.png index dc5a6bf5..58fdcfe7 100644 Binary files a/web/App_Themes/images/ui-bg_glass_40_0078a3_1x400.png and b/web/App_Themes/images/ui-bg_glass_40_0078a3_1x400.png differ diff --git a/web/App_Themes/images/ui-bg_glass_40_ffc73d_1x400.png b/web/App_Themes/images/ui-bg_glass_40_ffc73d_1x400.png index 72a035d5..05575c0f 100644 Binary files a/web/App_Themes/images/ui-bg_glass_40_ffc73d_1x400.png and b/web/App_Themes/images/ui-bg_glass_40_ffc73d_1x400.png differ diff --git a/web/App_Themes/images/ui-bg_gloss-wave_25_333333_500x100.png b/web/App_Themes/images/ui-bg_gloss-wave_25_333333_500x100.png index 670b844f..fa9479fd 100644 Binary files a/web/App_Themes/images/ui-bg_gloss-wave_25_333333_500x100.png and b/web/App_Themes/images/ui-bg_gloss-wave_25_333333_500x100.png differ diff --git a/web/App_Themes/images/ui-bg_highlight-soft_80_eeeeee_1x100.png b/web/App_Themes/images/ui-bg_highlight-soft_80_eeeeee_1x100.png index cce32824..e1adedd1 100644 Binary files a/web/App_Themes/images/ui-bg_highlight-soft_80_eeeeee_1x100.png and b/web/App_Themes/images/ui-bg_highlight-soft_80_eeeeee_1x100.png differ diff --git a/web/App_Themes/images/ui-bg_inset-soft_25_000000_1x100.png b/web/App_Themes/images/ui-bg_inset-soft_25_000000_1x100.png index b9f22318..242f12ba 100644 Binary files a/web/App_Themes/images/ui-bg_inset-soft_25_000000_1x100.png and b/web/App_Themes/images/ui-bg_inset-soft_25_000000_1x100.png differ diff --git a/web/App_Themes/images/ui-bg_inset-soft_30_f58400_1x100.png b/web/App_Themes/images/ui-bg_inset-soft_30_f58400_1x100.png index 6db83f8e..d91945b4 100644 Binary files a/web/App_Themes/images/ui-bg_inset-soft_30_f58400_1x100.png and b/web/App_Themes/images/ui-bg_inset-soft_30_f58400_1x100.png differ diff --git a/web/App_Themes/images/ui-icons_222222_256x240.png b/web/App_Themes/images/ui-icons_222222_256x240.png index e9c8e16a..8a188cb6 100644 Binary files a/web/App_Themes/images/ui-icons_222222_256x240.png and b/web/App_Themes/images/ui-icons_222222_256x240.png differ diff --git a/web/App_Themes/images/ui-icons_4b8e0b_256x240.png b/web/App_Themes/images/ui-icons_4b8e0b_256x240.png index 3b237fba..512a87b7 100644 Binary files a/web/App_Themes/images/ui-icons_4b8e0b_256x240.png and b/web/App_Themes/images/ui-icons_4b8e0b_256x240.png differ diff --git a/web/App_Themes/images/ui-icons_a83300_256x240.png b/web/App_Themes/images/ui-icons_a83300_256x240.png index 4e7008e0..c3008c6a 100644 Binary files a/web/App_Themes/images/ui-icons_a83300_256x240.png and b/web/App_Themes/images/ui-icons_a83300_256x240.png differ diff --git a/web/App_Themes/images/ui-icons_cccccc_256x240.png b/web/App_Themes/images/ui-icons_cccccc_256x240.png index 9fdc41a9..d5a2d82e 100644 Binary files a/web/App_Themes/images/ui-icons_cccccc_256x240.png and b/web/App_Themes/images/ui-icons_cccccc_256x240.png differ diff --git a/web/App_Themes/images/ui-icons_ffffff_256x240.png b/web/App_Themes/images/ui-icons_ffffff_256x240.png index 4d66f596..6126c4e3 100644 Binary files a/web/App_Themes/images/ui-icons_ffffff_256x240.png and b/web/App_Themes/images/ui-icons_ffffff_256x240.png differ diff --git a/web/App_Themes/style.css b/web/App_Themes/style.css index 4277faf2..e5c25f52 100644 --- a/web/App_Themes/style.css +++ b/web/App_Themes/style.css @@ -1,14 +1,12 @@ body { - background-color: black; - color: #D0FFD0; font-family: 'Arial', cursive; padding: 0; margin: 0; } -.tagname { color: #D0FFD0; } + .tagname+.tagname:before { content: ', '; } -.tagname:hover { background-color: red; cursor:pointer; } +.tagname:hover { cursor:pointer; } /* Start by setting display:none to make this hidden. Then we position it in relation to the viewport window @@ -36,6 +34,7 @@ body { left: 0; right: 0; width: 100%; + max-height: 100%; overflow-y: auto; overflow-x: hidden; } @@ -49,67 +48,21 @@ body.loading .modal { } .iconsmall { max-height: 1.3em; max-width: 1.3em; } -input, textarea, checkbox { - color: #FFFFA0; - background-color: black; - } - .photo { width: 100%; } .blogbanner { float: left; top:0; } .subtitle { font-size:small; font-style: italic; } -header { -transition: margin 2s, padding 2s; - padding: 0; - margin: 0; - padding-top: 2em; - padding-bottom:2em; - display: block; - background: url("/App_Themes/images/star-939235_1280.jpg") -3em -3em no-repeat fixed; - } -header h1, header a { -transition:padding 2s; -background-color: rgba(0,0,0,.5); -margin:0; padding:1em; -} -nav { -transition: margin 2s, padding 2s; - margin: 2em; - padding: 2em; - display: block; - border-radius:1em; - background: url("/App_Themes/images/helix-nebula-1400x1400.s.jpg") 50% 10% repeat fixed ; - justify-content: space-around; -} + nav li { display: inline-block; } -main { -transition: margin 2s, padding 2s; - margin: 2em; - padding: 2em; - display: block; - border-radius:1em; - background: url("/App_Themes/images/p8-av4.png") 50% 20em no-repeat fixed ; - } -footer { -transition: margin 2s, padding 2s; - background: url("/App_Themes/images/helix-nebula-1400x1400.s.jpg") 50% 90% repeat fixed ; - margin: 0; - margin-top: 2em; - padding: 2em; - display: block; - clear: both; - font-size: smaller; - justify-content: space-around; -} footer a { border-radius:1em; padding:1em; } + legend { border-radius:5px; padding:.5em; - background-color: rgba(0,0,32,.5); } #copyr { text-align: center; display: block; background-color: rgba(20,20,20,.8); } footer p { display:inline-block; } @@ -126,179 +79,30 @@ fieldset { border-radius:5px; border: solid 1px #000060; } -main video, main img { - max-width:100%; - max-height:75%; - padding: 1em; - } - -aside { - display: inline-block; - float: right; - max-width: 40em; -} - -.postpreview { - display: inline-block; - max-width: 40em; - padding: 1em; - background-color: rgba(0,0,32,0.8); - border-radius:1em; -} -.postpreview video, .postpreview img { - max-width: 100%; - padding: 1em; - } -.post { - display:block; - padding: 1em; - background-color: rgba(0,0,32,0.8); - color: #eee; - border-radius:1em; - } -.hiddenpost { background-color: rgba(16,16,16,0.5); } -.fullwidth { width: 100%; } - -textarea.fullwidth { min-height:10em; } - -.thanks { - max-width: 10%; - text-align: center; - font-size:smaller; - display:inline; - bottom:0; -} -.panel { -display:inline-block; - } - -.panel,.bshpanel, aside { - background-color: rgba(20,20,20,.8); - border-radius: 1em; - padding: 1em; -} -.spanel { - max-width: 18em; - display: inline-block; - padding: .3em; -} -.xspanel { - max-width:13em; - display: inline-block; - padding:.2em; -} -.xxspanel { - max-width:7em; - display: inline-block; - padding:.1em; -} -.hint { - display: inline; - font-style: italic; - font-size: smaller; -} -.hint::before { -content: "("; -} -.hint::after { -content: ")"; -} - - -.usertitleref { - border-radius: 1em; - background-color:rgba(0,0,32,0.6); - font-family: 'Arial', cursive; - padding: 1em; -} -label { - font-size: medium; -} -.editable { - margin: .5em; - min-height:1em; - border-radius: 1em; - border: dashed rgb(020,20,256) 2px; -} - -.notification { - font-size: large; - background-color: rgba(64,64,0,0.5); - border: solid green 1px; - padding: 1em; - border-radius:1em; - margin:1em; - padding:1em; - } -.dirty { - background-color: rgba(128,128,0,0.5); -} -.error, #error { - color: #f88; - font-size: large; - background-color: rgba(256,0,0,0.5); -} -.validation-summary-errors{ - color: #f88; - background-color: rgba(256,0,0,0.5); -} - -.hidden { display:none; } - -ul.preview li:nth-child(-n+10) { - display:inline; - font-size:xx-small; -} - -ul.preview li:nth-child(n) { - display:none; -} - -.validation-summary-errors{ - color: #f88; -} - -a { - text-decoration: none; -} - .actionlink, .menuitem, a { display:inline-block; - color: yellow; border-radius:1em; - border: solid black 1px; - background-color: rgba(20,20,20,.8); + border-style: solid; + border-width:1px; cursor: pointer; font-family: 'Arial', cursive; padding: 1em; } input, select, textarea { - color: white; - background-color:rgba(0,0,64,0.8); - border: solid 1px rgb(128,128,128); border-radius:1em; + border-style: solid; + border-width:1px; + font-family: 'Arial', cursive; } - a:hover { - background-color:rgba(30,0,124,0.9); - border: solid green 1px; -} -a:active { - background-color:rgba(124,0,32,0.9); -} - - input:hover, textarea:hover { - color: white; - background-color:rgba(64,64,64,0.8); -} .code { font-family: "monospace"; - background-color: rgba(0,0,256,0.1); border-radius:25px; white-space: pre-wrap; } + #avatar { float: left; margin:1em; @@ -320,18 +124,31 @@ a:active { padding:5px; margin:5px; background-color: rgba(0,0,40,.8); } - -.input-validation-error { border: solid 1px red; } -.field-validation-error { color: red; } +.skillname { +padding:.5em; +margin:.25em; + max-width: 24em; + text-align: center; +display: inline-block; + background-color: rgba(16,16,64,0.8); + border-radius:1em; + border: solid 1px #aaf; + } +.input-validation-error { border: solid 1px red; background-color: rgba(180,256,256,.5); } +.field-validation-error { color: red; background-color: rgba(180,256,256,.5); } .c2 { font-size: small; font-style: italic; } .c3 { font-size: x-small; font-style: italic; } + +.rate { width:5em; cursor: pointer; text-align:center; } +h2 select { font-size: large; } + @media print { body {background-color:white;color:black;} .control, .actionlink, .menuitem, nav { display:none;} } - .bshpanel { display:block; } + .bshpanel { display: inline-block; } .bsh { display: none; } .c3 { display:initial; } .c3-alt { display:none; } @@ -373,6 +190,8 @@ header h1, header a , .actionlink, .menuitem, a { padding:.5em;} border-radius:.5em; margin:.5em; padding:.5em; + max-height: 100%; + overflow-y: auto; } .menuitem { display: block; @@ -423,3 +242,4 @@ header h1, header a { padding:.2em;} .c2-alt { display:initial; } } + diff --git a/web/ChangeLog b/web/ChangeLog index d6285fc3..aa32038d 100644 --- a/web/ChangeLog +++ b/web/ChangeLog @@ -1,945 +1,665 @@ -2015-11-04 Paul Schneider +2015-11-17 Paul Schneider - * Web.csproj: - * AppAdmin.master: - * AddRole.aspx: + * RateControl.ascx: A rate control for the Front Office + + * UserCard.ascx: WIP UserCard + + * FrontOfficeController.cs: restricts the Skills view to + Admins, + uses the new PerformerProfile object + + * Edit.aspx: + * Title.aspx: + * Profile.aspx: + * Skills.aspx: + * Estimate.aspx: the `aside` html node is better placed at the + top of the content, + overall when it's floating. + + * PostActions.ascx: code formatting + + * UserSkills.aspx: Uses the new `PerformerProfile` object + + + * Web.csproj: adds a skill view, + WIP UserCard + +2015-11-17 Paul Schneider + + * yavsc.skills.js: Implements skills Ajax methods + + * RateControl.ascx: + * RateSkillControl.ascx: + * RateUserSkillControl.ascx: refactorization + + * UserSkills.aspx: Implements a site user's skills view + + * BlogsController.cs: Refactorization, with skill and + userskills ratings + + * GCMController.cs: xml doc + + * SkillController.cs: implements a skill controller + + * Skills.sql: defines the skill data model + + * style.css: mainly adds the `rate` css class + + * style.css: adds rate & skill name style + + * AuthorizeAttribute.cs: * OAuth2.cs: - * RoleList.aspx: - * UsersInRole.aspx: - * AdminController.cs: - * AddMemberToRole.ascx: + * FormatterException.cs: xmldoc -2015-11-04 Paul Schneider + * FrontOfficeController.cs: implements an user's skills method + + * App.master: code formatting + + * yavsc.rate.js: Makes it a JQuery module + + * EventPub.aspx: no more ImgLocator ... I don't remember why. + + * Skills.aspx: Implements a site wize skills view + + * Web.config: imports the skill model name space + + * Web.config: SkillProvider section and code formatting + +2015-11-14 Paul Schneider + + * SkillController.cs: WIP Skill interface + + * Skills.sql: WIP skills + + * star.gif: + * rateit.css: + * delete.gif: + * AuthorizeAttribute.cs: + * AddRole.aspx: + * jquery.rateit.js: + * jquery.validate.js: + * jquery.rateit.min.js: + * HomeController.cs: + * jquery.validate.min.js: + * BlogsController.cs: + * GoogleHelpers.cs: + * GoogleController.cs: + * jquery.validate-vsdoc.js: + * jquery.rateit.min.js.map: + * FrontOfficeController.cs: + + * Skills.aspx: + * RateControl.ascx: WIP lists skils + + * Contact.template.aspx: a default contact page + + * Contact.totem.aspx: the totem contact page + + * BlogsController.cs: Uniformize the creation/modificaton + action profiles: + * no more `Create` action + * The Post action creates or updates. + + * FrontOfficeController.cs: The FE controller is a Yavsc one. * instdbws.sql: - * BlogsController.cs: Implements the note + * RateControl.ascx: refactoring - * robots.txt: + * yavsc.rate.js: the default treatment in case of error is the + same. + + * Circles.aspx: + * Index.aspx: + * UsersInRole.aspx: MAS disapeared + + * Index.aspx: + * Basket.aspx: + * Command.aspx: + * Estimate.aspx: MAS disparition + + * Contact.aspx: My information + + * Index.aspx: This site could talk about Yavsc + + * RestrictedArea.aspx: A customized restricted area wall, with + a security hole? + + * Web.csproj: fixes the `Deploy` compilation target + + * WebDeploy.targets: My `DirectorySepartionChar` is a slash + ... It's prettier to me. + + * packages.config: We don't need jQuery.RateIt ... it's + perhaps awesome, I not yet know nor for a while. + +2015-11-11 Paul Schneider + + * App.master: + * NoLogin.master: + * AppAdmin.master: master pages sync + +2015-11-11 Paul Schneider + + * style.css: + * style.css: removes the themable code, + it goes to the dark theme. + + * yavsc.rate.js: rates using the web API + + * UserCard.ascx: WIP UserCard + + * RateControl.ascx: + * RateControl.ascx.cs: implements a rate control + + * BlogsController.cs: implements a rating API on Blog spot + + * AccountController.cs: Saves the user's theme at profile + edition + + * AdminController.cs: Enrols users + + * HomeController.cs: there's still no artiste here. + + * App.master: Uses a page theme + + * yavsc.circles.js: cleaning + + * yavsc.js: some enhancement + + * yavsc.tags.js: adds a new line :-) + + * Profile.aspx: offers the theme choice + + * AddUserToRole.ascx: Implements the enrolment + + * Admin.aspx: code formatting + + * UserList.aspx: lists user's roles and link to enrol + + * UsersInRole.aspx: a more relevant title, and a list as html + `UL` node + + * PostActions.ascx: adds on control on rate + + * Index.aspx: Fixes the latest merge + + * Web.csproj: references the rating control + + * ChooseMedia.aspx: useless + + * Web.config: configures the `UITheme` profile property + +2015-11-08 Paul Schneider + + * helix-nebula.l.jpg: + * helix-nebula.s.jpg: + * helix-nebula.xs.jpg: helix nebula in new sizes + + * Web.config: hides my info on Google + + * facebook.png: a facebook icon, in case of + +2015-11-06 Paul Schneider + + * ChangeLog: * Web.csproj: * Web.config: - * Catalog.xml: - * Global.asax.cs: * pgsql.xcf: - * pgsql.jpeg: * p8-av4.png: + * pgsql.jpeg: + * logo-1.jpg: + * App.master: * logoDev.png: * logoDev.xcf: - * apache_pb.gif: - * style.css: - * theme.css: + * datepair.js: * debian-pb.gif: + * apache_pb.gif: * apache_pbw.gif: * apache_pby.gif: + * Index.aspx: + * Index.aspx: + * Title.aspx: * Book.aspx: - * jquery-ui.css: - * Login.aspx: + * Auth.aspx: + * AppAdmin.master: + * datepair.min.js: + * Index.aspx: + * Book.aspx: + * TagPanel.ascx: + * CalAuth.aspx: + * instdbws.sql: + * date.js: + * TagPanel.ascx: * debian-powered.png: + * YavscAjaxHelper.cs: + * logo.jpg: + * UserPosts.aspx: + * jquery.datepair.js: * FhHRx.gif: - * TagControl.ascx: + * number.js: + * plural.js: * pgsql.png: - * jquery-ui.min.css: - * theme.css: + * totem.jpg: + * TagControl.ascx: + * RemoveRole.aspx: + * twiter.png: + * logo.s.png: + * jquery-1.11.3.min.js: + * UsersInRole.aspx: + * logo-1.png: + * PostActions.ascx: + * message.js: + * logo.xs.png: + * currency.js: + * ChooseADate.aspx: + * facebook.png: * noavatar.png: + * logo.xxs.png: * p8-av4.s.jpg: - * p8-av4.xxs.jpg: + * jquery.datepair.min.js: + * globalize.js: + * totemprod.png: + * p8-av4.xxs.png: * apache_pbw.png: + * AddMemberToRole.ascx: + * p8-av4.xxs.jpg: + * ChooseCalendar.aspx: + * YavscController.cs: * debian-logo.png: + * relative-time.js: + * totem-banner.png: * Mono-powered.png: + * OtherWebException.aspx: + * concert.clear.jpg: * helix-nebula-1400x1400.l.jpg: + * totem-banner.xs.jpg: * star-939235_1280.jpg: - * animated-overlay.gif: + * totem-banner.xxs.jpg: * star-939235_1280.s.jpg: + * drummer-652345_1280.jpg: * sign-in-with-google.png: + * star-939235_1280.xs.jpg: + * musician-923526_1280.jpg: + * musician-923526_1.nb.jpg: * star-939235_1280.xxs.jpg: * sign-in-with-google-s.png: + * an-pierle-876094_1280.jpg: + * musician-923526_1.nbb.jpg: + * drummer-652345_1280.s.jpg: * helix-nebula-1400x1400.jpg: + * musician-923526_1280.s.jpg: + * drummer-652345_1280.xxs.jpg: + * musician-923526_1.nb.xs.jpg: * helix-nebula-1400x1400.s.jpg: - * helix-nebula-1400x1400.xxs.jpg: - -2015-11-03 Paul Schneider - - * YavscController.cs: TODO ... - -2015-11-03 Paul Schneider - - * YavscController.cs: Fixes the cookies agreement - - * HomeController.cs: Finalizes the cookie agreement system. - - * YavscHelpers.cs: Adds a "click_action_name" field, to give a - text to the notification dimissing button. - - - * App.master: Uses the new field from Notification - - * Web.config: No VB code to compile - - * Web.csproj: moves Sql files to Sql folder - - * instdbws.sql: permits profile records with no users record - associated to, - and so, anonymous profiles creation. - -2015-11-01 Paul Schneider - - * CalAuth.aspx: A view ... still unused - - * style.css: css overflow-y auto, the container making it - modal has no margin. - - * GoogleController.cs: Fixes again the calendar usage, - uses Google API key and client credentials found in - configuration file - - * ApiClient.cs: Google API key and client credentials are now - found in configuration file - - * CalendarApi.cs: Let the controller build the credential - string from thr profile object. - - * OAuth2.cs: The OAuth2 Client only needs a client id and - secret - - * yavsc.js: Fixes some css flipping - - * ValidateAjaxAttribute.cs: A FIXME - - * Web.config: Google key, client id and secret come from - application settings - - * Web.csproj: a page in more - -2015-11-01 Paul Schneider - - * Book-next.aspx: pollution - - * instdbws.sql: The conversion to a valid .Net DateTime - requires a credible date time as source value, the null one is - not supported. - - * style.css: Fixes the new notification style - - * AccountController.cs: Fixes the profile edition. - Now using the anti forgery key at login time - - * Book.aspx: - * CalendarApi.cs: - * GoogleController.cs: WIP booking - - * HomeController.cs: code prettying - - * Global.asax.cs: Limits the usage of titles in a route to the - blog controller - - * OAuth2.cs: Profile values may be of type DBNull ... - - * T.cs: All translated strings will be Html encoded, as - expected from an html helper - - * YavscHelpers.cs: A new method to build a javascript - string... - - * App.master: - * AppAdmin.master: Notification.body is now a js string - literal - - * NoLogin.master: sync with the true master - - * Login.aspx: Permits the anti forgery key usage - - * Profile.aspx: Fixes the username modification - - * Estimate.aspx: refactoring - - * Web.config: Fixes a later commit on the catalog name space - - * Web.csproj: An ajax helper to notify - - * ChangeLog: should not be indexed - - * ValidateAjaxAttribute.cs: Fixes usage of HtmlFieldPrefix - -2015-10-31 Paul Schneider - - * Web.csproj: - * Web.config: - * T.cs: - * Global.asax.cs: - * App.master: - * Book.aspx: - * YavscHelpers.cs: - * OAuth2.cs: - * Profile.aspx: - * YavscAjaxHelper.cs: - * Book-next.aspx: - * CalendarApi.cs: - * HomeController.cs: - * GoogleController.cs: - * Estimate.aspx: - * AccountController.cs: - -2015-10-30 Paul Schneider - - * packages.config: - * App.master: - * datepair.js: - * Book.aspx: - * datepair.min.js: - * jquery.datepair.js: - * jquery-ui-1.11.4.js: - * jquery.timepicker.js: - * jquery-1.11.3.min.js: - * jquery.datepair.min.js: - * WebCatalogExtensions.cs: - * GoogleController.cs: - * jquery.timepicker.min.js: - * jquery.timepicker.css: - * FrontOfficeController.cs: - * ui-icons_ffffff_256x240.png: - * ui-icons_cccccc_256x240.png: - * ui-icons_a83300_256x240.png: - * ui-icons_4b8e0b_256x240.png: - * ui-icons_222222_256x240.png: - * ui-bg_glass_40_ffc73d_1x400.png: - * ui-bg_glass_40_0078a3_1x400.png: - * ui-bg_glass_20_555555_1x400.png: - * ui-icons_222222_256x240.png: - * ui-icons_4b8e0b_256x240.png: - * ui-icons_a83300_256x240.png: - * ui-icons_cccccc_256x240.png: - * ui-icons_ffffff_256x240.png: - * ui-bg_glass_40_ffc73d_1x400.png: - * ui-bg_glass_40_0078a3_1x400.png: - * ui-bg_glass_20_555555_1x400.png: - * ui-bg_inset-soft_25_000000_1x100.png: - * ui-bg_inset-soft_30_f58400_1x100.png: - * ui-bg_gloss-wave_25_333333_500x100.png: - * ui-bg_highlight-soft_80_eeeeee_1x100.png: - * ui-bg_inset-soft_30_f58400_1x100.png: - * ui-bg_inset-soft_25_000000_1x100.png: - * ui-bg_gloss-wave_25_333333_500x100.png: - * ui-bg_highlight-soft_80_eeeeee_1x100.png: - - * FrontOfficeController.cs: refactoring: a dedicated name - space for the catalog - - * ChooseADate.aspx: WIP - - * Web.csproj: date pairing : includes the javascript modules - -2015-10-29 Paul Schneider - - * Index.aspx: Gives this page a title - - * AdminController.cs: Trying to fix this Index : /Admin ... a - 404 - - * FileSystemController.cs: Refactoring the name of the files - manager class - - * Index.aspx: Fixes the file system access - - * RemoveRole.aspx: Role removal form, had not a canonical - name! - - * Web.csproj: a page was renamed - -2015-10-28 Paul Schneider - - * yavsc.circles.js: - -2015-10-28 Paul Schneider - - * BlogsController.cs: - * AccountController.cs: - * CalendarController.cs: refactoring : the Yavsc controller - name - - * instdbws.sql: a new profile value : a boolean, - `AllowCookies` :'{ - - * style.css: a class to display notification - - * HomeController.cs: Notifies users this site uses cookies - (what for an information!) - If authenticated, at dimissing this notification, the user's - profile is updated, - and he'll not mess up anymore with the info. - - * App.master: - * YavscHelpers.cs: adds usage of click_action value at - displaying a notification. - - * yavsc.js: Implements the notification `click_action` - - - * Web.config: * enables anonymous profiles - * adds a new `allowcookies` profile property - - - * Web.csproj: Yavsc controller refactoring - - * Web.config: code prettying - - * YavscController.cs: Gives Yavsc a concrete base controller - -2015-10-27 Paul Schneider - - * AppAdmin.master: A new master page for Administration - - * Web.csproj: - * Web.config: - * Auth.aspx: - * Auth.aspx: - * Book.aspx: - * Book.aspx: - * Book.aspx: - * Restore.aspx: - * Auth.aspx: - * TagPanel.ascx: - * date.js: - * UserList.aspx: - * Restored.aspx: - * RoleList.aspx: - * plural.js: - * number.js: - * message.js: - * ChooseADate.aspx: - * ChooseADate.aspx: - * currency.js: - * ErrorMessage.aspx: - * globalize.js: - * ChooseADate.aspx: - * ChooseCalendar.aspx: - * ErrorMessage.aspx: - * ChooseCalendar.aspx: - * relative-time.js: - * ChooseCalendar.aspx: - * OtherWebException.aspx: + * live-concert-388160_1280.jpg: + * musician-923526_1.nb.xxs.jpg: + * musician-923526_1.nbb.xs.jpg: + * musician-923526_1280.xxs.jpg: + * musician-923526_1.nbb.xxs.jpg: * globalize.cultures.js: - * globalize.culture.et.js: - * globalize.culture.it.js: - * globalize.culture.oc.js: - * globalize.culture.sq.js: - * globalize.culture.sr.js: - * globalize.culture.or.js: - * globalize.culture.sk.js: - * globalize.culture.es.js: - * globalize.culture.ii.js: - * globalize.culture.sl.js: - * globalize.culture.pa.js: - * globalize.culture.is.js: - * globalize.culture.no.js: + * helix-nebula-1400x1400.xxs.jpg: + * live-concert-388160_1280.s.jpg: * globalize.culture.nl.js: - * globalize.culture.te.js: - * globalize.culture.ta.js: - * globalize.culture.ka.js: - * globalize.culture.tg.js: - * globalize.culture.ja.js: - * globalize.culture.iu.js: - * globalize.culture.sv.js: - * globalize.culture.nn.js: - * globalize.culture.th.js: - * globalize.culture.kk.js: - * globalize.culture.sw.js: - * globalize.culture.eu.js: - * globalize.culture.fy.js: - * globalize.culture.ru.js: - * globalize.culture.ga.js: + * globalize.culture.ko.js: + * globalize.culture.zh.js: * globalize.culture.hr.js: - * globalize.culture.gd.js: - * globalize.culture.ro.js: - * globalize.culture.he.js: - * globalize.culture.gu.js: - * globalize.culture.rm.js: - * globalize.culture.pt.js: - * globalize.culture.hi.js: - * globalize.culture.gl.js: - * globalize.culture.ps.js: - * globalize.culture.id.js: - * globalize.culture.se.js: - * globalize.culture.fi.js: - * globalize.culture.ig.js: - * globalize.culture.fa.js: - * globalize.culture.si.js: - * globalize.culture.pl.js: - * globalize.culture.fr.js: - * globalize.culture.rw.js: - * globalize.culture.sa.js: - * globalize.culture.hu.js: - * globalize.culture.hy.js: - * globalize.culture.fo.js: - * globalize.culture.kl.js: + * globalize.culture.th.js: * globalize.culture.ml.js: * globalize.culture.mk.js: - * globalize.culture.bs.js: - * globalize.culture.mr.js: - * globalize.culture.ca.js: - * globalize.culture.mi.js: - * globalize.culture.lt.js: - * globalize.culture.cy.js: - * globalize.culture.yo.js: - * globalize.culture.cs.js: - * globalize.culture.lv.js: - * globalize.culture.co.js: - * globalize.culture.zh.js: - * globalize.culture.az.js: - * globalize.culture.as.js: - * globalize.culture.mn.js: - * globalize.culture.ar.js: - * globalize.culture.am.js: - * globalize.culture.af.js: - * globalize.culture.ba.js: - * globalize.culture.br.js: + * globalize.culture.id.js: + * globalize.culture.pl.js: + * globalize.culture.hy.js: + * globalize.culture.tk.js: + * globalize.culture.hu.js: * globalize.culture.zu.js: + * globalize.culture.lo.js: + * globalize.culture.no.js: + * globalize.culture.lb.js: + * globalize.culture.tt.js: + * globalize.culture.ha.js: + * globalize.culture.ky.js: + * globalize.culture.sr.js: + * globalize.culture.hi.js: + * globalize.culture.nn.js: + * globalize.culture.ps.js: + * globalize.culture.lt.js: + * globalize.culture.he.js: + * globalize.culture.ig.js: + * globalize.culture.ug.js: + * globalize.culture.ja.js: + * globalize.culture.uz.js: + * globalize.culture.ka.js: + * globalize.culture.kn.js: + * globalize.culture.lv.js: + * globalize.culture.ur.js: + * globalize.culture.kk.js: + * globalize.culture.sq.js: + * globalize.culture.kl.js: + * globalize.culture.uk.js: + * globalize.culture.km.js: + * globalize.culture.oc.js: + * globalize.culture.pa.js: + * globalize.culture.ii.js: + * globalize.culture.yo.js: + * globalize.culture.is.js: + * globalize.culture.mi.js: + * globalize.culture.xh.js: + * globalize.culture.iu.js: + * globalize.culture.vi.js: + * globalize.culture.tn.js: + * globalize.culture.wo.js: + * globalize.culture.or.js: + * globalize.culture.it.js: + * globalize.culture.gu.js: + * globalize.culture.nb.js: + * globalize.culture.dv.js: + * globalize.culture.el.js: + * live-concert-388160_1280.xxs.jpg: + * globalize.culture.sa.js: + * globalize.culture.af.js: + * globalize.culture.ro.js: + * globalize.culture.ru.js: + * globalize.culture.mt.js: + * globalize.culture.rw.js: + * globalize.culture.am.js: + * globalize.culture.sw.js: + * globalize.culture.de.js: * globalize.culture.bo.js: * globalize.culture.bn.js: * globalize.culture.bg.js: * globalize.culture.be.js: + * globalize.culture.ba.js: + * globalize.culture.az.js: + * globalize.culture.br.js: * globalize.culture.da.js: - * globalize.culture.ko.js: - * globalize.culture.nb.js: - * globalize.culture.ug.js: - * globalize.culture.uk.js: - * globalize.culture.ky.js: - * globalize.culture.el.js: - * globalize.culture.tt.js: - * globalize.culture.tk.js: - * globalize.culture.km.js: - * globalize.culture.tn.js: - * globalize.culture.ne.js: - * globalize.culture.tr.js: - * globalize.culture.kn.js: - * globalize.culture.mt.js: - * globalize.culture.lb.js: - * globalize.culture.de.js: - * globalize.culture.vi.js: - * globalize.culture.lo.js: - * globalize.culture.wo.js: + * globalize.culture.cy.js: + * globalize.culture.cs.js: + * globalize.culture.co.js: + * globalize.culture.ca.js: + * globalize.culture.bs.js: * globalize.culture.ms.js: - * globalize.culture.xh.js: - * globalize.culture.ha.js: - * globalize.culture.uz.js: - * globalize.culture.ur.js: - * globalize.culture.dv.js: - * globalize.culture.qut.js: - * globalize.culture.moh.js: - * globalize.culture.prs.js: - * globalize.culture.kok.js: - * globalize.culture.nso.js: - * globalize.culture.hsb.js: - * globalize.culture.tzm.js: - * globalize.culture.sah.js: - * globalize.culture.fil.js: - * globalize.culture.sms.js: - * globalize.culture.smn.js: - * globalize.culture.smj.js: - * globalize.culture.dsb.js: + * globalize.culture.fr.js: + * globalize.culture.mn.js: + * globalize.culture.ar.js: + * globalize.culture.te.js: + * globalize.culture.pt.js: + * globalize.culture.fo.js: + * globalize.culture.fy.js: + * globalize.culture.as.js: + * globalize.culture.tg.js: + * globalize.culture.gl.js: + * globalize.culture.gd.js: + * globalize.culture.sl.js: + * globalize.culture.ga.js: + * globalize.culture.sk.js: + * globalize.culture.ta.js: + * globalize.culture.et.js: + * globalize.culture.ne.js: + * globalize.culture.es.js: + * globalize.culture.se.js: + * globalize.culture.rm.js: + * globalize.culture.eu.js: + * globalize.culture.tr.js: + * globalize.culture.sv.js: + * globalize.culture.fi.js: + * globalize.culture.mr.js: + * globalize.culture.fa.js: + * globalize.culture.si.js: * globalize.culture.syr.js: - * globalize.culture.quz.js: - * globalize.culture.arn.js: - * globalize.culture.gsw.js: + * globalize.culture.moh.js: * globalize.culture.sma.js: - * globalize.culture.uk-UA.js: - * globalize.culture.ne-NP.js: - * globalize.culture.tt-RU.js: - * globalize.culture.ur-PK.js: - * globalize.culture.tr-TR.js: - * globalize.culture.nl-BE.js: - * globalize.culture.tn-ZA.js: - * globalize.culture.ug-CN.js: - * globalize.culture.nb-NO.js: - * globalize.culture.zh-HK.js: - * globalize.culture.zh-MO.js: - * globalize.culture.zh-SG.js: - * globalize.culture.mr-IN.js: - * globalize.culture.zh-TW.js: - * globalize.culture.zu-ZA.js: - * globalize.culture.ms-BN.js: - * globalize.culture.vi-VN.js: - * globalize.culture.mt-MT.js: - * globalize.culture.wo-SN.js: - * globalize.culture.xh-ZA.js: - * globalize.culture.yo-NG.js: - * globalize.culture.ms-MY.js: - * globalize.culture.zh-CN.js: - * globalize.culture.tk-TM.js: - * globalize.culture.ps-AF.js: - * globalize.culture.se-FI.js: + * globalize.culture.gsw.js: + * globalize.culture.arn.js: + * globalize.culture.fil.js: + * globalize.culture.qut.js: + * globalize.culture.quz.js: + * globalize.culture.sah.js: + * globalize.culture.dsb.js: + * globalize.culture.hsb.js: + * globalize.culture.sms.js: + * globalize.culture.kok.js: + * globalize.culture.smn.js: + * globalize.culture.prs.js: + * globalize.culture.nso.js: + * globalize.culture.smj.js: + * globalize.culture.tzm.js: * globalize.culture.se-NO.js: * globalize.culture.se-SE.js: - * globalize.culture.pl-PL.js: - * globalize.culture.si-LK.js: - * globalize.culture.sa-IN.js: - * globalize.culture.rm-CH.js: - * globalize.culture.ro-RO.js: - * globalize.culture.pt-PT.js: - * globalize.culture.pt-BR.js: - * globalize.culture.ru-RU.js: - * globalize.culture.rw-RW.js: - * globalize.culture.sk-SK.js: - * globalize.culture.sw-KE.js: - * globalize.culture.nn-NO.js: - * globalize.culture.ta-IN.js: - * globalize.culture.te-IN.js: - * globalize.culture.th-TH.js: - * globalize.culture.nl-NL.js: + * globalize.culture.se-FI.js: * globalize.culture.sv-SE.js: - * globalize.culture.sl-SI.js: - * globalize.culture.pa-IN.js: - * globalize.culture.or-IN.js: - * globalize.culture.oc-FR.js: - * globalize.culture.sq-AL.js: * globalize.culture.sv-FI.js: - * globalize.culture.lo-LA.js: - * globalize.culture.es-DO.js: - * globalize.culture.es-EC.js: - * globalize.culture.es-ES.js: - * globalize.culture.es-GT.js: - * globalize.culture.es-HN.js: - * globalize.culture.es-MX.js: - * globalize.culture.es-NI.js: - * globalize.culture.es-CR.js: - * globalize.culture.en-ZA.js: - * globalize.culture.en-ZW.js: - * globalize.culture.es-AR.js: - * globalize.culture.as-IN.js: - * globalize.culture.es-BO.js: - * globalize.culture.es-CL.js: - * globalize.culture.es-CO.js: - * globalize.culture.ar-YE.js: - * globalize.culture.es-PA.js: - * globalize.culture.es-PE.js: - * globalize.culture.es-PR.js: - * globalize.culture.es-PY.js: - * globalize.culture.es-SV.js: - * globalize.culture.es-US.js: - * globalize.culture.es-UY.js: - * globalize.culture.ar-LB.js: - * globalize.culture.ar-TN.js: - * globalize.culture.ar-SY.js: - * globalize.culture.ar-SA.js: - * globalize.culture.ar-QA.js: - * globalize.culture.ar-OM.js: - * globalize.culture.ar-MA.js: + * globalize.culture.sl-SI.js: + * globalize.culture.sq-AL.js: + * globalize.culture.sk-SK.js: + * globalize.culture.si-LK.js: + * globalize.culture.sw-KE.js: * globalize.culture.ar-LY.js: - * globalize.culture.en-US.js: - * globalize.culture.de-CH.js: - * globalize.culture.de-DE.js: - * globalize.culture.de-LI.js: - * globalize.culture.de-LU.js: - * globalize.culture.dv-MV.js: - * globalize.culture.bn-IN.js: - * globalize.culture.bn-BD.js: - * globalize.culture.de-AT.js: - * globalize.culture.ca-ES.js: - * globalize.culture.br-FR.js: - * globalize.culture.bo-CN.js: - * globalize.culture.co-FR.js: - * globalize.culture.cs-CZ.js: - * globalize.culture.cy-GB.js: - * globalize.culture.da-DK.js: - * globalize.culture.bg-BG.js: - * globalize.culture.en-IN.js: - * globalize.culture.en-JM.js: - * globalize.culture.en-MY.js: - * globalize.culture.en-NZ.js: - * globalize.culture.en-PH.js: - * globalize.culture.en-SG.js: - * globalize.culture.en-TT.js: - * globalize.culture.ba-RU.js: - * globalize.culture.be-BY.js: - * globalize.culture.el-GR.js: - * globalize.culture.en-AU.js: - * globalize.culture.en-BZ.js: - * globalize.culture.en-CA.js: - * globalize.culture.en-GB.js: - * globalize.culture.en-IE.js: - * globalize.culture.es-VE.js: + * globalize.culture.ar-MA.js: + * globalize.culture.ar-OM.js: + * globalize.culture.ar-QA.js: + * globalize.culture.ar-SA.js: + * globalize.culture.ar-SY.js: + * globalize.culture.ar-TN.js: + * globalize.culture.ar-YE.js: + * globalize.culture.as-IN.js: + * globalize.culture.ar-LB.js: + * globalize.culture.af-ZA.js: + * globalize.culture.am-ET.js: + * globalize.culture.ar-AE.js: + * globalize.culture.ar-BH.js: + * globalize.culture.ar-DZ.js: + * globalize.culture.ar-EG.js: + * globalize.culture.ar-IQ.js: + * globalize.culture.ar-JO.js: + * globalize.culture.ar-KW.js: + * globalize.culture.pa-IN.js: + * globalize.culture.uk-UA.js: + * globalize.culture.ug-CN.js: + * globalize.culture.tt-RU.js: + * globalize.culture.tr-TR.js: + * globalize.culture.tn-ZA.js: + * globalize.culture.tk-TM.js: + * globalize.culture.th-TH.js: + * globalize.culture.te-IN.js: + * globalize.culture.ta-IN.js: + * globalize.culture.ur-PK.js: + * globalize.culture.zu-ZA.js: + * globalize.culture.zh-TW.js: + * globalize.culture.zh-SG.js: + * globalize.culture.zh-MO.js: + * globalize.culture.zh-HK.js: + * globalize.culture.zh-CN.js: + * globalize.culture.yo-NG.js: + * globalize.culture.xh-ZA.js: + * globalize.culture.wo-SN.js: + * globalize.culture.vi-VN.js: + * globalize.culture.hu-HU.js: + * globalize.culture.es-DO.js: + * globalize.culture.is-IS.js: * globalize.culture.it-CH.js: * globalize.culture.it-IT.js: - * globalize.culture.ar-IQ.js: - * globalize.culture.ar-EG.js: - * globalize.culture.ar-DZ.js: - * globalize.culture.ar-BH.js: - * globalize.culture.ja-JP.js: - * globalize.culture.is-IS.js: - * globalize.culture.hi-IN.js: - * globalize.culture.hr-BA.js: - * globalize.culture.hr-HR.js: - * globalize.culture.hu-HU.js: + * globalize.culture.es-CR.js: + * globalize.culture.es-CO.js: + * globalize.culture.es-EC.js: * globalize.culture.hy-AM.js: * globalize.culture.id-ID.js: + * globalize.culture.es-GT.js: + * globalize.culture.es-ES.js: * globalize.culture.ig-NG.js: * globalize.culture.ii-CN.js: - * globalize.culture.ka-GE.js: - * globalize.culture.lv-LV.js: - * globalize.culture.mi-NZ.js: - * globalize.culture.mk-MK.js: - * globalize.culture.ml-IN.js: - * globalize.culture.ar-AE.js: - * globalize.culture.mn-MN.js: - * globalize.culture.am-ET.js: - * globalize.culture.lt-LT.js: - * globalize.culture.kk-KZ.js: + * globalize.culture.es-CL.js: * globalize.culture.kl-GL.js: * globalize.culture.km-KH.js: * globalize.culture.kn-IN.js: * globalize.culture.ko-KR.js: + * globalize.culture.en-TT.js: * globalize.culture.ky-KG.js: - * globalize.culture.lb-LU.js: - * globalize.culture.af-ZA.js: - * globalize.culture.gd-GB.js: - * globalize.culture.gu-IN.js: - * globalize.culture.fa-IR.js: - * globalize.culture.gl-ES.js: + * globalize.culture.kk-KZ.js: + * globalize.culture.es-BO.js: + * globalize.culture.ja-JP.js: + * globalize.culture.ka-GE.js: + * globalize.culture.es-AR.js: + * globalize.culture.en-ZW.js: + * globalize.culture.en-ZA.js: + * globalize.culture.en-US.js: + * globalize.culture.es-HN.js: + * globalize.culture.fr-CA.js: + * globalize.culture.fr-CH.js: * globalize.culture.fr-FR.js: - * globalize.culture.ga-IE.js: - * globalize.culture.fy-NL.js: - * globalize.culture.fi-FI.js: + * globalize.culture.es-SV.js: + * globalize.culture.fr-LU.js: * globalize.culture.fr-MC.js: - * globalize.culture.ar-KW.js: - * globalize.culture.he-IL.js: + * globalize.culture.fr-BE.js: + * globalize.culture.es-VE.js: * globalize.culture.et-EE.js: * globalize.culture.eu-ES.js: + * globalize.culture.fa-IR.js: + * globalize.culture.fi-FI.js: + * globalize.culture.es-US.js: * globalize.culture.fo-FO.js: - * globalize.culture.fr-LU.js: - * globalize.culture.fr-BE.js: - * globalize.culture.ar-JO.js: - * globalize.culture.fr-CH.js: - * globalize.culture.fr-CA.js: - * globalize.culture.sms-FI.js: - * globalize.culture.fil-PH.js: - * globalize.culture.smn-FI.js: - * globalize.culture.moh-CA.js: - * globalize.culture.sma-NO.js: - * globalize.culture.sma-SE.js: - * globalize.culture.zh-CHT.js: + * globalize.culture.fy-NL.js: + * globalize.culture.es-NI.js: + * globalize.culture.he-IL.js: + * globalize.culture.hi-IN.js: + * globalize.culture.hr-BA.js: + * globalize.culture.hr-HR.js: + * globalize.culture.es-MX.js: + * globalize.culture.es-PA.js: + * globalize.culture.ga-IE.js: + * globalize.culture.gd-GB.js: + * globalize.culture.gl-ES.js: + * globalize.culture.es-PY.js: + * globalize.culture.gu-IN.js: + * globalize.culture.es-PR.js: + * globalize.culture.es-PE.js: + * globalize.culture.en-SG.js: + * globalize.culture.ms-MY.js: + * globalize.culture.cy-GB.js: + * globalize.culture.pl-PL.js: + * globalize.culture.cs-CZ.js: + * globalize.culture.co-FR.js: + * globalize.culture.ca-ES.js: + * globalize.culture.or-IN.js: + * globalize.culture.de-LU.js: + * globalize.culture.de-LI.js: + * globalize.culture.de-DE.js: + * globalize.culture.de-CH.js: + * globalize.culture.de-AT.js: + * globalize.culture.da-DK.js: + * globalize.culture.oc-FR.js: + * globalize.culture.br-FR.js: + * globalize.culture.ba-RU.js: + * globalize.culture.rm-CH.js: + * globalize.culture.ro-RO.js: + * globalize.culture.ru-RU.js: + * globalize.culture.rw-RW.js: + * globalize.culture.sa-IN.js: + * globalize.culture.be-BY.js: + * globalize.culture.ps-AF.js: + * globalize.culture.bo-CN.js: + * globalize.culture.bn-IN.js: + * globalize.culture.pt-BR.js: + * globalize.culture.pt-PT.js: + * globalize.culture.bn-BD.js: + * globalize.culture.bg-BG.js: + * globalize.culture.es-UY.js: + * globalize.culture.en-NZ.js: + * globalize.culture.mn-MN.js: + * globalize.culture.en-MY.js: + * globalize.culture.en-JM.js: + * globalize.culture.en-IN.js: + * globalize.culture.en-IE.js: + * globalize.culture.ml-IN.js: + * globalize.culture.en-PH.js: + * globalize.culture.lb-LU.js: + * globalize.culture.lo-LA.js: + * globalize.culture.lt-LT.js: + * globalize.culture.lv-LV.js: + * globalize.culture.mi-NZ.js: + * globalize.culture.mk-MK.js: + * globalize.culture.en-GB.js: + * globalize.culture.nl-BE.js: + * globalize.culture.nl-NL.js: + * globalize.culture.nn-NO.js: + * globalize.culture.en-AU.js: + * globalize.culture.el-GR.js: + * globalize.culture.dv-MV.js: + * globalize.culture.ne-NP.js: + * globalize.culture.mr-IN.js: + * globalize.culture.ms-BN.js: + * globalize.culture.en-CA.js: + * globalize.culture.mt-MT.js: + * globalize.culture.en-BZ.js: + * globalize.culture.nb-NO.js: + * globalize.culture.en-029.js: + * globalize.culture.dsb-DE.js: * globalize.culture.zh-CHS.js: * globalize.culture.smj-NO.js: - * globalize.culture.qut-GT.js: * globalize.culture.smj-SE.js: - * globalize.culture.dsb-DE.js: * globalize.culture.prs-AF.js: - * globalize.culture.quz-PE.js: - * globalize.culture.quz-EC.js: - * globalize.culture.hsb-DE.js: - * globalize.culture.syr-SY.js: - * globalize.culture.quz-BO.js: - * globalize.culture.gsw-FR.js: + * globalize.culture.smn-FI.js: + * globalize.culture.sms-FI.js: * globalize.culture.kok-IN.js: - * globalize.culture.sah-RU.js: - * globalize.culture.en-029.js: * globalize.culture.nso-ZA.js: + * globalize.culture.syr-SY.js: + * globalize.culture.moh-CA.js: + * globalize.culture.zh-CHT.js: + * globalize.culture.quz-BO.js: + * globalize.culture.quz-EC.js: + * globalize.culture.quz-PE.js: + * globalize.culture.gsw-FR.js: * globalize.culture.arn-CL.js: - * globalize.culture.az-Cyrl.js: + * globalize.culture.fil-PH.js: + * globalize.culture.qut-GT.js: + * globalize.culture.hsb-DE.js: + * globalize.culture.sma-SE.js: + * globalize.culture.sma-NO.js: + * globalize.culture.sah-RU.js: * globalize.culture.az-Latn.js: - * globalize.culture.bs-Cyrl.js: - * globalize.culture.iu-Latn.js: * globalize.culture.sr-Latn.js: - * globalize.culture.tg-Cyrl.js: - * globalize.culture.iu-Cans.js: + * globalize.culture.bs-Cyrl.js: * globalize.culture.sr-Cyrl.js: - * globalize.culture.uz-Cyrl.js: - * globalize.culture.mn-Cyrl.js: * globalize.culture.bs-Latn.js: - * globalize.culture.mn-Mong.js: - * globalize.culture.zh-Hant.js: + * globalize.culture.tg-Cyrl.js: + * globalize.culture.uz-Cyrl.js: + * globalize.culture.iu-Latn.js: + * globalize.culture.iu-Cans.js: * globalize.culture.zh-Hans.js: + * globalize.culture.zh-Hant.js: + * globalize.culture.az-Cyrl.js: + * globalize.culture.mn-Mong.js: * globalize.culture.uz-Latn.js: + * globalize.culture.mn-Cyrl.js: * globalize.culture.ha-Latn.js: * globalize.culture.tzm-Latn.js: - * globalize.culture.sr-Cyrl-CS.js: - * globalize.culture.sr-Cyrl-ME.js: + * globalize.culture.az-Cyrl-AZ.js: + * globalize.culture.iu-Latn-CA.js: * globalize.culture.bs-Latn-BA.js: - * globalize.culture.sr-Cyrl-BA.js: * globalize.culture.ha-Latn-NG.js: * globalize.culture.iu-Cans-CA.js: - * globalize.culture.iu-Latn-CA.js: - * globalize.culture.sr-Cyrl-RS.js: * globalize.culture.bs-Cyrl-BA.js: - * globalize.culture.uz-Latn-UZ.js: - * globalize.culture.uz-Cyrl-UZ.js: - * globalize.culture.az-Latn-AZ.js: - * globalize.culture.az-Cyrl-AZ.js: - * globalize.culture.sr-Latn-BA.js: - * globalize.culture.sr-Latn-CS.js: - * globalize.culture.sr-Latn-ME.js: * globalize.culture.mn-Mong-CN.js: + * globalize.culture.az-Latn-AZ.js: * globalize.culture.sr-Latn-RS.js: + * globalize.culture.sr-Latn-ME.js: + * globalize.culture.sr-Latn-CS.js: + * globalize.culture.sr-Latn-BA.js: + * globalize.culture.uz-Latn-UZ.js: + * globalize.culture.sr-Cyrl-BA.js: + * globalize.culture.sr-Cyrl-CS.js: + * globalize.culture.sr-Cyrl-ME.js: + * globalize.culture.sr-Cyrl-RS.js: + * globalize.culture.uz-Cyrl-UZ.js: * globalize.culture.tg-Cyrl-TJ.js: * globalize.culture.tzm-Latn-DZ.js: - * style.css: list in the nav are in line by default. + * style.css: nothing to see - * AdminController.cs: refactoring + * BlogsController.cs: Removes the `ValidateEdit` method, + and gives Admins the Blogger role ... a commit to blame in a + near future - * App.master: Restores hallo editing by solving again - jQuery-ui ref + * yavsc.js: comes from yavsc - * Login.aspx: Prettier code at building Urls - - * Admin.aspx: - * Index.aspx: - * AddRole.aspx: - * Backups.aspx: - * RemoveUser.aspx: - * RemoveRole..aspx: - * CreateBackup.aspx: - * BackupCreated.aspx: new master page - -2015-10-25 Paul Schneider - - * style.css: backgrounds don't really need - transitions. - - * App.master: Removes a duplicated link to contact form - - * parallax.js: enforce responsivity on small devices - supporting orientation capture. - -2015-10-24 Paul Schneider - - * p8-av4.s.jpg: - * star-939235_1280.s.jpg: - * star-939235_1280.xxs.jpg: a smaller background - - * style.css: adds animation - - * AdminController.cs: Fixes the call to Notify - - * Global.asax.cs: restores a dropped route - - * App.master: Drops script references to jQuery-ui and - Prettify from - the master page. They are heavy. - - * parallax.js: specifies the capture to false at calling the - event listener registration - - * UserPost.aspx: Fixes this page - - * Index.aspx: adds the `panel` class to embed those default - home page links - - * Web.csproj: dropping the imported parallax.js script - - * animated-overlay.gif: may be used in a futur work :-) - -2015-10-23 Paul Schneider - - * AdminController.cs: Notification when Admin group is created - -2015-10-22 Paul Schneider - - * parralax.js: YastepInDaPresentation - move backgrounds with mouse postion and mobile orientation - -2015-10-22 Paul Schneider - - * style.css: no max width for panels, it's too abstract for a - notion - - * RemovePost.aspx: Adds a Title and fixes the action call - - * Contact.aspx: cleans the code from totem - -2015-10-20 Paul Schneider - - * Web.config: - * Web.csproj: - * totem.jpg: - * App.master: - * twiter.png: - * facebook.png: - * totemprod.png: - * style.css: - * p8-av4.xxs.png: - * totem-banner.png: - * YavscHelpers.cs: - * concert.clear.jpg: - * totem-banner.xs.jpg: - * totem-banner.xxs.jpg: - * drummer-652345_1280.jpg: - * musician-923526_1.nb.jpg: - * musician-923526_1280.jpg: - * drummer-652345_1280.s.jpg: - * an-pierle-876094_1280.jpg: - * musician-923526_1.nbb.jpg: - * musician-923526_1280.s.jpg: - * drummer-652345_1280.xxs.jpg: - * musician-923526_1.nb.xs.jpg: - * live-concert-388160_1280.jpg: - * musician-923526_1280.xxs.jpg: - * musician-923526_1.nb.xxs.jpg: - * musician-923526_1.nbb.xs.jpg: - * musician-923526_1.nbb.xxs.jpg: - * live-concert-388160_1280.s.jpg: - * live-concert-388160_1280.xxs.jpg: - -2015-10-19 Paul Schneider - - * Web.csproj: - * packages.config: - * App.master: - * doxy.css: - * Edit.aspx: - * desert.css: - * sunburst.css: - * YavscHelpers.cs: - * prettify.css: - * lang-r.js: - * lang-n.js: - * UserPosts.aspx: - * lang-hs.js: - * lang-rd.js: - * lang-ml.js: - * lang-go.js: - * lang-vb.js: - * lang-xq.js: - * lang-tex.js: - * lang-tcl.js: - * lang-sql.js: - * lang-clj.js: - * lang-lua.js: - * PostActions.ascx: - * prettify.js: - * lang-css.js: - * HomeController.cs: - * lang-lisp.js: - * lang-wiki.js: - * lang-vhdl.js: - * lang-llvm.js: - * lang-dart.js: - * lang-yaml.js: - * lang-basic.js: - * lang-proto.js: - * lang-scala.js: - * lang-mumps.js: - * lang-erlang.js: - * lang-matlab.js: - * sons-of-obsidian.css: - * lang-pascal.js: - * lang-apollo.js: - * run_prettify.js: - - * TagPanel.ascx: displays the photo - - * IValueProvider.cs: useless, unused - - * TestExec.cs: pollution - -2015-10-18 Paul Schneider - - * BlogsController.cs: Fixes the redirection after bill edition - -2015-10-18 Paul Schneider - - * App.master: - * Title.aspx: Reset the Home page link - - * TagPanel.ascx: implements html links from tag related titles - -2015-10-17 Paul Schneider - - * Web.csproj: - * Index.aspx: - * Error.aspx: - * TagPanel.ascx: - * UserPost.aspx: - * PageLinks.ascx: - * HomeController.cs: - * BlogsController.cs: - -2015-10-17 Paul Schneider - - * Web.csproj: - * Global.asax.cs: - * yavsc.js: - * App.master: - * style.css: - * NoLogin.master: - * YavscHelpers.cs: - * TagPanel.ascx: - * UserPosts.aspx: - * AccountController.cs: - * FrontOfficeController.cs: - -2015-10-17 Paul Schneider - - * Web.csproj: - * Global.asax.cs: - * yavsc.js: - * App.master: - * style.css: - * Edit.aspx: - * Title.aspx: - * Index.aspx: - * YavscHelpers.cs: - * UserPost.aspx: - * UserPosts.aspx: - * PageLinks.ascx: - * TagControl.ascx: - * PostActions.ascx: - * HomeController.cs: - * AdminController.cs: - * BlogsController.cs: - * GoogleController.cs: - * Estimate.aspx: - * AccountController.cs: - * BlogsController.cs: - * knockout-jqAutocomplete.js: - * knockout-jqAutocomplete.min.js: - -2015-10-13 Paul Schneider - - * Index.aspx: - * Title.aspx: - * yavsc.scrollnotif.js: - * AccountController.cs: refactoring - - * yavsc.tags.js: Implements a js call - to the tag & untag methods - - * PostActions.ascx: a better html structure - - * yavsc.circles.js: - * AccountController.cs: code formatting - - * BlogsController.cs: Untag a post - - * style.css: yastyle, yet a better one. - - * BlogsController.cs: View the Title after edition - - * App.master: - * UserPosts.aspx: a nicer html structure - - * yavsc.js: Fixes notice & dimiss js - - * Login.aspx: refactoring - - * Edit.aspx: better html - - * UserPost.aspx: A promess to be allowed to tag. - - * Web.csproj: Adds yavsc.tags.js and yavsc.scrollnotifs.js to - the project decription. - -2015-10-10 Paul Schneider - - * Web.csproj: - * Global.asax.cs: - * App.master: - * Index.aspx: - * NoLogin.master: - * Title.aspx: - * Index.aspx: - * YavscHelpers.cs: - * Profile.aspx: - * UserPosts.aspx: - * HomeController.cs: - * BlogsController.cs: - * GoogleController.cs: - * AccountController.cs: + * Edit.aspx: refactoring `ValidateEdit` diff --git a/web/Controllers/AccountController.cs b/web/Controllers/AccountController.cs index 53ed2338..75592258 100644 --- a/web/Controllers/AccountController.cs +++ b/web/Controllers/AccountController.cs @@ -335,6 +335,7 @@ namespace Yavsc.Controllers prf.SetPropertyValue ("AccountNumber", model.AccountNumber); prf.SetPropertyValue ("BankedKey", model.BankedKey); prf.SetPropertyValue ("gcalid", model.GoogleCalendar); + prf.SetPropertyValue ("UITheme", model.UITheme); prf.Save (); if (editsTheUserName) { diff --git a/web/Controllers/AdminController.cs b/web/Controllers/AdminController.cs index 57ed5c5b..d292d4da 100644 --- a/web/Controllers/AdminController.cs +++ b/web/Controllers/AdminController.cs @@ -25,9 +25,9 @@ namespace Yavsc.Controllers public ActionResult Index() { // FIXME do this in a new installation script. - if (!Roles.RoleExists (roleName)) { - Roles.CreateRole (roleName); - YavscHelpers.Notify (ViewData, roleName + " " + LocalizedText.role_created); + if (!Roles.RoleExists (_adminRoleName)) { + Roles.CreateRole (_adminRoleName); + YavscHelpers.Notify (ViewData, _adminRoleName + " " + LocalizedText.role_created); } return View (); } @@ -156,6 +156,13 @@ namespace Yavsc.Controllers Roles.RemoveUserFromRole(username,rolename); return Redirect(returnUrl); } + + [Authorize(Roles="Admin")] + public ActionResult AddUserToRole(string username, string rolename, string returnUrl) + { + Roles.AddUsersToRole(new string[] { username } ,rolename); + return Redirect(returnUrl); + } /// /// Removes the user. /// @@ -223,7 +230,27 @@ namespace Yavsc.Controllers MembershipUserCollection c = Membership.GetAllUsers (); return View (c); } + [Authorize()] + public ActionResult UsersInRole (string rolename) + { + if (rolename == null) + rolename = "Admin"; + ViewData ["RoleName"] = rolename; + ViewData ["Roles"] = Roles.GetAllRoles (); + ViewData ["UsersInRole"] = Roles.GetUsersInRole (rolename); + return View (); + } + [Authorize()] + public ActionResult UserRoles (string username) + { + ViewData ["AllRoles"] = Roles.GetAllRoles (); + if (username == null) + username = User.Identity.Name; + ViewData ["UserName"] = username; + ViewData ["UsersRoles"] = Roles.GetRolesForUser (username); + return View (); + } /// /// a form to add a role /// @@ -257,7 +284,7 @@ namespace Yavsc.Controllers return View (Roles.GetAllRoles ()); } - private const string roleName = "Admin"; + private const string _adminRoleName = "Admin"; /// /// Assing the Admin role to the specified user in model. @@ -267,7 +294,7 @@ namespace Yavsc.Controllers public ActionResult Admin (NewAdminModel model) { // ASSERT (Roles.RoleExists (adminRoleName)) - string [] admins = Roles.GetUsersInRole (roleName); + string [] admins = Roles.GetUsersInRole (_adminRoleName); string currentUser = Membership.GetUser ().UserName; List users = new List (); foreach (MembershipUser u in Membership.GetAllUsers ()) { @@ -279,22 +306,21 @@ namespace Yavsc.Controllers ViewData ["admins"] = admins; ViewData ["useritems"] = users; if (ModelState.IsValid) { - Roles.AddUserToRole (model.UserName, roleName); - YavscHelpers.Notify(ViewData, model.UserName + " "+LocalizedText.was_added_to_the_role+" '" + roleName + "'"); + Roles.AddUserToRole (model.UserName, _adminRoleName); + YavscHelpers.Notify(ViewData, model.UserName + " "+LocalizedText.was_added_to_the_role+" '" + _adminRoleName + "'"); } else { if (admins.Length > 0) { if (! admins.Contains (Membership.GetUser ().UserName)) { ModelState.Remove("UserName"); ModelState.AddModelError("UserName",LocalizedText.younotadmin+"!"); - return View ("Index"); } } else { // No admin, gives the Admin Role to the current user - Roles.AddUserToRole (currentUser, roleName); + Roles.AddUserToRole (currentUser, _adminRoleName); admins = new string[] { currentUser }; YavscHelpers.Notify(ViewData, string.Format ( LocalizedText.was_added_to_the_empty_role, - currentUser, roleName)); + currentUser, _adminRoleName)); } } return View (model); diff --git a/web/Controllers/BlogsController.cs b/web/Controllers/BlogsController.cs index 2306ce3c..3cb34daa 100644 --- a/web/Controllers/BlogsController.cs +++ b/web/Controllers/BlogsController.cs @@ -77,7 +77,6 @@ namespace Yavsc.Controllers /// Title. /// Page index. /// Page size. - /// [HttpGet] public ActionResult Title (string title, int pageIndex = 0, int pageSize = 10) { @@ -89,7 +88,7 @@ namespace Yavsc.Controllers BlogManager.FindPost (username, title, sf, pageIndex, pageSize, out recordCount); var utc = new UTBlogEntryCollection (title); utc.AddRange (c); - ViewData ["RecordCount"] = recordCount; + ViewData ["ResultCount"] = recordCount; ViewData ["PageIndex"] = pageIndex; ViewData ["PageSize"] = pageSize; return View ("Title", utc); @@ -135,8 +134,10 @@ namespace Yavsc.Controllers ViewData ["BlogTitle"] = bupr.BlogTitle; ViewData ["Avatar"] = bupr.avatar; } - ViewData ["RecordCount"] = recordcount; UUBlogEntryCollection uuc = new UUBlogEntryCollection (user, c); + ViewData ["ResultCount"] = recordcount; + ViewData ["PageIndex"] = pageIndex; + ViewData ["PageSize"] = pageSize; return View ("UserPosts", uuc); } @@ -279,8 +280,8 @@ namespace Yavsc.Controllers /// /// The edit. /// Model. - [Authorize(Roles="Blogger")] - public ActionResult ValidateEdit (BlogEntry model) + [Authorize(Roles="")] + public ActionResult Edit (BlogEntry model) { ViewData ["SiteName"] = sitename; ViewData ["Author"] = Membership.GetUser ().UserName; @@ -289,13 +290,13 @@ namespace Yavsc.Controllers // ensures rights to update BlogManager.GetForEditing (model.Id, true); BlogManager.UpdatePost (model.Id, model.Title, model.Content, model.Visible, model.AllowedCircles); + YavscHelpers.Notify (ViewData, LocalizedText.BillUpdated); - } - else + } else { model.Id = BlogManager.Post (model.Author, model.Title, model.Content, model.Visible, model.AllowedCircles); - if (model.Photo != null) - BlogManager.UpdatePostPhoto (model.Id, model.Photo); - return RedirectToAction ("Title", new { title = model.Title }); + YavscHelpers.Notify (ViewData, LocalizedText.BillCreated); + } + BlogManager.UpdatePostPhoto (model.Id, model.Photo); } ViewData ["AllowedCircles"] = CircleManager.DefaultProvider.List ( @@ -312,7 +313,7 @@ namespace Yavsc.Controllers /// /// Identifier. [Authorize(Roles="Blogger")] - public ActionResult Edit (long postid) + public ActionResult EditId (long postid) { BlogEntry e = BlogManager.GetForEditing (postid); @@ -333,7 +334,7 @@ namespace Yavsc.Controllers Text = x.Title, Selected = e.AllowedCircles.Contains (x.Id) }); - return View (e); + return View ("Edit",e); } /// diff --git a/web/Controllers/FrontOfficeController.cs b/web/Controllers/FrontOfficeController.cs index 1886e892..b4322b68 100644 --- a/web/Controllers/FrontOfficeController.cs +++ b/web/Controllers/FrontOfficeController.cs @@ -16,6 +16,7 @@ using Yavsc.Model.Calendar; using System.Configuration; using Yavsc.Helpers; using Yavsc.Model.FrontOffice.Catalog; +using Yavsc.Model.Skill; namespace Yavsc.Controllers { @@ -85,12 +86,12 @@ namespace Yavsc.Controllers /// Estimate the specified id. /// /// Identifier. - public ActionResult Get (long id) + public ActionResult Get (long estimid) { - Estimate f = wfmgr.GetEstimate (id); + Estimate f = wfmgr.GetEstimate (estimid); if (f == null) { ModelState.AddModelError ("Id", "Wrong Id"); - return View (new Estimate () { Id=id } ); + return View (new Estimate () { Id=estimid } ); } return View (f); } @@ -162,11 +163,11 @@ namespace Yavsc.Controllers /// Catalog this instance. /// [AcceptVerbs ("GET")] - public ActionResult Brand (string id) + public ActionResult Brand (string brandid) { Catalog c = CatalogManager.GetCatalog (); - ViewData ["BrandName"] = id; - return View (c.GetBrand (id)); + ViewData ["BrandName"] = brandid; + return View (c.GetBrand (brandid)); } /// @@ -200,10 +201,10 @@ namespace Yavsc.Controllers /// Pc. /// Preference. [AcceptVerbs ("GET")] - public ActionResult Product (string id, string pc, string pref) + public ActionResult Product (string brandid, string pc, string pref) { Product p = null; - ViewData ["BrandName"] = id; + ViewData ["BrandName"] = brandid; ViewData ["ProdCatRef"] = pc; ViewData ["ProdRef"] = pref; Catalog cat = CatalogManager.GetCatalog (); @@ -212,7 +213,7 @@ namespace Yavsc.Controllers ViewData ["RefType"] = "Catalog"; return View ("ReferenceNotFound"); } - Brand b = cat.GetBrand (id); + Brand b = cat.GetBrand (brandid); if (b == null) { ViewData ["RefType"] = "Brand"; return View ("ReferenceNotFound"); @@ -259,5 +260,50 @@ namespace Yavsc.Controllers } } + /// + /// Booking the specified model. + /// + /// Model. + public ActionResult Booking (BookingQuery model) + { + return View (); + } + + /// + /// Skills the specified model. + /// + [Authorize(Roles="Admin")] + public ActionResult Skills (string search) + { + if (search == null) + search = "%"; + var skills = SkillManager.FindSkill (search); + return View (skills); + } + + /// + /// Display and should + /// offer Ajax edition of + /// user's skills. + /// + /// the User Skills Profile. + [Authorize()] + public ActionResult UserSkills (PerformerProfile usp) + { + if (usp.UserName == null) + // this is not a call to update, + // and this can not concern another user + // than the current logged one. + usp = new PerformerProfile( User.Identity.Name ); + // if (usp.UserName was null) { + usp = SkillManager.GetUserSkills (usp.UserName); + var skills = SkillManager.FindSkill ("%"); + ViewData ["SiteSkills"] = skills; + // TODO or not to do, handle a skills profile update, + // actually performed via the Web API :-° + // } else if (ModelState.IsValid) {} + return View (usp); + } + } } diff --git a/web/Controllers/GoogleController.cs b/web/Controllers/GoogleController.cs index 332016d0..7d8ae296 100644 --- a/web/Controllers/GoogleController.cs +++ b/web/Controllers/GoogleController.cs @@ -78,12 +78,9 @@ namespace Yavsc.Controllers if (string.IsNullOrWhiteSpace (returnUrl)) returnUrl = "/"; Session ["returnUrl"] = returnUrl; - OAuth2 oa = new OAuth2 (AuthGRU,clientId,clientSecret); - oa.Login (Response, SetSessionSate ()); + string state = SetSessionSate (); + Response.Login (state, AuthGRU); } - private string clientId = ConfigurationManager.AppSettings ["GOOGLE_CLIENT_ID"]; - private string clientSecret = ConfigurationManager.AppSettings ["GOOGLE_CLIENT_SECRET"]; - private string clientApiKey = ConfigurationManager.AppSettings ["GOOGLE_API_KEY"]; /// /// Gets the cal auth. /// @@ -93,8 +90,7 @@ namespace Yavsc.Controllers if (string.IsNullOrWhiteSpace (returnUrl)) returnUrl = "/"; Session ["returnUrl"] = returnUrl; - OAuth2 oa = new OAuth2 (CalendarGRU,clientId,clientSecret); - oa.GetCalendarScope (Response, SetSessionSate ()); + Response.CalLogin (SetSessionSate (), CalendarGRU); } /// @@ -107,8 +103,7 @@ namespace Yavsc.Controllers public ActionResult CalAuth () { string msg; - OAuth2 oa = new OAuth2 (CalendarGRU,clientId,clientSecret); - + OAuth2 oa = GoogleHelpers.CreateOAuth2 (CalendarGRU); AuthToken gat = oa.GetToken (Request, (string) Session ["state"], out msg); if (gat == null) { YavscHelpers.Notify(ViewData, msg); @@ -127,6 +122,7 @@ namespace Yavsc.Controllers /// It should be called immediatly after getting the token from Google, in /// order to save a descent value as expiration date. /// + /// pr. /// Gat. private void SaveToken (ProfileBase pr, AuthToken gat) { @@ -145,7 +141,7 @@ namespace Yavsc.Controllers public ActionResult Auth () { string msg; - OAuth2 oa = new OAuth2 (AuthGRU,clientId,clientSecret); + OAuth2 oa = GoogleHelpers.CreateOAuth2 (AuthGRU); AuthToken gat = oa.GetToken (Request, (string)Session ["state"], out msg); if (gat == null) { YavscHelpers.Notify(ViewData, msg); @@ -268,9 +264,7 @@ namespace Yavsc.Controllers returnUrl = Url.Action ("ChooseCalendar") // "ChooseCalendar?returnUrl="+HttpUtility.UrlEncode(returnUrl) }); } - string cred = OAuth2.GetFreshGoogleCredential (HttpContext.Profile); - CalendarApi c = new CalendarApi (clientApiKey); - CalendarList cl = c.GetCalendars (cred); + CalendarList cl = GoogleHelpers.GetCalendars(HttpContext.Profile); ViewData ["returnUrl"] = Session ["chooseCalReturnUrl"]; return View (cl); } @@ -301,7 +295,7 @@ namespace Yavsc.Controllers [Authorize,HttpGet] public ActionResult Book () { - var model = new BookQuery (); + var model = new BookingQuery (); model.StartDate = DateTime.Now; model.EndDate = model.StartDate.AddDays(2); model.StartHour = DateTime.Now.ToString("HH:mm"); @@ -315,49 +309,35 @@ namespace Yavsc.Controllers /// The query. /// Model. [Authorize,HttpPost] - public ActionResult Book (BookQuery model) + public ActionResult Book (BookingQuery model) { + DateTime mindate = DateTime.Now; + if (model.StartDate.Date < mindate.Date){ + ModelState.AddModelError ("StartDate", LocalizedText.FillInAFutureDate); + } + if (model.EndDate < model.StartDate) + ModelState.AddModelError ("EndDate", LocalizedText.StartDateAfterEndDate); + if (ModelState.IsValid) { - DateTime mindate = DateTime.Now; - if (model.StartDate.Date < mindate.Date){ - ModelState.AddModelError ("StartDate", LocalizedText.FillInAFutureDate); - } - if (model.EndDate < model.StartDate) - ModelState.AddModelError ("EndDate", LocalizedText.StartDateAfterEndDate); - - var muc = Membership.FindUsersByName (model.Person); - if (muc.Count == 0) { - ModelState.AddModelError ("Person", LocalizedText.Non_existent_user); - } - if (!Roles.IsUserInRole (model.Role)) { - ModelState.AddModelError ("Role", LocalizedText.UserNotInThisRole); - } - ProfileBase upr = ProfileBase.Create (model.Person); - var gcalid = upr.GetPropertyValue ("gcalid"); - if (gcalid is DBNull) - ModelState.AddModelError ("Person", LocalizedText.No_calendar_for_this_user); - if (ModelState.IsValid) { - string calid = (string) gcalid; - DateTime maxdate = model.EndDate; - CalendarApi c = new CalendarApi (clientApiKey); - CalendarEventList events; - try { - string creds = OAuth2.GetFreshGoogleCredential (upr); - events = c.GetCalendar (calid, mindate, maxdate, creds); - YavscHelpers.Notify (ViewData, "Google calendar API call success"); - } catch (WebException ex) { - string response; - using (var stream = ex.Response.GetResponseStream()) - using (var reader = new StreamReader(stream)) - { - response = reader.ReadToEnd(); + foreach (string rolename in model.Roles) { + foreach (string username in Roles.GetUsersInRole(rolename)) { + try { + var pr = ProfileBase.Create(username); + var events = pr.GetEvents(model.StartDate,model.EndDate); + } catch (WebException ex) { + string response; + using (var stream = ex.Response.GetResponseStream()) + using (var reader = new StreamReader(stream)) + { + response = reader.ReadToEnd(); + } + YavscHelpers.Notify (ViewData, + string.Format( + "Google calendar API exception {0} : {1}
{2}
", + ex.Status.ToString(), + ex.Message, + response)); } - YavscHelpers.Notify (ViewData, - string.Format( - "Google calendar API exception {0} : {1}
{2}
", - ex.Status.ToString(), - ex.Message, - response)); } } } diff --git a/web/Controllers/HomeController.cs b/web/Controllers/HomeController.cs index 80e58123..9b3b5624 100644 --- a/web/Controllers/HomeController.cs +++ b/web/Controllers/HomeController.cs @@ -14,8 +14,6 @@ using Yavsc.Helpers; using Yavsc; using System.Web.Mvc; using Yavsc.Model.Blogs; -using System.Web.Security; -using System.Web.Profile; namespace Yavsc.Controllers { @@ -24,6 +22,21 @@ namespace Yavsc.Controllers ///
public class HomeController : Controller { + // Site name + private static string name = null; + + /// + /// Gets or sets the site name. + /// + /// The name. + [Obsolete("Use YavscHelpers.SiteName insteed.")] + public static string Name { + get { + if (name == null) + name = WebConfigurationManager.AppSettings ["Name"]; + return name; + } + } /// /// Lists the referenced assemblies. @@ -72,23 +85,14 @@ namespace Yavsc.Controllers /// public ActionResult Index () { - if (Session.IsNewSession) { - string uid = (!Request.IsAuthenticated) ? Request.AnonymousID : User.Identity.Name; - ProfileBase pr = - ProfileBase.Create (uid); - bool ac = (bool) pr.GetPropertyValue ("allowcookies"); - if (!ac) - YavscHelpers.Notify (ViewData, LocalizedText.ThisSiteUsesCookies, - "function(){Yavsc.ajax(\"/Yavsc/AllowCookies\", { id:'"+uid+"' });}", - LocalizedText.I_understood); - } - - foreach (string tagname in new string[] {"Accueil","Événements","Mentions légales"}) + foreach (string tagname in new string[] {"Accueil","Yavsc","Événements","Mentions légales"}) { TagInfo ti = BlogManager.GetTagInfo (tagname); // TODO specialyze BlogEntry creating a PhotoEntry ViewData [tagname] = ti; + } + return View (); } /// diff --git a/web/Formatters/FormatterException.cs b/web/Formatters/FormatterException.cs index 08725d8e..13963aae 100644 --- a/web/Formatters/FormatterException.cs +++ b/web/Formatters/FormatterException.cs @@ -50,8 +50,15 @@ namespace Yavsc.Formatters public FormatterException(string message,Exception innerException):base(message,innerException) { } - + /// + /// Gets or sets the output. + /// + /// The output. public string Output { get; set; } + /// + /// Gets or sets the error. + /// + /// The error. public string Error { get; set; } } } diff --git a/web/Helpers/Google/OAuth2.cs b/web/Helpers/Google/OAuth2.cs index 03da8e16..aae35812 100644 --- a/web/Helpers/Google/OAuth2.cs +++ b/web/Helpers/Google/OAuth2.cs @@ -58,6 +58,8 @@ namespace Yavsc.Helpers.Google /// Initializes a new instance of the class. /// /// Redirect URI. + /// Client identifier. + /// Client secret. public OAuth2 (string redirectUri, string clientId, string clientSecret) { RedirectUri = redirectUri; diff --git a/web/Models/App.master b/web/Models/App.master index 0e2e44c2..912738d1 100644 --- a/web/Models/App.master +++ b/web/Models/App.master @@ -2,12 +2,16 @@ <% ViewState["orgtitle"] = Html.Translate(Page.Title); %> -<% Page.Title = ViewState["orgtitle"] + " - " + YavscHelpers.SiteName; %> +<% Page.Title = ViewState["orgtitle"] + " - " + YavscHelpers.SiteName; +Page.Theme = (string) Profile.UITheme; +Page.StyleSheetTheme = (string) Profile.UITheme; %> - + + +" /> " /> " /> " /> @@ -15,14 +19,16 @@ " /> - + +<%=Ajax.GlobalizationScript()%> + @@ -74,8 +80,6 @@ else {%> Yavsc.notice(<%=note.body%>, <%=note.click_action%>, <%=note.click_acti - -
© 2015 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 diff --git a/web/Models/AppAdmin.master b/web/Models/AppAdmin.master index ce7c3e06..77f74720 100644 --- a/web/Models/AppAdmin.master +++ b/web/Models/AppAdmin.master @@ -2,12 +2,19 @@ <% ViewState["orgtitle"] = Html.Translate(Page.Title); %> -<% Page.Title = ViewState["orgtitle"] + " - " + YavscHelpers.SiteName; %> +<% Page.Title = ViewState["orgtitle"] + " - " + YavscHelpers.SiteName; +Page.Theme = (string) Profile.UITheme; +Page.StyleSheetTheme = (string) Profile.UITheme; + +%> - + + + +" /> " /> " /> " /> @@ -23,6 +30,7 @@ var apiBaseUrl = '<%=Url.Content(Yavsc.WebApiConfig.UrlPrefixRelative)%>'; + @@ -85,8 +93,6 @@ else {%> Yavsc.notice(<%=note.body%>, <%=note.click_action%>); <% } %> - -
© 2015 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 diff --git a/web/Models/NoLogin.master b/web/Models/NoLogin.master index 0e88e45a..0bb0b48a 100644 --- a/web/Models/NoLogin.master +++ b/web/Models/NoLogin.master @@ -2,12 +2,19 @@ <% ViewState["orgtitle"] = Html.Translate(Page.Title); %> -<% Page.Title = ViewState["orgtitle"] + " - " + YavscHelpers.SiteName; %> +<% Page.Title = ViewState["orgtitle"] + " - " + YavscHelpers.SiteName; +Page.Theme = (string) Profile.UITheme; +Page.StyleSheetTheme = (string) Profile.UITheme; + +%> - + + + +" /> " /> " /> " /> @@ -15,14 +22,14 @@ " /> - + +<%=Ajax.GlobalizationScript()%> - @@ -41,7 +48,7 @@ var apiBaseUrl = '<%=Url.Content(Yavsc.WebApiConfig.UrlPrefixRelative)%>'; $(document).ready(function(){ <% foreach (Notification note in (IEnumerable) ViewData ["Notifications"] ) { if (note.click_action == null) {%> Yavsc.notice(<%=note.body%>); <% } -else {%> Yavsc.notice(<%=note.body%>, <%=note.click_action%>); <% } %> +else {%> Yavsc.notice(<%=note.body%>, <%=note.click_action%>, <%=note.click_action_name%>); <% } %> <% } %> }); @@ -51,8 +58,6 @@ else {%> Yavsc.notice(<%=note.body%>, <%=note.click_action%>); <% } %> - -
© 2015 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 diff --git a/web/Scripts/yavsc.circles.js b/web/Scripts/yavsc.circles.js index 6ae47636..ad67f7fa 100644 --- a/web/Scripts/yavsc.circles.js +++ b/web/Scripts/yavsc.circles.js @@ -1,9 +1,6 @@  - -var errspanid="msg"; var CirclesApiUrl = apiBaseUrl + "/Circle"; - function editNewCircle() { if ($('#fncirc').hasClass('hidden')) $('#fncirc').removeClass('hidden') $('#lgdnvcirc').html("Creation d'un cercle"); diff --git a/web/Scripts/yavsc.js b/web/Scripts/yavsc.js index 52b72288..1d936c32 100644 --- a/web/Scripts/yavsc.js +++ b/web/Scripts/yavsc.js @@ -1,7 +1,7 @@ -var Yavsc = (function(apiBaseUrl){ + +var Yavsc = (function(apiBaseUrl){ var self = {}; - self.dumpprops = function (obj) { var str = ""; for(var k in obj) @@ -30,9 +30,11 @@ self.dimiss = function () { $(this).parent().remove(); }; -self.ajax = function (method,data,callback) { +self.ajax = function (method,data,callback,badInputCallback,errorCallBack) { +if (!badInputCallback) badInputCallback=Yavsc.onAjaxBadInput; +if (!errorCallBack) errorCallBack=Yavsc.onAjaxError; $.ajax({ - url: self.apiBaseUrl+method, + url: self.apiBaseUrl+'/'+method, type: "POST", data: data, success: function (response) { @@ -74,7 +76,7 @@ self.onAjaxBadInput = function (data) var errspanid = "Err_" + value.key; var errspan = document.getElementById(errspanid); if (errspan==null) - alert('enoent '+errspanid); + Yavsc.notice('ENOTANODE: '+errspanid); else errspan.innerHTML=value.errors.join("
"); }); diff --git a/web/Scripts/yavsc.tags.js b/web/Scripts/yavsc.tags.js index 0ace63a8..a5b6b31e 100644 --- a/web/Scripts/yavsc.tags.js +++ b/web/Scripts/yavsc.tags.js @@ -1,4 +1,5 @@ -var Tags = (function(apiBaseUrl){ + +var Tags = (function(apiBaseUrl){ var self = {}; self.blogsApiUrl = (apiBaseUrl || '/api') + "/Blogs"; diff --git a/web/Views/Account/Circles.aspx b/web/Views/Account/Circles.aspx index e1f46398..1f156549 100644 --- a/web/Views/Account/Circles.aspx +++ b/web/Views/Account/Circles.aspx @@ -34,8 +34,7 @@ $(function(){ $("#tbc").stupidtable(); }); - - + +
Interface utilisateur +<%= Html.LabelFor(model => model.UITheme) %> : +<%= Html.TextBox("UITheme") %> +<%= Html.ValidationMessage("UITheme", "*") %> +
<% } %> - - +
diff --git a/web/Views/Admin/AddMemberToRole.ascx b/web/Views/Admin/AddMemberToRole.ascx deleted file mode 100644 index bc63fa55..00000000 --- a/web/Views/Admin/AddMemberToRole.ascx +++ /dev/null @@ -1,11 +0,0 @@ -<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> - -<%= Html.ValidationSummary() %> -<% using(Ajax.BeginForm()) - { %> -Nom du rôle : -<%= Html.TextBox( "RoleName" ) %> -<%= Html.ValidationMessage("RoleName", "*") %>
- -<% } %> - diff --git a/web/Views/Admin/AddRole.aspx b/web/Views/Admin/AddRole.aspx index ded10055..3f9f40da 100644 --- a/web/Views/Admin/AddRole.aspx +++ b/web/Views/Admin/AddRole.aspx @@ -9,7 +9,6 @@ Nom du rôle : <%= Html.ValidationMessage("RoleName", "*") %>
<% } %> -<%= Html.Partial("AddMemberToRole")%> diff --git a/web/Views/Admin/Admin.aspx b/web/Views/Admin/Admin.aspx index aec1c763..6dba1dcd 100644 --- a/web/Views/Admin/Admin.aspx +++ b/web/Views/Admin/Admin.aspx @@ -6,7 +6,10 @@ <% foreach (string u in (string[])ViewData["admins"]) { %> <% } %> diff --git a/web/Views/Admin/RoleList.aspx b/web/Views/Admin/RoleList.aspx index 613ffead..8706a1dc 100644 --- a/web/Views/Admin/RoleList.aspx +++ b/web/Views/Admin/RoleList.aspx @@ -1,4 +1,6 @@ <%@ Page Title="Liste des rôles" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/AppAdmin.master" %> + + Roles:
    diff --git a/web/Views/Admin/UserList.aspx b/web/Views/Admin/UserList.aspx index c329ef09..a4a875e6 100644 --- a/web/Views/Admin/UserList.aspx +++ b/web/Views/Admin/UserList.aspx @@ -6,8 +6,18 @@
      <%foreach (MembershipUser user in Model){ %>
    • <%=user.UserName%> (created <%=user.CreationDate.ToString("D")%>) <%=user.Email%> <%=(user.IsApproved)?"":"("+LocalizedText.Not_Approuved+")"%> <%=user.IsOnline?LocalizedText.Online:LocalizedText.Offline%> +
      + Roles : +
        + <%foreach (string role in Roles.GetRolesForUser(user.UserName)){ %> +
      • <%=role%>
      • + <% } %> +
      + + <% if (Roles.IsUserInRole("Admin")) { %> - <%= Html.ActionLink(LocalizedText.Remove,"RemoveUser", new { username = user.UserName }, new { @class="actionlink" } ) %> + <%= Html.ActionLink(LocalizedText.Remove,"RemoveUser", new { username = user.UserName, returnUrl = Request.Url.PathAndQuery }, new { @class="actionlink" } ) %> + <%= Html.ActionLink("Blogger","AddUserToRole", new { username = user.UserName, rolename="Blogger", returnUrl = Request.Url.PathAndQuery }, new { @class="actionlink" } ) %> <% } %>
    • <% }%>
    diff --git a/web/Views/Admin/UsersInRole.aspx b/web/Views/Admin/UsersInRole.aspx index a294ef8c..d2ffc7e0 100644 --- a/web/Views/Admin/UsersInRole.aspx +++ b/web/Views/Admin/UsersInRole.aspx @@ -1,11 +1,21 @@ -<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %> - - - - - - -
    +<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" Title="UsersInRoleOf" MasterPageFile="~/Models/AppAdmin.master" %> + +<% ViewState["orgtitle"] = string.Format ( LocalizedText.UsersInRole , Html.Encode(ViewData["RoleName"])); %> +<% Page.Title = ViewState["orgtitle"] + " - " + YavscHelpers.SiteName; %> -
    - + + +

    "> +<%=ViewState["orgtitle"]%> +- "><%= YavscHelpers.SiteName %> +

    +
    + +
      + <%foreach (string username in (string[]) ViewData["UsersInRole"]){ %> +
    • <%= username %>
    • + <% } %> +
    + +<%= Html.Partial("AddUserToRole") %> +
    \ No newline at end of file diff --git a/web/Views/BackOffice/Index.aspx b/web/Views/BackOffice/Index.aspx index 66563f3f..3f7b78be 100644 --- a/web/Views/BackOffice/Index.aspx +++ b/web/Views/BackOffice/Index.aspx @@ -1,9 +1,9 @@ <%@ Page Title="Back office" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> - -
    • <%= Html.ActionLink("Catalog","Catalog","FrontOffice" ) %> -
    + +
  • <%= Html.ActionLink(LocalizedText.Skill,"Skills","FrontOffice" ) %>
  • +
diff --git a/web/Views/Blogs/Edit.aspx b/web/Views/Blogs/Edit.aspx index db3aba3e..5b0a9dc7 100644 --- a/web/Views/Blogs/Edit.aspx +++ b/web/Views/Blogs/Edit.aspx @@ -12,8 +12,13 @@ + -<% using(Html.BeginForm("ValidateEdit","Blogs")) { %> +<% using(Html.BeginForm("Edit","Blogs")) { %>
Contrôle d'accès au Billet <%= Html.LabelFor(model => model.Visible) %> : <%= Html.CheckBox( "Visible" ) %> @@ -234,10 +239,5 @@ var data = new FormData($('#frmajax').get()[0]); - \ No newline at end of file diff --git a/web/Views/Blogs/Index.aspx b/web/Views/Blogs/Index.aspx index 67e0ad52..49eb8665 100644 --- a/web/Views/Blogs/Index.aspx +++ b/web/Views/Blogs/Index.aspx @@ -8,6 +8,9 @@

" class="usertitleref"><%=Html.Encode(g.Key)%>

<% foreach (var p in g) { %>
+<% if (p.Photo != null ) { %> +<%=p.Photo%> +<% } %>

<%= Html.Markdown(p.Intro,"/bfiles/"+p.Id+"/") %>

<%= Html.Partial("PostActions",p)%>
<% } %> diff --git a/web/Views/Blogs/PostActions.ascx b/web/Views/Blogs/PostActions.ascx index befcdb55..6c2d12e3 100644 --- a/web/Views/Blogs/PostActions.ascx +++ b/web/Views/Blogs/PostActions.ascx @@ -1,11 +1,14 @@ <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> -
-<%= u %> <%= Html.ActionLink("Remove","RemoveFromRole",new { username = u, rolename="Admin", returnUrl = Request.Url.PathAndQuery })%> +<%= u %> +<%= Html.ActionLink("Remove","RemoveFromRole", +new { username = u, rolename="Admin", returnUrl = Request.Url.PathAndQuery })%> +
- - - - - - - - - - -<% int lc=0; - if (Model.Lines!=null) - foreach (Writting wr in Model.Lines) { lc++; %> -row" id="wr<%=wr.Id%>"> - - - - - - -<% } %> - -
<%=Yavsc.Model.LocalizedText.Description%><%=Yavsc.Model.LocalizedText.Product_reference%><%=Yavsc.Model.LocalizedText.Count%><%=Yavsc.Model.LocalizedText.Unitary_cost%>
<%=wr.Description%><%=wr.ProductReference%><%=wr.Count%><%=wr.UnitaryCost%> - -
-<% } %> -<% } %> - - - - - - -
/// true if visible; otherwise, false. public bool Visible { get; set ; } + + /// + /// Gets or sets the rate. + /// + /// The rate. + public int Rate { get; set; } + + /// + /// Gets or sets the circles allowed to read this ticket. + /// An empty collection specifies a public post. + /// + /// The circles. + [Display(Name="Cercles autorisés")] + public long[] AllowedCircles { get; set; } + + /// + /// Gets or sets the tags. + /// + /// The tags. + public string [] Tags { get; set ; } } } diff --git a/yavscModel/Blogs/BasePostInfo.cs b/yavscModel/Blogs/BasePostInfo.cs index f4f34749..f1d45b4c 100644 --- a/yavscModel/Blogs/BasePostInfo.cs +++ b/yavscModel/Blogs/BasePostInfo.cs @@ -37,6 +37,21 @@ namespace Yavsc.Model.Blogs /// The intro. ///
public string Intro; + + public bool Truncated; + public BasePostInfo (BlogEntry be) + { + Title = be.Title; + Id = be.Id; + Posted = be.Posted; + Modified = be.Modified; + Intro = MarkdownHelper.MarkdownIntro (be.Content, out Truncated); + Photo = be.Photo; + Tags = be.Tags; + AllowedCircles = be.AllowedCircles; + Visible = be.Visible; + Rate = be.Rate; + } } } diff --git a/yavscModel/Blogs/BlogEntry.cs b/yavscModel/Blogs/BlogEntry.cs index e46809e0..b6644e4e 100644 --- a/yavscModel/Blogs/BlogEntry.cs +++ b/yavscModel/Blogs/BlogEntry.cs @@ -11,22 +11,7 @@ namespace Yavsc.Model.Blogs /// Blog entry. ///
public class BlogEntry : BasePost { - - - /// - /// Gets or sets the circles allowed to read this ticket. - /// An empty collection specifies a public post. - /// - /// The circles. - [Display(Name="Cercles autorisés")] - public long[] AllowedCircles { get; set; } - - /// - /// Gets or sets the tags. - /// - /// The tags. - public string [] Tags { get; set ; } - + string content; /// @@ -34,7 +19,6 @@ namespace Yavsc.Model.Blogs /// /// The content. [DisplayName("Corps du billet")] - [Required(ErrorMessage = "S'il vous plait, saisissez un texte.")] public string Content { get { return content; diff --git a/yavscModel/Blogs/BlogEntryCollection.cs b/yavscModel/Blogs/BlogEntryCollection.cs index 02b48d17..1f8bc3e3 100644 --- a/yavscModel/Blogs/BlogEntryCollection.cs +++ b/yavscModel/Blogs/BlogEntryCollection.cs @@ -84,19 +84,10 @@ namespace Yavsc.Model.Blogs /// public IEnumerable> GroupByTitle () { - bool truncated; return from be in this orderby be.Posted descending - group - new BasePostInfo { Author = be.Author, Id = be.Id, - Posted = be.Posted, Modified = be.Modified, - Intro = MarkdownHelper.MarkdownIntro (be.Content, out truncated), - Visible = be.Visible, - Photo = be.Photo - } - by be.Title - into titlegroup - select titlegroup; + group new BasePostInfo(be) by be.Title + into titlegroup select titlegroup; } /// @@ -105,19 +96,10 @@ namespace Yavsc.Model.Blogs /// The by user. public IEnumerable> GroupByUser () { - bool truncated; return from be in this orderby be.Posted descending group - new BasePostInfo { - Title = be.Title, - Id = be.Id, - Posted = be.Posted, - Modified = be.Modified, - Intro = MarkdownHelper.MarkdownIntro (be.Content, out truncated), - Photo = be.Photo, - Visible = be.Visible - } + new BasePostInfo (be) by be.Author into usergroup select usergroup; diff --git a/yavscModel/Blogs/BlogHelper.cs b/yavscModel/Blogs/BlogHelper.cs deleted file mode 100644 index 21579cc4..00000000 --- a/yavscModel/Blogs/BlogHelper.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Configuration; -using System.Reflection; -using System.Collections.Specialized; - -namespace Yavsc.Model.Blogs -{ - /// - /// Blog helper. - /// - public static class BlogHelper - { - /// - /// Gets the provider. - /// - /// The provider. - public static BlogProvider GetProvider () - { - DataProviderConfigurationSection config = ConfigurationManager.GetSection ("system.web/blog") as DataProviderConfigurationSection; - if (config == null) - throw new ConfigurationErrorsException("The configuration bloc for the blog provider was not found"); - ProviderSettings celt = - config.Providers[config.DefaultProvider]; - if (config == null) - throw new ConfigurationErrorsException("The default blog provider was not found"); - ConstructorInfo ci = Type.GetType (celt.Type).GetConstructor (Type.EmptyTypes); - BlogProvider bp = ci.Invoke (Type.EmptyTypes) as BlogProvider; - bp.Initialize (celt.Name, celt.Parameters); - return bp; - } - - - } - -} diff --git a/yavscModel/Blogs/BlogManager.cs b/yavscModel/Blogs/BlogManager.cs index 5242baaf..f4b3dceb 100644 --- a/yavscModel/Blogs/BlogManager.cs +++ b/yavscModel/Blogs/BlogManager.cs @@ -12,11 +12,21 @@ using System.Collections.Generic; namespace Yavsc.Model.Blogs { + /// /// Blog manager. /// - public static class BlogManager + public static class BlogManager { + static BlogProvider provider = null; + static BlogProvider Provider { + get { + if (provider == null) + provider = ManagerHelper.GetDefaultProvider + ("system.web/blog"); + return provider; + } + } /// /// Removes the comment. /// @@ -39,20 +49,6 @@ namespace Yavsc.Model.Blogs Provider.Comment (from, postid, content); } - static BlogProvider provider; - - /// - /// Gets the provider. - /// - /// The provider. - public static BlogProvider Provider { - get { - if (provider == null) - provider = BlogHelper.GetProvider (); - return provider; - } - } - /// /// Gets the post. /// @@ -99,7 +95,10 @@ namespace Yavsc.Model.Blogs { Provider.UpdatePost (postid, title, content, visible, cids); } - + public static void UpdatePost (BlogEntry be) + { + Provider.UpdatePost (be); + } /// /// Updates the post photo. /// @@ -152,9 +151,22 @@ namespace Yavsc.Model.Blogs } Provider.RemoveTitle (username, title); } - public static TagInfo GetTagInfo(string tagname) + /// + /// Gets the tag info. + /// + /// The tag info. + /// Tagname. + /// Page index. + /// Page size. + public static TagInfo GetTagInfo(string tagname, int pageIndex=0, int pageSize=50) { - return Provider.GetTagInfo (tagname); + var res = new TagInfo (tagname); + int recordCount = 0; + var posts = Provider.FindPost (null,tagname,FindBlogEntryFlags.MatchTag,pageIndex,pageSize,out recordCount); + res.Titles = posts.GroupByTitle ().ToArray(); + res.Name = tagname; + // out int recordCount , + return res; } /// /// Lasts the posts. @@ -192,9 +204,9 @@ namespace Yavsc.Model.Blogs } - public static void Note (long postid, int note) + public static void Rate (long postid, int rate) { - Provider.Note (postid, note); + Provider.Rate (postid, rate); } /// diff --git a/yavscModel/Blogs/BlogProvider.cs b/yavscModel/Blogs/BlogProvider.cs index ce929ef5..f7f4b921 100644 --- a/yavscModel/Blogs/BlogProvider.cs +++ b/yavscModel/Blogs/BlogProvider.cs @@ -19,12 +19,6 @@ namespace Yavsc.Model.Blogs /// Postid. public abstract BlogEntry GetPost (long postid); - /// - /// Gets the tag info. - /// - /// The tag info. - /// Tagname. - public abstract TagInfo GetTagInfo (string tagname); /// /// Gets the post collection from a given user and at a given title. @@ -50,8 +44,8 @@ namespace Yavsc.Model.Blogs /// Note the specified postid and note. /// /// Postid. - /// Note. - public abstract void Note (long postid, int note); + /// rate. + public abstract void Rate (long postid, int rate); /// @@ -65,6 +59,13 @@ namespace Yavsc.Model.Blogs /// Allowed circles. public abstract void UpdatePost (long postid, string title, string content, bool visible, long[] allowedCircles); + /// + /// Updates the post. + /// + /// Be. + public abstract void UpdatePost ( BlogEntry be ); + + /// /// Finds a post. /// diff --git a/yavscModel/Blogs/TagInfo.cs b/yavscModel/Blogs/TagInfo.cs index 03f67629..cd38c15d 100644 --- a/yavscModel/Blogs/TagInfo.cs +++ b/yavscModel/Blogs/TagInfo.cs @@ -20,13 +20,14 @@ // along with this program. If not, see . using System; using System.Collections.Generic; +using System.Linq; namespace Yavsc.Model.Blogs { /// /// Tag info. /// - public abstract class TagInfo + public class TagInfo { string name; /// @@ -54,7 +55,7 @@ namespace Yavsc.Model.Blogs /// Gets the titles. /// /// The titles. - public abstract IEnumerable Titles { get; } + public IEnumerable> Titles { get; set; } } } diff --git a/yavscModel/Calendar/BookQuery.cs b/yavscModel/Calendar/BookQuery.cs deleted file mode 100644 index 35dd7d21..00000000 --- a/yavscModel/Calendar/BookQuery.cs +++ /dev/null @@ -1,86 +0,0 @@ -// -// AskForADate.cs -// -// Author: -// Paul Schneider -// -// 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 . -using System; -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; - -namespace Yavsc.Model.Calendar -{ - /// - /// Ask for A date. - /// - public class BookQuery - { - - /// - /// Gets or sets the prefered date. - /// - /// The prefered date. - [DataType(DataType.Date)] - [DisplayFormat(DataFormatString = "{0:yyyy/MM/dd}", ApplyFormatInEditMode = true)] - [Display(ResourceType=typeof(LocalizedText),Name="StartDate")] - public DateTime StartDate { get; set; } - - /// - /// Gets or sets the minimum time. - /// - /// The minimum time. - [RegularExpression("\\d\\d:\\d\\d")] - [Display(ResourceType=typeof(LocalizedText),Name="StartHour")] - [Required(ErrorMessage= "S'il vous plait, saisissez une heure de début d'intervention")] - public string StartHour { get; set; } - - /// - /// Gets or sets the max date. - /// - /// The max date. - [Display(Name="EndDate",ResourceType=typeof(LocalizedText))] - [DataType(DataType.Date)] - [DisplayFormat(DataFormatString = "{0:yyyy/MM/dd}", ApplyFormatInEditMode = true)] - public DateTime EndDate { get; set; } - - - /// - /// Gets or sets the minimal duration. - /// - /// The duration. - [RegularExpression("\\d\\d:\\d\\d")] - [Required(ErrorMessage= "S'il vous plait, saisissez une heure de fin d'intervention")] - [Display(Name="EndHour",ResourceType=typeof(LocalizedText))] - public string EndHour { get; set; } - - /// - /// Gets or sets the person. - /// - /// The name of the user. - [Display(Name="Person",ResourceType=typeof(LocalizedText))] - public string Person { get; set; } - - /// - /// Gets or sets the role. - /// - /// The role. - [Required(ErrorMessage= "S'il vous plait, saisissez le type d'intervention souhaité")] - [Display(Name="Role",ResourceType=typeof(LocalizedText))] - public string Role { get; set; } - } -} - diff --git a/yavscModel/Calendar/ICalendarManager.cs b/yavscModel/Calendar/ICalendarManager.cs index 59baf6e4..e82f762f 100644 --- a/yavscModel/Calendar/ICalendarManager.cs +++ b/yavscModel/Calendar/ICalendarManager.cs @@ -25,8 +25,22 @@ using System.Collections.Generic; namespace Yavsc.Model.Calendar { + /// + /// I calendar manager. + /// public interface ICalendarManager { - IFreeDateSet GetFreeDates(string username, BookQuery req); + /// + /// Gets the free dates. + /// + /// The free dates. + /// Username. + /// Req. + IFreeDateSet GetFreeDates(string username, BookingQuery req); + /// + /// Book the specified username and ev. + /// + /// Username. + /// Ev. bool Book(string username, YaEvent ev); } } diff --git a/yavscModel/Calendar/YaEvent.cs b/yavscModel/Calendar/YaEvent.cs index 41f3b1f1..dd3571c7 100644 --- a/yavscModel/Calendar/YaEvent.cs +++ b/yavscModel/Calendar/YaEvent.cs @@ -26,6 +26,9 @@ using Yavsc.Model; namespace Yavsc.Model.Calendar { + /// + /// Base event. + /// public class BaseEvent { /// diff --git a/yavscModel/ChangeLog b/yavscModel/ChangeLog index 805d95be..707d87fe 100644 --- a/yavscModel/ChangeLog +++ b/yavscModel/ChangeLog @@ -1,235 +1,139 @@ -2015-11-04 Paul Schneider +2015-11-17 Paul Schneider - * LocalizedText.resx: - * LocalizedText.fr.resx: - * LocalizedText.Designer.cs: - * LocalizedText.fr.Designer.cs: texts relatives to message or - notification sending + * PerformerProfile.cs: implements a performer profile -2015-11-04 Paul Schneider + * SkillManager.cs: + * SkillProvider.cs: Makes the method rendering skills return a + PerformerProfile object - * BlogManager.cs: - * BlogProvider.cs: + * YavscModel.csproj: replaces the UserSkillProfile with the + PerformerProfile class -2015-11-03 Paul Schneider + * UserSkillProfile.cs: obsolete - * LocalizedText.resx: - * LocalizedText.fr.resx: - * LocalizedText.Designer.cs: - * LocalizedText.fr.Designer.cs: I understood ... +2015-11-17 Paul Schneider - * Notification.cs: a new click action name. - -2015-11-01 Paul Schneider + * IRating.cs: + * IComment.cs: + * IIdentified.cs: + * IAuthorized.cs: + * BasePost.cs: + * SkillProvider.cs: refactorization + * Skill.cs: * YavscModel.csproj: - * PostInfoByUser.cs: - * PostInfoByTitle.cs: - * BlogEntryCollection.cs: refactoring + * UserSkill.cs: + * SkillManager.cs: + * UserSkillRating.cs: + * UserSkillProfile.cs: + * UserSkillReference.cs: + * UserSkillDeclaration.cs: implements the skill data model -2015-11-01 Paul Schneider - - * ProfileEdition.cs: Fixes the username modification - - * LocalizedText.resx: - * LocalizedText.fr.resx: - * LocalizedText.Designer.cs: - * LocalizedText.fr.Designer.cs: WIP booking - - * ChangePasswordModel.cs: - * RegisterClientModel.cs: A regexp for user name - - * LoginModel.cs: A regexp for user name and password - - * Profile.cs: A regexp for user name, and profile usage fixes - - * UserManager.cs: Checks for username availability before - trying to modify it - - * YavscModel.csproj: `ProfileEdition` class addition - - * ChangeLog: useless here - - * BookQuery.cs: Start, end hour and role are required - - * OtherWebException.cs: useless - -2015-10-31 Paul Schneider - - * LocalizedText.resx: - * OtherWebException.cs: - * BookQuery.cs: - * LocalizedText.fr.resx: - * LocalizedText.Designer.cs: - * LocalizedText.fr.Designer.cs: - -2015-10-30 Paul Schneider - - * LocalizedText.resx: - * LocalizedText.fr.resx: - * BookQuery.cs: - * LocalizedText.Designer.cs: - * Link.cs: - * Note.cs: - * Euro.cs: - * Text.cs: - * Unit.cs: - * LocalizedText.fr.Designer.cs: - * Brand.cs: - * Label.cs: - * Scalar.cs: - * Period.cs: - * Option.cs: - * Product.cs: - * Catalog.cs: - * Service.cs: - * SaleForm.cs: - * Currency.cs: - * CheckBox.cs: - * FormInput.cs: - * TextInput.cs: - * SelectItem.cs: - * FilesInput.cs: - * RadioButton.cs: - * StockStatus.cs: - * SelectInput.cs: - * FormElement.cs: - * ProductImage.cs: - * CatalogHelper.cs: - * CatalogManager.cs: - * CatalogProvider.cs: - * PhysicalProduct.cs: - * ProductCategory.cs: - * CatalogProviderConfigurationElement.cs: - * CatalogProvidersConfigurationSection.cs: - * CatalogProvidersConfigurationCollection.cs: - - * WorkFlowManager.cs: - * IContentProvider.cs: - * Price.cs: - * PriceOnItemCount.cs: refactoring: a dedicated name space for - the catalog - -2015-10-29 Paul Schneider - - * YavscModel.csproj: - * Commande.cs: - * WebFileSystemManager.cs: Refactoring the name of the files - manager class - -2015-10-28 Paul Schneider - - * ICalendarManager.cs: WIP booking TODO a calendar provider + * UserSkillComment.cs: defines an user's skill comment + * GDate.cs: * YaEvent.cs: - * IFreeDateSet.cs: WIP booking - - * LocalizedText.resx: - * LocalizedText.fr.resx: - * LocalizedText.Designer.cs: - * LocalizedText.fr.Designer.cs: implements the message "uses - cookies" - - * YavscModel.csproj: refactoring - - * Notification.cs: The Yavsc otification will start as a - Google one ... - many properties are not yet used, but all seems usefull. - -2015-10-27 Paul Schneider - - * YavscModel.csproj: - * LocalizedText.resx: - * FreeDate.cs: - * BookQuery.cs: - * LocalizedText.fr.resx: - * LocalizedText.Designer.cs: - * LocalizedText.fr.Designer.cs: - -2015-10-23 Paul Schneider - - * LocalizedText.resx: - * LocalizedText.fr.resx: - * LocalizedText.Designer.cs: - * LocalizedText.fr.Designer.cs: Existant DB message - -2015-10-22 Paul Schneider - - * LocalizedText.resx: - * LocalizedText.fr.resx: - * LocalizedText.Designer.cs: - * LocalizedText.fr.Designer.cs: Localizes a "bill removal" - -2015-10-19 Paul Schneider - - * YavscModel.csproj: - * MarkdownHelper.cs: - -2015-10-17 Paul Schneider - - * BlogManager.cs: - -2015-10-17 Paul Schneider - - * TagInfo.cs: - * YavscModel.csproj: - * BasePost.cs: - * LocalizedText.resx: - * LocalizedText.fr.resx: * BlogProvider.cs: - * BasePostInfo.cs: - * PostInfoByUser.cs: - * PostInfoByTitle.cs: + * CircleBase.cs: + * Profile.cs: + * CalendarListEntry.cs: + * CalendarEventList.cs: + * UserRole.cs: + * ICalendarManager.cs: + * ProfileEdition.cs: + * LostPasswordModel.cs: + * RegisterClientModel.cs: xmldoc + + * LocalizedText.fr.resx: skills + + * Manager.cs: throws an exception when implementation for the + provider was not found + + * IDataProvider.cs: xml doc + +2015-11-14 Paul Schneider + + * IRated.cs: + * BlogHelper.cs: + * ICalendarManager.cs: + + * Manager.cs: + * BookingQuery.cs: refactoring + + * Manager.cs: + * YavscModel.csproj: + * SkillRating.cs: + * SkillManager.cs: + * SkillRating.cs: + * SkillProvider.cs: + * SkillManager.cs: + * SkillProvider.cs: + * SkillDeclaration.cs: + * SkillDeclaration.cs: VIP skills + + * BasePost.cs: One may rate a bill + + * BlogProvider.cs: The blogs provider takes BlogEntry objects + at Update time + + * LocalizedText.resx: + * LocalizedText.fr.resx: * LocalizedText.Designer.cs: - * LocalizedText.fr.Designer.cs: - * BlogEntryCollection.cs: + * LocalizedText.fr.Designer.cs: WIP skills -2015-10-17 Paul Schneider + * Profile.cs: prettifies the code, as long as the profile + providers does'nt return any more DBNull values - * PostTag.cs: + * BlogManager.cs: Uses the static ManagerHelper class to get + the configuration + +2015-11-11 Paul Schneider + + * BasePost.cs: all BasePost contains a rate + + * BasePostInfo.cs: due to base implementation + + * BlogEntry.cs: code formatting + + * BlogManager.cs: Fixes the taginfo object delivering + + * BlogProvider.cs: refactoring + + * LocalizedText.resx: + * LocalizedText.fr.resx: + * LocalizedText.Designer.cs: + * LocalizedText.fr.Designer.cs: localizes UserInRole + + * LoginModel.cs: enables spaces in the legacy login names + + * Profile.cs: gives users the theme choice + +2015-11-08 Paul Schneider + + * LoginModel.cs: + * UserNameBase.cs: enables legacy login with spaces in the + user name + + * ProfileEdition.cs: xml doc + +2015-11-06 Paul Schneider + + * ChangeLog: + * TagInfo.cs: * BasePost.cs: - * YavscModel.csproj: - * BlogEntry.cs: * LocalizedText.resx: - * Automate.cs: - * LocalizedText.fr.resx: - * LocalizedText.Designer.cs: - * BlogEntryCollection.cs: - * LocalizedText.fr.Designer.cs: - -2015-10-13 Paul Schneider - - * BasePost.cs: refactoring: - allows the "PostActions" user control to use a common base - object as post reference - - * YavscModel.csproj: * BlogEntry.cs: - * BlogEntryCollection.cs: refactoring - - * BlogManager.cs: Makes the blog manager expose of the new - `UnTag` method - - * BlogProvider.cs: introduces a method to `untag` - - * FindBlogEntryFlags.cs: Find post entry by tag - - * LocalizedText.resx: - * LocalizedText.Designer.cs: new translations: - "Tag" - - "Edit" - - - * LocalizedText.fr.resx: - * LocalizedText.fr.Designer.cs: nouvelles traductions: - "Tag" - - "Edit" - - * Profile.cs: a nicer stack trace at buggy usage - -2015-10-10 Paul Schneider - - * YavscModel.csproj: * BlogManager.cs: - * UTBlogEntryCollection.cs: - * UUTBlogEntryCollection.cs: - * FileSystemManager.cs: + * BlogProvider.cs: + * BookQuery.cs: + * BasePostInfo.cs: + * LocalizedText.fr.resx: + * IFreeDateSet.cs: + * LocalizedText.Designer.cs: + * Notification.cs: + * LocalizedText.fr.Designer.cs: + * ICalendarManager.cs: + * BlogEntryCollection.cs: + * ProfileEdition.cs: + * WebFileSystemManager.cs: diff --git a/yavscModel/Circles/CircleBase.cs b/yavscModel/Circles/CircleBase.cs index aba8f55f..1f2175a9 100644 --- a/yavscModel/Circles/CircleBase.cs +++ b/yavscModel/Circles/CircleBase.cs @@ -22,8 +22,14 @@ using System; namespace Yavsc.Model.Circles { + /// + /// Circle base. + /// public class CircleBase { + /// + /// Initializes a new instance of the class. + /// public CircleBase () { } diff --git a/yavscModel/Google/CalendarEventList.cs b/yavscModel/Google/CalendarEventList.cs index 45067363..84f284f9 100644 --- a/yavscModel/Google/CalendarEventList.cs +++ b/yavscModel/Google/CalendarEventList.cs @@ -23,13 +23,22 @@ using System; namespace Yavsc.Model.Google { - + /// + /// Calendar event list. + /// public class CalendarEventList { - + /// + /// The next page token. + /// public string nextPageToken; + /// + /// The next sync token. + /// public string nextSyncToken; - + /// + /// The items. + /// public Resource [] items ; } } diff --git a/yavscModel/Google/CalendarListEntry.cs b/yavscModel/Google/CalendarListEntry.cs index 72e1912b..89265756 100644 --- a/yavscModel/Google/CalendarListEntry.cs +++ b/yavscModel/Google/CalendarListEntry.cs @@ -115,7 +115,9 @@ namespace Yavsc.Model.Google */ } - + /// + /// Reminder. + /// public class Reminder { /// /// Gets or sets the method. diff --git a/yavscModel/Google/GDate.cs b/yavscModel/Google/GDate.cs index 81904ea7..c66fd1be 100644 --- a/yavscModel/Google/GDate.cs +++ b/yavscModel/Google/GDate.cs @@ -23,9 +23,21 @@ using System; namespace Yavsc.Model.Google { + /// + /// G date. + /// public class GDate { + /// + /// The date. + /// public DateTime date; + /// + /// The datetime. + /// public DateTime datetime; + /// + /// The time zone. + /// public string timeZone; } diff --git a/yavscModel/LocalizedText.Designer.cs b/yavscModel/LocalizedText.Designer.cs index 73987ef2..e862efa3 100644 --- a/yavscModel/LocalizedText.Designer.cs +++ b/yavscModel/LocalizedText.Designer.cs @@ -244,6 +244,12 @@ namespace Yavsc.Model { } } + public static string Skills { + get { + return ResourceManager.GetString("Skills", resourceCulture); + } + } + public static string Title { get { return ResourceManager.GetString("Title", resourceCulture); @@ -286,6 +292,12 @@ namespace Yavsc.Model { } } + public static string PhotoUpdated { + get { + return ResourceManager.GetString("PhotoUpdated", resourceCulture); + } + } + public static string Register { get { return ResourceManager.GetString("Register", resourceCulture); @@ -364,6 +376,12 @@ namespace Yavsc.Model { } } + public static string was_added_to_the_role { + get { + return ResourceManager.GetString("was_added_to_the_role", resourceCulture); + } + } + public static string Offline { get { return ResourceManager.GetString("Offline", resourceCulture); @@ -406,9 +424,9 @@ namespace Yavsc.Model { } } - public static string View_source { + public static string Skill { get { - return ResourceManager.GetString("View_source", resourceCulture); + return ResourceManager.GetString("Skill", resourceCulture); } } @@ -436,6 +454,12 @@ namespace Yavsc.Model { } } + public static string View_source { + get { + return ResourceManager.GetString("View_source", resourceCulture); + } + } + public static string EndDate { get { return ResourceManager.GetString("EndDate", resourceCulture); @@ -472,9 +496,9 @@ namespace Yavsc.Model { } } - public static string was_added_to_the_role { + public static string BillUpdated { get { - return ResourceManager.GetString("was_added_to_the_role", resourceCulture); + return ResourceManager.GetString("BillUpdated", resourceCulture); } } @@ -532,6 +556,12 @@ namespace Yavsc.Model { } } + public static string BillCreated { + get { + return ResourceManager.GetString("BillCreated", resourceCulture); + } + } + public static string StartDate { get { return ResourceManager.GetString("StartDate", resourceCulture); @@ -544,6 +574,12 @@ namespace Yavsc.Model { } } + public static string UsersInRole { + get { + return ResourceManager.GetString("UsersInRole", resourceCulture); + } + } + public static string DB { get { return ResourceManager.GetString("DB", resourceCulture); diff --git a/yavscModel/LocalizedText.fr.Designer.cs b/yavscModel/LocalizedText.fr.Designer.cs index 4eea0cad..c393f315 100644 --- a/yavscModel/LocalizedText.fr.Designer.cs +++ b/yavscModel/LocalizedText.fr.Designer.cs @@ -100,12 +100,6 @@ namespace Yavsc.Model { } } - public static string Not_Approuved { - get { - return ResourceManager.GetString("Not Approuved", resourceCulture); - } - } - public static string UserNotInThisRole { get { return ResourceManager.GetString("UserNotInThisRole", resourceCulture); @@ -172,6 +166,12 @@ namespace Yavsc.Model { } } + public static string Remember_me { + get { + return ResourceManager.GetString("Remember_me", resourceCulture); + } + } + public static string access_denied { get { return ResourceManager.GetString("access_denied", resourceCulture); @@ -238,6 +238,12 @@ namespace Yavsc.Model { } } + public static string Skills { + get { + return ResourceManager.GetString("Skills", resourceCulture); + } + } + public static string Title { get { return ResourceManager.GetString("Title", resourceCulture); @@ -352,6 +358,12 @@ namespace Yavsc.Model { } } + public static string was_added_to_the_role { + get { + return ResourceManager.GetString("was_added_to_the_role", resourceCulture); + } + } + public static string Offline { get { return ResourceManager.GetString("Offline", resourceCulture); @@ -394,9 +406,9 @@ namespace Yavsc.Model { } } - public static string View_source { + public static string Skill { get { - return ResourceManager.GetString("View_source", resourceCulture); + return ResourceManager.GetString("Skill", resourceCulture); } } @@ -424,6 +436,12 @@ namespace Yavsc.Model { } } + public static string View_source { + get { + return ResourceManager.GetString("View_source", resourceCulture); + } + } + public static string EndDate { get { return ResourceManager.GetString("EndDate", resourceCulture); @@ -442,9 +460,9 @@ namespace Yavsc.Model { } } - public static string Remember_me { + public static string Not_Approuved { get { - return ResourceManager.GetString("Remember_me", resourceCulture); + return ResourceManager.GetString("Not Approuved", resourceCulture); } } @@ -460,9 +478,9 @@ namespace Yavsc.Model { } } - public static string was_added_to_the_role { + public static string BillUpdated { get { - return ResourceManager.GetString("was_added_to_the_role", resourceCulture); + return ResourceManager.GetString("BillUpdated", resourceCulture); } } @@ -520,6 +538,12 @@ namespace Yavsc.Model { } } + public static string BillCreated { + get { + return ResourceManager.GetString("BillCreated", resourceCulture); + } + } + public static string StartDate { get { return ResourceManager.GetString("StartDate", resourceCulture); @@ -532,6 +556,12 @@ namespace Yavsc.Model { } } + public static string UsersInRole { + get { + return ResourceManager.GetString("UsersInRole", resourceCulture); + } + } + public static string DB { get { return ResourceManager.GetString("DB", resourceCulture); diff --git a/yavscModel/LocalizedText.fr.resx b/yavscModel/LocalizedText.fr.resx index 4806efc9..668e8573 100644 --- a/yavscModel/LocalizedText.fr.resx +++ b/yavscModel/LocalizedText.fr.resx @@ -19,6 +19,8 @@ lui présentant votre demande. Vous devriez être contacté très rapidement. Édition d'un billet Suppression d'un billet + Billet créé + Billet mis à jour Consultant Nombre Chiffre @@ -79,6 +81,8 @@ Se souvenir du mot de passe Supprimer Rôle créé + Compétence + Compétences Date de début La date de fin doit être postérieure à la date de début. Heure de début @@ -90,10 +94,11 @@ Coût unitaire Liste des utilisateurs Nom d'utilisateur + Liste des utilisateurs assumant le rôle "{0}" Le rôle demandé n'est pas assumé par ce préstataire Voir le texte source du billet a été ajouté au rôle - Il n'y avait pas 'utilisateur dans le rôle '{1}'. Vous ({0}) avez été ajouté au rôle '{1}'. + Il n'y avait pas d'utilisateur dans le rôle "{1}". Vous ({0}) avez été ajouté au rôle "{1}". Bienvenue {0} à été notifié de votre demande, vous devriez être contacté rapidement Au vu de son calendrier, diff --git a/yavscModel/LocalizedText.resx b/yavscModel/LocalizedText.resx index 02aa3ca3..bae9ef10 100644 --- a/yavscModel/LocalizedText.resx +++ b/yavscModel/LocalizedText.resx @@ -12,12 +12,16 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + additionally Access denied An instant message has been sent to {0}, showing to him your query. You should be contacted very soon. Bill edition Bill removal + Bill created + Bill updated + Photo updated Create Count Ciffer @@ -81,6 +85,8 @@ Remove Role role created + Skill + Skills Start date Submit Start hour @@ -93,10 +99,11 @@ Unitary_cost User List User name + List of users assuming the role "{0}" This user is not in this role View source was added to the role - There was no user in the '{1}' role. You ({0}) was just added as firt user in the '{1}' role. + There was no user in the "{1}" role. You ({0}) was just added as firt user in the "{1}" role. Welcome {0} has been notified of your query, you should be fast contacted regarding his calendar, diff --git a/yavscModel/RolesAndMembers/LoginModel.cs b/yavscModel/RolesAndMembers/LoginModel.cs index 13f8e76c..5bd401a4 100644 --- a/yavscModel/RolesAndMembers/LoginModel.cs +++ b/yavscModel/RolesAndMembers/LoginModel.cs @@ -14,8 +14,8 @@ namespace Yavsc.Model.RolesAndMembers /// /// The name of the user. [DisplayName("Nom d'utilisateur"), - Required(ErrorMessage = "S'il vous plait, entrez un nom d'utilisateur ([a-z]|[A-Z]|[-_.~]|[0-9])+"), - RegularExpression("([a-z]|[A-Z]|[0-9])+")] + Required(ErrorMessage = "S'il vous plait, entrez un nom d'utilisateur ([a-z]|[A-Z]|[-_.~]|[0-9]|\\s)+"), + RegularExpression("([a-z]|[A-Z]|[0-9]|\\s)+")] public string UserName { get; set; } /// diff --git a/yavscModel/RolesAndMembers/LostPasswordModel.cs b/yavscModel/RolesAndMembers/LostPasswordModel.cs index 70e05136..c98fce04 100644 --- a/yavscModel/RolesAndMembers/LostPasswordModel.cs +++ b/yavscModel/RolesAndMembers/LostPasswordModel.cs @@ -22,9 +22,20 @@ using System; namespace Yavsc.Model.RolesAndMembers { + /// + /// Lost password model. + /// public class LostPasswordModel { + /// + /// Gets or sets the name of the user. + /// + /// The name of the user. public string UserName { get; set; } + /// + /// Gets or sets the email. + /// + /// The email. public string Email { get; set; } } } diff --git a/yavscModel/RolesAndMembers/Profile.cs b/yavscModel/RolesAndMembers/Profile.cs index 44fd02bd..1816cd82 100644 --- a/yavscModel/RolesAndMembers/Profile.cs +++ b/yavscModel/RolesAndMembers/Profile.cs @@ -36,6 +36,13 @@ namespace Yavsc.Model.RolesAndMembers [StringLength (2047)] public string Address { get; set; } + /// + /// Gets or sets the user interface theme. + /// + /// The user interface theme. + [DisplayName ("Thème")] + [StringLength (2047)] + public string UITheme { get; set; } /// /// Gets or sets the state of the city and. /// @@ -241,64 +248,27 @@ namespace Yavsc.Model.RolesAndMembers /// Profile. public Profile (ProfileBase profile) { - if (profile == null) - throw new Exception ("No profile"); - - object b = profile.GetPropertyValue ("BlogVisible"); - BlogVisible = (b == null) ? true : (b is DBNull)? true : (bool)b; - - object s = profile.GetPropertyValue ("BlogTitle"); - BlogTitle = (s is DBNull) ? null : (string)s; - - s = profile.GetPropertyValue ("Avatar"); - avatar = (s is DBNull) ? null : (string)s; - - - s = profile.GetPropertyValue ("Address"); - Address = (s is DBNull) ? null : (string)s; - - s = profile.GetPropertyValue ("CityAndState"); - CityAndState = (s is DBNull) ? null : (string)s; - - s = profile.GetPropertyValue ("Country"); - Country = (s is DBNull) ? null : (string)s; - - s = profile.GetPropertyValue ("ZipCode"); - ZipCode = (s is DBNull) ? null : (string)s; - - s = profile.GetPropertyValue ("WebSite"); - WebSite = (s is DBNull) ? null : (string)s; - - s = profile.GetPropertyValue ("Name"); - Name = (s is DBNull) ? null : (string)s; - - s = profile.GetPropertyValue ("Phone"); - Phone = (s is DBNull) ? null : (string)s; - - s = profile.GetPropertyValue ("Mobile"); - Mobile = (s is DBNull) ? null : (string)s; - + if (profile == null) throw new Exception ("No profile"); userName = profile.UserName; - - s = profile.GetPropertyValue ("BankCode"); - BankCode = (s is DBNull) ? null : (string)s; - - s = profile.GetPropertyValue ("IBAN"); - IBAN = (s is DBNull) ? null : (string)s; - - s = profile.GetPropertyValue ("BIC"); - BIC = (s is DBNull) ? null : (string)s; - - s = profile.GetPropertyValue ("WicketCode"); - WicketCode = (s is DBNull) ? null : (string)s; - - s = profile.GetPropertyValue ("AccountNumber"); - AccountNumber = (s is DBNull) ? null : (string)s; - - object o = profile.GetPropertyValue ("BankedKey"); - BankedKey = (int)0; - s = profile.GetPropertyValue ("gcalid"); - GoogleCalendar = (s is DBNull)? null : (string) s; + UITheme = (string) profile.GetPropertyValue ("UITheme"); + BlogVisible = (bool) profile.GetPropertyValue ("BlogVisible"); + BlogTitle = (string) profile.GetPropertyValue ("BlogTitle"); + avatar = (string) profile.GetPropertyValue ("Avatar"); + Address = (string) profile.GetPropertyValue ("Address"); + CityAndState = (string) profile.GetPropertyValue ("CityAndState"); + Country = (string) profile.GetPropertyValue ("Country"); + ZipCode = (string) profile.GetPropertyValue ("ZipCode"); + WebSite = (string) profile.GetPropertyValue ("WebSite"); + Name = (string) profile.GetPropertyValue ("Name"); + Phone = (string) profile.GetPropertyValue ("Phone"); + Mobile = (string) profile.GetPropertyValue ("Mobile"); + BankCode = (string)profile.GetPropertyValue ("BankCode"); + IBAN = (string)profile.GetPropertyValue ("IBAN"); + BIC = (string)profile.GetPropertyValue ("BIC"); + WicketCode = (string) profile.GetPropertyValue ("WicketCode"); + AccountNumber = (string) profile.GetPropertyValue ("AccountNumber"); + BankedKey = (int) profile.GetPropertyValue ("BankedKey");; + GoogleCalendar = (string) profile.GetPropertyValue ("gcalid"); } } } diff --git a/yavscModel/RolesAndMembers/ProfileEdition.cs b/yavscModel/RolesAndMembers/ProfileEdition.cs index 3f45bb1b..d21ec033 100644 --- a/yavscModel/RolesAndMembers/ProfileEdition.cs +++ b/yavscModel/RolesAndMembers/ProfileEdition.cs @@ -25,8 +25,14 @@ using System.Web.Profile; namespace Yavsc.Model.RolesAndMembers { + /// + /// Profile edition. + /// public class ProfileEdition : Profile { + /// + /// Initializes a new instance of the class. + /// public ProfileEdition() {} @@ -36,6 +42,10 @@ namespace Yavsc.Model.RolesAndMembers NewUserName = UserName; } + /// + /// Gets or sets the new name of the user. + /// + /// The new name of the user. [Localizable(true), Required(ErrorMessage = "S'il vous plait, entrez un nom d'utilisateur valide") ,Display(ResourceType=typeof(LocalizedText),Name="User_name"), RegularExpression("([a-z]|[A-Z]|[\\s-_.~]|[0-9])+") diff --git a/yavscModel/RolesAndMembers/RegisterClientModel.cs b/yavscModel/RolesAndMembers/RegisterClientModel.cs index b36ea829..50b2b437 100644 --- a/yavscModel/RolesAndMembers/RegisterClientModel.cs +++ b/yavscModel/RolesAndMembers/RegisterClientModel.cs @@ -69,8 +69,16 @@ namespace Yavsc.Model.RolesAndMembers [DisplayName("Téléphone mobile")] public string Mobile { get; set; } + /// + /// Gets or sets the question. + /// + /// The question. public string Question { get; set; } + /// + /// Gets or sets the answer. + /// + /// The answer. public string Answer { get; set; } } } diff --git a/yavscModel/RolesAndMembers/RegisterModel.cs b/yavscModel/RolesAndMembers/RegisterModel.cs index de2bbd77..b8feb6c8 100644 --- a/yavscModel/RolesAndMembers/RegisterModel.cs +++ b/yavscModel/RolesAndMembers/RegisterModel.cs @@ -25,19 +25,11 @@ using System.ComponentModel.DataAnnotations; namespace Yavsc.Model.RolesAndMembers { - /// /// Register view model. /// - public class RegisterModel + public class RegisterModel: UserNameBase { - /// - /// Gets or sets the name of the user. - /// - /// The name of the user. - [Localizable(true), Required(ErrorMessage = "S'il vous plait, entrez un nom d'utilisateur") - ,Display(ResourceType=typeof(LocalizedText),Name="User_name")] - public string UserName { get; set; } /// /// Gets or sets the password. diff --git a/yavscModel/WorkFlow/IDataProvider.cs b/yavscModel/WorkFlow/IDataProvider.cs index d86e8361..84dc0bbd 100644 --- a/yavscModel/WorkFlow/IDataProvider.cs +++ b/yavscModel/WorkFlow/IDataProvider.cs @@ -4,9 +4,20 @@ using Yavsc.Model.FrontOffice; namespace Yavsc.Model.WorkFlow { + /// + /// I data provider. + /// public interface IDataProvider { + /// + /// Get the specified id. + /// + /// Identifier. T Get (long id); + /// + /// Update the specified data. + /// + /// Data. void Update (T data); } diff --git a/yavscModel/YavscModel.csproj b/yavscModel/YavscModel.csproj index 5780f8f9..04986a3e 100644 --- a/yavscModel/YavscModel.csproj +++ b/yavscModel/YavscModel.csproj @@ -62,7 +62,6 @@ - LocalizedText.fr.resx @@ -172,12 +171,29 @@ - + + + + + + + + + + + + + + + + + + @@ -193,6 +209,7 @@ + diff --git a/yavscclient/ChangeLog b/yavscclient/ChangeLog index 9090fcd6..f9032943 100644 --- a/yavscclient/ChangeLog +++ b/yavscclient/ChangeLog @@ -1,14 +1,4 @@ -2015-10-30 Paul Schneider +2015-11-06 Paul Schneider - * MyClass.cs: refactoring: a dedicated name space for the - catalog - -2015-07-15 Paul Schneider - - * YavscClient.csproj: Moves to Mono framework - -2015-06-09 Paul Schneider - - * YavscClient.csproj: Helps to fix packaging, and cleans - dependencies + * ChangeLog: