Merge pull request #2 from ganjoor/audioman

Audioman
This commit is contained in:
Hamid Reza Mohammadi 2020-08-29 19:57:41 +04:30 committed by GitHub
commit cc7992e78f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 489 additions and 60 deletions

View File

@ -0,0 +1,23 @@
namespace RMuseum.Models.GanjoorAudio
{
/// <summary>
/// Audio Review Status
/// </summary>
public enum AudioReviewStatus
{
/// <summary>
/// pending for review
/// </summary>
Pending = 0,
/// <summary>
/// approved
/// </summary>
Approved = 1,
/// <summary>
/// Rejected
/// </summary>
Rejected = 2
}
}

View File

@ -0,0 +1,39 @@
namespace RMuseum.Models.GanjoorAudio
{
/// <summary>
/// Audio Synchronization Status (binary combination is acceptable)
/// </summary>
public enum AudioSyncStatus
{
/// <summary>
/// no changed
/// </summary>
SynchronizedOrRejected = 0,
/// <summary>
/// new upload
/// </summary>
NewItem = 1,
/// <summary>
/// meta data should be updated
/// </summary>
MetadataChanged = 2,
/// <summary>
/// sound files should be reuploaded
/// </summary>
SoundFilesChanged = 4,
/// <summary>
/// Xml file should be reuploaded
/// </summary>
XmlFileChanged = 8,
/// <summary>
/// Item is deleted
/// </summary>
Deleted = 16
}
}

View File

@ -0,0 +1,164 @@
using RSecurityBackend.Models.Auth.Db;
using System;
namespace RMuseum.Models.GanjoorAudio
{
/// <summary>
/// Poem Narration
/// </summary>
public class PoemNarration
{
/// <summary>
/// Id
/// </summary>
public Guid Id { get; set; }
/// <summary>
/// Owner User
/// </summary>
public RAppUser Owner { get; set; }
/// <summary>
/// Owner User Id
/// </summary>
public Guid OwnerId { get; set; }
/// <summary>
/// Final data is actually exported to a MySQL database which this auto increment field is its key
/// </summary>
public int GanjoorAudioId { get; set; }
/// <summary>
/// Ganjoor Post Id
/// </summary>
public int GanjoorPostId { get; set; }
/// <summary>
/// This determines where an audio is displayed between a list of sounds related to a specfic poem
/// </summary>
public int AudioOrder { get; set; }
/// <summary>
/// Using this field content you would determine xml, mp3 and ogg file names
/// </summary>
public string FileNameWithoutExtension { get; set; }
/// <summary>
/// combining this with <see cref="FileNameWithoutExtension"/> + .ext would preduce relative path of sound files on our file server the full path would become [HOMEPath] + '/i/' + this value
/// </summary>
/// <sample>
/// "a2"
/// </sample>
/// <remarks>
/// We had previously used different pathes because when a directory became overcrowded our connection time would increase unbearably due to IRAN internet problems, so it is sensible to store it per record and not as a global option value
/// </remarks>
public string SoundFilesFolder { get; set; }
/// <summary>
/// MP3 File Path
/// </summary>
public string RemoteMp3FilePath { get { return $"/i/{SoundFilesFolder}/{FileNameWithoutExtension}.mp3"; } }
/// <summary>
/// MP3 url
/// </summary>
public string Mp3Url { get { return $"https://i.ganjoor.net/{SoundFilesFolder}/{FileNameWithoutExtension}.mp3"; } }
/// <summary>
/// OGG File Path
/// </summary>
public string RemoteOggFilePath { get { return $"/i/{SoundFilesFolder}/{FileNameWithoutExtension}.ogg"; } }
/// <summary>
/// OGG url
/// </summary>
public string OggUrl { get { return $"https://i.ganjoor.net/{SoundFilesFolder}/{FileNameWithoutExtension}.ogg"; } }
/// <summary>
/// This is also a legacy field
/// </summary>
/// <sample>
/// "/i/a2/x"
/// </sample>
public string RemoteXMLFilePath { get { return $"/i/{SoundFilesFolder}/x/{FileNameWithoutExtension}.xml"; } }
/// <summary>
/// Audio Title
/// </summary>
public string AudioTitle { get; set; }
/// <summary>
/// Audio Artist
/// </summary>
public string AudioArtist { get; set; }
/// <summary>
/// Audio Artist Url
/// </summary>
public string AudioArtistUrl { get; set; }
/// <summary>
/// Audio Source
/// </summary>
public string AudioSrc { get; set; }
/// <summary>
/// Audio Src Url
/// </summary>
public string AudioSrcUrl { get; set; }
/// <summary>
/// Legacy Audio Guid
/// </summary>
public Guid LegacyAudioGuid { get; set; }
/// <summary>
/// Audio File CheckSum
/// </summary>
public string Mp3FileCheckSum { get; set; }
/// <summary>
/// mp3 size in bytes
/// </summary>
public int Mp3SizeInBytes { get; set; }
/// <summary>
/// ogg size in bytes
/// </summary>
public int OggSizeInBytes { get; set; }
/// <summary>
/// Upload Date
/// </summary>
public DateTime UploadDate { get; set; }
/// <summary>
/// Review Date (Approve or Reject)
/// </summary>
public DateTime ReviewDate{ get; set; }
/// <summary>
/// MP3 File local path on Windows Server (if item is not rejected probably it is not valid and it is deleted)
/// </summary>
public string LocalMp3FilePath { get; set; }
/// <summary>
/// XML File local path on Windows Server (if item is not rejected probably it is not valid and it is deleted)
/// </summary>
public string LocalXmlFilePath { get; set; }
/// <summary>
/// Value is one or a combination of <see cref="RMuseum.Models.GanjoorAudio.AudioSyncStatus"/>
/// </summary>
public int AudioSyncStatus { get; set; }
/// <summary>
/// Review Status
/// </summary>
public AudioReviewStatus ReviewStatus { get; set; }
}
}

