public IActionResult Post(int observationId, [FromBody] ObsResourceDtoForCreationAndUpdate newObsResourceDto)
        {
            ObsResource newObsResource = _mapper.Map <ObsResource>(newObsResourceDto);

            // Verify the type
            if (newObsResourceDto.Type != "sketch" && newObsResourceDto.Type != "jot" && newObsResourceDto.Type != "image" && newObsResourceDto.Type != "link")
            {
                return(BadRequest("Invalid type"));
            }

            Observation observation = _observationsRepo.GetObservationById(observationId);

            if (observation == null)
            {
                return(NotFound("Could not find the observation"));
            }

            newObsResource.ObservationId = observation.Id;

            ObsResource addedObsResource = _obsResourceRepo.AddObsResource(newObsResource);

            if (addedObsResource == null)
            {
                return(StatusCode(500, "Something went wrong creating a resource"));
            }

            _logger.LogInformation("Created a resource:");
            _logger.LogInformation(PocoPrinter.ToString(addedObsResource));

            ObsResourceDto addedObsResourceDto = _mapper.Map <ObsResourceDto>(addedObsResource);

            return(CreatedAtRoute("GetOneObsResource", new { resourceId = addedObsResourceDto.Id }, addedObsResourceDto));
        }
Example #2
0
        public ObsResource AddObsResource(ObsResource ObsResource)
        {
            var addedObsResource = _dbContext.ObsResources.Add(ObsResource);

            _dbContext.SaveChanges();

            return(addedObsResource.Entity);
        }
        public IActionResult Get(int resourceId)
        {
            ObsResource obsResource = _obsResourceRepo.GetOneResource(resourceId);

            if (obsResource == null)
            {
                return(NotFound());
            }
            return(Ok(_mapper.Map <ObsResourceDto>(obsResource)));
        }
        public IActionResult Delete(int id)
        {
            ObsResource obsResourceEntity = _obsResourceRepo.GetOneResource(id);

            if (obsResourceEntity == null)
            {
                return(NotFound());
            }

            bool result = _obsResourceRepo.DeleteObsResource(obsResourceEntity);

            if (!result)
            {
                return(StatusCode(500, "Something went wrong deleting the resource"));
            }

            _logger.LogInformation("Deleted a resource:");
            _logger.LogInformation(PocoPrinter.ToString(obsResourceEntity));

            return(Ok());
        }
        public IActionResult Put(int resourceId, [FromBody] ObsResourceDtoForCreationAndUpdate obsResourceDtoForUpdate)
        {
            if (obsResourceDtoForUpdate == null)
            {
                return(BadRequest());
            }

            ObsResource obsResourceEntity = _obsResourceRepo.GetOneResource(resourceId);

            if (obsResourceEntity == null)
            {
                return(NotFound());
            }

            // Verify the type
            if (obsResourceDtoForUpdate.Type != "sketch" &&
                obsResourceDtoForUpdate.Type != "jot" &&
                obsResourceDtoForUpdate.Type != "image" &&
                obsResourceDtoForUpdate.Type != "link" &&
                obsResourceDtoForUpdate.Type != "aladin")
            {
                return(BadRequest("Invalid type"));
            }

            _mapper.Map(obsResourceDtoForUpdate, obsResourceEntity);

            _obsResourceRepo.SaveChanges();

            _logger.LogInformation("Updated a resource:");
            _logger.LogInformation(PocoPrinter.ToString(obsResourceEntity));

            ObsResource freshObsResourceEntity = _obsResourceRepo.GetOneResource(resourceId);
            var         resultingDto           = _mapper.Map <ObsResourceDto>(freshObsResourceEntity);

            return(Ok(resultingDto));
        }
