This commit is contained in:
Дмитрий Шиманский
2023-12-19 11:57:19 +03:00
parent 4e43b1631b
commit a5d39384ac
34 changed files with 1825 additions and 79 deletions

View File

@@ -2,16 +2,38 @@
using Microsoft.AspNetCore.Mvc.ModelBinding;
using System.Text.Json;
using System.Text.Json.Nodes;
using yaflay.ru.Models.Tables;
using yaflay.ru.Pages;
namespace yaflay.ru.Новая_папка
{
[Route("")]
public class HomeController : Controller
{
// GET: HomeController
{
public class commentBody
{
public string text { get; set; }
public string sender { get; set; }
}
public class articleBody
{
public string title { get; set; }
public string annotation { get; set; }
public string text { get; set; }
public string image { get; set; }
public string author { get; set; }
}
public class redirectBody
{
public string url { get; set; }
public string uri { get; set; }
public string author { get; set; }
}
/// <summary>
/// Getting redirect url from github file
/// </summary>
/// <param name="baseUrl"> uri-key of json in github file</param>
/// <returns type="string">url</returns>
private async Task<string?> getUrlFromGit(string baseUrl)
{
try
@@ -33,12 +55,117 @@ namespace yaflay.ru.Новая_папка
return null;
}
}
[HttpPost("api/redirects")]
public async Task<IActionResult> createRedirectUri([FromBody]redirectBody body)
{
Console.WriteLine("url" + body.uri);
HttpResponseMessage message;
using (var requestMessage =
new HttpRequestMessage(HttpMethod.Get, "https://discordapp.com/api/oauth2/@me"))
{
requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", Request.Cookies["melon"]); ;
message = await Startup.client.SendAsync(requestMessage);
}
string responseBody = await message.Content.ReadAsStringAsync();
JsonNode response = JsonNode.Parse(responseBody);
if (response["user"] != null || response["user"]?["id"].ToString() == "945317832290336798")
{
Redirects redirects = new()
{
redirectTo = body.url,
uri = body.uri
};
await Startup.dbContext.Redirects.AddAsync(redirects);
await Startup.dbContext.SaveChangesAsync();
return Ok();
}
else
{
return Unauthorized();
}
}
[HttpPost("api/Blog")]
public async Task<IActionResult> createArticle([FromBody] articleBody body)
{
HttpResponseMessage message;
using (var requestMessage =
new HttpRequestMessage(HttpMethod.Get, "https://discordapp.com/api/oauth2/@me"))
{
requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", Request.Cookies["melon"]); ;
message = await Startup.client.SendAsync(requestMessage);
}
string responseBody = await message.Content.ReadAsStringAsync();
JsonNode response = JsonNode.Parse(responseBody);
if (response["user"] != null || response["user"]?["id"].ToString() == "945317832290336798")
{
Blogs article = new()
{
Annotation = body.annotation,
author = new Author()
{
discordId = int.Parse(response["user"]["id"].ToString()),
discordNickName = response["user"]["display_name"].ToString()
},
dateTime = DateTime.Now,
ImageUrl = body.image,
Text = body.text,
Title = body.title
};
await Startup.dbContext.Blogs.AddAsync(article);
await Startup.dbContext.SaveChangesAsync();
return Ok();
}
else
{
return Unauthorized();
}
}
[HttpGet("logout")]
public async Task<IActionResult> authorizeDiscord()
{
Response.Cookies.Delete("melon");
Response.Cookies.Delete("watermelon");
Response.Cookies.Delete("cable");
return Redirect("/");
}
[HttpGet("api/Blog/{blogId?}/comments")]
public async Task<IActionResult> blogComments(int? blogId)
{
Comments[] comments = Startup.dbContext.Comments.Where(k => k.postId == blogId).ToArray();
return Ok(comments);
}
[HttpPost("api/Blog/{blogId}/comments")]
public async Task<IActionResult> CreateBlogComments(int blogId, [FromBody]commentBody body)
{
Comments comment = new()
{
creatorMail = body.sender,
dateTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
Text = body.text,
postId = blogId
};
await Startup.dbContext.Comments.AddAsync(comment);
await Startup.dbContext.SaveChangesAsync();
return Ok();
}
[HttpGet("api/Blog/{blogId}")]
public async Task<IActionResult> blog(int blogId)
{
Blogs? blog = Startup.dbContext.Blogs.FirstOrDefault(k => k.Id == blogId) ?? null;
return Ok(blog);
}
[HttpGet("{uri}")]
public async Task<IActionResult> FromGitHub(string uri)
{
string? url = await getUrlFromGit(uri);
string? url = Startup.dbContext.Redirects.FirstOrDefault(k => k.uri == uri)?.redirectTo;
if (url != null)
{
return Redirect(url);

View File

@@ -0,0 +1,88 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using yaflay.ru.Models;
#nullable disable
namespace yaflay.ru.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20231127204250_Migrate271122342")]
partial class Migrate271122342
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.12")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("yaflay.ru.Models.Tables.Blogs", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Annotation")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ImageUrl")
.HasColumnType("text");
b.Property<string>("Text")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("text");
b.Property<DateTime>("dateTime")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.ToTable("Blogs", "public");
});
modelBuilder.Entity("yaflay.ru.Models.Tables.Comments", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Text")
.IsRequired()
.HasColumnType("text");
b.Property<string>("creatorMail")
.IsRequired()
.HasColumnType("text");
b.Property<long>("dateTime")
.HasColumnType("bigint");
b.Property<int>("postId")
.HasColumnType("integer");
b.HasKey("Id");
b.ToTable("Comments", "public");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,66 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace yaflay.ru.Migrations
{
/// <inheritdoc />
public partial class Migrate271122342 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.EnsureSchema(
name: "public");
migrationBuilder.CreateTable(
name: "Blogs",
schema: "public",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Title = table.Column<string>(type: "text", nullable: false),
Text = table.Column<string>(type: "text", nullable: false),
Annotation = table.Column<string>(type: "text", nullable: false),
ImageUrl = table.Column<string>(type: "text", nullable: true),
dateTime = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Blogs", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Comments",
schema: "public",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
dateTime = table.Column<long>(type: "bigint", nullable: false),
Text = table.Column<string>(type: "text", nullable: false),
creatorMail = table.Column<string>(type: "text", nullable: false),
postId = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Comments", x => x.Id);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Blogs",
schema: "public");
migrationBuilder.DropTable(
name: "Comments",
schema: "public");
}
}
}

