Skip to content

Commit 3701d4d

Browse files
authored
Merge pull request #1 from pedrobahito/master
Master
2 parents 7f4ea15 + 1cdfc05 commit 3701d4d

File tree

671 files changed

+95079
-212
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

671 files changed

+95079
-212
lines changed

.DS_Store

6 KB
Binary file not shown.

.idea/vcs.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.vscode/settings.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"livePreview.defaultPreviewPath": "/index.html"
3+
}

engine-d.js

+210
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
// Utility function to parse HTML and XML
2+
function parseContent(content, type) {
3+
const parser = new DOMParser();
4+
return parser.parseFromString(content, type);
5+
}
6+
7+
document.getElementById('scrapeBtn').addEventListener('click', async () => {
8+
const urlInput = document.getElementById('url-input');
9+
const targetUrl = urlInput.value.trim();
10+
11+
try {
12+
new URL(targetUrl); // This will throw an error if the URL is invalid
13+
if (!targetUrl.startsWith('http://') && !targetUrl.startsWith('https://')) {
14+
throw new Error('URL must be absolute.');
15+
}
16+
showLoadingMessage();
17+
await fetchAndDisplayRSSLinks(targetUrl);
18+
} catch (error) {
19+
showError('Please enter a valid URL.');
20+
} finally {
21+
hideLoadingMessage();
22+
}
23+
});
24+
25+
// Fetch and display RSS links from the provided URL
26+
async function fetchAndDisplayRSSLinks(url) {
27+
const proxyUrls = ['https://cors-anywhere.herokuapp.com/', 'https://cors.bridged.cc/', 'http://localhost:8080/proxy?url='];
28+
29+
for (const proxyUrl of proxyUrls) {
30+
try {
31+
const fullUrl = proxyUrl + encodeURIComponent(url);
32+
const html = await fetchHTML(fullUrl);
33+
const rssUrls = extractRSSUrls(html, url);
34+
displayRSSUrls(rssUrls);
35+
break;
36+
} catch (error) {
37+
showError(`Error fetching RSS links with proxy ${proxyUrl}: ${error.message}`);
38+
}
39+
}
40+
}
41+
42+
// Fetch HTML content from the provided URL
43+
async function fetchHTML(url) {
44+
const headers = new Headers({
45+
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36'
46+
});
47+
const response = await fetch(url, { headers });
48+
return await response.text();
49+
}
50+
51+
// Extract RSS URLs from the provided HTML content
52+
function extractRSSUrls(html, baseUrl) {
53+
const doc = parseContent(html, 'text/html');
54+
const linkTags = doc.querySelectorAll('link[type="application/rss+xml"], link[type="application/atom+xml"], link[rel="alternate"][type="application/rss+xml"], link[rel="alternate"][type="application/atom+xml"]');
55+
const rssUrls = new Set();
56+
57+
linkTags.forEach(linkTag => {
58+
let rssUrl = linkTag.getAttribute('href') || '';
59+
if (rssUrl) {
60+
// Check if the URL is relative
61+
if (rssUrl.startsWith('/')) {
62+
const urlObj = new URL(baseUrl);
63+
rssUrl = `${urlObj.protocol}//${urlObj.host}${rssUrl}`;
64+
}
65+
rssUrls.add(rssUrl);
66+
}
67+
});
68+
69+
return rssUrls;
70+
}
71+
72+
// Display RSS URLs in the output textarea
73+
function displayRSSUrls(rssUrls) {
74+
const outputArea = document.getElementById('output-area');
75+
outputArea.value = Array.from(rssUrls).join('\n');
76+
77+
if (rssUrls.size > 0) {
78+
showAddFeedModal(rssUrls);
79+
} else {
80+
alert('No RSS feeds found.');
81+
}
82+
}
83+
84+
// Show modal with options to add RSS feeds to the feed list
85+
function showAddFeedModal(rssUrls) {
86+
const feedOptions = document.getElementById('feedOptions');
87+
feedOptions.innerHTML = '';
88+
89+
rssUrls.forEach(url => {
90+
const checkbox = document.createElement('input');
91+
checkbox.type = 'checkbox';
92+
checkbox.value = url;
93+
94+
const label = document.createElement('label');
95+
label.textContent = url;
96+
97+
feedOptions.appendChild(checkbox);
98+
feedOptions.appendChild(label);
99+
feedOptions.appendChild(document.createElement('br'));
100+
});
101+
102+
const modal = document.getElementById('addFeedModal');
103+
modal.style.display = 'flex';
104+
105+
document.getElementById('addFeedsBtn').onclick = () => {
106+
const selectedUrls = Array.from(feedOptions.querySelectorAll('input[type="checkbox"]:checked')).map(input => input.value);
107+
addFeedsToList(selectedUrls);
108+
modal.style.display = 'none';
109+
};
110+
}
111+
112+
// Add selected RSS feeds to the feed list
113+
function addFeedsToList(urls) {
114+
const sidebarFeedsList = document.getElementById('sidebar-feeds-list');
115+
116+
urls.forEach(url => {
117+
const listItem = document.createElement('li');
118+
const link = document.createElement('a');
119+
link.href = '#';
120+
link.textContent = url;
121+
link.onclick = () => {
122+
fetchAndDisplayRSSPosts(url);
123+
};
124+
125+
listItem.appendChild(link);
126+
sidebarFeedsList.appendChild(listItem);
127+
128+
// Fetch and display posts from the RSS feed
129+
fetchAndDisplayRSSPosts(url);
130+
});
131+
}
132+
133+
// Fetch and display RSS posts from the provided URL
134+
async function fetchAndDisplayRSSPosts(url) {
135+
try {
136+
const response = await fetch(url);
137+
const data = await response.text();
138+
const items = parseRSSFeed(data);
139+
displayRSSPosts(items);
140+
} catch (error) {
141+
console.error('Error fetching RSS posts:', error);
142+
}
143+
}
144+
145+
// Parse the RSS feed data and return the items
146+
function parseRSSFeed(data) {
147+
const xmlDoc = parseContent(data, 'text/xml');
148+
return xmlDoc.querySelectorAll('item');
149+
}
150+
151+
// Display RSS posts in the DOM
152+
function displayRSSPosts(items) {
153+
const rssFeedContainer = document.getElementById('rssPostsFeed');
154+
rssFeedContainer.innerHTML = '';
155+
156+
const fragment = document.createDocumentFragment();
157+
158+
items.forEach(item => {
159+
const title = item.querySelector('title').textContent;
160+
const link = item.querySelector('link').textContent;
161+
const description = item.querySelector('description').textContent;
162+
const pubDate = item.querySelector('pubDate').textContent;
163+
164+
const postElement = createPostElement(title, description, link, pubDate);
165+
fragment.appendChild(postElement);
166+
});
167+
168+
rssFeedContainer.appendChild(fragment);
169+
}
170+
171+
// Create a DOM element for an RSS post
172+
function createPostElement(title, description, link, pubDate) {
173+
const postElement = document.createElement('div');
174+
postElement.classList.add('rssPost');
175+
postElement.innerHTML = `
176+
<h3>${title}</h3>
177+
<p>${description}</p>
178+
<p><strong>Published on:</strong> ${pubDate}</p>
179+
<a href="${link}" target="_blank">Read More</a>
180+
`;
181+
return postElement;
182+
}
183+
184+
// Display all posts from all feeds when "All Feeds" is clicked
185+
document.getElementById('sidebar-all-feeds').addEventListener('click', async () => {
186+
const urls = Array.from(document.querySelectorAll('#sidebar-feeds-list a')).map(a => a.textContent);
187+
const allPosts = [];
188+
for (const url of urls) {
189+
const response = await fetch(url);
190+
const data = await response.text();
191+
const items = parseRSSFeed(data);
192+
allPosts.push(...items);
193+
}
194+
displayRSSPosts(allPosts);
195+
});
196+
197+
// Show a loading message (Placeholder function)
198+
function showLoadingMessage() {
199+
console.log('Loading...');
200+
}
201+
202+
// Hide a loading message (Placeholder function)
203+
function hideLoadingMessage() {
204+
console.log('Done loading.');
205+
}
206+
207+
// Show an error message (Placeholder function)
208+
function showError(message) {
209+
alert(message);
210+
}

