summaryrefslogtreecommitdiffstats
path: root/apps/files_trashbin
Commit message (Collapse)AuthorAgeFilesLines
* Fix(l10n): Update translations from TransifexNextcloud bot2023-06-262-2/+2
| | | | Signed-off-by: Nextcloud bot <bot@nextcloud.com>
* Fix(l10n): Update translations from TransifexNextcloud bot2023-06-242-0/+12
| | | | Signed-off-by: Nextcloud bot <bot@nextcloud.com>
* Fix(l10n): Update translations from TransifexNextcloud bot2023-06-182-2/+2
| | | | Signed-off-by: Nextcloud bot <bot@nextcloud.com>
* Fix(l10n): Update translations from TransifexNextcloud bot2023-06-174-18/+54
| | | | Signed-off-by: Nextcloud bot <bot@nextcloud.com>
* Fix(l10n): Update translations from TransifexNextcloud bot2023-06-142-12/+12
| | | | Signed-off-by: Nextcloud bot <bot@nextcloud.com>
* Correctly react to bad configurationCôme Chilliet2023-06-091-13/+23
| | | | Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
* Do not cast sizes to int in Trashbin classCôme Chilliet2023-06-091-29/+24
| | | | | | This helps with 32bits support Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
* Fix(l10n): Update translations from TransifexNextcloud bot2023-06-082-0/+2
| | | | Signed-off-by: Nextcloud bot <bot@nextcloud.com>
* fix(trashbin): Truncate long filenamesChristopher Ng2023-06-016-19/+88
| | | | Signed-off-by: Christopher Ng <chrng8@gmail.com>
* Fix(l10n): Update translations from TransifexNextcloud bot2023-05-302-0/+4
| | | | Signed-off-by: Nextcloud bot <bot@nextcloud.com>
* Fix(l10n): Update translations from TransifexNextcloud bot2023-05-276-2/+8
| | | | Signed-off-by: Nextcloud bot <bot@nextcloud.com>
* Merge pull request #38104 from nextcloud/feat/um-32-bitPytal2023-05-091-2/+2
|\
| * feat(UserMigration)!: 32-bit supportChristopher Ng2023-05-051-2/+2
| | | | | | | | Signed-off-by: Christopher Ng <chrng8@gmail.com>
* | Fix(l10n): Update translations from TransifexNextcloud bot2023-05-092-0/+2
|/ | | | Signed-off-by: Nextcloud bot <bot@nextcloud.com>
* Fix(l10n): Update translations from TransifexNextcloud bot2023-04-262-0/+2
| | | | Signed-off-by: Nextcloud bot <bot@nextcloud.com>
* fix(assets): Optimize SVGs with scour 0.38.2Joas Schilling2023-04-241-1/+1
| | | | Signed-off-by: Joas Schilling <coding@schilljs.com>
* chore(autoloader): Update autoloaders with composer 2.5.5Joas Schilling2023-04-213-11/+22
| | | | Signed-off-by: Joas Schilling <coding@schilljs.com>
* Fix(l10n): Update translations from TransifexNextcloud bot2023-04-202-0/+2
| | | | Signed-off-by: Nextcloud bot <bot@nextcloud.com>
* Fix(l10n): Update translations from TransifexNextcloud bot2023-04-172-0/+2
| | | | Signed-off-by: Nextcloud bot <bot@nextcloud.com>
* Fix(l10n): Update translations from TransifexNextcloud bot2023-04-162-0/+2
| | | | Signed-off-by: Nextcloud bot <bot@nextcloud.com>
* Fix(l10n): Update translations from TransifexNextcloud bot2023-04-152-0/+2
| | | | Signed-off-by: Nextcloud bot <bot@nextcloud.com>
* fix(files): standardize `files:node:event` event syntaxJohn Molakvoæ2023-04-141-1/+1
| | | | Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
* Fix(l10n): 🔠 Update translations from TransifexNextcloud bot2023-04-132-0/+2
| | | | Signed-off-by: Nextcloud bot <bot@nextcloud.com>
* Fix(l10n): 🔠 Update translations from TransifexNextcloud bot2023-04-12146-718/+720
| | | | Signed-off-by: Nextcloud bot <bot@nextcloud.com>
* fix(files_trashbin): set real filename on trashbin downloadJohn Molakvoæ2023-04-115-8/+25
| | | | Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
* Merge pull request #37646 from nextcloud/feat/trashbin-cleanupJohn Molakvoæ2023-04-112-500/+0
|\ | | | | chore(files_trashbin): cleanup old legacy files
| * chore(files_trashbin): cleanup old legacy filesJohn Molakvoæ2023-04-072-500/+0
| | | | | | | | Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
* | Fix(l10n): 🔠 Update translations from TransifexNextcloud bot2023-04-102-0/+2
| | | | | | | | Signed-off-by: Nextcloud bot <bot@nextcloud.com>
* | Fix(l10n): 🔠 Update translations from TransifexNextcloud bot2023-04-094-0/+4
| | | | | | | | Signed-off-by: Nextcloud bot <bot@nextcloud.com>
* | Fix(l10n): 🔠 Update translations from TransifexNextcloud bot2023-04-0812-0/+12
|/ | | | Signed-off-by: Nextcloud bot <bot@nextcloud.com>
* Fix(l10n): 🔠 Update translations from TransifexNextcloud bot2023-04-07148-294/+294
| | | | Signed-off-by: Nextcloud bot <bot@nextcloud.com>
* chore(eslint): clean and fixJohn Molakvoæ2023-04-064-10/+8
| | | | Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
* feat(files): add FileAction serviceJohn Molakvoæ2023-04-061-1/+3
| | | | Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
* fix: improved preview handlingJohn Molakvoæ2023-04-061-1/+1
| | | | Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
* feat(files): move userconfig to dedicated store and fix crop previewsJohn Molakvoæ2023-04-061-1/+1
| | | | Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
* feat(files): batch actionsJohn Molakvoæ2023-04-061-16/+26
| | | | Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
* feat(files): propagate restore and delete eventsJohn Molakvoæ2023-04-061-4/+10
| | | | Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
* feat(accessibility): add files table caption and summaryJohn Molakvoæ2023-04-061-0/+1
| | | | Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
* fix(files): fix custom render components reactivityJohn Molakvoæ2023-04-061-1/+3
| | | | Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
* feat(files): implement sorting per viewJohn Molakvoæ2023-04-062-3/+6
| | | | Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
* feat(files): actions apiJohn Molakvoæ2023-04-063-5/+71
| | | | Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
* feat(files): custom columnsJohn Molakvoæ2023-04-062-1/+24
| | | | Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
* fix(files_trashbin): previews crop supportJohn Molakvoæ2023-04-062-4/+8
| | | | Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
* feat(files_trashbin): migrate to vueJohn Molakvoæ2023-04-0610-508/+197
| | | | Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
* add a bit more verbose option for trashbin cleanupRobin Appelman2023-04-032-27/+52
| | | | Signed-off-by: Robin Appelman <robin@icewind.nl>
* Fix(l10n): 🔠 Update translations from TransifexNextcloud bot2023-03-302-2/+2
| | | | Signed-off-by: Nextcloud bot <bot@nextcloud.com>
* chore(eslint): fix missing import extensionsJohn Molakvoæ2023-03-231-2/+2
| | | | Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
* chore(eslint): replace node/no-missing-import by n/no-missing-importJohn Molakvoæ2023-03-231-1/+1
| | | | Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
* Fix(l10n): 🔠 Update translations from TransifexNextcloud bot2023-03-202-0/+2
| | | | Signed-off-by: Nextcloud bot <bot@nextcloud.com>
* chore(release): Bump requirements and versions in apps/Joas Schilling2023-03-031-2/+2
| | | | Signed-off-by: Joas Schilling <coding@schilljs.com>
n>Error("unable to set %s as the local head for PR #%d from %s in %s/%s. Error: %v", pr.Head.SHA, pr.Number, pr.Head.Ref, g.repoOwner, g.repoName, err) } } } return head, nil } func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*issues_model.PullRequest, error) { var labels []*issues_model.Label for _, label := range pr.Labels { lb, ok := g.labels[label.Name] if ok { labels = append(labels, lb) } } milestoneID := g.milestones[pr.Milestone] head, err := g.updateGitForPullRequest(pr) if err != nil { return nil, fmt.Errorf("updateGitForPullRequest: %w", err) } // Now we may need to fix the mergebase if pr.Base.SHA == "" { if pr.Base.Ref != "" && pr.Head.SHA != "" { // A PR against a tag base does not make sense - therefore pr.Base.Ref must be a branch // TODO: should we be checking for the refs/heads/ prefix on the pr.Base.Ref? (i.e. are these actually branches or refs) pr.Base.SHA, _, err = g.gitRepo.GetMergeBase("", git.BranchPrefix+pr.Base.Ref, pr.Head.SHA) if err != nil { log.Error("Cannot determine the merge base for PR #%d in %s/%s. Error: %v", pr.Number, g.repoOwner, g.repoName, err) } } else { log.Error("Cannot determine the merge base for PR #%d in %s/%s. Not enough information", pr.Number, g.repoOwner, g.repoName) } } if pr.Created.IsZero() { if pr.Closed != nil { pr.Created = *pr.Closed } else if pr.MergedTime != nil { pr.Created = *pr.MergedTime } else { pr.Created = time.Now() } } if pr.Updated.IsZero() { pr.Updated = pr.Created } issue := issues_model.Issue{ RepoID: g.repo.ID, Repo: g.repo, Title: pr.Title, Index: pr.Number, Content: pr.Content, MilestoneID: milestoneID, IsPull: true, IsClosed: pr.State == "closed", IsLocked: pr.IsLocked, Labels: labels, CreatedUnix: timeutil.TimeStamp(pr.Created.Unix()), UpdatedUnix: timeutil.TimeStamp(pr.Updated.Unix()), } if err := g.remapUser(pr, &issue); err != nil { return nil, err } // add reactions for _, reaction := range pr.Reactions { res := issues_model.Reaction{ Type: reaction.Content, CreatedUnix: timeutil.TimeStampNow(), } if err := g.remapUser(reaction, &res); err != nil { return nil, err } issue.Reactions = append(issue.Reactions, &res) } pullRequest := issues_model.PullRequest{ HeadRepoID: g.repo.ID, HeadBranch: head, BaseRepoID: g.repo.ID, BaseBranch: pr.Base.Ref, MergeBase: pr.Base.SHA, Index: pr.Number, HasMerged: pr.Merged, Issue: &issue, } if pullRequest.Issue.IsClosed && pr.Closed != nil { pullRequest.Issue.ClosedUnix = timeutil.TimeStamp(pr.Closed.Unix()) } if pullRequest.HasMerged && pr.MergedTime != nil { pullRequest.MergedUnix = timeutil.TimeStamp(pr.MergedTime.Unix()) pullRequest.MergedCommitID = pr.MergeCommitSHA pullRequest.MergerID = g.doer.ID } // TODO: assignees return &pullRequest, nil } func convertReviewState(state string) issues_model.ReviewType { switch state { case base.ReviewStatePending: return issues_model.ReviewTypePending case base.ReviewStateApproved: return issues_model.ReviewTypeApprove case base.ReviewStateChangesRequested: return issues_model.ReviewTypeReject case base.ReviewStateCommented: return issues_model.ReviewTypeComment case base.ReviewStateRequestReview: return issues_model.ReviewTypeRequest default: return issues_model.ReviewTypePending } } // CreateReviews create pull request reviews of currently migrated issues func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error { cms := make([]*issues_model.Review, 0, len(reviews)) for _, review := range reviews { var issue *issues_model.Issue issue, ok := g.issues[review.IssueIndex] if !ok { return fmt.Errorf("review references non existent IssueIndex %d", review.IssueIndex) } if review.CreatedAt.IsZero() { review.CreatedAt = time.Unix(int64(issue.CreatedUnix), 0) } cm := issues_model.Review{ Type: convertReviewState(review.State), IssueID: issue.ID, Content: review.Content, Official: review.Official, CreatedUnix: timeutil.TimeStamp(review.CreatedAt.Unix()), UpdatedUnix: timeutil.TimeStamp(review.CreatedAt.Unix()), } if err := g.remapUser(review, &cm); err != nil { return err } cms = append(cms, &cm) // get pr pr, ok := g.prCache[issue.ID] if !ok { var err error pr, err = issues_model.GetPullRequestByIssueIDWithNoAttributes(issue.ID) if err != nil { return err } g.prCache[issue.ID] = pr } if pr.MergeBase == "" { // No mergebase -> no basis for any patches log.Warn("PR #%d in %s/%s: does not have a merge base, all review comments will be ignored", pr.Index, g.repoOwner, g.repoName) continue } headCommitID, err := g.gitRepo.GetRefCommitID(pr.GetGitRefName()) if err != nil { log.Warn("PR #%d GetRefCommitID[%s] in %s/%s: %v, all review comments will be ignored", pr.Index, pr.GetGitRefName(), g.repoOwner, g.repoName, err) continue } for _, comment := range review.Comments { line := comment.Line if line != 0 { comment.Position = 1 } else { _, _, line, _ = git.ParseDiffHunkString(comment.DiffHunk) } // SECURITY: The TreePath must be cleaned! comment.TreePath = path.Clean("/" + comment.TreePath)[1:] var patch string reader, writer := io.Pipe() defer func() { _ = reader.Close() _ = writer.Close() }() go func(comment *base.ReviewComment) { if err := git.GetRepoRawDiffForFile(g.gitRepo, pr.MergeBase, headCommitID, git.RawDiffNormal, comment.TreePath, writer); err != nil { // We should ignore the error since the commit maybe removed when force push to the pull request log.Warn("GetRepoRawDiffForFile failed when migrating [%s, %s, %s, %s]: %v", g.gitRepo.Path, pr.MergeBase, headCommitID, comment.TreePath, err) } _ = writer.Close() }(comment) patch, _ = git.CutDiffAroundLine(reader, int64((&issues_model.Comment{Line: int64(line + comment.Position - 1)}).UnsignedLine()), line < 0, setting.UI.CodeCommentLines) if comment.CreatedAt.IsZero() { comment.CreatedAt = review.CreatedAt } if comment.UpdatedAt.IsZero() { comment.UpdatedAt = comment.CreatedAt } if !git.IsValidSHAPattern(comment.CommitID) { log.Warn("Invalid comment CommitID[%s] on comment[%d] in PR #%d of %s/%s replaced with %s", comment.CommitID, pr.Index, g.repoOwner, g.repoName, headCommitID) comment.CommitID = headCommitID } c := issues_model.Comment{ Type: issues_model.CommentTypeCode, IssueID: issue.ID, Content: comment.Content, Line: int64(line + comment.Position - 1), TreePath: comment.TreePath, CommitSHA: comment.CommitID, Patch: patch, CreatedUnix: timeutil.TimeStamp(comment.CreatedAt.Unix()), UpdatedUnix: timeutil.TimeStamp(comment.UpdatedAt.Unix()), } if err := g.remapUser(review, &c); err != nil { return err } cm.Comments = append(cm.Comments, &c) } } return issues_model.InsertReviews(cms) } // Rollback when migrating failed, this will rollback all the changes. func (g *GiteaLocalUploader) Rollback() error { if g.repo != nil && g.repo.ID > 0 { g.gitRepo.Close() if err := models.DeleteRepository(g.doer, g.repo.OwnerID, g.repo.ID); err != nil { return err } } return nil } // Finish when migrating success, this will do some status update things. func (g *GiteaLocalUploader) Finish() error { if g.repo == nil || g.repo.ID <= 0 { return ErrRepoNotCreated } // update issue_index if err := issues_model.RecalculateIssueIndexForRepo(g.repo.ID); err != nil { return err } if err := models.UpdateRepoStats(g.ctx, g.repo.ID); err != nil { return err } g.repo.Status = repo_model.RepositoryReady return repo_model.UpdateRepositoryCols(g.ctx, g.repo, "status") } func (g *GiteaLocalUploader) remapUser(source user_model.ExternalUserMigrated, target user_model.ExternalUserRemappable) error { var userid int64 var err error if g.sameApp { userid, err = g.remapLocalUser(source, target) } else { userid, err = g.remapExternalUser(source, target) } if err != nil { return err } if userid > 0 { return target.RemapExternalUser("", 0, userid) } return target.RemapExternalUser(source.GetExternalName(), source.GetExternalID(), g.doer.ID) } func (g *GiteaLocalUploader) remapLocalUser(source user_model.ExternalUserMigrated, target user_model.ExternalUserRemappable) (int64, error) { userid, ok := g.userMap[source.GetExternalID()] if !ok { name, err := user_model.GetUserNameByID(g.ctx, source.GetExternalID()) if err != nil { return 0, err } // let's not reuse an ID when the user was deleted or has a different user name if name != source.GetExternalName() { userid = 0 } else { userid = source.GetExternalID() } g.userMap[source.GetExternalID()] = userid } return userid, nil } func (g *GiteaLocalUploader) remapExternalUser(source user_model.ExternalUserMigrated, target user_model.ExternalUserRemappable) (userid int64, err error) { userid, ok := g.userMap[source.GetExternalID()] if !ok { userid, err = user_model.GetUserIDByExternalUserID(g.gitServiceType.Name(), fmt.Sprintf("%d", source.GetExternalID())) if err != nil { log.Error("GetUserIDByExternalUserID: %v", err) return 0, err } g.userMap[source.GetExternalID()] = userid } return userid, nil }