View File

@@ -0,0 +1,88 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using yaflay.ru.Models;
#nullable disable
namespace yaflay.ru.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20231204171742_Migrate04122016")]
partial class Migrate04122016
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.12")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("yaflay.ru.Models.Tables.Blogs", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Annotation")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ImageUrl")
.HasColumnType("text");
b.Property<string>("Text")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("text");
b.Property<DateTime>("dateTime")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.ToTable("Blogs", "public");
});
modelBuilder.Entity("yaflay.ru.Models.Tables.Comments", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Text")
.IsRequired()
.HasColumnType("text");
b.Property<string>("creatorMail")
.IsRequired()
.HasColumnType("text");
b.Property<long>("dateTime")
.HasColumnType("bigint");
b.Property<int>("postId")
.HasColumnType("integer");
b.HasKey("Id");
b.ToTable("Comments", "public");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,22 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace yaflay.ru.Migrations
{
/// <inheritdoc />
public partial class Migrate04122016 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}

View File

@@ -0,0 +1,109 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using yaflay.ru.Models;
#nullable disable
namespace yaflay.ru.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20231204210831_Migrate0512")]
partial class Migrate0512
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.12")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("yaflay.ru.Models.Tables.Blogs", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Annotation")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ImageUrl")
.HasColumnType("text");
b.Property<string>("Text")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("text");
b.Property<DateTime>("dateTime")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.ToTable("Blogs", "public");
});
modelBuilder.Entity("yaflay.ru.Models.Tables.Comments", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Text")
.IsRequired()
.HasColumnType("text");
b.Property<string>("creatorMail")
.IsRequired()
.HasColumnType("text");
b.Property<long>("dateTime")
.HasColumnType("bigint");
b.Property<int>("postId")
.HasColumnType("integer");
b.HasKey("Id");
b.ToTable("Comments", "public");
});
modelBuilder.Entity("yaflay.ru.Models.Tables.Redirects", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("redirectTo")
.IsRequired()
.HasColumnType("text");
b.Property<string>("uri")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Redirects");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,36 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace yaflay.ru.Migrations
{
/// <inheritdoc />
public partial class Migrate0512 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Redirects",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
uri = table.Column<string>(type: "text", nullable: false),
redirectTo = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Redirects", x => x.Id);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Redirects");
}
}
}

View File

@@ -0,0 +1,145 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using yaflay.ru.Models;
#nullable disable
namespace yaflay.ru.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20231218172614_Migrate18122023")]
partial class Migrate18122023
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.12")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("yaflay.ru.Models.Tables.Author", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("discordId")
.HasColumnType("integer");
b.Property<string>("discordNickName")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Author");
});
modelBuilder.Entity("yaflay.ru.Models.Tables.Blogs", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Annotation")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ImageUrl")
.HasColumnType("text");
b.Property<string>("Text")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("text");
b.Property<int>("authorId")
.HasColumnType("integer");
b.Property<DateTime>("dateTime")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("authorId");
b.ToTable("Blogs", "public");
});
modelBuilder.Entity("yaflay.ru.Models.Tables.Comments", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Text")
.IsRequired()
.HasColumnType("text");
b.Property<string>("creatorMail")
.IsRequired()
.HasColumnType("text");
b.Property<long>("dateTime")
.HasColumnType("bigint");
b.Property<int>("postId")
.HasColumnType("integer");
b.HasKey("Id");
b.ToTable("Comments", "public");
});
modelBuilder.Entity("yaflay.ru.Models.Tables.Redirects", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("redirectTo")
.IsRequired()
.HasColumnType("text");
b.Property<string>("uri")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Redirects");
});
modelBuilder.Entity("yaflay.ru.Models.Tables.Blogs", b =>
{
b.HasOne("yaflay.ru.Models.Tables.Author", "author")
.WithMany()
.HasForeignKey("authorId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("author");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,74 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace yaflay.ru.Migrations
{
/// <inheritdoc />
public partial class Migrate18122023 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "authorId",
schema: "public",
table: "Blogs",
type: "integer",
nullable: false,
defaultValue: 0);
migrationBuilder.CreateTable(
name: "Author",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
discordId = table.Column<int>(type: "integer", nullable: false),
discordNickName = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Author", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_Blogs_authorId",
schema: "public",
table: "Blogs",
column: "authorId");
migrationBuilder.AddForeignKey(
name: "FK_Blogs_Author_authorId",
schema: "public",
table: "Blogs",
column: "authorId",
principalTable: "Author",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Blogs_Author_authorId",
schema: "public",
table: "Blogs");
migrationBuilder.DropTable(
name: "Author");
migrationBuilder.DropIndex(
name: "IX_Blogs_authorId",
schema: "public",
table: "Blogs");
migrationBuilder.DropColumn(
name: "authorId",
schema: "public",
table: "Blogs");
}
}
}

