Пример #1
0
        public virtual GroupForArtist AddMember(Artist member)
        {
            ParamIs.NotNull(() => member);

            return(member.AddGroup(this));
        }
Пример #2
0
        public static bool CanEditAdditionalPermissions(IUserPermissionContext permissionContext)
        {
            ParamIs.NotNull(() => permissionContext);

            return(permissionContext.UserGroupId == UserGroupId.Admin);
        }
Пример #3
0
        public PictureData(PictureDataContract contract)
        {
            ParamIs.NotNull(() => contract);

            Bytes = contract.Bytes;
        }
Пример #4
0
        public int UpdateSeries(ReleaseEventSeriesForEditContract contract, EntryPictureFileContract pictureData)
        {
            ParamIs.NotNull(() => contract);

            PermissionContext.VerifyPermission(PermissionToken.ManageEventSeries);

            return(HandleTransaction(session => {
                ReleaseEventSeries series;

                if (contract.Id == 0)
                {
                    series = new ReleaseEventSeries(contract.Name, contract.Description, contract.Aliases);
                    session.Save(series);

                    var diff = new ReleaseEventSeriesDiff(ReleaseEventSeriesEditableFields.Name);

                    diff.Description.Set(!string.IsNullOrEmpty(contract.Description));
                    diff.Names.Set(contract.Aliases.Any());

                    var weblinksDiff = WebLink.Sync(series.WebLinks, contract.WebLinks, series);

                    if (weblinksDiff.Changed)
                    {
                        diff.WebLinks.Set();
                        session.OfType <ReleaseEventWebLink>().Sync(weblinksDiff);
                    }

                    if (pictureData != null)
                    {
                        diff.Picture.Set();
                        SaveImage(series, pictureData);
                        session.Update(series);
                    }

                    session.Update(series);

                    Archive(session, series, diff, EntryEditEvent.Created, string.Empty);

                    AuditLog(string.Format("created {0}", entryLinkFactory.CreateEntryLink(series)), session);
                }
                else
                {
                    series = session.Load <ReleaseEventSeries>(contract.Id);
                    var diff = new ReleaseEventSeriesDiff(ReleaseEventSeriesEditableFields.Name);

                    if (series.Name != contract.Name)
                    {
                        diff.Name.Set();
                        series.Name = contract.Name;
                    }

                    if (series.Description != contract.Description)
                    {
                        diff.Description.Set();
                        series.Description = contract.Description;
                    }

                    if (series.UpdateAliases(contract.Aliases))
                    {
                        diff.Names.Set();
                    }

                    if (pictureData != null)
                    {
                        diff.Picture.Set();
                        SaveImage(series, pictureData);
                    }

                    var weblinksDiff = WebLink.Sync(series.WebLinks, contract.WebLinks, series);

                    if (weblinksDiff.Changed)
                    {
                        diff.WebLinks.Set();
                        session.OfType <ReleaseEventWebLink>().Sync(weblinksDiff);
                    }

                    session.Update(series);

                    Archive(session, series, diff, EntryEditEvent.Updated, string.Empty);

                    AuditLog(string.Format("updated {0}", entryLinkFactory.CreateEntryLink(series)), session);
                }

                return series.Id;
            }));
        }
Пример #5
0
        public bool CreateReport <TEntry, TReport, TReportType>(IDatabaseContext <TEntry> ctx,
                                                                IUserPermissionContext permissionContext,
                                                                IEntryLinkFactory entryLinkFactory,
                                                                Expression <Func <TReport, bool> > addExistingEntryFunc,
                                                                Func <TEntry, User, string, TReport> reportFunc,
                                                                Func <string> reportNameFunc,
                                                                int entryId, TReportType reportType, string hostname, string notes)
            where TEntry : IEntryWithVersions
            where TReport : EntryReport
        {
            ParamIs.NotNull(() => hostname);
            ParamIs.NotNull(() => notes);

            var msg = string.Format("creating report for {0} [{1}] as {2}", typeof(TEntry).Name, entryId, reportType);

            ctx.AuditLogger.SysLog(msg, hostname);

            var loggedUserId = permissionContext.LoggedUserId;
            var existing     = ctx.Query <TReport>()
                               .Where(addExistingEntryFunc)
                               .Where(r => (loggedUserId != 0 && r.User.Id == loggedUserId) || r.Hostname == hostname)
                               .FirstOrDefault();

            if (existing != null && !permissionContext.IsLoggedIn)
            {
                return(false);
            }

            var entry    = ctx.Load(entryId);
            var reporter = ctx.OfType <User>().GetLoggedUserOrNull(permissionContext);
            var report   = reportFunc(entry, reporter, notes.Truncate(EntryReport.MaxNotesLength));

            // Reported version. If a specific version was reported the author is already defined.
            var versionForReport = report.VersionBase;

            if (versionForReport == null)
            {
                // Get first version, check if all following edits were made by the same user OR the reporter
                var firstVersion = entry.ArchivedVersionsManager.VersionsBase.FirstOrDefault(
                    ver => ver.Author != null && !ver.Author.Equals(reporter));

                var oneEditor = firstVersion != null && firstVersion.Author != null &&
                                entry.ArchivedVersionsManager.VersionsBase.All(ver =>
                                                                               Equals(ver.Author, reporter) ||          // Editor is reporter
                                                                               firstVersion.Author.Equals(ver.Author)); // Editor is the creator

                if (oneEditor)
                {
                    versionForReport = firstVersion;                     // TODO: need to include report type in notification
                }
            }

            // Get translated report type name
            string reportName = null;

            if (versionForReport != null && versionForReport.Author != null)
            {
                using (new ImpersonateUICulture(CultureHelper.GetCultureOrDefault(versionForReport.Author.LanguageOrLastLoginCulture))) {
                    reportName = reportNameFunc();
                }
            }

            new EntryReportNotifier().SendReportNotification(ctx.OfType <UserMessage>(), versionForReport, notes, entryLinkFactory, reportName);

            if (existing != null)
            {
                return(false);
            }

            msg = string.Format("reported {0} as {1} ({2})", entryLinkFactory.CreateEntryLink(entry), reportType, HttpUtility.HtmlEncode(notes));
            ctx.AuditLogger.AuditLog(msg.Truncate(200), new AgentLoginData(reporter, hostname));

            ctx.Save(report);
            return(true);
        }
