Skip to content
Snippets Groups Projects
Select Git revision
  • 256b0db12766064c4a38f9d6322659491036b7d3
  • main default protected
  • dev protected
  • Issue/3142-kpiGenerator
  • Hotfix/3115-userReportingEmpty2
  • Hotfix/3115-userReportingEmpty
  • Issue/3073-kpi
  • Issue/2492-respOrg
  • Issue/3005-kpiReportingBroken
  • Issue/2982-kpiDataPub
  • gitkeep
  • Issue/2847-reporting
  • Issue/2850-removeGrantId
  • Issue/2432-publicationKpi
  • Hotfix/xxxx-rors
  • Issue/2666-adminCronjobs-theSequal
  • Issue/2666-adminCronjobs
  • Issue/2568-betterLogging
  • Issue/2518-docs
  • Hotfix/2388-sensitive
  • Issue/2330-fixNaNQuotainAdmin
  • v1.2.10
  • v1.2.9
  • v1.2.8
  • v1.2.7
  • v1.2.6
  • v1.2.5
  • v1.2.4
  • v1.2.3
  • v1.2.2
  • v1.2.1
  • v1.2.0
  • v1.1.1
  • v1.1.0
  • v1.0.9
  • v1.0.8
  • v1.0.7
  • v1.0.6
  • v1.0.5
  • v1.0.4
  • v1.0.3
41 results

Reporting.cs