View File

@@ -0,0 +1,145 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using yaflay.ru.Models;
#nullable disable
namespace yaflay.ru.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20231218173546_Migrate18122035")]
partial class Migrate18122035
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.12")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("yaflay.ru.Models.Tables.Author", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("discordId")
.HasColumnType("integer");
b.Property<string>("discordNickName")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Author");
});
modelBuilder.Entity("yaflay.ru.Models.Tables.Blogs", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Annotation")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ImageUrl")
.HasColumnType("text");
b.Property<string>("Text")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("text");
b.Property<int>("authorId")
.HasColumnType("integer");
b.Property<DateTime>("dateTime")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("authorId");
b.ToTable("Blogs", "public");
});
modelBuilder.Entity("yaflay.ru.Models.Tables.Comments", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Text")
.IsRequired()
.HasColumnType("text");
b.Property<string>("creatorMail")
.IsRequired()
.HasColumnType("text");
b.Property<long>("dateTime")
.HasColumnType("bigint");
b.Property<int>("postId")
.HasColumnType("integer");
b.HasKey("Id");
b.ToTable("Comments", "public");
});
modelBuilder.Entity("yaflay.ru.Models.Tables.Redirects", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("redirectTo")
.IsRequired()
.HasColumnType("text");
b.Property<string>("uri")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Redirects");
});
modelBuilder.Entity("yaflay.ru.Models.Tables.Blogs", b =>
{
b.HasOne("yaflay.ru.Models.Tables.Author", "author")
.WithMany()
.HasForeignKey("authorId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("author");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,22 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace yaflay.ru.Migrations
{
/// <inheritdoc />
public partial class Migrate18122035 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}

View File

@@ -0,0 +1,142 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using yaflay.ru.Models;
#nullable disable
namespace yaflay.ru.Migrations
{
[DbContext(typeof(AppDbContext))]
partial class AppDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.12")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("yaflay.ru.Models.Tables.Author", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("discordId")
.HasColumnType("integer");
b.Property<string>("discordNickName")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Author");
});
modelBuilder.Entity("yaflay.ru.Models.Tables.Blogs", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Annotation")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ImageUrl")
.HasColumnType("text");
b.Property<string>("Text")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("text");
b.Property<int>("authorId")
.HasColumnType("integer");
b.Property<DateTime>("dateTime")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("authorId");
b.ToTable("Blogs", "public");
});
modelBuilder.Entity("yaflay.ru.Models.Tables.Comments", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Text")
.IsRequired()
.HasColumnType("text");
b.Property<string>("creatorMail")
.IsRequired()
.HasColumnType("text");
b.Property<long>("dateTime")
.HasColumnType("bigint");
b.Property<int>("postId")
.HasColumnType("integer");
b.HasKey("Id");
b.ToTable("Comments", "public");
});
modelBuilder.Entity("yaflay.ru.Models.Tables.Redirects", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("redirectTo")
.IsRequired()
.HasColumnType("text");
b.Property<string>("uri")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Redirects");
});
modelBuilder.Entity("yaflay.ru.Models.Tables.Blogs", b =>
{
b.HasOne("yaflay.ru.Models.Tables.Author", "author")
.WithMany()
.HasForeignKey("authorId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("author");
});
#pragma warning restore 612, 618
}
}
}

19
Models/AppDbContext.cs Normal file
View File

@@ -0,0 +1,19 @@
using Microsoft.EntityFrameworkCore;
using yaflay.ru.Models.Tables;
namespace yaflay.ru.Models
{
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) {}
public DbSet<Blogs> Blogs { get; set; }
public DbSet<Comments> Comments { get; set; }
public DbSet<Redirects> Redirects { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
}

26
Models/Tables/Blogs.cs Normal file
View File

@@ -0,0 +1,26 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations.Schema;
namespace yaflay.ru.Models.Tables
{
[Table("Blogs", Schema = "public")]
public class Blogs
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Title { get; set; }
public string Text { get; set; }
public string Annotation { get; set; }
public string? ImageUrl { get; set; }
public DateTime dateTime { get; set; }
public Author author { get; set; }
}
public class Author
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int discordId { get; set; }
public string discordNickName { get; set; }
}
}

17
Models/Tables/Comments.cs Normal file
View File

@@ -0,0 +1,17 @@
using System.ComponentModel.DataAnnotations.Schema;
using System.Net.Mail;
namespace yaflay.ru.Models.Tables
{
[Table("Comments", Schema = "public")]
public class Comments
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public long dateTime { get; set; }
public string Text { get; set; }
public string creatorMail { get; set; }
public int postId { get; set; }
}
}

View File

@@ -0,0 +1,12 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace yaflay.ru.Models.Tables
{
public class Redirects
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string? uri { get; set; }
public string? redirectTo { get; set; }
}
}

75
Pages/AdminPanel.cshtml Normal file
View File

