Spaces:
Running
Running
michaelkri commited on
Commit ·
037df93
1
Parent(s): 00f9b6a
Minor improvements
Browse files- app/summarizer.py +7 -7
- app/templates/index.html +61 -17
app/summarizer.py
CHANGED
|
@@ -8,13 +8,13 @@ import logging
|
|
| 8 |
|
| 9 |
class Summarizer:
|
| 10 |
ARTICLE_CATEGORIES = [
|
|
|
|
| 11 |
'politics',
|
| 12 |
'technology',
|
| 13 |
'sports',
|
| 14 |
'entertainment',
|
| 15 |
-
'
|
| 16 |
-
'health'
|
| 17 |
-
'world news'
|
| 18 |
]
|
| 19 |
|
| 20 |
|
|
@@ -45,7 +45,7 @@ class Summarizer:
|
|
| 45 |
return self.embedding_model.encode(sentences)
|
| 46 |
|
| 47 |
|
| 48 |
-
def summarize(self, content, min_length=30, max_length=
|
| 49 |
# truncate content if exceeds model capabilities
|
| 50 |
max_model_length = self.summarization_model.model.config.max_position_embeddings
|
| 51 |
if len(content) > max_model_length:
|
|
@@ -74,7 +74,7 @@ class Summarizer:
|
|
| 74 |
return ranked_sentences
|
| 75 |
|
| 76 |
|
| 77 |
-
def summarize_clusters(self, clusters, top_cluster_count=
|
| 78 |
# sort clusters by their length (descending) to find the most important topics
|
| 79 |
clusters = sorted(clusters, key=len, reverse=True)
|
| 80 |
|
|
@@ -86,7 +86,7 @@ class Summarizer:
|
|
| 86 |
for i, cluster in enumerate(clusters):
|
| 87 |
logging.debug(f'Extracting from cluster {i + 1}...')
|
| 88 |
top_sentences = Summarizer.rank_cluster_sentences(cluster)
|
| 89 |
-
content = '\n'.join(top_sentences[:
|
| 90 |
key_sentences.append(content)
|
| 91 |
|
| 92 |
combined = ' '.join(key_sentences)
|
|
@@ -96,7 +96,7 @@ class Summarizer:
|
|
| 96 |
summary = self.summarize(
|
| 97 |
combined,
|
| 98 |
min_length=60,
|
| 99 |
-
max_length=
|
| 100 |
)
|
| 101 |
return summary
|
| 102 |
|
|
|
|
| 8 |
|
| 9 |
class Summarizer:
|
| 10 |
ARTICLE_CATEGORIES = [
|
| 11 |
+
'world',
|
| 12 |
'politics',
|
| 13 |
'technology',
|
| 14 |
'sports',
|
| 15 |
'entertainment',
|
| 16 |
+
'economy',
|
| 17 |
+
'health'
|
|
|
|
| 18 |
]
|
| 19 |
|
| 20 |
|
|
|
|
| 45 |
return self.embedding_model.encode(sentences)
|
| 46 |
|
| 47 |
|
| 48 |
+
def summarize(self, content, min_length=30, max_length=200):
|
| 49 |
# truncate content if exceeds model capabilities
|
| 50 |
max_model_length = self.summarization_model.model.config.max_position_embeddings
|
| 51 |
if len(content) > max_model_length:
|
|
|
|
| 74 |
return ranked_sentences
|
| 75 |
|
| 76 |
|
| 77 |
+
def summarize_clusters(self, clusters, top_cluster_count=20):
|
| 78 |
# sort clusters by their length (descending) to find the most important topics
|
| 79 |
clusters = sorted(clusters, key=len, reverse=True)
|
| 80 |
|
|
|
|
| 86 |
for i, cluster in enumerate(clusters):
|
| 87 |
logging.debug(f'Extracting from cluster {i + 1}...')
|
| 88 |
top_sentences = Summarizer.rank_cluster_sentences(cluster)
|
| 89 |
+
content = '\n'.join(top_sentences[:2])
|
| 90 |
key_sentences.append(content)
|
| 91 |
|
| 92 |
combined = ' '.join(key_sentences)
|
|
|
|
| 96 |
summary = self.summarize(
|
| 97 |
combined,
|
| 98 |
min_length=60,
|
| 99 |
+
max_length=400
|
| 100 |
)
|
| 101 |
return summary
|
| 102 |
|
app/templates/index.html
CHANGED
|
@@ -64,7 +64,7 @@
|
|
| 64 |
<ul class="space-y-2 font-medium">
|
| 65 |
{% for category in categorized_articles.keys() %}
|
| 66 |
<li>
|
| 67 |
-
<a href="#"
|
| 68 |
class="flex items-center p-2 text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700 group">
|
| 69 |
<span class="flex-1 ms-3 whitespace-nowrap">{{ category | capitalize }}</span>
|
| 70 |
</a>
|
|
@@ -110,24 +110,39 @@
|
|
| 110 |
|
| 111 |
<div class="p-8 sm:ml-64 mt-14">
|
| 112 |
{% for category, articles in categorized_articles.items() %}
|
| 113 |
-
<div
|
| 114 |
<h1 class="text-2xl font-semibold tracking-tight text-gray-900">{{ category | capitalize }}</h1>
|
| 115 |
|
| 116 |
{% for article in articles %}
|
| 117 |
<article>
|
| 118 |
<hr class="h-px my-8 bg-gray-200 border-0 dark:bg-gray-700">
|
| 119 |
<span class="text-sm text-gray-500">{{ article.date }}</span>
|
| 120 |
-
<h2 class="mb-4 mt-4 text-xl font-
|
| 121 |
<p class="text-base mb-4">
|
| 122 |
{{ article.content }}
|
| 123 |
</p>
|
| 124 |
-
<button type="button"
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
<
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 131 |
</button>
|
| 132 |
<div class="collapsible-content">
|
| 133 |
<div class="bg-gray-100 p-4 rounded-lg mt-4 {% if not article.sources %}hidden{% endif %}">
|
|
@@ -135,11 +150,10 @@
|
|
| 135 |
<ul class="list-inside mb-4">
|
| 136 |
{% for source in article.sources %}
|
| 137 |
<li>
|
| 138 |
-
<a href="{{ source.url }}" class="flex justify-start items-center space-x-2">
|
| 139 |
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
| 140 |
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
| 141 |
-
stroke-linejoin="round"
|
| 142 |
-
class="h-3 w-3 flex-shrink-0" aria-hidden="true">
|
| 143 |
<path d="M15 3h6v6"></path>
|
| 144 |
<path d="M10 14 21 3"></path>
|
| 145 |
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path>
|
|
@@ -172,16 +186,46 @@
|
|
| 172 |
allToggleButtons.forEach(button => {
|
| 173 |
button.addEventListener('click', function () {
|
| 174 |
const content = this.nextElementSibling;
|
| 175 |
-
const
|
| 176 |
-
const
|
| 177 |
|
| 178 |
content.classList.toggle('expanded');
|
| 179 |
|
| 180 |
-
|
| 181 |
-
|
| 182 |
});
|
| 183 |
});
|
| 184 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 185 |
</script>
|
| 186 |
</body>
|
| 187 |
|
|
|
|
| 64 |
<ul class="space-y-2 font-medium">
|
| 65 |
{% for category in categorized_articles.keys() %}
|
| 66 |
<li>
|
| 67 |
+
<a href="#{{ category }}"
|
| 68 |
class="flex items-center p-2 text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700 group">
|
| 69 |
<span class="flex-1 ms-3 whitespace-nowrap">{{ category | capitalize }}</span>
|
| 70 |
</a>
|
|
|
|
| 110 |
|
| 111 |
<div class="p-8 sm:ml-64 mt-14">
|
| 112 |
{% for category, articles in categorized_articles.items() %}
|
| 113 |
+
<div id="{{ category }}" class="block w-full mb-8 rounded-lg border border-gray-300 border-l-4 border-l-blue-500 bg-white p-6">
|
| 114 |
<h1 class="text-2xl font-semibold tracking-tight text-gray-900">{{ category | capitalize }}</h1>
|
| 115 |
|
| 116 |
{% for article in articles %}
|
| 117 |
<article>
|
| 118 |
<hr class="h-px my-8 bg-gray-200 border-0 dark:bg-gray-700">
|
| 119 |
<span class="text-sm text-gray-500">{{ article.date }}</span>
|
| 120 |
+
<h2 class="mb-4 mt-4 text-xl font-semibold tracking-tight text-gray-900">{{ article.title }}</h2>
|
| 121 |
<p class="text-base mb-4">
|
| 122 |
{{ article.content }}
|
| 123 |
</p>
|
| 124 |
+
<button type="button"
|
| 125 |
+
class="toggle-button flex items-center space-x-2 text-gray-900 bg-white border border-gray-300 focus:outline-none focus:ring-4 focus:ring-gray-100 hover:bg-gray-100 font-semibold rounded-lg text-sm px-4 py-2 me-2 mb-2"
|
| 126 |
+
aria-expanded="false" aria-controls="content-to-toggle">
|
| 127 |
+
<div class="icon-container relative w-4 h-4">
|
| 128 |
+
<svg id="chevron-down" xmlns="http://www.w3.org/2000/svg" width="24" height="24"
|
| 129 |
+
viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"
|
| 130 |
+
stroke-linecap="round" stroke-linejoin="round"
|
| 131 |
+
class="lucide lucide-chevron-down w-full h-full transition-opacity duration-300"
|
| 132 |
+
aria-hidden="true">
|
| 133 |
+
<path d="m6 9 6 6 6-6"></path>
|
| 134 |
+
</svg>
|
| 135 |
+
|
| 136 |
+
<svg id="chevron-up" xmlns="http://www.w3.org/2000/svg" width="24" height="24"
|
| 137 |
+
viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"
|
| 138 |
+
stroke-linecap="round" stroke-linejoin="round"
|
| 139 |
+
class="lucide lucide-chevron-up w-full h-full absolute top-0 left-0 opacity-0 transition-opacity duration-300"
|
| 140 |
+
aria-hidden="true">
|
| 141 |
+
<path d="m18 15-6-6-6 6"></path>
|
| 142 |
+
</svg>
|
| 143 |
+
</div>
|
| 144 |
+
|
| 145 |
+
<span>Sources ({{ article.sources | length }})</span>
|
| 146 |
</button>
|
| 147 |
<div class="collapsible-content">
|
| 148 |
<div class="bg-gray-100 p-4 rounded-lg mt-4 {% if not article.sources %}hidden{% endif %}">
|
|
|
|
| 150 |
<ul class="list-inside mb-4">
|
| 151 |
{% for source in article.sources %}
|
| 152 |
<li>
|
| 153 |
+
<a href="{{ source.url }}" class="flex justify-start items-center space-x-2 mb-2">
|
| 154 |
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
| 155 |
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
| 156 |
+
stroke-linejoin="round" class="h-3 w-3 flex-shrink-0" aria-hidden="true">
|
|
|
|
| 157 |
<path d="M15 3h6v6"></path>
|
| 158 |
<path d="M10 14 21 3"></path>
|
| 159 |
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path>
|
|
|
|
| 186 |
allToggleButtons.forEach(button => {
|
| 187 |
button.addEventListener('click', function () {
|
| 188 |
const content = this.nextElementSibling;
|
| 189 |
+
const downChevron = this.querySelector('.plus-icon');
|
| 190 |
+
const upChevron = this.querySelector('.minus-icon');
|
| 191 |
|
| 192 |
content.classList.toggle('expanded');
|
| 193 |
|
| 194 |
+
downChevron.classList.toggle('hidden');
|
| 195 |
+
upChevron.classList.toggle('hidden');
|
| 196 |
});
|
| 197 |
});
|
| 198 |
});
|
| 199 |
+
|
| 200 |
+
document.addEventListener('DOMContentLoaded', () => {
|
| 201 |
+
const toggleButton = document.querySelector('.toggle-button');
|
| 202 |
+
|
| 203 |
+
if (toggleButton) {
|
| 204 |
+
const targetId = toggleButton.getAttribute('aria-controls');
|
| 205 |
+
const targetContent = document.getElementById(targetId);
|
| 206 |
+
|
| 207 |
+
const chevronDown = document.getElementById('chevron-down');
|
| 208 |
+
const chevronUp = document.getElementById('chevron-up');
|
| 209 |
+
|
| 210 |
+
toggleButton.addEventListener('click', () => {
|
| 211 |
+
const isExpanded = toggleButton.getAttribute('aria-expanded') === 'true';
|
| 212 |
+
|
| 213 |
+
toggleButton.setAttribute('aria-expanded', String(!isExpanded));
|
| 214 |
+
|
| 215 |
+
if (targetContent) {
|
| 216 |
+
targetContent.classList.toggle('hidden');
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
if (!isExpanded) {
|
| 220 |
+
chevronDown.classList.add('opacity-0');
|
| 221 |
+
chevronUp.classList.remove('opacity-0');
|
| 222 |
+
} else {
|
| 223 |
+
chevronDown.classList.remove('opacity-0');
|
| 224 |
+
chevronUp.classList.add('opacity-0');
|
| 225 |
+
}
|
| 226 |
+
});
|
| 227 |
+
}
|
| 228 |
+
});
|
| 229 |
</script>
|
| 230 |
</body>
|
| 231 |
|