summaryrefslogtreecommitdiff
path: root/internal/trans/export.go
blob: f242c9b940bdbb08bb8fc97736c9b9ed62832864 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
// GoToSocial
// Copyright (C) GoToSocial Authors admin@gotosocial.org
// SPDX-License-Identifier: AGPL-3.0-or-later
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
package trans

import (
	"context"
	"fmt"
	"os"

	"github.com/superseriousbusiness/gotosocial/internal/db"
	transmodel "github.com/superseriousbusiness/gotosocial/internal/trans/model"
)

func (e *exporter) exportAccounts(ctx context.Context, where []db.Where, file *os.File) ([]*transmodel.Account, error) {
	// select using the 'where' we've been provided
	accounts := []*transmodel.Account{}
	if err := e.db.GetWhere(ctx, where, &accounts); err != nil {
		return nil, fmt.Errorf("exportAccounts: error selecting accounts: %s", err)
	}

	// write any accounts found to file
	for _, a := range accounts {
		if err := e.accountEncode(ctx, file, a); err != nil {
			return nil, fmt.Errorf("exportAccounts: error encoding account: %s", err)
		}
	}

	return accounts, nil
}

func (e *exporter) exportBlocks(ctx context.Context, accounts []*transmodel.Account, file *os.File) ([]*transmodel.Block, error) {
	blocksUnique := make(map[string]*transmodel.Block)

	// for each account we want to export both where it's blocking and where it's blocked
	for _, a := range accounts {
		// 1. export blocks owned by given account
		whereBlocking := []db.Where{{Key: "account_id", Value: a.ID}}
		blocking := []*transmodel.Block{}
		if err := e.db.GetWhere(ctx, whereBlocking, &blocking); err != nil {
			return nil, fmt.Errorf("exportBlocks: error selecting blocks owned by account %s: %s", a.ID, err)
		}
		for _, b := range blocking {
			b.Type = transmodel.TransBlock
			if err := e.simpleEncode(ctx, file, b, b.ID); err != nil {
				return nil, fmt.Errorf("exportBlocks: error encoding block owned by account %s: %s", a.ID, err)
			}
			blocksUnique[b.ID] = b
		}

		// 2. export blocks that target given account
		whereBlocked := []db.Where{{Key: "target_account_id", Value: a.ID}}
		blocked := []*transmodel.Block{}
		if err := e.db.GetWhere(ctx, whereBlocked, &blocked); err != nil {
			return nil, fmt.Errorf("exportBlocks: error selecting blocks targeting account %s: %s", a.ID, err)
		}
		for _, b := range blocked {
			b.Type = transmodel.TransBlock
			if err := e.simpleEncode(ctx, file, b, b.ID); err != nil {
				return nil, fmt.Errorf("exportBlocks: error encoding block targeting account %s: %s", a.ID, err)
			}
			blocksUnique[b.ID] = b
		}
	}

	// now return all the blocks we found
	blocks := []*transmodel.Block{}
	for _, b := range blocksUnique {
		blocks = append(blocks, b)
	}

	return blocks, nil
}

func (e *exporter) exportDomainBlocks(ctx context.Context, file *os.File) ([]*transmodel.DomainBlock, error) {
	domainBlocks := []*transmodel.DomainBlock{}

	if err := e.db.GetAll(ctx, &domainBlocks); err != nil {
		return nil, fmt.Errorf("exportBlocks: error selecting domain blocks: %s", err)
	}

	for _, b := range domainBlocks {
		b.Type = transmodel.TransDomainBlock
		if err := e.simpleEncode(ctx, file, b, b.ID); err != nil {
			return nil, fmt.Errorf("exportBlocks: error encoding domain block: %s", err)
		}
	}

	return domainBlocks, nil
}