@@ -0,0 +1,75 @@
@page "{type?}"
@model yaflay.ru.Pages.AdminPanelModel
@using System.Text.Json.Nodes
@{
ViewData["Title"] = "AdminPanel";
bool isAllowed = true;
}
@if (Request.Cookies["melon"] != null)
{
if (Request.Cookies["cable"] != "945317832290336798")
{
<h1 align="center">Вы не авторизованы! Сасни хуйца, олух</h1>
isAllowed = false;
}
} else
{
<h1 align="center">Вы не авторизованы! Сасни хуйца, олух</h1>
isAllowed = false;
}
@if (Model.type == "article" & isAllowed){
<div class="card margin-2-vm">
<div class="card-body bg-dark">
<h5 class="card-title">Код статьи (HTML)</h5>
<div class="card-text form-group bg-dark text-muted">
<label for="titleInput">Тайтл статьи</label>
<input type="text" class="form-control bg-dark text-muted" id="titleInput" />
<label for="annotationArea">Код аннотации</label>
<textarea class="form-control bg-dark text-muted" id="annotationArea" rows="2" onkeyup="updateAnnotation(this.value)"></textarea>
<label for="textArea">Код статьи</label>
<textarea class="form-control bg-dark text-muted" id="textArea" rows="5" onkeyup="updatePreview(this.value)"></textarea>
<label for="imgInput">Ссылка на изображение</label>
<input type="url" class="form-control bg-dark text-muted" id="imgInput" ></input>
</div>
</div>
</div>
<div class="card margin-2-vm" >
<div class="card-body bg-dark">
<h5 class="card-title text-muted">Превью аннотации</h5>
<div class="card-text text-muted overflow-auto" id="annotationCard">
<code id="code"><p id="annotationText"></p></code>
</div>
<h5 class="card-title text-muted">Превью текста</h5>
<div class="card-text text-muted overflow-auto" id="previewCard">
<code id="code"><p id="blogText"></p></code>
</div>
</div>
</div>
<button type="button" id="sendBlogText" align="center" class="btn-primary margin-2-vm " onclick="sendArticleData()">Send!</button>
}
else if (Model.type == "redirects" & isAllowed)
{
<div class="card margin-2-vm">
<div class="card-body bg-dark">
<h5 class="card-title">Редиректы</h5>
<div class="card-text form-group bg-dark text-muted">
<label for="urlInput">Ссылка</label>
<input type="url" class="form-control bg-dark text-muted" id="urlInput" />
<label for="uriInput">Uri</label>
<input type="text" class="form-control bg-dark text-muted" id="uriInput" />
</div>
</div>
</div>
<button type="button" id="sendRedirect" align="center" class="btn-primary margin-2-vm " onclick="sendRedirectData()">Send!</button>
}
else if (isAllowed)
{
<h2 align="center" class="text-white absolute"><a href="/AdminPanel/redirects">Редиректы</a><a href="/AdminPanel/article">Статьи</a></h2>
}

View File

@@ -0,0 +1,14 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace yaflay.ru.Pages
{
public class AdminPanelModel : PageModel
{
public string? type = null;
public void OnGet(string? type)
{
this.type = type;
}
}
}

64
Pages/Authorize.cshtml Normal file
View File

@@ -0,0 +1,64 @@
@page "{code}"
@model yaflay.ru.Pages.AuthorizeModel
@using System.Text.Json.Nodes
@{
ViewData["Title"] = "Authorize";
<h4>code - @Model.code</h4>
if (Model.code == null)
{
if (Request.Cookies["melon"]?.ToString() == null)
{
<a href="https://discord.com/api/oauth2/authorize?client_id=1115013432710799440&response_type=code&redirect_uri=https%3A%2F%2Fyawaflua.ru%2Fauthorize&scope=identify">Login while Discord</a>
}
else
{
HttpResponseMessage message;
using (var requestMessage =
new HttpRequestMessage(HttpMethod.Get, "https://discordapp.com/api/oauth2/@me"))
{
requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", Request.Cookies["melon"]); ;
message = await Startup.client.SendAsync(requestMessage);
}
string responseBody = await message.Content.ReadAsStringAsync();
JsonNode response = JsonNode.Parse(responseBody);
if (response["user"] != null)
{
<h4>Вы авторизованы!</h4>
<a href="/AdminPanel"> Админка </a>
}
else
{
<h4>
Токен авторизации неправильный! Попробуйте <a href="https://discord.com/api/oauth2/authorize?client_id=1115013432710799440&response_type=code&redirect_uri=https%3A%2F%2Fyawaflua.ru%2Fauthorize&scope=identify">заново</a>
</h4>
}
}
}
else
{
HttpResponseMessage message;
using (var requestMessage =
new HttpRequestMessage(HttpMethod.Post, "https://discordapp.com/api/oauth2/token"))
{
requestMessage.Content = new StringContent(
@$"grant_type=authorization_code&code={Model.code}&client_id={Startup.clientId}&client_secret={Startup.clientSecret}&scope=identify&redirect_uri=https://yawaflua.ru/authorize",
new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-www-form-urlencoded")
);
message = await Startup.client.SendAsync(requestMessage);
}
string responseBody = await message.Content.ReadAsStringAsync();
JsonNode body = JsonNode.Parse(responseBody);
if (body["access_token"]?.ToString() == null)
{
<h4>Ошибка! Попробуй авторизоваться заново</h4>
}
else
{
Response.Cookies.Append("melon", body["access_token"].ToString());
Response.Cookies.Append("watermelon", body["refresh_token"].ToString());
Response.Redirect("/authorize");
}
}
}

18
Pages/Authorize.cshtml.cs Normal file
View File

@@ -0,0 +1,18 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace yaflay.ru.Pages
{
public class AuthorizeModel : PageModel
{
public string code;
public void OnGet(string code)
{
this.code = code;
Page();
}
}
}

99
Pages/Blog.cshtml Normal file
View File

