Avatars implemented; avatars importing implemented; ShallerConnector refactored

main
Inga 🏳‍🌈 14 years ago
parent e9d03cc18b
commit d6efb7e789
  1. 2
      Builder/IISMainHandler/build.txt
  2. 2
      Builder/IISUploadHandler/build.txt
  3. 2
      Common/actions/UpdateChange.cs
  4. 8
      Common/dataobjects/Upload.cs
  5. 21
      Common/dataobjects/User.cs
  6. 7
      ImportConsole/Program.cs
  7. 37
      ImportConsole/UsersImporter.cs
  8. 17
      Importer/FileInfo.cs
  9. 1
      Importer/Importer.csproj
  10. 50
      Importer/ShallerConnector.cs
  11. 24
      Importer/ShallerGateway.cs
  12. BIN
      static/images/noavatar.gif
  13. 11
      templates/Full/UserInfo.xslt
  14. 14
      templates/Full/elems/UserInfoBar.xslt

@ -5,7 +5,7 @@ using System.Text;
using FLocal.Core.DB;
namespace FLocal.Common.actions {
class UpdateChange : AbstractChange {
public class UpdateChange : AbstractChange {
private readonly int id;

@ -67,8 +67,8 @@ namespace FLocal.Common.dataobjects {
}
}
private int? _userId;
public int? userId {
private int _userId;
public int userId {
get {
this.LoadIfNotLoaded();
return this._userId;
@ -76,7 +76,7 @@ namespace FLocal.Common.dataobjects {
}
public User user {
get {
return User.LoadById(this.userId.Value);
return User.LoadById(this.userId);
}
}
@ -86,7 +86,7 @@ namespace FLocal.Common.dataobjects {
this._size = int.Parse(data[TableSpec.FIELD_SIZE]);
this._filename = data[TableSpec.FIELD_FILENAME];
this._uploadDate = Util.ParseDateTimeFromTimestamp(data[TableSpec.FIELD_UPLOADDATE]).Value;
this._userId = Util.ParseInt(data[TableSpec.FIELD_USERID]);
this._userId = int.Parse(data[TableSpec.FIELD_USERID]);
}
public XElement exportToXml(UserContext context) {

@ -22,6 +22,7 @@ namespace FLocal.Common.dataobjects {
public const string FIELD_USERGROUPID = "UserGroupId";
public const string FIELD_SHOWPOSTSTOUSERS = "ShowPostsToUsers";
public const string FIELD_BIOGRAPHY = "Biography";
public const string FIELD_AVATARID = "AvatarId";
public static readonly TableSpec instance = new TableSpec();
public string name { get { return TABLE; } }
public string idName { get { return FIELD_ID; } }
@ -102,6 +103,19 @@ namespace FLocal.Common.dataobjects {
}
}
private int? _avatarId;
public int? avatarId {
get {
this.LoadIfNotLoaded();
return this._avatarId;
}
}
public Upload avatar {
get {
return Upload.LoadById(this.avatarId.Value);
}
}
private static Dictionary<string, int> id2user = new Dictionary<string,int>();
public static User LoadByName(string name) {
if(!id2user.ContainsKey(name)) {
@ -140,10 +154,11 @@ namespace FLocal.Common.dataobjects {
this._userGroupId = int.Parse(data[TableSpec.FIELD_USERGROUPID]);
this._showPostsToUsers = data[TableSpec.FIELD_SHOWPOSTSTOUSERS];
this._biography = data[TableSpec.FIELD_BIOGRAPHY];
this._avatarId = Util.ParseInt(data[TableSpec.FIELD_AVATARID]);
}
public XElement exportToXmlForViewing(UserContext context) {
return new XElement("user",
XElement result = new XElement("user",
new XElement("id", this.id),
new XElement("regDate", this.regDate.ToXml()),
new XElement("totalPosts", this.totalPosts),
@ -154,6 +169,10 @@ namespace FLocal.Common.dataobjects {
new XElement("userGroupId", this.userGroupId),
new XElement("showPostsToUsers", this.showPostsToUsers)
);
if(this.avatarId.HasValue) {
result.Add(new XElement("avatar", this.avatarId));
}
return result;
}
public static IEnumerable<User> getUsers(Diapasone diapasone, UserContext context) {

@ -22,7 +22,12 @@ namespace FLocal.ImportConsole {
[Action]
public static void ImportUsers() {
UsersImporter.ImportUsers();
try {
UsersImporter.ImportUsers();
} catch(Exception e) {
Console.WriteLine(e.GetType().FullName + ": " + e.Message);
Console.WriteLine(e.StackTrace);
}
}
[Action]

@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using FLocal.Core;
using FLocal.Importer;
using FLocal.Common;
using FLocal.Common.dataobjects;
using FLocal.Common.actions;
@ -15,11 +16,12 @@ namespace FLocal.ImportConsole {
for(int i=1; i<800; i++) {
Console.Write("[" + i + "]");
foreach(string userName in ShallerGateway.getUserNames(i)) {
Dictionary<string, string> userData = ShallerGateway.getUserInfo(userName);
User user;
try {
User.LoadByName(userName);
user = User.LoadByName(userName);
Console.Write("-");
} catch(NotFoundInDBException) {
Dictionary<string, string> userData = ShallerGateway.getUserInfo(userName);
AbstractChange addUser = new InsertChange(
User.TableSpec.instance,
new Dictionary<string, AbstractFieldValue>() {
@ -44,11 +46,40 @@ namespace FLocal.ImportConsole {
}
);
ChangeSetUtil.ApplyChanges(addUser, addAccount);
user = User.LoadById(addUser.getId().Value);
Console.Write(".");
}
if(!user.avatarId.HasValue && userData["avatar"] != null && userData["avatar"] != "") {
try {
Upload avatar;
string[] nameParts = userData["avatar"].Split('.');
if(nameParts.Length != 2) throw new FLocalException("wrong avatar filename '" + userData["avatar"] + "'");
int oldAvatarId = int.Parse(nameParts[0]);
FileInfo avatarInfo = ShallerGateway.getFileInfo("user/" + userData["avatar"]);
try {
avatar = UploadManager.UploadFile(avatarInfo.dataStream, avatarInfo.fileName, avatarInfo.lastModified, user, 900000 + oldAvatarId);
} catch(UploadManager.AlreadyUploadedException e) {
avatar = Upload.LoadById(e.uploadId);
}
ChangeSetUtil.ApplyChanges(
new UpdateChange(
User.TableSpec.instance,
new Dictionary<string,AbstractFieldValue> {
{ User.TableSpec.FIELD_AVATARID, new ScalarFieldValue(avatar.id.ToString()) }
},
user.id
)
);
Console.Write("a");
} catch(Exception e) {
Console.Write("!{" + user.id + "}{" + e.Message + "}!");
}
}
}
}
}
}
}
}

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace FLocal.Importer {
public struct FileInfo {
public Stream dataStream;
public string filePath;
public string fileName;
public long fileSize;
public DateTime lastModified;
}
}

@ -50,6 +50,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ShallerConnector.cs" />
<Compile Include="ShallerGateway.cs" />
<Compile Include="FileInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

@ -10,17 +10,17 @@ using System.IO;
namespace FLocal.Importer {
class ShallerConnector {
public static Encoding encoding {
get {
return Encoding.GetEncoding(1251);
}
}
public static readonly Encoding encoding = Encoding.GetEncoding(1251);
private const int BUFFER = 1024;
public static string getPageContent(string requestUrl, Dictionary<string, string> postData, CookieContainer cookies) {
public static FileInfo getPageInfo(string requestUrl, Dictionary<string, string> postData, CookieContainer cookies) {
string baseUrl = ConfigurationManager.AppSettings["Importer_BaseUrl"];
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(baseUrl + requestUrl);
request.KeepAlive = true;
request.CookieContainer = cookies;
request.ReadWriteTimeout = 3*1000;
request.Timeout = 3*1000;
request.Accept = "*";
if(postData.Count < 1) {
request.Method = "GET";
} else {
@ -42,10 +42,40 @@ namespace FLocal.Importer {
stream.Write(postBytes, 0, postBytes.Length);
stream.Close();
}
request.UserAgent = "ShallerConnector v0.1";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
cookies.Add(response.Cookies);
using(StreamReader reader = new StreamReader(response.GetResponseStream(), encoding)) {
request.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; FDM; .NET4.0C; .NET4.0E)";
using(HttpWebResponse response = (HttpWebResponse)request.GetResponse()) {
cookies.Add(response.Cookies);
byte[] content;
using(Stream responseStream = response.GetResponseStream()) {
using(MemoryStream memoryStream = new MemoryStream()) {
byte[] buffer = new byte[BUFFER];
int bytes;
while((bytes = responseStream.Read(buffer, 0, BUFFER)) > 0) {
memoryStream.Write(buffer, 0, bytes);
}
content = memoryStream.ToArray();
}
}
if(response.ContentLength > 0 && content.Length != response.ContentLength) {
throw new ApplicationException("incomplete file (expected " + response.ContentLength + ", got " + content.Length + ")");
}
FileInfo result = new FileInfo {
dataStream = new MemoryStream(content),
fileName = response.ResponseUri.Segments.Last(),
filePath = response.ResponseUri.AbsolutePath,
fileSize = response.ContentLength,
lastModified = response.LastModified,
};
response.Close();
return result;
}
}
public static string getPageContent(string requestUrl, Dictionary<string, string> postData, CookieContainer cookies) {
FileInfo info = getPageInfo(requestUrl, postData, cookies);
using(StreamReader reader = new StreamReader(info.dataStream, encoding)) {
return reader.ReadToEnd();
}
}

@ -3,7 +3,9 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Net;
using System.Web;
using System.IO;
namespace FLocal.Importer {
public class ShallerGateway {
@ -25,6 +27,8 @@ namespace FLocal.Importer {
return regexInfoCache[caption];
}
private static Regex avatarRegex = new Regex("<img\\s+src=\"/user/(\\d+\\.\\w+)\"\\s+alt=\"Picture\"\\s+width=\"\\d+\"\\s+height=\"\\d+\"\\s*/>", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline);
private static Dictionary<string, string> userImportStructure {
get {
return new Dictionary<string,string>() {
@ -39,10 +43,12 @@ namespace FLocal.Importer {
public static Dictionary<string, string> getUserInfo(string userName) {
string content = getUserInfoAsString(userName);
return userImportStructure.ToDictionary<KeyValuePair<string, string>, string, string>(
Dictionary<string, string> result = userImportStructure.ToDictionary<KeyValuePair<string, string>, string, string>(
kvp => kvp.Key,
kvp => HttpUtility.HtmlDecode(getInfoRegexByCaption(kvp.Value).Match(content).Groups[1].Value).Trim()
);
result["avatar"] = avatarRegex.Match(content).Groups[1].Value;
return result;
}
public static IEnumerable<string> getUserNames(int pageNum) {
@ -56,5 +62,21 @@ namespace FLocal.Importer {
return result;
}
private static FileInfo getFileInfo(string path, int attempt) {
try {
return ShallerConnector.getPageInfo(path, new Dictionary<string,string>(), new CookieContainer());
} catch(Exception) {
if(attempt > 3) {
throw;
} else {
return getFileInfo(path, attempt + 1);
}
}
}
public static FileInfo getFileInfo(string path) {
return getFileInfo(path, 1);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

@ -30,7 +30,16 @@
<xsl:text>Not implemented</xsl:text>
</td>
<td align="right" valign="top" rowspan="11">
<img src="/user/14291.png" alt="Picture" width="80" height="80" />
<img alt="Picture" width="80" height="80">
<xsl:choose>
<xsl:when test="user/avatar">
<xsl:attribute name="src">/Upload/Item/<xsl:value-of select="user/avatar"/>/</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="src">/static/images/noavatar.gif</xsl:attribute>
</xsl:otherwise>
</xsl:choose>
</img>
</td>
</tr>
<tr>

@ -26,11 +26,15 @@
<i><font color="red"></font></i>
</td>
</tr>
<tr>
<td class="small">
<img src="/user/7901.jpg" alt="" width="80" height="80" />
</td>
</tr>
<xsl:if test="avatar">
<tr>
<td class="small">
<img alt="" width="80" height="80">
<xsl:attribute name="src">/Upload/Item/<xsl:value-of select="avatar"/>/</xsl:attribute>
</img>
</td>
</tr>
</xsl:if>
<tr>
<td class="small">
<xsl:text>Ðåã.: </xsl:text>

Loading…
Cancel
Save