Skip to content

Commit

Permalink
Release 0.2.0, Kubo 0.26.0+ support
Browse files Browse the repository at this point in the history
[Breaking]
Inherited breaking changes from IpfsShipyard.Ipfs.Core 0.2.0.
IDataBlock.DataStream was removed. This pattern encouraged async calls behind synchronous property getters, which is a bad practice and can cause deadlocks. Call the async methods directly on the API instead.
The obsolete IFileSystemApi.ListFileAsync was removed due to prior deprecation and removal in Kubo 0.26.0. Use IFileSystemApi.ListAsync and MfsApi.StatAsync instead.

[New]
Added missing IFileSystemApi.ListAsync. Doesn't fully replace the removed IFileSystemApi.ListFileAsync, but is a step in the right direction.

See also ipfs-shipyard/net-ipfs-core#29
  • Loading branch information
Arlodotexe committed Mar 23, 2024
1 parent b9b71c4 commit 78a6b9f
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 187 deletions.
40 changes: 7 additions & 33 deletions src/Block.cs
Original file line number Diff line number Diff line change
@@ -1,49 +1,23 @@
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization;

namespace Ipfs.Http
{
/// <inheritdoc />
[DataContract]
public class Block : IDataBlock

Check failure on line 7 in src/Block.cs

View workflow job for this annotation

GitHub Actions / build-and-test

Missing compiler required member 'System.Runtime.CompilerServices.RequiredMemberAttribute..ctor'

Check failure on line 7 in src/Block.cs

View workflow job for this annotation

GitHub Actions / build-and-test

Missing compiler required member 'System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute..ctor'

Check failure on line 7 in src/Block.cs

View workflow job for this annotation

GitHub Actions / build-and-test

Missing compiler required member 'System.Runtime.CompilerServices.RequiredMemberAttribute..ctor'
{
long? size;

/// <inheritdoc />
[DataMember]
public Cid Id { get; set; }
/// <summary>
/// The data of the block.
/// </summary>
public byte[] DataBytes { get; set; }

/// <inheritdoc />
[DataMember]
public byte[] DataBytes { get; set; }
public required Cid Id { get; set; }

Check failure on line 16 in src/Block.cs

View workflow job for this annotation

GitHub Actions / build-and-test

Feature 'required members' is not available in C# 7.3. Please use language version 11.0 or greater.

Check failure on line 16 in src/Block.cs

View workflow job for this annotation

GitHub Actions / build-and-test

Feature 'required members' is not available in C# 7.3. Please use language version 11.0 or greater.

/// <inheritdoc />
public Stream DataStream
{
get
{
return new MemoryStream(DataBytes, false);
}
}

/// <inheritdoc />
[DataMember]
public long Size
{
get
{
if (size.HasValue)
{
return size.Value;
}
return DataBytes.Length;
}
set
{
size = value;
}
}

public required long Size { get; set; }

Check failure on line 20 in src/Block.cs

View workflow job for this annotation

GitHub Actions / build-and-test

Feature 'required members' is not available in C# 7.3. Please use language version 11.0 or greater.

Check failure on line 20 in src/Block.cs

View workflow job for this annotation

GitHub Actions / build-and-test

Feature 'required members' is not available in C# 7.3. Please use language version 11.0 or greater.
}

}
3 changes: 2 additions & 1 deletion src/CoreApi/BlockApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ internal BlockApi(IpfsClient ipfs)
return new Block
{
DataBytes = data,
Id = id
Id = id,
Size = data.Length,
};
}

Expand Down
55 changes: 29 additions & 26 deletions src/CoreApi/FileSystemApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ internal FileSystemApi(IpfsClient ipfs)
this.emptyFolder = new Lazy<DagNode>(() => ipfs.Object.NewDirectoryAsync().Result);
}

public async Task<IFileSystemNode> AddFileAsync(string path, AddFileOptions options = null, CancellationToken cancel = default(CancellationToken))
public async Task<IFileSystemNode> AddFileAsync(string path, AddFileOptions options = null, CancellationToken cancel = default)
{
using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
{
Expand All @@ -31,15 +31,16 @@ internal FileSystemApi(IpfsClient ipfs)
}
}

public Task<IFileSystemNode> AddTextAsync(string text, AddFileOptions options = null, CancellationToken cancel = default(CancellationToken))
public Task<IFileSystemNode> AddTextAsync(string text, AddFileOptions options = null, CancellationToken cancel = default)
{
return AddAsync(new MemoryStream(Encoding.UTF8.GetBytes(text), false), "", options, cancel);
}