@@ -0,0 +1,99 @@
@page "{id?}"
@model BlogModel
@using yaflay.ru.Models.Tables
@{
if (Model.Id == 0)
ViewData["Title"] = "Blog";
}
@{
string path = $"{this.Request.Scheme}://{this.Request.Host}";
}
@{
if (Model.Id != 0)
{
Blogs? Post = Startup.dbContext.Blogs.FirstOrDefault(k => k.Id == Model.Id);
if (Post == null)
{
ViewData["Title"] = "Blogs";
<h1 align="center">Что-то не так...</h1>
<h1 align="center">Пост не найден, но ты держи яблочко -> 🍎</h1>
} else
{
ViewData["Title"] = Post.Title;
ViewData["og:title"] = Post.Title;
ViewData["og:url"] = this.Request.Host.Host + this.Request.Path.ToString();
ViewData["og:description"] = Post.Annotation;
ViewData["og:image"] = Post.ImageUrl;
<p align="left">
<h1 align="left">@Html.Raw(Post.Title)</h1>
<h5>@Post.dateTime</h5>
</p>
<div id="blogId" style="display:none;">@Model.Id</div>
<p align="center"><img src="@Post.ImageUrl" style="width:50vmax;"/></p>
<p align="center">@Html.Raw(Post.Text)</p>
<h6 align="left">Статья подготовлена <a href="https://yawaflua.ru/gh">Дмитрием</a></h6>
<div class="container my-5 py-5 bg-dark text-muted">
<div class="row d-flex justify-content-center">
<div class="col-md-12 col-lg-10">
<div class="card text-muted bg-dark">
<div class="card-body position-static p-4" id="allComments">
<h4 class="mb-0" id="commentBar">Последние комментарии</h4>
<h1 align="center">Дальше тьма...</h1>
</div>
</div>
</div>
</div>
</div>
}
<div class="card-footer text-white bg-dark mb-3 py-3 border-0" >
<div class="d-flex flex-start w-100">
<div class="form-outline w-100">
<label for="userEmail" class="form-label">Адрес электронной почты</label>
<input type="email" class="form-control bg-dark text-white" id="userEmail" placeholder="name@example.com" name="userEmail">
<label for="commentText" class="form-label">Комментарий</label>
<input type="text" class="form-control bg-dark text-white" id="commentText" rows="4" name="commentText">
</div>
</div>
<div class="float-end mt-2 pt-1">
<button type="button" class="btn btn-primary btn-sm" id="postComment" >Запостить коммент</button>
</div>
</div>
}
else
{
var allBlogs = Startup.dbContext.Blogs.ToArray();
if (allBlogs.Length == 0)
{
<p>
<h1 align="center">Ничего нет...</h1>
<h1 align="center">Вот вам банан -> 🍌</h1>
</p>
}
else
{
foreach (var blog in allBlogs)
{
<div class="card text-white bg-dark mb-3 text-center" style="width: 18rem;">
<img src="@blog.ImageUrl" class="card-img-top" alt="...">
<div class="card-body ">
<h5 class="card-title">@Html.Raw(blog.Title)</h5>
<p class="card-text">@Html.Raw(blog.Annotation)</p>
<a href="/Blog/@blog.Id" class="btn btn-primary center">Читать</a>
</div>
</div>
}
}
}
}

37
Pages/Blog.cshtml.cs Normal file
View File

@@ -0,0 +1,37 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.AspNetCore.Mvc.RazorPages;
using yaflay.ru.Models.Tables;
namespace yaflay.ru.Pages
{
public class BlogModel : PageModel
{
public int Id { get; private set; }
//public Comments[] comments { get; set; }
public void OnGet(int? id)
{
Id = id ?? 0;
Page();
//comments = Startup.dbContext.Comments.Where(k => k.postId == Id).OrderBy(k => k.dateTime).Reverse().ToArray();
}
public void OnPost(int? id)
{
Id = id ?? 0;
//comments = Startup.dbContext.Comments.Where(k => k.postId == Id).OrderBy(k => k.dateTime).Reverse().ToArray();
string userEmail = Request.Form["userEmail"];
string commentMessage = Request.Form["commentText"];
if (Id == 0 || commentMessage == null || userEmail == null) { Page(); return; }
Startup.dbContext.Comments.Add(new Comments()
{
Text = commentMessage,
creatorMail = userEmail,
dateTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
postId = Id
});
Startup.dbContext.SaveChanges();
Page();
}
}
}

View File

@@ -1,4 +1,4 @@
@page
@page
@model IndexModel
@{
ViewData["Title"] = "yawaflua";
@@ -12,3 +12,4 @@
}

View File

@@ -16,6 +16,7 @@ namespace yaflay.ru.Pages
public void OnGet()
{
Page();
}
}

View File

@@ -10,7 +10,7 @@
<title>Page not found</title>
<link rel="shortcut icon" type="image/png" href="#">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://yaflay.ru/css/404.css" />
<link rel="stylesheet" href="~/css/404.css" />
</head>
<body>
@@ -21,7 +21,7 @@
<div class="container">
<div class="row justify-content-center">
<div class="col-lg-7 text-center">
<img src="https://yaflay.ru/img/error-404.png" alt="image 404">
<img src="~/img/error-404.png" alt="image 404">
<h2><b>404</b> Страница не найдена</h2>
<p>посетите главную страницу <br> возможно вы найдёте её</p>
<a href="@path" class="cmn-btn mt-4">На главную</a>

View File

