-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.js
171 lines (136 loc) · 5.21 KB
/
server.js
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
const express = require('express');
const axios = require('axios');
const fs = require('fs');
const path = require('path');
const app = express();
const port = 3005;
app.use(express.static('public'));
app.use(express.json());
app.get('/', (req, res) => {
console.log('Received GET request for /');
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
app.post('/convert', async (req, res) => {
try {
const { link } = req.body;
console.log(`Received POST request to convert link: ${link}`);
const url = `${link}.json`;
console.log(`URL requested: ${url}`);
const response = await axios.get(url);
const data = response.data;
console.log('Successfully fetched data from Reddit API');
const responseJson = JSON.stringify(data, null, 4);
// save responseJson to a file
const linkFileName = link.replace(/[^a-zA-Z0-9]/g, '_');
fs.writeFileSync(`response-${linkFileName}.json`, responseJson);
console.log("Creating obsidian canvas");
const obsidianCanvas = redditToObsidianCanvas(data);
const obsidianCanvasJson = JSON.stringify(obsidianCanvas, null, 4);
fs.writeFileSync(`canvas-${linkFileName}.canvas`, obsidianCanvasJson);
console.log(`Created obsidian canvas: canvas-${linkFileName}.canvas`);
let markdown = '';
const post = data[0].data.children[0].data;
markdown += `# ${post.title}\n\n`;
markdown += `${post.selftext}\n\n`;
const comments = data[1].data.children;
for (const comment of comments) {
if (comment.kind === 't1') {
markdown += `## ${comment.data.author}\n\n${comment.data.body}\n\n`;
}
}
console.log('Successfully converted data to markdown');
res.json({ markdown });
} catch (error) {
console.error('Error during conversion:', error.message);
res.status(500).json({ error: error.message });
}
});
function redditToObsidianCanvas(redditJson) {
let currentY = 0; // Track the current Y position globally
let nodes = [];
let edges = [];
let yOffset = 0; // Global offset to manage Y positions
function createNode(id, text, x, y) {
const minHeight = 100; // Minimum height of the node
const lineHeight = 20; // Approximate height per line of text
// Calculate the number of lines (assuming ~50 characters per line for estimation)
const numberOfLines = Math.ceil(text.length / 20); // this is duplicated with numberOfLines in processComment
// Calculate the height based on the number of lines
const calculatedHeight = Math.max(minHeight, numberOfLines * lineHeight);
return {
id: id,
type: "text",
x: x,
y: y,
width: 300,
height: calculatedHeight,
text: text,
color: "#FFD700"
};
}
function processComment(comment, parentId = null, x = 0, y = 0, depth = 0) {
const commentId = uuidv4();
const nodeText = `${comment.author}: ${comment.body}`;
// Calculate the height of the current node
const minHeight = 100; // Minimum height of the node
const lineHeight = 20; // Approximate height per line of text
const numberOfLines = Math.ceil(nodeText.length / 20); // changed 50 to 20 for more lines
const nodeHeight = Math.max(minHeight, numberOfLines * lineHeight);
// Create the node with the updated currentY position
nodes.push(createNode(commentId, nodeText, x, currentY));
// Update currentY for the next node to avoid overlap
currentY += nodeHeight + 50; // Add extra spacing of 50 pixels
// Create an edge between the parent and this comment
if (parentId !== null) {
edges.push({
id: uuidv4(),
fromNode: parentId,
toNode: commentId,
fromSide: "right",
toSide: "left"
});
}
// Process replies if any
if (comment.replies && comment.replies.data && comment.replies.data.children) {
comment.replies.data.children.forEach(reply => {
if (reply.kind === 't1') { // It's a comment
processComment(reply.data, commentId, x + 400, currentY, depth + 1);
}
});
}
}
// Process the main post
redditJson[0].data.children.forEach(child => {
const post = child.data;
const postId = uuidv4();
const postText = `${post.author}: ${post.title}\n${post.selftext}`;
nodes.push(createNode(postId, postText, 0, yOffset)); // Use yOffset to place the post
// Process comments
let commentY = yOffset + 150;
redditJson[1].data.children.forEach(comment => {
if (comment.kind === 't1') { // It's a comment
processComment(comment.data, postId, 400, commentY);
commentY += 150; // Increment Y for the next top-level comment
}
});
// Update yOffset for the next post (if any)
yOffset = commentY;
});
// Prepare the final canvas data
return {
nodes: nodes,
edges: edges
};
}
// Helper function to generate unique IDs
function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
const r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
// Output the canvas JSON
// fs.writeFileSync('output_canvas.json', JSON.stringify(canvasJson, null, 4));
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});