Compare commits

...

6 Commits

  1. 4
      ozgursozluk/__init__.py
  2. 41
      ozgursozluk/api.py
  3. 6
      ozgursozluk/models.py
  4. 2
      ozgursozluk/static/style.css
  5. 11
      ozgursozluk/templates/base.html
  6. 6
      ozgursozluk/templates/macros.html
  7. 27
      ozgursozluk/templates/search.html
  8. 2
      ozgursozluk/templates/settings.html
  9. 17
      ozgursozluk/views.py
  10. 10
      pyproject.toml
  11. 2
      tests.py

@ -3,8 +3,8 @@ from flask import Flask
from ozgursozluk.configs import SECRET_KEY
__version__ = "0.7.3"
__source__ = "https://github.com/beucismis/ozgursozluk"
__version__ = "0.7.4"
__source_code__ = "https://github.com/beucismis/ozgursozluk"
__description__ = "a free and open source alternative ekşi sözlük front-end"
app = Flask(__name__)

@ -6,7 +6,7 @@ from bs4 import BeautifulSoup
from fake_useragent import UserAgent
from ozgursozluk.configs import EKSI_SOZLUK_BASE_URL
from ozgursozluk.models import Entry, EntryTopic, Topic, Author, Gundem, Debe
from ozgursozluk.models import Entry, EntryTopic, Topic, Author, Gundem, Debe, SearchResult
class EksiSozluk:
@ -20,13 +20,11 @@ class EksiSozluk:
headers = headers or {"User-Agent": UserAgent().random}
self.session.headers.update(headers)
def request(self, method: str, path: str = "/", **params) -> BeautifulSoup:
def request(self, method: str, path: str = "/", params: dict = {}) -> BeautifulSoup:
"""Make a request."""
response = self.session.request(
method,
f"{self.base_url}/{path}",
params=params,
method, f"{self.base_url}{path}", params=params,
)
if response.status_code != 200:
@ -49,28 +47,31 @@ class EksiSozluk:
int(entry.attrs["data-favorite-count"]),
)
def search_topic(self, query: str) -> Topic:
"""Search topic for the given query."""
def search_topic(self, keywords: str) -> Iterator[SearchResult]:
"""Search topic for the given keywords."""
response = self.request("GET", q=query)
h1 = response.find("h1", id="title")
pager = response.find("div", class_="pager")
payload = {
"SearchForm.Keywords": keywords,
"SearchForm.NiceOnly": True,
"SearchForm.SortOrder": "Count",
}
response = self.request("GET", "/basliklar/ara", payload)
topic_list = response.find("ul", class_="topic-list").find_all("a", href=True)
return Topic(
int(h1.attrs["data-id"]),
h1.attrs["data-title"],
h1.find("a")["href"][1:],
self.entrys(response),
int(pager.attrs["data-pagecount"]) if pager else 0,
)
for topic in topic_list:
yield SearchResult(
topic.contents[0],
topic["href"].split("?")[0],
None if len(topic.contents) < 2 else topic.contents[1].text,
)
def get_topic(self, path: str, page: int = 1, a: Optional[str] = None) -> Topic:
"""Get topic for the given path."""
if a is None:
response = self.request("GET", f"/{path}", p=page)
response = self.request("GET", f"/{path}", {"p": page})
else:
response = self.request("GET", f"/{path}", p=page, a=a)
response = self.request("GET", f"/{path}", {"p": page, "a": a})
h1 = response.find("h1", id="title")
pager = response.find("div", class_="pager")
@ -127,7 +128,7 @@ class EksiSozluk:
https://eksisozluk.com/basliklar/gundem
"""
response = self.request("GET", "/basliklar/gundem", p=page)
response = self.request("GET", "/basliklar/gundem", {"p": page})
topic_list = response.find("ul", class_="topic-list").find_all("a", href=True)
for topic in topic_list:

@ -53,3 +53,9 @@ class Gundem:
class Debe:
id: int
title: str
@dataclass
class SearchResult:
title: str
path: str
entry_count: Union[str, None] = None

@ -193,7 +193,7 @@ form input, form select, form button {
text-align: left;
}
header a, .info a, .settings a {
header a, .author a, .info a, .settings a {
font-size: larger;
}

@ -1,7 +1,8 @@
<!DOCTYPE html>
<html>
<html lang="tr">
<head>
<meta charset="utf-8">
<meta charset="UTF-8">
<meta content="origin" name="referrer">
{% block meta %}{% endblock %}
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="{{ url_for('static', filename='favicon.png') }}">
@ -12,9 +13,7 @@
{% set filename = '{}.css'.format(request.cookies.get('theme')) %}
<link rel="stylesheet" href="{{ url_for('static', filename=filename) }}">
{% endif %}
<title>
{% block title %}{% endblock %}
</title>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<header>
@ -22,7 +21,7 @@
<a href="{{ url_for('random') }}">random</a>
<a href="{{ url_for('donate') }}">donate</a>
<a href="{{ url_for('settings') }}">settings</a>
<a href="{{ source }}" target="_blank">source code</a>
<a href="{{ source_code }}" target="_blank">source code</a>
</div>
</header>
<main>

@ -39,9 +39,7 @@
{% macro render_gundem(topic) %}
<a href="{{ url_for('topic', path=topic.path, a='popular') }}" class="entry">
<div style="display: flex; justify-content: space-between;">
<div>
{{ topic.title }}
</div>
<div>{{ topic.title }}</div>
<div>
{% if topic.pinned %}<small style="opacity: 0.5;">pinned</small>{% endif %}
{% if topic.entry_count %}
@ -50,4 +48,4 @@
</div>
</div>
</a>
{% endmacro %}
{% endmacro %}

@ -0,0 +1,27 @@
{% extends "base.html" %}
{% block title %}search - özgürsözlük{% endblock %}
{% block meta %}
<meta name="title" content="search - özgürsözlük">
<meta name="description" content="{{ q }}">
{% endblock %}
{% block main %}
<nav>{% include "navigation.html" %}</nav>
<div class="topic">
<div class="info">
<div><p>search result: {{ q }}</p></div>
<div></div>
</div>
{% for topic in search_result %}
<a href="{{ url_for('topic', path=topic.path) }}" class="entry">
<div style="display: flex; justify-content: space-between;">
<div>{{ topic.title }}</div>
<div>
{% if topic.entry_count %}
<small style="opacity: 0.5;">{{ topic.entry_count }}</small>
{% endif %}
</div>
</div>
</a>
{% endfor %}
</div>
{% endblock %}

@ -73,7 +73,7 @@
v{{ version }}
-
last commit:
<a href="{{ source }}/commit/{{ last_commit }}" target="_blank">{{ last_commit[:8] }}</a>
<a href="{{ source_code }}/commit/{{ last_commit }}" target="_blank">{{ last_commit[:8] }}</a>
-
made with <3 on the <a href="{{ url_for('topic', path='thinkpad-t61--1883047') }}">t61</a>
</br></br>

@ -20,7 +20,7 @@ def global_template_variables():
last_commit=last_commit(),
contributors=contributors(),
version=ozgursozluk.__version__,
source=ozgursozluk.__source__,
source_code=ozgursozluk.__source_code__,
description=ozgursozluk.__description__,
)
@ -36,7 +36,7 @@ def index():
return redirect(url_for("search", q=q))
if request.method == "POST":
return redirect(url_for("search", q=request.form["q"]))
return redirect(url_for("search", q=request.form["q"] or None))
gundem = es.get_gundem(p)
@ -74,16 +74,21 @@ def debe():
return render_template("debe.html", debe=es.get_debe())
@ozgursozluk.app.route("/search/<q>")
def search(q: str):
@ozgursozluk.app.route("/search")
def search():
"""Search route."""
return render_template("topic.html", topic=es.search_topic(q), p=1, a=None)
q = request.args.get("q", default=None, type=str)
if q is None or not bool(len(q)):
return render_template("404.html"), 404
return render_template("search.html", search_result=es.search_topic(q), q=q)
@ozgursozluk.app.route("/random")
def random():
return redirect(url_for("entry", id=randint(1, 500_000_000)))
return redirect(url_for("entry", id=randint(1, 300_000_000)))
@ozgursozluk.app.route("/donate")

@ -4,10 +4,9 @@ build-backend = "setuptools.build_meta"
[project]
name = "ozgursozluk"
authors = [
{name = "beucismis", email = "beucismis@tutamail.com"},
]
authors = [{name = "beucismis", email = "beucismis@tutamail.com"}]
description = "A free and open source alternative ekşi sözlük front-end"
readme = "README.md"
requires-python = ">=3.8"
keywords = [
"alternative", "flask", "front-end", "eksisozluk", "self-hosted",
@ -22,10 +21,7 @@ classifiers = [
dynamic = ["version", "dependencies"]
[tool.poetry]
readme = "README.md"
include = [
"ozgursozluk/static/*", "ozgursozluk/templates/*",
]
include = ["ozgursozluk/static/*", "ozgursozluk/templates/*"]
[tool.setuptools.dynamic]
version = {attr = "ozgursozluk.__version__"}

@ -4,7 +4,7 @@ from ozgursozluk.api import EksiSozluk
es = EksiSozluk()
topic = es.search_topic("linux")
topic = es.get_topic("linux--32084")
entry = es.get_entry(1)

Loading…
Cancel
Save