Пример #6
0
        public SongContract Create(CreateSongContract contract)
        {
            ParamIs.NotNull(() => contract);

            if (contract.Names == null || !contract.Names.Any())
            {
                throw new ArgumentException("Song needs at least one name", nameof(contract));
            }

            VerifyManageDatabase();

            return(repository.HandleTransaction(ctx => {
                var pvResult = ParsePV(ctx.OfType <PVForSong>(), contract.PVUrl);
                var reprintPvResult = ParsePV(ctx.OfType <PVForSong>(), contract.ReprintPVUrl);

                ctx.AuditLogger.SysLog(string.Format("creating a new song with name '{0}'", contract.Names.First().Value));

                var diff = new SongDiff();
                diff.Names.Set();
                var song = new Song {
                    SongType = contract.SongType
                };

                if (contract.OriginalVersion != null && contract.OriginalVersion.Id != 0)
                {
                    song.OriginalVersion = ctx.Load(contract.OriginalVersion.Id);
                    diff.OriginalVersion.Set();
                }

                song.Names.Init(contract.Names, song);

                ctx.Save(song);

                foreach (var artistContract in contract.Artists)
                {
                    if (artistContract.Artist != null)
                    {
                        var artist = ctx.OfType <Artist>().Load(artistContract.Artist.Id);
                        if (!song.HasArtist(artist))
                        {
                            ctx.OfType <ArtistForSong>().Save(song.AddArtist(artist, artistContract.IsSupport, artistContract.Roles));
                        }
                    }
                    else
                    {
                        ctx.OfType <ArtistForSong>().Save(song.AddArtist(artistContract.Name, artistContract.IsSupport, artistContract.Roles));
                    }
                }

                diff.Artists.Set(contract.Artists.Any());

                var pvs = new List <PVContract>();
                Tag[] addedTags = null;

                if (pvResult != null)
                {
                    pvs.Add(new PVContract(pvResult, PVType.Original));

                    addedTags = AddTagsFromPV(pvResult, song, ctx);
                }

                if (reprintPvResult != null)
                {
                    pvs.Add(new PVContract(reprintPvResult, PVType.Reprint));
                }

                var pvDiff = song.SyncPVs(pvs);
                ctx.OfType <PVForSong>().Sync(pvDiff);
                diff.PVs.Set(pvs.Any());

                if (contract.WebLinks != null)
                {
                    var weblinksDiff = ctx.Sync(WebLink.Sync(song.WebLinks, contract.WebLinks, song));
                    diff.WebLinks.Set(weblinksDiff.Changed);
                }

                if (contract.Lyrics != null && contract.Lyrics.Any())
                {
                    contract.Lyrics.ForEach(song.CreateLyrics);
                    diff.Lyrics.Set();
                }

                song.Status = (contract.Draft || !(new SongValidator().IsValid(song, config.SpecialTags.Instrumental))) ? EntryStatus.Draft : EntryStatus.Finished;

                song.UpdateArtistString();

                var archived = Archive(ctx, song, diff, SongArchiveReason.Created, contract.UpdateNotes ?? string.Empty);
                ctx.Update(song);

                var logStr = string.Format("created song {0} of type {1} ({2})", entryLinkFactory.CreateEntryLink(song), song.SongType, diff.ChangedFieldsString)
                             + (!string.IsNullOrEmpty(contract.UpdateNotes) ? " " + HttpUtility.HtmlEncode(contract.UpdateNotes) : string.Empty)
                             .Truncate(400);

                ctx.AuditLogger.AuditLog(logStr);
                AddEntryEditedEntry(ctx.OfType <ActivityEntry>(), song, EntryEditEvent.Created, archived);

                var user = PermissionContext.LoggedUser;

                // Send notifications. Avoid sending notification to the same users twice.
                var notifiedUsers = new FollowedArtistNotifier().SendNotifications(ctx, song, song.ArtistList, user, entryLinkFactory, mailer, enumTranslations);

                if (addedTags != null && addedTags.Length > 0)
                {
                    new FollowedTagNotifier().SendNotifications(ctx, song, addedTags, notifiedUsers.Select(u => u.Id).Concat(new[] { user.Id }).ToArray(), entryLinkFactory, enumTranslations);
                }

                return new SongContract(song, PermissionContext.LanguagePreference);
            }));
        }
Пример #7
0
        public int UpdateSongList(SongListForEditContract contract, UploadedFileContract uploadedFile)
        {
            ParamIs.NotNull(() => contract);

            PermissionContext.VerifyPermission(PermissionToken.EditProfile);

            return(repository.HandleTransaction(ctx => {
                var user = GetLoggedUser(ctx);
                SongList list;

                if (contract.Id == 0)
                {
                    list = CreateSongList(ctx, contract, uploadedFile);
                }
                else
                {
                    list = ctx.Load(contract.Id);
                    var diff = new SongListDiff();

                    EntryPermissionManager.VerifyEdit(PermissionContext, list);

                    if (list.Description != contract.Description)
                    {
                        diff.Description.Set();
                        list.Description = contract.Description ?? string.Empty;
                    }

                    if (list.Name != contract.Name)
                    {
                        diff.Name.Set();
                        list.Name = contract.Name;
                    }

                    if (EntryPermissionManager.CanManageFeaturedLists(PermissionContext) && list.FeaturedCategory != contract.FeaturedCategory)
                    {
                        diff.FeaturedCategory.Set();
                        list.FeaturedCategory = contract.FeaturedCategory;
                    }

                    if (list.EventDate != contract.EventDate)
                    {
                        diff.SetChanged(SongListEditableFields.EventDate);
                        list.EventDate = contract.EventDate;
                    }

                    if (list.Status != contract.Status)
                    {
                        diff.Status.Set();
                        list.Status = contract.Status;
                    }

                    var songDiff = list.SyncSongs(contract.SongLinks, c => ctx.OfType <Song>().Load(c.Song.Id));

                    if (songDiff.Changed)
                    {
                        diff.Songs.Set();
                    }

                    ctx.OfType <SongInList>().Sync(songDiff);

                    if (uploadedFile != null)
                    {
                        diff.Thumbnail.Set();
                        SetThumb(list, uploadedFile);
                    }

                    ctx.Update(list);

                    ctx.AuditLogger.AuditLog(
                        string.Format("updated song list {0} ({1})", entryLinkFactory.CreateEntryLink(list), diff.ChangedFieldsString), user);

                    var archived = Archive(ctx, list, diff, EntryEditEvent.Updated, contract.UpdateNotes);

                    if (list.FeaturedList)
                    {
                        AddEntryEditedEntry(ctx.OfType <ActivityEntry>(), list, EntryEditEvent.Updated, archived);
                    }
                }

                return list.Id;
            }));
        }