public async Task<IFileSystemNode> AddAsync(Stream stream, string name = "", AddFileOptions options = null, CancellationToken cancel = default(CancellationToken))
public async Task<IFileSystemNode> AddAsync(Stream stream, string name = "", AddFileOptions options = null, CancellationToken cancel = default)
{
if (options == null)
options = new AddFileOptions();

var opts = new List<string>();
if (!options.Pin)
opts.Add("pin=false");
Expand All @@ -59,6 +60,7 @@ internal FileSystemApi(IpfsClient ipfs)
opts.Add($"cid-base=${options.Encoding}");
if (!string.IsNullOrWhiteSpace(options.ProtectionKey))
opts.Add($"protect={options.ProtectionKey}");

opts.Add($"chunker=size-{options.ChunkSize}");

var response = await ipfs.Upload2Async("add", cancel, stream, name, opts.ToArray());
Expand Down Expand Up @@ -92,7 +94,6 @@ internal FileSystemApi(IpfsClient ipfs)
Size = long.Parse((string)r["Size"]),
IsDirectory = false,
Name = name,
IpfsClient = ipfs
};
}
}
Expand All @@ -102,7 +103,7 @@ internal FileSystemApi(IpfsClient ipfs)
return fsn;
}

public async Task<IFileSystemNode> AddDirectoryAsync(string path, bool recursive = true, AddFileOptions options = null, CancellationToken cancel = default(CancellationToken))
public async Task<IFileSystemNode> AddDirectoryAsync(string path, bool recursive = true, AddFileOptions options = null, CancellationToken cancel = default)
{
if (options == null)
options = new AddFileOptions();
Expand Down Expand Up @@ -145,7 +146,6 @@ internal FileSystemApi(IpfsClient ipfs)
Links = links,
IsDirectory = true,
Size = directory.Size,
IpfsClient = ipfs
};

}
Expand All @@ -163,7 +163,7 @@ internal FileSystemApi(IpfsClient ipfs)
/// <returns>
/// The contents of the <paramref name="path"/> as a <see cref="string"/>.
/// </returns>
public async Task<String> ReadAllTextAsync(string path, CancellationToken cancel = default(CancellationToken))
public async Task<String> ReadAllTextAsync(string path, CancellationToken cancel = default)
{
using (var data = await ReadFileAsync(path, cancel))
using (var text = new StreamReader(data))
Expand All @@ -186,12 +186,12 @@ internal FileSystemApi(IpfsClient ipfs)
/// <returns>
/// A <see cref="Stream"/> to the file contents.
/// </returns>
public Task<Stream> ReadFileAsync(string path, CancellationToken cancel = default(CancellationToken))
public Task<Stream> ReadFileAsync(string path, CancellationToken cancel = default)
{
return ipfs.PostDownloadAsync("cat", cancel, path);
}

public Task<Stream> ReadFileAsync(string path, long offset, long length = 0, CancellationToken cancel = default(CancellationToken))
public Task<Stream> ReadFileAsync(string path, long offset, long length = 0, CancellationToken cancel = default)
{
// https://github.com/ipfs/go-ipfs/issues/5380
if (offset > int.MaxValue)
Expand All @@ -206,33 +206,36 @@ internal FileSystemApi(IpfsClient ipfs)
$"length={length}");
}

/// <inheritdoc cref="ListAsync"/>
public Task<IFileSystemNode> ListFileAsync(string path, CancellationToken cancel = default)
{
return ListAsync(path, cancel);
}

/// <summary>
/// Get information about the file or directory.
/// Get information about the directory.
/// </summary>
/// <param name="path">
/// A path to an existing file or directory, such as "QmXarR6rgkQ2fDSHjSY5nM2kuCXKYGViky5nohtwgF65Ec/about"
/// or "QmZTR5bcpQD7cFgTorqxZDYaew1Wqgfbd2ud9QqGPAkK2V"
/// A path to an existing directory, such as "QmZTR5bcpQD7cFgTorqxZDYaew1Wqgfbd2ud9QqGPAkK2V"
/// </param>
/// <param name="cancel">
/// Is used to stop the task. When cancelled, the <see cref="TaskCanceledException"/> is raised.
/// Is used to stop the task. When cancelled, the <see cref="TaskCanceledException"/> is raised.
/// </param>
/// <returns></returns>
public async Task<IFileSystemNode> ListFileAsync(string path, CancellationToken cancel = default(CancellationToken))
public async Task<IFileSystemNode> ListAsync(string path, CancellationToken cancel = default)
{
var json = await ipfs.DoCommandAsync("file/ls", cancel, path);
var json = await ipfs.DoCommandAsync("ls", cancel, path);
var r = JObject.Parse(json);
var hash = (string)r["Arguments"][path];
var o = (JObject)r["Objects"][hash];
var o = (JObject)r["Objects"]?[0];

var node = new FileSystemNode()
{
Id = (string)o["Hash"],
Size = (long)o["Size"],
IsDirectory = (string)o["Type"] == "Directory",
Links = new FileSystemLink[0],
IpfsClient = ipfs
IsDirectory = true,
Links = Array.Empty<FileSystemLink>(),
};
var links = o["Links"] as JArray;
if (links != null)

if (o["Links"] is JArray links)
{
node.Links = links
.Select(l => new FileSystemLink()
Expand All @@ -245,9 +248,9 @@ internal FileSystemApi(IpfsClient ipfs)
}

return node;
}

public Task<Stream> GetAsync(string path, bool compress = false, CancellationToken cancel = default(CancellationToken))
}