@@ -5,48 +5,133 @@
}
<h1>@ViewData["Title"]</h1>
<h2>End-User License Agreement (EULA) of <span class="app_name">yaflay.ru</span></h2>
Statement of Purpose
<p>This End-User License Agreement ("EULA") is a legal agreement between you and <span class="company_name">YaFlay</span>. Our EULA was created by <a href="https://www.eulatemplate.com">EULA Template</a> for <span class="app_name">yaflay.ru</span>.</p>
<p>The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").</p>
<p>This EULA agreement governs your acquisition and use of our <span class="app_name">yaflay.ru</span> software ("Software") directly from <span class="company_name">YaFlay</span> or indirectly through a <span class="company_name">YaFlay</span> authorized reseller or distributor (a "Reseller"). </p>
<p>Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.</p>
<p>Please read this EULA agreement carefully before completing the installation process and using the <span class="app_name">yaflay.ru</span> software. It provides a license to use the <span class="app_name">yaflay.ru</span> software and contains warranty information and liability disclaimers.</p>
<p>For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.</p>
<p>If you register for a free trial of the <span class="app_name">yaflay.ru</span> software, this EULA agreement will also govern that trial. By clicking "accept" or installing and/or using the <span class="app_name">yaflay.ru</span> software, you are confirming your acceptance of the Software and agreeing to become bound by the terms of this EULA agreement.</p>
<p>If you are entering into this EULA agreement on behalf of a company or other legal entity, you represent that you have the authority to bind such entity and its affiliates to these terms and conditions. If you do not have such authority or if you do not agree with the terms and conditions of this EULA agreement, do not install or use the Software, and you must not accept this EULA agreement.</p>
<p>This EULA agreement shall apply only to the Software supplied by <span class="company_name">YaFlay</span> herewith regardless of whether other software is referred to or described herein. The terms also apply to any <span class="company_name">YaFlay</span> updates, supplements, Internet-based services, and support services for the Software, unless other terms accompany those items on delivery. If so, those terms apply.</p>
<h3>License Grant</h3>
<p><span class="company_name">YaFlay</span> hereby grants you a personal, non-transferable, non-exclusive licence to use the <span class="app_name">yaflay.ru</span> software on your devices in accordance with the terms of this EULA agreement.</p>
<p>You are permitted to load the <span class="app_name">yaflay.ru</span> software (for example a PC, laptop, mobile or tablet) under your control. You are responsible for ensuring your device meets the minimum requirements of the <span class="app_name">yaflay.ru</span> software.</p>
<p>You are not permitted to:</p>
<p> Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:</p>
<ul>i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work.</ul>
<ul>
<li>Edit, alter, modify, adapt, translate or otherwise change the whole or any part of the Software nor permit the whole or any part of the Software to be combined with or become incorporated in any other software, nor decompile, disassemble or reverse engineer the Software or attempt to do any such things</li>
<li>Reproduce, copy, distribute, resell or otherwise use the Software for any commercial purpose</li>
<li>Allow any third party to use the Software on behalf of or for the benefit of any third party</li>
<li>Use the Software in any way which breaches any applicable local, national or international law</li>
<li>use the Software for any purpose that <span class="company_name">YaFlay</span> considers is a breach of this EULA agreement</li>
ii. moral rights retained by the original author(s) and/or performer(s);
</ul>
<ul>
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
</ul>
<ul>
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
</ul>
<ul>
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
</ul>
<ul>
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation
thereof, including any amended or successor version of such
directive); and
</ul>
<ul>
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
</ul>
<h3>Intellectual Property and Ownership</h3>
<p><span class="company_name">YaFlay</span> shall at all times retain ownership of the Software as originally downloaded by you and all subsequent downloads of the Software by you. The Software (and the copyright, and other intellectual property rights of whatever nature in the Software, including any modifications made thereto) are and shall remain the property of <span class="company_name">YaFlay</span>.</p>
<p><span class="company_name">YaFlay</span> reserves the right to grant licences to use the Software to third parties.</p>
<h3>Termination</h3>
<p>This EULA agreement is effective from the date you first use the Software and shall continue until terminated. You may terminate it at any time upon written notice to <span class="company_name">YaFlay</span>.</p>
<p>It will also terminate immediately if you fail to comply with any term of this EULA agreement. Upon such termination, the licenses granted by this EULA agreement will immediately terminate and you agree to stop all access and use of the Software. The provisions that by their nature continue and survive will survive any termination of this EULA agreement.</p>
<h3>Governing Law</h3>
<p>This EULA agreement, and any dispute arising out of or in connection with this EULA agreement, shall be governed by and construed in accordance with the laws of <span class="country">ru</span>.</p>
<p>2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
</p>
<p>
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.
</p>
<p>
4. Limitations and Disclaimers.
</p>
<ul>
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
</ul>
<ul>
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
the greatest extent permissible under applicable law.
</ul>
<ul>
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
Work.
</ul>
<ul>
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.
</ul>

View File