Пример #8
0
        public virtual bool HasSong(Song song)
        {
            ParamIs.NotNull(() => song);

            return(Songs.Any(a => a.Song.Equals(song)));
        }
Пример #9
0
        public virtual bool HasWebLink(string url)
        {
            ParamIs.NotNull(() => url);

            return(WebLinks.Any(w => w.Url == url));
        }
Пример #10
0
        public virtual bool HasName(LocalizedString name)
        {
            ParamIs.NotNull(() => name);

            return(Names.HasName(name));
        }
Пример #11
0
        public virtual bool HasOwnerUser(User user)
        {
            ParamIs.NotNull(() => user);

            return(OwnerUsers.Any(a => a.User.Equals(user)));
        }
Пример #12
0
        public virtual bool HasMember(Artist member)
        {
            ParamIs.NotNull(() => member);

            return(Members.Any(a => a.Member.Equals(member)));
        }
Пример #13
0
        public virtual bool HasGroup(Artist grp)
        {
            ParamIs.NotNull(() => grp);

            return(Groups.Any(a => a.Group.Equals(grp)));
        }
Пример #14
0
        /// <summary>
        /// Checks whether this artist has a specific album.
        /// </summary>
        /// <param name="album">Album to be checked. Cannot be null.</param>
        /// <returns>True if the artist has the album. Otherwise false.</returns>
        /// <remarks>
        /// Warning: This check can be slow if the artist has too many albums and the collection needs to be loaded.
        /// Most of the time the check should be done from the album side, since usually albums have fewer artist links than artist have linked albums.
        /// </remarks>
        public virtual bool HasAlbum(Album album)
        {
            ParamIs.NotNull(() => album);

            return(Albums.Any(a => a.Album.Equals(album)));
        }
Пример #15
0
        public static bool IsAjaxRequest(HttpRequest request)
        {
            ParamIs.NotNull(() => request);

            return(request["X-Requested-With"] == "XMLHttpRequest" || request.Headers["X-Requested-With"] == "XMLHttpRequest");
        }
Пример #16
0
        public bool CanEdit(IEntryWithStatus entry)
        {
            ParamIs.NotNull(() => entry);

            return(EntryPermissionManager.CanEdit(Manager, entry));
        }
Пример #17
0
        public int Update(VenueForEditContract contract)
        {
            ParamIs.NotNull(() => contract);

            PermissionContext.VerifyManageDatabase();

            return(HandleTransaction(ctx =>
            {
                Venue venue;

                if (contract.Id == 0)
                {
                    venue = new Venue(contract.DefaultNameLanguage, contract.Names, contract.Description)
                    {
                        Address = contract.Address,
                        AddressCountryCode = contract.AddressCountryCode,
                        Coordinates = (contract.Coordinates != null) ? new OptionalGeoPoint(contract.Coordinates) : new OptionalGeoPoint(),
                        Status = contract.Status
                    };
                    ctx.Save(venue);

                    var diff = new VenueDiff(VenueEditableFields.OriginalName | VenueEditableFields.Names);

                    diff.Address.Set(!string.IsNullOrEmpty(contract.Address));
                    diff.AddressCountryCode.Set(!string.IsNullOrEmpty(contract.AddressCountryCode));
                    diff.Description.Set(!string.IsNullOrEmpty(contract.Description));

                    if (contract.Coordinates != null)
                    {
                        diff.Coordinates.Set();
                    }

                    var webLinkDiff = venue.WebLinks.Sync(contract.WebLinks, venue);
                    ctx.OfType <VenueWebLink>().Sync(webLinkDiff);

                    if (webLinkDiff.Changed)
                    {
                        diff.WebLinks.Set();
                    }

                    ctx.Update(venue);

                    var archived = Archive(ctx, venue, diff, EntryEditEvent.Created, string.Empty);
                    AddEntryEditedEntry(ctx.OfType <ActivityEntry>(), venue, EntryEditEvent.Created, archived);

                    AuditLog($"created {_entryLinkFactory.CreateEntryLink(venue)}", ctx);
                }
                else
                {
                    venue = ctx.Load <Venue>(contract.Id);
                    _permissionContext.VerifyEntryEdit(venue);
                    var diff = new VenueDiff(DoSnapshot(venue, ctx));

                    if (venue.TranslatedName.DefaultLanguage != contract.DefaultNameLanguage)
                    {
                        venue.TranslatedName.DefaultLanguage = contract.DefaultNameLanguage;
                        diff.OriginalName.Set();
                    }

                    var nameDiff = venue.Names.Sync(contract.Names, venue);
                    ctx.Sync(nameDiff);

                    if (nameDiff.Changed)
                    {
                        diff.Names.Set();
                    }

                    if (venue.Address != contract.Address)
                    {
                        diff.Address.Set();
                        venue.Address = contract.Address;
                    }

                    if (venue.AddressCountryCode != contract.AddressCountryCode)
                    {
                        diff.AddressCountryCode.Set();
                        venue.AddressCountryCode = contract.AddressCountryCode;
                    }

                    if (venue.Description != contract.Description)
                    {
                        diff.Description.Set();
                        venue.Description = contract.Description;
                    }

                    if (!venue.Coordinates.Equals(contract.Coordinates))
                    {
                        diff.Coordinates.Set();
                        venue.Coordinates = (contract.Coordinates != null) ? new OptionalGeoPoint(contract.Coordinates) : new OptionalGeoPoint();
                    }

                    if (venue.Status != contract.Status)
                    {
                        diff.Status.Set();
                        venue.Status = contract.Status;
                    }

                    var webLinkDiff = venue.WebLinks.Sync(contract.WebLinks, venue);
                    ctx.OfType <VenueWebLink>().Sync(webLinkDiff);

                    if (webLinkDiff.Changed)
                    {
                        diff.WebLinks.Set();
                    }

                    ctx.Update(venue);

                    var archived = Archive(ctx, venue, diff, EntryEditEvent.Updated, string.Empty);
                    AddEntryEditedEntry(ctx.OfType <ActivityEntry>(), venue, EntryEditEvent.Updated, archived);

                    AuditLog($"updated {_entryLinkFactory.CreateEntryLink(venue)}", ctx);
                }

                return venue.Id;
            }));
        }
