275 lines
12 KiB
C#
275 lines
12 KiB
C#
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Configuration;
|
|
using MySql.Data.MySqlClient;
|
|
using RMuseum.DbContext;
|
|
using RMuseum.Models.GanjoorAudio;
|
|
using RMuseum.Models.GanjoorAudio.ViewModels;
|
|
using RMuseum.Models.UploadSession;
|
|
using RSecurityBackend.Models.Generic;
|
|
using RSecurityBackend.Services.Implementation;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace RMuseum.Services.Implementation
|
|
{
|
|
|
|
/// <summary>
|
|
/// Audio Narration Service Implementation
|
|
/// </summary>
|
|
public class AudioNarrationService : IAudioNarrationService
|
|
{
|
|
/// <summary>
|
|
/// returns list of narrations
|
|
/// </summary>
|
|
/// <param name="paging"></param>
|
|
/// <param name="filteredUserId">send Guid.Empty if you want all narrations</param>
|
|
/// <param name="status"></param>
|
|
/// <returns></returns>
|
|
public async Task<RServiceResult<(PaginationMetadata PagingMeta, PoemNarrationViewModel[] Items)>> GetAll(PagingParameterModel paging, Guid filteredUserId, AudioReviewStatus status)
|
|
{
|
|
try
|
|
{
|
|
var source =
|
|
|
|
_context.AudioFiles
|
|
.Include(a => a.Owner)
|
|
.Where(a =>
|
|
(filteredUserId == Guid.Empty || a.OwnerId == filteredUserId)
|
|
&&
|
|
(status == AudioReviewStatus.All || a.ReviewStatus == status)
|
|
)
|
|
.OrderBy(a => a.UploadDate)
|
|
.AsQueryable();
|
|
|
|
(PaginationMetadata PagingMeta, PoemNarration[] Items) paginatedResult =
|
|
await QueryablePaginator<PoemNarration>.Paginate(source, paging);
|
|
|
|
List<PoemNarrationViewModel> res = new List<PoemNarrationViewModel>();
|
|
foreach(PoemNarration audio in paginatedResult.Items)
|
|
{
|
|
res.Add(new PoemNarrationViewModel(audio));
|
|
}
|
|
|
|
return new RServiceResult<(PaginationMetadata PagingMeta, PoemNarrationViewModel[] Items)>((paginatedResult.PagingMeta, res.ToArray()));
|
|
}
|
|
catch (Exception exp)
|
|
{
|
|
return new RServiceResult<(PaginationMetadata PagingMeta, PoemNarrationViewModel[] Items)>((PagingMeta: null, Items: null), exp.ToString());
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// imports data from ganjoor MySql database
|
|
/// </summary>
|
|
/// <param name="OwnrRAppUserId">User Id which becomes owner of imported data</param>
|
|
public async Task<RServiceResult<bool>> OneTimeImport(Guid OwnrRAppUserId)
|
|
{
|
|
try
|
|
{
|
|
PoemNarration sampleCheck = await _context.AudioFiles.FirstOrDefaultAsync();
|
|
if(sampleCheck != null)
|
|
{
|
|
return new RServiceResult<bool>(false, "OneTimeImport is a one time operation and cannot be called multiple times.");
|
|
}
|
|
using (MySqlConnection connection = new MySqlConnection
|
|
(
|
|
$"server={Configuration.GetSection("AudioMySqlServer")["Server"]};uid={Configuration.GetSection("AudioMySqlServer")["Username"]};pwd={Configuration.GetSection("AudioMySqlServer")["Password"]};database={Configuration.GetSection("AudioMySqlServer")["Database"]};charset=utf8"
|
|
))
|
|
{
|
|
connection.Open();
|
|
using(MySqlDataAdapter src = new MySqlDataAdapter(
|
|
"SELECT audio_ID, audio_post_ID, audio_order, audio_xml, audio_ogg, audio_mp3, " +
|
|
"audio_title, audio_artist, audio_artist_url, audio_src, audio_src_url, audio_guid, " +
|
|
"audio_fchecksum, audio_mp3bsize, audio_oggbsize, audio_date " +
|
|
"FROM adab.ganja_gaudio ORDER BY audio_ID",
|
|
connection
|
|
))
|
|
{
|
|
using(DataTable srcData = new DataTable())
|
|
{
|
|
await src.FillAsync(srcData);
|
|
|
|
int audioSyncStatus = (int)AudioSyncStatus.SynchronizedOrRejected;
|
|
foreach (DataRow row in srcData.Rows)
|
|
{
|
|
PoemNarration newRecord = new PoemNarration()
|
|
{
|
|
OwnerId = OwnrRAppUserId,
|
|
GanjoorAudioId = int.Parse(row["audio_ID"].ToString()),
|
|
GanjoorPostId = (int)row["audio_post_ID"],
|
|
AudioOrder = (int)row["audio_order"],
|
|
AudioTitle = row["audio_title"].ToString(),
|
|
AudioArtist = row["audio_artist"].ToString(),
|
|
AudioArtistUrl = row["audio_artist_url"].ToString(),
|
|
AudioSrc = row["audio_src"].ToString(),
|
|
AudioSrcUrl = row["audio_src_url"].ToString(),
|
|
LegacyAudioGuid = new Guid(row["audio_guid"].ToString()),
|
|
Mp3FileCheckSum = row["audio_fchecksum"].ToString(),
|
|
Mp3SizeInBytes = (int)row["audio_mp3bsize"],
|
|
OggSizeInBytes = (int)row["audio_oggbsize"],
|
|
UploadDate = (DateTime)row["audio_date"],
|
|
AudioSyncStatus = audioSyncStatus,
|
|
ReviewStatus = AudioReviewStatus.Approved
|
|
};
|
|
newRecord.ReviewDate = newRecord.UploadDate;
|
|
string audio_xml = row["audio_xml"].ToString();
|
|
//sample audio_xml value: /i/a/x/11876-Simorgh.xml
|
|
audio_xml = audio_xml.Substring("/i/".Length); // /i/a/x/11876-Simorgh.xml -> a/x/11876-Simorgh.xml
|
|
newRecord.SoundFilesFolder = audio_xml.Substring(0, audio_xml.IndexOf('/')); //(a)
|
|
newRecord.FileNameWithoutExtension = Path.GetFileNameWithoutExtension(audio_xml.Substring(audio_xml.LastIndexOf('/') + 1)); //(11876-Simorgh)
|
|
|
|
_context.AudioFiles.Add(newRecord);
|
|
}
|
|
}
|
|
await _context.SaveChangesAsync();
|
|
}
|
|
}
|
|
return new RServiceResult<bool>(true);
|
|
}
|
|
catch(Exception exp)
|
|
{
|
|
return new RServiceResult<bool>(false, exp.ToString());
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initiate New Upload Session for audio
|
|
/// </summary>
|
|
/// <param name="userId"></param>
|
|
/// <returns></returns>
|
|
public async Task<RServiceResult<UploadSession>> InitiateNewUploadSession(Guid userId)
|
|
{
|
|
try
|
|
{
|
|
UploadSession session = new UploadSession()
|
|
{
|
|
SessionType = UploadSessionType.Audio,
|
|
UseId = userId,
|
|
UploadStartTime = DateTime.Now,
|
|
Status = UploadSessionProcessStatus.NotStarted,
|
|
ProcessProgress = 0
|
|
};
|
|
await _context.UploadSessions.AddAsync(session);
|
|
await _context.SaveChangesAsync();
|
|
|
|
return new RServiceResult<UploadSession>(session);
|
|
|
|
}
|
|
catch(Exception exp)
|
|
{
|
|
return new RServiceResult<UploadSession>(null, exp.ToString());
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save uploaded file
|
|
/// </summary>
|
|
/// <param name="uploadedFile"></param>
|
|
/// <returns></returns>
|
|
public async Task<RServiceResult<UploadSessionFile>> SaveUploadedFile(IFormFile uploadedFile)
|
|
{
|
|
try
|
|
{
|
|
UploadSessionFile file = new UploadSessionFile()
|
|
{
|
|
ContentDisposition = uploadedFile.ContentDisposition,
|
|
ContentType = uploadedFile.ContentType,
|
|
FileName = uploadedFile.FileName,
|
|
Length = uploadedFile.Length,
|
|
Name = uploadedFile.Name,
|
|
ProcessResult = true,
|
|
ProcessResultMsg = ""
|
|
};
|
|
|
|
string ext = Path.GetExtension(file.FileName).ToLower();
|
|
if(ext != ".mp3" && ext != ".xml" && ext != ".zip")
|
|
{
|
|
file.ProcessResult = false;
|
|
file.ProcessResultMsg = "تنها فایلهای با پسوند mp3، xml و zip قابل قبول هستند.";
|
|
}
|
|
else
|
|
{
|
|
if (!Directory.Exists(Configuration.GetSection("AudioUploadService")["StoragePath"]))
|
|
{
|
|
try
|
|
{
|
|
Directory.CreateDirectory(Configuration.GetSection("AudioUploadService")["StoragePath"]);
|
|
}
|
|
catch
|
|
{
|
|
return new RServiceResult<UploadSessionFile>(null, $"ProcessImage: create dir failed {Configuration.GetSection("AudioUploadService")["StoragePath"]}");
|
|
}
|
|
}
|
|
|
|
string filePath = Path.Combine(Configuration.GetSection("AudioUploadService")["StoragePath"], file.FileName);
|
|
while(File.Exists(filePath))
|
|
{
|
|
filePath = Path.Combine(Configuration.GetSection("AudioUploadService")["StoragePath"], Guid.NewGuid().ToString() + ext);
|
|
}
|
|
using (FileStream fsMain = new FileStream(filePath, FileMode.Create))
|
|
{
|
|
await uploadedFile.CopyToAsync(fsMain);
|
|
}
|
|
file.FilePath = filePath;
|
|
}
|
|
|
|
return new RServiceResult<UploadSessionFile>(file);
|
|
|
|
}
|
|
catch (Exception exp)
|
|
{
|
|
return new RServiceResult<UploadSessionFile>(null, exp.ToString());
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Upload Session (including files)
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public async Task<RServiceResult<UploadSession>> GetUploadSession(Guid id)
|
|
{
|
|
try
|
|
{
|
|
return new RServiceResult<UploadSession>
|
|
(
|
|
await _context.UploadSessions.Include(s => s.UploadedFiles).FirstOrDefaultAsync(s => s.Id == id)
|
|
);
|
|
|
|
}
|
|
catch (Exception exp)
|
|
{
|
|
return new RServiceResult<UploadSession>(null, exp.ToString());
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Configuration
|
|
/// </summary>
|
|
protected IConfiguration Configuration { get; }
|
|
|
|
/// <summary>
|
|
/// Database Contetxt
|
|
/// </summary>
|
|
protected readonly RMuseumDbContext _context;
|
|
|
|
/// <summary>
|
|
/// constructor
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
/// <param name="configuration"></param>
|
|
public AudioNarrationService(RMuseumDbContext context, IConfiguration configuration)
|
|
{
|
|
_context = context;
|
|
Configuration = configuration;
|
|
}
|
|
}
|
|
}
|