Example #6
0
 public bool DeleteObsResource(ObsResource ObsResource)
 {
     _dbContext.ObsResources.Remove(ObsResource);
     return(_dbContext.SaveChanges() > 0);
 }
        public IDictionary <string, Observation> Parse(ObsSession obsSession)
        {
            string reportText = obsSession.ReportText;
            IDictionary <string, Observation> observationsDict      = new Dictionary <string, Observation>();
            IDictionary <Match, string>       newSectionMatchesDict = new Dictionary <Match, string>();

            // If report text is empty, just return
            if (reportText == null)
            {
                return(observationsDict);
            }

            //string[] primaryCatalogs = { "M", "NGC", "IC", "Sh", "UGC", "PGC" };

            // Get a list of all catalogs designators to search for
            var allCatalogs = _dsoRepo.GetAllCatalogs();

            allCatalogs.Add("Sh2");

            // Regexp for finding DSO names
            string regexpAllCatalogs         = RegExpJoinCatalogs(allCatalogs);
            string introRegexp               = @"(?:\s|\G)"; // non-capturing group of \s or end-of-previous-match (for when the designator starts at the beginning of the line)
            string startingParenthesisRegexp = @"(\()?";
            string endingParenthesisRegexp   = @"(\))?";
            string outroRegexp               = @"[\s\.,]";
            // The ?: at the start of one of the groups is to make that the group is non-capturing.
            // This results in the fourth group always beeing the ending parenthesis.
            string dsoNameRegexp = introRegexp
                                   + startingParenthesisRegexp
                                   + "(" + regexpAllCatalogs + @")[\ |-]?([0-9]+(?:[+-\.]?[0-9]+)*)"
                                   + endingParenthesisRegexp
                                   + outroRegexp;
            var findDsoNamesRegexp = new Regex(dsoNameRegexp, RegexOptions.Compiled | RegexOptions.IgnoreCase);

            // Regexp for finding text sections that include DSO names
            string sectionStart      = @"[^\n]*";                           // the ? after the * makes it non-greedy, or else it doesn't stop at the first section end in singleline (all text as one string) mode
            string sectionEnding     = @".*?(?:\n\n|\r\n\r\n|\n$|\r\n$|$)"; // a section can end with \n\n, or \n$, or just $. The ?: after the parenthesis makes the group non-capturing.
            string findSectionRegexp = sectionStart
                                       + dsoNameRegexp
                                       + sectionEnding;
            // The RegexOptions.Singleline below is what makes it find sections that include a newline and then a Photo:/Link:/Sketch:/Jot: tag.
            // It also makes it necessary to use a ? in .*? to make it non-greedy.
            var findSectionsRegexp = new Regex(findSectionRegexp,
                                               RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);

            string resourceRegexp      = @"(Link|Image|Photo|Sketch|Jot):\s?(.*)";
            var    findResourcesRegexp = new Regex(resourceRegexp, RegexOptions.Compiled | RegexOptions.IgnoreCase);

            string flagOutro = @"(?:\s|\.|$)";  // non-capturing group of \s or . or $

            string nonDetectionRegexp     = @"!!" + flagOutro;
            var    findNonDetectionRegexp = new Regex(nonDetectionRegexp, RegexOptions.Compiled | RegexOptions.IgnoreCase);

            string ratingRegexp     = @"\s(-1|\+1|\+2|\*|\*\*)" + flagOutro;
            var    findRatingRegexp = new Regex(ratingRegexp, RegexOptions.Compiled | RegexOptions.IgnoreCase);

            string followUpRegexp     = @"\s(re-?visit|come back|telescope)" + flagOutro;
            var    findFollowUpRegexp = new Regex(followUpRegexp, RegexOptions.Compiled | RegexOptions.IgnoreCase);

            if (findSectionsRegexp.IsMatch(reportText))  // matches anywhere
            {
                int        obsIndex    = 0;
                ISet <int> foundDsoIds = new HashSet <int>();

                MatchCollection sectionsMatches = findSectionsRegexp.Matches(reportText);  // matching on the whole report text
                foreach (Match sectionsMatch in sectionsMatches)
                {
                    string sectionText = sectionsMatch.Value.Trim();  // the whole section, including resource links

                    string sectionObsText        = GetPartBeforeFirstNewlineIfAny(sectionText);
                    var    dsosInSection         = new Dictionary <int, Dso>();
                    var    obsResourcesInSection = new List <ObsResource>();

                    // Collect all the DSO's in the section text.
                    MatchCollection dsoNameMatches = findDsoNamesRegexp.Matches(sectionObsText);  // matching on a single section
                    foreach (Match dsoNameMatch in dsoNameMatches)
                    {
                        string startingParenthesis = dsoNameMatch.Groups[1].Value;
                        string catalog             = dsoNameMatch.Groups[2].Value;
                        string catalogNo           = dsoNameMatch.Groups[3].Value;
                        string endingParenthesis   = dsoNameMatch.Groups[4].Value;

                        Debug.WriteLine("---------------------------------------------------------");
                        Debug.WriteLine($"Match: {catalog} {catalogNo}");
                        //Debug.WriteLine($"Match: {sectionText}");

                        // Ignore pattern if it's surrounded by parenthesis
                        if (startingParenthesis == "(" || endingParenthesis == ")")
                        {
                            continue;
                        }

                        string dsoName = $"{catalog} {catalogNo}";
                        Dso    dso     = _dsoRepo.GetDsoByName(dsoName, normalize: false);

                        if (dso == null)
                        {
                            Debug.WriteLine("Could not match name");
                            continue;
                        }
                        else
                        {
                            Debug.WriteLine("Found: " + dso.ToString());
                        }

                        if (foundDsoIds.Contains(dso.Id))
                        {
                            throw new ObsToolException("DSO " + dso.ToString() + " found in more than one section of the report text!");
                        }
                        if (dsosInSection.ContainsKey(dso.Id))
                        {
                            continue;  // ignore when the same object is mentioned more than one
                        }

                        dsosInSection.Add(dso.Id, dso);

                        Debug.WriteLine("---------------------------------------------------------");
                    }

                    // Collect all the obs resources
                    MatchCollection resourceMatches = findResourcesRegexp.Matches(sectionText);  // matching on a single section
                    foreach (Match resourceMatch in resourceMatches)
                    {
                        string resourceType = resourceMatch.Groups[1].Value;
                        string resourceUrl  = resourceMatch.Groups[2].Value;
                        Debug.WriteLine($"Match: {resourceType} {resourceUrl}");

                        bool   isGoogleDriveUrl = (resourceType == "Sketch" || resourceType == "Jot");
                        string url = isGoogleDriveUrl ? GetFileIdFromGoogleDriveUrl(resourceUrl) : resourceUrl;

                        var obsResource = new ObsResource
                        {
                            Type = resourceType.Replace("Photo", "Image").ToLower(),
                            Url  = url
                        };
                        obsResourcesInSection.Add(obsResource);
                    }

                    // Collect non-detection
                    bool nonDetection = findNonDetectionRegexp.IsMatch(sectionText);

                    // Collect rating
                    int rating = 0;  // TODO: Change this to nullable and null?
                    if (findRatingRegexp.IsMatch(sectionText))
                    {
                        Match  lastMatch    = findRatingRegexp.Matches(sectionText).Last();
                        string ratingString = lastMatch.Groups[1].Value;
                        if (ratingString == "-1" || ratingString == "+1" || ratingString == "+2")
                        {
                            int.TryParse(ratingString, out rating);
                        }
                        else
                        {
                            rating = ratingString.Length;  // count number of *(stars)
                        }
                    }

                    // Collect follow-up
                    bool followUp = findFollowUpRegexp.IsMatch(sectionText);

                    // If section contained matches regex'ly but that could not be matched against anything
                    // in the DSO database
                    if (dsosInSection.Count == 0)
                    {
                        continue;
                    }

                    // Add any ratings or follow up flags to the DSO's
                    foreach (Dso dso in dsosInSection.Values)
                    {
                        bool noExistingDsoExtra = (dso.DsoExtra == null);
                        if (noExistingDsoExtra)
                        {
                            dso.DsoExtra = new DsoExtra();
                        }
                        // If there is no existing DSO extra, or if this obs session is newer than the obs session used to store
                        // the existing DSO extra, then we replace the attributes in it.
                        if (noExistingDsoExtra || (dso.DsoExtra != null && dso.DsoExtra.ObsSession != null && obsSession.Date >= dso.DsoExtra.ObsSession.Date))
                        {
                            dso.DsoExtra.ObsSession = obsSession;
                            dso.DsoExtra.Rating     = rating;
                            dso.DsoExtra.FollowUp   = followUp;
                        }
                    }

                    string replacedDeprectedIdentifiers = ReplaceDeprecatedObsIdentifiers(sectionText);

                    // Find any existing observations identifier based on the DSO objects the observation contains
                    var observationsIdentifier = FindExistingObsIdentifier(sectionText);
                    if (string.IsNullOrEmpty(observationsIdentifier))
                    {
                        // If none was found in the section text, create one and remember it
                        observationsIdentifier = CreateNewObsIdentifier(obsSession.Id, dsosInSection.Values.ToList());
                        newSectionMatchesDict.Add(sectionsMatch, observationsIdentifier);
                    }

                    // Now, create the observation!
                    Observation observation = new Observation
                    {
                        Text            = sectionObsText,
                        Identifier      = observationsIdentifier,
                        DsoObservations = new List <DsoObservation>(),
                        DisplayOrder    = obsIndex++,
                        NonDetection    = nonDetection
                    };

                    // Add all DSOs to the observation
                    int dsoObsIndex = 0;
                    foreach (Dso dso in dsosInSection.Values)
                    {
                        // Remember all the DSOs in this section for the checks in the next section, and the next etc..
                        foundDsoIds.Add(dso.Id);

                        var dsoObservation = new DsoObservation
                        {
                            Dso          = dso,
                            DsoId        = dso.Id,
                            DisplayOrder = dsoObsIndex++
                                           // no need to add observation.Id since it's just a POCO anyway ??????
                        };

                        // Add the DSOs as DsoObservation's to the observation
                        observation.DsoObservations.Add(dsoObservation);
                    }

                    // Add all obs resources to the observation
                    observation.ObsResources.AddRange(obsResourcesInSection);

                    // Save observation to be returned
                    observationsDict.Add(observation.Identifier, observation);
                }

                // Insert the identifier at the end of all new section matches in the report text.
                // Do it from back to front to keep the match indices from becoming obsolete when you add to the text.
                foreach (var sectionsMatch in sectionsMatches.Cast <Match>().Reverse())
                {
                    if (newSectionMatchesDict.ContainsKey(sectionsMatch))  // only the new ones
                    {
                        // Using the trimmed length to find the end position of the text to be replaced so that the
                        // inserted obs identifier doesn't end up two newlines below, at the start of the next section.
                        int    trimmedLength       = sectionsMatch.Value.Trim().Length;
                        int    sectionEndPos       = sectionsMatch.Index + trimmedLength;
                        string newObsIdentifier    = newSectionMatchesDict[sectionsMatch];
                        string decoratedIdentifier = DecorateObsIdentifier(newObsIdentifier);
                        reportText = reportText.Replace(sectionEndPos, 0, decoratedIdentifier);
                    }
                }

                // Remove all obs resource links.
                // Do it from back to front to keep the match indices from becoming obsolete when you add to the text.
                MatchCollection globalResourceMatches = findResourcesRegexp.Matches(reportText);
                foreach (Match resourceMatch in globalResourceMatches.Cast <Match>().Reverse())
                {
                    reportText = reportText.Replace(resourceMatch.Index, resourceMatch.Length + 1, "");
                }
            }

            obsSession.ReportText = reportText;

            return(observationsDict);
        }