Пример #18
0
        public async Task <TagUsageForApiContract[]> AddTags <TEntry, TTag>(int entryId,
                                                                            TagBaseContract[] tags,
                                                                            bool onlyAdd,
                                                                            IRepository <User> repository,
                                                                            IEntryLinkFactory entryLinkFactory,
                                                                            IEnumTranslations enumTranslations,
                                                                            Func <TEntry, TagManager <TTag> > tagFunc,
                                                                            Func <TEntry, IDatabaseContext <TTag>, ITagUsageFactory <TTag> > tagUsageFactoryFactory)
            where TEntry : class, IEntryWithNames, IEntryWithTags
            where TTag : TagUsage
        {
            ParamIs.NotNull(() => tags);

            _permissionContext.VerifyPermission(PermissionToken.EditTags);

            tags = tags.Where(IsValid).ToArray();

            if (onlyAdd && !tags.Any())
            {
                return(new TagUsageForApiContract[0]);
            }

            return(await repository.HandleTransactionAsync(async ctx =>
            {
                // Tags are primarily added by Id, secondarily by translated name.
                // First separate given tags for tag IDs and tag names
                var tagIds = tags.Where(HasId).Select(t => t.Id).ToArray();
                var translatedTagNames = tags.Where(t => !HasId(t) && !string.IsNullOrEmpty(t.Name)).Select(t => t.Name).ToArray();

                // Load existing tags by name and ID.
                var tagsFromIds = await ctx.Query <Tag>().Where(t => tagIds.Contains(t.Id)).VdbToListAsync();

                var tagsFromNames = await ctx.Query <Tag>().WhereHasName(translatedTagNames).VdbToListAsync();

                // Figure out tags that don't exist yet (no ID and no matching name).
                var newTagNames = translatedTagNames.Except(tagsFromNames.SelectMany(t => t.Names.AllValues), StringComparer.InvariantCultureIgnoreCase).ToArray();

                var user = await ctx.OfType <User>().GetLoggedUserAsync(_permissionContext);
                var tagFactory = new TagFactoryRepository(ctx.OfType <Tag>(), new AgentLoginData(user));
                var newTags = await tagFactory.CreateTagsAsync(newTagNames);

                var entry = await ctx.LoadAsync <TEntry>(entryId);

                // Get the final list of tag names with translations
                var appliedTags = tagsFromNames
                                  .Concat(tagsFromIds)
                                  .Where(t => _permissionContext.HasPermission(PermissionToken.ApplyAnyTag) || t.IsValidFor(entry.EntryType))
                                  .Concat(newTags)
                                  .Distinct()
                                  .ToArray();

                var tagUsageFactory = tagUsageFactoryFactory(entry, ctx.OfType <TTag>());

                var tagNames = appliedTags.Select(t => t.DefaultName);
                await ctx.AuditLogger.AuditLogAsync($"tagging {entryLinkFactory.CreateEntryLink(entry)} with {string.Join(", ", tagNames)}", user);

                var addedTags = appliedTags.Except(entry.Tags.Tags).ToArray();

                if (entry.AllowNotifications)
                {
                    await new FollowedTagNotifier().SendNotificationsAsync(ctx, entry, addedTags, new[] { user.Id }, entryLinkFactory, enumTranslations);
                }

                var updatedTags = tagFunc(entry).SyncVotes(user, appliedTags, tagUsageFactory, onlyAdd: onlyAdd);
                var tagCtx = ctx.OfType <Tag>();

                foreach (var tag in updatedTags)
                {
                    await tagCtx.UpdateAsync(tag);
                }

                RecomputeTagUsagesCounts(tagCtx, updatedTags);

                ctx.AuditLogger.SysLog("finished tagging");

                return tagFunc(entry).ActiveUsages.Select(t => new TagUsageForApiContract(t, _permissionContext.LanguagePreference)).ToArray();
            }));
        }
