Skip to content

Commit

Permalink
Merge branch 'develop2'
Browse files Browse the repository at this point in the history
  • Loading branch information
yar229 committed Nov 6, 2017
2 parents d6be7a7 + f71cee6 commit 152a789
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 62 deletions.
5 changes: 5 additions & 0 deletions MailRuCloud/MailRuCloudApi/Base/WebDavPath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ public static string ModifyParent(string path, string oldParent, string newParen

return Combine(newParent, path);
}

public static bool PathEquals(string path1, string path2)
{
return String.Compare(Clean(path1), Clean(path2), StringComparison.InvariantCultureIgnoreCase) == 0;
}
}

public struct WebDavPathParts
Expand Down
119 changes: 68 additions & 51 deletions MailRuCloud/MailRuCloudApi/Links/LinkManager.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
Expand All @@ -19,7 +17,8 @@ public class LinkManager
{
private static readonly log4net.ILog Logger = log4net.LogManager.GetLogger(typeof(LinkManager));

public static string LinkContainerName = "item.links.wdmrc";
public static readonly string LinkContainerName = "item.links.wdmrc";
public static readonly string HistoryContainerName = "item.links.history.wdmrc";
private readonly MailRuCloud _cloud;
private ItemList _itemList = new ItemList();

Expand All @@ -40,13 +39,8 @@ public void Save()
Logger.Info($"Saving links to {LinkContainerName}");

string content = JsonConvert.SerializeObject(_itemList, Formatting.Indented);
var data = Encoding.UTF8.GetBytes(content);

using (var stream = _cloud.GetFileUploadStream(WebDavPath.Combine(WebDavPath.Root, LinkContainerName), data.Length))
{
stream.Write(data, 0, data.Length);
//stream.Close();
}
string path = WebDavPath.Combine(WebDavPath.Root, LinkContainerName);
_cloud.UploadFile(path, content);
}

/// <summary>
Expand All @@ -61,16 +55,7 @@ public void Load()
var file = (File)_cloud.GetItem(WebDavPath.Combine(WebDavPath.Root, LinkContainerName), MailRuCloud.ItemType.File, false).Result;

