mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-10-31 14:31:02 +00:00 
			
		
		
		
	user, topic, project, label, milestone, repository, pull_request, release, asset, comment, reaction, review providers Signed-off-by: Earl Warren <contact@earl-warren.org> Preserve file size when creating attachments Introduced inc6f5029708repoList.LoadAttributes has a ctx argument now Rename `repo.GetOwner` to `repo.LoadOwner`bd66fa586aupgrade to the latest gof3 (cherry picked from commitc770713656) [F3] ID remapping logic is in place, remove workaround (cherry picked from commitd0fee30167) [F3] it is experimental, do not enable by default (cherry picked from commitde325b21d0) (cherry picked from commit547e7b3c40)
		
			
				
	
	
		
			157 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			157 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // SPDX-License-Identifier: MIT
 | |
| 
 | |
| package driver
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"fmt"
 | |
| 	"io"
 | |
| 	"net/http"
 | |
| 
 | |
| 	repo_model "code.gitea.io/gitea/models/repo"
 | |
| 	"code.gitea.io/gitea/modules/timeutil"
 | |
| 	"code.gitea.io/gitea/services/attachment"
 | |
| 
 | |
| 	"github.com/google/uuid"
 | |
| 	"lab.forgefriends.org/friendlyforgeformat/gof3/format"
 | |
| 	"lab.forgefriends.org/friendlyforgeformat/gof3/util"
 | |
| )
 | |
| 
 | |
| type Asset struct {
 | |
| 	repo_model.Attachment
 | |
| 	DownloadFunc func() io.ReadCloser
 | |
| }
 | |
| 
 | |
| func AssetConverter(f *repo_model.Attachment) *Asset {
 | |
| 	return &Asset{
 | |
| 		Attachment: *f,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (o Asset) GetID() int64 {
 | |
| 	return o.ID
 | |
| }
 | |
| 
 | |
| func (o *Asset) SetID(id int64) {
 | |
| 	o.ID = id
 | |
| }
 | |
| 
 | |
| func (o *Asset) IsNil() bool {
 | |
| 	return o.ID == 0
 | |
| }
 | |
| 
 | |
| func (o *Asset) Equals(other *Asset) bool {
 | |
| 	return o.Name == other.Name
 | |
| }
 | |
| 
 | |
| func (o *Asset) ToFormat() *format.ReleaseAsset {
 | |
| 	return &format.ReleaseAsset{
 | |
| 		Common:        format.NewCommon(o.ID),
 | |
| 		Name:          o.Name,
 | |
| 		Size:          int(o.Size),
 | |
| 		DownloadCount: int(o.DownloadCount),
 | |
| 		Created:       o.CreatedUnix.AsTime(),
 | |
| 		DownloadURL:   o.DownloadURL(),
 | |
| 		DownloadFunc:  o.DownloadFunc,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (o *Asset) FromFormat(asset *format.ReleaseAsset) {
 | |
| 	*o = Asset{
 | |
| 		Attachment: repo_model.Attachment{
 | |
| 			ID:            asset.GetID(),
 | |
| 			Name:          asset.Name,
 | |
| 			Size:          int64(asset.Size),
 | |
| 			DownloadCount: int64(asset.DownloadCount),
 | |
| 			CreatedUnix:   timeutil.TimeStamp(asset.Created.Unix()),
 | |
| 		},
 | |
| 		DownloadFunc: asset.DownloadFunc,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| type AssetProvider struct {
 | |
| 	g *Forgejo
 | |
| }
 | |
| 
 | |
| func (o *AssetProvider) ToFormat(ctx context.Context, asset *Asset) *format.ReleaseAsset {
 | |
| 	httpClient := o.g.GetNewMigrationHTTPClient()()
 | |
| 	a := asset.ToFormat()
 | |
| 	a.DownloadFunc = func() io.ReadCloser {
 | |
| 		o.g.GetLogger().Debug("download from %s", asset.DownloadURL())
 | |
| 		req, err := http.NewRequest("GET", asset.DownloadURL(), nil)
 | |
| 		if err != nil {
 | |
| 			panic(err)
 | |
| 		}
 | |
| 		resp, err := httpClient.Do(req)
 | |
| 		if err != nil {
 | |
| 			panic(fmt.Errorf("while downloading %s %w", asset.DownloadURL(), err))
 | |
| 		}
 | |
| 
 | |
| 		// resp.Body is closed by the consumer
 | |
| 		return resp.Body
 | |
| 	}
 | |
| 	return a
 | |
| }
 | |
| 
 | |
| func (o *AssetProvider) FromFormat(ctx context.Context, p *format.ReleaseAsset) *Asset {
 | |
| 	var asset Asset
 | |
| 	asset.FromFormat(p)
 | |
| 	return &asset
 | |
| }
 | |
| 
 | |
| func (o *AssetProvider) ProcessObject(ctx context.Context, user *User, project *Project, release *Release, asset *Asset) {
 | |
| }
 | |
| 
 | |
| func (o *AssetProvider) GetObjects(ctx context.Context, user *User, project *Project, release *Release, page int) []*Asset {
 | |
| 	if page > 1 {
 | |
| 		return []*Asset{}
 | |
| 	}
 | |
| 	r, err := repo_model.GetReleaseByID(ctx, release.GetID())
 | |
| 	if err != nil {
 | |
| 		panic(err)
 | |
| 	}
 | |
| 	if err := r.LoadAttributes(ctx); err != nil {
 | |
| 		panic(fmt.Errorf("error while listing assets: %v", err))
 | |
| 	}
 | |
| 
 | |
| 	return util.ConvertMap[*repo_model.Attachment, *Asset](r.Attachments, AssetConverter)
 | |
| }
 | |
| 
 | |
| func (o *AssetProvider) Get(ctx context.Context, user *User, project *Project, release *Release, exemplar *Asset) *Asset {
 | |
| 	id := exemplar.GetID()
 | |
| 	asset, err := repo_model.GetAttachmentByID(ctx, id)
 | |
| 	if repo_model.IsErrAttachmentNotExist(err) {
 | |
| 		return &Asset{}
 | |
| 	}
 | |
| 	if err != nil {
 | |
| 		panic(err)
 | |
| 	}
 | |
| 	return AssetConverter(asset)
 | |
| }
 | |
| 
 | |
| func (o *AssetProvider) Put(ctx context.Context, user *User, project *Project, release *Release, asset *Asset) *Asset {
 | |
| 	asset.ID = 0
 | |
| 	asset.UploaderID = user.GetID()
 | |
| 	asset.RepoID = project.GetID()
 | |
| 	asset.ReleaseID = release.GetID()
 | |
| 	asset.UUID = uuid.New().String()
 | |
| 
 | |
| 	download := asset.DownloadFunc()
 | |
| 	defer download.Close()
 | |
| 	a, err := attachment.NewAttachment(&asset.Attachment, download, asset.Size)
 | |
| 	if err != nil {
 | |
| 		panic(err)
 | |
| 	}
 | |
| 	return o.Get(ctx, user, project, release, AssetConverter(a))
 | |
| }
 | |
| 
 | |
| func (o *AssetProvider) Delete(ctx context.Context, user *User, project *Project, release *Release, asset *Asset) *Asset {
 | |
| 	a := o.Get(ctx, user, project, release, asset)
 | |
| 	if !a.IsNil() {
 | |
| 		err := repo_model.DeleteAttachment(&a.Attachment, true)
 | |
| 		if err != nil {
 | |
| 			panic(err)
 | |
| 		}
 | |
| 	}
 | |
| 	return a
 | |
| }
 |