Пример #19
0
        public SongForEditContract UpdateBasicProperties(SongForEditContract properties)
        {
            ParamIs.NotNull(() => properties);

            VerifyManageDatabase();

            return(repository.HandleTransaction(ctx => {
                var song = ctx.Load(properties.Id);

                VerifyEntryEdit(song);

                var diff = new SongDiff(DoSnapshot(song.GetLatestVersion(), ctx.OfType <User>().GetLoggedUser(PermissionContext)));

                ctx.AuditLogger.SysLog(string.Format("updating properties for {0}", song));

                var oldPvCount = song.PVs.OfType(PVType.Original).Count();
                diff.Notes.Set(song.Notes.CopyFrom(properties.Notes));

                var newOriginalVersion = (properties.OriginalVersion != null && properties.OriginalVersion.Id != 0 ? ctx.Load(properties.OriginalVersion.Id) : null);

                if (!Equals(song.OriginalVersion, newOriginalVersion))
                {
                    song.SetOriginalVersion(newOriginalVersion);
                    diff.OriginalVersion.Set();
                }

                if (song.SongType != properties.SongType)
                {
                    diff.SongType.Set();
                    song.SongType = properties.SongType;
                }

                if (song.LengthSeconds != properties.LengthSeconds)
                {
                    diff.Length.Set();
                    song.LengthSeconds = properties.LengthSeconds;
                }

                if (song.TranslatedName.DefaultLanguage != properties.DefaultNameLanguage)
                {
                    song.TranslatedName.DefaultLanguage = properties.DefaultNameLanguage;
                    diff.OriginalName.Set();
                }

                var nameDiff = song.Names.Sync(properties.Names, song);
                ctx.OfType <SongName>().Sync(nameDiff);

                if (nameDiff.Changed)
                {
                    diff.Names.Set();
                }

                var webLinkDiff = WebLink.Sync(song.WebLinks, properties.WebLinks, song);
                ctx.OfType <SongWebLink>().Sync(webLinkDiff);

                if (webLinkDiff.Changed)
                {
                    diff.WebLinks.Set();
                }

                if (song.Status != properties.Status)
                {
                    song.Status = properties.Status;
                    diff.Status.Set();
                }

                var artistGetter = new Func <ArtistForSongContract, Artist>(artistForSong =>
                                                                            ctx.OfType <Artist>().Load(artistForSong.Artist.Id));

                var artistsDiff = song.SyncArtists(properties.Artists, artistGetter);
                ctx.OfType <ArtistForSong>().Sync(artistsDiff);

                if (artistsDiff.Changed)
                {
                    diff.Artists.Set();
                }

                var newEvent = new CreateEventQuery().FindOrCreate(ctx, PermissionContext, properties.ReleaseEvent, song);
                if (!song.ReleaseEvent.NullSafeIdEquals(newEvent))
                {
                    diff.ReleaseEvent.Set();
                    song.SetReleaseEvent(newEvent);
                }

                if (!song.PublishDate.Equals(properties.PublishDate))
                {
                    song.PublishDate = properties.PublishDate;
                    diff.PublishDate.Set();
                }

                UpdatePVs(ctx, song, diff, properties.PVs);

                var lyricsDiff = song.SyncLyrics(properties.Lyrics);
                ctx.OfType <LyricsForSong>().Sync(lyricsDiff);

                if (lyricsDiff.Changed)
                {
                    diff.Lyrics.Set();
                }

                var logStr = string.Format("updated properties for song {0} ({1})", entryLinkFactory.CreateEntryLink(song), diff.ChangedFieldsString)
                             + (properties.UpdateNotes != string.Empty ? " " + HttpUtility.HtmlEncode(properties.UpdateNotes) : string.Empty)
                             .Truncate(400);

                var archived = Archive(ctx, song, diff, SongArchiveReason.PropertiesUpdated, properties.UpdateNotes);
                ctx.Update(song);

                ctx.AuditLogger.AuditLog(logStr);
                AddEntryEditedEntry(ctx.OfType <ActivityEntry>(), song, EntryEditEvent.Updated, archived);

                var newPVCutoff = TimeSpan.FromDays(7);
                if (oldPvCount == 0 && song.PVs.OfType(PVType.Original).Any() && song.CreateDate <= DateTime.Now - newPVCutoff)
                {
                    new FollowedArtistNotifier().SendNotifications(ctx, song, song.ArtistList, PermissionContext.LoggedUser, entryLinkFactory, mailer, enumTranslations);
                }

                var newSongCutoff = TimeSpan.FromHours(1);
                if (artistsDiff.Added.Any() && song.CreateDate >= DateTime.Now - newSongCutoff)
                {
                    var addedArtists = artistsDiff.Added.Where(a => a.Artist != null).Select(a => a.Artist).Distinct().ToArray();

                    if (addedArtists.Any())
                    {
                        new FollowedArtistNotifier().SendNotifications(ctx, song, addedArtists, PermissionContext.LoggedUser, entryLinkFactory, mailer, enumTranslations);
                    }
                }

                return new SongForEditContract(song, PermissionContext.LanguagePreference);
            }));
        }
Пример #20
0
        public int Update(ArtistForEditContract properties, EntryPictureFileContract pictureData, IUserPermissionContext permissionContext)
        {
            ParamIs.NotNull(() => properties);
            ParamIs.NotNull(() => permissionContext);

            return(repository.HandleTransaction(ctx => {
                var artist = ctx.Load(properties.Id);

                VerifyEntryEdit(artist);

                var diff = new ArtistDiff(DoSnapshot(artist.GetLatestVersion(), ctx.OfType <User>().GetLoggedUser(permissionContext)));

                ctx.AuditLogger.SysLog(string.Format("updating properties for {0}", artist));

                if (artist.ArtistType != properties.ArtistType)
                {
                    artist.ArtistType = properties.ArtistType;
                    diff.ArtistType = true;
                }

                if (artist.Description != properties.Description)
                {
                    artist.Description = properties.Description;
                    diff.Description = true;
                }

                if (artist.TranslatedName.DefaultLanguage != properties.DefaultNameLanguage)
                {
                    artist.TranslatedName.DefaultLanguage = properties.DefaultNameLanguage;
                    diff.OriginalName = true;
                }

                // Required because of a bug in NHibernate
                NHibernateUtil.Initialize(artist.Picture);

                if (pictureData != null)
                {
                    var parsed = ImageHelper.GetOriginal(pictureData.UploadedFile, pictureData.ContentLength, pictureData.Mime);
                    artist.Picture = new PictureData(parsed);
                    artist.PictureMime = parsed.Mime;

                    pictureData.Id = artist.Id;
                    pictureData.EntryType = EntryType.Artist;
                    var thumbGenerator = new ImageThumbGenerator(imagePersister);
                    thumbGenerator.GenerateThumbsAndMoveImage(pictureData.UploadedFile, pictureData, ImageSizes.Thumb | ImageSizes.SmallThumb | ImageSizes.TinyThumb);

                    diff.Picture = true;
                }

                if (artist.Status != properties.Status)
                {
                    artist.Status = properties.Status;
                    diff.Status = true;
                }

                var nameDiff = artist.Names.Sync(properties.Names, artist);
                ctx.OfType <ArtistName>().Sync(nameDiff);

                if (nameDiff.Changed)
                {
                    diff.Names = true;
                }

                if (!artist.BaseVoicebank.NullSafeIdEquals(properties.BaseVoicebank))
                {
                    var newBase = ctx.NullSafeLoad(properties.BaseVoicebank);

                    if (artist.IsValidBaseVoicebank(newBase))
                    {
                        diff.BaseVoicebank = true;
                        artist.SetBaseVoicebank(ctx.NullSafeLoad(properties.BaseVoicebank));
                    }
                }

                var validWebLinks = properties.WebLinks.Where(w => !string.IsNullOrEmpty(w.Url));
                var webLinkDiff = WebLink.Sync(artist.WebLinks, validWebLinks, artist);
                ctx.OfType <ArtistWebLink>().Sync(webLinkDiff);

                if (webLinkDiff.Changed)
                {
                    diff.WebLinks = true;
                }

                if (diff.ArtistType || diff.Names)
                {
                    foreach (var song in artist.Songs)
                    {
                        song.Song.UpdateArtistString();
                        ctx.Update(song);
                    }
                }

                var groupsDiff = CollectionHelper.Diff(artist.Groups, properties.Groups, (i, i2) => (i.Id == i2.Id));

                foreach (var grp in groupsDiff.Removed)
                {
                    grp.Delete();
                    ctx.Delete(grp);
                }

                foreach (var grp in groupsDiff.Added)
                {
                    var link = artist.AddGroup(ctx.Load(grp.Group.Id));
                    ctx.Save(link);
                }

                if (groupsDiff.Changed)
                {
                    diff.Groups = true;
                }

                var picsDiff = artist.Pictures.SyncPictures(properties.Pictures, ctx.OfType <User>().GetLoggedUser(permissionContext), artist.CreatePicture);
                ctx.OfType <ArtistPictureFile>().Sync(picsDiff);
                ImageHelper.GenerateThumbsAndMoveImages(picsDiff.Added);

                if (picsDiff.Changed)
                {
                    diff.Pictures = true;
                }

                var logStr = string.Format("updated properties for artist {0} ({1})", entryLinkFactory.CreateEntryLink(artist), diff.ChangedFieldsString)
                             + (properties.UpdateNotes != string.Empty ? " " + properties.UpdateNotes : string.Empty)
                             .Truncate(400);

                ctx.AuditLogger.AuditLog(logStr);
                AddEntryEditedEntry(ctx.OfType <ActivityEntry>(), artist, EntryEditEvent.Updated);

                Archive(ctx, artist, diff, ArtistArchiveReason.PropertiesUpdated, properties.UpdateNotes);
                ctx.Update(artist);

                return artist.Id;
            }));
        }