image-placeholder.png

6 KB
Loading

index.html

+41-58
Original file line numberDiff line numberDiff line change
@@ -3,70 +3,53 @@
33
<head>
44
<meta charset="UTF-8">
55
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6-
<title>RSS Feed News Release</title>
6+
<title>RSS Feed</title>
77
<link rel="stylesheet" href="style.css">
8+
<link rel="stylesheet" href="posts.css">
89
</head>
910
<body>
10-
<header>
11-
<h1>RSS Feed News Release</h1>
12-
</header>
13-
<nav>
14-
<div id="hamburger">&#9776;</div>
15-
<ul>
16-
<li><a href="#">Home</a></li>
17-
<li><a href="#">Categories</a></li>
18-
<li><a href="#">About</a></li>
19-
<li><a href="#">Contact</a></li>
20-
</ul>
21-
</nav>
22-
23-
<aside>
24-
<div class="bento-box">
25-
<h2>Search RSS Feed</h2>
26-
<form id="searchForm">
27-
<input type="text" id="rssInput" placeholder="Enter RSS URL">
28-
<button type="submit" id="searchBtn">Search</button>
29-
</form>
30-
</div>
31-
<div class="bento-box">
32-
<h2>Categories</h2>
33-
<ul>
34-
<li><a href="#">Politics</a></li>
35-
<li><a href="#">Technology</a></li>
36-
<li><a href="#">Sports</a></li>
37-
<li><a href="#">Entertainment</a></li>
11+
<aside class="glass-effect sidebar">
12+
<a class="sidebar-item" href="#" role="button">
13+
<h1>RSS Feed</h1>
14+
</a>
15+
<form class="sidebar-item glass-effect search-form" action="#" method="get">
16+
<input type="url" name="url-input" id="url-input" placeholder="Enter URL">
17+
<button type="submit" id="scrapeBtn">Search</button>
18+
<output id="url-output">
19+
<textarea name="output-area" id="output-area" readonly></textarea>
20+
</output>
21+
<button type="submit" id="add-feed">Add Feed</button>
22+
</form>
23+
<section class="glass-effect sidebar-item feeds-section">
24+
<h2 class="feeds-heading">Feeds</h2>
25+
<ul class="feeds-list" id="sidebar-feeds-list">
26+
<li><a class="sidebar-item" href="#" id="sidebar-all-feeds">All Feeds</a></li>
27+
<li><a class="sidebar-item" href="#">Archer</a></li>
28+
<li><a class="sidebar-item" href="#">NetWitness</a></li>
3829
</ul>
39-
</div>
40-
<div class="bento-box">
41-
<h2>About</h2>
42-
<p>Welcome to RSS Feed News Release, your one-stop destination for the latest news and updates.</p>
43-
</div>
44-
<div class="bento-box">
45-
<h2>Contact</h2>
46-
<form>
47-
<input type="text" placeholder="Name" />
48-
<input type="email" placeholder="Email" />
49-
<textarea placeholder="Message"></textarea>
50-
<button type="submit">Submit</button>
51-
</form>
52-
</div>
30+
</section>
5331
</aside>
54-
<main>
55-
<div class="bento-container">
56-
<div class="bento-box">
57-
<h2>Latest News</h2>
58-
<div class="feed-items" id="feedItems">
59-
<!-- RSS feed items will be dynamically inserted here -->
32+
<main class="main-content glass-effect">
33+
<section class="posts-section">
34+
<article class="rss-post card">
35+
<div class="img-container">
36+
<img class="card-img" src="/image-placeholder.png" alt="Image description">
6037
</div>
61-
</div>
62-
63-
</div>
38+
<div>
39+
<h3>Title</h3>
40+
<div class="date-time">
41+
<time class="date">Date</time>
42+
<span class="separator"></span>
43+
<time class="time">Time</time>
44+
</div>
45+
<a class="source-post-link" href="#">Source</a>
46+
</div>
47+
</article>
48+
</section>
6449
</main>
65-
66-
<footer>
67-
<p>&copy;</p>
68-
</footer>
69-
7050
<script src="script.js"></script>
51+
<script src="./my-cors-proxy/server.js"></script>
52+
<script src="engine.js"></script>
53+
<script src="test.js"></script>
7154
</body>
72-
</html>
55+
</html>

my-cors-proxy/node_modules/.bin/mime

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)