@@ -3,7 +3,10 @@
Layout = null;
this.Response.ContentType = "text/plain";
}
# /Robots.txt file for httpы://yaflay.com/
# /Robots.txt file for httpы://yawaflua.ru/
User-agent: *
<environment include="Development,Staging">Disallow: /</environment>
<environment include="Production">Disallow: /* </environment>
<environment include="Development,Staging">Disallow: /*</environment>
<environment include="Production">Disallow: /* </environment>
<environment include="Production">Allow: /Blog </environment>
<environment include="Production">Allow: /Privacy </environment>
<environment include="Production">Allow: / </environment>

View File

@@ -1,6 +1,7 @@
<!DOCTYPE html>
<html lang="en">
<head>
@using System.Text.Json.Nodes
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="~/favicon.ico" />
@@ -9,14 +10,34 @@
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link type="application/json+oembed" href="~/json/oembed.json" />
<!--<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">-->
<meta property="og:title" content="yawaflua readme" />
<meta property="og:type" content="rich" />
<meta property="og:url" content="@Context.Request.Host.Host" />
<meta property="og:image" content="https://user-images.githubusercontent.com/5713670/87202985-820dcb80-c2b6-11ea-9f56-7ec461c497c3.gif" />
<meta property="og:description"
content="Here you can check info about yawaflua: social networks, programming languages that he knows and his projects." />
<meta property="og:locale" content="en_US" />
<meta property="og:site_name" content="yawaflua.ru" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
<!-- and it's easy to individually load additional languages -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/go.min.js"></script>
@if (Context.Request.Path == "")
{
<meta property="og:title" content="yawaflua readme" />
<meta property="og:type" content="rich" />
<meta property="og:url" content="@Context.Request.Host.Host" />
<meta property="og:image" content="https://user-images.githubusercontent.com/5713670/87202985-820dcb80-c2b6-11ea-9f56-7ec461c497c3.gif" />
<meta property="og:description"
content="Here you can check info about yawaflua: social networks, programming languages that he knows and his projects." />
<meta property="og:locale" content="en_US" />
<meta property="og:site_name" content="yawaflua.ru" />
}
else
{
<meta property="og:title" content="@ViewData["og:title"]" />
<meta property="og:type" content="rich" />
<meta property="og:url" content="@ViewData["og:url"]" />
<meta property="og:image" content="@ViewData["og:title"]" />
<meta property="og:description"
content="@ViewData["og:title"]" />
<meta property="og:locale" content="ru_RU" />
<meta property="og:site_name" content="yawaflua.ru" />
}
</head>
<body>
<header>
@@ -29,6 +50,7 @@
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<a class="nav-link " style="color: cornflowerblue;" asp-area="" asp-page="/Index">
@Context.Request.Host.Host
</a>
@@ -39,8 +61,35 @@
<a class="nav-link text-white" asp-area="" asp-page="/Privacy">Privacy</a>
</li>
<li class="nav-item">
<a class="nav-link text-white" href="https://storespw.ru/">StoreSPw</a>
<a class="nav-link text-white" asp-area="" asp-page="/Blog">Blog</a>
</li>
@{
Context.Response.Cookies.Delete("cable");
if (Context.Request.Cookies["melon"] != null)
{
HttpResponseMessage message;
using (var requestMessage =
new HttpRequestMessage(HttpMethod.Get, "https://discordapp.com/api/oauth2/@me"))
{
requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", Context.Request.Cookies["melon"]); ;
message = await Startup.client.SendAsync(requestMessage);
}
string responseBody = await message.Content.ReadAsStringAsync();
JsonNode response = JsonNode.Parse(responseBody);
if (response["user"] != null)
{
Context.Response.Cookies.Append("cable", response["user"]["id"].ToString());
string userName = response["user"]["global_name"].ToString();
<li class="nav-item">
<a href="/logout"
class="nav-link blurple hover:decoration-wavy underline dashed decoration-purple"
style="color: #5865F2; font-size: calc(var(--bs-body-font-size) + .15rem);">
@userName
</a>
</li>
}
}
}
</ul>
</div>
</div>
@@ -82,7 +131,10 @@
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@if (Context.Request.Path.ToString().StartsWith("/AdminPanel"))
{
<script src="~/js/AdminPanel.js"></script>
}
@await RenderSectionAsync("Scripts", required: false)
</body>

View File

@@ -11,7 +11,7 @@ public class Program
.ConfigureWebHostDefaults(webHost => {
webHost.UseStartup<Startup>();
webHost.UseStaticWebAssets();
webHost.UseKestrel(kestrelOptions => { kestrelOptions.ListenAnyIP(80); });
webHost.UseKestrel(kestrelOptions => { kestrelOptions.ListenAnyIP(80);});
});
}

View File

@@ -1,17 +1,40 @@

using System;
using System.Net;
using System.Reflection.Metadata.Ecma335;
using System.Runtime.CompilerServices;
using DotNetEd.CoreAdmin;
using Microsoft.EntityFrameworkCore;
using yaflay.ru.Models;
using Discord.OAuth2;
namespace yaflay.ru
{
public class Startup
{
private readonly IConfiguration configuration;
public static HttpClient client = new HttpClient();
public static CookieContainer cookieContainer = new();
public static HttpClientHandler handler = new() { CookieContainer = cookieContainer};
public static HttpClient client = new(handler);
public static AppDbContext? dbContext;
public static string applicationId;
public static string appToken;
public static string clientId;
public static string clientSecret;
public static string redirectUrl;
public Startup()
{
configuration = new ConfigurationBuilder()
.AddEnvironmentVariables(prefix: "m.")
.AddJsonFile("appsettings.json", optional: true)
.AddJsonFile("appsettings.json", optional: false)
.Build();
Console.WriteLine(configuration.GetValue<string>("applicationId"));
applicationId = configuration.GetValue<string>("applicationId");
appToken = configuration.GetValue<string>("appToken");
clientId = configuration.GetValue<string>("clientId");
clientSecret = configuration.GetValue<string>("clientSecret");
redirectUrl = configuration.GetValue<string>("redirectUrl");
}
public void ConfigureServices(IServiceCollection services)
{
@@ -21,19 +44,27 @@ namespace yaflay.ru
options.Conventions.AddPageRoute("/RobotsTxt", "/Robots.txt");
options.Conventions.AddPageRoute("/NotFound", "/404");
options.Conventions.AddPageRoute("/IternalErrorPage", "/500");
options.Conventions.AddPageRoute("/Authorize", "/authorize");
});
services.AddRouting();
services
.AddAuthentication();
services
.AddRouting()
.AddSingleton(configuration)
.AddDbContext<AppDbContext>(c => c.UseNpgsql(connectionString: configuration.GetValue<string>("connectionOnServer")))
.AddCoreAdmin("Admin");
services.AddRazorPages();
services.AddMvc()
.AddRazorPagesOptions(options =>
{
options.Conventions.AddPageRoute("/RobotsTxt", "/Robots.txt");
options.Conventions.AddPageRoute("/NotFound", "/404");
options.Conventions.AddPageRoute("/IternalErrorPage", "/500");
});
//services.AddDirectoryBrowser();
services.AddCors(k => { k.AddDefaultPolicy(l => { l.AllowAnyHeader(); l.AllowAnyMethod(); l.AllowAnyOrigin(); }); })
.AddMvc()
.AddRazorPagesOptions(options =>
{
options.Conventions.AddPageRoute("/RobotsTxt", "/Robots.txt");
options.Conventions.AddPageRoute("/NotFound", "/404");
options.Conventions.AddPageRoute("/IternalErrorPage", "/500");
options.Conventions.AddPageRoute("/Authorize", "/authorize");
});
dbContext = services.BuildServiceProvider().GetRequiredService<AppDbContext>();
}
@@ -44,20 +75,25 @@ namespace yaflay.ru
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
//app.UseHsts();
app.UseHsts();
}
// Configure the HTTP request pipeline.
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseCoreAdminCustomTitle("yawaflua");
app.UseCoreAdminCustomAuth((k) => Task.FromResult(true));
app.UseCoreAdminCustomUrl("admin/coreadmin");
app.UseCors(k => { k.AllowAnyMethod(); k.AllowAnyOrigin(); k.AllowAnyHeader(); });
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
endpoints.MapRazorPages();
endpoints.MapControllers();
});
}

View File

@@ -6,6 +6,9 @@ html {
color: white;
}
.app_name {
font-size: calc(12px + 1vmax);
}
.readme{
font-family: 'Anonymous Pro';
}
@@ -83,7 +86,22 @@ img {
margin-bottom: 1vh;
}
.bot-1 {
padding-bottom: 1vmax;
}
body {
margin-bottom: 60px;
}
.margin-left-2-vm{
margin-left: 2vmax;
}
.margin-right-2-vm {
margin-right: 2vmax;
}
.width-4 {
width: 4vmax;
}
.blurple {
color: #5865F2;
}

53
wwwroot/js/AdminPanel.js Normal file
View File

@@ -0,0 +1,53 @@
function updatePreview(value) {
var blogText = $("#previewCard").children("#code").children("#blogText");
blogText.empty();
blogText.append(value);
}
function updateAnnotation(value) {
var blogText = $("#annotationCard").children("#code").children("#annotationText");
blogText.empty();
blogText.append(value);
}
function sendArticleData () {
let melon = document.cookie.split(';')[0].replace("melon=", "");
fetch("/api/Blog", {
method: "POST",
headers: {
Authorization: `Bearer ${melon}`
},
body: {
title: $("#titleInput").val(),
annotation: $("#annotationArea").val(),
text: $("#textArea").val(),
image: $("#imgInput").val(),
author: melon
}
}).then(k => console.log(k));
$("#titleInput").val('');
$("#annotationArea").val('');
$("#textArea").val('');
$("#imgInput").val('');
}
function sendRedirectData() {
console.log("click!")
let melon = document.cookie.split(';')[0].replace("melon=", "");
let body = `{
"url": "${$("#urlInput").val()}",
"uri": "${$("#uriInput").val()}",
"author": "${melon}"
}`;
fetch("/api/redirects", {
method: "POST",
headers: {
Authorization: `Bearer ${melon}`,
"Content-Type": "application/json"
},
body: body
}).then(k => console.log(k));
$("#urlInput").val('');
$("#uriInput").val('');
}

View File

@@ -1,4 +1,42 @@
// Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification
// for details on configuring this project to bundle and minify static web assets.
let blogId = $("#blogId").text();
function loadComments () {
fetch(`/api/Blog/${blogId}/comments`)
.then(response => {
let data = response.json();
data.then(k => {
for (let i = 0; i < k.length; i++) {
let date = new Date(k[i].dateTime * 1000);
$("#commentBar").after(
`<div class="d-flex flex flex-start bg-dark bot-1">
<div class="container">
<h6 class="fw-bold mb-1">${k[i].creatorMail}</h6>
<div class="d-flex align-items-center mb-3">
<p class="mb-0">
${date.toLocaleString() }
</p>
</div>
<p class="mb-0">
${k[i].text}
</p>
</div>
</div>`
)
}
});
});
}
$("#postComment").click(
function () {
var contentBody = {
text: $("#commentText").val(),
sender: $("#userEmail").val()
}
$.ajax(`/api/Blog/${blogId}/comments`, {
data: JSON.stringify(contentBody),
contentType: "application/json",
method: "post"
}).done(response => { $("#commentText").val(''); $("#userEmail").val(''); $("#commentBar").empty(); loadComments(); })
// Write your JavaScript code.
}
);
$(loadComments());

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>0c1057bc-b206-4a40-b003-9b6299aa9c64</UserSecretsId>
@@ -11,7 +11,21 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AspNet.Security.OAuth.Discord" Version="7.0.4" />
<PackageReference Include="CoreAdmin" Version="2.7.1" />
<PackageReference Include="Discord.OAuth2" Version="1.1.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.12" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.12" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.12">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.11" />
</ItemGroup>
<ItemGroup>
<Folder Include="Migrations\" />
</ItemGroup>
</Project>