View File

@ -1495,6 +1495,215 @@
User Note
</summary>
</member>
<member name="T:RMuseum.Models.GanjoorAudio.AudioReviewStatus">
<summary>
Audio Review Status
</summary>
</member>
<member name="F:RMuseum.Models.GanjoorAudio.AudioReviewStatus.Pending">
<summary>
pending for review
</summary>
</member>
<member name="F:RMuseum.Models.GanjoorAudio.AudioReviewStatus.Approved">
<summary>
approved
</summary>
</member>
<member name="F:RMuseum.Models.GanjoorAudio.AudioReviewStatus.Rejected">
<summary>
Rejected
</summary>
</member>
<member name="T:RMuseum.Models.GanjoorAudio.AudioSyncStatus">
<summary>
Audio Synchronization Status (binary combination is acceptable)
</summary>
</member>
<member name="F:RMuseum.Models.GanjoorAudio.AudioSyncStatus.SynchronizedOrRejected">
<summary>
no changed
</summary>
</member>
<member name="F:RMuseum.Models.GanjoorAudio.AudioSyncStatus.NewItem">
<summary>
new upload
</summary>
</member>
<member name="F:RMuseum.Models.GanjoorAudio.AudioSyncStatus.MetadataChanged">
<summary>
meta data should be updated
</summary>
</member>
<member name="F:RMuseum.Models.GanjoorAudio.AudioSyncStatus.SoundFilesChanged">
<summary>
sound files should be reuploaded
</summary>
</member>
<member name="F:RMuseum.Models.GanjoorAudio.AudioSyncStatus.XmlFileChanged">
<summary>
Xml file should be reuploaded
</summary>
</member>
<member name="F:RMuseum.Models.GanjoorAudio.AudioSyncStatus.Deleted">
<summary>
Item is deleted
</summary>
</member>
<member name="T:RMuseum.Models.GanjoorAudio.PoemNarration">
<summary>
Poem Narration
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.Id">
<summary>
Id
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.Owner">
<summary>
Owner User
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.OwnerId">
<summary>
Owner User Id
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.GanjoorAudioId">
<summary>
Final data is actually exported to a MySQL database which this auto increment field is its key
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.GanjoorPostId">
<summary>
Ganjoor Post Id
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.AudioOrder">
<summary>
This determines where an audio is displayed between a list of sounds related to a specfic poem
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.FileNameWithoutExtension">
<summary>
Using this field content you would determine xml, mp3 and ogg file names
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.SoundFilesFolder">
<summary>
combining this with <see cref="P:RMuseum.Models.GanjoorAudio.PoemNarration.FileNameWithoutExtension"/> + .ext would preduce relative path of sound files on our file server the full path would become [HOMEPath] + '/i/' + this value
</summary>
<sample>
"a2"
</sample>
<remarks>
We had previously used different pathes because when a directory became overcrowded our connection time would increase unbearably due to IRAN internet problems, so it is sensible to store it per record and not as a global option value
</remarks>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.RemoteMp3FilePath">
<summary>
MP3 File Path
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.Mp3Url">
<summary>
MP3 url
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.RemoteOggFilePath">
<summary>
OGG File Path
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.OggUrl">
<summary>
OGG url
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.RemoteXMLFilePath">
<summary>
This is also a legacy field
</summary>
<sample>
"/i/a2/x"
</sample>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.AudioTitle">
<summary>
Audio Title
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.AudioArtist">
<summary>
Audio Artist
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.AudioArtistUrl">
<summary>
Audio Artist Url
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.AudioSrc">
<summary>
Audio Source
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.AudioSrcUrl">
<summary>
Audio Src Url
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.LegacyAudioGuid">
<summary>
Legacy Audio Guid
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.Mp3FileCheckSum">
<summary>
Audio File CheckSum
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.Mp3SizeInBytes">
<summary>
mp3 size in bytes
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.OggSizeInBytes">
<summary>
ogg size in bytes
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.UploadDate">
<summary>
Upload Date
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.ReviewDate">
<summary>
Review Date (Approve or Reject)
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.LocalMp3FilePath">
<summary>
MP3 File local path on Windows Server (if item is not rejected probably it is not valid and it is deleted)
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.LocalXmlFilePath">
<summary>
XML File local path on Windows Server (if item is not rejected probably it is not valid and it is deleted)
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.AudioSyncStatus">
<summary>
Value is one or a combination of <see cref="T:RMuseum.Models.GanjoorAudio.AudioSyncStatus"/>
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.PoemNarration.ReviewStatus">
<summary>
Review Status
</summary>
</member>
<member name="T:RMuseum.Models.GanjoorIntegration.GanjoorLink">
<summary>
ganjoor link for artifacts and items
@ -3501,11 +3710,6 @@
<param name="format"></param>
<returns></returns>
</member>
<member name="P:RMuseum.Services.Implementation.MailKitEmailSender.SmptConfig">
<summary>
SmptConfig
</summary>
</member>
<member name="T:RMuseum.Services.Implementation.PictureFileService">
<summary>
manipulating picture files