Blame
  • sirieamhunke's avatar
    Sirieam Marie Hunke authored
    256b0db1
    History
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    Reporting.cs 7.31 KiB
    using Coscine.Configuration;
    using Coscine.Metadata;
    using GitLabApiClient;
    using GitLabApiClient.Models.Commits.Requests.CreateCommitRequest;
    using KPIGenerator.Utils;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using System.Text;
    using VDS.RDF;
    using VDS.RDF.Query;
    using static KPIGenerator.Utils.CommandLineOptions;
    
    namespace KPIGenerator;
    
    public abstract class Reporting<O> where O : class
    {
        public O Options { get; init; }
        public GitLabClient GitLabClient { get; set; }
        public List<Organization> Organizations { get; set; }
        public RdfStoreConnector RdfStoreConnector { get; init; }
        public SparqlRemoteEndpoint QueryEndpoint { get; init; }
        public ConsulConfiguration Configuration { get; }
        private static string HostUrl { get; } = "https://git.rwth-aachen.de/";
        private static string InstanceName { get; set; } = null!;
        public virtual string ReportingFileName { get; init; } = null!;
    
    
        public readonly Organization _otherOrganization = new()
        {
            Name = "Other",
            RorUrl = "https://ror.org/_other",
        };
    
        /// <summary>
        /// Reporting Database GitLab Project URL
        /// </summary>
        /// <remarks>https://git.rwth-aachen.de/coscine/reporting/reporting-database</remarks>
        private static readonly int ReportingDatabaseProjectId = 75304;
    
    
        public Reporting(O options)
        {
            InstanceName = this.GetType().Name;
            Options = options;
            Configuration = new ConsulConfiguration();
            RdfStoreConnector = new RdfStoreConnector(Configuration.GetStringAndWait("coscine/local/virtuoso/additional/url"));
            QueryEndpoint = new SparqlRemoteEndpoint(new Uri(Configuration.GetStringAndWait("coscine/local/virtuoso/additional/url")));
            GitLabClient = new GitLabClient(HostUrl, Configuration.GetStringAndWait("coscine/global/gitlabtoken"));
            Organizations = new List<Organization>() { _otherOrganization };
        }
    
        public abstract IEnumerable<ReportingFileObject> GenerateReporting();
    
        public bool Run()
        {
            // Console text output
            Console.Write($"{new string('=', 60)}\n{InstanceName}");
            var baseOptions = Options as BaseOptions;
            if (baseOptions is not null && baseOptions.DummyMode)
            {
                Console.Write(" : DUMMY MODE");
            }
            Console.WriteLine($"\n{new string('-', 60)}");
            // Generate Reporting based on CLI input
            var reportingFiles = GenerateReporting();
            Console.WriteLine($"\n{new string('=', 60)}");
            Console.WriteLine("Reporting generated successfully. Publishing...");
            // Publish Report
            var success = PublishAsync(reportingFiles).Result;
            Console.WriteLine(success ? "Published successfully." : "Publishing FAILED!");
            return success;
        }
    
    
        private async Task<bool> PublishAsync(IEnumerable<ReportingFileObject> files)
        {
            try
            {
                // Retrieve Reporting Database project
                var reportingDatabaseProject = await GitLabClient.Projects.GetAsync(ReportingDatabaseProjectId);
                var commitBranch = reportingDatabaseProject.DefaultBranch;
                var commitMessage = $"{InstanceName} Generated - {DateTime.Now:dd.MM.yyyy HH:mm}"; // CompleteReporting Generated - 31.08.2022 10:25
    
                var projectTree = await GitLabClient.Trees.GetAsync(reportingDatabaseProject, o =>
                {
                    o.Recursive = true;
                    o.Reference = commitBranch;
                });
    
                // Define commit actions
                var actions = new List<CreateCommitRequestAction>();
    
                // Delete files or organizations that are not valid anymore
                foreach (var fileInProject in projectTree.Where(file => file.Type.Equals("blob")))
                {
                    if (!files.Any(f => f.Path.Equals(fileInProject.Path)) && !fileInProject.Path.Equals("README.md"))
                    {
                        // Add Action
                        actions.Add(new CreateCommitRequestAction(CreateCommitRequestActionType.Delete, fileInProject.Path));
                    }
                }
    
                // Create a commit per file with its contents
                foreach (var file in files)
                {
                    // Write file contents to bytes
                    byte[] bytes;
                    using (var ms = new MemoryStream())
                    {
                        file.Content.CopyTo(ms);
                        bytes = ms.ToArray();
                    }
    
                    // Distinguish between Creating or Updating a file
                    var actionType = CreateCommitRequestActionType.Create;
                    if (projectTree.Any(f => f.Path.Equals(file.Path)))
                    {
                        actionType = CreateCommitRequestActionType.Update;
                    }
    
                    // Add Action
                    actions.Add(new CreateCommitRequestAction(actionType, file.Path)
                    {
                        Content = Convert.ToBase64String(bytes),
                        Encoding = CreateCommitRequestActionEncoding.Base64
                    });
                }
                // Push Commit
                var baseOptions = Options as BaseOptions;
                if (baseOptions is not null && !baseOptions.DummyMode)
                {
                    await GitLabClient.Commits.CreateAsync(reportingDatabaseProject, new CreateCommitRequest(commitBranch, commitMessage, actions));
                }
                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return false;
            }
        }
    
        public Organization FetchOrganizationByRor(string rorUrl)
        {
            var result = new Organization();
            var organizationFound = Organizations.Find(o => o.RorUrl.Equals(rorUrl));
            if (organizationFound is not null)
            {
                result = new Organization
                {
                    Name = organizationFound.Name,
                    RorUrl = organizationFound.RorUrl,
                };
            }
            else
            {
                var organizationTriples = RdfStoreConnector.GetLabelForSubject(new Uri(Uri.UnescapeDataString(rorUrl))).ToList();
                if (organizationTriples.Any())
                {
                    result = new Organization
                    {
                        // Only one entry possible per organization, take 0th element
                        Name = organizationTriples[0].Object.ToString(),
                        RorUrl = organizationTriples[0].Subject.ToString(),
                    };
                    Organizations.Add(result); // Cache the fetched organization
                }
                else
                {
                    result = _otherOrganization;
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine($"WARNING!: Organization with ROR \"{rorUrl}\" could not be correctly identified. Will use \"{result.RorUrl}\" and \"{result.Name}\".");
                    Console.ResetColor();
                }
            }
            return result;
        }
    
        public static string GetReportingPathGeneral(string fileName)
        {
            return string.Format("General/{0}", fileName);
        }
        public static string GetReportingPathOrganization(string organizationRor, string fileName)
        {
            return string.Format("Organizations/{0}/{1}", organizationRor, fileName);
        }
    
        public static Stream ConvertStringContentsToStream(string contents)
        {
            byte[] byteArray = Encoding.UTF8.GetBytes(contents);
            return new MemoryStream(byteArray);
        }
    }