Compare commits

..

2 Commits

Author SHA1 Message Date
743593affe Formatting. 2025-04-09 15:21:23 +02:00
44dd77cec5 Shed. 2025-04-09 15:12:34 +02:00
12 changed files with 62 additions and 54 deletions

View File

@ -17,8 +17,8 @@ from aiohttp_session import (
setup as session_setup, setup as session_setup,
) )
from aiohttp_session.cookie_storage import EncryptedCookieStorage from aiohttp_session.cookie_storage import EncryptedCookieStorage
from app.app import Application as BaseApplication
from app.app import Application as BaseApplication
from snek.docs.app import Application as DocsApplication from snek.docs.app import Application as DocsApplication
from snek.mapper import get_mappers from snek.mapper import get_mappers
from snek.service import get_services from snek.service import get_services
@ -92,10 +92,10 @@ class Application(BaseApplication):
self.on_startup.append(self.prepare_asyncio) self.on_startup.append(self.prepare_asyncio)
self.on_startup.append(self.prepare_database) self.on_startup.append(self.prepare_database)
async def prepare_asyncio(self,app): async def prepare_asyncio(self, app):
#app.loop = asyncio.get_running_loop() # app.loop = asyncio.get_running_loop()
app.executor = ThreadPoolExecutor(max_workers=200) app.executor = ThreadPoolExecutor(max_workers=200)
app.loop.set_default_executor(self.executor) app.loop.set_default_executor(self.executor)
async def create_task(self, task): async def create_task(self, task):
await self.tasks.put(task) await self.tasks.put(task)

View File

@ -1,8 +1,8 @@
import pathlib import pathlib
from aiohttp import web from aiohttp import web
from app.app import Application as BaseApplication
from app.app import Application as BaseApplication
from snek.system.markdown import MarkdownExtension from snek.system.markdown import MarkdownExtension

View File

@ -1,14 +1,25 @@
from snek.system.form import Form, FormInputElement, FormButtonElement, HTMLElement from snek.system.form import Form, FormButtonElement, FormInputElement, HTMLElement
class SettingsProfileForm(Form): class SettingsProfileForm(Form):
nick = FormInputElement(name="nick", required=True, place_holder="Your Nickname", min_length=1, max_length=20) nick = FormInputElement(
name="nick",
required=True,
place_holder="Your Nickname",
min_length=1,
max_length=20,
)
action = FormButtonElement( action = FormButtonElement(
name="action", value="submit", text="Save", type="button" name="action", value="submit", text="Save", type="button"
) )
title = HTMLElement(tag="h1", text="Profile") title = HTMLElement(tag="h1", text="Profile")
profile = FormInputElement(name="profile", place_holder="Tell about yourself.", required=False,max_length=300) profile = FormInputElement(
name="profile",
place_holder="Tell about yourself.",
required=False,
max_length=300,
)
action = FormButtonElement( action = FormButtonElement(
name="action", value="submit", text="Save", type="button" name="action", value="submit", text="Save", type="button"
) )

View File

@ -1,5 +1,3 @@
import mimetypes
from snek.system.model import BaseModel, ModelField from snek.system.model import BaseModel, ModelField
@ -7,4 +5,3 @@ class UserPropertyModel(BaseModel):
user_uid = ModelField(name="user_uid", required=True, kind=str) user_uid = ModelField(name="user_uid", required=True, kind=str)
name = ModelField(name="name", required=True, kind=str) name = ModelField(name="name", required=True, kind=str)
value = ModelField(name="path", required=True, kind=str) value = ModelField(name="path", required=True, kind=str)

View File

@ -9,9 +9,10 @@ from snek.service.drive_item import DriveItemService
from snek.service.notification import NotificationService from snek.service.notification import NotificationService
from snek.service.socket import SocketService from snek.service.socket import SocketService
from snek.service.user import UserService from snek.service.user import UserService
from snek.service.user_property import UserPropertyService
from snek.service.util import UtilService from snek.service.util import UtilService
from snek.system.object import Object from snek.system.object import Object
from snek.service.user_property import UserPropertyService
@functools.cache @functools.cache
def get_services(app): def get_services(app):

View File

@ -1,6 +1,5 @@
import pathlib import json
import json
from snek.system import security
from snek.system.service import BaseService from snek.system.service import BaseService
@ -14,12 +13,12 @@ class UserPropertyService(BaseService):
prop["user_uid"] = user_uid prop["user_uid"] = user_uid
prop["name"] = name prop["name"] = name
prop["value"] = json.dumps(value,default=str) prop["value"] = json.dumps(value, default=str)
return await self.save(prop) return await self.save(prop)
async def get(self, user_uid, name): async def get(self, user_uid, name):
try: try:
return json.loads((await self.get(user_uid=user_uid, name=name)).value) return json.loads((await self.get(user_uid=user_uid, name=name)).value)
except: except:
return None return None
@ -31,4 +30,3 @@ class UserPropertyService(BaseService):
async for result in self.find(name={"ilike": "%" + query + "%"}, **kwargs): async for result in self.find(name={"ilike": "%" + query + "%"}, **kwargs):
results.append(result) results.append(result)
return results return results

