From 2025c058f764d7747110b9784c087f197aa24312 Mon Sep 17 00:00:00 2001 From: inga-lovinde <52715130+inga-lovinde@users.noreply.github.com> Date: Fri, 10 Sep 2010 14:53:22 +0000 Subject: [PATCH] Avatar settings implemented --- Builder/IISMainHandler/build.txt | 2 +- Common/Common.csproj | 1 + Common/TableManager.cs | 1 + Common/actions/ChangeSet.cs | 1 + Common/dataobjects/Account.cs | 7 + Common/dataobjects/AccountSettings.cs | 10 +- Common/dataobjects/AvatarsSettings.cs | 122 ++++++++++++++++++ Common/dataobjects/Upload.cs | 2 + Common/dataobjects/User.cs | 15 +++ IISMainHandler/HandlersFactory.cs | 16 +++ IISMainHandler/IISMainHandler.csproj | 4 + .../handlers/request/avatars/AddHandler.cs | 45 +++++++ .../handlers/request/avatars/RemoveHandler.cs | 35 +++++ .../request/avatars/SetAsDefaultHandler.cs | 39 ++++++ .../response/AvatarsSettingsHandler.cs | 37 ++++++ templates/Full/AvatarsSettings.xslt | 122 ++++++++++++++++++ templates/Full/UploadNew.xslt | 2 +- templates/Full/elems/MyHeader.xslt | 8 ++ templates/Full/result/AvatarAdded.xslt | 48 +++++++ templates/Full/result/AvatarRemoved.xslt | 48 +++++++ templates/Full/result/AvatarSetted.xslt | 48 +++++++ 21 files changed, 607 insertions(+), 6 deletions(-) create mode 100644 Common/dataobjects/AvatarsSettings.cs create mode 100644 IISMainHandler/handlers/request/avatars/AddHandler.cs create mode 100644 IISMainHandler/handlers/request/avatars/RemoveHandler.cs create mode 100644 IISMainHandler/handlers/request/avatars/SetAsDefaultHandler.cs create mode 100644 IISMainHandler/handlers/response/AvatarsSettingsHandler.cs create mode 100644 templates/Full/AvatarsSettings.xslt create mode 100644 templates/Full/result/AvatarAdded.xslt create mode 100644 templates/Full/result/AvatarRemoved.xslt create mode 100644 templates/Full/result/AvatarSetted.xslt diff --git a/Builder/IISMainHandler/build.txt b/Builder/IISMainHandler/build.txt index a65c2ed..0e129d2 100644 --- a/Builder/IISMainHandler/build.txt +++ b/Builder/IISMainHandler/build.txt @@ -1 +1 @@ -1171 \ No newline at end of file +1183 \ No newline at end of file diff --git a/Common/Common.csproj b/Common/Common.csproj index 27e1cb8..8e46de9 100644 --- a/Common/Common.csproj +++ b/Common/Common.csproj @@ -87,6 +87,7 @@ + diff --git a/Common/TableManager.cs b/Common/TableManager.cs index 82d5724..5c270fa 100644 --- a/Common/TableManager.cs +++ b/Common/TableManager.cs @@ -11,6 +11,7 @@ namespace FLocal.Common { dataobjects.Account.TableSpec.instance, dataobjects.AccountIndicator.TableSpec.instance, dataobjects.AccountSettings.TableSpec.instance, + dataobjects.AvatarsSettings.TableSpec.instance, dataobjects.Board.TableSpec.instance, dataobjects.Category.TableSpec.instance, dataobjects.Invite.TableSpec.instance, diff --git a/Common/actions/ChangeSet.cs b/Common/actions/ChangeSet.cs index d8c0b07..25470b7 100644 --- a/Common/actions/ChangeSet.cs +++ b/Common/actions/ChangeSet.cs @@ -26,6 +26,7 @@ namespace FLocal.Common.actions { dataobjects.Account.TableSpec.TABLE, dataobjects.User.TableSpec.TABLE, dataobjects.AccountSettings.TableSpec.TABLE, + dataobjects.AvatarsSettings.TableSpec.TABLE, dataobjects.AccountIndicator.TableSpec.TABLE, dataobjects.PMConversation.TableSpec.TABLE, dataobjects.PMMessage.TableSpec.TABLE, diff --git a/Common/dataobjects/Account.cs b/Common/dataobjects/Account.cs index bdda8a1..196b590 100644 --- a/Common/dataobjects/Account.cs +++ b/Common/dataobjects/Account.cs @@ -279,6 +279,13 @@ namespace FLocal.Common.dataobjects { { User.TableSpec.FIELD_SHOWPOSTSTOUSERS, new ScalarFieldValue(User.ENUM_SHOWPOSTSTOUSERS_ALL) }, }, this.user.id + ), + new InsertChange( + AvatarsSettings.TableSpec.instance, + new Dictionary { + { AvatarsSettings.TableSpec.FIELD_ACCOUNTID, new ScalarFieldValue(this.id.ToString()) }, + { AvatarsSettings.TableSpec.FIELD_AVATARS, new ScalarFieldValue(this.user.avatarId.HasValue ? this.user.avatarId.ToString() : "") }, + } ) }); } diff --git a/Common/dataobjects/AccountSettings.cs b/Common/dataobjects/AccountSettings.cs index 1eb289e..1f2681f 100644 --- a/Common/dataobjects/AccountSettings.cs +++ b/Common/dataobjects/AccountSettings.cs @@ -144,19 +144,21 @@ namespace FLocal.Common.dataobjects { } public static void Save(Account account, int postsPerPage, int threadsPerPage, int usersPerPage, int uploadsPerPage, Skin skin) { - Dictionary data = new Dictionary { - { TableSpec.FIELD_ACCOUNTID, new ScalarFieldValue(account.id.ToString()) }, + Dictionary dataToUpdate = new Dictionary { { TableSpec.FIELD_POSTSPERPAGE, new ScalarFieldValue(postsPerPage.ToString()) }, { TableSpec.FIELD_THREADSPERPAGE, new ScalarFieldValue(threadsPerPage.ToString()) }, { TableSpec.FIELD_USERSPERPAGE, new ScalarFieldValue(usersPerPage.ToString()) }, { TableSpec.FIELD_UPLOADSPERPAGE, new ScalarFieldValue(uploadsPerPage.ToString()) }, { TableSpec.FIELD_SKINID, new ScalarFieldValue(skin.id.ToString()) }, }; + Dictionary dataToInsert = new Dictionary(dataToUpdate) { + { TableSpec.FIELD_ACCOUNTID, new ScalarFieldValue(account.id.ToString()) }, + }; ChangeSetUtil.ApplyChanges( new InsertOrUpdateChange( TableSpec.instance, - data, - data, + dataToInsert, + dataToUpdate, new ComparisonCondition( TableSpec.instance.getColumnSpec(TableSpec.FIELD_ACCOUNTID), ComparisonType.EQUAL, diff --git a/Common/dataobjects/AvatarsSettings.cs b/Common/dataobjects/AvatarsSettings.cs new file mode 100644 index 0000000..8c08736 --- /dev/null +++ b/Common/dataobjects/AvatarsSettings.cs @@ -0,0 +1,122 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml.Linq; +using FLocal.Core; +using FLocal.Core.DB; +using FLocal.Core.DB.conditions; +using FLocal.Common.actions; + +namespace FLocal.Common.dataobjects { + public class AvatarsSettings : SqlObject { + + public class TableSpec : ISqlObjectTableSpec { + public const string TABLE = "Accounts_AvatarsSettings"; + public const string FIELD_ID = "Id"; + public const string FIELD_ACCOUNTID = "AccountId"; + public const string FIELD_AVATARS = "Avatars"; + public static readonly TableSpec instance = new TableSpec(); + public string name { get { return TABLE; } } + public string idName { get { return FIELD_ID; } } + public void refreshSqlObject(int id) { Refresh(id); } + } + + protected override ISqlObjectTableSpec table { get { return TableSpec.instance; } } + + private int _accountId; + public int accountId { + get { + this.LoadIfNotLoaded(); + return this._accountId; + } + } + public Account account { + get { + return Account.LoadById(this._accountId); + } + } + + private HashSet _avatarsIds; + public HashSet avatarsIds { + get { + this.LoadIfNotLoaded(); + return new HashSet(this._avatarsIds); + } + } + public IEnumerable avatars { + get { + return from avatarId in this.avatarsIds select Upload.LoadById(avatarId); + } + } + + protected override void doFromHash(Dictionary data) { + this._accountId = int.Parse(data[TableSpec.FIELD_ACCOUNTID]); + this._avatarsIds = new HashSet(from stringId in data[TableSpec.FIELD_AVATARS].Split(',') select int.Parse(stringId)); + } + + private static readonly Dictionary accountid2id = new Dictionary(); + public static AvatarsSettings LoadByAccount(Account account) { + if(!accountid2id.ContainsKey(account.id)) { + lock(accountid2id) { + if(!accountid2id.ContainsKey(account.id)) { + accountid2id[account.id] = int.Parse( + Config.instance.mainConnection.LoadIdByField( + TableSpec.instance.getColumnSpec(TableSpec.FIELD_ACCOUNTID), + account.id.ToString() + ) + ); + } + } + } + return AvatarsSettings.LoadById(accountid2id[account.id]); + } + + private static void Save(Account account, HashSet avatars) { + Dictionary dataToUpdate = new Dictionary { + { TableSpec.FIELD_AVATARS, new ScalarFieldValue(avatars.Join(",")) }, + }; + Dictionary dataToInsert = new Dictionary(dataToUpdate) { + { TableSpec.FIELD_ACCOUNTID, new ScalarFieldValue(account.id.ToString()) }, + }; + ChangeSetUtil.ApplyChanges( + new InsertOrUpdateChange( + TableSpec.instance, + dataToInsert, + dataToUpdate, + new ComparisonCondition( + TableSpec.instance.getColumnSpec(TableSpec.FIELD_ACCOUNTID), + ComparisonType.EQUAL, + account.id.ToString() + ) + ) + ); + } + + private static HashSet SafeGetAvatars(Account account) { + try { + return AvatarsSettings.LoadByAccount(account).avatarsIds; + } catch(NotFoundInDBException) { + return new HashSet(); + } + } + + public static void AddAvatar(Account account, Upload avatar) { + + if(avatar.size > Upload.AVATAR_MAX_FILESIZE) throw new FLocalException("Avatar is too big (max. 80KB allowed)"); + + HashSet avatars = SafeGetAvatars(account); + avatars.Add(avatar.id); + + Save(account, avatars); + } + + public static void RemoveAvatar(Account account, Upload avatar) { + HashSet avatars = SafeGetAvatars(account); + avatars.Remove(avatar.id); + + Save(account, avatars); + } + + } +} diff --git a/Common/dataobjects/Upload.cs b/Common/dataobjects/Upload.cs index eee7842..48ef94c 100644 --- a/Common/dataobjects/Upload.cs +++ b/Common/dataobjects/Upload.cs @@ -10,6 +10,8 @@ using FLocal.Core.DB.conditions; namespace FLocal.Common.dataobjects { public class Upload : SqlObject { + public const int AVATAR_MAX_FILESIZE = 80*1024; + public class TableSpec : ISqlObjectTableSpec { public const string TABLE = "Uploads"; public const string FIELD_ID = "Id"; diff --git a/Common/dataobjects/User.cs b/Common/dataobjects/User.cs index a9b82cf..7c0334b 100644 --- a/Common/dataobjects/User.cs +++ b/Common/dataobjects/User.cs @@ -327,5 +327,20 @@ namespace FLocal.Common.dataobjects { ); } + public void SetAvatar(Upload avatar) { + + if((avatar != null) && (avatar.size > Upload.AVATAR_MAX_FILESIZE)) throw new FLocalException("Avatar is too big (max. 80KB allowed)"); + + ChangeSetUtil.ApplyChanges( + new UpdateChange( + TableSpec.instance, + new Dictionary { + { TableSpec.FIELD_AVATARID, new ScalarFieldValue((avatar != null) ? avatar.id.ToString() : null) }, + }, + this.id + ) + ); + } + } } diff --git a/IISMainHandler/HandlersFactory.cs b/IISMainHandler/HandlersFactory.cs index f2fc524..f7bcb2f 100644 --- a/IISMainHandler/HandlersFactory.cs +++ b/IISMainHandler/HandlersFactory.cs @@ -102,6 +102,8 @@ namespace FLocal.IISHandler { return new handlers.response.SettingsHandler(); case "userdata": return new handlers.response.UserDataHandler(); + case "avatars": + return new handlers.response.AvatarsSettingsHandler(); case "conversations": if(context.requestParts.Length == 2) { return new handlers.response.ConversationsHandler(); @@ -238,6 +240,20 @@ namespace FLocal.IISHandler { return new handlers.request.CreatePollHandler(); case "vote": return new handlers.request.VoteHandler(); + case "avatars": + if(context.requestParts.Length < 3) { + return new handlers.WrongUrlHandler(); + } + switch(context.requestParts[2].ToLower()) { + case "add": + return new handlers.request.avatars.AddHandler(); + case "remove": + return new handlers.request.avatars.RemoveHandler(); + case "setasdefault": + return new handlers.request.avatars.SetAsDefaultHandler(); + default: + return new handlers.WrongUrlHandler(); + } case "maintenance": if(context.requestParts.Length < 3) { return new handlers.WrongUrlHandler(); diff --git a/IISMainHandler/IISMainHandler.csproj b/IISMainHandler/IISMainHandler.csproj index 8245d18..e14a606 100644 --- a/IISMainHandler/IISMainHandler.csproj +++ b/IISMainHandler/IISMainHandler.csproj @@ -144,8 +144,12 @@ + + + + diff --git a/IISMainHandler/handlers/request/avatars/AddHandler.cs b/IISMainHandler/handlers/request/avatars/AddHandler.cs new file mode 100644 index 0000000..56aaf80 --- /dev/null +++ b/IISMainHandler/handlers/request/avatars/AddHandler.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml.Linq; +using FLocal.Common.dataobjects; +using FLocal.Importer; +using System.Text.RegularExpressions; +using FLocal.Core; +using FLocal.Common; +using FLocal.Common.actions; +using System.Web; + +namespace FLocal.IISHandler.handlers.request.avatars { + class AddHandler : AbstractPostHandler { + + protected override string templateName { + get { + return "result/AvatarAdded.xslt"; + } + } + + protected override XElement[] Do(WebContext context) { + Upload upload; + if(context.httprequest.Files["file"] != null && context.httprequest.Files["file"].ContentLength > 0) { + HttpPostedFile file = context.httprequest.Files["file"]; + if(file.ContentLength != file.InputStream.Length) throw new FLocalException("file is not uploaded completely"); + try { + upload = UploadManager.UploadFile(file.InputStream, System.IO.Path.GetFileName(file.FileName), DateTime.Now, context.session.account.user, null); + } catch(UploadManager.AlreadyUploadedException e) { + upload = Upload.LoadById(e.uploadId); + } + } else { + upload = Upload.LoadById(int.Parse(context.httprequest.Form["uploadId"])); + } + + AvatarsSettings.AddAvatar(context.account, upload); + + return new XElement[] { + new XElement("uploadedId", upload.id) + }; + } + + } +} diff --git a/IISMainHandler/handlers/request/avatars/RemoveHandler.cs b/IISMainHandler/handlers/request/avatars/RemoveHandler.cs new file mode 100644 index 0000000..377081c --- /dev/null +++ b/IISMainHandler/handlers/request/avatars/RemoveHandler.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml.Linq; +using FLocal.Common.dataobjects; +using FLocal.Importer; +using System.Text.RegularExpressions; +using FLocal.Core; +using FLocal.Common; +using FLocal.Common.actions; +using System.Web; + +namespace FLocal.IISHandler.handlers.request.avatars { + class RemoveHandler : AbstractPostHandler { + + protected override string templateName { + get { + return "result/AvatarRemoved.xslt"; + } + } + + protected override XElement[] Do(WebContext context) { + + Upload upload = Upload.LoadById(int.Parse(context.httprequest.Form["uploadId"])); + + AvatarsSettings.RemoveAvatar(context.account, upload); + + return new XElement[] { + new XElement("uploadedId", upload.id) + }; + } + + } +} diff --git a/IISMainHandler/handlers/request/avatars/SetAsDefaultHandler.cs b/IISMainHandler/handlers/request/avatars/SetAsDefaultHandler.cs new file mode 100644 index 0000000..e5d3d69 --- /dev/null +++ b/IISMainHandler/handlers/request/avatars/SetAsDefaultHandler.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml.Linq; +using FLocal.Common.dataobjects; +using FLocal.Importer; +using System.Text.RegularExpressions; +using FLocal.Core; +using FLocal.Common; +using FLocal.Common.actions; +using System.Web; + +namespace FLocal.IISHandler.handlers.request.avatars { + class SetAsDefaultHandler : AbstractPostHandler { + + protected override string templateName { + get { + return "result/AvatarSetted.xslt"; + } + } + + protected override XElement[] Do(WebContext context) { + + Upload upload = null; + + if(!string.IsNullOrEmpty(context.httprequest.Form["uploadId"])) { + upload = Upload.LoadById(int.Parse(context.httprequest.Form["uploadId"])); + } + + context.account.user.SetAvatar(upload); + + return new XElement[] { + (upload != null) ? new XElement("uploadedId", upload.id) : null + }; + } + + } +} diff --git a/IISMainHandler/handlers/response/AvatarsSettingsHandler.cs b/IISMainHandler/handlers/response/AvatarsSettingsHandler.cs new file mode 100644 index 0000000..af51875 --- /dev/null +++ b/IISMainHandler/handlers/response/AvatarsSettingsHandler.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; +using System.Xml.Linq; +using FLocal.Core; +using FLocal.Common; +using FLocal.Common.dataobjects; + +namespace FLocal.IISHandler.handlers.response { + + class AvatarsSettingsHandler : AbstractGetHandler { + + override protected string templateName { + get { + return "AvatarsSettings.xslt"; + } + } + + override protected IEnumerable getSpecificData(WebContext context) { + + AvatarsSettings settings = null; + try { + settings = AvatarsSettings.LoadByAccount(context.account); + int accountId = settings.accountId; //just to make sure it is loaded + } catch(NotFoundInDBException) { + } + + return new XElement[] { + (settings != null) ? new XElement("avatars", from avatar in settings.avatars select avatar.exportToXml(context)) : null, + (context.account.user.avatarId.HasValue) ? new XElement("currentAvatar", context.account.user.avatar.exportToXml(context)) : null, + }; + } + } + +} \ No newline at end of file diff --git a/templates/Full/AvatarsSettings.xslt b/templates/Full/AvatarsSettings.xslt new file mode 100644 index 0000000..21655de --- /dev/null +++ b/templates/Full/AvatarsSettings.xslt @@ -0,0 +1,122 @@ + + + + Íàñòðîéêà àâàòàðîê + + + + + +
+ + + + + + + + + + +
+ Íàñòðîéêà àâàòàðîê +
+

Âàøè àâàòàðêè:

+ +
+
+ + + + disabled + + +
+
+
+
+ + + + +
+ + + + + + + + + + +
+ Âûáåðèòå àâàòàðêó äëÿ çàãðóçêè +
+ Ìàêñèìàëüíûé ðàçìåð ôàéëà – 80ÊÁ, äîïóñòèìûå ðàçðåøåíèÿ: gif, jpg, png, svg, jpe, jpeg, jfif, jif +
+
+
+ +
+
+
+
+ + + + +
+ + + + + + + +
+ Èëè óêàæèòå íîìåð ôàéëà â àïëîàäå +
+
+
+ +
+
+
+
+ + + + + + + +
+ + /Upload/Item// + + +
+ + + + + + disabled + + +

+
+ + + + + + disabled + + +
+
+
+ +
\ No newline at end of file diff --git a/templates/Full/UploadNew.xslt b/templates/Full/UploadNew.xslt index 2ade259..6d4976f 100644 --- a/templates/Full/UploadNew.xslt +++ b/templates/Full/UploadNew.xslt @@ -16,7 +16,7 @@ Âûáåðèòå ôàéë äëÿ çàãðóçêè
- Ìàêñèìàëüíûé ðàçìåð ôàéëà – 1ÌÁ, äîïóñòèìûå ðàçðåøåíèÿ: gif, jpg, png + Ìàêñèìàëüíûé ðàçìåð ôàéëà – 1ÌÁ, äîïóñòèìûå ðàçðåøåíèÿ: gif, jpg, png, svg, jpe, jpeg, jfif, jif diff --git a/templates/Full/elems/MyHeader.xslt b/templates/Full/elems/MyHeader.xslt index d9e48d6..b89d418 100644 --- a/templates/Full/elems/MyHeader.xslt +++ b/templates/Full/elems/MyHeader.xslt @@ -53,6 +53,14 @@ | + + /My/Avatars/ + Àâàòàðêè + + true + + + | /Users/User//Info/ diff --git a/templates/Full/result/AvatarAdded.xslt b/templates/Full/result/AvatarAdded.xslt new file mode 100644 index 0000000..1e6ef2e --- /dev/null +++ b/templates/Full/result/AvatarAdded.xslt @@ -0,0 +1,48 @@ + + + + Äîáàâëåíèå àâàòàðêè + + + + + + + + +
+ + + + +
+ Äîáàâëåíèå àâàòàðêè +
+
+ + + + +
+

Âàøà àâàòàðêà áûëà óñïåøíî çàãðóæåíà

+

+ [←] + + /My/Avatars/ + Âåðíóòüñÿ ê íàñòðîéêàì àâàòàðîê + + | + + /Upload/Item/ + Ïðîñìîòðåòü àâàòàðêó + + [→] +

+ +
+
+
+ +
\ No newline at end of file diff --git a/templates/Full/result/AvatarRemoved.xslt b/templates/Full/result/AvatarRemoved.xslt new file mode 100644 index 0000000..425e0fb --- /dev/null +++ b/templates/Full/result/AvatarRemoved.xslt @@ -0,0 +1,48 @@ + + + + Óäàëåíèå àâàòàðêè + + + + + + + + +
+ + + + +
+ Óäàëåíèå àâàòàðêè +
+
+ + + + +
+

Âàøà àâàòàðêà áûëà óñïåøíî óäàëåíà. Òåì íå ìåíåå, â àïëîàäå îíà îñòàëàñü - àâàòàðêè óäàëÿþòñÿ òîëüêî èç ñïèñêà àâàòàðîê.

+

+ [←] + + /My/Avatars/ + Âåðíóòüñÿ ê íàñòðîéêàì àâàòàðîê + + | + + /Upload/Item/ + Ïðîñìîòðåòü óäàë¸ííóþ àâàòàðêó + + [→] +

+ +
+
+
+ +
\ No newline at end of file diff --git a/templates/Full/result/AvatarSetted.xslt b/templates/Full/result/AvatarSetted.xslt new file mode 100644 index 0000000..b3cc5bf --- /dev/null +++ b/templates/Full/result/AvatarSetted.xslt @@ -0,0 +1,48 @@ + + + + Èçìåíåíèå àâàòàðêè + + + + + + + + +
+ + + + +
+ Èçìåíåíèå àâàòàðêè +
+
+ + + + +
+

Íîâàÿ àâàòàðêà áûëà óñïåøíî óñòàíîâëåíà

+

+ [←] + + /My/Avatars/ + Âåðíóòüñÿ ê íàñòðîéêàì àâàòàðîê + + | + + /Upload/Item/ + Ïðîñìîòðåòü àâàòàðêó + + [→] +

+ +
+
+
+ +
\ No newline at end of file