func (e *exporter) exportFollowing(ctx context.Context, accounts []*transmodel.Account, file *os.File) ([]*transmodel.Follow, error) {
	followsUnique := make(map[string]*transmodel.Follow)

	// for each account we want to export both where it's following and where it's followed
	for _, a := range accounts {
		// 1. export follows owned by given account
		whereFollowing := []db.Where{{Key: "account_id", Value: a.ID}}
		following := []*transmodel.Follow{}
		if err := e.db.GetWhere(ctx, whereFollowing, &following); err != nil {
			return nil, fmt.Errorf("exportFollowing: error selecting follows owned by account %s: %s", a.ID, err)
		}
		for _, follow := range following {
			follow.Type = transmodel.TransFollow
			if err := e.simpleEncode(ctx, file, follow, follow.ID); err != nil {
				return nil, fmt.Errorf("exportFollowing: error encoding follow owned by account %s: %s", a.ID, err)
			}
			followsUnique[follow.ID] = follow
		}

		// 2. export follows that target given account
		whereFollowed := []db.Where{{Key: "target_account_id", Value: a.ID}}
		followed := []*transmodel.Follow{}
		if err := e.db.GetWhere(ctx, whereFollowed, &followed); err != nil {
			return nil, fmt.Errorf("exportFollowing: error selecting follows targeting account %s: %s", a.ID, err)
		}
		for _, follow := range followed {
			follow.Type = transmodel.TransFollow
			if err := e.simpleEncode(ctx, file, follow, follow.ID); err != nil {
				return nil, fmt.Errorf("exportFollowing: error encoding follow targeting account %s: %s", a.ID, err)
			}
			followsUnique[follow.ID] = follow
		}
	}

	// now return all the follows we found
	follows := []*transmodel.Follow{}
	for _, follow := range followsUnique {
		follows = append(follows, follow)
	}

	return follows, nil
}

func (e *exporter) exportFollowRequests(ctx context.Context, accounts []*transmodel.Account, file *os.File) ([]*transmodel.FollowRequest, error) {
	frsUnique := make(map[string]*transmodel.FollowRequest)

	// for each account we want to export both where it's following and where it's followed
	for _, a := range accounts {
		// 1. export follow requests owned by given account
		whereRequesting := []db.Where{{Key: "account_id", Value: a.ID}}
		requesting := []*transmodel.FollowRequest{}
		if err := e.db.GetWhere(ctx, whereRequesting, &requesting); err != nil {
			return nil, fmt.Errorf("exportFollowRequests: error selecting follow requests owned by account %s: %s", a.ID, err)
		}
		for _, fr := range requesting {
			fr.Type = transmodel.TransFollowRequest
			if err := e.simpleEncode(ctx, file, fr, fr.ID); err != nil {
				return nil, fmt.Errorf("exportFollowRequests: error encoding follow request owned by account %s: %s", a.ID, err)
			}
			frsUnique[fr.ID] = fr
		}

		// 2. export follow requests that target given account
		whereRequested := []db.Where{{Key: "target_account_id", Value: a.ID}}
		requested := []*transmodel.FollowRequest{}
		if err := e.db.GetWhere(ctx, whereRequested, &requested); err != nil {
			return nil, fmt.Errorf("exportFollowRequests: error selecting follow requests targeting account %s: %s", a.ID, err)
		}
		for _, fr := range requested {
			fr.Type = transmodel.TransFollowRequest
			if err := e.simpleEncode(ctx, file, fr, fr.ID); err != nil {
				return nil, fmt.Errorf("exportFollowRequests: error encoding follow request targeting account %s: %s", a.ID, err)
			}
			frsUnique[fr.ID] = fr
		}
	}

	// now return all the followRequests we found
	followRequests := []*transmodel.FollowRequest{}
	for _, fr := range frsUnique {
		followRequests = append(followRequests, fr)
	}

	return followRequests, nil
}

func (e *exporter) exportInstances(ctx context.Context, file *os.File) ([]*transmodel.Instance, error) {
	instances := []*transmodel.Instance{}

	if err := e.db.GetAll(ctx, &instances); err != nil {
		return nil, fmt.Errorf("exportInstances: error selecting instance: %s", err)
	}

	for _, u := range instances {
		u.Type = transmodel.TransInstance
		if err := e.simpleEncode(ctx, file, u, u.ID); err != nil {
			return nil, fmt.Errorf("exportInstances: error encoding instance: %s", err)
		}
	}

	return instances, nil
}

func (e *exporter) exportUsers(ctx context.Context, file *os.File) ([]*transmodel.User, error) {
	users := []*transmodel.User{}

	if err := e.db.GetAll(ctx, &users); err != nil {
		return nil, fmt.Errorf("exportUsers: error selecting users: %s", err)
	}

	for _, u := range users {
		u.Type = transmodel.TransUser
		if err := e.simpleEncode(ctx, file, u, u.ID); err != nil {
			return nil, fmt.Errorf("exportUsers: error encoding user: %s", err)
		}
	}

	return users, nil
}