View File

@ -1,33 +0,0 @@
using RSecurityBackend.Models.Mail;
using RSecurityBackend.Services.Implementation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace RMuseum.Services.Implementation
{
public class MailKitEmailSender : MailKitEmailSenderBase
{
/// <summary>
/// SmptConfig
/// </summary>
public override SmptConfig SmptConfig
{
get
{
return
new SmptConfig()
{
port = 25,
server = "ganjgah.ir",
smtpUsername = "noreply@ganjgah.ir",
smtpPassword = "sahY%6&$OnD67i0978",
from = "noreply@ganjgah.ir",
useSsl = false
};
}
}
}
}

View File

@ -25,5 +25,14 @@
"Secret": "k4Fy7pDsc0LgXQ8PCCfZtwmju5Ed8asc",
"DefaultTokenExpirationInSeconds": "2502000"
},
"AllowedHosts": "*"
}
"SmptConfig": {
"Server": "smtp.gmail.com",
"Port": "465",
"UseSsl": "true",
"Username": "test@gmail.com",
"Password": "password",
"From": "test@gmail.com"
},
"AllowedHosts": "*"
}

View File

@ -2571,27 +2571,33 @@
<param name="context"></param>
<param name="configuration"></param>
</member>
<member name="T:RSecurityBackend.Services.Implementation.MailKitEmailSenderBase">
<member name="T:RSecurityBackend.Services.Implementation.MailKitEmailSender">
<summary>
mail sender using MailKit
</summary>
</member>
<member name="M:RSecurityBackend.Services.Implementation.MailKitEmailSenderBase.#ctor">
<member name="M:RSecurityBackend.Services.Implementation.MailKitEmailSender.#ctor(Microsoft.Extensions.Configuration.IConfiguration)">
<summary>
constructor
</summary>
<param name="configuration"></param>
</member>
<member name="P:RSecurityBackend.Services.Implementation.MailKitEmailSenderBase.Options">
<member name="P:RSecurityBackend.Services.Implementation.MailKitEmailSender.Configuration">
<summary>
Configuration
</summary>
</member>
<member name="P:RSecurityBackend.Services.Implementation.MailKitEmailSender.Options">
<summary>
options
</summary>
</member>
<member name="P:RSecurityBackend.Services.Implementation.MailKitEmailSenderBase.SmptConfig">
<member name="P:RSecurityBackend.Services.Implementation.MailKitEmailSender.SmptConfig">
<summary>
SmptConfig
</summary>
</member>
<member name="M:RSecurityBackend.Services.Implementation.MailKitEmailSenderBase.SendEmailAsync(System.String,System.String,System.String)">
<member name="M:RSecurityBackend.Services.Implementation.MailKitEmailSender.SendEmailAsync(System.String,System.String,System.String)">
<summary>
send email
</summary>
@ -2600,7 +2606,7 @@
<param name="message"></param>
<returns></returns>
</member>
<member name="M:RSecurityBackend.Services.Implementation.MailKitEmailSenderBase.Execute(RSecurityBackend.Models.Mail.SmptConfig,System.String,System.String,System.String)">
<member name="M:RSecurityBackend.Services.Implementation.MailKitEmailSender.Execute(RSecurityBackend.Models.Mail.SmptConfig,System.String,System.String,System.String)">
<summary>
</summary>