View File

@ -32,9 +32,10 @@ from urllib.parse import urljoin
import aiohttp import aiohttp
import imgkit import imgkit
from app.cache import time_cache_async
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from app.cache import time_cache_async
async def crc32(data): async def crc32(data):
try: try:

View File

@ -2,12 +2,13 @@
from types import SimpleNamespace from types import SimpleNamespace
from app.cache import time_cache_async
from mistune import HTMLRenderer, Markdown from mistune import HTMLRenderer, Markdown
from pygments import highlight from pygments import highlight
from pygments.formatters import html from pygments.formatters import html
from pygments.lexers import get_lexer_by_name from pygments.lexers import get_lexer_by_name
from app.cache import time_cache_async
class MarkdownRenderer(HTMLRenderer): class MarkdownRenderer(HTMLRenderer):

View File

@ -89,15 +89,13 @@ def set_link_target_blank(text):
def embed_youtube(text): def embed_youtube(text):
soup = BeautifulSoup(text, "html.parser") soup = BeautifulSoup(text, "html.parser")
for element in soup.find_all("a"): for element in soup.find_all("a"):
if ( if element.attrs["href"].startswith("https://www.you"):
element.attrs["href"].startswith("https://www.you")
):
video_name = element.attrs["href"].split("/")[-1] video_name = element.attrs["href"].split("/")[-1]
if "v=" in element.attrs["href"]: if "v=" in element.attrs["href"]:
video_name = element.attrs["href"].split("?v=")[1].split("&")[0] video_name = element.attrs["href"].split("?v=")[1].split("&")[0]
#if "si=" in element.attrs["href"]: # if "si=" in element.attrs["href"]:
# video_name = "?v=" + element.attrs["href"].split("/")[-1] # video_name = "?v=" + element.attrs["href"].split("/")[-1]
#if "t=" in element.attrs["href"]: # if "t=" in element.attrs["href"]:
# video_name += "&t=" + element.attrs["href"].split("&t=")[1].split("&")[0] # video_name += "&t=" + element.attrs["href"].split("&t=")[1].split("&")[0]
embed_template = f'<iframe width="560" height="315" style="display:block" src="https://www.youtube.com/embed/{video_name}" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>' embed_template = f'<iframe width="560" height="315" style="display:block" src="https://www.youtube.com/embed/{video_name}" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>'
element.replace_with(BeautifulSoup(embed_template, "html.parser")) element.replace_with(BeautifulSoup(embed_template, "html.parser"))

View File

@ -1,8 +1,9 @@
from snek.system.view import BaseView from snek.system.view import BaseView
class SettingsIndexView(BaseView): class SettingsIndexView(BaseView):
login_required = True login_required = True
async def get(self): async def get(self):
return await self.render_template('settings/index.html') return await self.render_template("settings/index.html")

View File