if (file != null && file.Size > 3) //some clients put one/two/three-byte file before original file
{
DownloadStream stream = new DownloadStream(file, _cloud.CloudApi);

using (StreamReader reader = new StreamReader(stream))
using (JsonTextReader jsonReader = new JsonTextReader(reader))
{
var ser = new JsonSerializer();
_itemList = ser.Deserialize<ItemList>(jsonReader);
}
}
_itemList = _cloud.DownloadFileAsJson<ItemList>(file);
}
catch (Exception e)
{
Expand Down Expand Up @@ -123,49 +108,64 @@ public void RemoveItem(string path, bool doSave = true)
/// Убрать все привязки на мёртвые ссылки
/// </summary>
/// <param name="doWriteHistory"></param>
public void RemoveDeadLinks(bool doWriteHistory)
public async void RemoveDeadLinks(bool doWriteHistory)
{
var removes = _itemList.Items
.AsParallel()
.WithDegreeOfParallelism(5)
.Where(it => !IsLinkAlive(it)).ToList();
.Select(it => GetItemLink(WebDavPath.Combine(it.MapTo, it.Name)).Result)
.Where(itl => itl.IsBad)
.ToList();
if (removes.Count == 0) return;

_itemList.Items.RemoveAll(it => removes.Contains(it));
_itemList.Items.RemoveAll(it => removes.Any(rem => rem.MapTo == it.MapTo && rem.Name == it.Name));

if (doWriteHistory)
if (removes.Any())
{
//TODO:load item.links.history.wdmrc
//TODO:append removed
//TODO:save item.links.history.wdmrc
if (doWriteHistory)
{
string path = WebDavPath.Combine(WebDavPath.Root, HistoryContainerName);
string res = await _cloud.DownloadFileAsString(path);
var history = new StringBuilder(res ?? string.Empty);
foreach (var link in removes)
{
history.Append($"{DateTime.Now} REMOVE: {link.Href} {link.Name}\r\n");
}
_cloud.UploadFile(path, history.ToString());
}
Save();
}

Save();
}

///// <summary>
///// Проверка доступности ссылки
///// </summary>
///// <param name="link"></param>
///// <returns></returns>
//private bool IsLinkAlive(ItemLink link)
//{
// string path = WebDavPath.Combine(link.MapTo, link.Name);
// try
// {
// var entry = _cloud.GetItem(path).Result;
// return entry != null;
// }
// catch (AggregateException e)
// when ( // let's check if there really no file or just other network error
// e.InnerException is WebException we &&
// (we.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.NotFound
// )
// {
// return false;
// }
//}

/// <summary>
/// Проверка доступности ссылки
///
/// </summary>
/// <param name="link"></param>
/// <param name="path"></param>
/// <param name="doResolveType">Resolving file/folder type requires addition request to cloud</param>
/// <returns></returns>
private bool IsLinkAlive(ItemLink link)
{
string path = WebDavPath.Combine(link.MapTo, link.Name);
try
{
var entry = _cloud.GetItem(path).Result;
return entry != null;
}
catch (AggregateException e)
when ( // let's check if there really no file or just other network error
e.InnerException is WebException we &&
(we.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.NotFound
)
{
return false;
}
}

public async Task<ItemfromLink> GetItemLink(string path, bool doResolveType = true)
{
//TODO: subject to refact
Expand All @@ -191,8 +191,9 @@ public async Task<ItemfromLink> GetItemLink(string path, bool doResolveType = tr
var infores = await new ItemInfoRequest(_cloud.CloudApi, res.Href, true).MakeRequestAsync()
.ConfigureAwait(false);
res.IsFile = infores.body.kind == "file";
res.OriginalName = infores.body.name;
}
catch (Exception e) //TODO check 404 etc.
catch (Exception) //TODO check 404 etc.
{
//this means a bad link
// don't know what to do
Expand All @@ -205,7 +206,7 @@ public async Task<ItemfromLink> GetItemLink(string path, bool doResolveType = tr

public class ItemfromLink : ItemLink
{
public ItemfromLink() { }
private ItemfromLink() { }

public ItemfromLink(ItemLink link) : this()
{
Expand All @@ -220,6 +221,9 @@ public ItemfromLink(ItemLink link) : this()
public bool IsBad { get; set; }
public string Path { get; set; }

public bool IsRoot => WebDavPath.PathEquals(WebDavPath.Parent(Path), MapTo);
public string OriginalName { get; set; }

public IEntry ToBadEntry()
{
var res = IsFile
Expand Down Expand Up @@ -291,5 +295,18 @@ public void ProcessRename(string fullPath, string newName)
}
if (changed) Save();
}

public bool RenameLink(ItemfromLink link, string newName)
{
// can't rename items within linked folder
if (!link.IsRoot) return false;

var ilink = _itemList.Items.FirstOrDefault(it => it.MapTo == link.MapTo && it.Name == link.Name);
if (null == ilink) return false;

ilink.Name = newName;
Save();
return true;
}
}
}
84 changes: 77 additions & 7 deletions MailRuCloud/MailRuCloudApi/MailRuCloud.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using YaR.MailRuCloud.Api.Base;
using YaR.MailRuCloud.Api.Base.Requests;
using YaR.MailRuCloud.Api.Base.Requests.Types;
using YaR.MailRuCloud.Api.Extensions;
using YaR.MailRuCloud.Api.Links;
using File = YaR.MailRuCloud.Api.Base.File;
Expand Down Expand Up @@ -111,7 +113,8 @@ public virtual async Task<IEntry> GetItem(string path, ItemType itemType = ItemT
}

var entry = itemType == ItemType.File
? (IEntry)datares.ToFile(WebDavPath.Name(path))
//? (IEntry)datares.ToFile(WebDavPath.Name(path))
? (IEntry)datares.ToFile(ulink == null ? WebDavPath.Name(path) : ulink.OriginalName)
: datares.ToFolder();

if (itemType == ItemType.Folder && entry is Folder folder)
Expand Down Expand Up @@ -381,6 +384,62 @@ public Stream GetFileUploadStream(string destinationPath, long size)
return stream;
}

public T DownloadFileAsJson<T>(File file)
{
DownloadStream stream = new DownloadStream(file, CloudApi);

using (var reader = new StreamReader(stream))
using (var jsonReader = new JsonTextReader(reader))
{
var ser = new JsonSerializer();
return ser.Deserialize<T>(jsonReader);
}
}

public string DownloadFileAsString(File file)
{
using (var stream = new DownloadStream(file, CloudApi))
using (var reader = new StreamReader(stream))
{
string res = reader.ReadToEnd();
return res;
}
}

/// <summary>
/// Download content of file
/// </summary>
/// <param name="path"></param>
/// <returns>file content or null if NotFound</returns>
public async Task<string> DownloadFileAsString(string path)
{
try
{
var file = (File)await GetItem(path);
return DownloadFileAsString(file);
}
catch (Exception e)
when ( // let's check if there really no file or just other network error
(e is AggregateException && e.InnerException is WebException we && (we.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.NotFound)
||
(e is WebException wee && (wee.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.NotFound)
)
{
return null;
}
}

public void UploadFile(string path, string content)
{
var data = Encoding.UTF8.GetBytes(content);

using (var stream = GetFileUploadStream(path, data.Length))
{
stream.Write(data, 0, data.Length);
//stream.Close();
}
}

/// <summary>
/// Rename item on server.
/// </summary>
Expand All @@ -389,14 +448,25 @@ public Stream GetFileUploadStream(string destinationPath, long size)
/// <returns>True or false result operation.</returns>
private async Task<bool> Rename(string fullPath, string newName)
{
var res = await new RenameRequest(CloudApi, fullPath, newName)
.MakeRequestAsync();
var link = await _linkManager.GetItemLink(fullPath, false);

if (res.status == 200)
//rename item
if (link == null)
{
_linkManager.ProcessRename(fullPath, newName);
var data = await new RenameRequest(CloudApi, fullPath, newName)
.MakeRequestAsync();

if (data.status == 200)
{
_linkManager.ProcessRename(fullPath, newName);
}
return data.status == 200;
}
return res.status == 200;

//rename link
var res = _linkManager.RenameLink(link, newName);

return res;
}

/// <summary>
Expand Down
4 changes: 2 additions & 2 deletions WDMRC.Console/WDMRC.Console.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
<Copyright>yar229@yandex.ru</Copyright>
<Description>WebDAV emulator for Cloud.mail.ru</Description>
<PackageId>WebDAVCloudMailRu</PackageId>
<AssemblyVersion>1.8.0.9</AssemblyVersion>
<FileVersion>1.8.0.9</FileVersion>
<AssemblyVersion>1.8.0.10</AssemblyVersion>
<FileVersion>1.8.0.10</FileVersion>
<AssemblyName>wdmrc</AssemblyName>
<RootNamespace>YaR.CloudMailRu.Console</RootNamespace>
<StartupObject></StartupObject>
Expand Down
4 changes: 2 additions & 2 deletions WDMRC.Console/WDMRC.Console.netcoreapp.publish.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
<Copyright>yar229@yandex.ru</Copyright>
<Description>WebDAV emulator for Cloud.mail.ru</Description>
<PackageId>WebDAVCloudMailRu</PackageId>
<AssemblyVersion>1.8.0.9</AssemblyVersion>
<FileVersion>1.8.0.9</FileVersion>
<AssemblyVersion>1.8.0.10</AssemblyVersion>
<FileVersion>1.8.0.10</FileVersion>
<AssemblyName>wdmrc</AssemblyName>
<RootNamespace>YaR.CloudMailRu.Console</RootNamespace>
<StartupObject></StartupObject>
Expand Down

0 comments on commit 152a789

Please sign in to comment.