View File

@ -1,6 +1,6 @@
using MailKit.Net.Smtp;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Configuration;
using MimeKit;
using RSecurityBackend.Models.Mail;
using System.Threading.Tasks;
@ -10,38 +10,55 @@ namespace RSecurityBackend.Services.Implementation
/// <summary>
/// mail sender using MailKit
/// </summary>
public class MailKitEmailSenderBase : IEmailSender
public class MailKitEmailSender : IEmailSender
{
/// <summary>
/// constructor
/// </summary>
public MailKitEmailSenderBase()
/// <param name="configuration"></param>
public MailKitEmailSender(IConfiguration configuration)
{
Configuration = configuration;
Options = SmptConfig;
}
/// <summary>
/// Configuration
/// </summary>
protected IConfiguration Configuration { get; }
/// <summary>
/// options
/// </summary>
public SmptConfig Options { get; } //set only via Secret Manager
private SmptConfig _SmptConfig = null;
/// <summary>
/// SmptConfig
/// </summary>
public virtual SmptConfig SmptConfig
public SmptConfig SmptConfig
{
get
{
return
new SmptConfig()
{
port = 465,
server = "smtp.gmail.com",
smtpUsername = "nonexistingganjoor@gmail.com",
smtpPassword = "APasswordHere",
from = "nonexistingganjoor@gmail.com",
useSsl = true
};
if (_SmptConfig == null)
{
_SmptConfig =
new SmptConfig()
{
server = $"{Configuration.GetSection("SmptConfig")["Server"]}",
port = int.Parse($"{Configuration.GetSection("SmptConfig")["Port"]}"),
useSsl = bool.Parse($"{Configuration.GetSection("SmptConfig")["UseSsl"]}"),
smtpUsername = $"{ Configuration.GetSection("SmptConfig")["Username"] }",
smtpPassword = $"{Configuration.GetSection("SmptConfig")["Password"]}",
from = $"{ Configuration.GetSection("SmptConfig")["From"] }"
};
}
return _SmptConfig;
}
}