@ -1,7 +1,7 @@
from snek.system.view import BaseView,BaseFormView from aiohttp import web
from snek.form.settings.profile import SettingsProfileForm from snek.form.settings.profile import SettingsProfileForm
from aiohttp import web from snek.system.view import BaseFormView
class SettingsProfileView(BaseFormView): class SettingsProfileView(BaseFormView):
@ -11,13 +11,12 @@ class SettingsProfileView(BaseFormView):
async def get(self): async def get(self):
form = self.form(app=self.app) form = self.form(app=self.app)
if self.request.path.endswith(".json"):
form['nick'] = self.request['user']['nick']
return web.json_response(await form.to_json())
user = await self.services.user.get(uid=self.session.get("uid"))
if self.request.path.endswith(".json"):
form["nick"] = self.request["user"]["nick"]
return web.json_response(await form.to_json())
user = await self.services.user.get(uid=self.session.get("uid"))
return await self.render_template( return await self.render_template(
"settings/profile.html", {"form": await form.to_json(), "user": user} "settings/profile.html", {"form": await form.to_json(), "user": user}
@ -28,9 +27,8 @@ class SettingsProfileView(BaseFormView):
form.set_user_data(post["form"]) form.set_user_data(post["form"])
if await form.is_valid: if await form.is_valid:
user = self.request['user'] user = self.request["user"]
user["nick"] = form["nick"] user["nick"] = form["nick"]
await self.services.user.save(user) await self.services.user.save(user)
return {"redirect_url": "/settings/profile.html"} return {"redirect_url": "/settings/profile.html"}
return {"is_valid": False} return {"is_valid": False}

View File

@ -1,8 +1,7 @@
import logging import logging
import pathlib import pathlib
import asyncio
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG)
from app.cache import time_cache,time_cache_async
import base64 import base64
import datetime import datetime
import mimetypes import mimetypes
@ -15,6 +14,9 @@ import aiohttp
import aiohttp.web import aiohttp.web
from lxml import etree from lxml import etree
from app.cache import time_cache_async
@aiohttp.web.middleware @aiohttp.web.middleware
async def debug_middleware(request, handler): async def debug_middleware(request, handler):
print(request.method, request.path, request.headers) print(request.method, request.path, request.headers)
@ -26,13 +28,14 @@ async def debug_middleware(request, handler):
pass pass
return result return result
class WebdavApplication(aiohttp.web.Application): class WebdavApplication(aiohttp.web.Application):
def __init__(self, parent, *args, **kwargs): def __init__(self, parent, *args, **kwargs):
middlewares = [debug_middleware] middlewares = [debug_middleware]
super().__init__(middlewares=middlewares, *args, **kwargs) super().__init__(middlewares=middlewares, *args, **kwargs)
self.locks = {} self.locks = {}
self.relative_url = "/webdav" self.relative_url = "/webdav"
self.router.add_route("OPTIONS", "/{filename:.*}", self.handle_options) self.router.add_route("OPTIONS", "/{filename:.*}", self.handle_options)
@ -182,10 +185,10 @@ class WebdavApplication(aiohttp.web.Application):
@time_cache_async(10) @time_cache_async(10)
async def get_file_size(self, path): async def get_file_size(self, path):
loop = self.parent.loop loop = self.parent.loop
stat = await loop.run_in_executor(None,os.stat, path) stat = await loop.run_in_executor(None, os.stat, path)
return stat.st_size return stat.st_size
@time_cache_async(10) @time_cache_async(10)
async def get_directory_size(self, directory): async def get_directory_size(self, directory):
total_size = 0 total_size = 0
@ -196,11 +199,10 @@ class WebdavApplication(aiohttp.web.Application):
total_size += await self.get_file_size(str(fp)) total_size += await self.get_file_size(str(fp))
return total_size return total_size
@time_cache_async(30)
@time_cache_async(30)
async def get_disk_free_space(self, path="/"): async def get_disk_free_space(self, path="/"):
loop = self.parent.loop loop = self.parent.loop
statvfs = await loop.run_in_executor(None,os.statvfs, path) statvfs = await loop.run_in_executor(None, os.statvfs, path)
return statvfs.f_bavail * statvfs.f_frsize return statvfs.f_bavail * statvfs.f_frsize
async def create_node(self, request, response_xml, full_path, depth): async def create_node(self, request, response_xml, full_path, depth):
@ -208,9 +210,9 @@ class WebdavApplication(aiohttp.web.Application):
relative_path = str(full_path.relative_to(request["home"])) relative_path = str(full_path.relative_to(request["home"]))
href_path = f"{self.relative_url}/{relative_path}".strip(".") href_path = f"{self.relative_url}/{relative_path}".strip(".")
href_path = href_path.replace("./","/") href_path = href_path.replace("./", "/")
href_path = href_path.replace("//", "/") href_path = href_path.replace("//", "/")
response = etree.SubElement(response_xml, "{DAV:}response") response = etree.SubElement(response_xml, "{DAV:}response")
href = etree.SubElement(response, "{DAV:}href") href = etree.SubElement(response, "{DAV:}href")
href.text = href_path href.text = href_path
@ -270,7 +272,7 @@ class WebdavApplication(aiohttp.web.Application):
pass pass
requested_path = request.match_info.get("filename", "") requested_path = request.match_info.get("filename", "")
abs_path = request["home"] / requested_path abs_path = request["home"] / requested_path
if not abs_path.exists(): if not abs_path.exists():
return aiohttp.web.Response(status=404, text="Directory not found") return aiohttp.web.Response(status=404, text="Directory not found")
@ -316,7 +318,7 @@ class WebdavApplication(aiohttp.web.Application):
resource = request.match_info.get("filename", "/") resource = request.match_info.get("filename", "/")
lock_token = request.headers.get("Lock-Token", "").replace( lock_token = request.headers.get("Lock-Token", "").replace(
"opaquelocktoken:", "" "opaquelocktoken:", ""
)[1:-1] )[1:-1]
if self.locks.get(resource) == lock_token: if self.locks.get(resource) == lock_token:
del self.locks[resource] del self.locks[resource]
return aiohttp.web.Response(status=204) return aiohttp.web.Response(status=204)