Initial commit way too late
There's a lot of rubbish in here, but I don't want to lose anything, so I'm going to commit it all before getting rid of some of the trash.
This commit is contained in:
commit
7c84fbc4c5
75 changed files with 2943 additions and 0 deletions
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
.mono
|
||||
.vs
|
||||
bin
|
||||
obj
|
||||
*.user
|
35
.vscode/launch.json
vendored
Normal file
35
.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
// Use IntelliSense to find out which attributes exist for C# debugging
|
||||
// Use hover for the description of the existing attributes
|
||||
// For further information visit https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md.
|
||||
"name": ".NET Core Launch (web)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
// If you have changed target frameworks, make sure to update the program path.
|
||||
"program": "${workspaceFolder}/bin/Debug/net8.0/ap.net.dll",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
// Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser
|
||||
"serverReadyAction": {
|
||||
"action": "openExternally",
|
||||
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
|
||||
},
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/Views": "${workspaceFolder}/Views"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": ".NET Core Attach",
|
||||
"type": "coreclr",
|
||||
"request": "attach"
|
||||
}
|
||||
]
|
||||
}
|
41
.vscode/tasks.json
vendored
Normal file
41
.vscode/tasks.json
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "build",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"build",
|
||||
"${workspaceFolder}/ap.net.csproj",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary;ForceNoAlign"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "publish",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"publish",
|
||||
"${workspaceFolder}/ap.net.csproj",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary;ForceNoAlign"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "watch",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"watch",
|
||||
"run",
|
||||
"--project",
|
||||
"${workspaceFolder}/ap.net.csproj"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
}
|
||||
]
|
||||
}
|
241
ActivityStore.cs
Normal file
241
ActivityStore.cs
Normal file
|
@ -0,0 +1,241 @@
|
|||
using ActivityPub.Utils;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.ComponentModel;
|
||||
using KristofferStrube.ActivityStreams;
|
||||
using OneOf;
|
||||
|
||||
namespace ActivityPub;
|
||||
using Activity = OneOf<Activity, IntransitiveActiviy>;
|
||||
|
||||
public enum ActivityStoreType {
|
||||
Inbox,
|
||||
Outbox
|
||||
}
|
||||
|
||||
public class ActivityStore {
|
||||
private static Dictionary<string, Activity> _outbox = new();
|
||||
private static Dictionary<string, Activity> _inbox = new();
|
||||
private Dictionary<string, Activity> _activities { get => ActivityStoreType == ActivityStoreType.Inbox ? _inbox : _outbox; }
|
||||
private IUrlHelper Url { get; set; }
|
||||
private ObjectStore ObjectStore { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The type (inbox or outbox) of this ActivityStore instance
|
||||
/// </summary>
|
||||
public ActivityStoreType ActivityStoreType { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
/// <param name="url">A url helper to construct id urls</param>
|
||||
/// <param name="activityStoreType">The typee (inbox or outbox) of this ActivityStore</param>
|
||||
public ActivityStore(IUrlHelper url, ActivityStoreType activityStoreType) {
|
||||
this.Url = url;
|
||||
this.ObjectStore = new ObjectStore(url);
|
||||
this.ActivityStoreType = activityStoreType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a new Id for an Activity
|
||||
/// </summary>
|
||||
public string NewId {
|
||||
get {
|
||||
long idTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
while (_activities.ContainsKey(Base36.ToString(idTime))) idTime++;
|
||||
return Base36.ToString(idTime);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps an Object in a Create Activity
|
||||
/// </summary>
|
||||
/// <param name="newObject">The object to create</param>
|
||||
/// <returns>The create Activity, with the object inside.</returns>
|
||||
public Create WrapObjectInCreate(KristofferStrube.ActivityStreams.Object newObject) {
|
||||
Create newActivity = new Create() { // new create activity
|
||||
Actor = newObject.AttributedTo,
|
||||
To = newObject.To,
|
||||
Cc = newObject.Cc,
|
||||
Bto = newObject.Bto,
|
||||
Bcc = newObject.Bcc,
|
||||
Audience = newObject.Audience,
|
||||
AttributedTo = newObject.AttributedTo,
|
||||
Name = newObject.Name?.FirstOrDefault() == null ? null : new List<string> { $"Create {newObject.Name.First()}" },
|
||||
};
|
||||
newActivity.Object = new List<IObjectOrLink> { newObject };
|
||||
|
||||
return newActivity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an activity by Id
|
||||
/// </summary>
|
||||
/// <param name="id">The Id to find</param>
|
||||
/// <returns>The activity with the corresponding id, or null if not found</returns>
|
||||
public Activity? GetById(string id) {
|
||||
foreach (KeyValuePair<string, Activity> kvp in _activities) {
|
||||
if (kvp.Key == id) return kvp.Value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets All activities
|
||||
/// </summary>
|
||||
/// <returns>A lit of all activities</returns>
|
||||
public List<Activity> GetAll() {
|
||||
return _activities.Values.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an activity into the data store
|
||||
/// </summary>
|
||||
/// <param name="newActivity">The Activity to create</param>
|
||||
/// <param name="runSideEffects">A boolean indicating whether side effects should be run (default true)</param>
|
||||
/// <param name="runDelivery">A boolean indicating whether delivery tasks should be run (default true)</param>
|
||||
/// <returns>The newly inserted activity</returns>
|
||||
public Activity InsertActivity(Activity newActivity, bool runSideEffects = true, bool runDelivery = true) {
|
||||
List<Uri> recipients = runDelivery ? ExtractRecipients(newActivity) : new List<Uri>();
|
||||
|
||||
string id = NewId;
|
||||
string uriId = this.Url.AbsoluteRouteUrl(ActivityStoreType == ActivityStoreType.Inbox ? "GetInboxById" : "GetOutboxById", new { id }).ToLower();
|
||||
newActivity.Switch(
|
||||
_ => { _.Id = uriId; _.Bto = _.Bcc = null; },
|
||||
_ => { _.Id = uriId; _.Bto = _.Bcc = null; }
|
||||
);
|
||||
if (runSideEffects) newActivity = RunSideEffect(newActivity);
|
||||
|
||||
_activities[id] = newActivity;
|
||||
|
||||
if (runDelivery) RunDelivery(newActivity, recipients);
|
||||
|
||||
return newActivity;
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// Inserts an activity into the data store
|
||||
///// </summary>
|
||||
///// <param name="newActivity">The Activity to create</param>
|
||||
///// <param name="runSideEffects">A boolean indicating whether side effects should be run (default true)</param>
|
||||
///// <param name="runDelivery">A boolean indicating whether delivery tasks should be run (default true)</param>
|
||||
///// <returns>The newly inserted activity</returns>
|
||||
//public Activity InsertActivity(IntransitiveActiviy newActivity, bool runSideEffects = true, bool runDelivery = true) {
|
||||
// string id = NewId;
|
||||
// newActivity.Id = this.Url.AbsoluteRouteUrl(ActivityStoreType == ActivityStoreType.Inbox ? "GetInboxById" : "GetOutboxById", new { id }).ToLower();
|
||||
// if (runSideEffects) newActivity = RunSideEffect(newActivity);
|
||||
|
||||
// List<Uri> recipients = runDelivery ? ExtractRecipients(newActivity) : new List<Uri>();
|
||||
// newActivity.Bto = newActivity.Bcc = null;
|
||||
|
||||
// _activities[id] = newActivity;
|
||||
|
||||
// if (runDelivery) RunDelivery(newActivity, recipients);
|
||||
|
||||
// return newActivity;
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Extract a list of recipients for an activity.
|
||||
/// clients must be aware that the server will only forward new Activities to addressees in the to, bto, cc, bcc, and audience fields.
|
||||
/// </summary>
|
||||
/// <param name="newActivity">The activity to extract recipients from</param>
|
||||
/// <returns>A list of Uris representing inboxes to post to</returns>
|
||||
private List<Uri> ExtractRecipients(Activity newActivity) {
|
||||
List<Uri> recipients = new();
|
||||
// TODO: recipients.Add(newActivity.To)
|
||||
// TODO: recipients.Add(newActivity.Bto)
|
||||
// TODO: recipients.Add(newActivity.Cc)
|
||||
// TODO: recipients.Add(newActivity.Bcc)
|
||||
// TODO: recipients.Add(newActivity.Audience)
|
||||
// TODO: Filter out duplicates
|
||||
// TODO: Populate lists (e.g. followers)
|
||||
// TODO: Again, filter out duplicates
|
||||
// TODO: change (remove?) public collection
|
||||
return recipients;
|
||||
}
|
||||
|
||||
private void RunDelivery(Activity newActivity, List<Uri> recipients) {
|
||||
foreach (Uri recipient in recipients) {
|
||||
// TODO: send a Http request to each recipient
|
||||
// it should be a POST request with the Activity as the body
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates an activity
|
||||
/// </summary>
|
||||
/// <param name="newActivity">the activity to validate</param>
|
||||
/// <returns>True on successful validation</returns>
|
||||
/// <exception cref="ArgumentException">Thown if the activity is invalid</exception>
|
||||
public bool ValidateActivity(Activity newActivity) {
|
||||
string? type = newActivity.Match(
|
||||
_ => _.Type?.FirstOrDefault(),
|
||||
_ => _.Type?.FirstOrDefault()
|
||||
);
|
||||
switch (type) {
|
||||
case "Create":
|
||||
case "Update":
|
||||
case "Delete":
|
||||
case "Follow":
|
||||
case "Add":
|
||||
case "Remove":
|
||||
case "Like":
|
||||
case "Dislike":
|
||||
case "Block":
|
||||
|
||||
if (!newActivity.IsT0 || newActivity.AsT0.Object == null) throw new ArgumentException($"'{type}' Activities require an 'Object' property");
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private Activity RunSideEffect(Activity newActivity) {
|
||||
string? type = newActivity.Match(
|
||||
_ => _.Type?.FirstOrDefault(),
|
||||
_ => _.Type?.FirstOrDefault()
|
||||
);
|
||||
switch (type) {
|
||||
case "Create":
|
||||
KristofferStrube.ActivityStreams.Object? newObject = newActivity.AsT0.Object.FirstOrDefault() as KristofferStrube.ActivityStreams.Object;
|
||||
if (newObject == null) throw new ArgumentException("'Create' Activities require an 'Object' property");
|
||||
newActivity.AsT0.Object = new List<IObjectOrLink> { (IObjectOrLink)ObjectStore.InsertObject(newObject) };
|
||||
break;
|
||||
|
||||
case "Update":
|
||||
case "Delete":
|
||||
case "Follow":
|
||||
case "Add":
|
||||
case "Remove":
|
||||
case "Like":
|
||||
case "Dislike":
|
||||
case "Block":
|
||||
case "Undo":
|
||||
|
||||
case "Accept":
|
||||
case "Announce":
|
||||
case "Arrive":
|
||||
case "Flag":
|
||||
case "Ignore":
|
||||
case "Invite":
|
||||
case "Join":
|
||||
case "Leave":
|
||||
case "Listen":
|
||||
case "Move":
|
||||
case "Offer":
|
||||
case "Question":
|
||||
case "Reject":
|
||||
case "Read":
|
||||
case "TentativeReject":
|
||||
case "TentativeAccept":
|
||||
case "Travel":
|
||||
case "View":
|
||||
throw new NotImplementedException();
|
||||
default:
|
||||
throw new InvalidEnumArgumentException($"Invalid Activity Type '{type}'");
|
||||
}
|
||||
|
||||
return newActivity;
|
||||
}
|
||||
|
||||
}
|
208
BaseActivity.cs
Normal file
208
BaseActivity.cs
Normal file
|
@ -0,0 +1,208 @@
|
|||
using KristofferStrube.ActivityStreams;
|
||||
using KristofferStrube.ActivityStreams.JsonConverters;
|
||||
using KristofferStrube.ActivityStreams.JsonLD;
|
||||
using OneOf;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ActivityPub;
|
||||
public class BaseActivity : OneOfBase<Activity, IntransitiveActiviy>, IObject {
|
||||
|
||||
protected BaseActivity(OneOf<Activity, IntransitiveActiviy> _) : base(_) { }
|
||||
|
||||
public static implicit operator BaseActivity(Activity _) => new BaseActivity(_);
|
||||
public static implicit operator BaseActivity(IntransitiveActiviy _) => new BaseActivity(_);
|
||||
|
||||
public static explicit operator Activity(BaseActivity _) => _.Match(a => a, ia => throw new InvalidCastException());
|
||||
public static explicit operator IntransitiveActiviy(BaseActivity _) => _.Match(a => throw new InvalidCastException(), ia => ia);
|
||||
|
||||
public bool IsIntransitive { get => IsT1; }
|
||||
|
||||
/// <summary>
|
||||
/// Describes one or more entities that either performed or are expected to perform the activity. Any single activity can have multiple actors. The actor may be specified using an indirect Link.
|
||||
/// </summary>
|
||||
public IEnumerable<IObjectOrLink>? Actor {
|
||||
get => Match(a => a.Actor, ia => ia.Actor);
|
||||
set => Switch(a => a.Actor = value, ia => ia.Actor = value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes an object of any kind. The Object type serves as the base type for most of the other kinds of objects defined in the Activity Vocabulary, including other Core types such as Activity, IntransitiveActivity, Collection and OrderedCollection.
|
||||
/// </summary>
|
||||
public IEnumerable<IObjectOrLink>? Object {
|
||||
get => Match(a => a.Object, ia => throw new InvalidOperationException("Activity is Intransitive"));
|
||||
set => Switch(a => a.Object = value, ia => throw new InvalidOperationException("Activity is Intransitive"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes the indirect object, or target, of the activity. The precise meaning of the target is largely dependent on the type of action being described but will often be the object of the English preposition "to". For instance, in the activity "John added a movie to his wishlist", the target of the activity is John's wishlist. An activity can have more than one target.
|
||||
/// </summary>
|
||||
public IEnumerable<IObjectOrLink>? Target {
|
||||
get => Match(a => a.Target, ia => ia.Target);
|
||||
set => Switch(a => a.Target = value, ia => ia.Target = value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes the result of the activity. For instance, if a particular action results in the creation of a new resource, the result property can be used to describe that new resource.
|
||||
/// </summary>
|
||||
public IEnumerable<IObjectOrLink>? Result {
|
||||
get => Match(a => a.Result, ia => ia.Result);
|
||||
set => Switch(a => a.Result = value, ia => ia.Result = value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes an indirect object of the activity from which the activity is directed. The precise meaning of the origin is the object of the English preposition "from". For instance, in the activity "John moved an item to List B from List A", the origin of the activity is "List A".
|
||||
/// </summary>
|
||||
public IEnumerable<IObjectOrLink>? Origin {
|
||||
get => Match(a => a.Origin, ia => ia.Origin);
|
||||
set => Switch(a => a.Origin = value, ia => ia.Origin = value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Identifies one or more objects used (or to be used) in the completion of an Activity.
|
||||
/// </summary>
|
||||
public IEnumerable<IObjectOrLink>? Instrument {
|
||||
get => Match(a => a.Instrument, ia => ia.Instrument);
|
||||
set => Switch(a => a.Instrument = value, ia => ia.Instrument = value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public IEnumerable<IObjectOrLink>? Attachment {
|
||||
get => Match(a => a.Attachment, ia => ia.Attachment);
|
||||
set => Switch(a => a.Attachment = value, ia => ia.Attachment = value);
|
||||
}
|
||||
public IEnumerable<IObjectOrLink>? AttributedTo {
|
||||
get => Match(a => a.AttributedTo, ia => ia.AttributedTo);
|
||||
set => Switch(a => a.AttributedTo = value, ia => ia.AttributedTo = value);
|
||||
}
|
||||
public IEnumerable<IObjectOrLink>? Audience {
|
||||
get => Match(a => a.Audience, ia => ia.Audience);
|
||||
set => Switch(a => a.Audience = value, ia => ia.Audience = value);
|
||||
}
|
||||
public IEnumerable<IObjectOrLink>? Bcc {
|
||||
get => Match(a => a.Bcc, ia => ia.Bcc);
|
||||
set => Switch(a => a.Bcc = value, ia => ia.Bcc = value);
|
||||
}
|
||||
public IEnumerable<IObjectOrLink>? Bto {
|
||||
get => Match(a => a.Bto, ia => ia.Bto);
|
||||
set => Switch(a => a.Bto = value, ia => ia.Bto = value);
|
||||
}
|
||||
public IEnumerable<IObjectOrLink>? Cc {
|
||||
get => Match(a => a.Cc, ia => ia.Cc);
|
||||
set => Switch(a => a.Cc = value, ia => ia.Cc = value);
|
||||
}
|
||||
public IEnumerable<IObjectOrLink>? Context {
|
||||
get => Match(a => a.Context, ia => ia.Context);
|
||||
set => Switch(a => a.Context = value, ia => ia.Context = value);
|
||||
}
|
||||
public IEnumerable<IObjectOrLink>? Generator {
|
||||
get => Match(a => a.Generator, ia => ia.Generator);
|
||||
set => Switch(a => a.Generator = value, ia => ia.Generator = value);
|
||||
}
|
||||
public IEnumerable<IImageOrLink>? Icon {
|
||||
get => Match(a => a.Icon, ia => ia.Icon);
|
||||
set => Switch(a => a.Icon = value, ia => ia.Icon = value);
|
||||
}
|
||||
public IEnumerable<IImageOrLink>? Image {
|
||||
get => Match(a => a.Image, ia => ia.Image);
|
||||
set => Switch(a => a.Image = value, ia => ia.Image = value);
|
||||
}
|
||||
public IEnumerable<IObjectOrLink>? InReplyTo {
|
||||
get => Match(a => a.InReplyTo, ia => ia.InReplyTo);
|
||||
set => Switch(a => a.InReplyTo = value, ia => ia.InReplyTo = value);
|
||||
}
|
||||
public IEnumerable<IObjectOrLink>? Location {
|
||||
get => Match(a => a.Location, ia => ia.Location);
|
||||
set => Switch(a => a.Location = value, ia => ia.Location = value);
|
||||
}
|
||||
public Collection? Replies {
|
||||
get => Match(a => a.Replies, ia => ia.Replies);
|
||||
set => Switch(a => a.Replies = value, ia => ia.Replies = value);
|
||||
}
|
||||
public IEnumerable<IObjectOrLink>? Tag {
|
||||
get => Match(a => a.Tag, ia => ia.Tag);
|
||||
set => Switch(a => a.Tag = value, ia => ia.Tag = value);
|
||||
}
|
||||
public IEnumerable<IObjectOrLink>? To {
|
||||
get => Match(a => a.To, ia => ia.To);
|
||||
set => Switch(a => a.To = value, ia => ia.To = value);
|
||||
}
|
||||
public IEnumerable<ILink>? Url {
|
||||
get => Match(a => a.Url, ia => ia.Url);
|
||||
set => Switch(a => a.Url = value, ia => ia.Url = value);
|
||||
}
|
||||
public IEnumerable<string>? Content {
|
||||
get => Match(a => a.Content, ia => ia.Content);
|
||||
set => Switch(a => a.Content = value, ia => ia.Content = value);
|
||||
}
|
||||
public IEnumerable<IDictionary<string, string>>? ContentMap {
|
||||
get => Match(a => a.ContentMap, ia => ia.ContentMap);
|
||||
set => Switch(a => a.ContentMap = value, ia => ia.ContentMap = value);
|
||||
}
|
||||
public IEnumerable<IDictionary<string, string>>? NameMap {
|
||||
get => Match(a => a.NameMap, ia => ia.NameMap);
|
||||
set => Switch(a => a.NameMap = value, ia => ia.NameMap = value);
|
||||
}
|
||||
public TimeSpan? Duration {
|
||||
get => Match(a => a.Duration, ia => ia.Duration);
|
||||
set => Switch(a => a.Duration = value, ia => ia.Duration = value);
|
||||
}
|
||||
public DateTime? EndTime {
|
||||
get => Match(a => a.EndTime, ia => ia.EndTime);
|
||||
set => Switch(a => a.EndTime = value, ia => ia.EndTime = value);
|
||||
}
|
||||
public DateTime? Published {
|
||||
get => Match(a => a.Published, ia => ia.Published);
|
||||
set => Switch(a => a.Published = value, ia => ia.Published = value);
|
||||
}
|
||||
public DateTime? StartTime {
|
||||
get => Match(a => a.Published, ia => ia.Published);
|
||||
set => Switch(a => a.Published = value, ia => ia.Published = value);
|
||||
}
|
||||
public IEnumerable<string>? Summary {
|
||||
get => Match(a => a.Summary, ia => ia.Summary);
|
||||
set => Switch(a => a.Summary = value, ia => ia.Summary = value);
|
||||
}
|
||||
public IEnumerable<IDictionary<string, string>>? SummaryMap {
|
||||
get => Match(a => a.SummaryMap, ia => ia.SummaryMap);
|
||||
set => Switch(a => a.SummaryMap = value, ia => ia.SummaryMap = value);
|
||||
}
|
||||
public DateTime? Updated {
|
||||
get => Match(a => a.Updated, ia => ia.Updated);
|
||||
set => Switch(a => a.Updated = value, ia => ia.Updated = value);
|
||||
}
|
||||
public Source? Source {
|
||||
get => Match(a => a.Source, ia => ia.Source);
|
||||
set => Switch(a => a.Source = value, ia => ia.Source = value);
|
||||
}
|
||||
public Dictionary<string, JsonElement>? ExtensionData {
|
||||
get => Match(a => a.ExtensionData, ia => ia.ExtensionData);
|
||||
set => Switch(a => a.ExtensionData = value, ia => ia.ExtensionData = value);
|
||||
}
|
||||
public string? Id {
|
||||
get => Match(a => a.Id, ia => ia.Id);
|
||||
set => Switch(a => a.Id = value, ia => ia.Id = value);
|
||||
}
|
||||
public IEnumerable<ITermDefinition>? JsonLDContext {
|
||||
get => Match(a => a.JsonLDContext, ia => ia.JsonLDContext);
|
||||
set => Switch(a => a.JsonLDContext = value, ia => ia.JsonLDContext = value);
|
||||
}
|
||||
public IEnumerable<string>? Type {
|
||||
get => Match(a => a.Type, ia => ia.Type);
|
||||
set => Switch(a => a.Type = value, ia => ia.Type = value);
|
||||
}
|
||||
public string? MediaType {
|
||||
get => Match(a => a.MediaType, ia => ia.MediaType);
|
||||
set => Switch(a => a.MediaType = value, ia => ia.MediaType = value);
|
||||
}
|
||||
public IEnumerable<string>? Name {
|
||||
get => Match(a => a.Name, ia => ia.Name);
|
||||
set => Switch(a => a.Name = value, ia => ia.Name = value);
|
||||
}
|
||||
public IEnumerable<IObjectOrLink>? Preview {
|
||||
get => Match(a => a.Preview, ia => ia.Preview);
|
||||
set => Switch(a => a.Preview = value, ia => ia.Preview = value);
|
||||
}
|
||||
}
|
14
Constants.cs
Normal file
14
Constants.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
public class Context {
|
||||
public static readonly Uri ActivityStreams = new("https://www.w3.org/ns/activitystreams");
|
||||
}
|
||||
|
||||
public class Collections {
|
||||
/// <summary>
|
||||
/// The public address for delivery.
|
||||
/// See https://www.w3.org/TR/activitypub/#x5-6-public-addressing
|
||||
/// Also note, may be represented as "Public" or "as:Public"
|
||||
/// </summary>
|
||||
public static readonly Uri Public = new("https://www.w3.org/ns/activitystreams#Public");
|
||||
}
|
43
Controllers/ObjectController.cs
Normal file
43
Controllers/ObjectController.cs
Normal file
|
@ -0,0 +1,43 @@
|
|||
using ActivityPub.Utils;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace ActivityPub.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// API endpoint(s) for retrieving objects
|
||||
/// </summary>
|
||||
[Route("")]
|
||||
[ApiController]
|
||||
public class ObjectController : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// TODO: Temporary Object data store (until I work out the data layer)
|
||||
/// </summary>
|
||||
public static Dictionary<string, Dictionary<string, Object>> _objects = new();
|
||||
private readonly ILogger<ObjectController> _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
/// <param name="logger">The logger</param>
|
||||
public ObjectController(ILogger<ObjectController> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a single object by id
|
||||
/// </summary>
|
||||
/// <param name="type">The type of Object to retrieve (see https://www.w3.org/TR/activitystreams-vocabulary/#object-types) </param>
|
||||
/// <param name="id">The identifier of the object</param>
|
||||
/// <returns>The requested object, or else 404</returns>
|
||||
[HttpGet("{type}/{id}", Name = "GetObject")]
|
||||
public IActionResult Get(string type, string id)
|
||||
{
|
||||
string properType = Types.Normalize(type);
|
||||
if (Types.IsObjectOrLink(properType) && _objects.ContainsKey(properType) && _objects[properType].ContainsKey(id.ToLower()))
|
||||
return this.Ok(_objects[properType][id.ToLower()]);
|
||||
|
||||
return NotFound();
|
||||
}
|
||||
}
|
87
Controllers/OutboxController.cs
Normal file
87
Controllers/OutboxController.cs
Normal file
|
@ -0,0 +1,87 @@
|
|||
using ActivityPub.Utils;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using KristofferStrube;
|
||||
using KristofferStrube.ActivityStreams;
|
||||
using OneOf;
|
||||
|
||||
namespace ActivityPub.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// API Controller for the Outbox
|
||||
/// </summary>
|
||||
[Route("[controller]")]
|
||||
[ApiController]
|
||||
public class OutboxController : ControllerBase {
|
||||
private readonly ILogger<OutboxController> _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
/// <param name="logger">The logger</param>
|
||||
public OutboxController(ILogger<OutboxController> logger) {
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to create and process a new object.
|
||||
/// See https://www.w3.org/TR/activitypub/#client-to-server-interactions
|
||||
/// </summary>
|
||||
/// <param name="newData">The data for the Activity or Object to create</param>
|
||||
/// <returns>
|
||||
/// 201 (Created) on success with the new id in the Location header
|
||||
/// TODO: Also currently returns the newly created Action to assist in debugging.
|
||||
/// </returns>
|
||||
/// <response code="201">The new Activity's id is returned in the Location header</response>
|
||||
/// <response code="400">If the provided data is not a valid Activity or Object</response>
|
||||
[HttpPost(Name = "PostOutboxObject")]
|
||||
[ProducesResponseType(StatusCodes.Status201Created)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
public async Task<IActionResult> Post(IObjectOrLink newObjectOrLink) {
|
||||
|
||||
ActivityStore Outbox = new(this.Url, ActivityStoreType.Outbox);
|
||||
|
||||
if(newObjectOrLink == null || !(newObjectOrLink is KristofferStrube.ActivityStreams.Object))
|
||||
return this.BadRequest($"No valid Activity or Object found in the request body");
|
||||
|
||||
OneOf<Activity, IntransitiveActiviy> newActivity =
|
||||
(newObjectOrLink is Activity) ? (Activity)newObjectOrLink
|
||||
: (newObjectOrLink is IntransitiveActiviy) ? (IntransitiveActiviy)newObjectOrLink
|
||||
: Outbox.WrapObjectInCreate(newObjectOrLink as KristofferStrube.ActivityStreams.Object);
|
||||
|
||||
//// Validate the activity
|
||||
//try {
|
||||
// if (!Outbox.ValidateActivity(newActivity)) throw new ArgumentException();
|
||||
//}
|
||||
//catch (ArgumentException err) {
|
||||
// return this.BadRequest(err.Message);
|
||||
//}
|
||||
|
||||
newActivity = Outbox.InsertActivity(newActivity);
|
||||
return Created(newActivity.Id, newActivity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a single Activity by id
|
||||
/// See: https://www.w3.org/TR/activitypub/#outbox
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the object to retrieve.</param>
|
||||
/// <returns>The Activity requested, or 404 (Not Found)</returns>
|
||||
[HttpGet("{id}", Name = "GetOutboxById")]
|
||||
public IActionResult Get(string id) {
|
||||
ActivityStore Outbox = new(this.Url, ActivityStoreType.Outbox);
|
||||
Activity? activity = Outbox.GetById(id);
|
||||
if (activity == null) return NotFound();
|
||||
else return Ok(activity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves all Activities
|
||||
/// See: https://www.w3.org/TR/activitypub/#outbox
|
||||
/// </summary>
|
||||
/// <returns>A list of all activities</returns>
|
||||
[HttpGet(Name = "GetOutboxList")]
|
||||
public IActionResult Get() {
|
||||
ActivityStore Outbox = new(this.Url, ActivityStoreType.Outbox);
|
||||
return Ok(Outbox.GetAll());
|
||||
}
|
||||
}
|
654
DynamicObjectFactory.cs
Normal file
654
DynamicObjectFactory.cs
Normal file
|
@ -0,0 +1,654 @@
|
|||
//namespace ActivityPub;
|
||||
|
||||
|
||||
///// <summary>
|
||||
///// A class to create ActivityPub Objects/Activities/etc from an incoming dynamic object
|
||||
///// </summary>
|
||||
//public static class DynamicObjectFactory {
|
||||
// public static ObjectOrLink? NewObjectOrLink(dynamic that) {
|
||||
// if (that is string) return (ObjectOrLink) new Uri((string)that);
|
||||
// if (that is Uri) return (ObjectOrLink)that;
|
||||
|
||||
// string type = that.Type;
|
||||
// if (type == null) return null; // TODO: throw exception?
|
||||
// type = Types.Normalize(type);
|
||||
|
||||
// ObjectOrLink newObject;
|
||||
// switch (type) {
|
||||
// // https://www.w3.org/TR/activitystreams-vocabulary/#types
|
||||
// case "Object": return (ObjectOrLink)NewObject(that);
|
||||
// case "Link": return (ObjectOrLink)NewLink(that);
|
||||
// case "Activity": return (ObjectOrLink)NewActivity(that);
|
||||
// case "IntransitiveActivity": return (ObjectOrLink)NewIntransitiveActivity(that);
|
||||
// case "Collection": return (ObjectOrLink)NewCollection(that);
|
||||
// case "OrderedCollection": return (ObjectOrLink)NewOrderedCollection(that);
|
||||
// case "CollectionPage": return (ObjectOrLink)NewCollectionPage(that);
|
||||
// case "OrderedCollectionPage": return (ObjectOrLink)NewOrderedCollectionPage(that);
|
||||
|
||||
// // this is technically not an ActivityStreams type, but it's useful to exist
|
||||
// case "Actor": return (ObjectOrLink)NewActor(that);
|
||||
|
||||
// // https://www.w3.org/TR/activitystreams-vocabulary/#activity-types
|
||||
// case "Accept": return (ObjectOrLink)NewAccept(that);
|
||||
// case "Add": return (ObjectOrLink)NewAdd(that);
|
||||
// case "Announce": return (ObjectOrLink)NewAnnounce(that);
|
||||
// case "Arrive": return (ObjectOrLink)NewArrive(that);
|
||||
// case "Block": return (ObjectOrLink)NewBlock(that);
|
||||
// case "Create": return (ObjectOrLink)NewCreate(that);
|
||||
// case "Delete": return (ObjectOrLink)NewDelete(that);
|
||||
// case "Dislike": return (ObjectOrLink)NewDislike(that);
|
||||
// case "Flag": return (ObjectOrLink)NewFlag(that);
|
||||
// case "Follow": return (ObjectOrLink)NewFollow(that);
|
||||
// case "Ignore": return (ObjectOrLink)NewIgnore(that);
|
||||
// case "Invite": return (ObjectOrLink)NewInvite(that);
|
||||
// case "Join": return (ObjectOrLink)NewJoin(that);
|
||||
// case "Leave": return (ObjectOrLink)NewLeave(that);
|
||||
// case "Like": return (ObjectOrLink)NewLike(that);
|
||||
// case "Listen": return (ObjectOrLink)NewListen(that);
|
||||
// case "Move": return (ObjectOrLink)NewMove(that);
|
||||
// case "Offer": return (ObjectOrLink)NewOffer(that);
|
||||
// case "Question": return (ObjectOrLink)NewQuestion(that);
|
||||
// case "Reject": return (ObjectOrLink)NewReject(that);
|
||||
// case "Read": return (ObjectOrLink)NewRead(that);
|
||||
// case "Remove": return (ObjectOrLink)NewRemove(that);
|
||||
// case "TentativeReject": return (ObjectOrLink)NewTentativeReject(that);
|
||||
// case "TentativeAccept": return (ObjectOrLink)NewTentativeAccept(that);
|
||||
// case "Travel": return (ObjectOrLink)NewTravel(that);
|
||||
// case "Undo": return (ObjectOrLink)NewUndo(that);
|
||||
// case "Update": return (ObjectOrLink)NewUpdate(that);
|
||||
// case "View": return (ObjectOrLink)NewView(that);
|
||||
|
||||
// // https://www.w3.org/TR/activitystreams-vocabulary/#actor-types
|
||||
// case "Application": return (ObjectOrLink)NewApplication(that);
|
||||
// case "Group": return (ObjectOrLink)NewGroup(that);
|
||||
// case "Organization": return (ObjectOrLink)NewOrganization(that);
|
||||
// case "Person": return (ObjectOrLink)NewPerson(that);
|
||||
// case "Service": return (ObjectOrLink)NewService(that);
|
||||
|
||||
// // https://www.w3.org/TR/activitystreams-vocabulary/#object-types
|
||||
// case "Article": return (ObjectOrLink)NewArticle(that);
|
||||
// case "Audio": return (ObjectOrLink)NewAudio(that);
|
||||
// case "Document": return (ObjectOrLink)NewDocument(that);
|
||||
// case "Event": return (ObjectOrLink)NewEvent(that);
|
||||
// case "Image": return (ObjectOrLink)NewImage(that);
|
||||
// case "Note": return (ObjectOrLink)NewNote(that);
|
||||
// case "Page": return (ObjectOrLink)NewPage(that);
|
||||
// case "Place": return (ObjectOrLink)NewPlace(that);
|
||||
// case "Profile": return (ObjectOrLink)NewProfile(that);
|
||||
// case "Relationship": return (ObjectOrLink)NewRelationship(that);
|
||||
// case "Tombstone": return (ObjectOrLink)NewTombstone(that);
|
||||
// case "Video": return (ObjectOrLink)NewVideo(that);
|
||||
// case "Mention": return (ObjectOrLink)NewMention(that);
|
||||
|
||||
// default: return null;
|
||||
// }
|
||||
// }
|
||||
|
||||
// public static ListOrLink<T>? NewListOrLink<T>(dynamic that) where T : KristofferStrube.ActivityStreams.Object, new() {
|
||||
// if (that == null) return null;
|
||||
|
||||
// if (that is string) return (ListOrLink<T>)new Uri((string)that);
|
||||
// if (that is Uri) return (ListOrLink<T>)that;
|
||||
|
||||
// if (that is IEnumerable<dynamic>)
|
||||
// return (ListOrLink<T>)(that as IEnumerable<dynamic>).Select(x => NewObjectOrLink(x)).Cast<GenericObjectOrLink<T>>().ToList();
|
||||
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// public static DateTimeOffset? NewDate(dynamic that) {
|
||||
// DateTimeOffset result;
|
||||
// if(DateTimeOffset.TryParse(that, out result)) { return result; }
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// public static Object NewObject(dynamic that, Object? self = null) {
|
||||
// if(self == null) self = new Object();
|
||||
|
||||
// self.Id = new Uri(that.Id);
|
||||
// // self.Type = that.Type; // not necessary
|
||||
// self.Attachment = NewObjectOrLink(that.Attachment);
|
||||
// self.AttributedTo = NewObjectOrLink(that.AttributedTo);
|
||||
// self.Audience = NewObjectOrLink(that.Audience);
|
||||
// self.Content = that.Content;
|
||||
// self.Source = NewObjectOrLink(that.Source);
|
||||
// self.Context = NewObjectOrLink(that.Id);
|
||||
// self.Name = that.Name;
|
||||
// self.EndTime = NewDate(that.EndTime);
|
||||
// self.Generator = NewObjectOrLink(that.Generator);
|
||||
// self.Icon = NewObjectOrLink(that.Icon);
|
||||
// self.Image = NewObjectOrLink(that.Image);
|
||||
// self.InReplyTo = NewObjectOrLink(that.InReplyTo);
|
||||
// self.Location = NewObjectOrLink(that.Location);
|
||||
// self.Preview = NewObjectOrLink(that.Preview);
|
||||
// self.Published = NewDate(that.Published);
|
||||
// self.Replies = NewObjectOrLink(that.Replies);
|
||||
// self.StartTime = NewDate(that.StartTime);
|
||||
// self.Summary = that.Summary;
|
||||
// self.Tag = NewObjectOrLink(that.Tag);
|
||||
// self.Updated = NewDate(that.Id);
|
||||
// self.Url = (that.Url == null || that.Url is Uri) ? that.Url : new Uri(that.Url);
|
||||
// self.To = NewListOrLink<Object>(that.To);
|
||||
// self.Bto = NewListOrLink<Object>(that.Bto);
|
||||
// self.Cc = NewListOrLink<Object>(that.Cc);
|
||||
// self.Bcc = NewListOrLink<Object>(that.Bcc);
|
||||
// self.MediaType = that.MediaType;
|
||||
// self.Duration = that.Duration;
|
||||
// self.Likes = NewListOrLink<Object>(that.Likes);
|
||||
// self.Shares = NewListOrLink<Object>(that.Shares);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Link NewLink(dynamic that, Link? self = null) {
|
||||
// if (self == null) self = new Link();
|
||||
|
||||
// self.Id = new Uri(that.Id);
|
||||
// // self.Type = that.Type; // not necessary
|
||||
|
||||
// self.Rel = that.Rel;
|
||||
// self.MediaType = that.MediaType;
|
||||
// self.Name = that.Name;
|
||||
// self.Hreflang = that.Hreflang;
|
||||
// self.Height = that.Height;
|
||||
// self.Width = that.Width;
|
||||
// self.Preview = NewObjectOrLink(that.Preview);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Mention NewMention(dynamic that, Mention? self = null) {
|
||||
// if(self == null) self = new Mention();
|
||||
|
||||
// self = NewLink(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static IntransitiveActivity NewIntransitiveActivity(dynamic that, IntransitiveActivity? self = null) {
|
||||
// if (self == null) self = new IntransitiveActivity();
|
||||
|
||||
// self = NewObject(that, self);
|
||||
|
||||
// self.Actor = NewObjectOrLink(that.Actor);
|
||||
// self.Target = NewObjectOrLink(that.Target);
|
||||
// self.Result = NewObjectOrLink(that.Result);
|
||||
// self.Origin = NewObjectOrLink(that.Origin);
|
||||
// self.Instrument = NewObjectOrLink(that.Instrument);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Activity NewActivity(dynamic that, Activity? self = null) {
|
||||
// if (self == null) self = new Activity();
|
||||
|
||||
// self = NewIntransitiveActivity(that, self);
|
||||
|
||||
// self.Object = NewObjectOrLink(that.Object);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Collection NewCollection(dynamic that, Collection? self = null) {
|
||||
// if (self == null) self = new Collection();
|
||||
|
||||
// self = NewObject(that, self);
|
||||
|
||||
// self.TotalItems = that.TotalItems;
|
||||
// self.Current = NewObjectOrLink(that.Current);
|
||||
// self.First = NewObjectOrLink(that.First);
|
||||
// self.Last = NewObjectOrLink(that.Last);
|
||||
// self.Items = NewObjectOrLink(that.Items);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Collection NewOrderedCollection(dynamic that, OrderedCollection? self = null) {
|
||||
// if (self == null) self = new OrderedCollection();
|
||||
|
||||
// self = NewCollection(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Collection NewCollectionPage(dynamic that, CollectionPage? self = null) {
|
||||
// if (self == null) self = new CollectionPage();
|
||||
|
||||
// self = NewCollection(that, self);
|
||||
|
||||
// self.PartOf = NewObjectOrLink(that.PartOf);
|
||||
// self.Next = NewObjectOrLink(that.Next);
|
||||
// self.Prev = NewObjectOrLink(that.Prev);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Collection NewOrderedCollectionPage(dynamic that, OrderedCollectionPage? self = null) {
|
||||
// if (self == null) self = new OrderedCollectionPage();
|
||||
|
||||
// self = NewCollectionPage(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static OneOf<Uri, Endpoints>? NewEndpointsOrUri(dynamic that) {
|
||||
// if (that == null) return null;
|
||||
|
||||
// if (that is string) return (OneOf<Uri, Endpoints>)new Uri((string)that);
|
||||
// if (that is Uri) return (OneOf<Uri, Endpoints>)that;
|
||||
|
||||
// return NewEndpoints(that);
|
||||
// }
|
||||
|
||||
// public static Endpoints NewEndpoints(dynamic that, Endpoints? self = null) {
|
||||
// if (self == null) self = new Endpoints();
|
||||
|
||||
// self.ProxyUrl = new Uri(that.ProxyUrl);
|
||||
// self.OauthAuthorizationEndpoint = new Uri(that.OauthAuthorizationEndpoint);
|
||||
// self.OauthTokenEndpoint = new Uri(that.OauthTokenEndpoint);
|
||||
// self.ProvideClientKey = new Uri(that.ProvideClientKey);
|
||||
// self.SignClientKey = new Uri(that.SignClientKey);
|
||||
// self.SharedInbox = new Uri(that.SharedInbox);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Actor NewActor(dynamic that, Actor? self = null) {
|
||||
// if (self == null) self = new Actor();
|
||||
|
||||
// self = NewObject(that, self);
|
||||
|
||||
// self.Inbox = NewObjectOrLink(that.Inbox);
|
||||
// self.Outbox = NewObjectOrLink(that.Outbox);
|
||||
// self.Following = NewObjectOrLink(that.Following);
|
||||
// self.Followers = NewObjectOrLink(that.Followers);
|
||||
// self.Liked = NewObjectOrLink(that.Liked);
|
||||
// self.Streams = NewListOrLink<Collection>(that.Streams);
|
||||
// self.PreferredUsername = that.PreferredUsername;
|
||||
// self.Endpoints = NewEndpointsOrUri(that.Endpoints);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Article NewArticle(dynamic that, Article? self = null) {
|
||||
// if (self == null) self = new Article();
|
||||
|
||||
// self = NewObject(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Document NewDocument(dynamic that, Document? self = null) {
|
||||
// if (self == null) self = new Document();
|
||||
|
||||
// self = NewObject(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Audio NewAudio(dynamic that, Audio? self = null) {
|
||||
// if (self == null) self = new Audio();
|
||||
|
||||
// self = NewDocument(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Event NewEvent(dynamic that, Event? self = null) {
|
||||
// if (self == null) self = new Event();
|
||||
|
||||
// self = NewObject(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Image NewImage(dynamic that, Image? self = null) {
|
||||
// if (self == null) self = new Image();
|
||||
|
||||
// self = NewDocument(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Note NewNote(dynamic that, Note? self = null) {
|
||||
// if (self == null) self = new Note();
|
||||
|
||||
// self = NewObject(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Page NewPage(dynamic that, Page? self = null) {
|
||||
// if (self == null) self = new Page();
|
||||
|
||||
// self = NewDocument(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Place NewPlace(dynamic that, Place? self = null) {
|
||||
// if (self == null) self = new Place();
|
||||
|
||||
// self = NewObject(that, self);
|
||||
// self.Accuracy = that.Accuracy;
|
||||
// self.Altitude = that.Altitude;
|
||||
// self.Latitude = that.Latitude;
|
||||
// self.Longitude = that.Longitude;
|
||||
// self.Radius = that.Radius;
|
||||
// self.Units = that.Units;
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Profile NewProfile(dynamic that, Profile? self = null) {
|
||||
// if (self == null) self = new Profile();
|
||||
|
||||
// self = NewObject(that, self);
|
||||
// self.Describes = NewObjectOrLink(that.Describes);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Relationship NewRelationship(dynamic that, Relationship? self = null) {
|
||||
// if (self == null) self = new Relationship();
|
||||
|
||||
// self = NewObject(that, self);
|
||||
// self.Subject = NewObjectOrLink(that.Subject);
|
||||
// self.Object = NewObjectOrLink(that.Object);
|
||||
// self.relationship = that.relationship;
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Tombstone NewTombstone(dynamic that, Tombstone? self = null) {
|
||||
// if (self == null) self = new Tombstone();
|
||||
|
||||
// self = NewObject(that, self);
|
||||
// self.FormerType = that.FormerType;
|
||||
// self.Deleted = NewDate(that.Deleted);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Video NewVideo(dynamic that, Video? self = null) {
|
||||
// if (self == null) self = new Video();
|
||||
|
||||
// self = NewDocument(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Application NewApplication(dynamic that, Application? self = null) {
|
||||
// if (self == null) self = new Application();
|
||||
|
||||
// self = NewActor(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Group NewGroup(dynamic that, Group? self = null) {
|
||||
// if (self == null) self = new Group();
|
||||
|
||||
// self = NewActor(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Organization NewOrganization(dynamic that, Organization? self = null) {
|
||||
// if (self == null) self = new Organization();
|
||||
|
||||
// self = NewActor(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Person NewPerson(dynamic that, Person? self = null) {
|
||||
// if (self == null) self = new Person();
|
||||
|
||||
// self = NewActor(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Service NewService(dynamic that, Service? self = null) {
|
||||
// if (self == null) self = new Service();
|
||||
|
||||
// self = NewActor(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Block NewBlock(dynamic that, Block? self = null) {
|
||||
// if (self == null) self = new Block();
|
||||
|
||||
// self = NewIgnore(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Invite NewInvite(dynamic that, Invite? self = null) {
|
||||
// if (self == null) self = new Invite();
|
||||
|
||||
// self = NewOffer(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Accept NewAccept(dynamic that, Accept? self = null) {
|
||||
// if (self == null) self = new Accept();
|
||||
|
||||
// self = NewActivity(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Add NewAdd(dynamic that, Add? self = null) {
|
||||
// if (self == null) self = new Add();
|
||||
|
||||
// self = NewActivity(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Announce NewAnnounce(dynamic that, Announce? self = null) {
|
||||
// if (self == null) self = new Announce();
|
||||
|
||||
// self = NewActivity(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Create NewCreate(dynamic that, Create? self = null) {
|
||||
// if (self == null) self = new Create();
|
||||
|
||||
// self = NewActivity(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Delete NewDelete(dynamic that, Delete? self = null) {
|
||||
// if (self == null) self = new Delete();
|
||||
|
||||
// self = NewActivity(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Dislike NewDislike(dynamic that, Dislike? self = null) {
|
||||
// if (self == null) self = new Dislike();
|
||||
|
||||
// self = NewActivity(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Flag NewFlag(dynamic that, Flag? self = null) {
|
||||
// if (self == null) self = new Flag();
|
||||
|
||||
// self = NewActivity(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Follow NewFollow(dynamic that, Follow? self = null) {
|
||||
// if (self == null) self = new Follow();
|
||||
|
||||
// self = NewActivity(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Ignore NewIgnore(dynamic that, Ignore? self = null) {
|
||||
// if (self == null) self = new Ignore();
|
||||
|
||||
// self = NewActivity(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Join NewJoin(dynamic that, Join? self = null) {
|
||||
// if (self == null) self = new Join();
|
||||
|
||||
// self = NewActivity(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Leave NewLeave(dynamic that, Leave? self = null) {
|
||||
// if (self == null) self = new Leave();
|
||||
|
||||
// self = NewActivity(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Like NewLike(dynamic that, Like? self = null) {
|
||||
// if (self == null) self = new Like();
|
||||
|
||||
// self = NewActivity(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Listen NewListen(dynamic that, Listen? self = null) {
|
||||
// if (self == null) self = new Listen();
|
||||
|
||||
// self = NewActivity(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Move NewMove(dynamic that, Move? self = null) {
|
||||
// if (self == null) self = new Move();
|
||||
|
||||
// self = NewActivity(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Offer NewOffer(dynamic that, Offer? self = null) {
|
||||
// if (self == null) self = new Offer();
|
||||
|
||||
// self = NewActivity(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Read NewRead(dynamic that, Read? self = null) {
|
||||
// if (self == null) self = new Read();
|
||||
|
||||
// self = NewActivity(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Reject NewReject(dynamic that, Reject? self = null) {
|
||||
// if (self == null) self = new Reject();
|
||||
|
||||
// self = NewActivity(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Remove NewRemove(dynamic that, Remove? self = null) {
|
||||
// if (self == null) self = new Remove();
|
||||
|
||||
// self = NewActivity(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Undo NewUndo(dynamic that, Undo? self = null) {
|
||||
// if (self == null) self = new Undo();
|
||||
|
||||
// self = NewActivity(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Update NewUpdate(dynamic that, Update? self = null) {
|
||||
// if (self == null) self = new Update();
|
||||
|
||||
// self = NewActivity(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static View NewView(dynamic that, View? self = null) {
|
||||
// if (self == null) self = new View();
|
||||
|
||||
// self = NewActivity(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static TentativeAccept NewTentativeAccept(dynamic that, TentativeAccept? self = null) {
|
||||
// if (self == null) self = new TentativeAccept();
|
||||
|
||||
// self = NewAccept(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static TentativeReject NewTentativeReject(dynamic that, TentativeReject? self = null) {
|
||||
// if (self == null) self = new TentativeReject();
|
||||
|
||||
// self = NewReject(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Arrive NewArrive(dynamic that, Arrive? self = null) {
|
||||
// if (self == null) self = new Arrive();
|
||||
|
||||
// self = NewIntransitiveActivity(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Travel NewTravel(dynamic that, Travel? self = null) {
|
||||
// if (self == null) self = new Travel();
|
||||
|
||||
// self = NewIntransitiveActivity(that, self);
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// public static Question NewQuestion(dynamic that, Question? self = null) {
|
||||
// if (self == null) self = new Question();
|
||||
|
||||
// self = NewIntransitiveActivity(that, self);
|
||||
// self.OneOf = NewListOrLink<Object>(that.OneOf);
|
||||
// self.AnyOf = NewListOrLink<Object>(that.AnyOf);
|
||||
// ObjectOrLink? closed = NewObjectOrLink(that.Closed);
|
||||
// if(closed != null) self.Closed = (Uri)closed;
|
||||
// else {
|
||||
// DateTimeOffset? dateClosed = NewDate(that.Closed);
|
||||
// if (dateClosed.HasValue) self.Closed = dateClosed.Value;
|
||||
// else self.Closed = !!that.closed;
|
||||
// }
|
||||
|
||||
// return self;
|
||||
// }
|
||||
|
||||
//}
|
17
Models/Activity.cs
Normal file
17
Models/Activity.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Activity
|
||||
/// </summary>
|
||||
public class Activity : IntransitiveActivity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Activity() : base() => this.Type = "Activity";
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Object
|
||||
/// </summary>
|
||||
public ObjectOrLink? Object { get; set; }
|
||||
}
|
12
Models/Activity/Accept.cs
Normal file
12
Models/Activity/Accept.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Accept
|
||||
/// </summary>
|
||||
public class Accept : Activity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Accept() : base() => this.Type = "Accept";
|
||||
}
|
12
Models/Activity/Add.cs
Normal file
12
Models/Activity/Add.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Add
|
||||
/// </summary>
|
||||
public class Add : Activity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Add() : base() => this.Type = "Add";
|
||||
}
|
12
Models/Activity/Announce.cs
Normal file
12
Models/Activity/Announce.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Announce
|
||||
/// </summary>
|
||||
public class Announce : Activity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Announce() : base() => this.Type = "Announce";
|
||||
}
|
12
Models/Activity/Block.cs
Normal file
12
Models/Activity/Block.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Block
|
||||
/// </summary>
|
||||
public class Block : Ignore {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Block() : base() => this.Type = "Block";
|
||||
}
|
12
Models/Activity/Create.cs
Normal file
12
Models/Activity/Create.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Create
|
||||
/// </summary>
|
||||
public class Create : Activity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Create() : base() => this.Type = "Create";
|
||||
}
|
12
Models/Activity/Delete.cs
Normal file
12
Models/Activity/Delete.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Delete
|
||||
/// </summary>
|
||||
public class Delete : Activity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Delete() : base() => this.Type = "Delete";
|
||||
}
|
12
Models/Activity/Dislike.cs
Normal file
12
Models/Activity/Dislike.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Dislike
|
||||
/// </summary>
|
||||
public class Dislike : Activity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Dislike() : base() => this.Type = "Dislike";
|
||||
}
|
12
Models/Activity/Flag.cs
Normal file
12
Models/Activity/Flag.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Flag
|
||||
/// </summary>
|
||||
public class Flag : Activity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Flag() : base() => this.Type = "Flag";
|
||||
}
|
12
Models/Activity/Follow.cs
Normal file
12
Models/Activity/Follow.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Follow
|
||||
/// </summary>
|
||||
public class Follow : Activity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Follow() : base() => this.Type = "Follow";
|
||||
}
|
12
Models/Activity/Ignore.cs
Normal file
12
Models/Activity/Ignore.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Ignore
|
||||
/// </summary>
|
||||
public class Ignore : Activity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Ignore() : base() => this.Type = "Ignore";
|
||||
}
|
12
Models/Activity/Intransitive/Arrive.cs
Normal file
12
Models/Activity/Intransitive/Arrive.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Arrive
|
||||
/// </summary>
|
||||
public class Arrive : IntransitiveActivity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Arrive() : base() => this.Type = "Arrive";
|
||||
}
|
29
Models/Activity/Intransitive/Question.cs
Normal file
29
Models/Activity/Intransitive/Question.cs
Normal file
|
@ -0,0 +1,29 @@
|
|||
using OneOf;
|
||||
|
||||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Question
|
||||
/// </summary>
|
||||
public class Question : IntransitiveActivity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Question() : base() => this.Type = "Question";
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#oneOf
|
||||
/// </summary>
|
||||
public ListOrLink<Object> OneOf { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#anyOf
|
||||
/// </summary>
|
||||
public ListOrLink<Object> AnyOf { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#closed
|
||||
/// </summary>
|
||||
public OneOf<Uri, Object, DateTimeOffset, bool> Closed { get; set; }
|
||||
}
|
12
Models/Activity/Intransitive/Travel.cs
Normal file
12
Models/Activity/Intransitive/Travel.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Travel
|
||||
/// </summary>
|
||||
public class Travel : IntransitiveActivity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Travel() : base() => this.Type = "Travel";
|
||||
}
|
12
Models/Activity/Invite.cs
Normal file
12
Models/Activity/Invite.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Invite
|
||||
/// </summary>
|
||||
public class Invite : Offer {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Invite() : base() => this.Type = "Invite";
|
||||
}
|
12
Models/Activity/Join.cs
Normal file
12
Models/Activity/Join.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Join
|
||||
/// </summary>
|
||||
public class Join : Activity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Join() : base() => this.Type = "Join";
|
||||
}
|
12
Models/Activity/Leave.cs
Normal file
12
Models/Activity/Leave.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Leave
|
||||
/// </summary>
|
||||
public class Leave : Activity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Leave() : base() => this.Type = "Leave";
|
||||
}
|
12
Models/Activity/Like.cs
Normal file
12
Models/Activity/Like.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Like
|
||||
/// </summary>
|
||||
public class Like : Activity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Like() : base() => this.Type = "Like";
|
||||
}
|
12
Models/Activity/Listen.cs
Normal file
12
Models/Activity/Listen.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Listen
|
||||
/// </summary>
|
||||
public class Listen : Activity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Listen() : base() => this.Type = "Listen";
|
||||
}
|
12
Models/Activity/Move.cs
Normal file
12
Models/Activity/Move.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Move
|
||||
/// </summary>
|
||||
public class Move : Activity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Move() : base() => this.Type = "Move";
|
||||
}
|
12
Models/Activity/Offer.cs
Normal file
12
Models/Activity/Offer.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Offer
|
||||
/// </summary>
|
||||
public class Offer : Activity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Offer() : base() => this.Type = "Offer";
|
||||
}
|
12
Models/Activity/Read.cs
Normal file
12
Models/Activity/Read.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Read
|
||||
/// </summary>
|
||||
public class Read : Activity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Read() : base() => this.Type = "Read";
|
||||
}
|
12
Models/Activity/Reject.cs
Normal file
12
Models/Activity/Reject.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Reject
|
||||
/// </summary>
|
||||
public class Reject : Activity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Reject() : base() => this.Type = "Reject";
|
||||
}
|
12
Models/Activity/Remove.cs
Normal file
12
Models/Activity/Remove.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Remove
|
||||
/// </summary>
|
||||
public class Remove : Activity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Remove() : base() => this.Type = "Remove";
|
||||
}
|
12
Models/Activity/TentativeAccept.cs
Normal file
12
Models/Activity/TentativeAccept.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#TentativeAccept
|
||||
/// </summary>
|
||||
public class TentativeAccept : Accept {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public TentativeAccept() : base() => this.Type = "TentaativeAccept";
|
||||
}
|
12
Models/Activity/TentativeReject.cs
Normal file
12
Models/Activity/TentativeReject.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#TentativeReject
|
||||
/// </summary>
|
||||
public class TentativeReject : Reject {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public TentativeReject() : base() => this.Type = "TentativeReject";
|
||||
}
|
12
Models/Activity/Undo.cs
Normal file
12
Models/Activity/Undo.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Undo
|
||||
/// </summary>
|
||||
public class Undo : Activity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Undo() : base() => this.Type = "Undo";
|
||||
}
|
12
Models/Activity/Update.cs
Normal file
12
Models/Activity/Update.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Update
|
||||
/// </summary>
|
||||
public class Update : Activity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Update() : base() => this.Type = "Update";
|
||||
}
|
12
Models/Activity/View.cs
Normal file
12
Models/Activity/View.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#View
|
||||
/// </summary>
|
||||
public class View : Activity {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public View() : base() => this.Type = "View";
|
||||
}
|
21
Models/Actor.cs
Normal file
21
Models/Actor.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/TR/activitypub/#actor-objects
|
||||
/// </summary>
|
||||
public class Actor : Object {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Actor() : base() => this.Type = "Actor";
|
||||
public CollectionOrLink Inbox { get; set; }
|
||||
public CollectionOrLink Outbox { get; set; }
|
||||
public CollectionOrLink Following { get; set; }
|
||||
public CollectionOrLink Followers { get; set; }
|
||||
public CollectionOrLink Liked { get; set; }
|
||||
|
||||
public ListOrLink<Collection>? Streams { get; set; }
|
||||
public string? PreferredUsername { get; set; }
|
||||
public OneOf.OneOf<Uri, Endpoints>? Endpoints { get; set; }
|
||||
}
|
12
Models/Actor/Application.cs
Normal file
12
Models/Actor/Application.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Application
|
||||
/// </summary>
|
||||
public class Application : Actor {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Application() : base() => this.Type = "Application";
|
||||
}
|
12
Models/Actor/Group.cs
Normal file
12
Models/Actor/Group.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Group
|
||||
/// </summary>
|
||||
public class Group : Actor {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Group() : base() => this.Type = "Group";
|
||||
}
|
12
Models/Actor/Organization.cs
Normal file
12
Models/Actor/Organization.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Organization
|
||||
/// </summary>
|
||||
public class Organization : Actor {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Organization() : base() => this.Type = "Organization";
|
||||
}
|
12
Models/Actor/Person.cs
Normal file
12
Models/Actor/Person.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Person
|
||||
/// </summary>
|
||||
public class Person : Actor {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Person() : base() => this.Type = "Person";
|
||||
}
|
12
Models/Actor/Service.cs
Normal file
12
Models/Actor/Service.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Service
|
||||
/// </summary>
|
||||
public class Service : Actor {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Service() : base() => this.Type = "Service";
|
||||
}
|
35
Models/Collection.cs
Normal file
35
Models/Collection.cs
Normal file
|
@ -0,0 +1,35 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
// https://www.w3.org/ns/activitystreams#Collection
|
||||
public class Collection : Object {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Collection() : base() => this.Type = "Collection";
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#totalItems
|
||||
/// </summary>
|
||||
public uint? TotalItems { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#current
|
||||
/// </summary>
|
||||
public CollectionPageOrLink? Current { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#first
|
||||
/// </summary>
|
||||
public CollectionPageOrLink? First { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#last
|
||||
/// </summary>
|
||||
public CollectionPageOrLink? Last { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#items
|
||||
/// </summary>
|
||||
public CollectionPageOrLink? Items { get; set; }
|
||||
}
|
20
Models/CollectionPage.cs
Normal file
20
Models/CollectionPage.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#CollectionPage
|
||||
/// </summary>
|
||||
public class CollectionPage : Collection {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public CollectionPage() : base() => this.Type = "CollectionPage";
|
||||
// https://www.w3.org/ns/activitystreams#partOf
|
||||
public CollectionOrLink? PartOf { get; set; }
|
||||
|
||||
// https://www.w3.org/ns/activitystreams#next
|
||||
public CollectionPageOrLink? Next { get; set; }
|
||||
|
||||
// https://www.w3.org/ns/activitystreams#prev
|
||||
public CollectionPageOrLink? Prev { get; set; }
|
||||
}
|
15
Models/Endpoints.cs
Normal file
15
Models/Endpoints.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/TR/activitypub/#endpoints
|
||||
/// </summary>
|
||||
public class Endpoints
|
||||
{
|
||||
public Uri? ProxyUrl { get; set; }
|
||||
public Uri? OauthAuthorizationEndpoint { get; set; }
|
||||
public Uri? OauthTokenEndpoint { get; set; }
|
||||
public Uri? ProvideClientKey { get; set; }
|
||||
public Uri? SignClientKey { get; set; }
|
||||
public Uri? SharedInbox { get; set; }
|
||||
}
|
||||
|
38
Models/IntransitiveActivity.cs
Normal file
38
Models/IntransitiveActivity.cs
Normal file
|
@ -0,0 +1,38 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#IntransitiveActivity
|
||||
/// </summary>
|
||||
public class IntransitiveActivity : Object {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public IntransitiveActivity() : base() => this.Type = "IntransitiveActivity";
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#actor
|
||||
/// </summary>
|
||||
public ObjectOrLink? Actor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#target
|
||||
/// </summary>
|
||||
public ObjectOrLink? Target { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#result
|
||||
/// </summary>
|
||||
public ObjectOrLink? Result { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#origin
|
||||
/// </summary>
|
||||
public ObjectOrLink? Origin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#instrument
|
||||
/// </summary>
|
||||
public ObjectOrLink? Instrument { get; set; }
|
||||
|
||||
}
|
63
Models/Link.cs
Normal file
63
Models/Link.cs
Normal file
|
@ -0,0 +1,63 @@
|
|||
using OneOf;
|
||||
|
||||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Link
|
||||
/// </summary>
|
||||
public class Link {
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Link() => this.Type = "Link";
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/TR/activitypub/#obj-id
|
||||
/// </summary>
|
||||
public Uri? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/TR/activitystreams-vocabulary/#dfn-type
|
||||
/// </summary>
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#href
|
||||
/// </summary>
|
||||
public Uri? Href { get => this.Id; set => this.Id = value; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#rel
|
||||
/// </summary>
|
||||
public string? Rel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#mediaType
|
||||
/// </summary>
|
||||
public string? MediaType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#name
|
||||
/// </summary>
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#hreflang
|
||||
/// </summary>
|
||||
public string? Hreflang { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#height
|
||||
/// </summary>
|
||||
public uint? Height { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#width
|
||||
/// </summary>
|
||||
public uint? Width { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#preview
|
||||
/// </summary>
|
||||
public ObjectOrLink? Preview { get; set; }
|
||||
}
|
13
Models/Links/Mention.cs
Normal file
13
Models/Links/Mention.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Mention
|
||||
/// </summary>
|
||||
public class Mention : Link {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Mention() : base() => this.Type = "Mention";
|
||||
|
||||
}
|
181
Models/Object.cs
Normal file
181
Models/Object.cs
Normal file
|
@ -0,0 +1,181 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Object
|
||||
/// </summary>
|
||||
public class Object {
|
||||
/// <summary>
|
||||
/// Default contructor
|
||||
/// </summary>
|
||||
public Object() => this.Type = "Object";
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/TR/activitypub/#obj-id
|
||||
/// </summary>
|
||||
public Uri? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/TR/activitystreams-vocabulary/#dfn-type
|
||||
/// </summary>
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#attachment
|
||||
/// </summary>
|
||||
public ObjectOrLink? Attachment { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#attributedTo
|
||||
/// </summary>
|
||||
public ObjectOrLink? AttributedTo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#audience
|
||||
/// </summary>
|
||||
public ObjectOrLink? Audience { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#content
|
||||
/// </summary>
|
||||
public string? Content { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/TR/activitypub/#source-property
|
||||
/// </summary>
|
||||
public ObjectOrLink? Source { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#context
|
||||
/// </summary>
|
||||
public ObjectOrLink? Context { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#name
|
||||
/// </summary>
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#endTime
|
||||
/// </summary>
|
||||
public DateTimeOffset? EndTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#generator
|
||||
/// </summary>
|
||||
public ObjectOrLink? Generator { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#icon
|
||||
/// </summary>
|
||||
public GenericObjectOrLink<Image>? Icon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Image
|
||||
/// </summary>
|
||||
public Image? Image { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#inReplyTo
|
||||
/// </summary>
|
||||
public ObjectOrLink? InReplyTo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#location
|
||||
/// </summary>
|
||||
public ObjectOrLink? Location { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#preview
|
||||
/// </summary>
|
||||
public ObjectOrLink? Preview { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#published
|
||||
/// </summary>
|
||||
public DateTimeOffset? Published { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#replies
|
||||
/// </summary>
|
||||
public Collection? Replies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#startTime
|
||||
/// </summary>
|
||||
public DateTimeOffset? StartTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#summary
|
||||
/// </summary>
|
||||
public string? Summary { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#tag
|
||||
/// </summary>
|
||||
public ObjectOrLink? Tag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#updated
|
||||
/// </summary>
|
||||
public DateTimeOffset? Updated { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#url
|
||||
/// </summary>
|
||||
public LinkOrUri? Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#to
|
||||
/// </summary>
|
||||
public ListOrLink<Object>? To { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#bto
|
||||
/// </summary>
|
||||
public ListOrLink<Object>? Bto { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#cc
|
||||
/// </summary>
|
||||
public ListOrLink<Object>? Cc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#bcc
|
||||
/// </summary>
|
||||
public ListOrLink<Object>? Bcc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#mediaType
|
||||
/// </summary>
|
||||
public string? MediaType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#duration
|
||||
/// </summary>
|
||||
public string? Duration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/TR/activitypub/#likes
|
||||
/// </summary>
|
||||
public ListOrLink<Object>? Likes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/TR/activitypub/#shares
|
||||
/// </summary>
|
||||
public ListOrLink<Object>? Shares { get; set; }
|
||||
|
||||
//public Object(dynamic that) {
|
||||
// if(that.Id is Uri) this.Id = that.Id;
|
||||
// if(that.Id is string) this.Id = new Uri(that.Id);
|
||||
|
||||
// this.Type = that.Type;
|
||||
//}
|
||||
|
||||
//public static ObjectOrLink? FromDynamic(dynamic that) {
|
||||
// if (that is null) return null;
|
||||
// if (that is Uri) return (ObjectOrLink?)(Uri)that;
|
||||
// if (that is string) return (ObjectOrLink?)new Uri((string)that);
|
||||
// if (that is Object) return (ObjectOrLink?)(Object)that;
|
||||
// return (ObjectOrLink?)new Object(that);
|
||||
//}
|
||||
}
|
13
Models/Objects/Article.cs
Normal file
13
Models/Objects/Article.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Article
|
||||
/// </summary>
|
||||
public class Article : Object {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Article() : base() => this.Type = "Article";
|
||||
|
||||
}
|
13
Models/Objects/Audio.cs
Normal file
13
Models/Objects/Audio.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Audio
|
||||
/// </summary>
|
||||
public class Audio : Document {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Audio() : base() => this.Type = "Audio";
|
||||
|
||||
}
|
13
Models/Objects/Document.cs
Normal file
13
Models/Objects/Document.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Document
|
||||
/// </summary>
|
||||
public class Document : Object {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Document() : base() => this.Type = "Document";
|
||||
|
||||
}
|
13
Models/Objects/Event.cs
Normal file
13
Models/Objects/Event.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Event
|
||||
/// </summary>
|
||||
public class Event : Object {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Event() : base() => this.Type = "Event";
|
||||
|
||||
}
|
13
Models/Objects/Image.cs
Normal file
13
Models/Objects/Image.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Image
|
||||
/// </summary>
|
||||
public class Image : Document {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Image() : base() => this.Type = "Image";
|
||||
|
||||
}
|
14
Models/Objects/Note.cs
Normal file
14
Models/Objects/Note.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Note
|
||||
/// </summary>
|
||||
public class Note : Object {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Note() : base() => this.Type = "Note";
|
||||
|
||||
}
|
||||
|
13
Models/Objects/Page.cs
Normal file
13
Models/Objects/Page.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Page
|
||||
/// </summary>
|
||||
public class Page : Document {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Page() : base() => this.Type = "Page";
|
||||
|
||||
}
|
42
Models/Objects/Place.cs
Normal file
42
Models/Objects/Place.cs
Normal file
|
@ -0,0 +1,42 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Place
|
||||
/// </summary>
|
||||
public class Place : Object {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Place() : base() => this.Type = "Place";
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#accuracy
|
||||
/// </summary>
|
||||
public float? Accuracy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#altitude
|
||||
/// </summary>
|
||||
public float? Altitude { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#latitude
|
||||
/// </summary>
|
||||
public float? Latitude { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#longitude
|
||||
/// </summary>
|
||||
public float? Longitude { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#radius
|
||||
/// </summary>
|
||||
public float? Radius { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#units
|
||||
/// </summary>
|
||||
public string? Units { get; set; }
|
||||
}
|
17
Models/Objects/Profile.cs
Normal file
17
Models/Objects/Profile.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Profile
|
||||
/// </summary>
|
||||
public class Profile : Object {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Profile() : base() => this.Type = "Profile";
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#describes
|
||||
/// </summary>
|
||||
public ObjectOrLink? Describes { get; set; }
|
||||
}
|
29
Models/Objects/Relationship.cs
Normal file
29
Models/Objects/Relationship.cs
Normal file
|
@ -0,0 +1,29 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Relationship
|
||||
/// </summary>
|
||||
public class Relationship : Object {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Relationship() : base() => this.Type = "Relationship";
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#subject
|
||||
/// </summary>
|
||||
public ObjectOrLink? Subject { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Object
|
||||
/// </summary>
|
||||
public ObjectOrLink? Object { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Relationship
|
||||
/// </summary>
|
||||
// This is the only lowercase property in all the classes
|
||||
// because "Member names cannot be the same as their enclosing type"
|
||||
public string? relationship { get; set; }
|
||||
}
|
22
Models/Objects/Tombstone.cs
Normal file
22
Models/Objects/Tombstone.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Tombstone
|
||||
/// </summary>
|
||||
public class Tombstone : Object {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Tombstone() : base() => this.Type = "Tombstone";
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#formerType
|
||||
/// </summary>
|
||||
public string? FormerType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#deleted
|
||||
/// </summary>
|
||||
public DateTimeOffset? Deleted { get; set; }
|
||||
}
|
13
Models/Objects/Video.cs
Normal file
13
Models/Objects/Video.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#Video
|
||||
/// </summary>
|
||||
public class Video : Document {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public Video() : base() => this.Type = "Video";
|
||||
|
||||
}
|
12
Models/OrderedCollection.cs
Normal file
12
Models/OrderedCollection.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#OrderedCollection
|
||||
/// </summary>
|
||||
public class OrderedCollection : Collection {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public OrderedCollection() : base() => this.Type = "OrderedCollection";
|
||||
}
|
17
Models/OrderedCollectionPage.cs
Normal file
17
Models/OrderedCollectionPage.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
namespace ActivityPub;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#OrderedCollectionPage
|
||||
/// </summary>
|
||||
public class OrderedCollectionPage : CollectionPage {
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public OrderedCollectionPage() : base() => this.Type = "OrderedCollectionPage";
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/ns/activitystreams#startIndex
|
||||
/// </summary>
|
||||
public uint StartIndex { get; set; }
|
||||
}
|
87
ObjectStore.cs
Normal file
87
ObjectStore.cs
Normal file
|
@ -0,0 +1,87 @@
|
|||
using ActivityPub.Controllers;
|
||||
using ActivityPub.Utils;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using KristofferStrube.ActivityStreams;
|
||||
|
||||
namespace ActivityPub;
|
||||
|
||||
public class ObjectStore {
|
||||
private static Dictionary<string, Dictionary<string, KristofferStrube.ActivityStreams.Object>> _objects = new();
|
||||
private IUrlHelper Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
/// <param name="url">A url helper to construct id urls</param>
|
||||
public ObjectStore(IUrlHelper url) {
|
||||
this.Url = url;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a new Id for an Object
|
||||
/// </summary>
|
||||
public static string NewId {
|
||||
get {
|
||||
long idTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
//while (_objects.ContainsKey(Base36.ToString(idTime))) idTime++;
|
||||
return Base36.ToString(idTime);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a new object into the data store
|
||||
/// </summary>
|
||||
/// <param name="newObject">The object to store</param>
|
||||
/// <returns>
|
||||
/// The new Object to be stored
|
||||
/// (with updated properties such as Id, Bto and Bcc removed, etc.)
|
||||
/// </returns>
|
||||
public KristofferStrube.ActivityStreams.Object InsertObject(KristofferStrube.ActivityStreams.Object newObject) {
|
||||
if (newObject.Type == null) throw new ArgumentException("Object must have Type");
|
||||
|
||||
string id = NewId;
|
||||
newObject.Id = this.Url.AbsoluteContent($"~/{newObject.Type.First()}/{id}");
|
||||
newObject.Bto = newObject.Bcc = null;
|
||||
|
||||
string objectType = newObject.Type.First();
|
||||
if (!ObjectController._objects.ContainsKey(objectType)) ObjectController._objects[objectType] = new();
|
||||
ObjectController._objects[objectType][id] = newObject;
|
||||
|
||||
return newObject;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an object just by Id
|
||||
/// </summary>
|
||||
/// <param name="id">The Id to find</param>
|
||||
/// <returns>The object with the corresponding id, or null if not found</returns>
|
||||
public KristofferStrube.ActivityStreams.Object? GetObjectById(string id) {
|
||||
foreach (Dictionary<string, KristofferStrube.ActivityStreams.Object> list in _objects.Values) {
|
||||
foreach (KeyValuePair<string, KristofferStrube.ActivityStreams.Object> kvp in list) {
|
||||
if (kvp.Key == id) return kvp.Value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an object by type and id
|
||||
/// </summary>
|
||||
/// <param name="type">The type</param>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public KristofferStrube.ActivityStreams.Object? GetObjectByTypeAndId(string type, string id) {
|
||||
type = Types.Normalize(type);
|
||||
return _objects[type]?[id];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of all Objects by Type
|
||||
/// </summary>
|
||||
/// <param name="type">The type of object to retrieve</param>
|
||||
/// <returns>A list of objects of the specified type</returns>
|
||||
public List<KristofferStrube.ActivityStreams.Object> GetObjectsByType(string type) {
|
||||
type = Types.Normalize(type);
|
||||
return _objects[type]?.Values.ToList() ?? new List<KristofferStrube.ActivityStreams.Object>();
|
||||
}
|
||||
}
|
65
Program.cs
Normal file
65
Program.cs
Normal file
|
@ -0,0 +1,65 @@
|
|||
using Microsoft.OpenApi.Models;
|
||||
using KristofferStrube.ActivityStreams.JsonConverters;
|
||||
using System.Reflection;
|
||||
using System.Text.Json.Serialization;
|
||||
using KristofferStrube.ActivityStreams;
|
||||
using KristofferStrube.ActivityStreams.JsonLD;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add services to the container.
|
||||
|
||||
builder.Services.AddControllers().AddJsonOptions(options =>
|
||||
{
|
||||
options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
|
||||
//options.JsonSerializerOptions.Converters.Add(new CollectionOrLinkConverter());
|
||||
//options.JsonSerializerOptions.Converters.Add(new CollectionPageOrLinkConverter());
|
||||
//options.JsonSerializerOptions.Converters.Add(new DateTimeBooleanObjectOrLinkConverter());
|
||||
//options.JsonSerializerOptions.Converters.Add(new EndpointsOrLinkConverter());
|
||||
//options.JsonSerializerOptions.Converters.Add(new ImageOrLinkConverter());
|
||||
//options.JsonSerializerOptions.Converters.Add(new LinkConverter());
|
||||
//options.JsonSerializerOptions.Converters.Add(new ObjectConverter());
|
||||
//options.JsonSerializerOptions.Converters.Add(new ObjectOrLinkConverter());
|
||||
//options.JsonSerializerOptions.Converters.Add(new TermDefinitionConverter());
|
||||
//options.JsonSerializerOptions.Converters.Add(new XMLTimeSpanConverter());
|
||||
//options.JsonSerializerOptions.Converters.Add(new OneOrMultipleConverter<string>());
|
||||
//options.JsonSerializerOptions.Converters.Add(new OneOrMultipleConverter<IObjectOrLink>());
|
||||
//options.JsonSerializerOptions.Converters.Add(new OneOrMultipleConverter<ITermDefinition>());
|
||||
//options.JsonSerializerOptions.Converters.Add(new OneOrMultipleConverter<IDictionary<string, string>>());
|
||||
});
|
||||
|
||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen(options =>
|
||||
{
|
||||
options.SwaggerDoc("v1", new OpenApiInfo
|
||||
{
|
||||
Version = "v0.0.1",
|
||||
Title = "ActivityPub API",
|
||||
Description = "An ASP.NET Core Web API for ActivityPub C2S and S2S Protocols"
|
||||
});
|
||||
|
||||
var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
||||
options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
|
||||
});
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI(options =>
|
||||
{
|
||||
options.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
|
||||
options.RoutePrefix = string.Empty;
|
||||
}); ;
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
app.MapControllers();
|
||||
|
||||
app.Run();
|
38
Properties/launchSettings.json
Normal file
38
Properties/launchSettings.json
Normal file
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"dotnetRunMessages": true,
|
||||
"applicationUrl": "http://localhost:5062"
|
||||
},
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"dotnetRunMessages": true,
|
||||
"applicationUrl": "https://localhost:7055;http://localhost:5062"
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
},
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:18653",
|
||||
"sslPort": 44371
|
||||
}
|
||||
}
|
||||
}
|
199
Types.cs
Normal file
199
Types.cs
Normal file
|
@ -0,0 +1,199 @@
|
|||
|
||||
namespace ActivityPub;
|
||||
|
||||
///// <summary>
|
||||
///// A class representing a link (either as a Uri or Link object)
|
||||
///// </summary>
|
||||
//public class LinkOrUri : OneOfBase<Uri, Link> {
|
||||
|
||||
// protected LinkOrUri(OneOf<Uri, Link> _) : base(_) { }
|
||||
|
||||
// public static implicit operator LinkOrUri(Uri _) => new LinkOrUri(_);
|
||||
// public static implicit operator LinkOrUri(Link _) => new LinkOrUri(_);
|
||||
// public static implicit operator LinkOrUri(string _) => new LinkOrUri(new Uri(_));
|
||||
|
||||
// public static explicit operator Uri?(LinkOrUri _) => _.Match(uri => uri, link => link.Href);
|
||||
// public static explicit operator Link(LinkOrUri _) => _.Match(
|
||||
// uri => new Link { Href = uri },
|
||||
// link => link
|
||||
// );
|
||||
// public static explicit operator string?(LinkOrUri _) => ((Uri?)_)?.ToString();
|
||||
|
||||
// public T? FetchObject<T>() where T : Object, new() {
|
||||
// Uri? uri = (Uri?)this;
|
||||
// if (uri == null) return default(T);
|
||||
|
||||
// // TODO: Fetch the object from the uri instead of the below:
|
||||
// return this.Match(
|
||||
// uri => new T { Id = uri }, // TODO: Fetch the object
|
||||
// link => new T { Id = link.Href, Name = link.Name } // TODO: Fetch the object
|
||||
// );
|
||||
// }
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// A class representing either an object or link
|
||||
///// </summary>
|
||||
//public class GenericObjectOrLink<T> : OneOfBase<Uri, Link, T> where T : Object, new() {
|
||||
|
||||
// protected GenericObjectOrLink(OneOf<Uri, Link, T> _) : base(_) { }
|
||||
|
||||
// public static implicit operator GenericObjectOrLink<T>(Uri _) => new GenericObjectOrLink<T>(_);
|
||||
// public static implicit operator GenericObjectOrLink<T>(Link _) => new GenericObjectOrLink<T>(_);
|
||||
// public static implicit operator GenericObjectOrLink<T>(T _) => new GenericObjectOrLink<T>(_);
|
||||
// public static implicit operator GenericObjectOrLink<T>(string _) => new GenericObjectOrLink<T>(new Uri(_));
|
||||
|
||||
// public static explicit operator Uri(GenericObjectOrLink<T> _) => _.Match(uri => uri, link => link.Href, obj => obj.Id);
|
||||
// public static explicit operator Link(GenericObjectOrLink<T> _) => _.Match(
|
||||
// uri => new Link { Href = uri },
|
||||
// link => link,
|
||||
// obj => new Link { Href = obj.Id, Name = obj.Name }
|
||||
// );
|
||||
// public static explicit operator T?(GenericObjectOrLink<T> _) => _.FetchObject();
|
||||
// public static explicit operator string?(GenericObjectOrLink<T> _) => ((Uri?)_)?.ToString();
|
||||
|
||||
// public T? FetchObject(bool force = false) {
|
||||
// if (this.IsT2 && !force) return this.AsT2;
|
||||
// Uri? uri = (Uri?)this;
|
||||
// if (uri == null) return null;
|
||||
|
||||
// // TODO: Fetch the object from the uri instead of the below:
|
||||
// return this.Match(
|
||||
// uri => new T { Id = uri }, // TODO: Fetch the object
|
||||
// link => new T { Id = link.Href, Name = link.Name }, // TODO: Fetch the object
|
||||
// obj => obj
|
||||
// );
|
||||
// }
|
||||
//}
|
||||
|
||||
//public class ObjectOrLink : GenericObjectOrLink<Object> {
|
||||
// protected ObjectOrLink(OneOf<Uri, Link, Object> _) : base(_) { }
|
||||
// public bool IsUri => this.IsT0;
|
||||
// public bool IsLink => this.IsT1;
|
||||
// public bool IsObject => this.IsT2;
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// A class representing either a collection or link
|
||||
///// </summary>
|
||||
//public class CollectionOrLink : GenericObjectOrLink<Collection> {
|
||||
// protected CollectionOrLink(OneOf<Uri, Link, Collection> _) : base(_) { }
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// A class representing either a collection page or link
|
||||
///// </summary>
|
||||
//public class CollectionPageOrLink : GenericObjectOrLink<CollectionPage> {
|
||||
// protected CollectionPageOrLink(OneOf<Uri, Link, CollectionPage> _) : base(_) { }
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// A class representing a list of ObjectOrLinks
|
||||
///// </summary>
|
||||
//public class ListOrLink<T> : List<GenericObjectOrLink<T>> where T : Object, new() {
|
||||
// protected ListOrLink(List<GenericObjectOrLink<T>> _) : base(_) { }
|
||||
|
||||
// public static implicit operator ListOrLink<T>(Uri _) => new ListOrLink<T>(new List<GenericObjectOrLink<T>> { _ });
|
||||
// public static implicit operator ListOrLink<T>(Link _) => new ListOrLink<T>(new List<GenericObjectOrLink<T>> { _ });
|
||||
// public static implicit operator ListOrLink<T>(T _) => new ListOrLink<T>(new List<GenericObjectOrLink<T>> { _ });
|
||||
// public static implicit operator ListOrLink<T>(string _) => new ListOrLink<T>(new List<GenericObjectOrLink<T>> { new Uri(_) });
|
||||
|
||||
// public static explicit operator List<Uri>(ListOrLink<T> _) => _.Cast<Uri>().ToList();
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Static functions for working with ActivityPub/ActivityStreams types
|
||||
/// </summary>
|
||||
public static class Types {
|
||||
|
||||
/// <summary>
|
||||
/// Normalizes the type string to title case (all types in ActivityStreams start with a capital letter)
|
||||
/// </summary>
|
||||
/// <param name="type">The type string to normalize</param>
|
||||
/// <returns>The normalized type string (capital first letter)</returns>
|
||||
public static string Normalize(string type) {
|
||||
return Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(type.ToLower());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/TR/activitystreams-vocabulary/#activity-types
|
||||
/// </summary>
|
||||
public static readonly string[] Activity = [
|
||||
"Accept",
|
||||
"Add",
|
||||
"Announce",
|
||||
"Arrive",
|
||||
"Block",
|
||||
"Create",
|
||||
"Delete",
|
||||
"Dislike",
|
||||
"Flag",
|
||||
"Follow",
|
||||
"Ignore",
|
||||
"Invite",
|
||||
"Join",
|
||||
"Leave",
|
||||
"Like",
|
||||
"Listen",
|
||||
"Move",
|
||||
"Offer",
|
||||
"Question",
|
||||
"Reject",
|
||||
"Read",
|
||||
"Remove",
|
||||
"TentativeReject",
|
||||
"TentativeAccept",
|
||||
"Travel",
|
||||
"Undo",
|
||||
"Update",
|
||||
"View"
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/TR/activitystreams-vocabulary/#actor-types
|
||||
/// </summary>
|
||||
public static readonly string[] Actor = [
|
||||
"Application",
|
||||
"Group",
|
||||
"Organization",
|
||||
"Person",
|
||||
"Service"
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/TR/activitystreams-vocabulary/#object-types
|
||||
/// </summary>
|
||||
public static readonly string[] Object = [
|
||||
"Article",
|
||||
"Audio",
|
||||
"Document",
|
||||
"Event",
|
||||
"Image",
|
||||
"Note",
|
||||
"Page",
|
||||
"Place",
|
||||
"Profile",
|
||||
"Relationship",
|
||||
"Tombstone",
|
||||
"Video"
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// https://www.w3.org/TR/activitystreams-vocabulary/#object-types
|
||||
/// </summary>
|
||||
public static readonly string[] Link = [
|
||||
"Mention"
|
||||
];
|
||||
|
||||
public static bool IsActivity(string type) => Activity.Contains(type);
|
||||
//public static bool IsActivity(this Object obj) => obj.Type == null ? false : IsActivity(obj.Type);
|
||||
public static bool IsActor(string type) => Actor.Contains(type);
|
||||
//public static bool IsActor(this Object obj) => obj.Type == null ? false : IsActor(obj.Type);
|
||||
public static bool IsObject(string type) => Object.Contains(type);
|
||||
//public static bool IsObject(this Object obj) => obj.Type == null ? false : IsObject(obj.Type);
|
||||
public static bool IsLink(string type) => Link.Contains(type);
|
||||
//public static bool IsLink(this Object obj) => obj.Type == null ? false : IsLink(obj.Type);
|
||||
public static bool IsObjectOrLink(string type) => Object.Concat(Link).Contains(type);
|
||||
//public static bool IsObjectOrLink(this Object obj) => obj.Type == null ? false : IsObjectOrLink(obj.Type);
|
||||
|
||||
}
|
43
Utils/Base36.cs
Normal file
43
Utils/Base36.cs
Normal file
|
@ -0,0 +1,43 @@
|
|||
namespace ActivityPub.Utils;
|
||||
|
||||
// https://stackoverflow.com/a/35004409
|
||||
public class Base36
|
||||
{
|
||||
private static readonly char[] BaseChars =
|
||||
"0123456789abcdefghijklmnopqrstuvwxyz".ToCharArray();
|
||||
private static readonly Dictionary<char, int> CharValues = BaseChars
|
||||
.Select((c, i) => new { Char = c, Index = i })
|
||||
.ToDictionary(c => c.Char, c => c.Index);
|
||||
|
||||
public static string ToString(long value)
|
||||
{
|
||||
long targetBase = BaseChars.Length;
|
||||
// Determine exact number of characters to use.
|
||||
char[] buffer = new char[Math.Max(
|
||||
(int)Math.Ceiling(Math.Log(value + 1, targetBase)), 1)];
|
||||
|
||||
var i = buffer.Length;
|
||||
do
|
||||
{
|
||||
buffer[--i] = BaseChars[value % targetBase];
|
||||
value = value / targetBase;
|
||||
}
|
||||
while (value > 0);
|
||||
|
||||
return new string(buffer, i, buffer.Length - i);
|
||||
}
|
||||
|
||||
public static long FromString(string number)
|
||||
{
|
||||
char[] chrs = number.ToLower().ToCharArray();
|
||||
int m = chrs.Length - 1;
|
||||
int n = BaseChars.Length, x;
|
||||
long result = 0;
|
||||
for (int i = 0; i < chrs.Length; i++)
|
||||
{
|
||||
x = CharValues[chrs[i]];
|
||||
result += x * (long)Math.Pow(n, m--);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
57
Utils/UrlHelperExtensions.cs
Normal file
57
Utils/UrlHelperExtensions.cs
Normal file
|
@ -0,0 +1,57 @@
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace ActivityPub.Utils;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="IUrlHelper"/> extension methods.
|
||||
/// </summary>
|
||||
public static class UrlHelperExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Generates a fully qualified URL to an action method by using the specified action name, controller name and
|
||||
/// route values.
|
||||
/// </summary>
|
||||
/// <param name="url">The URL helper.</param>
|
||||
/// <param name="actionName">The name of the action method.</param>
|
||||
/// <param name="controllerName">The name of the controller.</param>
|
||||
/// <param name="routeValues">The route values.</param>
|
||||
/// <returns>The absolute URL.</returns>
|
||||
public static string AbsoluteAction(
|
||||
this IUrlHelper url,
|
||||
string actionName,
|
||||
string controllerName,
|
||||
object routeValues = null)
|
||||
{
|
||||
return url.Action(actionName, controllerName, routeValues, url.ActionContext.HttpContext.Request.Scheme);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a fully qualified URL to the specified content by using the specified content path. Converts a
|
||||
/// virtual (relative) path to an application absolute path.
|
||||
/// </summary>
|
||||
/// <param name="url">The URL helper.</param>
|
||||
/// <param name="contentPath">The content path.</param>
|
||||
/// <returns>The absolute URL.</returns>
|
||||
public static string AbsoluteContent(
|
||||
this IUrlHelper url,
|
||||
string contentPath)
|
||||
{
|
||||
HttpRequest request = url.ActionContext.HttpContext.Request;
|
||||
return new Uri(new Uri(request.Scheme + "://" + request.Host.Value), url.Content(contentPath)).ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a fully qualified URL to the specified route by using the route name and route values.
|
||||
/// </summary>
|
||||
/// <param name="url">The URL helper.</param>
|
||||
/// <param name="routeName">Name of the route.</param>
|
||||
/// <param name="routeValues">The route values.</param>
|
||||
/// <returns>The absolute URL.</returns>
|
||||
public static string AbsoluteRouteUrl(
|
||||
this IUrlHelper url,
|
||||
string routeName,
|
||||
object routeValues = null)
|
||||
{
|
||||
return url.RouteUrl(routeName, routeValues, url.ActionContext.HttpContext.Request.Scheme);
|
||||
}
|
||||
}
|
24
ap.net.csproj
Normal file
24
ap.net.csproj
Normal file
|
@ -0,0 +1,24 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Models\**" />
|
||||
<Content Remove="Models\**" />
|
||||
<EmbeddedResource Remove="Models\**" />
|
||||
<None Remove="Models\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="KristofferStrube.ActivityStreams" Version="0.2.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.3" />
|
||||
<PackageReference Include="OneOf" Version="3.0.263" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
25
ap.net.sln
Normal file
25
ap.net.sln
Normal file
|
@ -0,0 +1,25 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.5.002.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ap.net", "ap.net.csproj", "{D42B5CF1-49B0-4E10-9DCF-E91975A2DFF2}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{D42B5CF1-49B0-4E10-9DCF-E91975A2DFF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D42B5CF1-49B0-4E10-9DCF-E91975A2DFF2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D42B5CF1-49B0-4E10-9DCF-E91975A2DFF2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D42B5CF1-49B0-4E10-9DCF-E91975A2DFF2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {06949CC5-F7E0-40F0-8FAD-BDC4FE11B349}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
8
appsettings.Development.json
Normal file
8
appsettings.Development.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
9
appsettings.json
Normal file
9
appsettings.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
Loading…
Reference in a new issue