diff --git a/Builder/IISMainHandler/build.txt b/Builder/IISMainHandler/build.txt index 4701cc7..147ea53 100644 --- a/Builder/IISMainHandler/build.txt +++ b/Builder/IISMainHandler/build.txt @@ -1 +1 @@ -150 \ No newline at end of file +158 \ No newline at end of file diff --git a/Common/Common.csproj b/Common/Common.csproj index d56721e..921c810 100644 --- a/Common/Common.csproj +++ b/Common/Common.csproj @@ -50,6 +50,9 @@ + + + diff --git a/Common/UserContext.cs b/Common/UserContext.cs index 1cfe564..bebdf25 100644 --- a/Common/UserContext.cs +++ b/Common/UserContext.cs @@ -20,6 +20,16 @@ namespace FLocal.Common { get; } + abstract public string formatDateTime(DateTime dateTime); + + } + + public static class UserContext_Extensions { + + public static string ToString(this DateTime dateTime, UserContext context) { + return context.formatDateTime(dateTime); + } + } } diff --git a/Common/dataobjects/Board.cs b/Common/dataobjects/Board.cs index 39757a2..54bece4 100644 --- a/Common/dataobjects/Board.cs +++ b/Common/dataobjects/Board.cs @@ -5,6 +5,7 @@ using System.Text; using System.Xml.Linq; using FLocal.Core; using FLocal.Core.DB; +using FLocal.Core.DB.conditions; namespace FLocal.Common.dataobjects { public class Board : SqlObject { @@ -55,6 +56,11 @@ namespace FLocal.Common.dataobjects { return this._lastPostId; } } + public Post lastPost { + get { + return Post.LoadById(this.lastPostId.Value); + } + } private int _totalPosts; public int totalPosts { @@ -138,16 +144,19 @@ namespace FLocal.Common.dataobjects { select board; } } + internal void subBoards_Reset() { + Cache>.instance.delete(this.subBoards_Locker); + } private bool hasNewPosts() { return Core.Util.RandomInt(0, 1000) < 500; } - private XElement exportLastPostInfo() { + private XElement exportLastPostInfo(UserContext context) { if(!this.lastPostId.HasValue) { return new XElement("none"); } else { - throw new NotImplementedException(); + return this.lastPost.exportToXmlWithoutThread(context); } } @@ -169,8 +178,8 @@ namespace FLocal.Common.dataobjects { new XElement("totalThreads", this.totalThreads), new XElement("name", this.name), new XElement("description", this.description), - new XElement("hasNewPosts", this.hasNewPosts() ? "true" : "false"), - new XElement("lastPostInfo", this.exportLastPostInfo()) + new XElement("hasNewPosts", this.hasNewPosts().ToPlainString()), + new XElement("lastPostInfo", this.exportLastPostInfo(context)) ); if(includeSubBoards) { @@ -182,5 +191,30 @@ namespace FLocal.Common.dataobjects { return result; } + public IEnumerable getThreads(Diapasone diapasone, UserContext context) { + return Thread.LoadByIds( + from stringId in Config.instance.mainConnection.LoadIdsByConditions( + Thread.TableSpec.instance, + new ComparisonCondition( + Thread.TableSpec.instance.getColumnSpec(Thread.TableSpec.FIELD_BOARDID), + ComparisonType.EQUAL, + this.id.ToString() + ), + diapasone, + new JoinSpec[0], + new SortSpec[] { + new SortSpec( + Thread.TableSpec.instance.getColumnSpec(Thread.TableSpec.FIELD_ISANNOUNCEMENT), + false + ), + new SortSpec( + Thread.TableSpec.instance.getColumnSpec(Thread.TableSpec.FIELD_LASTPOSTDATE), + true + ), + } + ) select int.Parse(stringId) + ); + } + } } diff --git a/Common/dataobjects/Category.cs b/Common/dataobjects/Category.cs index 3c9c413..56c4df4 100644 --- a/Common/dataobjects/Category.cs +++ b/Common/dataobjects/Category.cs @@ -95,6 +95,9 @@ namespace FLocal.Common.dataobjects { select board; } } + internal void subBoards_Reset() { + Cache>.instance.delete(this.subBoards_Locker); + } public XElement exportToXmlSimple(UserContext context) { return new XElement("category", diff --git a/Common/dataobjects/Post.cs b/Common/dataobjects/Post.cs new file mode 100644 index 0000000..5b63cc6 --- /dev/null +++ b/Common/dataobjects/Post.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml.Linq; +using FLocal.Core; +using FLocal.Core.DB; + +namespace FLocal.Common.dataobjects { + public class Post : SqlObject { + + public class TableSpec : FLocal.Core.DB.ITableSpec { + public const string TABLE = "Posts"; + public const string FIELD_ID = "Id"; + public const string FIELD_POSTERID = "PosterId"; + public const string FIELD_POSTDATE = "PostDate"; + public const string FIELD_LASTCHANGEDATE = "LastChangeDate"; + public const string FIELD_REVISION = "Revision"; + public const string FIELD_LAYER = "Layer"; + public const string FIELD_TITLE = "Title"; + public const string FIELD_BODY = "Body"; + public const string FIELD_THREADID = "ThreadId"; + public static readonly TableSpec instance = new TableSpec(); + public string name { get { return TABLE; } } + public string idName { get { return FIELD_ID; } } + } + + protected override FLocal.Core.DB.ITableSpec table { get { return TableSpec.instance; } } + + private int _posterId; + public int posterId { + get { + this.LoadIfNotLoaded(); + return this._posterId; + } + } + public User poster { + get { + this.LoadIfNotLoaded(); + return User.LoadById(this.posterId); + } + } + + private DateTime _postDate; + public DateTime postDate { + get { + this.LoadIfNotLoaded(); + return this._postDate; + } + } + + private DateTime? _lastChangeDate; + public DateTime? lastChangeDate { + get { + this.LoadIfNotLoaded(); + return this._lastChangeDate; + } + } + + private int _revision; + public int revision { + get { + this.LoadIfNotLoaded(); + return this._revision; + } + } + + private int _layer; + public int layer { + get { + this.LoadIfNotLoaded(); + return this._layer; + } + } + + private string _title; + public string title { + get { + this.LoadIfNotLoaded(); + return this._title; + } + } + + private string _body; + public string body { + get { + this.LoadIfNotLoaded(); + return this._body; + } + } + + private int _threadId; + public int threadId { + get { + this.LoadIfNotLoaded(); + return this._threadId; + } + } + public Thread thread { + get { + return Thread.LoadById(this.threadId); + } + } + + protected override void doFromHash(Dictionary data) { + this._posterId = int.Parse(data[TableSpec.FIELD_POSTERID]); + this._postDate = new DateTime(long.Parse(data[TableSpec.FIELD_POSTDATE])); + this._lastChangeDate = Util.ParseDateTimeFromTimestamp(data[TableSpec.FIELD_LASTCHANGEDATE]); + this._revision = int.Parse(data[TableSpec.FIELD_REVISION]); + this._layer = int.Parse(data[TableSpec.FIELD_LAYER]); + this._title = data[TableSpec.FIELD_TITLE]; + this._body = data[TableSpec.FIELD_BODY]; + this._threadId = int.Parse(data[TableSpec.FIELD_THREADID]); + } + + public XElement exportToXmlWithoutThread(UserContext context) { + return new XElement("post", + new XElement("id", this.id), + new XElement("poster", this.poster.exportToXmlForViewing(context)), + new XElement("postDate", this.postDate.ToString(context)), + new XElement("lastChangeDate", this.postDate.ToString(context)), + new XElement("revision", this.revision), + new XElement("layer", this.layer), + new XElement("title", this.title), + new XElement("body", this.body), + new XElement("threadId", this.threadId) + ); + } + + } +} diff --git a/Common/dataobjects/Thread.cs b/Common/dataobjects/Thread.cs new file mode 100644 index 0000000..b341f41 --- /dev/null +++ b/Common/dataobjects/Thread.cs @@ -0,0 +1,170 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml.Linq; +using FLocal.Core; +using FLocal.Core.DB; + +namespace FLocal.Common.dataobjects { + public class Thread : SqlObject { + + public class TableSpec : FLocal.Core.DB.ITableSpec { + public const string TABLE = "Threads"; + public const string FIELD_ID = "Id"; + public const string FIELD_BOARDID = "BoardId"; + public const string FIELD_FIRSTPOSTID = "FirstPostId"; + public const string FIELD_TOPICSTARTERID = "TopicstarterId"; + public const string FIELD_TITLE = "Title"; + public const string FIELD_LASTPOSTID = "LastPostId"; + public const string FIELD_LASTPOSTDATE = "LastPostDate"; + public const string FIELD_ISANNOUNCEMENT = "IsAnnouncement"; + public const string FIELD_ISLOCKED = "IsLocked"; + public const string FIELD_TOTALPOSTS = "TotalPosts"; + public const string FIELD_TOTALVIEWS = "TotalViews"; + public static readonly TableSpec instance = new TableSpec(); + public string name { get { return TABLE; } } + public string idName { get { return FIELD_ID; } } + } + + protected override FLocal.Core.DB.ITableSpec table { get { return TableSpec.instance; } } + + private int _boardId; + public int boardId { + get { + this.LoadIfNotLoaded(); + return this._boardId; + } + } + public Board board { + get { + return Board.LoadById(this.boardId); + } + } + + private int _firstPostId; + public int firstPostId { + get { + this.LoadIfNotLoaded(); + return this._firstPostId; + } + } + public Post firstPost { + get { + return Post.LoadById(this.firstPostId); + } + } + + private int _topicstarterId; + public int topicstarterId { + get { + this.LoadIfNotLoaded(); + return this._topicstarterId; + } + } + public User topicstarter { + get { + return User.LoadById(this.topicstarterId); + } + } + + private string _title; + public string title { + get { + this.LoadIfNotLoaded(); + return this._title; + } + } + + private int _lastPostId; + public int lastPostId { + get { + this.LoadIfNotLoaded(); + return this._lastPostId; + } + } + + private DateTime _lastPostDate; + public DateTime lastPostDate { + get { + this.LoadIfNotLoaded(); + return this._lastPostDate; + } + } + + private bool _isAnnouncement; + public bool isAnnouncement { + get { + this.LoadIfNotLoaded(); + return this._isAnnouncement; + } + } + + private bool _isLocked; + public bool isLocked { + get { + this.LoadIfNotLoaded(); + return this._isAnnouncement; + } + } + + private int _totalPosts; + public int totalPosts { + get { + this.LoadIfNotLoaded(); + return this._totalPosts; + } + } + + private int _totalViews; + public int totalViews { + get { + this.LoadIfNotLoaded(); + return this._totalViews; + } + } + + protected override void doFromHash(Dictionary data) { + this._boardId = int.Parse(data[TableSpec.FIELD_BOARDID]); + this._firstPostId = int.Parse(data[TableSpec.FIELD_FIRSTPOSTID]); + this._topicstarterId = int.Parse(data[TableSpec.FIELD_TOPICSTARTERID]); + this._title = data[TableSpec.FIELD_TITLE]; + this._lastPostId = int.Parse(data[TableSpec.FIELD_LASTPOSTID]); + this._lastPostDate = new DateTime(long.Parse(data[TableSpec.FIELD_LASTPOSTDATE])); + this._isAnnouncement = FLocal.Core.Util.string2bool(data[TableSpec.FIELD_ISANNOUNCEMENT]); + this._isLocked = FLocal.Core.Util.string2bool(data[TableSpec.FIELD_ISLOCKED]); + this._totalPosts = int.Parse(data[TableSpec.FIELD_TOTALPOSTS]); + this._totalViews = int.Parse(data[TableSpec.FIELD_TOTALVIEWS]); + } + + private bool hasNewPosts() { + return Core.Util.RandomInt(0, 1000) < 500; + } + + public XElement exportToXmlSimpleWithParent(UserContext context) { + return new XElement("thread", + new XElement("id", this.id), + new XElement("name", this.title), + new XElement("parent", this.board.exportToXmlSimpleWithParent(context)) + ); + } + + public XElement exportToXml(UserContext context) { + return new XElement("thread", + new XElement("id", this.id), + new XElement("firstPostId", this.firstPost.exportToXmlWithoutThread(context)), + new XElement("topicstarter", this.topicstarter.exportToXmlForViewing(context)), + new XElement("title", this.title), + new XElement("lastPostId", this.lastPostId), + new XElement("lastPostDate", this.lastPostDate.ToString(context)), + new XElement("isAnnouncement", this.isAnnouncement), + new XElement("isLocked", this.isLocked), + new XElement("totalPosts", this.totalPosts), + new XElement("totalViews", this.totalViews), + new XElement("hasNewPosts", this.hasNewPosts()), + new XElement("body", this.firstPost.body) + ); + } + + } +} diff --git a/Common/dataobjects/User.cs b/Common/dataobjects/User.cs new file mode 100644 index 0000000..7bf00ef --- /dev/null +++ b/Common/dataobjects/User.cs @@ -0,0 +1,120 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml.Linq; +using FLocal.Core; +using FLocal.Core.DB; + +namespace FLocal.Common.dataobjects { + public class User : SqlObject { + + public class TableSpec : FLocal.Core.DB.ITableSpec { + public const string TABLE = "Users"; + public const string FIELD_ID = "Id"; + public const string FIELD_REGDATE = "RegDate"; + public const string FIELD_TOTALPOSTS = "TotalPosts"; + public const string FIELD_SIGNATURE = "Signature"; + public const string FIELD_TITLE = "Title"; + public const string FIELD_LOCATION = "Location"; + public const string FIELD_NAME = "Name"; + public const string FIELD_USERGROUPID = "UserGroupId"; + public const string FIELD_SHOWPOSTSTOUSERS = "ShowPostsToUsers"; + public static readonly TableSpec instance = new TableSpec(); + public string name { get { return TABLE; } } + public string idName { get { return FIELD_ID; } } + } + + protected override FLocal.Core.DB.ITableSpec table { get { return TableSpec.instance; } } + + private DateTime _regDate; + public DateTime regDate { + get { + this.LoadIfNotLoaded(); + return this._regDate; + } + } + + private int _totalPosts; + public int totalPosts { + get { + this.LoadIfNotLoaded(); + return this._totalPosts; + } + } + + private string _signature; + public string signature { + get { + this.LoadIfNotLoaded(); + return this._signature; + } + } + + private string _title; + public string title { + get { + this.LoadIfNotLoaded(); + return this._title; + } + } + + private string _location; + public string location { + get { + this.LoadIfNotLoaded(); + return this._location; + } + } + + private string _name; + public string name { + get { + this.LoadIfNotLoaded(); + return this._name; + } + } + + private int _userGroupId; + public int userGroupId { + get { + this.LoadIfNotLoaded(); + return this._userGroupId; + } + } + + private string _showPostsToUsers; + public string showPostsToUsers { + get { + this.LoadIfNotLoaded(); + return this._showPostsToUsers; + } + } + + protected override void doFromHash(Dictionary data) { + this._regDate = new DateTime(long.Parse(data[TableSpec.FIELD_REGDATE])); + this._totalPosts = int.Parse(data[TableSpec.FIELD_TOTALPOSTS]); + this._signature = data[TableSpec.FIELD_SIGNATURE]; + this._title = data[TableSpec.FIELD_TITLE]; + this._location = data[TableSpec.FIELD_LOCATION]; + this._name = data[TableSpec.FIELD_NAME]; + this._userGroupId = int.Parse(data[TableSpec.FIELD_USERGROUPID]); + this._showPostsToUsers = data[TableSpec.FIELD_SHOWPOSTSTOUSERS]; + } + + public XElement exportToXmlForViewing(UserContext context) { + return new XElement("user", + new XElement("id", this.id), + new XElement("regDate", this.regDate.ToString(context)), + new XElement("totalPosts", this.totalPosts), + new XElement("signature", this.signature), + new XElement("title", this.title), + new XElement("location", this.location), + new XElement("name", this.name), + new XElement("userGroupId", this.userGroupId), + new XElement("showPostsToUsers", this.showPostsToUsers) + ); + } + + } +} diff --git a/Core/Util.cs b/Core/Util.cs index f5223fd..aff1e04 100644 --- a/Core/Util.cs +++ b/Core/Util.cs @@ -120,6 +120,19 @@ namespace FLocal.Core { } } + public static DateTime? ParseDateTimeFromTimestamp(string raw) { + if(raw == "") { + return null; + } else { + long timestamp = long.Parse(raw); + if(timestamp < 1) { + return null; + } else { + return new DateTime(timestamp); + } + } + } + } } diff --git a/Core/extensions/Extensions.cs b/Core/extensions/Extensions.cs index 37dde1a..241f345 100644 --- a/Core/extensions/Extensions.cs +++ b/Core/extensions/Extensions.cs @@ -49,6 +49,10 @@ namespace FLocal.Core { return val ? "Enabled" : "Disabled"; } + public static string ToPlainString(this bool val) { + return val ? "true" : "false"; + } + public static string ToPrintableString(this IEnumerable list) { return string.Join(",", (from elem in list select elem.ToString()).ToArray()); } diff --git a/IISMainHandler/IISMainHandler.csproj b/IISMainHandler/IISMainHandler.csproj index 7009b25..91c0b97 100644 --- a/IISMainHandler/IISMainHandler.csproj +++ b/IISMainHandler/IISMainHandler.csproj @@ -58,6 +58,7 @@ + diff --git a/IISMainHandler/WebContext.cs b/IISMainHandler/WebContext.cs index 48a5f1c..0f3d212 100644 --- a/IISMainHandler/WebContext.cs +++ b/IISMainHandler/WebContext.cs @@ -47,8 +47,15 @@ namespace FLocal.IISHandler { } } + public override string formatDateTime(DateTime dateTime) { + return dateTime.ToString(); + } + + public DateTime requestTime; + public WebContext(HttpContext httpcontext) { this.httpcontext = httpcontext; + this.requestTime = DateTime.Now; } public string Transform(string templateName, System.Xml.Linq.XDocument data) { diff --git a/IISMainHandler/handlers/BoardHandler.cs b/IISMainHandler/handlers/BoardHandler.cs index bde4754..915ee0f 100644 --- a/IISMainHandler/handlers/BoardHandler.cs +++ b/IISMainHandler/handlers/BoardHandler.cs @@ -20,8 +20,9 @@ namespace FLocal.IISHandler.handlers { override protected XElement[] getSpecificData(WebContext context) { Board board = Board.LoadById(int.Parse(context.requestParts[1])); return new XElement[] { - new XElement("currentBoard", board.exportToXmlSimpleWithParent(context)), - new XElement("boards", from subBoard in board.subBoards select subBoard.exportToXml(context, true)) + new XElement("currentLocation", board.exportToXmlSimpleWithParent(context)), + new XElement("boards", from subBoard in board.subBoards select subBoard.exportToXml(context, true)), + new XElement("threads", from thread in board.getThreads(FLocal.Core.DB.Diapasone.unlimited, context) select thread.exportToXml(context)) }; } diff --git a/IISMainHandler/handlers/DebugHandler.cs b/IISMainHandler/handlers/DebugHandler.cs index 695f6c6..39e95b8 100644 --- a/IISMainHandler/handlers/DebugHandler.cs +++ b/IISMainHandler/handlers/DebugHandler.cs @@ -32,6 +32,8 @@ namespace FLocal.IISHandler.handlers { context.httpresponse.WriteLine("description: " + board.description); context.httpresponse.WriteLine("categoryname: " + board.category.name); } + + Thread.LoadById(1).ReLoad(); } } diff --git a/IISMainHandler/handlers/ThreadHandler.cs b/IISMainHandler/handlers/ThreadHandler.cs new file mode 100644 index 0000000..75cb271 --- /dev/null +++ b/IISMainHandler/handlers/ThreadHandler.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; +using System.Xml.Linq; +using FLocal.Common; +using FLocal.Common.dataobjects; + +namespace FLocal.IISHandler.handlers { + + class ThreadHandler : AbstractGetHandler { + + override protected string templateName { + get { + return "Thread.xslt"; + } + } + + override protected XElement[] getSpecificData(WebContext context) { + Board board = Board.LoadById(int.Parse(context.requestParts[1])); + return new XElement[] { + new XElement("currentLocation", board.exportToXmlSimpleWithParent(context)), + new XElement("boards", from subBoard in board.subBoards select subBoard.exportToXml(context, true)) + }; + } + + } + +} \ No newline at end of file diff --git a/MySQLConnector/Connection.cs b/MySQLConnector/Connection.cs index 6b42153..c262112 100644 --- a/MySQLConnector/Connection.cs +++ b/MySQLConnector/Connection.cs @@ -54,7 +54,14 @@ namespace FLocal.MySQLConnector { Dictionary row = new Dictionary(); for(int i=0; i + @@ -12,7 +13,7 @@
+ + + + + + + + + + \ No newline at end of file
- + @@ -97,47 +98,7 @@ - - - - - - - +
Ïîñëåäíåå
- Äàâàéòå âûêëàäûâàòü ñþäà ñâîè ôîòîãðàôèè ñ ïðåòåíçèåé íà õóäîæåñòâåííîñòü èëè ïðîñòî êðàñèâûå. -À ïîòîì ïðîâåäåì êîíêóðñ è äàäèì êàêîé-íòü ïðèç - - Åñëè Âû íàøëè ýòîò òðåä â ìóñîðêå, âåðíèòå åãî ïîæàëóéñòà â Common. Atilla - - - Ñïåöèàëèçèðîâàííûé ñàéò ôîòî-âûñòàâêè: http://hg.b.gz.ru/peg/ by heGoat. - * - - - Ôîòî-âûñòàâêà. - - - 0 - 20 - 4620 - 4640 - Âñå - - - heGoat - - 811077 - - 26633 - - (10) - - - (41) - - - 13.09.2003 15:08 -
@@ -251,17 +212,4 @@
- - - - - - - - - - -
ÒåìûÑîîáùåíèéÏîñëåäíååÌîäåðàòîð
-
- \ No newline at end of file diff --git a/templates/Full/elems/BoardInfo.xslt b/templates/Full/elems/BoardInfo.xslt index e807778..06a808b 100644 --- a/templates/Full/elems/BoardInfo.xslt +++ b/templates/Full/elems/BoardInfo.xslt @@ -60,11 +60,11 @@ -
+
- /Thread/NOTIMPLEMENTED/p/ - îò - + /Thread//e/ + îò +
diff --git a/templates/Full/elems/Main.xslt b/templates/Full/elems/Main.xslt index b0bbe56..d15319f 100644 --- a/templates/Full/elems/Main.xslt +++ b/templates/Full/elems/Main.xslt @@ -38,9 +38,9 @@
- + - + diff --git a/templates/Full/elems/ThreadInfo.xslt b/templates/Full/elems/ThreadInfo.xslt new file mode 100644 index 0000000..6657e7d --- /dev/null +++ b/templates/Full/elems/ThreadInfo.xslt @@ -0,0 +1,64 @@ + + + + +
+ + * + + + /static/images/book-notread.gif + + + /static/images/book-read.gif + + + + + /Thread// + + + + + + + + /Thread//0/ + 0 + + + /Thread//20/ + 20 + + + + + /User// + + #0000ff + + + + + + + + + (10) + + + (41) + + + +