Пример #21
0
        /// <summary>
        /// Updates or creates release event.
        ///
        /// Album release event names will be updated as well if the name changed.
        /// </summary>
        /// <param name="contract">Updated contract. Cannot be null.</param>
        /// <returns>Updated release event data. Cannot be null.</returns>
        public ReleaseEventContract Update(ReleaseEventDetailsContract contract)
        {
            ParamIs.NotNull(() => contract);

            PermissionContext.VerifyManageDatabase();

            return(repository.HandleTransaction(session => {
                ReleaseEvent ev;

                if (contract.Id == 0)
                {
                    var diff = new ReleaseEventDiff();

                    if (!contract.Series.IsNullOrDefault())
                    {
                        var series = session.OfType <ReleaseEventSeries>().Load(contract.Series.Id);
                        ev = new ReleaseEvent(contract.Description, contract.Date, series, contract.SeriesNumber, contract.SeriesSuffix,
                                              contract.Name, contract.CustomName);
                        series.Events.Add(ev);
                    }
                    else
                    {
                        ev = new ReleaseEvent(contract.Description, contract.Date, contract.Name);
                    }

                    var weblinksDiff = WebLink.Sync(ev.WebLinks, contract.WebLinks, ev);

                    if (weblinksDiff.Changed)
                    {
                        diff.WebLinks.Set();
                    }

                    CheckDuplicateName(session, ev);

                    session.Save(ev);

                    var archived = Archive(session, ev, diff, EntryEditEvent.Created, string.Empty);
                    AddEntryEditedEntry(session.OfType <ActivityEntry>(), archived);

                    session.AuditLogger.AuditLog(string.Format("created {0}", entryLinkFactory.CreateEntryLink(ev)));
                }
                else
                {
                    ev = session.Load(contract.Id);
                    var diff = new ReleaseEventDiff(DoSnapshot(ev, session));

                    if (!ev.Date.Equals(contract.Date))
                    {
                        diff.Date.Set();
                    }

                    if (ev.Description != contract.Description)
                    {
                        diff.Description.Set();
                    }

                    if (ev.Name != contract.Name && (contract.Series == null || contract.CustomName))
                    {
                        diff.Name.Set();
                    }

                    if (!ev.Series.NullSafeIdEquals(contract.Series))
                    {
                        diff.Series.Set();
                    }

                    if (ev.SeriesNumber != contract.SeriesNumber)
                    {
                        diff.SeriesNumber.Set();
                    }

                    if (ev.SeriesSuffix != contract.SeriesSuffix)
                    {
                        diff.SeriesSuffix.Set();
                    }

                    var oldName = ev.Name;

                    ev.Series = session.OfType <ReleaseEventSeries>().NullSafeLoad(contract.Series);
                    ev.CustomName = contract.CustomName;
                    ev.Date = contract.Date;
                    ev.Description = contract.Description;
                    ev.Name = contract.Name;
                    ev.SeriesNumber = contract.SeriesNumber;
                    ev.SeriesSuffix = contract.SeriesSuffix;
                    ev.UpdateNameFromSeries();

                    var weblinksDiff = WebLink.Sync(ev.WebLinks, contract.WebLinks, ev);

                    if (weblinksDiff.Changed)
                    {
                        diff.WebLinks.Set();
                        session.OfType <ReleaseEventWebLink>().Sync(weblinksDiff);
                    }

                    CheckDuplicateName(session, ev);

                    session.Update(ev);

                    var archived = Archive(session, ev, diff, EntryEditEvent.Updated, string.Empty);
                    AddEntryEditedEntry(session.OfType <ActivityEntry>(), archived);

                    var logStr = string.Format("updated properties for {0} ({1})", entryLinkFactory.CreateEntryLink(ev), diff.ChangedFieldsString);
                    session.AuditLogger.AuditLog(logStr);
                }

                return new ReleaseEventContract(ev);
            }));
        }
Пример #22
0
        public virtual bool HasVoteByUser(User user)
        {
            ParamIs.NotNull(() => user);

            return(VotesBase.Any(v => v.User.Equals(user)));
        }
Пример #23
0
        public ArtistForSongContract(ArtistContract artistContract)
        {
            ParamIs.NotNull(() => artistContract);

            Artist = artistContract;
        }