public Task<Stream> GetAsync(string path, bool compress = false, CancellationToken cancel = default)
{
return ipfs.PostDownloadAsync("get", cancel, path, $"compress={compress}");
}
Expand Down
1 change: 0 additions & 1 deletion src/CoreApi/MfsApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ public async Task<IEnumerable<IFileSystemNode>> ListAsync(string path, bool? U =
Id = (string)l["Hash"],
Size = (long)l["Size"],
IsDirectory = (int)l["Type"] == 1,
IpfsClient = ipfs
})
.ToArray();
}
Expand Down
109 changes: 4 additions & 105 deletions src/FileSystemNode.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;

namespace Ipfs.Http
Expand All @@ -8,57 +7,13 @@ namespace Ipfs.Http
[DataContract]
public class FileSystemNode : IFileSystemNode

Check failure on line 8 in src/FileSystemNode.cs

View workflow job for this annotation

GitHub Actions / build-and-test

Missing compiler required member 'System.Runtime.CompilerServices.RequiredMemberAttribute..ctor'

Check failure on line 8 in src/FileSystemNode.cs

View workflow job for this annotation

GitHub Actions / build-and-test

Missing compiler required member 'System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute..ctor'
{
IpfsClient ipfsClient;
IEnumerable<IFileSystemLink> links;
long? size;
bool? isDirectory;

/// <inheritdoc />
public byte[] DataBytes
{
get
{
using (var stream = DataStream)
{
if (DataStream == null)
return null;

using (var data = new MemoryStream())
{
stream.CopyTo(data);
return data.ToArray();
}
}
}
}

/// <inheritdoc />
public Stream DataStream
{
get
{
return IpfsClient?.FileSystem.ReadFileAsync(Id).Result;
}
}

/// <inheritdoc />
[DataMember]
public Cid Id { get; set; }
public required Cid Id { get; set; }

Check failure on line 12 in src/FileSystemNode.cs

View workflow job for this annotation

GitHub Actions / build-and-test

Feature 'required members' is not available in C# 7.3. Please use language version 11.0 or greater.

/// <inheritdoc />
[DataMember]
public IEnumerable<IFileSystemLink> Links
{
get
{
if (links == null) GetInfo();
return links;
}
set
{
links = value;
}
}
public IEnumerable<IFileSystemLink> Links { get; set; } = [];

/// <summary>
/// Size of the file contents.
Expand All @@ -68,18 +23,7 @@ public IEnumerable<IFileSystemLink> Links
/// of the block.
/// </value>
[DataMember]
public long Size
{
get
{
if (!size.HasValue) GetInfo();
return size.Value;
}
set
{
size = value;
}
}
public long Size { get; set; }

/// <summary>
/// Determines if the link is a directory (folder).
Expand All @@ -89,18 +33,7 @@ public long Size
/// the link is some type of a file.
/// </value>
[DataMember]
public bool IsDirectory
{
get
{
if (!isDirectory.HasValue) GetInfo();
return isDirectory.Value;
}
set
{
isDirectory = value;
}
}
public bool IsDirectory { get; set; }

/// <summary>
/// The file name of the IPFS node.
Expand All @@ -119,39 +52,5 @@ public IFileSystemLink ToLink(string name = "")
};
return link;
}

/// <summary>
/// The client to IPFS.
/// </summary>
/// <value>
/// Used to fetch additional information on the node.
/// </value>
public IpfsClient IpfsClient
{
get
{
if (ipfsClient == null)
{
lock (this)
{
ipfsClient = new IpfsClient();
}
}
return ipfsClient;
}
set
{
ipfsClient = value;
}
}

void GetInfo()
{
var node = IpfsClient.FileSystem.ListFileAsync(Id).Result;
this.IsDirectory = node.IsDirectory;
this.Links = node.Links;
this.Size = node.Size;
}

}
}
Loading

0 comments on commit 78a6b9f

Please sign in to comment.