-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsource_local_extract.go
More file actions
170 lines (159 loc) · 5.1 KB
/
Copy pathsource_local_extract.go
File metadata and controls
170 lines (159 loc) · 5.1 KB
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
package store
import (
"context"
"fmt"
"strings"
"time"
"github.com/darron/dbrain/internal/model"
)
func (s *Store) GetPreferredLocalSourceExtract(ctx context.Context, sourceID int64) (model.ExtractResult, bool, error) {
rows, err := s.db.QueryContext(ctx, `
WITH local_candidates AS (
SELECT
s.canonical_url AS canonical_url,
s.normalized_url AS normalized_url,
s.domain AS domain,
s.source_type AS source_type,
COALESCE(NULLIF(i.article_title, ''), s.title, '') AS title,
CASE
WHEN i.article_title = '`+model.XMediaTranscriptArticleTitle+`' THEN ''
WHEN i.source_type = 'apple_note' THEN ''
ELSE i.article_text
END AS article_text,
i.author_handle AS author_handle,
i.x_post_json AS x_post_json,
i.updated_at AS updated_at,
COALESCE(i.last_seen_at, i.updated_at, '') AS sort_time,
0 AS provider_priority,
i.id AS item_id
FROM item_source_links l
JOIN items i ON i.id = l.item_id
JOIN sources s ON s.id = l.source_id
WHERE l.source_id = ?
UNION ALL
SELECT
s.canonical_url AS canonical_url,
s.normalized_url AS normalized_url,
s.domain AS domain,
s.source_type AS source_type,
COALESCE(NULLIF(p.article_title, ''), NULLIF(i.article_title, ''), s.title, '') AS title,
COALESCE(
NULLIF(CASE WHEN p.article_title = '`+model.XMediaTranscriptArticleTitle+`' THEN '' ELSE p.article_text END, ''),
CASE
WHEN i.article_title = '`+model.XMediaTranscriptArticleTitle+`' THEN ''
WHEN i.source_type = 'apple_note' THEN ''
ELSE i.article_text
END,
''
) AS article_text,
p.author_handle AS author_handle,
p.x_post_json AS x_post_json,
p.updated_at AS updated_at,
COALESCE(p.last_seen_at, p.updated_at, '') AS sort_time,
1 AS provider_priority,
p.id AS item_id
FROM item_source_links l
JOIN items i ON i.id = l.item_id
JOIN item_item_links q ON q.child_item_id = i.id AND q.link_kind = 'quoted_post'
JOIN items p ON p.id = q.parent_item_id
JOIN sources s ON s.id = l.source_id
WHERE l.source_id = ?
)
SELECT
canonical_url,
normalized_url,
domain,
source_type,
title,
article_text,
author_handle,
x_post_json,
updated_at
FROM local_candidates
ORDER BY sort_time DESC, provider_priority ASC, item_id DESC`, sourceID, sourceID)
if err != nil {
return model.ExtractResult{}, false, fmt.Errorf("load local source extract %d: %w", sourceID, err)
}
defer func() {
_ = rows.Close()
}()
var best model.ExtractResult
bestRank := -1
bestContentLen := -1
for rows.Next() {
var canonicalURL string
var normalizedURL string
var domain string
var sourceType string
var title string
var articleText string
var authorHandle string
var xPostJSON string
var updatedAt string
if err := rows.Scan(&canonicalURL, &normalizedURL, &domain, &sourceType, &title, &articleText, &authorHandle, &xPostJSON, &updatedAt); err != nil {
return model.ExtractResult{}, false, fmt.Errorf("scan local source extract %d: %w", sourceID, err)
}
sourceURL := preferredLocalExtractURL(sourceType, canonicalURL, normalizedURL)
var candidate model.ExtractResult
candidateRank := -1
if content := strings.TrimSpace(articleText); content != "" {
candidate = model.ExtractResult{
CanonicalURL: sourceURL,
FinalURL: sourceURL,
Title: title,
SiteName: domain,
Content: content,
Status: model.SourceExtractStatusOK,
FetchedAt: parseStoredTime(updatedAt),
Tool: "item-cache",
ToolVersion: "local-item-cache",
}
candidateRank = 2
} else if sourceType == "x_article" {
if preview, ok := parseXArticlePreview(xPostJSON, sourceURL); ok {
toolVersion := "local-article-preview-cache"
candidateRank = 1
if preview.HasFullText {
toolVersion = "local-article-body-cache"
candidateRank = 2
}
candidate = model.ExtractResult{
CanonicalURL: sourceURL,
FinalURL: sourceURL,
Title: firstNonEmpty(preview.Title, title),
SiteName: firstNonEmpty(domain, "x.com"),
Content: preview.Content,
Status: model.SourceExtractStatusOK,
FetchedAt: parseStoredTime(updatedAt),
Tool: "x-hydration",
ToolVersion: toolVersion,
}
}
}
if candidateRank < 0 || strings.TrimSpace(candidate.Content) == "" {
continue
}
contentLen := len(candidate.Content)
if candidateRank > bestRank || (candidateRank == bestRank && contentLen > bestContentLen) {
best = candidate
bestRank = candidateRank
bestContentLen = contentLen
}
}
if err := rows.Err(); err != nil {
return model.ExtractResult{}, false, fmt.Errorf("iterate local source extract %d: %w", sourceID, err)
}
if bestRank < 0 || strings.TrimSpace(best.Content) == "" {
return model.ExtractResult{}, false, nil
}
if best.FetchedAt.IsZero() {
best.FetchedAt = time.Now().UTC()
}
return best, true, nil
}
func preferredLocalExtractURL(sourceType string, canonicalURL string, normalizedURL string) string {
if sourceType == "x_article" && strings.Contains(normalizedURL, "/i/article/") {
return normalizedURL
}
return canonicalURL
}