Пример #24
0
        public SongDetails(SongDetailsContract contract, IUserPermissionContext userContext)
        {
            ParamIs.NotNull(() => contract);

            Contract                   = contract;
            AdditionalNames            = contract.AdditionalNames;
            Albums                     = contract.Albums;
            AlternateVersions          = contract.AlternateVersions.Where(a => a.SongType != SongType.Original).ToArray();
            ArtistString               = contract.ArtistString;
            CanEdit                    = EntryPermissionManager.CanEdit(userContext, contract.Song);
            CanEditPersonalDescription = contract.CanEditPersonalDescription;
            CanRemoveTagUsages         = contract.CanRemoveTagUsages;
            CommentCount               = contract.CommentCount;
            CreateDate                 = contract.CreateDate;
            DefaultLanguageSelection   = contract.TranslatedName.DefaultLanguage;
            Deleted                    = contract.Deleted;
            Draft                     = contract.Song.Status == EntryStatus.Draft;
            FavoritedTimes            = contract.Song.FavoritedTimes;
            Hits                      = contract.Hits;
            Id                        = contract.Song.Id;
            IsFavorited               = contract.UserRating != SongVoteRating.Nothing;
            LatestComments            = contract.LatestComments;
            Length                    = contract.Song.LengthSeconds;
            LikedTimes                = contract.LikeCount;
            ListCount                 = contract.ListCount;
            Lyrics                    = contract.LyricsFromParents;
            MergedTo                  = contract.MergedTo;
            Name                      = contract.Song.Name;
            NicoId                    = contract.Song.NicoId;
            Notes                     = contract.Notes;
            OriginalVersion           = (contract.Song.SongType != SongType.Original ? contract.OriginalVersion : null);
            Pools                     = contract.Pools;
            PublishDate               = contract.Song.PublishDate;
            RatingScore               = contract.Song.RatingScore;
            ReleaseEvent              = contract.ReleaseEvent;
            PersonalDescriptionText   = contract.PersonalDescriptionText;
            PersonalDescriptionAuthor = contract.PersonalDescriptionAuthor;
            SongType                  = contract.Song.SongType;
            Status                    = contract.Song.Status;
            Suggestions               = contract.Suggestions;
            Tags                      = contract.Tags;
            UserRating                = contract.UserRating;
            WebLinks                  = contract.WebLinks.ToList();

            Animators    = contract.Artists.Where(a => a.Categories.HasFlag(ArtistCategories.Animator)).ToArray();
            Bands        = contract.Artists.Where(a => a.Categories.HasFlag(ArtistCategories.Band)).ToArray();
            Performers   = contract.Artists.Where(a => a.Categories.HasFlag(ArtistCategories.Vocalist)).ToArray();
            Producers    = contract.Artists.Where(a => a.Categories.HasFlag(ArtistCategories.Producer)).ToArray();
            OtherArtists = contract.Artists.Where(a => a.Categories.HasFlag(ArtistCategories.Circle) ||
                                                  a.Categories.HasFlag(ArtistCategories.Label) ||
                                                  a.Categories.HasFlag(ArtistCategories.Other)).ToArray();

            var pvs = contract.PVs;

            OriginalPVs     = pvs.Where(p => p.PVType == PVType.Original).ToArray();
            OtherPVs        = pvs.Where(p => p.PVType != PVType.Original).ToArray();
            PrimaryPV       = PVHelper.PrimaryPV(pvs);
            ThumbUrl        = VideoServiceHelper.GetThumbUrlPreferNotNico(pvs);
            ThumbUrlMaxSize = VideoServiceHelper.GetMaxSizeThumbUrl(pvs) ?? ThumbUrl;

            if (PrimaryPV == null && !string.IsNullOrEmpty(NicoId))
            {
                PrimaryPV = new PVContract {
                    PVId = NicoId, Service = PVService.NicoNicoDouga
                }
            }
            ;

            if (pvs.All(p => p.Service != PVService.Youtube))
            {
                var nicoPV = VideoServiceHelper.PrimaryPV(pvs, PVService.NicoNicoDouga);
                var query  = HttpUtility.UrlEncode((nicoPV != null && !string.IsNullOrEmpty(nicoPV.Name))
                                        ? nicoPV.Name
                                        : string.Format("{0} {1}", ArtistString, Name));

                WebLinks.Add(new WebLinkContract(string.Format("http://www.youtube.com/results?search_query={0}", query),
                                                 ViewRes.Song.DetailsStrings.SearchYoutube, WebLinkCategory.Other));
            }

            Json = JsonHelpers.Serialize(new SongDetailsAjax(this, contract.PreferredLyrics, contract.Song.Version));
        }
Пример #25
0
        public static bool CanEditUser(IUserPermissionContext permissionContext, UserGroupId groupId)
        {
            ParamIs.NotNull(() => permissionContext);

            return(CanEditGroupTo(permissionContext, groupId));
        }
Пример #26
0
        public static OptionalDateTime Create(IOptionalDateTime contract)
        {
            ParamIs.NotNull(() => contract);

            return(new OptionalDateTime(contract.Year, contract.Month, contract.Day));
        }
Пример #27
0
        public static bool CanEditGroupTo(IUserPermissionContext permissionContext, UserGroupId groupId)
        {
            ParamIs.NotNull(() => permissionContext);

            return(permissionContext.UserGroupId == UserGroupId.Admin || permissionContext.UserGroupId > groupId);
        }
Пример #28
0
        public SongDetails(SongDetailsContract contract)
        {
            ParamIs.NotNull(() => contract);

            AdditionalNames   = contract.AdditionalNames;
            Albums            = contract.Albums;
            AlternateVersions = contract.AlternateVersions.Where(a => a.SongType != SongType.Original).ToArray();
            ArtistString      = contract.ArtistString;
            CanEdit           = EntryPermissionManager.CanEdit(MvcApplication.LoginManager, contract.Song);
            CommentCount      = contract.CommentCount;
            CreateDate        = contract.CreateDate;
            Deleted           = contract.Deleted;
            Draft             = contract.Song.Status == EntryStatus.Draft;
            FavoritedTimes    = contract.Song.FavoritedTimes;
            Hits            = contract.Hits;
            Id              = contract.Song.Id;
            IsFavorited     = contract.UserRating != SongVoteRating.Nothing;
            LatestComments  = contract.LatestComments;
            LikedTimes      = contract.LikeCount;
            Lyrics          = contract.LyricsFromParents;
            Name            = contract.Song.Name;
            NicoId          = contract.Song.NicoId;
            Notes           = contract.Notes;
            OriginalVersion = (contract.Song.SongType != SongType.Original ? contract.OriginalVersion : null);
            Pools           = contract.Pools;
            RatingScore     = contract.Song.RatingScore;
            SongType        = contract.Song.SongType;
            Status          = contract.Song.Status;
            Tags            = contract.Tags;
            UserRating      = contract.UserRating;
            WebLinks        = contract.WebLinks.ToList();

            Animators    = contract.Artists.Where(a => a.Categories.HasFlag(ArtistCategories.Animator)).ToArray();
            Performers   = contract.Artists.Where(a => a.Categories.HasFlag(ArtistCategories.Vocalist)).ToArray();
            Producers    = contract.Artists.Where(a => a.Categories.HasFlag(ArtistCategories.Producer)).ToArray();
            OtherArtists = contract.Artists.Where(a => a.Categories.HasFlag(ArtistCategories.Circle) ||
                                                  a.Categories.HasFlag(ArtistCategories.Label) ||
                                                  a.Categories.HasFlag(ArtistCategories.Other)).ToArray();

            var pvs = contract.PVs;

            OriginalPVs = pvs.Where(p => p.PVType == PVType.Original).ToArray();
            OtherPVs    = pvs.Where(p => p.PVType != PVType.Original).ToArray();
            PrimaryPV   = PVHelper.PrimaryPV(pvs);

            if (PrimaryPV == null && !string.IsNullOrEmpty(NicoId))
            {
                PrimaryPV = new PVContract {
                    PVId = NicoId, Service = PVService.NicoNicoDouga
                }
            }
            ;

            var nicoPvId = PVHelper.GetNicoId(pvs, NicoId);

            if (!string.IsNullOrEmpty(nicoPvId))
            {
                WebLinks.Add(new WebLinkContract(VideoServiceUrlFactory.NicoSound.CreateUrl(nicoPvId),
                                                 ViewRes.Song.DetailsStrings.CheckNicoSound, WebLinkCategory.Other));
            }

            if (pvs.All(p => p.Service != PVService.Youtube))
            {
                var nicoPV = VideoServiceHelper.PrimaryPV(pvs, PVService.NicoNicoDouga);
                var query  = (nicoPV != null && !string.IsNullOrEmpty(nicoPV.Name))
                                        ? nicoPV.Name
                                        : string.Format("{0} {1}", ArtistString, Name);

                WebLinks.Add(new WebLinkContract(string.Format("http://www.youtube.com/results?search_query={0}", query),
                                                 ViewRes.Song.DetailsStrings.SearchYoutube, WebLinkCategory.Other));
            }
        }
