feat: encode member usernames in URLs and add docstrings
Added URL encoding for member usernames to prevent errors with special characters in profile and Instructables URLs. Improved code readability by including docstrings for route functions, and refined HTML templates to conditionally display member location only if it exists. Updated the project version to 0.3.8.
This commit is contained in:
parent
f576555005
commit
cfb81fada1
4 changed files with 35 additions and 12 deletions
|
@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "structables"
|
name = "structables"
|
||||||
version = "0.3.7"
|
version = "0.3.8"
|
||||||
authors = [
|
authors = [
|
||||||
{ name="Private.coffee Team", email="support@private.coffee" },
|
{ name="Private.coffee Team", email="support@private.coffee" },
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,14 +1,32 @@
|
||||||
from flask import render_template, abort
|
from flask import render_template, abort
|
||||||
from urllib.request import urlopen
|
from urllib.request import urlopen
|
||||||
from urllib.error import HTTPError
|
from urllib.error import HTTPError
|
||||||
|
from urllib.parse import quote
|
||||||
from ..utils.helpers import proxy, member_header
|
from ..utils.helpers import proxy, member_header
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
from urllib.request import Request
|
from urllib.request import Request
|
||||||
|
|
||||||
|
|
||||||
def init_member_routes(app):
|
def init_member_routes(app):
|
||||||
|
"""This function initializes all the routes related to Instructables member profiles.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
app (Flask): The Flask app instance.
|
||||||
|
"""
|
||||||
|
|
||||||
@app.route("/member/<member>/instructables/")
|
@app.route("/member/<member>/instructables/")
|
||||||
def route_member_instructables(member):
|
def route_member_instructables(member):
|
||||||
|
"""Route to display a member's Instructables.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
member (str): The member's username.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response: The rendered HTML page.
|
||||||
|
"""
|
||||||
|
|
||||||
|
member = quote(member)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
data = urlopen(
|
data = urlopen(
|
||||||
f"https://www.instructables.com/member/{member}/instructables/"
|
f"https://www.instructables.com/member/{member}/instructables/"
|
||||||
|
@ -55,13 +73,18 @@ def init_member_routes(app):
|
||||||
|
|
||||||
@app.route("/member/<member>/")
|
@app.route("/member/<member>/")
|
||||||
def route_member(member):
|
def route_member(member):
|
||||||
headers = {
|
"""Route to display a member's profile.
|
||||||
"User-Agent": "Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/113.0"
|
|
||||||
}
|
|
||||||
|
|
||||||
request = Request(
|
Args:
|
||||||
f"https://www.instructables.com/member/{member}/", headers=headers
|
member (str): The member's username.
|
||||||
)
|
|
||||||
|
Returns:
|
||||||
|
Response: The rendered HTML page.
|
||||||
|
"""
|
||||||
|
|
||||||
|
member = quote(member)
|
||||||
|
|
||||||
|
request = Request(f"https://www.instructables.com/member/{member}/")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
data = urlopen(request)
|
data = urlopen(request)
|
||||||
|
@ -103,9 +126,9 @@ def init_member_routes(app):
|
||||||
"div.achievements-section.main-achievements.contest-achievements div.achievement-item:not(.two-column-filler)"
|
"div.achievements-section.main-achievements.contest-achievements div.achievement-item:not(.two-column-filler)"
|
||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
ach_title = ach.select("div.achievement-info span.achievement-title")[
|
ach_title = ach.select(
|
||||||
0
|
"div.achievement-info span.achievement-title"
|
||||||
].text
|
)[0].text
|
||||||
ach_desc = ach.select(
|
ach_desc = ach.select(
|
||||||
"div.achievement-info span.achievement-description"
|
"div.achievement-info span.achievement-description"
|
||||||
)[0].text
|
)[0].text
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<center>
|
<center>
|
||||||
<img width=150px height=150px style="display:inline-block;" src="{{ header_content.avatar }}" alt="{{ header_content.title }}">
|
<img width=150px height=150px style="display:inline-block;" src="{{ header_content.avatar }}" alt="{{ header_content.title }}">
|
||||||
<h1>{{ header_content.title }}</h1>
|
<h1>{{ header_content.title }}</h1>
|
||||||
<span>{{ header_content.location }} </span>
|
<span>{% if header_content.location %}{{ header_content.location }} {% endif %}</span>
|
||||||
<span>{{ header_content.signup }}</span>
|
<span>{{ header_content.signup }}</span>
|
||||||
<br>
|
<br>
|
||||||
<span>{{ header_content.instructables }} Instructables </span>
|
<span>{{ header_content.instructables }} Instructables </span>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<center>
|
<center>
|
||||||
<img width=150px height=150px style="display:inline-block;" src="{{ header_content.avatar }}" alt="{{ header_content.title }}">
|
<img width=150px height=150px style="display:inline-block;" src="{{ header_content.avatar }}" alt="{{ header_content.title }}">
|
||||||
<h1>{{ header_content.title }}</h1>
|
<h1>{{ header_content.title }}</h1>
|
||||||
<span>{{ header_content.location }} </span>
|
<span>{% if header_content.location %}{{ header_content.location }} {% endif %}</span>
|
||||||
<span>{{ header_content.signup }}</span>
|
<span>{{ header_content.signup }}</span>
|
||||||
<br>
|
<br>
|
||||||
<span>{{ header_content.instructables }} Instructables </span>
|
<span>{{ header_content.instructables }} Instructables </span>
|
||||||
|
|
Loading…
Reference in a new issue