Пример #29
0
        public AlbumDetails(AlbumDetailsContract contract, IUserPermissionContext permissionContext)
        {
            ParamIs.NotNull(() => contract);

            AdditionalNames            = contract.AdditionalNames;
            ArtistString               = contract.ArtistString;
            CanEdit                    = EntryPermissionManager.CanEdit(permissionContext, contract);
            CanEditPersonalDescription = contract.CanEditPersonalDescription;
            CanRemoveTagUsages         = contract.CanRemoveTagUsages;
            CommentCount               = contract.CommentCount;
            CreateDate                 = contract.CreateDate;
            Description                = contract.Description;
            Deleted                    = contract.Deleted;
            DiscType                   = contract.DiscType;
            Draft                     = contract.Status == EntryStatus.Draft;
            Hits                      = contract.Hits;
            Id                        = contract.Id;
            LatestComments            = contract.LatestComments;
            LatestReview              = contract.Stats.LatestReview;
            LatestReviewRatingScore   = contract.Stats.LatestReviewRatingScore;
            MergedTo                  = contract.MergedTo;
            Name                      = contract.Name;
            OwnedBy                   = contract.Stats.OwnedCount;
            PersonalDescriptionText   = contract.PersonalDescriptionText;
            PersonalDescriptionAuthor = contract.PersonalDescriptionAuthor;
            Pictures                  = contract.Pictures;
            PVs                       = contract.PVs;
            RatingAverage             = contract.RatingAverage;
            RatingCount               = contract.RatingCount;
            ReviewCount               = contract.Stats.ReviewCount;
            Status                    = contract.Status;
            Tags                      = contract.Tags;
            TotalLength               = contract.TotalLength;
            UserHasAlbum              = contract.AlbumForUser != null;
            Version                   = contract.Version;
            WebLinks                  = contract.WebLinks;
            WishlistedBy              = contract.Stats.WishlistCount;
            mime                      = contract.CoverPictureMime;

            var songsByDiscs = contract.Songs.GroupBy(s => s.DiscNumber);

            Discs =
                (from songsByDisc in songsByDiscs
                 let dn = songsByDisc.Key
                          select new AlbumDisc(dn, songsByDisc, contract.Discs.ContainsKey(dn) ? contract.Discs[dn] : null))
                .ToArray();

            if (contract.AlbumForUser != null)
            {
                AlbumMediaType      = contract.AlbumForUser.MediaType;
                AlbumPurchaseStatus = contract.AlbumForUser.PurchaseStatus;
                CollectionRating    = contract.AlbumForUser.Rating;
            }

            if (contract.OriginalRelease != null)
            {
                CatNum          = contract.OriginalRelease.CatNum;
                ReleaseEvent    = contract.OriginalRelease.ReleaseEvent;
                ReleaseDate     = contract.OriginalRelease.ReleaseDate;
                FullReleaseDate = ReleaseDate.Year.HasValue && ReleaseDate.Month.HasValue && ReleaseDate.Day.HasValue ? (DateTime?)new DateTime(ReleaseDate.Year.Value, ReleaseDate.Month.Value, ReleaseDate.Day.Value) : null;
            }

            var artists = contract.ArtistLinks;

            ContentFocus = AlbumHelper.GetContentFocus(DiscType);

            Bands        = artists.Where(a => a.Categories.HasFlag(ArtistCategories.Band)).ToArray();
            Circles      = artists.Where(a => a.Categories.HasFlag(ArtistCategories.Circle)).ToArray();
            Illustrators = ContentFocus == ContentFocus.Illustration ? artists.Where(a => a.Categories.HasFlag(ArtistCategories.Illustrator)).ToArray() : null;
            Labels       = artists.Where(a => a.Categories.HasFlag(ArtistCategories.Label)).ToArray();
            Producers    = artists.Where(a => a.Categories.HasFlag(ArtistCategories.Producer)).ToArray();
            Vocalists    = artists.Where(a => a.Categories.HasFlag(ArtistCategories.Vocalist)).ToArray();
            Subject      = artists.Where(a => a.Categories.HasFlag(ArtistCategories.Subject)).ToArray();
            OtherArtists = artists.Where(a => a.Categories.HasFlag(ArtistCategories.Other) ||
                                         a.Categories.HasFlag(ArtistCategories.Animator) ||
                                         (ContentFocus != ContentFocus.Illustration && a.Categories.HasFlag(ArtistCategories.Illustrator))).ToArray();

            PrimaryPV = PVHelper.PrimaryPV(PVs);
        }
Пример #30
0
        public virtual ArtistForArtist AddMember(Artist member, ArtistLinkType linkType)
        {
            ParamIs.NotNull(() => member);

            return(member.AddGroup(this, linkType));
        }