Compare commits
68 Commits
02388c80de
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 6678aed520 | |||
| a692ac8b05 | |||
| 11a0aa2d89 | |||
| 39fd46028f | |||
| 0107b7add7 | |||
| 5ee723e476 | |||
| 85927ef3d9 | |||
| 80baf62cc0 | |||
| f1fa3c6b36 | |||
| a9c6e6661f | |||
| 0c6e438b39 | |||
| 151e9c8ed3 | |||
| 2b56f1b6e1 | |||
| 3b90e814fc | |||
| d9c4c64ea7 | |||
| eb04b48e72 | |||
| da594e8e8c | |||
| 34a375c50d | |||
| 69295768d5 | |||
| df24780183 | |||
| 603eb6433c | |||
| db749bb2d6 | |||
| 166603f931 | |||
| aca340cde8 | |||
| 31b2f7ddc6 | |||
| e61a9c1540 | |||
| c996fea78d | |||
| 2dc8703577 | |||
| f565be6585 | |||
| 50e8bd9d10 | |||
| 429958600e | |||
| 490fc9cb8a | |||
| 5ba107cf28 | |||
| c13740a203 | |||
| f0a6c05791 | |||
| f55f12bb76 | |||
| 7a68db88f1 | |||
| 68c7217ada | |||
| f06f7a567c | |||
| 6e02785c12 | |||
| 287c8cf127 | |||
| 32f07554c0 | |||
| 29431b3786 | |||
| ce15671c64 | |||
| a47474a9f5 | |||
| 1321c9b068 | |||
| 7109834d42 | |||
| c46f5f0dfb | |||
| 04763146fa | |||
| 42168a2a3f | |||
| c9311fed30 | |||
| bc9515c412 | |||
| 8cf630c9c1 | |||
| d536863bcd | |||
| 5fc9831d55 | |||
| 448ee12f96 | |||
| 02022fe2f2 | |||
| 98e4e1e74b | |||
| d5effaa3e2 | |||
| 7a312b38b5 | |||
| ba944298fb | |||
| 0430dcc079 | |||
| acb0c6937d | |||
| 54850ec97c | |||
| b3a2205fef | |||
| f843a9cff9 | |||
| 1214405b27 | |||
| ec9fb118f1 |
22
.gitea/workflows/testing_on_host.yaml
Normal file
22
.gitea/workflows/testing_on_host.yaml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
name: test
|
||||||
|
|
||||||
|
on:
|
||||||
|
- pull_request
|
||||||
|
- push
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-docs:
|
||||||
|
runs-on: shell
|
||||||
|
steps:
|
||||||
|
- name: Run ansible Version
|
||||||
|
shell: bash
|
||||||
|
run: ansible --version
|
||||||
|
- name: Show all Vars
|
||||||
|
shell: bash
|
||||||
|
run: env
|
||||||
|
- name: Run 2
|
||||||
|
shell: bash
|
||||||
|
run: echo "Hello World"
|
||||||
|
- name: Test User
|
||||||
|
shell: bash
|
||||||
|
run: echo "Ich bin User $USER"
|
||||||
67
SSH_Agent/main.py
Executable file
67
SSH_Agent/main.py
Executable file
@@ -0,0 +1,67 @@
|
|||||||
|
#! /usr/bin/env python3.13
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
|
def import_ssh_keys_to_agent(privat_key=str):
|
||||||
|
try:
|
||||||
|
run_add_key = subprocess.run(
|
||||||
|
["/usr/bin/ssh-add", "-q", privat_key],
|
||||||
|
shell=False,
|
||||||
|
text=False,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
|
timeout=10,
|
||||||
|
)
|
||||||
|
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
print("\n", "Timeout, No Import :", privat_key)
|
||||||
|
return False
|
||||||
|
|
||||||
|
# print(run_add_key)
|
||||||
|
if run_add_key.returncode == 0:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_key_exist(ssh_pub=str):
|
||||||
|
if not os.path.exists(ssh_pub):
|
||||||
|
return False
|
||||||
|
run_check_key = subprocess.run(
|
||||||
|
["/usr/bin/ssh-add", "-L"],
|
||||||
|
shell=False,
|
||||||
|
text=False,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
|
)
|
||||||
|
|
||||||
|
list_agent_pubs = str(run_check_key.stdout, encoding="utf-8").splitlines()
|
||||||
|
read_input_pub = open(ssh_pub)
|
||||||
|
READ_FILE_PUB = read_input_pub.read()
|
||||||
|
count = 0
|
||||||
|
for pub in list_agent_pubs:
|
||||||
|
count = count + 1
|
||||||
|
if READ_FILE_PUB == pub + "\n":
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
ssh_keys = [
|
||||||
|
"/home/jonnybravo/.ssh/ansible-test",
|
||||||
|
"/home/jonnybravo/.ssh/blu",
|
||||||
|
"/home/jonnybravo/.ssh/gitea",
|
||||||
|
"/home/jonnybravo/.ssh/gitlab_ed25519",
|
||||||
|
]
|
||||||
|
|
||||||
|
for add_key in ssh_keys:
|
||||||
|
if not os.path.exists(add_key):
|
||||||
|
print("File", (add_key + ".pub"), "existiert nicht")
|
||||||
|
else:
|
||||||
|
if check_key_exist(ssh_pub=add_key + ".pub"):
|
||||||
|
print(add_key, "ist bereits vorhanden")
|
||||||
|
else:
|
||||||
|
print(add_key, "wird hinzugefügt...")
|
||||||
|
if import_ssh_keys_to_agent(privat_key=add_key):
|
||||||
|
print("Wurde hinzugefügt :", add_key)
|
||||||
19
check_git.py
Normal file
19
check_git.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
import subprocess, os
|
||||||
|
|
||||||
|
def git_test(git_file=str, git_root=str):
|
||||||
|
return subprocess.Popen(
|
||||||
|
"git -C {git_root} log -1 --pretty=format:%h:%ct {git_file}".format(
|
||||||
|
git_file=git_file,
|
||||||
|
git_root=git_root),
|
||||||
|
shell=True,
|
||||||
|
universal_newlines=True,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
|
).communicate()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(git_test(git_file="/home/jonnybravo/Projekte/Python_Skripte/jenkins/use_jenkins_api.py", git_root="/home/jonnybravo/Projekte/Python_Skripte")[0])
|
||||||
|
#git log -1 --pretty=format:%h:%c /home/jonnybravo/Projekte/Python_Skripte/jenkins/use_jenkins_api.py
|
||||||
|
|
||||||
32
create_ps/create_ps.py
Executable file
32
create_ps/create_ps.py
Executable file
@@ -0,0 +1,32 @@
|
|||||||
|
#! /usr/bin/env python
|
||||||
|
import string
|
||||||
|
import secrets
|
||||||
|
|
||||||
|
|
||||||
|
def create_password(long=int(10), sonder="!#$%&()*+-/:;<=>?@[]_{|}"):
|
||||||
|
print("Sonderzeichen:", sonder)
|
||||||
|
alle = string.ascii_letters + string.digits + sonder
|
||||||
|
|
||||||
|
while True:
|
||||||
|
tx = ""
|
||||||
|
anz = [0, 0, 0, 0]
|
||||||
|
for i in range(long):
|
||||||
|
zeichen = secrets.choice(alle)
|
||||||
|
tx += zeichen
|
||||||
|
if zeichen in string.ascii_lowercase:
|
||||||
|
anz[0] += 1
|
||||||
|
elif zeichen in string.ascii_uppercase:
|
||||||
|
anz[1] += 1
|
||||||
|
elif zeichen in string.digits:
|
||||||
|
anz[2] += 1
|
||||||
|
else:
|
||||||
|
anz[3] += 1
|
||||||
|
# print("Anzahl:", anz)
|
||||||
|
if 0 not in anz:
|
||||||
|
break
|
||||||
|
|
||||||
|
return tx
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(create_password(long=20))
|
||||||
4
funktional/test.py
Normal file
4
funktional/test.py
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
def square(nums):
|
||||||
|
return [ x*x for x in range(nums) ]
|
||||||
|
|
||||||
|
print(square(9))
|
||||||
1
imdb_parsen/imdb_top_250_movies.csv
Normal file
1
imdb_parsen/imdb_top_250_movies.csv
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
|
|
23
imdb_parsen/main.py
Normal file
23
imdb_parsen/main.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# print(the_matrix.get('tech'))
|
||||||
|
from imdb import Cinemagoer
|
||||||
|
|
||||||
|
# create an instance of the Cinemagoer class
|
||||||
|
ia = Cinemagoer()
|
||||||
|
|
||||||
|
# get a movie
|
||||||
|
movie = ia.get_movie('0133093')
|
||||||
|
|
||||||
|
# print the names of the directors of the movie
|
||||||
|
print('Directors:')
|
||||||
|
for director in movie['directors']:
|
||||||
|
print(director['name'])
|
||||||
|
|
||||||
|
# print the genres of the movie
|
||||||
|
print('Genres:')
|
||||||
|
for genre in movie['genres']:
|
||||||
|
print(genre)
|
||||||
|
|
||||||
|
# search for a person name
|
||||||
|
people = ia.search_person('Mel Gibson')
|
||||||
|
for person in people:
|
||||||
|
print(person.personID, person['name'])
|
||||||
48
imdb_parsen/test.py
Normal file
48
imdb_parsen/test.py
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
from bs4 import BeautifulSoup
|
||||||
|
import requests
|
||||||
|
import re
|
||||||
|
import pandas as pd
|
||||||
|
|
||||||
|
|
||||||
|
# Downloading imdb top 250 movie's data
|
||||||
|
url = 'http://www.imdb.com/chart/top'
|
||||||
|
response = requests.get(url)
|
||||||
|
soup = BeautifulSoup(response.text, "html.parser")
|
||||||
|
movies = soup.select('td.titleColumn')
|
||||||
|
crew = [a.attrs.get('title') for a in soup.select('td.titleColumn a')]
|
||||||
|
ratings = [b.attrs.get('data-value')
|
||||||
|
for b in soup.select('td.posterColumn span[name=ir]')]
|
||||||
|
|
||||||
|
|
||||||
|
# create a empty list for storing
|
||||||
|
# movie information
|
||||||
|
list = []
|
||||||
|
|
||||||
|
# Iterating over movies to extract
|
||||||
|
# each movie's details
|
||||||
|
for index in range(0, len(movies)):
|
||||||
|
|
||||||
|
# Separating movie into: 'place',
|
||||||
|
# 'title', 'year'
|
||||||
|
movie_string = movies[index].get_text()
|
||||||
|
movie = (' '.join(movie_string.split()).replace('.', ''))
|
||||||
|
movie_title = movie[len(str(index))+1:-7]
|
||||||
|
# year = re.search('\((.*?)\)', movie_string).group(1)
|
||||||
|
place = movie[:len(str(index))-(len(movie))]
|
||||||
|
data = {"place": place,
|
||||||
|
"movie_title": movie_title,
|
||||||
|
"rating": ratings[index],
|
||||||
|
# "year": year,
|
||||||
|
"star_cast": crew[index],
|
||||||
|
}
|
||||||
|
list.append(data)
|
||||||
|
|
||||||
|
# printing movie details with its rating.
|
||||||
|
for movie in list:
|
||||||
|
print(movie['place'], '-', movie['movie_title'],
|
||||||
|
'Starring:', movie['star_cast'], movie['rating'])
|
||||||
|
|
||||||
|
|
||||||
|
## .......##
|
||||||
|
df = pd.DataFrame(list)
|
||||||
|
df.to_csv('imdb_top_250_movies.csv', index=False)
|
||||||
@@ -3,6 +3,9 @@
|
|||||||
import os, sys, subprocess
|
import os, sys, subprocess
|
||||||
|
|
||||||
class nfs_server_conf:
|
class nfs_server_conf:
|
||||||
|
"""
|
||||||
|
Diese Class installiert nur einen NFS Server mit Systemd voraussetzung ist das nsfv4 installiert ist
|
||||||
|
"""
|
||||||
def __init__(self, nfs_srv_folders = ["/nfsroot/publicnfs","/nfsroot/datennfs"], nfs_config_file = "/etc/exports", allow_network = "192.168.50.0/25") -> None:
|
def __init__(self, nfs_srv_folders = ["/nfsroot/publicnfs","/nfsroot/datennfs"], nfs_config_file = "/etc/exports", allow_network = "192.168.50.0/25") -> None:
|
||||||
if not os.geteuid()==0:
|
if not os.geteuid()==0:
|
||||||
raise PermissionError("Sie sind kein Root")
|
raise PermissionError("Sie sind kein Root")
|
||||||
@@ -95,4 +98,4 @@ class nfs_server_conf:
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
my_nfs_server = nfs_server_conf(allow_network="*")
|
my_nfs_server = nfs_server_conf(allow_network="*")
|
||||||
my_nfs_server.main_install()
|
my_nfs_server.main_install()
|
||||||
|
|||||||
75
install_nfsv4_share/nfs_server_v2_ollama.py
Normal file
75
install_nfsv4_share/nfs_server_v2_ollama.py
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
import os
|
||||||
|
import systemd.daemon
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
class NFSServerConf:
|
||||||
|
def __init__(self, nfs_srv_folders: List[str] = ["/nfsroot/publicnfs", "/nfsroot/datennfs"],
|
||||||
|
nfs_config_file: str = "/etc/exports", allow_network: str = "192.168.50.0/25"):
|
||||||
|
self._validate_input(nfs_srv_folders)
|
||||||
|
self._validate_input(nfs_config_file)
|
||||||
|
|
||||||
|
self.nfs_srv_folders = nfs_srv_folders
|
||||||
|
self.nfs_config_file = nfs_config_file
|
||||||
|
self.allow_network = allow_network
|
||||||
|
|
||||||
|
def _validate_input(self, input_value: str) -> None:
|
||||||
|
if not isinstance(input_value, str):
|
||||||
|
raise ValueError(f"Input muss eine Zeichenkette sein. ({type(input_value).__name__} wurde verwendet.)")
|
||||||
|
if not os.path.exists(input_value):
|
||||||
|
raise ValueError(f"Datei {input_value} existiert nicht.")
|
||||||
|
|
||||||
|
def mount_serverfolder(self) -> None:
|
||||||
|
# Durchsuche das angegebene Verzeichnis und seine Unterordner nach Dateien und erstelle eine Liste von Dateipfaden
|
||||||
|
server_folder_list = []
|
||||||
|
for folder in self.nfs_srv_folders:
|
||||||
|
files_in_folder = [os.path.join(folder, file) for file in os.listdir(folder)]
|
||||||
|
server_folder_list.extend(files_in_folder)
|
||||||
|
|
||||||
|
# Erstelle für jedes Verzeichnis in nfs_srv_folders ein Unit-File im Format .mount in /etc/systemd/system/
|
||||||
|
for folder in self.nfs_srv_folders:
|
||||||
|
mount_unit_file = f"/etc/systemd/system/{os.path.basename(folder)}.mount"
|
||||||
|
with open(mount_unit_file, "w") as file:
|
||||||
|
file.write("[Unit]\n")
|
||||||
|
file.write(f"Description=Mount {folder}\n")
|
||||||
|
file.write("[Mount]\n")
|
||||||
|
file.write(f"Where={folder}\n")
|
||||||
|
file.write("What=/mnt/nfs\n")
|
||||||
|
|
||||||
|
# Starte und ermögliche den Dienst für jedes Unit-File
|
||||||
|
systemd.daemon.notify(systemd.daemon.DaemonReload)
|
||||||
|
|
||||||
|
def nfs_server_conf(self) -> None:
|
||||||
|
# Durchsuche die Konfiguration des NFS-Servers (im Standardfall /etc/exports) nach Verzeichnissen
|
||||||
|
with open(self.nfs_config_file, "r") as file:
|
||||||
|
config_content = file.readlines()
|
||||||
|
|
||||||
|
# Zähle, wie oft jeder Verzeichnis-Pfad in der Konfiguration vorkommt
|
||||||
|
folder_count = {}
|
||||||
|
for line in config_content:
|
||||||
|
if ":" in line and not line.startswith("#"):
|
||||||
|
folder_path = line.split(":")[0].strip()
|
||||||
|
if folder_path not in folder_count:
|
||||||
|
folder_count[folder_path] = 1
|
||||||
|
else:
|
||||||
|
folder_count[folder_path] += 1
|
||||||
|
|
||||||
|
# Füge für jeden Verzeichnis-Pfad hinzu, der nicht bereits in der Konfiguration vorhanden ist, einen neuen Eintrag in die Konfiguration
|
||||||
|
for folder in self.nfs_srv_folders:
|
||||||
|
if folder not in [line.strip() for line in config_content]:
|
||||||
|
with open(self.nfs_config_file, "a") as file:
|
||||||
|
file.write(f"{folder}({self.allow_network})\n")
|
||||||
|
|
||||||
|
def start_nfs_server(self) -> None:
|
||||||
|
# Starte und ermögliche den Dienst für den NFS-Server (im Standardfall nfsv4-server.service)
|
||||||
|
systemd.daemon.notify(systemd.daemon.DaemonReload)
|
||||||
|
|
||||||
|
|
||||||
|
def main_install():
|
||||||
|
nfsserverconf = NFSServerConf()
|
||||||
|
nfsserverconf.mount_serverfolder()
|
||||||
|
nfsserverconf.nfs_server_conf()
|
||||||
|
nfsserverconf.start_nfs_server()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main_install()
|
||||||
2
jenkins-module.txt
Normal file
2
jenkins-module.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fm=test.txt
|
||||||
|
|
||||||
0
jenkins/fm/dkdkd/djdj.txt
Normal file
0
jenkins/fm/dkdkd/djdj.txt
Normal file
1
jenkins/fm/test.txt
Normal file
1
jenkins/fm/test.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
dj
|
||||||
7
movie-db/.ipynb_checkpoints/README-checkpoint.md
Normal file
7
movie-db/.ipynb_checkpoints/README-checkpoint.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Folgende Punkte
|
||||||
|
|
||||||
|
- erstellen eine SQlite DB
|
||||||
|
- Die DB soll folgende Tabellen haben Genre, MyList,
|
||||||
|
- Die Anzeige soll über Flask angezeigt werden
|
||||||
|
|
||||||
|
Weitere Schritte folgen !!!
|
||||||
69
movie-db/.ipynb_checkpoints/moviedb_func-checkpoint.py
Normal file
69
movie-db/.ipynb_checkpoints/moviedb_func-checkpoint.py
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
import DBcm
|
||||||
|
|
||||||
|
|
||||||
|
def create_movie_database(db_name="movie_db.db"):
|
||||||
|
|
||||||
|
create_my_list = """
|
||||||
|
create table if not exists movie_list (
|
||||||
|
id integer not null primary key autoincrement,
|
||||||
|
titel varchar(64) not null,
|
||||||
|
genre_id integer not null,
|
||||||
|
regie_id integer not null
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
|
||||||
|
create_genre = """
|
||||||
|
create table if not exists genre (
|
||||||
|
id integer not null primary key autoincrement,
|
||||||
|
name varchar(64) not null
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
|
||||||
|
create_regie = """
|
||||||
|
create table if not exists regie (
|
||||||
|
id integer not null primary key autoincrement,
|
||||||
|
surname varchar(64) not null,
|
||||||
|
lastname varchr(64) not null
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
|
||||||
|
create_medium = """
|
||||||
|
create table if not exists medium (
|
||||||
|
id integer not null primary key autoincrement,
|
||||||
|
medium varchar(64) not null
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
|
||||||
|
with DBcm.UseDatabase(db_name) as db:
|
||||||
|
db.execute(create_my_list)
|
||||||
|
db.execute(create_genre)
|
||||||
|
db.execute(create_regie)
|
||||||
|
db.execute(create_medium)
|
||||||
|
|
||||||
|
|
||||||
|
def all_genres(db_name="movie_db.db"):
|
||||||
|
ALL_GENRE = "SELECT * from genre"
|
||||||
|
with DBcm.UseDatabase(db_name) as db:
|
||||||
|
db.execute(ALL_GENRE)
|
||||||
|
all_genre = [i[1] for i in db.fetchall()]
|
||||||
|
return all_genre
|
||||||
|
|
||||||
|
|
||||||
|
def search_genre_id(db_name="movie_db.db", genre_name=str):
|
||||||
|
GENRE_QUERY = """
|
||||||
|
select id from genre
|
||||||
|
where name = ?
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
with DBcm.UseDatabase(db_name) as db:
|
||||||
|
db.execute(GENRE_QUERY, (genre_name,))
|
||||||
|
genre_id = db.fetchone()[0]
|
||||||
|
return int(genre_id)
|
||||||
|
except:
|
||||||
|
return int(0)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
create_movie_database()
|
||||||
|
print(all_genres())
|
||||||
|
print(search_genre_id(genre_name="war"))
|
||||||
534
movie-db/.ipynb_checkpoints/test_jup-checkpoint.ipynb
Normal file
534
movie-db/.ipynb_checkpoints/test_jup-checkpoint.ipynb
Normal file
@@ -0,0 +1,534 @@
|
|||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 1,
|
||||||
|
"id": "5263a987-da36-46d7-a2e7-d0658cda09c1",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import DBcm"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 2,
|
||||||
|
"id": "3f6b0763-4106-4bfa-9aef-7afbd180c6d4",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"db_name = \"movie_db.db\"\n",
|
||||||
|
"\n",
|
||||||
|
"create_my_list = \"\"\"\n",
|
||||||
|
" create table if not exists movie_list (\n",
|
||||||
|
" id integer not null primary key autoincrement,\n",
|
||||||
|
" titel varchar(64) not null,\n",
|
||||||
|
" genre_id integer not null,\n",
|
||||||
|
" regie_id integer not null\n",
|
||||||
|
" \n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
"\"\"\"\n",
|
||||||
|
"\n",
|
||||||
|
"create_genre = \"\"\"\n",
|
||||||
|
" create table if not exists genre (\n",
|
||||||
|
" id integer not null primary key autoincrement,\n",
|
||||||
|
" name varchar(64) not null\n",
|
||||||
|
" )\n",
|
||||||
|
"\"\"\"\n",
|
||||||
|
"\n",
|
||||||
|
"create_regie = \"\"\"\n",
|
||||||
|
" create table if not exists regie (\n",
|
||||||
|
" id integer not null primary key autoincrement,\n",
|
||||||
|
" surname varchar(64) not null,\n",
|
||||||
|
" lastname varchr(64) not null\n",
|
||||||
|
" )\n",
|
||||||
|
"\"\"\"\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"with DBcm.UseDatabase(db_name) as db: \n",
|
||||||
|
" db.execute(create_my_list)\n",
|
||||||
|
" db.execute(create_genre)\n",
|
||||||
|
" db.execute(create_regie)\n",
|
||||||
|
" "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 3,
|
||||||
|
"id": "376ef812-97b5-45ba-8ef1-eb8d7829494a",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# ADDed Genre values\n",
|
||||||
|
"\n",
|
||||||
|
"ADD_GENRE_VALUE = \"\"\"\n",
|
||||||
|
" INSERT INTO genre(name)\n",
|
||||||
|
" SELECT ?\n",
|
||||||
|
" WHERE NOT EXISTS (SELECT 1 FROM genre WHERE name = ?);\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
"\n",
|
||||||
|
"with open(\"genre_list\", \"r\") as fs: \n",
|
||||||
|
" for genre_value in fs.readlines():\n",
|
||||||
|
" with DBcm.UseDatabase(db_name) as db:\n",
|
||||||
|
" db.execute(ADD_GENRE_VALUE, (genre_value.strip(), genre_value.strip()))\n",
|
||||||
|
" "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 27,
|
||||||
|
"id": "63b16a41-88bf-4832-a26c-09180832f597",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"['action', 'adventure', 'animation', 'biography', 'comedy', 'crime', 'cult movie', 'disney', 'documentary', 'drama', 'erotic', 'family', 'fantasy', 'film-noir', 'gangster', 'gay and lesbian', 'history', 'horror', 'military', 'music', 'musical', 'mystery', 'nature', 'neo-noir', 'period', 'pixar', 'road movie', 'romance', 'sci-fi', 'short', 'spy', 'super hero', 'thriller', 'visually stunning', 'war', 'western']\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"def all_genres():\n",
|
||||||
|
" ALL_GENRE = \"\"\"\n",
|
||||||
|
" SELECT * from genre \n",
|
||||||
|
" \"\"\" \n",
|
||||||
|
" with DBcm.UseDatabase(db_name) as db:\n",
|
||||||
|
" db.execute(ALL_GENRE)\n",
|
||||||
|
" all_genre = [i[1] for i in db.fetchall()]\n",
|
||||||
|
" \n",
|
||||||
|
" return all_genre\n",
|
||||||
|
"\n",
|
||||||
|
"print(all_genres())\n",
|
||||||
|
" "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 36,
|
||||||
|
"id": "89b20b5f-34aa-4490-a4c0-c186c9fa30bd",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"1\n",
|
||||||
|
"36\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"def search_genre_id(genre_name):\n",
|
||||||
|
" GENRE_QUERY = \"\"\"\n",
|
||||||
|
" select id from genre\n",
|
||||||
|
" where name = ?\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" try:\n",
|
||||||
|
" with DBcm.UseDatabase(db_name) as db:\n",
|
||||||
|
" db.execute(GENRE_QUERY,(genre_name,))\n",
|
||||||
|
" genre_id = db.fetchone()[0]\n",
|
||||||
|
" return int(genre_id)\n",
|
||||||
|
" except:\n",
|
||||||
|
" return int(0)\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"def search_medium_id(genre_name):\n",
|
||||||
|
" GENRE_QUERY = \"\"\"\n",
|
||||||
|
" select id from genre\n",
|
||||||
|
" where medium = ?\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" try:\n",
|
||||||
|
" with DBcm.UseDatabase(db_name) as db:\n",
|
||||||
|
" db.execute(GENRE_QUERY,(genre_name,))\n",
|
||||||
|
" genre_id = db.fetchone()[0]\n",
|
||||||
|
" return int(genre_id)\n",
|
||||||
|
" except:\n",
|
||||||
|
" return int(0)\n",
|
||||||
|
"\n",
|
||||||
|
"print(search_genre_id(genre_name=\"action\"))\n",
|
||||||
|
"print(search_genre_id(genre_name=\"western\"))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 18,
|
||||||
|
"id": "c70d91a5-7855-465d-a4a6-daebc065ee37",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"0-John-Smith\n",
|
||||||
|
"1-James-Johnson\n",
|
||||||
|
"2-William-Williams\n",
|
||||||
|
"3-Michael-Brown\n",
|
||||||
|
"4-David-Davis\n",
|
||||||
|
"5-Richard-Miller\n",
|
||||||
|
"6-Joseph-Wilson\n",
|
||||||
|
"7-Charles-Moore\n",
|
||||||
|
"8-Thomas-Taylor\n",
|
||||||
|
"9-Daniel-Anderson\n",
|
||||||
|
"10-Paul-Thomas\n",
|
||||||
|
"11-Mark-Jackson\n",
|
||||||
|
"12-Donna-White\n",
|
||||||
|
"13-Michelle-Harris\n",
|
||||||
|
"14-Laura-Martin\n",
|
||||||
|
"15-Sara-Thompson\n",
|
||||||
|
"16-Ana-Garcia\n",
|
||||||
|
"17-Carlos-Rodriguez\n",
|
||||||
|
"18-Maria-Martinez\n",
|
||||||
|
"19-Jose-Hernandez\n",
|
||||||
|
"20-Luis-Lopez\n",
|
||||||
|
"21-Rosa-Gonzalez\n",
|
||||||
|
"22-Pedro-Perez\n",
|
||||||
|
"23-Miguel-Sanchez\n",
|
||||||
|
"24-Juan-Ramirez\n",
|
||||||
|
"25-Ana-Flores\n",
|
||||||
|
"26-Isabella-Cruz\n",
|
||||||
|
"27-Victor-Rivera\n",
|
||||||
|
"28-Kevin-Lee\n",
|
||||||
|
"29-Brian-Walker\n",
|
||||||
|
"30-Emily-Hall\n",
|
||||||
|
"31-Ryan-Allen\n",
|
||||||
|
"32-Aaron-Young\n",
|
||||||
|
"33-Jeffrey-King\n",
|
||||||
|
"34-Joshua-Wright\n",
|
||||||
|
"35-Brandon-Scott\n",
|
||||||
|
"36-Frank-Turner\n",
|
||||||
|
"37-Gregory-Carter\n",
|
||||||
|
"38-Samuel-Phillips\n",
|
||||||
|
"39-Chris-Evans\n",
|
||||||
|
"40-Anthony-Collins\n",
|
||||||
|
"41-Eric-Stewart\n",
|
||||||
|
"42-Frank-Snyder\n",
|
||||||
|
"43-Thomas-Baker\n",
|
||||||
|
"44-Jeremy-Nelson\n",
|
||||||
|
"45-Steven-Roberts\n",
|
||||||
|
"46-Edward-Campbell\n",
|
||||||
|
"47-Ryan-Miller\n",
|
||||||
|
"48-Jacob-Davis\n",
|
||||||
|
"49-David-Garcia\n",
|
||||||
|
"50-Sophia-Rodriguez\n",
|
||||||
|
"51-Emma-Martinez\n",
|
||||||
|
"52-Noah-Hernandez\n",
|
||||||
|
"53-Ava-Lopez\n",
|
||||||
|
"54-Ethan-Gonzalez\n",
|
||||||
|
"55-Mia-Perez\n",
|
||||||
|
"56-William-Sanchez\n",
|
||||||
|
"57-James-Ramirez\n",
|
||||||
|
"58-Olivia-Flores\n",
|
||||||
|
"59-Lucas-Cruz\n",
|
||||||
|
"60-Isabella-Rivera\n",
|
||||||
|
"61-David-Lee\n",
|
||||||
|
"62-Sophie-Walker\n",
|
||||||
|
"63-Matthew-Hall\n",
|
||||||
|
"64-Emma-Allen\n",
|
||||||
|
"65-Ryan-Young\n",
|
||||||
|
"66-Ava-King\n",
|
||||||
|
"67-Ethan-Wright\n",
|
||||||
|
"68-Mia-Scott\n",
|
||||||
|
"69-William-Turner\n",
|
||||||
|
"70-James-Carter\n",
|
||||||
|
"71-Olivia-Phillips\n",
|
||||||
|
"72-Lucas-Evans\n",
|
||||||
|
"73-Sophie-Collins\n",
|
||||||
|
"74-Noah-Stewart\n",
|
||||||
|
"75-Ava-Snyder\n",
|
||||||
|
"76-Ethan-Baker\n",
|
||||||
|
"77-Mia-Nelson\n",
|
||||||
|
"78-Noah-Roberts\n",
|
||||||
|
"79-Emma-Campbell\n",
|
||||||
|
"80-William-Miller\n",
|
||||||
|
"81-James-Davis\n",
|
||||||
|
"82-Olivia-Garcia\n",
|
||||||
|
"83-Lucas-Rodriguez\n",
|
||||||
|
"84-Sophie-Martinez\n",
|
||||||
|
"85-Noah-Hernandez\n",
|
||||||
|
"86-Ava-Lopez\n",
|
||||||
|
"87-Ethan-Gonzalez\n",
|
||||||
|
"88-Mia-Perez\n",
|
||||||
|
"89-William-Sanchez\n",
|
||||||
|
"90-James-Ramirez\n",
|
||||||
|
"91-Olivia-Flores\n",
|
||||||
|
"92-Lucas-Cruz\n",
|
||||||
|
"93-Isabella-Rivera\n",
|
||||||
|
"94-David-Lee\n",
|
||||||
|
"95-Sophie-Walker\n",
|
||||||
|
"96-Matthew-Hall\n",
|
||||||
|
"97-Emma-Allen\n",
|
||||||
|
"98-Ryan-Young\n",
|
||||||
|
"99-Ava-King\n",
|
||||||
|
"100-Ethan-Wright\n",
|
||||||
|
"101-Mia-Scott\n",
|
||||||
|
"102-William-Turner\n",
|
||||||
|
"103-James-Carter\n",
|
||||||
|
"104-Olivia-Phillips\n",
|
||||||
|
"105-Lucas-Evans\n",
|
||||||
|
"106-Sophie-Collins\n",
|
||||||
|
"107-Noah-Stewart\n",
|
||||||
|
"108-Ava-Snyder\n",
|
||||||
|
"109-Ethan-Baker\n",
|
||||||
|
"110-Mia-Nelson\n",
|
||||||
|
"111-Noah-Roberts\n",
|
||||||
|
"112-Emma-Campbell\n",
|
||||||
|
"113-William-Miller\n",
|
||||||
|
"114-James-Davis\n",
|
||||||
|
"115-Olivia-Garcia\n",
|
||||||
|
"116-Lucas-Rodriguez\n",
|
||||||
|
"117-Sophie-Martinez\n",
|
||||||
|
"118-Noah-Hernandez\n",
|
||||||
|
"119-Ava-Lopez\n",
|
||||||
|
"120-Ethan-Gonzalez\n",
|
||||||
|
"121-Mia-Perez\n",
|
||||||
|
"122-William-Sanchez\n",
|
||||||
|
"123-James-Ramirez\n",
|
||||||
|
"124-Olivia-Flores\n",
|
||||||
|
"125-Lucas-Cruz\n",
|
||||||
|
"126-Isabella-Rivera\n",
|
||||||
|
"127-David-Lee\n",
|
||||||
|
"128-Sophie-Walker\n",
|
||||||
|
"129-Matthew-Hall\n",
|
||||||
|
"130-Emma-Allen\n",
|
||||||
|
"131-Ryan-Young\n",
|
||||||
|
"132-Ava-King\n",
|
||||||
|
"133-Ethan-Wright\n",
|
||||||
|
"134-Mia-Scott\n",
|
||||||
|
"135-William-Turner\n",
|
||||||
|
"136-James-Carter\n",
|
||||||
|
"137-Olivia-Phillips\n",
|
||||||
|
"138-Lucas-Evans\n",
|
||||||
|
"139-Sophie-Collins\n",
|
||||||
|
"140-Noah-Stewart\n",
|
||||||
|
"141-Ava-Snyder\n",
|
||||||
|
"142-Ethan-Baker\n",
|
||||||
|
"143-Mia-Nelson\n",
|
||||||
|
"144-Noah-Roberts\n",
|
||||||
|
"145-Emma-Campbell\n",
|
||||||
|
"146-William-Miller\n",
|
||||||
|
"147-James-Davis\n",
|
||||||
|
"148-Olivia-Garcia\n",
|
||||||
|
"149-Lucas-Rodriguez\n",
|
||||||
|
"150-Sophie-Martinez\n",
|
||||||
|
"151-Noah-Hernandez\n",
|
||||||
|
"152-Ava-Lopez\n",
|
||||||
|
"153-Ethan-Gonzalez\n",
|
||||||
|
"154-Mia-Perez\n",
|
||||||
|
"155-William-Sanchez\n",
|
||||||
|
"156-James-Ramirez\n",
|
||||||
|
"157-Olivia-Flores\n",
|
||||||
|
"158-Lucas-Cruz\n",
|
||||||
|
"159-Isabella-Rivera\n",
|
||||||
|
"160-David-Lee\n",
|
||||||
|
"161-Sophie-Walker\n",
|
||||||
|
"162-Matthew-Hall\n",
|
||||||
|
"163-Emma-Allen\n",
|
||||||
|
"164-Ryan-Young\n",
|
||||||
|
"165-Ava-King\n",
|
||||||
|
"166-Ethan-Wright\n",
|
||||||
|
"167-Mia-Scott\n",
|
||||||
|
"168-William-Turner\n",
|
||||||
|
"169-James-Carter\n",
|
||||||
|
"170-Olivia-Phillips\n",
|
||||||
|
"171-Lucas-Evans\n",
|
||||||
|
"172-Sophie-Collins\n",
|
||||||
|
"173-Noah-Stewart\n",
|
||||||
|
"174-Ava-Snyder\n",
|
||||||
|
"175-Ethan-Baker\n",
|
||||||
|
"176-Mia-Nelson\n",
|
||||||
|
"177-Noah-Roberts\n",
|
||||||
|
"178-Emma-Campbell\n",
|
||||||
|
"179-William-Miller\n",
|
||||||
|
"180-James-Davis\n",
|
||||||
|
"181-Olivia-Garcia\n",
|
||||||
|
"182-Lucas-Rodriguez\n",
|
||||||
|
"183-Sophie-Martinez\n",
|
||||||
|
"184-Noah-Hernandez\n",
|
||||||
|
"185-Ava-Lopez\n",
|
||||||
|
"186-Ethan-Gonzalez\n",
|
||||||
|
"187-Mia-Perez\n",
|
||||||
|
"188-William-Sanchez\n",
|
||||||
|
"189-James-Ramirez\n",
|
||||||
|
"190-Olivia-Flores\n",
|
||||||
|
"191-Lucas-Cruz\n",
|
||||||
|
"192-Isabella-Rivera\n",
|
||||||
|
"193-David-Lee\n",
|
||||||
|
"194-Sophie-Walker\n",
|
||||||
|
"195-Matthew-Hall\n",
|
||||||
|
"196-Emma-Allen\n",
|
||||||
|
"197-Ryan-Young\n",
|
||||||
|
"198-Ava-King\n",
|
||||||
|
"199-Ethan-Wright\n",
|
||||||
|
"200-Mia-Scott\n",
|
||||||
|
"201-William-Turner\n",
|
||||||
|
"202-James-Carter\n",
|
||||||
|
"203-Olivia-Phillips\n",
|
||||||
|
"204-Lucas-Evans\n",
|
||||||
|
"205-Sophie-Collins\n",
|
||||||
|
"206-Noah-Stewart\n",
|
||||||
|
"207-Ava-Snyder\n",
|
||||||
|
"208-Ethan-Baker\n",
|
||||||
|
"209-Mia-Nelson\n",
|
||||||
|
"210-Noah-Roberts\n",
|
||||||
|
"211-Emma-Campbell\n",
|
||||||
|
"212-William-Miller\n",
|
||||||
|
"213-James-Davis\n",
|
||||||
|
"214-Olivia-Garcia\n",
|
||||||
|
"215-Lucas-Rodriguez\n",
|
||||||
|
"216-Sophie-Martinez\n",
|
||||||
|
"217-Noah-Hernandez\n",
|
||||||
|
"218-Ava-Lopez\n",
|
||||||
|
"219-Ethan-Gonzalez\n",
|
||||||
|
"220-Mia-Perez\n",
|
||||||
|
"221-William-Sanchez\n",
|
||||||
|
"222-James-Ramirez\n",
|
||||||
|
"223-Olivia-Flores\n",
|
||||||
|
"224-Lucas-Cruz\n",
|
||||||
|
"225-Isabella-Rivera\n",
|
||||||
|
"226-David-Lee\n",
|
||||||
|
"227-Sophie-Walker\n",
|
||||||
|
"228-Matthew-Hall\n",
|
||||||
|
"229-Emma-Allen\n",
|
||||||
|
"230-Ryan-Young\n",
|
||||||
|
"231-Ava-King\n",
|
||||||
|
"232-Ethan-Wright\n",
|
||||||
|
"233-Mia-Scott\n",
|
||||||
|
"234-William-Turner\n",
|
||||||
|
"235-James-Carter\n",
|
||||||
|
"236-Olivia-Phillips\n",
|
||||||
|
"237-Lucas-Evans\n",
|
||||||
|
"238-Sophie-Collins\n",
|
||||||
|
"239-Noah-Stewart\n",
|
||||||
|
"240-Ava-Snyder\n",
|
||||||
|
"241-Ethan-Baker\n",
|
||||||
|
"242-Mia-Nelson\n",
|
||||||
|
"243-Noah-Roberts\n",
|
||||||
|
"244-Emma-Campbell\n",
|
||||||
|
"245-William-Miller\n",
|
||||||
|
"246-James-Davis\n",
|
||||||
|
"247-Olivia-Garcia\n",
|
||||||
|
"248-Lucas-Rodriguez\n",
|
||||||
|
"249-Sophie-Martinez\n",
|
||||||
|
"250-Noah-Hernandez\n",
|
||||||
|
"251-Ava-Lopez\n",
|
||||||
|
"252-Ethan-Gonzalez\n",
|
||||||
|
"253-Mia-Perez\n",
|
||||||
|
"254-William-Sanchez\n",
|
||||||
|
"255-James-Ramirez\n",
|
||||||
|
"256-Olivia-Flores\n",
|
||||||
|
"257-Lucas-Cruz\n",
|
||||||
|
"258-Isabella-Rivera\n",
|
||||||
|
"259-David-Lee\n",
|
||||||
|
"260-Sophie-Walker\n",
|
||||||
|
"261-Matthew-Hall\n",
|
||||||
|
"262-Emma-Allen\n",
|
||||||
|
"263-Ryan-Young\n",
|
||||||
|
"264-Ava-King\n",
|
||||||
|
"265-Ethan-Wright\n",
|
||||||
|
"266-Mia-Scott\n",
|
||||||
|
"267-William-Turner\n",
|
||||||
|
"268-James-Carter\n",
|
||||||
|
"269-Olivia-Phillips\n",
|
||||||
|
"270-Lucas-Evans\n",
|
||||||
|
"271-Sophie-Collins\n",
|
||||||
|
"272-Noah-Stewart\n",
|
||||||
|
"273-Ava-Snyder\n",
|
||||||
|
"274-Ethan-Baker\n",
|
||||||
|
"275-Mia-Nelson\n",
|
||||||
|
"276-Noah-Roberts\n",
|
||||||
|
"277-Emma-Campbell\n",
|
||||||
|
"278-William-Miller\n",
|
||||||
|
"279-James-Davis\n",
|
||||||
|
"280-Olivia-Garcia\n",
|
||||||
|
"281-Lucas-Rodriguez\n",
|
||||||
|
"282-Sophie-Martinez\n",
|
||||||
|
"283-Noah-Hernandez\n",
|
||||||
|
"284-Ava-Lopez\n",
|
||||||
|
"285-Ethan-Gonzalez\n",
|
||||||
|
"286-Mia-Perez\n",
|
||||||
|
"287-William-Sanchez\n",
|
||||||
|
"288-James-Ramirez\n",
|
||||||
|
"289-Olivia-Flores\n",
|
||||||
|
"290-Lucas-Cruz\n",
|
||||||
|
"291-Isabella-Rivera\n",
|
||||||
|
"292-David-Lee\n",
|
||||||
|
"293-Sophie-Walker\n",
|
||||||
|
"294-Matthew-Hall\n",
|
||||||
|
"295-Emma-Allen\n",
|
||||||
|
"296-Ryan-Young\n",
|
||||||
|
"297-Ava-King\n",
|
||||||
|
"298-Ethan-Wright\n",
|
||||||
|
"299-Mia-Scott\n",
|
||||||
|
"300-William-Turner\n",
|
||||||
|
"301-James-Carter\n",
|
||||||
|
"302-Olivia-Phillips\n",
|
||||||
|
"303-Lucas-Evans\n",
|
||||||
|
"304-Sophie-Collins\n",
|
||||||
|
"305-Noah-Stewart\n",
|
||||||
|
"306-Ava-Snyder\n",
|
||||||
|
"307-Ethan-Baker\n",
|
||||||
|
"308-Mia-Nelson\n",
|
||||||
|
"309-Noah-Roberts\n",
|
||||||
|
"310-Emma-Campbell\n",
|
||||||
|
"311-William-Miller\n",
|
||||||
|
"312-James-Davis\n",
|
||||||
|
"313-Olivia-Garcia\n",
|
||||||
|
"314-Lucas-Rodriguez\n",
|
||||||
|
"315-Sophie-Martinez\n",
|
||||||
|
"316-Noah-Hernandez\n",
|
||||||
|
"317-Ava-Lopez\n",
|
||||||
|
"318-Ethan-Gonzalez\n",
|
||||||
|
"319-Mia-Perez\n",
|
||||||
|
"320-William-Sanchez\n",
|
||||||
|
"321-James-Ramirez\n",
|
||||||
|
"322-Olivia-Flores\n",
|
||||||
|
"323-Lucas-Cruz\n",
|
||||||
|
"324-Isabella-Rivera\n",
|
||||||
|
"325-David-Lee\n",
|
||||||
|
"326-Sophie-Walker\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"import pandas as pd\n",
|
||||||
|
"usecols = [\"Name\", \"Vorname\"]\n",
|
||||||
|
"air = pd.read_csv(\"regie_name.csv\", usecols=usecols)\n",
|
||||||
|
"\n",
|
||||||
|
"for count, (i, b) in enumerate(zip(air[\"Name\"], air[\"Vorname\"])):\n",
|
||||||
|
" print(count, b, i, sep=\"-\")\n",
|
||||||
|
"\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "ee4b5dee-6b41-49eb-8d75-9db50d20fdef",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3 (ipykernel)",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.13.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 5
|
||||||
|
}
|
||||||
7
movie-db/README.md
Normal file
7
movie-db/README.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Folgende Punkte
|
||||||
|
|
||||||
|
- erstellen eine SQlite DB
|
||||||
|
- Die DB soll folgende Tabellen haben Genre, MyList,
|
||||||
|
- Die Anzeige soll über Flask angezeigt werden
|
||||||
|
|
||||||
|
Weitere Schritte folgen !!!
|
||||||
BIN
movie-db/__pycache__/moviedb_func.cpython-313.pyc
Normal file
BIN
movie-db/__pycache__/moviedb_func.cpython-313.pyc
Normal file
Binary file not shown.
36
movie-db/genre_list
Normal file
36
movie-db/genre_list
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
action
|
||||||
|
adventure
|
||||||
|
animation
|
||||||
|
biography
|
||||||
|
comedy
|
||||||
|
crime
|
||||||
|
cult movie
|
||||||
|
disney
|
||||||
|
documentary
|
||||||
|
drama
|
||||||
|
erotic
|
||||||
|
family
|
||||||
|
fantasy
|
||||||
|
film-noir
|
||||||
|
gangster
|
||||||
|
gay and lesbian
|
||||||
|
history
|
||||||
|
horror
|
||||||
|
military
|
||||||
|
music
|
||||||
|
musical
|
||||||
|
mystery
|
||||||
|
nature
|
||||||
|
neo-noir
|
||||||
|
period
|
||||||
|
pixar
|
||||||
|
road movie
|
||||||
|
romance
|
||||||
|
sci-fi
|
||||||
|
short
|
||||||
|
spy
|
||||||
|
super hero
|
||||||
|
thriller
|
||||||
|
visually stunning
|
||||||
|
war
|
||||||
|
western
|
||||||
59
movie-db/main.py
Normal file
59
movie-db/main.py
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import flask
|
||||||
|
|
||||||
|
import moviedb_func
|
||||||
|
|
||||||
|
app = flask.Flask(__name__)
|
||||||
|
app.secret_key = "Start1234!"
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/add_movie")
|
||||||
|
def add_movie():
|
||||||
|
return flask.render_template(
|
||||||
|
"add_movie.html",
|
||||||
|
sitename="Meine Movieliste !!!",
|
||||||
|
url="output",
|
||||||
|
select_movie="add_movie",
|
||||||
|
select_genre="add_genre",
|
||||||
|
select_medium="add_medium",
|
||||||
|
select_regie="add_regie",
|
||||||
|
data=moviedb_func.all_select(),
|
||||||
|
data_medium=moviedb_func.all_select(what_select="medium"),
|
||||||
|
data_regie=moviedb_func.all_select(what_select="regie"),
|
||||||
|
data_all=moviedb_func.show_movie_list()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/output")
|
||||||
|
def csv_output():
|
||||||
|
select_add_movie = flask.request.form["add_movie"]
|
||||||
|
select_genre = flask.request.form["add_genre"]
|
||||||
|
select_genre_id = moviedb_func.search_id(
|
||||||
|
search_name=flask.request.form["add_genre"])
|
||||||
|
|
||||||
|
select_medium = flask.request.form["add_medium"]
|
||||||
|
select_medium_id = moviedb_func.search_id(
|
||||||
|
search_name=flask.request.form["add_medium"], select_from="medium", select_where="medium")
|
||||||
|
select_regie = flask.request.form["add_regie"]
|
||||||
|
select_regie_id = moviedb_func.search_id(
|
||||||
|
search_name=flask.request.form["add_regie"], select_from="regie", select_where="regie")
|
||||||
|
|
||||||
|
moviedb_func.add_movie_to_list(movie_name=select_add_movie, regie_id=select_regie_id,
|
||||||
|
medium_id=select_medium_id, genre_id=select_genre_id)
|
||||||
|
|
||||||
|
return flask.render_template(
|
||||||
|
"output.html",
|
||||||
|
sitename="Meine Movieliste !!!",
|
||||||
|
add_movie=select_add_movie,
|
||||||
|
add_genre=select_genre,
|
||||||
|
add_medium=select_medium,
|
||||||
|
add_regie=select_regie,
|
||||||
|
add_genre_id=select_genre_id,
|
||||||
|
add_medium_id=select_medium_id,
|
||||||
|
add_regie_id=select_regie_id
|
||||||
|
# data=modify_csv.read_csv_file(),
|
||||||
|
# sum_all=modify_csv.sum_all(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app.run(port=5082, host="0.0.0.0", debug=True)
|
||||||
BIN
movie-db/movie_db.db
Normal file
BIN
movie-db/movie_db.db
Normal file
Binary file not shown.
175
movie-db/moviedb_func.py
Normal file
175
movie-db/moviedb_func.py
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
import DBcm
|
||||||
|
from mariadb import ProgrammingError
|
||||||
|
import pandas as pd
|
||||||
|
import sqlite3
|
||||||
|
|
||||||
|
|
||||||
|
def create_movie_database(db_name="movie_db.db"):
|
||||||
|
|
||||||
|
create_my_list = """
|
||||||
|
create table if not exists movie_list (
|
||||||
|
id integer not null primary key autoincrement,
|
||||||
|
titel varchar(64) not null,
|
||||||
|
genre_id integer not null,
|
||||||
|
regie_id integer not null,
|
||||||
|
medium_id integer not null
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
|
||||||
|
create_genre = """
|
||||||
|
create table if not exists genre (
|
||||||
|
id integer not null primary key autoincrement,
|
||||||
|
name varchar(64) not null
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
|
||||||
|
create_regie = """
|
||||||
|
create table if not exists regie (
|
||||||
|
id integer not null primary key autoincrement,
|
||||||
|
surname varchar(64) not null,
|
||||||
|
lastname varchar(64) not null
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
|
||||||
|
create_medium = """
|
||||||
|
create table if not exists medium (
|
||||||
|
id integer not null primary key autoincrement,
|
||||||
|
medium varchar(64) not null
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
|
||||||
|
ADD_GENRE_VALUE = """
|
||||||
|
INSERT INTO genre(name)
|
||||||
|
SELECT ?
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM genre WHERE name = ?);
|
||||||
|
"""
|
||||||
|
|
||||||
|
ADD_MEDIUM_VALUE = """
|
||||||
|
INSERT INTO medium(medium)
|
||||||
|
SELECT ?
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM medium WHERE medium = ?);
|
||||||
|
"""
|
||||||
|
|
||||||
|
ADD_REGIE_VALUE = """
|
||||||
|
INSERT INTO regie (surname, lastname )
|
||||||
|
SELECT ?, ?
|
||||||
|
WHERE NOT EXISTS
|
||||||
|
(SELECT surname, lastname
|
||||||
|
FROM regie
|
||||||
|
WHERE surname = ? AND lastname = ?);
|
||||||
|
"""
|
||||||
|
|
||||||
|
with DBcm.UseDatabase(db_name) as db:
|
||||||
|
db.execute(create_my_list)
|
||||||
|
db.execute(create_genre)
|
||||||
|
db.execute(create_regie)
|
||||||
|
db.execute(create_medium)
|
||||||
|
|
||||||
|
with open("genre_list", "r") as fs:
|
||||||
|
for genre_value in fs.readlines():
|
||||||
|
with DBcm.UseDatabase(db_name) as db:
|
||||||
|
db.execute(ADD_GENRE_VALUE,
|
||||||
|
(genre_value.strip(), genre_value.strip()))
|
||||||
|
|
||||||
|
usecols = ["Name", "Vorname"]
|
||||||
|
air = pd.read_csv("regie_name.csv", usecols=usecols)
|
||||||
|
for count, (reg_name, reg_vorname) in enumerate(zip(air["Name"], air["Vorname"])):
|
||||||
|
# print(count, reg_vorname, reg_name)
|
||||||
|
with DBcm.UseDatabase(db_name) as db:
|
||||||
|
db.execute(ADD_REGIE_VALUE, (reg_vorname,
|
||||||
|
reg_name, reg_vorname, reg_name))
|
||||||
|
|
||||||
|
LISTE_MEDIUM = ["BlueRay", "DVD", "Datei",
|
||||||
|
"BlueRay Steelbook", "DVD Steelbook"]
|
||||||
|
with DBcm.UseDatabase(db_name) as db:
|
||||||
|
for MEDIUM in LISTE_MEDIUM:
|
||||||
|
db.execute(ADD_MEDIUM_VALUE, (MEDIUM, MEDIUM))
|
||||||
|
|
||||||
|
|
||||||
|
def all_select(db_name="movie_db.db", what_select="genre"):
|
||||||
|
ALL_SELECT = "SELECT * from " + what_select
|
||||||
|
if what_select == "genre" or what_select == "medium":
|
||||||
|
with DBcm.UseDatabase(db_name) as db:
|
||||||
|
db.execute(ALL_SELECT)
|
||||||
|
all_value = [i[1] for i in db.fetchall()]
|
||||||
|
return all_value
|
||||||
|
elif what_select == 'regie':
|
||||||
|
all_value = []
|
||||||
|
with DBcm.UseDatabase(db_name) as db:
|
||||||
|
db.execute(ALL_SELECT)
|
||||||
|
for i in db.fetchall():
|
||||||
|
all_value.append(i[1] + " " + i[2])
|
||||||
|
return all_value
|
||||||
|
else:
|
||||||
|
return "Wrong Value !!!"
|
||||||
|
|
||||||
|
|
||||||
|
def search_id(db_name="movie_db.db", search_name=str, select_from="genre", select_where="name"):
|
||||||
|
if select_from == "regie":
|
||||||
|
split_search = search_name.split(" ")
|
||||||
|
GENRE_QUERY = f"""select id from {select_from}
|
||||||
|
where surname = ? and lastname = ?"""
|
||||||
|
with DBcm.UseDatabase(db_name) as db:
|
||||||
|
db.execute(GENRE_QUERY, (split_search[0], split_search[1],))
|
||||||
|
regie_id = db.fetchone()[0]
|
||||||
|
return int(regie_id)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
GENRE_QUERY = f"""select id from {select_from}
|
||||||
|
where {select_where} = ?"""
|
||||||
|
with DBcm.UseDatabase(db_name) as db:
|
||||||
|
db.execute(GENRE_QUERY, (search_name,))
|
||||||
|
genre_id = db.fetchone()[0]
|
||||||
|
return int(genre_id)
|
||||||
|
except:
|
||||||
|
return int(0)
|
||||||
|
|
||||||
|
|
||||||
|
def add_movie_to_list(db_name="movie_db.db", movie_name=str, genre_id=int, regie_id=int, medium_id=int):
|
||||||
|
SQL_PARAM = f"""
|
||||||
|
INSERT INTO movie_list (titel, genre_id, regie_id, medium_id )
|
||||||
|
SELECT ?, ?, ?, ?
|
||||||
|
WHERE NOT EXISTS
|
||||||
|
(SELECT titel FROM movie_list WHERE titel = ?);
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
with DBcm.UseDatabase(db_name) as db:
|
||||||
|
db.execute(SQL_PARAM, (movie_name.lower(), genre_id,
|
||||||
|
regie_id, medium_id, movie_name.lower(),))
|
||||||
|
except ProgrammingError:
|
||||||
|
raise ProgrammingError("Konnte nicht in die DB schreiben")
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def show_movie_list(db_name="movie_db.db"):
|
||||||
|
SQL_PARAM = f"""SELECT
|
||||||
|
movie_list.id,
|
||||||
|
titel,
|
||||||
|
genre.name AS genre,
|
||||||
|
regie.surname as regie_surname,
|
||||||
|
regie.lastname as regie_lastname,
|
||||||
|
medium.medium
|
||||||
|
FROM movie_list
|
||||||
|
INNER JOIN genre ON movie_list.genre_id=genre.id
|
||||||
|
INNER JOIN regie ON movie_list.regie_id=regie.id
|
||||||
|
INNER JOIN medium ON movie_list.medium_id=medium.id
|
||||||
|
;
|
||||||
|
"""
|
||||||
|
db = sqlite3.connect(db_name)
|
||||||
|
SELCET_VALUE = pd.read_sql(SQL_PARAM, db)
|
||||||
|
return_list_dict = []
|
||||||
|
for id, titel, genre, regie_surname, regie_lastname, medium in zip(SELCET_VALUE["id"], SELCET_VALUE["titel"], SELCET_VALUE["genre"], SELCET_VALUE["regie_surname"], SELCET_VALUE["regie_lastname"], SELCET_VALUE["medium"]):
|
||||||
|
return_list_dict.append(
|
||||||
|
{"id": id, "titel": titel, "genre": genre, "regie": regie_surname + " " + regie_lastname, "medium": medium})
|
||||||
|
return return_list_dict
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
create_movie_database()
|
||||||
|
# print(all_select())
|
||||||
|
# id_genre = search_id(
|
||||||
|
# search_name="DVD", select_from="medium", select_where="medium")
|
||||||
|
add_movie_to_list(movie_name="Schlumpfland",
|
||||||
|
genre_id=1, regie_id=1, medium_id=1)
|
||||||
|
for test in show_movie_list():
|
||||||
|
print(test.get("id"), test.get("medium"))
|
||||||
329
movie-db/regie_name.csv
Normal file
329
movie-db/regie_name.csv
Normal file
@@ -0,0 +1,329 @@
|
|||||||
|
Name,Vorname
|
||||||
|
Rodriguez,Robert
|
||||||
|
Smith,John
|
||||||
|
Johnson,James
|
||||||
|
Williams,William
|
||||||
|
Brown,Michael
|
||||||
|
Davis,David
|
||||||
|
Miller,Richard
|
||||||
|
Wilson,Joseph
|
||||||
|
Moore,Charles
|
||||||
|
Taylor,Thomas
|
||||||
|
Anderson,Daniel
|
||||||
|
Thomas,Paul
|
||||||
|
Jackson,Mark
|
||||||
|
White,Donna
|
||||||
|
Harris,Michelle
|
||||||
|
Martin,Laura
|
||||||
|
Thompson,Sara
|
||||||
|
Garcia,Ana
|
||||||
|
Rodriguez,Carlos
|
||||||
|
Martinez,Maria
|
||||||
|
Hernandez,Jose
|
||||||
|
Lopez,Luis
|
||||||
|
Gonzalez,Rosa
|
||||||
|
Perez,Pedro
|
||||||
|
Sanchez,Miguel
|
||||||
|
Ramirez,Juan
|
||||||
|
Flores,Ana
|
||||||
|
Cruz,Isabella
|
||||||
|
Rivera,Victor
|
||||||
|
Lee,Kevin
|
||||||
|
Walker,Brian
|
||||||
|
Hall,Emily
|
||||||
|
Allen,Ryan
|
||||||
|
Young,Aaron
|
||||||
|
King,Jeffrey
|
||||||
|
Wright,Joshua
|
||||||
|
Scott,Brandon
|
||||||
|
Turner,Frank
|
||||||
|
Carter,Gregory
|
||||||
|
Phillips,Samuel
|
||||||
|
Evans,Chris
|
||||||
|
Collins,Anthony
|
||||||
|
Stewart,Eric
|
||||||
|
Snyder,Frank
|
||||||
|
Baker,Thomas
|
||||||
|
Nelson,Jeremy
|
||||||
|
Roberts,Steven
|
||||||
|
Campbell,Edward
|
||||||
|
Miller,Ryan
|
||||||
|
Davis,Jacob
|
||||||
|
Garcia,David
|
||||||
|
Rodriguez,Sophia
|
||||||
|
Martinez,Emma
|
||||||
|
Hernandez,Noah
|
||||||
|
Lopez,Ava
|
||||||
|
Gonzalez,Ethan
|
||||||
|
Perez,Mia
|
||||||
|
Sanchez,William
|
||||||
|
Ramirez,James
|
||||||
|
Flores,Olivia
|
||||||
|
Cruz,Lucas
|
||||||
|
Rivera,Isabella
|
||||||
|
Lee,David
|
||||||
|
Walker,Sophie
|
||||||
|
Hall,Matthew
|
||||||
|
Allen,Emma
|
||||||
|
Young,Ryan
|
||||||
|
King,Ava
|
||||||
|
Wright,Ethan
|
||||||
|
Scott,Mia
|
||||||
|
Turner,William
|
||||||
|
Carter,James
|
||||||
|
Phillips,Olivia
|
||||||
|
Evans,Lucas
|
||||||
|
Collins,Sophie
|
||||||
|
Stewart,Noah
|
||||||
|
Snyder,Ava
|
||||||
|
Baker,Ethan
|
||||||
|
Nelson,Mia
|
||||||
|
Roberts,Noah
|
||||||
|
Campbell,Emma
|
||||||
|
Miller,William
|
||||||
|
Davis,James
|
||||||
|
Garcia,Olivia
|
||||||
|
Rodriguez,Lucas
|
||||||
|
Martinez,Sophie
|
||||||
|
Hernandez,Noah
|
||||||
|
Lopez,Ava
|
||||||
|
Gonzalez,Ethan
|
||||||
|
Perez,Mia
|
||||||
|
Sanchez,William
|
||||||
|
Ramirez,James
|
||||||
|
Flores,Olivia
|
||||||
|
Cruz,Lucas
|
||||||
|
Rivera,Isabella
|
||||||
|
Lee,David
|
||||||
|
Walker,Sophie
|
||||||
|
Hall,Matthew
|
||||||
|
Allen,Emma
|
||||||
|
Young,Ryan
|
||||||
|
King,Ava
|
||||||
|
Wright,Ethan
|
||||||
|
Scott,Mia
|
||||||
|
Turner,William
|
||||||
|
Carter,James
|
||||||
|
Phillips,Olivia
|
||||||
|
Evans,Lucas
|
||||||
|
Collins,Sophie
|
||||||
|
Stewart,Noah
|
||||||
|
Snyder,Ava
|
||||||
|
Baker,Ethan
|
||||||
|
Nelson,Mia
|
||||||
|
Roberts,Noah
|
||||||
|
Campbell,Emma
|
||||||
|
Miller,William
|
||||||
|
Davis,James
|
||||||
|
Garcia,Olivia
|
||||||
|
Rodriguez,Lucas
|
||||||
|
Martinez,Sophie
|
||||||
|
Hernandez,Noah
|
||||||
|
Lopez,Ava
|
||||||
|
Gonzalez,Ethan
|
||||||
|
Perez,Mia
|
||||||
|
Sanchez,William
|
||||||
|
Ramirez,James
|
||||||
|
Flores,Olivia
|
||||||
|
Cruz,Lucas
|
||||||
|
Rivera,Isabella
|
||||||
|
Lee,David
|
||||||
|
Walker,Sophie
|
||||||
|
Hall,Matthew
|
||||||
|
Allen,Emma
|
||||||
|
Young,Ryan
|
||||||
|
King,Ava
|
||||||
|
Wright,Ethan
|
||||||
|
Scott,Mia
|
||||||
|
Turner,William
|
||||||
|
Carter,James
|
||||||
|
Phillips,Olivia
|
||||||
|
Evans,Lucas
|
||||||
|
Collins,Sophie
|
||||||
|
Stewart,Noah
|
||||||
|
Snyder,Ava
|
||||||
|
Baker,Ethan
|
||||||
|
Nelson,Mia
|
||||||
|
Roberts,Noah
|
||||||
|
Campbell,Emma
|
||||||
|
Miller,William
|
||||||
|
Davis,James
|
||||||
|
Garcia,Olivia
|
||||||
|
Rodriguez,Lucas
|
||||||
|
Martinez,Sophie
|
||||||
|
Hernandez,Noah
|
||||||
|
Lopez,Ava
|
||||||
|
Gonzalez,Ethan
|
||||||
|
Perez,Mia
|
||||||
|
Sanchez,William
|
||||||
|
Ramirez,James
|
||||||
|
Flores,Olivia
|
||||||
|
Cruz,Lucas
|
||||||
|
Rivera,Isabella
|
||||||
|
Lee,David
|
||||||
|
Walker,Sophie
|
||||||
|
Hall,Matthew
|
||||||
|
Allen,Emma
|
||||||
|
Young,Ryan
|
||||||
|
King,Ava
|
||||||
|
Wright,Ethan
|
||||||
|
Scott,Mia
|
||||||
|
Turner,William
|
||||||
|
Carter,James
|
||||||
|
Phillips,Olivia
|
||||||
|
Evans,Lucas
|
||||||
|
Collins,Sophie
|
||||||
|
Stewart,Noah
|
||||||
|
Snyder,Ava
|
||||||
|
Baker,Ethan
|
||||||
|
Nelson,Mia
|
||||||
|
Roberts,Noah
|
||||||
|
Campbell,Emma
|
||||||
|
Miller,William
|
||||||
|
Davis,James
|
||||||
|
Garcia,Olivia
|
||||||
|
Rodriguez,Lucas
|
||||||
|
Martinez,Sophie
|
||||||
|
Hernandez,Noah
|
||||||
|
Lopez,Ava
|
||||||
|
Gonzalez,Ethan
|
||||||
|
Perez,Mia
|
||||||
|
Sanchez,William
|
||||||
|
Ramirez,James
|
||||||
|
Flores,Olivia
|
||||||
|
Cruz,Lucas
|
||||||
|
Rivera,Isabella
|
||||||
|
Lee,David
|
||||||
|
Walker,Sophie
|
||||||
|
Hall,Matthew
|
||||||
|
Allen,Emma
|
||||||
|
Young,Ryan
|
||||||
|
King,Ava
|
||||||
|
Wright,Ethan
|
||||||
|
Scott,Mia
|
||||||
|
Turner,William
|
||||||
|
Carter,James
|
||||||
|
Phillips,Olivia
|
||||||
|
Evans,Lucas
|
||||||
|
Collins,Sophie
|
||||||
|
Stewart,Noah
|
||||||
|
Snyder,Ava
|
||||||
|
Baker,Ethan
|
||||||
|
Nelson,Mia
|
||||||
|
Roberts,Noah
|
||||||
|
Campbell,Emma
|
||||||
|
Miller,William
|
||||||
|
Davis,James
|
||||||
|
Garcia,Olivia
|
||||||
|
Rodriguez,Lucas
|
||||||
|
Martinez,Sophie
|
||||||
|
Hernandez,Noah
|
||||||
|
Lopez,Ava
|
||||||
|
Gonzalez,Ethan
|
||||||
|
Perez,Mia
|
||||||
|
Sanchez,William
|
||||||
|
Ramirez,James
|
||||||
|
Flores,Olivia
|
||||||
|
Cruz,Lucas
|
||||||
|
Rivera,Isabella
|
||||||
|
Lee,David
|
||||||
|
Walker,Sophie
|
||||||
|
Hall,Matthew
|
||||||
|
Allen,Emma
|
||||||
|
Young,Ryan
|
||||||
|
King,Ava
|
||||||
|
Wright,Ethan
|
||||||
|
Scott,Mia
|
||||||
|
Turner,William
|
||||||
|
Carter,James
|
||||||
|
Phillips,Olivia
|
||||||
|
Evans,Lucas
|
||||||
|
Collins,Sophie
|
||||||
|
Stewart,Noah
|
||||||
|
Snyder,Ava
|
||||||
|
Baker,Ethan
|
||||||
|
Nelson,Mia
|
||||||
|
Roberts,Noah
|
||||||
|
Campbell,Emma
|
||||||
|
Miller,William
|
||||||
|
Davis,James
|
||||||
|
Garcia,Olivia
|
||||||
|
Rodriguez,Lucas
|
||||||
|
Martinez,Sophie
|
||||||
|
Hernandez,Noah
|
||||||
|
Lopez,Ava
|
||||||
|
Gonzalez,Ethan
|
||||||
|
Perez,Mia
|
||||||
|
Sanchez,William
|
||||||
|
Ramirez,James
|
||||||
|
Flores,Olivia
|
||||||
|
Cruz,Lucas
|
||||||
|
Rivera,Isabella
|
||||||
|
Lee,David
|
||||||
|
Walker,Sophie
|
||||||
|
Hall,Matthew
|
||||||
|
Allen,Emma
|
||||||
|
Young,Ryan
|
||||||
|
King,Ava
|
||||||
|
Wright,Ethan
|
||||||
|
Scott,Mia
|
||||||
|
Turner,William
|
||||||
|
Carter,James
|
||||||
|
Phillips,Olivia
|
||||||
|
Evans,Lucas
|
||||||
|
Collins,Sophie
|
||||||
|
Stewart,Noah
|
||||||
|
Snyder,Ava
|
||||||
|
Baker,Ethan
|
||||||
|
Nelson,Mia
|
||||||
|
Roberts,Noah
|
||||||
|
Campbell,Emma
|
||||||
|
Miller,William
|
||||||
|
Davis,James
|
||||||
|
Garcia,Olivia
|
||||||
|
Rodriguez,Lucas
|
||||||
|
Martinez,Sophie
|
||||||
|
Hernandez,Noah
|
||||||
|
Lopez,Ava
|
||||||
|
Gonzalez,Ethan
|
||||||
|
Perez,Mia
|
||||||
|
Sanchez,William
|
||||||
|
Ramirez,James
|
||||||
|
Flores,Olivia
|
||||||
|
Cruz,Lucas
|
||||||
|
Rivera,Isabella
|
||||||
|
Lee,David
|
||||||
|
Walker,Sophie
|
||||||
|
Hall,Matthew
|
||||||
|
Allen,Emma
|
||||||
|
Young,Ryan
|
||||||
|
King,Ava
|
||||||
|
Wright,Ethan
|
||||||
|
Scott,Mia
|
||||||
|
Turner,William
|
||||||
|
Carter,James
|
||||||
|
Phillips,Olivia
|
||||||
|
Evans,Lucas
|
||||||
|
Collins,Sophie
|
||||||
|
Stewart,Noah
|
||||||
|
Snyder,Ava
|
||||||
|
Baker,Ethan
|
||||||
|
Nelson,Mia
|
||||||
|
Roberts,Noah
|
||||||
|
Campbell,Emma
|
||||||
|
Miller,William
|
||||||
|
Davis,James
|
||||||
|
Garcia,Olivia
|
||||||
|
Rodriguez,Lucas
|
||||||
|
Martinez,Sophie
|
||||||
|
Hernandez,Noah
|
||||||
|
Lopez,Ava
|
||||||
|
Gonzalez,Ethan
|
||||||
|
Perez,Mia
|
||||||
|
Sanchez,William
|
||||||
|
Ramirez,James
|
||||||
|
Flores,Olivia
|
||||||
|
Cruz,Lucas
|
||||||
|
Rivera,Isabella
|
||||||
|
Lee,David
|
||||||
|
Walker,Sophie
|
||||||
|
2
movie-db/requirements.txt
Normal file
2
movie-db/requirements.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
flask
|
||||||
|
dbcm
|
||||||
50
movie-db/templates/add_movie.html
Normal file
50
movie-db/templates/add_movie.html
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block body %}
|
||||||
|
<form action="{{ url }}" method="POST">
|
||||||
|
<input type="text"
|
||||||
|
placeholder="Movie"
|
||||||
|
name="{{ select_movie }}"
|
||||||
|
id="{{ select_movie }}">
|
||||||
|
|
||||||
|
<select name="{{ select_genre }}" id="{{ select_genre }}">
|
||||||
|
{% for name in data %}
|
||||||
|
<option value="{{ name }}">{{ name }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select name="{{ select_medium }}" id="{{ select_medium }}">
|
||||||
|
{% for name in data_medium %}
|
||||||
|
<option value="{{ name }}">{{ name }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select name="{{ select_regie }}" id="{{ select_regie }}">
|
||||||
|
{% for name in data_regie %}
|
||||||
|
<option value="{{ name }}">{{ name }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<button type="submit"> Eingabe </button>
|
||||||
|
</form>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<table border="1" width="50%">
|
||||||
|
<tr>
|
||||||
|
<th>Id</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Genre</th>
|
||||||
|
<th>Regie</th>
|
||||||
|
<th>Medium</th>
|
||||||
|
</tr>
|
||||||
|
{% for list_all in data_all %}
|
||||||
|
<tr>
|
||||||
|
<td>{{list_all.get("id")}}</td>
|
||||||
|
<td>{{list_all.get("titel")}}</td>
|
||||||
|
<td>{{list_all.get("genre")}}</td>
|
||||||
|
<td>{{list_all.get("regie")}}</td>
|
||||||
|
<td>{{list_all.get("medium")}}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
12
movie-db/templates/base.html
Normal file
12
movie-db/templates/base.html
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title> {{ sitename }} </title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2> {{ sitename }} </h2>
|
||||||
|
<p> Es werden alle Filmtitel in einer Liste angezeigt.
|
||||||
|
{% block body %}
|
||||||
|
{% endblock %}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
10
movie-db/templates/output.html
Normal file
10
movie-db/templates/output.html
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<p>
|
||||||
|
Film = {{ add_movie }} <br>
|
||||||
|
Genre = {{ add_genre }} <span>  genre_id = {{ add_genre_id }} <br>
|
||||||
|
Medium = {{ add_medium }} <span>  medium_id = {{add_medium_id }} <br>
|
||||||
|
Regie = {{ add_regie }} <span>  reg_id = {{ add_regie_id }} <br>
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
||||||
650
movie-db/test_jup.ipynb
Normal file
650
movie-db/test_jup.ipynb
Normal file
@@ -0,0 +1,650 @@
|
|||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 1,
|
||||||
|
"id": "5263a987-da36-46d7-a2e7-d0658cda09c1",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import DBcm"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 2,
|
||||||
|
"id": "3f6b0763-4106-4bfa-9aef-7afbd180c6d4",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"db_name = \"movie_db.db\"\n",
|
||||||
|
"\n",
|
||||||
|
"create_my_list = \"\"\"\n",
|
||||||
|
" create table if not exists movie_list (\n",
|
||||||
|
" id integer not null primary key autoincrement,\n",
|
||||||
|
" titel varchar(64) not null,\n",
|
||||||
|
" genre_id integer not null,\n",
|
||||||
|
" regie_id integer not null\n",
|
||||||
|
" \n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
"\"\"\"\n",
|
||||||
|
"\n",
|
||||||
|
"create_genre = \"\"\"\n",
|
||||||
|
" create table if not exists genre (\n",
|
||||||
|
" id integer not null primary key autoincrement,\n",
|
||||||
|
" name varchar(64) not null\n",
|
||||||
|
" )\n",
|
||||||
|
"\"\"\"\n",
|
||||||
|
"\n",
|
||||||
|
"create_regie = \"\"\"\n",
|
||||||
|
" create table if not exists regie (\n",
|
||||||
|
" id integer not null primary key autoincrement,\n",
|
||||||
|
" surname varchar(64) not null,\n",
|
||||||
|
" lastname varchr(64) not null\n",
|
||||||
|
" )\n",
|
||||||
|
"\"\"\"\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"with DBcm.UseDatabase(db_name) as db: \n",
|
||||||
|
" db.execute(create_my_list)\n",
|
||||||
|
" db.execute(create_genre)\n",
|
||||||
|
" db.execute(create_regie)\n",
|
||||||
|
" "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 3,
|
||||||
|
"id": "376ef812-97b5-45ba-8ef1-eb8d7829494a",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# ADDed Genre values\n",
|
||||||
|
"\n",
|
||||||
|
"ADD_GENRE_VALUE = \"\"\"\n",
|
||||||
|
" INSERT INTO genre(name)\n",
|
||||||
|
" SELECT ?\n",
|
||||||
|
" WHERE NOT EXISTS (SELECT 1 FROM genre WHERE name = ?);\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
"\n",
|
||||||
|
"with open(\"genre_list\", \"r\") as fs: \n",
|
||||||
|
" for genre_value in fs.readlines():\n",
|
||||||
|
" with DBcm.UseDatabase(db_name) as db:\n",
|
||||||
|
" db.execute(ADD_GENRE_VALUE, (genre_value.strip(), genre_value.strip()))\n",
|
||||||
|
" "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 27,
|
||||||
|
"id": "63b16a41-88bf-4832-a26c-09180832f597",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"['action', 'adventure', 'animation', 'biography', 'comedy', 'crime', 'cult movie', 'disney', 'documentary', 'drama', 'erotic', 'family', 'fantasy', 'film-noir', 'gangster', 'gay and lesbian', 'history', 'horror', 'military', 'music', 'musical', 'mystery', 'nature', 'neo-noir', 'period', 'pixar', 'road movie', 'romance', 'sci-fi', 'short', 'spy', 'super hero', 'thriller', 'visually stunning', 'war', 'western']\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"def all_genres():\n",
|
||||||
|
" ALL_GENRE = \"\"\"\n",
|
||||||
|
" SELECT * from genre \n",
|
||||||
|
" \"\"\" \n",
|
||||||
|
" with DBcm.UseDatabase(db_name) as db:\n",
|
||||||
|
" db.execute(ALL_GENRE)\n",
|
||||||
|
" all_genre = [i[1] for i in db.fetchall()]\n",
|
||||||
|
" \n",
|
||||||
|
" return all_genre\n",
|
||||||
|
"\n",
|
||||||
|
"print(all_genres())\n",
|
||||||
|
" "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 36,
|
||||||
|
"id": "89b20b5f-34aa-4490-a4c0-c186c9fa30bd",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"1\n",
|
||||||
|
"36\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"def search_genre_id(genre_name):\n",
|
||||||
|
" GENRE_QUERY = \"\"\"\n",
|
||||||
|
" select id from genre\n",
|
||||||
|
" where name = ?\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" try:\n",
|
||||||
|
" with DBcm.UseDatabase(db_name) as db:\n",
|
||||||
|
" db.execute(GENRE_QUERY,(genre_name,))\n",
|
||||||
|
" genre_id = db.fetchone()[0]\n",
|
||||||
|
" return int(genre_id)\n",
|
||||||
|
" except:\n",
|
||||||
|
" return int(0)\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"def search_medium_id(genre_name):\n",
|
||||||
|
" GENRE_QUERY = \"\"\"\n",
|
||||||
|
" select id from genre\n",
|
||||||
|
" where medium = ?\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" try:\n",
|
||||||
|
" with DBcm.UseDatabase(db_name) as db:\n",
|
||||||
|
" db.execute(GENRE_QUERY,(genre_name,))\n",
|
||||||
|
" genre_id = db.fetchone()[0]\n",
|
||||||
|
" return int(genre_id)\n",
|
||||||
|
" except:\n",
|
||||||
|
" return int(0)\n",
|
||||||
|
"\n",
|
||||||
|
"print(search_genre_id(genre_name=\"action\"))\n",
|
||||||
|
"print(search_genre_id(genre_name=\"western\"))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 18,
|
||||||
|
"id": "c70d91a5-7855-465d-a4a6-daebc065ee37",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"0-John-Smith\n",
|
||||||
|
"1-James-Johnson\n",
|
||||||
|
"2-William-Williams\n",
|
||||||
|
"3-Michael-Brown\n",
|
||||||
|
"4-David-Davis\n",
|
||||||
|
"5-Richard-Miller\n",
|
||||||
|
"6-Joseph-Wilson\n",
|
||||||
|
"7-Charles-Moore\n",
|
||||||
|
"8-Thomas-Taylor\n",
|
||||||
|
"9-Daniel-Anderson\n",
|
||||||
|
"10-Paul-Thomas\n",
|
||||||
|
"11-Mark-Jackson\n",
|
||||||
|
"12-Donna-White\n",
|
||||||
|
"13-Michelle-Harris\n",
|
||||||
|
"14-Laura-Martin\n",
|
||||||
|
"15-Sara-Thompson\n",
|
||||||
|
"16-Ana-Garcia\n",
|
||||||
|
"17-Carlos-Rodriguez\n",
|
||||||
|
"18-Maria-Martinez\n",
|
||||||
|
"19-Jose-Hernandez\n",
|
||||||
|
"20-Luis-Lopez\n",
|
||||||
|
"21-Rosa-Gonzalez\n",
|
||||||
|
"22-Pedro-Perez\n",
|
||||||
|
"23-Miguel-Sanchez\n",
|
||||||
|
"24-Juan-Ramirez\n",
|
||||||
|
"25-Ana-Flores\n",
|
||||||
|
"26-Isabella-Cruz\n",
|
||||||
|
"27-Victor-Rivera\n",
|
||||||
|
"28-Kevin-Lee\n",
|
||||||
|
"29-Brian-Walker\n",
|
||||||
|
"30-Emily-Hall\n",
|
||||||
|
"31-Ryan-Allen\n",
|
||||||
|
"32-Aaron-Young\n",
|
||||||
|
"33-Jeffrey-King\n",
|
||||||
|
"34-Joshua-Wright\n",
|
||||||
|
"35-Brandon-Scott\n",
|
||||||
|
"36-Frank-Turner\n",
|
||||||
|
"37-Gregory-Carter\n",
|
||||||
|
"38-Samuel-Phillips\n",
|
||||||
|
"39-Chris-Evans\n",
|
||||||
|
"40-Anthony-Collins\n",
|
||||||
|
"41-Eric-Stewart\n",
|
||||||
|
"42-Frank-Snyder\n",
|
||||||
|
"43-Thomas-Baker\n",
|
||||||
|
"44-Jeremy-Nelson\n",
|
||||||
|
"45-Steven-Roberts\n",
|
||||||
|
"46-Edward-Campbell\n",
|
||||||
|
"47-Ryan-Miller\n",
|
||||||
|
"48-Jacob-Davis\n",
|
||||||
|
"49-David-Garcia\n",
|
||||||
|
"50-Sophia-Rodriguez\n",
|
||||||
|
"51-Emma-Martinez\n",
|
||||||
|
"52-Noah-Hernandez\n",
|
||||||
|
"53-Ava-Lopez\n",
|
||||||
|
"54-Ethan-Gonzalez\n",
|
||||||
|
"55-Mia-Perez\n",
|
||||||
|
"56-William-Sanchez\n",
|
||||||
|
"57-James-Ramirez\n",
|
||||||
|
"58-Olivia-Flores\n",
|
||||||
|
"59-Lucas-Cruz\n",
|
||||||
|
"60-Isabella-Rivera\n",
|
||||||
|
"61-David-Lee\n",
|
||||||
|
"62-Sophie-Walker\n",
|
||||||
|
"63-Matthew-Hall\n",
|
||||||
|
"64-Emma-Allen\n",
|
||||||
|
"65-Ryan-Young\n",
|
||||||
|
"66-Ava-King\n",
|
||||||
|
"67-Ethan-Wright\n",
|
||||||
|
"68-Mia-Scott\n",
|
||||||
|
"69-William-Turner\n",
|
||||||
|
"70-James-Carter\n",
|
||||||
|
"71-Olivia-Phillips\n",
|
||||||
|
"72-Lucas-Evans\n",
|
||||||
|
"73-Sophie-Collins\n",
|
||||||
|
"74-Noah-Stewart\n",
|
||||||
|
"75-Ava-Snyder\n",
|
||||||
|
"76-Ethan-Baker\n",
|
||||||
|
"77-Mia-Nelson\n",
|
||||||
|
"78-Noah-Roberts\n",
|
||||||
|
"79-Emma-Campbell\n",
|
||||||
|
"80-William-Miller\n",
|
||||||
|
"81-James-Davis\n",
|
||||||
|
"82-Olivia-Garcia\n",
|
||||||
|
"83-Lucas-Rodriguez\n",
|
||||||
|
"84-Sophie-Martinez\n",
|
||||||
|
"85-Noah-Hernandez\n",
|
||||||
|
"86-Ava-Lopez\n",
|
||||||
|
"87-Ethan-Gonzalez\n",
|
||||||
|
"88-Mia-Perez\n",
|
||||||
|
"89-William-Sanchez\n",
|
||||||
|
"90-James-Ramirez\n",
|
||||||
|
"91-Olivia-Flores\n",
|
||||||
|
"92-Lucas-Cruz\n",
|
||||||
|
"93-Isabella-Rivera\n",
|
||||||
|
"94-David-Lee\n",
|
||||||
|
"95-Sophie-Walker\n",
|
||||||
|
"96-Matthew-Hall\n",
|
||||||
|
"97-Emma-Allen\n",
|
||||||
|
"98-Ryan-Young\n",
|
||||||
|
"99-Ava-King\n",
|
||||||
|
"100-Ethan-Wright\n",
|
||||||
|
"101-Mia-Scott\n",
|
||||||
|
"102-William-Turner\n",
|
||||||
|
"103-James-Carter\n",
|
||||||
|
"104-Olivia-Phillips\n",
|
||||||
|
"105-Lucas-Evans\n",
|
||||||
|
"106-Sophie-Collins\n",
|
||||||
|
"107-Noah-Stewart\n",
|
||||||
|
"108-Ava-Snyder\n",
|
||||||
|
"109-Ethan-Baker\n",
|
||||||
|
"110-Mia-Nelson\n",
|
||||||
|
"111-Noah-Roberts\n",
|
||||||
|
"112-Emma-Campbell\n",
|
||||||
|
"113-William-Miller\n",
|
||||||
|
"114-James-Davis\n",
|
||||||
|
"115-Olivia-Garcia\n",
|
||||||
|
"116-Lucas-Rodriguez\n",
|
||||||
|
"117-Sophie-Martinez\n",
|
||||||
|
"118-Noah-Hernandez\n",
|
||||||
|
"119-Ava-Lopez\n",
|
||||||
|
"120-Ethan-Gonzalez\n",
|
||||||
|
"121-Mia-Perez\n",
|
||||||
|
"122-William-Sanchez\n",
|
||||||
|
"123-James-Ramirez\n",
|
||||||
|
"124-Olivia-Flores\n",
|
||||||
|
"125-Lucas-Cruz\n",
|
||||||
|
"126-Isabella-Rivera\n",
|
||||||
|
"127-David-Lee\n",
|
||||||
|
"128-Sophie-Walker\n",
|
||||||
|
"129-Matthew-Hall\n",
|
||||||
|
"130-Emma-Allen\n",
|
||||||
|
"131-Ryan-Young\n",
|
||||||
|
"132-Ava-King\n",
|
||||||
|
"133-Ethan-Wright\n",
|
||||||
|
"134-Mia-Scott\n",
|
||||||
|
"135-William-Turner\n",
|
||||||
|
"136-James-Carter\n",
|
||||||
|
"137-Olivia-Phillips\n",
|
||||||
|
"138-Lucas-Evans\n",
|
||||||
|
"139-Sophie-Collins\n",
|
||||||
|
"140-Noah-Stewart\n",
|
||||||
|
"141-Ava-Snyder\n",
|
||||||
|
"142-Ethan-Baker\n",
|
||||||
|
"143-Mia-Nelson\n",
|
||||||
|
"144-Noah-Roberts\n",
|
||||||
|
"145-Emma-Campbell\n",
|
||||||
|
"146-William-Miller\n",
|
||||||
|
"147-James-Davis\n",
|
||||||
|
"148-Olivia-Garcia\n",
|
||||||
|
"149-Lucas-Rodriguez\n",
|
||||||
|
"150-Sophie-Martinez\n",
|
||||||
|
"151-Noah-Hernandez\n",
|
||||||
|
"152-Ava-Lopez\n",
|
||||||
|
"153-Ethan-Gonzalez\n",
|
||||||
|
"154-Mia-Perez\n",
|
||||||
|
"155-William-Sanchez\n",
|
||||||
|
"156-James-Ramirez\n",
|
||||||
|
"157-Olivia-Flores\n",
|
||||||
|
"158-Lucas-Cruz\n",
|
||||||
|
"159-Isabella-Rivera\n",
|
||||||
|
"160-David-Lee\n",
|
||||||
|
"161-Sophie-Walker\n",
|
||||||
|
"162-Matthew-Hall\n",
|
||||||
|
"163-Emma-Allen\n",
|
||||||
|
"164-Ryan-Young\n",
|
||||||
|
"165-Ava-King\n",
|
||||||
|
"166-Ethan-Wright\n",
|
||||||
|
"167-Mia-Scott\n",
|
||||||
|
"168-William-Turner\n",
|
||||||
|
"169-James-Carter\n",
|
||||||
|
"170-Olivia-Phillips\n",
|
||||||
|
"171-Lucas-Evans\n",
|
||||||
|
"172-Sophie-Collins\n",
|
||||||
|
"173-Noah-Stewart\n",
|
||||||
|
"174-Ava-Snyder\n",
|
||||||
|
"175-Ethan-Baker\n",
|
||||||
|
"176-Mia-Nelson\n",
|
||||||
|
"177-Noah-Roberts\n",
|
||||||
|
"178-Emma-Campbell\n",
|
||||||
|
"179-William-Miller\n",
|
||||||
|
"180-James-Davis\n",
|
||||||
|
"181-Olivia-Garcia\n",
|
||||||
|
"182-Lucas-Rodriguez\n",
|
||||||
|
"183-Sophie-Martinez\n",
|
||||||
|
"184-Noah-Hernandez\n",
|
||||||
|
"185-Ava-Lopez\n",
|
||||||
|
"186-Ethan-Gonzalez\n",
|
||||||
|
"187-Mia-Perez\n",
|
||||||
|
"188-William-Sanchez\n",
|
||||||
|
"189-James-Ramirez\n",
|
||||||
|
"190-Olivia-Flores\n",
|
||||||
|
"191-Lucas-Cruz\n",
|
||||||
|
"192-Isabella-Rivera\n",
|
||||||
|
"193-David-Lee\n",
|
||||||
|
"194-Sophie-Walker\n",
|
||||||
|
"195-Matthew-Hall\n",
|
||||||
|
"196-Emma-Allen\n",
|
||||||
|
"197-Ryan-Young\n",
|
||||||
|
"198-Ava-King\n",
|
||||||
|
"199-Ethan-Wright\n",
|
||||||
|
"200-Mia-Scott\n",
|
||||||
|
"201-William-Turner\n",
|
||||||
|
"202-James-Carter\n",
|
||||||
|
"203-Olivia-Phillips\n",
|
||||||
|
"204-Lucas-Evans\n",
|
||||||
|
"205-Sophie-Collins\n",
|
||||||
|
"206-Noah-Stewart\n",
|
||||||
|
"207-Ava-Snyder\n",
|
||||||
|
"208-Ethan-Baker\n",
|
||||||
|
"209-Mia-Nelson\n",
|
||||||
|
"210-Noah-Roberts\n",
|
||||||
|
"211-Emma-Campbell\n",
|
||||||
|
"212-William-Miller\n",
|
||||||
|
"213-James-Davis\n",
|
||||||
|
"214-Olivia-Garcia\n",
|
||||||
|
"215-Lucas-Rodriguez\n",
|
||||||
|
"216-Sophie-Martinez\n",
|
||||||
|
"217-Noah-Hernandez\n",
|
||||||
|
"218-Ava-Lopez\n",
|
||||||
|
"219-Ethan-Gonzalez\n",
|
||||||
|
"220-Mia-Perez\n",
|
||||||
|
"221-William-Sanchez\n",
|
||||||
|
"222-James-Ramirez\n",
|
||||||
|
"223-Olivia-Flores\n",
|
||||||
|
"224-Lucas-Cruz\n",
|
||||||
|
"225-Isabella-Rivera\n",
|
||||||
|
"226-David-Lee\n",
|
||||||
|
"227-Sophie-Walker\n",
|
||||||
|
"228-Matthew-Hall\n",
|
||||||
|
"229-Emma-Allen\n",
|
||||||
|
"230-Ryan-Young\n",
|
||||||
|
"231-Ava-King\n",
|
||||||
|
"232-Ethan-Wright\n",
|
||||||
|
"233-Mia-Scott\n",
|
||||||
|
"234-William-Turner\n",
|
||||||
|
"235-James-Carter\n",
|
||||||
|
"236-Olivia-Phillips\n",
|
||||||
|
"237-Lucas-Evans\n",
|
||||||
|
"238-Sophie-Collins\n",
|
||||||
|
"239-Noah-Stewart\n",
|
||||||
|
"240-Ava-Snyder\n",
|
||||||
|
"241-Ethan-Baker\n",
|
||||||
|
"242-Mia-Nelson\n",
|
||||||
|
"243-Noah-Roberts\n",
|
||||||
|
"244-Emma-Campbell\n",
|
||||||
|
"245-William-Miller\n",
|
||||||
|
"246-James-Davis\n",
|
||||||
|
"247-Olivia-Garcia\n",
|
||||||
|
"248-Lucas-Rodriguez\n",
|
||||||
|
"249-Sophie-Martinez\n",
|
||||||
|
"250-Noah-Hernandez\n",
|
||||||
|
"251-Ava-Lopez\n",
|
||||||
|
"252-Ethan-Gonzalez\n",
|
||||||
|
"253-Mia-Perez\n",
|
||||||
|
"254-William-Sanchez\n",
|
||||||
|
"255-James-Ramirez\n",
|
||||||
|
"256-Olivia-Flores\n",
|
||||||
|
"257-Lucas-Cruz\n",
|
||||||
|
"258-Isabella-Rivera\n",
|
||||||
|
"259-David-Lee\n",
|
||||||
|
"260-Sophie-Walker\n",
|
||||||
|
"261-Matthew-Hall\n",
|
||||||
|
"262-Emma-Allen\n",
|
||||||
|
"263-Ryan-Young\n",
|
||||||
|
"264-Ava-King\n",
|
||||||
|
"265-Ethan-Wright\n",
|
||||||
|
"266-Mia-Scott\n",
|
||||||
|
"267-William-Turner\n",
|
||||||
|
"268-James-Carter\n",
|
||||||
|
"269-Olivia-Phillips\n",
|
||||||
|
"270-Lucas-Evans\n",
|
||||||
|
"271-Sophie-Collins\n",
|
||||||
|
"272-Noah-Stewart\n",
|
||||||
|
"273-Ava-Snyder\n",
|
||||||
|
"274-Ethan-Baker\n",
|
||||||
|
"275-Mia-Nelson\n",
|
||||||
|
"276-Noah-Roberts\n",
|
||||||
|
"277-Emma-Campbell\n",
|
||||||
|
"278-William-Miller\n",
|
||||||
|
"279-James-Davis\n",
|
||||||
|
"280-Olivia-Garcia\n",
|
||||||
|
"281-Lucas-Rodriguez\n",
|
||||||
|
"282-Sophie-Martinez\n",
|
||||||
|
"283-Noah-Hernandez\n",
|
||||||
|
"284-Ava-Lopez\n",
|
||||||
|
"285-Ethan-Gonzalez\n",
|
||||||
|
"286-Mia-Perez\n",
|
||||||
|
"287-William-Sanchez\n",
|
||||||
|
"288-James-Ramirez\n",
|
||||||
|
"289-Olivia-Flores\n",
|
||||||
|
"290-Lucas-Cruz\n",
|
||||||
|
"291-Isabella-Rivera\n",
|
||||||
|
"292-David-Lee\n",
|
||||||
|
"293-Sophie-Walker\n",
|
||||||
|
"294-Matthew-Hall\n",
|
||||||
|
"295-Emma-Allen\n",
|
||||||
|
"296-Ryan-Young\n",
|
||||||
|
"297-Ava-King\n",
|
||||||
|
"298-Ethan-Wright\n",
|
||||||
|
"299-Mia-Scott\n",
|
||||||
|
"300-William-Turner\n",
|
||||||
|
"301-James-Carter\n",
|
||||||
|
"302-Olivia-Phillips\n",
|
||||||
|
"303-Lucas-Evans\n",
|
||||||
|
"304-Sophie-Collins\n",
|
||||||
|
"305-Noah-Stewart\n",
|
||||||
|
"306-Ava-Snyder\n",
|
||||||
|
"307-Ethan-Baker\n",
|
||||||
|
"308-Mia-Nelson\n",
|
||||||
|
"309-Noah-Roberts\n",
|
||||||
|
"310-Emma-Campbell\n",
|
||||||
|
"311-William-Miller\n",
|
||||||
|
"312-James-Davis\n",
|
||||||
|
"313-Olivia-Garcia\n",
|
||||||
|
"314-Lucas-Rodriguez\n",
|
||||||
|
"315-Sophie-Martinez\n",
|
||||||
|
"316-Noah-Hernandez\n",
|
||||||
|
"317-Ava-Lopez\n",
|
||||||
|
"318-Ethan-Gonzalez\n",
|
||||||
|
"319-Mia-Perez\n",
|
||||||
|
"320-William-Sanchez\n",
|
||||||
|
"321-James-Ramirez\n",
|
||||||
|
"322-Olivia-Flores\n",
|
||||||
|
"323-Lucas-Cruz\n",
|
||||||
|
"324-Isabella-Rivera\n",
|
||||||
|
"325-David-Lee\n",
|
||||||
|
"326-Sophie-Walker\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"import pandas as pd\n",
|
||||||
|
"usecols = [\"Name\", \"Vorname\"]\n",
|
||||||
|
"air = pd.read_csv(\"regie_name.csv\", usecols=usecols)\n",
|
||||||
|
"\n",
|
||||||
|
"for count, (i, b) in enumerate(zip(air[\"Name\"], air[\"Vorname\"])):\n",
|
||||||
|
" print(count, b, i, sep=\"-\")\n",
|
||||||
|
"\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 3,
|
||||||
|
"id": "ee4b5dee-6b41-49eb-8d75-9db50d20fdef",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/html": [
|
||||||
|
"<div>\n",
|
||||||
|
"<style scoped>\n",
|
||||||
|
" .dataframe tbody tr th:only-of-type {\n",
|
||||||
|
" vertical-align: middle;\n",
|
||||||
|
" }\n",
|
||||||
|
"\n",
|
||||||
|
" .dataframe tbody tr th {\n",
|
||||||
|
" vertical-align: top;\n",
|
||||||
|
" }\n",
|
||||||
|
"\n",
|
||||||
|
" .dataframe thead th {\n",
|
||||||
|
" text-align: right;\n",
|
||||||
|
" }\n",
|
||||||
|
"</style>\n",
|
||||||
|
"<table border=\"1\" class=\"dataframe\">\n",
|
||||||
|
" <thead>\n",
|
||||||
|
" <tr style=\"text-align: right;\">\n",
|
||||||
|
" <th></th>\n",
|
||||||
|
" <th>Name</th>\n",
|
||||||
|
" <th>Vorname</th>\n",
|
||||||
|
" </tr>\n",
|
||||||
|
" </thead>\n",
|
||||||
|
" <tbody>\n",
|
||||||
|
" <tr>\n",
|
||||||
|
" <th>0</th>\n",
|
||||||
|
" <td>Smith</td>\n",
|
||||||
|
" <td>John</td>\n",
|
||||||
|
" </tr>\n",
|
||||||
|
" <tr>\n",
|
||||||
|
" <th>1</th>\n",
|
||||||
|
" <td>Johnson</td>\n",
|
||||||
|
" <td>James</td>\n",
|
||||||
|
" </tr>\n",
|
||||||
|
" <tr>\n",
|
||||||
|
" <th>2</th>\n",
|
||||||
|
" <td>Williams</td>\n",
|
||||||
|
" <td>William</td>\n",
|
||||||
|
" </tr>\n",
|
||||||
|
" <tr>\n",
|
||||||
|
" <th>3</th>\n",
|
||||||
|
" <td>Brown</td>\n",
|
||||||
|
" <td>Michael</td>\n",
|
||||||
|
" </tr>\n",
|
||||||
|
" <tr>\n",
|
||||||
|
" <th>4</th>\n",
|
||||||
|
" <td>Davis</td>\n",
|
||||||
|
" <td>David</td>\n",
|
||||||
|
" </tr>\n",
|
||||||
|
" </tbody>\n",
|
||||||
|
"</table>\n",
|
||||||
|
"</div>"
|
||||||
|
],
|
||||||
|
"text/plain": [
|
||||||
|
" Name Vorname\n",
|
||||||
|
"0 Smith John\n",
|
||||||
|
"1 Johnson James\n",
|
||||||
|
"2 Williams William\n",
|
||||||
|
"3 Brown Michael\n",
|
||||||
|
"4 Davis David"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 3,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"import pandas as pd\n",
|
||||||
|
"air = pd.read_csv(\"regie_name.csv\", nrows=5)\n",
|
||||||
|
"air"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 7,
|
||||||
|
"id": "8017742d-3b8e-4847-b5a3-4f28e0c9057a",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"Name\n",
|
||||||
|
"Flores 10.0\n",
|
||||||
|
"Davis 10.0\n",
|
||||||
|
"Gonzalez 10.0\n",
|
||||||
|
"Garcia 10.0\n",
|
||||||
|
"Cruz 10.0\n",
|
||||||
|
" ... \n",
|
||||||
|
"Taylor 1.0\n",
|
||||||
|
"White 1.0\n",
|
||||||
|
"Thompson 1.0\n",
|
||||||
|
"Wilson 1.0\n",
|
||||||
|
"Williams 1.0\n",
|
||||||
|
"Length: 47, dtype: float64\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"chunker = pd.read_csv(\"regie_name.csv\", chunksize=1000)\n",
|
||||||
|
"tot = pd.Series([], dtype='int64')\n",
|
||||||
|
"for piece in chunker:\n",
|
||||||
|
" tot = tot.add(piece[\"Name\"].value_counts(), fill_value=0)\n",
|
||||||
|
"tot = tot.sort_values(ascending=False)\n",
|
||||||
|
"print(tot)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "d7531f34-19a6-4606-88f2-1c4fdd3b0b7d",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3 (ipykernel)",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.13.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 5
|
||||||
|
}
|
||||||
@@ -46,12 +46,13 @@ INSERT INTO filmgenres(genre, beschreibung)
|
|||||||
cursor = con_db.cursor()
|
cursor = con_db.cursor()
|
||||||
while True:
|
while True:
|
||||||
##Abfrage Name
|
##Abfrage Name
|
||||||
|
|
||||||
name = input("Name des Films: ")
|
name = input("Name des Films: ")
|
||||||
if not name:
|
if not name:
|
||||||
break
|
break
|
||||||
##Abfrage Genre
|
##Abfrage Genre
|
||||||
while True:
|
|
||||||
|
|
||||||
|
while True:
|
||||||
movie_genre = input("Genre: ")
|
movie_genre = input("Genre: ")
|
||||||
sql = """Select * from filmgenres where genre = '{genre}'""".format(genre=movie_genre)
|
sql = """Select * from filmgenres where genre = '{genre}'""".format(genre=movie_genre)
|
||||||
cursor.execute(sql)
|
cursor.execute(sql)
|
||||||
@@ -65,7 +66,13 @@ INSERT INTO filmgenres(genre, beschreibung)
|
|||||||
self.ausgabe_abfrage(sql_abfrage="""Select genre from filmgenres""")
|
self.ausgabe_abfrage(sql_abfrage="""Select genre from filmgenres""")
|
||||||
|
|
||||||
#Abfrage Jahr
|
#Abfrage Jahr
|
||||||
movie_year = input("Jahr: ")
|
while True:
|
||||||
|
movie_year = input("Jahr: ")
|
||||||
|
if len(str(movie_year)) == 4 and movie_year.isdigit() is True:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print("Das Jahr muss 4 Zeichen haben und aus Zahlen bestehen.")
|
||||||
|
|
||||||
#Abfrage Format
|
#Abfrage Format
|
||||||
while True:
|
while True:
|
||||||
format = input("Format :")
|
format = input("Format :")
|
||||||
@@ -74,7 +81,7 @@ INSERT INTO filmgenres(genre, beschreibung)
|
|||||||
else:
|
else:
|
||||||
print("blue-ray", "dvd", "platte", "sd")
|
print("blue-ray", "dvd", "platte", "sd")
|
||||||
#Abfrage Meinung
|
#Abfrage Meinung
|
||||||
per_info = input("Meinung : ")
|
per_info = input("Meinung : ").lower()
|
||||||
|
|
||||||
sql = """Select * from movies WHERE name = '{name}';""".format(name=name)
|
sql = """Select * from movies WHERE name = '{name}';""".format(name=name)
|
||||||
cursor.execute(sql)
|
cursor.execute(sql)
|
||||||
@@ -121,7 +128,10 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
for query in argv.sys.argv[1:]:
|
for query in argv.sys.argv[1:]:
|
||||||
if query == '-q':
|
if query == '-q':
|
||||||
my_db.ausgabe_abfrage(sql_abfrage="""SELECT * FROM movies;""")
|
if argv.argv_value('-q') is None:
|
||||||
|
my_db.ausgabe_abfrage(sql_abfrage="""SELECT * FROM movies;""")
|
||||||
|
else:
|
||||||
|
my_db.ausgabe_abfrage(sql_abfrage="""Select * from movies WHERE name like '%{search}%';""".format(search=argv.argv_value('-q')))
|
||||||
if query == '-a':
|
if query == '-a':
|
||||||
my_db.add_value_db()
|
my_db.add_value_db()
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
0
my_movies/spam.db
Normal file
0
my_movies/spam.db
Normal file
30
my_movies/webserver.py
Normal file
30
my_movies/webserver.py
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# Python 3 server example
|
||||||
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||||
|
import time
|
||||||
|
hostName = "localhost"
|
||||||
|
serverPort = 8080
|
||||||
|
|
||||||
|
|
||||||
|
class MyServer(BaseHTTPRequestHandler):
|
||||||
|
def do_GET(self):
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header("Content-type", "text/html")
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(bytes("<html><head><title>Mein Test</title></head>", "utf-8"))
|
||||||
|
self.wfile.write(bytes("<p>Request: %s</p>" % self.path, "utf-8"))
|
||||||
|
self.wfile.write(bytes(str("<p>Uhrzeit :" + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + "</p>",), "utf-8" ))
|
||||||
|
self.wfile.write(bytes("<body>", "utf-8"))
|
||||||
|
self.wfile.write(bytes("<p>Hier kommen die Infos rein !!!</p>", "utf-8"))
|
||||||
|
self.wfile.write(bytes("</body></html>", "utf-8"))
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
webServer = HTTPServer((hostName, serverPort), MyServer)
|
||||||
|
print("Server started http://%s:%s" % (hostName, serverPort))
|
||||||
|
|
||||||
|
try:
|
||||||
|
webServer.serve_forever()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
|
||||||
|
webServer.server_close()
|
||||||
|
print("Server stopped.")
|
||||||
37
ollama_remote_query/ollama_prompt.py
Executable file
37
ollama_remote_query/ollama_prompt.py
Executable file
@@ -0,0 +1,37 @@
|
|||||||
|
#! /usr/bin/env python
|
||||||
|
from ollama import Client
|
||||||
|
import datetime
|
||||||
|
import os
|
||||||
|
|
||||||
|
output_folder = "output"
|
||||||
|
|
||||||
|
if not os.path.exists(output_folder):
|
||||||
|
os.makedirs(output_folder)
|
||||||
|
|
||||||
|
# Create_Timestamp
|
||||||
|
now = int(datetime.datetime.now().timestamp())
|
||||||
|
# res = int(now.timestamp())
|
||||||
|
|
||||||
|
# PROMT
|
||||||
|
prompt = input("Was möchtest du Fragen: ")
|
||||||
|
|
||||||
|
client = Client(
|
||||||
|
host='http://localhost:11434',
|
||||||
|
headers={'x-some-header': 'some-value'}
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.chat(
|
||||||
|
model='gemma3n:e2b',
|
||||||
|
messages=[
|
||||||
|
{
|
||||||
|
'role': 'user',
|
||||||
|
'content': prompt,
|
||||||
|
}],
|
||||||
|
stream=True)
|
||||||
|
|
||||||
|
for chunk in response:
|
||||||
|
print(chunk['message']["content"], end='', flush=True)
|
||||||
|
with open(str(output_folder + "/ollama_output_" + str(now) + ".md"), "a") as dm:
|
||||||
|
print(chunk['message']["content"], end='', flush=True, file=dm)
|
||||||
|
|
||||||
|
# with open("test.md", "w") as dm:
|
||||||
6
ollama_remote_query/output/ollama_output_1755524506.md
Normal file
6
ollama_remote_query/output/ollama_output_1755524506.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Okay, I'm exiting. Have a good one!
|
||||||
|
|
||||||
|
If you need anything in the future, feel free to ask. 😊
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
38
ollama_remote_query/translate_func.py
Normal file
38
ollama_remote_query/translate_func.py
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# %% packages
|
||||||
|
# from langchain_openai import ChatOpenAI
|
||||||
|
import langchain_ollama
|
||||||
|
from langchain_core.prompts import ChatPromptTemplate
|
||||||
|
# from dotenv import load_dotenv
|
||||||
|
from langchain_core.output_parsers import StrOutputParser
|
||||||
|
# load_dotenv('.env')
|
||||||
|
|
||||||
|
|
||||||
|
def translate_func(select_lang="Germany", target_lang="English", query_trans="prompt"):
|
||||||
|
if query_trans == "prompt":
|
||||||
|
query_trans = input("Was soll Übersetzt werden ? ")
|
||||||
|
# %% set up prompt template
|
||||||
|
prompt_template = ChatPromptTemplate.from_messages([
|
||||||
|
("system", f"You are an AI assistant that translates {
|
||||||
|
select_lang} into another language."),
|
||||||
|
("user", "Translate this sentence: '{input}' into {target_language}"),
|
||||||
|
])
|
||||||
|
|
||||||
|
# %% model
|
||||||
|
model = langchain_ollama.llms.OllamaLLM(base_url='http://localhost:11434', model="gemma3n:e2b",
|
||||||
|
temperature=0)
|
||||||
|
|
||||||
|
# %% chain
|
||||||
|
chain = prompt_template | model | StrOutputParser()
|
||||||
|
|
||||||
|
# %% invoke chain
|
||||||
|
res = chain.invoke({"input": query_trans,
|
||||||
|
"target_language": target_lang})
|
||||||
|
print(res)
|
||||||
|
|
||||||
|
# %%
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
select_lang = "Germany"
|
||||||
|
target_lang = "English"
|
||||||
|
translate_func(select_lang=target_lang, target_lang=select_lang)
|
||||||
13
play_ansible/inv_plugin/ansible.cfg
Executable file
13
play_ansible/inv_plugin/ansible.cfg
Executable file
@@ -0,0 +1,13 @@
|
|||||||
|
[defaults]
|
||||||
|
#inventory = /home/user06/hosts
|
||||||
|
inventory = ./ansible_inv_main.py
|
||||||
|
ansible_managed = Ansible managed: {file} modified on %Y-%m-%d %H:%M:%S on {host}
|
||||||
|
private_key_file = /home/jonnybravo/.ssh/ansible-test
|
||||||
|
gathering = smart
|
||||||
|
fact_caching = yaml
|
||||||
|
fact_caching_timeout = 3600
|
||||||
|
fact_caching_connection = fact
|
||||||
|
library = lib
|
||||||
|
lookup_plugins = lookup
|
||||||
|
|
||||||
|
filter_plugins = ./filter
|
||||||
105
play_ansible/inv_plugin/ansible_inv_main.py
Executable file
105
play_ansible/inv_plugin/ansible_inv_main.py
Executable file
@@ -0,0 +1,105 @@
|
|||||||
|
#! /usr/bin/env python3
|
||||||
|
|
||||||
|
import csv
|
||||||
|
import errno
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import socket
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import scapy.all as scapy
|
||||||
|
|
||||||
|
|
||||||
|
def scan(ip):
|
||||||
|
arp_request = scapy.ARP(pdst=ip)
|
||||||
|
broadcast = scapy.Ether(dst="ff:ff:ff:ff:ff:ff")
|
||||||
|
arp_request_broadcast = broadcast / arp_request
|
||||||
|
answered_list = scapy.srp(arp_request_broadcast,
|
||||||
|
timeout=1, verbose=False)[0]
|
||||||
|
results = []
|
||||||
|
for element in answered_list:
|
||||||
|
result = {
|
||||||
|
"ip": element[1].psrc,
|
||||||
|
"mac": element[1].hwsrc,
|
||||||
|
"hostname": socket.gethostbyaddr(element[1].psrc)[0],
|
||||||
|
}
|
||||||
|
results.append(result)
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
def port_open(address: str, dest_port=22) -> bool:
|
||||||
|
# result = sock.connect_ex(('ras-dan-01.local',22))
|
||||||
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
|
||||||
|
sock.settimeout(5)
|
||||||
|
result = sock.connect_ex((address, dest_port))
|
||||||
|
if result == 0:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def scan_csv(csvfile=str, colm="hostname"):
|
||||||
|
if os.path.exists(csvfile):
|
||||||
|
hostlist = []
|
||||||
|
with open(csvfile) as csv_file:
|
||||||
|
csv_reader = csv.DictReader(csv_file, delimiter=",")
|
||||||
|
for count, row in enumerate(csv_reader, 1):
|
||||||
|
hostlist.append(row[colm])
|
||||||
|
else:
|
||||||
|
raise FileNotFoundError(
|
||||||
|
errno.ENOENT, os.strerror(errno.ENOENT), csvfile)
|
||||||
|
return tuple(hostlist)
|
||||||
|
|
||||||
|
|
||||||
|
def create_ip_list(target_ip=["192.168.50.1/24"]):
|
||||||
|
only_ip_list = []
|
||||||
|
for ip_rage in target_ip:
|
||||||
|
for i in scan(ip_rage):
|
||||||
|
if i["hostname"] != ".":
|
||||||
|
scan_name = i["hostname"]
|
||||||
|
else:
|
||||||
|
scan_name = i["ip"]
|
||||||
|
|
||||||
|
# print(scan_name)
|
||||||
|
# print(port_open(address=scan_name))
|
||||||
|
if port_open(address=scan_name):
|
||||||
|
only_ip_list.append(scan_name)
|
||||||
|
|
||||||
|
return tuple(only_ip_list)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# if len(sys.argv) == 1:
|
||||||
|
ip_list = create_ip_list()
|
||||||
|
man_list = scan_csv(
|
||||||
|
csvfile=os.path.dirname(os.path.realpath(
|
||||||
|
__file__)) + "/hostname_manuel.csv"
|
||||||
|
)
|
||||||
|
output = {
|
||||||
|
"_meta": {
|
||||||
|
"hostvars": {
|
||||||
|
"scan_csv": {
|
||||||
|
"http_port": 123,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"network_scan": {
|
||||||
|
"hosts": ip_list,
|
||||||
|
"vars": {
|
||||||
|
"ansible_user": "jonnybravo",
|
||||||
|
"ansible_python_interpreter": "/usr/bin/python3",
|
||||||
|
"ansible_ssh_private_key_file": "/home/jonnybravo/.ssh/ansible-test",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"csv_scan": {
|
||||||
|
"hosts": man_list,
|
||||||
|
"vars": {
|
||||||
|
"ansible_user": "jonnybravo",
|
||||||
|
"ansible_python_interpreter": "/usr/bin/python3",
|
||||||
|
"ansible_ssh_private_key_file": "/home/jonnybravo/.ssh/ansible-test",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
print(json.dumps(output, indent=4, sort_keys=True))
|
||||||
|
# elif len(sys.argv) == 2:
|
||||||
|
# print(sys.argv)
|
||||||
669
play_ansible/inv_plugin/fact/dan-jam-01
Normal file
669
play_ansible/inv_plugin/fact/dan-jam-01
Normal file
@@ -0,0 +1,669 @@
|
|||||||
|
ansible_all_ipv4_addresses:
|
||||||
|
- 172.23.0.187
|
||||||
|
ansible_all_ipv6_addresses:
|
||||||
|
- fe80::7815:ceff:fe98:b5ed
|
||||||
|
ansible_apparmor:
|
||||||
|
status: disabled
|
||||||
|
ansible_architecture: x86_64
|
||||||
|
ansible_bios_date: 02/02/2024
|
||||||
|
ansible_bios_vendor: LENOVO
|
||||||
|
ansible_bios_version: N32ET91W (1.67 )
|
||||||
|
ansible_board_asset_tag: Not Available
|
||||||
|
ansible_board_name: 20XW0055GE
|
||||||
|
ansible_board_serial: NA
|
||||||
|
ansible_board_vendor: LENOVO
|
||||||
|
ansible_board_version: SDK0J40697 WIN
|
||||||
|
ansible_chassis_asset_tag: No Asset Information
|
||||||
|
ansible_chassis_serial: NA
|
||||||
|
ansible_chassis_vendor: LENOVO
|
||||||
|
ansible_chassis_version: None
|
||||||
|
ansible_cmdline:
|
||||||
|
BOOT_IMAGE: /boot/vmlinuz-6.12-x86_64
|
||||||
|
cryptdevice: UUID=9cf04ebe-7c4d-4987-afa5-0585f14cd1d7:luks-9cf04ebe-7c4d-4987-afa5-0585f14cd1d7
|
||||||
|
nmi_watchdog: '0'
|
||||||
|
nowatchdog: true
|
||||||
|
quiet: true
|
||||||
|
reboot: acpi
|
||||||
|
resume: /dev/mapper/luks-e3c32a55-f6b4-4d3d-a17a-9901f57c152f
|
||||||
|
root: /dev/mapper/luks-9cf04ebe-7c4d-4987-afa5-0585f14cd1d7
|
||||||
|
rw: true
|
||||||
|
splash: true
|
||||||
|
udev.log_priority: '3'
|
||||||
|
ansible_date_time:
|
||||||
|
date: '2025-01-28'
|
||||||
|
day: '28'
|
||||||
|
epoch: '1738052955'
|
||||||
|
epoch_int: '1738052955'
|
||||||
|
hour: 09
|
||||||
|
iso8601: '2025-01-28T08:29:15Z'
|
||||||
|
iso8601_basic: 20250128T092915446279
|
||||||
|
iso8601_basic_short: 20250128T092915
|
||||||
|
iso8601_micro: '2025-01-28T08:29:15.446279Z'
|
||||||
|
minute: '29'
|
||||||
|
month: '01'
|
||||||
|
second: '15'
|
||||||
|
time: 09:29:15
|
||||||
|
tz: CET
|
||||||
|
tz_dst: CEST
|
||||||
|
tz_offset: '+0100'
|
||||||
|
weekday: Tuesday
|
||||||
|
weekday_number: '2'
|
||||||
|
weeknumber: '04'
|
||||||
|
year: '2025'
|
||||||
|
ansible_default_ipv4:
|
||||||
|
address: 172.23.0.187
|
||||||
|
alias: host0
|
||||||
|
broadcast: 172.23.0.255
|
||||||
|
gateway: 172.23.0.1
|
||||||
|
interface: host0
|
||||||
|
macaddress: 7a:15:ce:98:b5:ed
|
||||||
|
mtu: 1500
|
||||||
|
netmask: 255.255.255.0
|
||||||
|
network: 172.23.0.0
|
||||||
|
prefix: '24'
|
||||||
|
type: ether
|
||||||
|
ansible_default_ipv6: {}
|
||||||
|
ansible_device_links:
|
||||||
|
ids: {}
|
||||||
|
labels: {}
|
||||||
|
masters:
|
||||||
|
nvme0n1p2:
|
||||||
|
- dm-0
|
||||||
|
nvme0n1p3:
|
||||||
|
- dm-1
|
||||||
|
uuids: {}
|
||||||
|
ansible_devices:
|
||||||
|
dm-0:
|
||||||
|
holders: []
|
||||||
|
host: ''
|
||||||
|
links:
|
||||||
|
ids: []
|
||||||
|
labels: []
|
||||||
|
masters: []
|
||||||
|
uuids: []
|
||||||
|
model: null
|
||||||
|
partitions: {}
|
||||||
|
removable: '0'
|
||||||
|
rotational: '0'
|
||||||
|
sas_address: null
|
||||||
|
sas_device_handle: null
|
||||||
|
scheduler_mode: ''
|
||||||
|
sectors: 1928097365
|
||||||
|
sectorsize: '512'
|
||||||
|
size: 919.39 GB
|
||||||
|
support_discard: '0'
|
||||||
|
vendor: null
|
||||||
|
virtual: 1
|
||||||
|
dm-1:
|
||||||
|
holders: []
|
||||||
|
host: ''
|
||||||
|
links:
|
||||||
|
ids: []
|
||||||
|
labels: []
|
||||||
|
masters: []
|
||||||
|
uuids: []
|
||||||
|
model: null
|
||||||
|
partitions: {}
|
||||||
|
removable: '0'
|
||||||
|
rotational: '0'
|
||||||
|
sas_address: null
|
||||||
|
sas_device_handle: null
|
||||||
|
scheduler_mode: ''
|
||||||
|
sectors: 71673682
|
||||||
|
sectorsize: '512'
|
||||||
|
size: 34.18 GB
|
||||||
|
support_discard: '0'
|
||||||
|
vendor: null
|
||||||
|
virtual: 1
|
||||||
|
nvme0n1:
|
||||||
|
holders: []
|
||||||
|
host: ''
|
||||||
|
links:
|
||||||
|
ids: []
|
||||||
|
labels: []
|
||||||
|
masters: []
|
||||||
|
uuids: []
|
||||||
|
model: Micron MTFDKBA1T0TFH
|
||||||
|
partitions:
|
||||||
|
nvme0n1p1:
|
||||||
|
holders: []
|
||||||
|
links:
|
||||||
|
ids: []
|
||||||
|
labels: []
|
||||||
|
masters: []
|
||||||
|
uuids: []
|
||||||
|
sectors: 614400
|
||||||
|
sectorsize: 512
|
||||||
|
size: 300.00 MB
|
||||||
|
start: '4096'
|
||||||
|
uuid: null
|
||||||
|
nvme0n1p2:
|
||||||
|
holders:
|
||||||
|
- luks-9cf04ebe-7c4d-4987-afa5-0585f14cd1d7
|
||||||
|
links:
|
||||||
|
ids: []
|
||||||
|
labels: []
|
||||||
|
masters:
|
||||||
|
- dm-0
|
||||||
|
uuids: []
|
||||||
|
sectors: 1928101461
|
||||||
|
sectorsize: 512
|
||||||
|
size: 919.39 GB
|
||||||
|
start: '618496'
|
||||||
|
uuid: null
|
||||||
|
nvme0n1p3:
|
||||||
|
holders:
|
||||||
|
- luks-e3c32a55-f6b4-4d3d-a17a-9901f57c152f
|
||||||
|
links:
|
||||||
|
ids: []
|
||||||
|
labels: []
|
||||||
|
masters:
|
||||||
|
- dm-1
|
||||||
|
uuids: []
|
||||||
|
sectors: 71677778
|
||||||
|
sectorsize: 512
|
||||||
|
size: 34.18 GB
|
||||||
|
start: '1928719957'
|
||||||
|
uuid: null
|
||||||
|
removable: '0'
|
||||||
|
rotational: '0'
|
||||||
|
sas_address: null
|
||||||
|
sas_device_handle: null
|
||||||
|
scheduler_mode: none
|
||||||
|
sectors: 2000409264
|
||||||
|
sectorsize: '512'
|
||||||
|
serial: 222538DCB6A6
|
||||||
|
size: 953.87 GB
|
||||||
|
support_discard: '512'
|
||||||
|
vendor: null
|
||||||
|
virtual: 1
|
||||||
|
sda:
|
||||||
|
holders: []
|
||||||
|
host: ''
|
||||||
|
links:
|
||||||
|
ids: []
|
||||||
|
labels: []
|
||||||
|
masters: []
|
||||||
|
uuids: []
|
||||||
|
model: 1081CS0
|
||||||
|
partitions: {}
|
||||||
|
removable: '1'
|
||||||
|
rotational: '0'
|
||||||
|
sas_address: null
|
||||||
|
sas_device_handle: null
|
||||||
|
scheduler_mode: mq-deadline
|
||||||
|
sectors: 0
|
||||||
|
sectorsize: '512'
|
||||||
|
size: 0.00 Bytes
|
||||||
|
support_discard: '0'
|
||||||
|
vendor: NORELSYS
|
||||||
|
virtual: 1
|
||||||
|
sdb:
|
||||||
|
holders: []
|
||||||
|
host: ''
|
||||||
|
links:
|
||||||
|
ids: []
|
||||||
|
labels: []
|
||||||
|
masters: []
|
||||||
|
uuids: []
|
||||||
|
model: 1081CS1
|
||||||
|
partitions: {}
|
||||||
|
removable: '1'
|
||||||
|
rotational: '0'
|
||||||
|
sas_address: null
|
||||||
|
sas_device_handle: null
|
||||||
|
scheduler_mode: mq-deadline
|
||||||
|
sectors: 0
|
||||||
|
sectorsize: '512'
|
||||||
|
size: 0.00 Bytes
|
||||||
|
support_discard: '0'
|
||||||
|
vendor: NORELSYS
|
||||||
|
virtual: 1
|
||||||
|
sdc:
|
||||||
|
holders: []
|
||||||
|
host: ''
|
||||||
|
links:
|
||||||
|
ids: []
|
||||||
|
labels: []
|
||||||
|
masters: []
|
||||||
|
uuids: []
|
||||||
|
model: CT1000X8SSD9
|
||||||
|
partitions:
|
||||||
|
sdc1:
|
||||||
|
holders: []
|
||||||
|
links:
|
||||||
|
ids: []
|
||||||
|
labels: []
|
||||||
|
masters: []
|
||||||
|
uuids: []
|
||||||
|
sectors: 1953521664
|
||||||
|
sectorsize: 512
|
||||||
|
size: 931.51 GB
|
||||||
|
start: '2048'
|
||||||
|
uuid: null
|
||||||
|
removable: '0'
|
||||||
|
rotational: '1'
|
||||||
|
sas_address: null
|
||||||
|
sas_device_handle: null
|
||||||
|
scheduler_mode: mq-deadline
|
||||||
|
sectors: 1953525168
|
||||||
|
sectorsize: '512'
|
||||||
|
size: 931.51 GB
|
||||||
|
support_discard: '0'
|
||||||
|
vendor: Micron
|
||||||
|
virtual: 1
|
||||||
|
ansible_distribution: Ubuntu
|
||||||
|
ansible_distribution_file_parsed: true
|
||||||
|
ansible_distribution_file_path: /etc/os-release
|
||||||
|
ansible_distribution_file_variety: Debian
|
||||||
|
ansible_distribution_major_version: '22'
|
||||||
|
ansible_distribution_release: jammy
|
||||||
|
ansible_distribution_version: '22.04'
|
||||||
|
ansible_dns:
|
||||||
|
nameservers:
|
||||||
|
- 10.50.0.3
|
||||||
|
options:
|
||||||
|
edns0: true
|
||||||
|
trust-ad: true
|
||||||
|
search:
|
||||||
|
- speedport.ip
|
||||||
|
ansible_domain: ''
|
||||||
|
ansible_effective_group_id: 1000
|
||||||
|
ansible_effective_user_id: 1000
|
||||||
|
ansible_env:
|
||||||
|
HOME: /home/jonnybravo
|
||||||
|
LC_CTYPE: C.UTF-8
|
||||||
|
LOGNAME: jonnybravo
|
||||||
|
MOTD_SHOWN: pam
|
||||||
|
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
|
||||||
|
PWD: /home/jonnybravo
|
||||||
|
SHELL: /bin/bash
|
||||||
|
SHLVL: '0'
|
||||||
|
SSH_CLIENT: 172.23.0.1 59494 22
|
||||||
|
SSH_CONNECTION: 172.23.0.1 59494 172.23.0.187 22
|
||||||
|
SSH_TTY: /dev/pts/1
|
||||||
|
TERM: tmux-256color
|
||||||
|
USER: jonnybravo
|
||||||
|
XDG_RUNTIME_DIR: /run/user/1000
|
||||||
|
XDG_SESSION_CLASS: user
|
||||||
|
XDG_SESSION_ID: '6'
|
||||||
|
XDG_SESSION_TYPE: tty
|
||||||
|
_: /bin/sh
|
||||||
|
ansible_fibre_channel_wwn: []
|
||||||
|
ansible_fips: false
|
||||||
|
ansible_flags:
|
||||||
|
- fpu
|
||||||
|
- vme
|
||||||
|
- de
|
||||||
|
- pse
|
||||||
|
- tsc
|
||||||
|
- msr
|
||||||
|
- pae
|
||||||
|
- mce
|
||||||
|
- cx8
|
||||||
|
- apic
|
||||||
|
- sep
|
||||||
|
- mtrr
|
||||||
|
- pge
|
||||||
|
- mca
|
||||||
|
- cmov
|
||||||
|
- pat
|
||||||
|
- pse36
|
||||||
|
- clflush
|
||||||
|
- dts
|
||||||
|
- acpi
|
||||||
|
- mmx
|
||||||
|
- fxsr
|
||||||
|
- sse
|
||||||
|
- sse2
|
||||||
|
- ss
|
||||||
|
- ht
|
||||||
|
- tm
|
||||||
|
- pbe
|
||||||
|
- syscall
|
||||||
|
- nx
|
||||||
|
- pdpe1gb
|
||||||
|
- rdtscp
|
||||||
|
- lm
|
||||||
|
- constant_tsc
|
||||||
|
- art
|
||||||
|
- arch_perfmon
|
||||||
|
- pebs
|
||||||
|
- bts
|
||||||
|
- rep_good
|
||||||
|
- nopl
|
||||||
|
- xtopology
|
||||||
|
- nonstop_tsc
|
||||||
|
- cpuid
|
||||||
|
- aperfmperf
|
||||||
|
- tsc_known_freq
|
||||||
|
- pni
|
||||||
|
- pclmulqdq
|
||||||
|
- dtes64
|
||||||
|
- monitor
|
||||||
|
- ds_cpl
|
||||||
|
- vmx
|
||||||
|
- est
|
||||||
|
- tm2
|
||||||
|
- ssse3
|
||||||
|
- sdbg
|
||||||
|
- fma
|
||||||
|
- cx16
|
||||||
|
- xtpr
|
||||||
|
- pdcm
|
||||||
|
- pcid
|
||||||
|
- sse4_1
|
||||||
|
- sse4_2
|
||||||
|
- x2apic
|
||||||
|
- movbe
|
||||||
|
- popcnt
|
||||||
|
- tsc_deadline_timer
|
||||||
|
- aes
|
||||||
|
- xsave
|
||||||
|
- avx
|
||||||
|
- f16c
|
||||||
|
- rdrand
|
||||||
|
- lahf_lm
|
||||||
|
- abm
|
||||||
|
- 3dnowprefetch
|
||||||
|
- cpuid_fault
|
||||||
|
- epb
|
||||||
|
- cat_l2
|
||||||
|
- cdp_l2
|
||||||
|
- ssbd
|
||||||
|
- ibrs
|
||||||
|
- ibpb
|
||||||
|
- stibp
|
||||||
|
- ibrs_enhanced
|
||||||
|
- tpr_shadow
|
||||||
|
- flexpriority
|
||||||
|
- ept
|
||||||
|
- vpid
|
||||||
|
- ept_ad
|
||||||
|
- fsgsbase
|
||||||
|
- tsc_adjust
|
||||||
|
- bmi1
|
||||||
|
- avx2
|
||||||
|
- smep
|
||||||
|
- bmi2
|
||||||
|
- erms
|
||||||
|
- invpcid
|
||||||
|
- rdt_a
|
||||||
|
- avx512f
|
||||||
|
- avx512dq
|
||||||
|
- rdseed
|
||||||
|
- adx
|
||||||
|
- smap
|
||||||
|
- avx512ifma
|
||||||
|
- clflushopt
|
||||||
|
- clwb
|
||||||
|
- intel_pt
|
||||||
|
- avx512cd
|
||||||
|
- sha_ni
|
||||||
|
- avx512bw
|
||||||
|
- avx512vl
|
||||||
|
- xsaveopt
|
||||||
|
- xsavec
|
||||||
|
- xgetbv1
|
||||||
|
- xsaves
|
||||||
|
- split_lock_detect
|
||||||
|
- user_shstk
|
||||||
|
- dtherm
|
||||||
|
- ida
|
||||||
|
- arat
|
||||||
|
- pln
|
||||||
|
- pts
|
||||||
|
- hwp
|
||||||
|
- hwp_notify
|
||||||
|
- hwp_act_window
|
||||||
|
- hwp_epp
|
||||||
|
- hwp_pkg_req
|
||||||
|
- vnmi
|
||||||
|
- avx512vbmi
|
||||||
|
- umip
|
||||||
|
- pku
|
||||||
|
- ospke
|
||||||
|
- avx512_vbmi2
|
||||||
|
- gfni
|
||||||
|
- vaes
|
||||||
|
- vpclmulqdq
|
||||||
|
- avx512_vnni
|
||||||
|
- avx512_bitalg
|
||||||
|
- avx512_vpopcntdq
|
||||||
|
- rdpid
|
||||||
|
- movdiri
|
||||||
|
- movdir64b
|
||||||
|
- fsrm
|
||||||
|
- avx512_vp2intersect
|
||||||
|
- md_clear
|
||||||
|
- ibt
|
||||||
|
- flush_l1d
|
||||||
|
- arch_capabilities
|
||||||
|
ansible_form_factor: Notebook
|
||||||
|
ansible_fqdn: localhost
|
||||||
|
ansible_host0:
|
||||||
|
active: true
|
||||||
|
device: host0
|
||||||
|
ipv4:
|
||||||
|
address: 172.23.0.187
|
||||||
|
broadcast: 172.23.0.255
|
||||||
|
netmask: 255.255.255.0
|
||||||
|
network: 172.23.0.0
|
||||||
|
prefix: '24'
|
||||||
|
ipv6:
|
||||||
|
- address: fe80::7815:ceff:fe98:b5ed
|
||||||
|
prefix: '64'
|
||||||
|
scope: link
|
||||||
|
macaddress: 7a:15:ce:98:b5:ed
|
||||||
|
mtu: 1500
|
||||||
|
promisc: false
|
||||||
|
speed: 10000
|
||||||
|
type: ether
|
||||||
|
ansible_hostname: dan-jam-01
|
||||||
|
ansible_hostnqn: ''
|
||||||
|
ansible_interfaces:
|
||||||
|
- lo
|
||||||
|
- host0
|
||||||
|
ansible_is_chroot: true
|
||||||
|
ansible_iscsi_iqn: ''
|
||||||
|
ansible_kernel: 6.12.4-1-MANJARO
|
||||||
|
ansible_kernel_version: '#1 SMP PREEMPT_DYNAMIC Mon, 09 Dec 2024 11:58:37 +0000'
|
||||||
|
ansible_lo:
|
||||||
|
active: true
|
||||||
|
device: lo
|
||||||
|
ipv4:
|
||||||
|
address: 127.0.0.1
|
||||||
|
broadcast: ''
|
||||||
|
netmask: 255.0.0.0
|
||||||
|
network: 127.0.0.0
|
||||||
|
prefix: '8'
|
||||||
|
ipv6:
|
||||||
|
- address: ::1
|
||||||
|
prefix: '128'
|
||||||
|
scope: host
|
||||||
|
mtu: 65536
|
||||||
|
promisc: false
|
||||||
|
type: loopback
|
||||||
|
ansible_loadavg:
|
||||||
|
15m: 0.37646484375
|
||||||
|
1m: 1.17431640625
|
||||||
|
5m: 0.80224609375
|
||||||
|
ansible_local: {}
|
||||||
|
ansible_locally_reachable_ips:
|
||||||
|
ipv4:
|
||||||
|
- 127.0.0.0/8
|
||||||
|
- 127.0.0.1
|
||||||
|
- 172.23.0.187
|
||||||
|
ipv6:
|
||||||
|
- ::1
|
||||||
|
- fe80::7815:ceff:fe98:b5ed
|
||||||
|
ansible_lsb:
|
||||||
|
codename: jammy
|
||||||
|
description: Ubuntu 22.04.5 LTS
|
||||||
|
id: Ubuntu
|
||||||
|
major_release: '22'
|
||||||
|
release: '22.04'
|
||||||
|
ansible_lvm: N/A
|
||||||
|
ansible_machine: x86_64
|
||||||
|
ansible_machine_id: 74fa9d4996124ff58eea3b7b9f53f38f
|
||||||
|
ansible_memfree_mb: 15518
|
||||||
|
ansible_memory_mb:
|
||||||
|
nocache:
|
||||||
|
free: 23611
|
||||||
|
used: 8203
|
||||||
|
real:
|
||||||
|
free: 15518
|
||||||
|
total: 31814
|
||||||
|
used: 16296
|
||||||
|
swap:
|
||||||
|
cached: 8
|
||||||
|
free: 34976
|
||||||
|
total: 34996
|
||||||
|
used: 20
|
||||||
|
ansible_memtotal_mb: 31814
|
||||||
|
ansible_mounts:
|
||||||
|
- block_available: 162114263
|
||||||
|
block_size: 4096
|
||||||
|
block_total: 236947382
|
||||||
|
block_used: 74833119
|
||||||
|
device: /dev/mapper/luks-9cf04ebe-7c4d-4987-afa5-0585f14cd1d7
|
||||||
|
dump: 0
|
||||||
|
fstype: ext4
|
||||||
|
inode_available: 58698830
|
||||||
|
inode_total: 60260352
|
||||||
|
inode_used: 1561522
|
||||||
|
mount: /
|
||||||
|
options: rw,noatime,idmapped,bind
|
||||||
|
passno: 0
|
||||||
|
size_available: 664020021248
|
||||||
|
size_total: 970536476672
|
||||||
|
uuid: N/A
|
||||||
|
- block_available: 162114263
|
||||||
|
block_size: 4096
|
||||||
|
block_total: 236947382
|
||||||
|
block_used: 74833119
|
||||||
|
device: /dev/mapper/luks-9cf04ebe-7c4d-4987-afa5-0585f14cd1d7
|
||||||
|
dump: 0
|
||||||
|
fstype: ext4
|
||||||
|
inode_available: 58698830
|
||||||
|
inode_total: 60260352
|
||||||
|
inode_used: 1561522
|
||||||
|
mount: /run/host/os-release
|
||||||
|
options: ro,nosuid,nodev,noexec,noatime,bind
|
||||||
|
passno: 0
|
||||||
|
size_available: 664020021248
|
||||||
|
size_total: 970536476672
|
||||||
|
uuid: N/A
|
||||||
|
ansible_nodename: dan-jam-01
|
||||||
|
ansible_os_family: Debian
|
||||||
|
ansible_pkg_mgr: apt
|
||||||
|
ansible_proc_cmdline:
|
||||||
|
BOOT_IMAGE: /boot/vmlinuz-6.12-x86_64
|
||||||
|
cryptdevice: UUID=9cf04ebe-7c4d-4987-afa5-0585f14cd1d7:luks-9cf04ebe-7c4d-4987-afa5-0585f14cd1d7
|
||||||
|
nmi_watchdog: '0'
|
||||||
|
nowatchdog: true
|
||||||
|
quiet: true
|
||||||
|
reboot: acpi
|
||||||
|
resume: /dev/mapper/luks-e3c32a55-f6b4-4d3d-a17a-9901f57c152f
|
||||||
|
root:
|
||||||
|
- UUID=38f88aa5-03f0-4608-ac46-6b9cad7cb1c4
|
||||||
|
- /dev/mapper/luks-9cf04ebe-7c4d-4987-afa5-0585f14cd1d7
|
||||||
|
rw: true
|
||||||
|
splash: true
|
||||||
|
udev.log_priority: '3'
|
||||||
|
ansible_processor:
|
||||||
|
- '0'
|
||||||
|
- GenuineIntel
|
||||||
|
- 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
|
||||||
|
- '1'
|
||||||
|
- GenuineIntel
|
||||||
|
- 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
|
||||||
|
- '2'
|
||||||
|
- GenuineIntel
|
||||||
|
- 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
|
||||||
|
- '3'
|
||||||
|
- GenuineIntel
|
||||||
|
- 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
|
||||||
|
- '4'
|
||||||
|
- GenuineIntel
|
||||||
|
- 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
|
||||||
|
- '5'
|
||||||
|
- GenuineIntel
|
||||||
|
- 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
|
||||||
|
- '6'
|
||||||
|
- GenuineIntel
|
||||||
|
- 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
|
||||||
|
- '7'
|
||||||
|
- GenuineIntel
|
||||||
|
- 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
|
||||||
|
ansible_processor_cores: 4
|
||||||
|
ansible_processor_count: 1
|
||||||
|
ansible_processor_nproc: 8
|
||||||
|
ansible_processor_threads_per_core: 2
|
||||||
|
ansible_processor_vcpus: 8
|
||||||
|
ansible_product_name: 20XW0055GE
|
||||||
|
ansible_product_serial: NA
|
||||||
|
ansible_product_uuid: NA
|
||||||
|
ansible_product_version: ThinkPad X1 Carbon Gen 9
|
||||||
|
ansible_python:
|
||||||
|
executable: /usr/bin/python3
|
||||||
|
has_sslcontext: true
|
||||||
|
type: cpython
|
||||||
|
version:
|
||||||
|
major: 3
|
||||||
|
micro: 12
|
||||||
|
minor: 10
|
||||||
|
releaselevel: final
|
||||||
|
serial: 0
|
||||||
|
version_info:
|
||||||
|
- 3
|
||||||
|
- 10
|
||||||
|
- 12
|
||||||
|
- final
|
||||||
|
- 0
|
||||||
|
ansible_python_version: 3.10.12
|
||||||
|
ansible_real_group_id: 1000
|
||||||
|
ansible_real_user_id: 1000
|
||||||
|
ansible_selinux:
|
||||||
|
status: disabled
|
||||||
|
ansible_selinux_python_present: true
|
||||||
|
ansible_service_mgr: systemd
|
||||||
|
ansible_ssh_host_key_ecdsa_public: AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBlQf89/mIPEp3lsLUSkqVWQaU1yvskxPFbvnedoV0f+vi5vQKUoUfcX//3jqIKgjdH6fnqiQRfROO+seF+mjjo=
|
||||||
|
ansible_ssh_host_key_ecdsa_public_keytype: ecdsa-sha2-nistp256
|
||||||
|
ansible_ssh_host_key_ed25519_public: AAAAC3NzaC1lZDI1NTE5AAAAIIZpUjgZziEasuYZLOLxU/ex4HiuyOf6oofL1DqM55xx
|
||||||
|
ansible_ssh_host_key_ed25519_public_keytype: ssh-ed25519
|
||||||
|
ansible_ssh_host_key_rsa_public: AAAAB3NzaC1yc2EAAAADAQABAAABgQCxAnj9PVaIaAMaRExN0t0cW+7mu2QOum1BowLjoWFhgNcYeoev38a0FqUy49WE9+wIYG+URr1vIjO2F5Udd6QRtm8//wbcdBA4sbc5JKmd+ILMpy2FI6rmAjAfzYQkxLxGB+AwblAKTAJgoFn6/stXELiY8QYfVf2+SKTVk96gvVlMsIuFQy36PSjS2nSwdovTML4N/KrwJdUMDp7ysJ8bOB3NyXY/hBy+dgzGZ8ezYx5pkg7PRR+Y5rRh++dsfrkm+8e4gHi6uY+mwitpxodNMzVBRI6KzijUhbj4bTU7ASCwfmQSoNBZrY+4Xb9DiI421GP9/TWxAOz7vLWNcnkKtVeZpzXrxH5mmAbKJqu6vFhOkkz4IGz/mvvAAOgX/J6ILgT+1VHAIooQVfIDoOE/9GfDEPmWpjCmP1IQRokJwIy3isUZwMoN4V0rYfZ2YDW8YHwgirRXa6eEBXKZzkHAnqCt+WSss6jVdGW+1PjiakG1N1NL+dUI0NcPHgiuZIM=
|
||||||
|
ansible_ssh_host_key_rsa_public_keytype: ssh-rsa
|
||||||
|
ansible_swapfree_mb: 34976
|
||||||
|
ansible_swaptotal_mb: 34996
|
||||||
|
ansible_system: Linux
|
||||||
|
ansible_system_capabilities:
|
||||||
|
- ''
|
||||||
|
ansible_system_capabilities_enforced: 'True'
|
||||||
|
ansible_system_vendor: LENOVO
|
||||||
|
ansible_systemd:
|
||||||
|
features: +PAM +AUDIT +SELINUX +APPARMOR +IMA +SMACK +SECCOMP +GCRYPT +GNUTLS +OPENSSL
|
||||||
|
+ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK
|
||||||
|
+PCRE2 -PWQUALITY -P11KIT -QRENCODE +BZIP2 +LZ4 +XZ +ZLIB +ZSTD -XKBCOMMON +UTMP
|
||||||
|
+SYSVINIT default-hierarchy=unified
|
||||||
|
version: 249
|
||||||
|
ansible_uptime_seconds: 73395
|
||||||
|
ansible_user_dir: /home/jonnybravo
|
||||||
|
ansible_user_gecos: Jonny Bravo,,,
|
||||||
|
ansible_user_gid: 1000
|
||||||
|
ansible_user_id: jonnybravo
|
||||||
|
ansible_user_shell: /bin/bash
|
||||||
|
ansible_user_uid: 1000
|
||||||
|
ansible_userspace_architecture: x86_64
|
||||||
|
ansible_userspace_bits: '64'
|
||||||
|
ansible_virtualization_role: guest
|
||||||
|
ansible_virtualization_tech_guest:
|
||||||
|
- container
|
||||||
|
- systemd-nspawn
|
||||||
|
ansible_virtualization_tech_host:
|
||||||
|
- kvm
|
||||||
|
- virtualbox
|
||||||
|
ansible_virtualization_type: systemd-nspawn
|
||||||
|
gather_subset:
|
||||||
|
- all
|
||||||
|
module_setup: true
|
||||||
1946
play_ansible/inv_plugin/fact/ras-dan-01.local
Normal file
1946
play_ansible/inv_plugin/fact/ras-dan-01.local
Normal file
File diff suppressed because it is too large
Load Diff
3
play_ansible/inv_plugin/hostname_manuel.csv
Normal file
3
play_ansible/inv_plugin/hostname_manuel.csv
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
hostname, info
|
||||||
|
dan-jam-01, keine,
|
||||||
|
ras-dan-01.local, keine,
|
||||||
|
57
play_with_os/os_play.py
Normal file → Executable file
57
play_with_os/os_play.py
Normal file → Executable file
@@ -1,6 +1,5 @@
|
|||||||
#! /usr/bin/env python3.10
|
#! /usr/bin/env python3
|
||||||
|
import os, sys
|
||||||
import os
|
|
||||||
|
|
||||||
def show_all_files_directory(dir_path = str, search_endung = False, search_string = False):
|
def show_all_files_directory(dir_path = str, search_endung = False, search_string = False):
|
||||||
li_all = []
|
li_all = []
|
||||||
@@ -16,20 +15,48 @@ def show_all_files_directory(dir_path = str, search_endung = False, search_strin
|
|||||||
else:
|
else:
|
||||||
li_all.append(FullPATH)
|
li_all.append(FullPATH)
|
||||||
return li_all
|
return li_all
|
||||||
|
|
||||||
|
def simple_files(dir_path):
|
||||||
|
files = os.listdir(dir_path)
|
||||||
|
return [f for f in files if os.path.isfile(dir_path + '/'+f)]
|
||||||
|
|
||||||
|
|
||||||
|
def main(check_list = list, main_folder_in = str):
|
||||||
|
output_list = []
|
||||||
|
for folder_name in check_list:
|
||||||
|
main_folder =main_folder_in + os.sep + folder_name
|
||||||
|
if os.path.exists(main_folder):
|
||||||
|
run_file_check = simple_files(dir_path=main_folder)
|
||||||
|
print(run_file_check)
|
||||||
|
for file_name in run_file_check:
|
||||||
|
if file_name == "frm_ref":
|
||||||
|
filename = "frmref"
|
||||||
|
#output_list.append(str(folder_name + '=' +file_name[1]))
|
||||||
|
output_list.append(str(folder_name + '=' +file_name))
|
||||||
|
output_list.append("")
|
||||||
|
else:
|
||||||
|
print(main_folder, "existiert nicht")
|
||||||
|
return output_list
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
# test = show_all_files_directory(dir_path=os.sep + "home" + os.sep + "jonnybravo" + os.sep + "Downloads", search_string="linux")
|
|
||||||
# for i in test:
|
|
||||||
# print(i)
|
|
||||||
print(os.get_exec_path())
|
print(os.get_exec_path())
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
|
||||||
|
check_folders = ["fm", "plsqllib", "frm_ref"]
|
||||||
|
|
||||||
|
if len(sys.argv) == 1 or len(sys.argv) == 3:
|
||||||
|
raise SystemExit("Das Skript muss mit einen Parameter aufgerufen werden. Zum Beispiel ./skript.py suma oder python3 skript.py suma")
|
||||||
|
print(sys.argv)
|
||||||
|
output_file = sys.argv[1] + "-module.txt"
|
||||||
|
main_folder = sys.argv[1]
|
||||||
|
#show all Folders from dir
|
||||||
|
#test = [os.path.join(".", o) for o in os.listdir(".") if os.path.isdir(os.path.join(".",o))]
|
||||||
|
running_main = main(check_list=check_folders, main_folder_in=main_folder)
|
||||||
|
if os.path.exists(output_file):
|
||||||
|
os.remove(output_file)
|
||||||
|
|
||||||
|
for run in running_main:
|
||||||
|
with open(output_file, "a") as file:
|
||||||
|
print(run, file=file)
|
||||||
16
play_with_os/scan_test.py
Normal file
16
play_with_os/scan_test.py
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#! /usr/bin/env Python3
|
||||||
|
|
||||||
|
# import OS module
|
||||||
|
import os
|
||||||
|
|
||||||
|
def scandir_recursive(directory):
|
||||||
|
scan_list = []
|
||||||
|
for entry in os.scandir(directory):
|
||||||
|
if entry.is_dir(follow_symlinks=False):
|
||||||
|
yield from scandir_recursive(entry.path)
|
||||||
|
else:
|
||||||
|
yield entry.path
|
||||||
|
|
||||||
|
scan_path = "/home/jonnybravo/Downloads"
|
||||||
|
for i in list(scandir_recursive(scan_path)):
|
||||||
|
print(i)
|
||||||
48
play_with_os/test.py
Normal file
48
play_with_os/test.py
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
def show_all_files_directory(dir_path: str, search_endung: str = None, search_string: str = None) -> list:
|
||||||
|
"""
|
||||||
|
Returns a list of all files in the directory and its subdirectories.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
dir_path (str): Path to the root directory.
|
||||||
|
search_endung (str): Ending for the file names to be searched. Default is None.
|
||||||
|
search_string (str): String to be searched in the file names. Default is None.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list: List of full paths to all files matching the search criteria.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Check if dir_path is not empty and exists
|
||||||
|
if not os.path.isdir(dir_path):
|
||||||
|
print("Die angegebene Verzeichnispfad existiert nicht.")
|
||||||
|
return []
|
||||||
|
|
||||||
|
all_files_path = []
|
||||||
|
|
||||||
|
for root_folder, dirs, files in os.walk(dir_path, topdown=False):
|
||||||
|
for name in files:
|
||||||
|
full_path = str(os.path.join(root_folder, name))
|
||||||
|
|
||||||
|
# If search_endung is specified
|
||||||
|
if search_endung:
|
||||||
|
if not full_path.endswith(search_endung):
|
||||||
|
continue
|
||||||
|
|
||||||
|
# If search_string is specified
|
||||||
|
elif search_string:
|
||||||
|
if full_path.find(search_string) == -1:
|
||||||
|
continue
|
||||||
|
|
||||||
|
all_files_path.append(full_path)
|
||||||
|
|
||||||
|
print("Dateien:")
|
||||||
|
for file in all_files_path:
|
||||||
|
print(file)
|
||||||
|
|
||||||
|
return all_files_path
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test = show_all_files_directory(dir_path="/home/jonnybravo/Downloads", search_endung=".txt")
|
||||||
|
print(test)
|
||||||
247
rclone/bin/Activate.ps1
Normal file
247
rclone/bin/Activate.ps1
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
<#
|
||||||
|
.Synopsis
|
||||||
|
Activate a Python virtual environment for the current PowerShell session.
|
||||||
|
|
||||||
|
.Description
|
||||||
|
Pushes the python executable for a virtual environment to the front of the
|
||||||
|
$Env:PATH environment variable and sets the prompt to signify that you are
|
||||||
|
in a Python virtual environment. Makes use of the command line switches as
|
||||||
|
well as the `pyvenv.cfg` file values present in the virtual environment.
|
||||||
|
|
||||||
|
.Parameter VenvDir
|
||||||
|
Path to the directory that contains the virtual environment to activate. The
|
||||||
|
default value for this is the parent of the directory that the Activate.ps1
|
||||||
|
script is located within.
|
||||||
|
|
||||||
|
.Parameter Prompt
|
||||||
|
The prompt prefix to display when this virtual environment is activated. By
|
||||||
|
default, this prompt is the name of the virtual environment folder (VenvDir)
|
||||||
|
surrounded by parentheses and followed by a single space (ie. '(.venv) ').
|
||||||
|
|
||||||
|
.Example
|
||||||
|
Activate.ps1
|
||||||
|
Activates the Python virtual environment that contains the Activate.ps1 script.
|
||||||
|
|
||||||
|
.Example
|
||||||
|
Activate.ps1 -Verbose
|
||||||
|
Activates the Python virtual environment that contains the Activate.ps1 script,
|
||||||
|
and shows extra information about the activation as it executes.
|
||||||
|
|
||||||
|
.Example
|
||||||
|
Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv
|
||||||
|
Activates the Python virtual environment located in the specified location.
|
||||||
|
|
||||||
|
.Example
|
||||||
|
Activate.ps1 -Prompt "MyPython"
|
||||||
|
Activates the Python virtual environment that contains the Activate.ps1 script,
|
||||||
|
and prefixes the current prompt with the specified string (surrounded in
|
||||||
|
parentheses) while the virtual environment is active.
|
||||||
|
|
||||||
|
.Notes
|
||||||
|
On Windows, it may be required to enable this Activate.ps1 script by setting the
|
||||||
|
execution policy for the user. You can do this by issuing the following PowerShell
|
||||||
|
command:
|
||||||
|
|
||||||
|
PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
|
||||||
|
|
||||||
|
For more information on Execution Policies:
|
||||||
|
https://go.microsoft.com/fwlink/?LinkID=135170
|
||||||
|
|
||||||
|
#>
|
||||||
|
Param(
|
||||||
|
[Parameter(Mandatory = $false)]
|
||||||
|
[String]
|
||||||
|
$VenvDir,
|
||||||
|
[Parameter(Mandatory = $false)]
|
||||||
|
[String]
|
||||||
|
$Prompt
|
||||||
|
)
|
||||||
|
|
||||||
|
<# Function declarations --------------------------------------------------- #>
|
||||||
|
|
||||||
|
<#
|
||||||
|
.Synopsis
|
||||||
|
Remove all shell session elements added by the Activate script, including the
|
||||||
|
addition of the virtual environment's Python executable from the beginning of
|
||||||
|
the PATH variable.
|
||||||
|
|
||||||
|
.Parameter NonDestructive
|
||||||
|
If present, do not remove this function from the global namespace for the
|
||||||
|
session.
|
||||||
|
|
||||||
|
#>
|
||||||
|
function global:deactivate ([switch]$NonDestructive) {
|
||||||
|
# Revert to original values
|
||||||
|
|
||||||
|
# The prior prompt:
|
||||||
|
if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) {
|
||||||
|
Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt
|
||||||
|
Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT
|
||||||
|
}
|
||||||
|
|
||||||
|
# The prior PYTHONHOME:
|
||||||
|
if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) {
|
||||||
|
Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME
|
||||||
|
Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME
|
||||||
|
}
|
||||||
|
|
||||||
|
# The prior PATH:
|
||||||
|
if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) {
|
||||||
|
Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH
|
||||||
|
Remove-Item -Path Env:_OLD_VIRTUAL_PATH
|
||||||
|
}
|
||||||
|
|
||||||
|
# Just remove the VIRTUAL_ENV altogether:
|
||||||
|
if (Test-Path -Path Env:VIRTUAL_ENV) {
|
||||||
|
Remove-Item -Path env:VIRTUAL_ENV
|
||||||
|
}
|
||||||
|
|
||||||
|
# Just remove VIRTUAL_ENV_PROMPT altogether.
|
||||||
|
if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) {
|
||||||
|
Remove-Item -Path env:VIRTUAL_ENV_PROMPT
|
||||||
|
}
|
||||||
|
|
||||||
|
# Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether:
|
||||||
|
if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) {
|
||||||
|
Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force
|
||||||
|
}
|
||||||
|
|
||||||
|
# Leave deactivate function in the global namespace if requested:
|
||||||
|
if (-not $NonDestructive) {
|
||||||
|
Remove-Item -Path function:deactivate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<#
|
||||||
|
.Description
|
||||||
|
Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the
|
||||||
|
given folder, and returns them in a map.
|
||||||
|
|
||||||
|
For each line in the pyvenv.cfg file, if that line can be parsed into exactly
|
||||||
|
two strings separated by `=` (with any amount of whitespace surrounding the =)
|
||||||
|
then it is considered a `key = value` line. The left hand string is the key,
|
||||||
|
the right hand is the value.
|
||||||
|
|
||||||
|
If the value starts with a `'` or a `"` then the first and last character is
|
||||||
|
stripped from the value before being captured.
|
||||||
|
|
||||||
|
.Parameter ConfigDir
|
||||||
|
Path to the directory that contains the `pyvenv.cfg` file.
|
||||||
|
#>
|
||||||
|
function Get-PyVenvConfig(
|
||||||
|
[String]
|
||||||
|
$ConfigDir
|
||||||
|
) {
|
||||||
|
Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg"
|
||||||
|
|
||||||
|
# Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue).
|
||||||
|
$pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue
|
||||||
|
|
||||||
|
# An empty map will be returned if no config file is found.
|
||||||
|
$pyvenvConfig = @{ }
|
||||||
|
|
||||||
|
if ($pyvenvConfigPath) {
|
||||||
|
|
||||||
|
Write-Verbose "File exists, parse `key = value` lines"
|
||||||
|
$pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath
|
||||||
|
|
||||||
|
$pyvenvConfigContent | ForEach-Object {
|
||||||
|
$keyval = $PSItem -split "\s*=\s*", 2
|
||||||
|
if ($keyval[0] -and $keyval[1]) {
|
||||||
|
$val = $keyval[1]
|
||||||
|
|
||||||
|
# Remove extraneous quotations around a string value.
|
||||||
|
if ("'""".Contains($val.Substring(0, 1))) {
|
||||||
|
$val = $val.Substring(1, $val.Length - 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
$pyvenvConfig[$keyval[0]] = $val
|
||||||
|
Write-Verbose "Adding Key: '$($keyval[0])'='$val'"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $pyvenvConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
<# Begin Activate script --------------------------------------------------- #>
|
||||||
|
|
||||||
|
# Determine the containing directory of this script
|
||||||
|
$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition
|
||||||
|
$VenvExecDir = Get-Item -Path $VenvExecPath
|
||||||
|
|
||||||
|
Write-Verbose "Activation script is located in path: '$VenvExecPath'"
|
||||||
|
Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)"
|
||||||
|
Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)"
|
||||||
|
|
||||||
|
# Set values required in priority: CmdLine, ConfigFile, Default
|
||||||
|
# First, get the location of the virtual environment, it might not be
|
||||||
|
# VenvExecDir if specified on the command line.
|
||||||
|
if ($VenvDir) {
|
||||||
|
Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir."
|
||||||
|
$VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/")
|
||||||
|
Write-Verbose "VenvDir=$VenvDir"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Next, read the `pyvenv.cfg` file to determine any required value such
|
||||||
|
# as `prompt`.
|
||||||
|
$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir
|
||||||
|
|
||||||
|
# Next, set the prompt from the command line, or the config file, or
|
||||||
|
# just use the name of the virtual environment folder.
|
||||||
|
if ($Prompt) {
|
||||||
|
Write-Verbose "Prompt specified as argument, using '$Prompt'"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value"
|
||||||
|
if ($pyvenvCfg -and $pyvenvCfg['prompt']) {
|
||||||
|
Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'"
|
||||||
|
$Prompt = $pyvenvCfg['prompt'];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)"
|
||||||
|
Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'"
|
||||||
|
$Prompt = Split-Path -Path $venvDir -Leaf
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Verbose "Prompt = '$Prompt'"
|
||||||
|
Write-Verbose "VenvDir='$VenvDir'"
|
||||||
|
|
||||||
|
# Deactivate any currently active virtual environment, but leave the
|
||||||
|
# deactivate function in place.
|
||||||
|
deactivate -nondestructive
|
||||||
|
|
||||||
|
# Now set the environment variable VIRTUAL_ENV, used by many tools to determine
|
||||||
|
# that there is an activated venv.
|
||||||
|
$env:VIRTUAL_ENV = $VenvDir
|
||||||
|
|
||||||
|
if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) {
|
||||||
|
|
||||||
|
Write-Verbose "Setting prompt to '$Prompt'"
|
||||||
|
|
||||||
|
# Set the prompt to include the env name
|
||||||
|
# Make sure _OLD_VIRTUAL_PROMPT is global
|
||||||
|
function global:_OLD_VIRTUAL_PROMPT { "" }
|
||||||
|
Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT
|
||||||
|
New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt
|
||||||
|
|
||||||
|
function global:prompt {
|
||||||
|
Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) "
|
||||||
|
_OLD_VIRTUAL_PROMPT
|
||||||
|
}
|
||||||
|
$env:VIRTUAL_ENV_PROMPT = $Prompt
|
||||||
|
}
|
||||||
|
|
||||||
|
# Clear PYTHONHOME
|
||||||
|
if (Test-Path -Path Env:PYTHONHOME) {
|
||||||
|
Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME
|
||||||
|
Remove-Item -Path Env:PYTHONHOME
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add the venv to the PATH
|
||||||
|
Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH
|
||||||
|
$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH"
|
||||||
69
rclone/bin/activate
Normal file
69
rclone/bin/activate
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# This file must be used with "source bin/activate" *from bash*
|
||||||
|
# you cannot run it directly
|
||||||
|
|
||||||
|
deactivate () {
|
||||||
|
# reset old environment variables
|
||||||
|
if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then
|
||||||
|
PATH="${_OLD_VIRTUAL_PATH:-}"
|
||||||
|
export PATH
|
||||||
|
unset _OLD_VIRTUAL_PATH
|
||||||
|
fi
|
||||||
|
if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then
|
||||||
|
PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}"
|
||||||
|
export PYTHONHOME
|
||||||
|
unset _OLD_VIRTUAL_PYTHONHOME
|
||||||
|
fi
|
||||||
|
|
||||||
|
# This should detect bash and zsh, which have a hash command that must
|
||||||
|
# be called to get it to forget past commands. Without forgetting
|
||||||
|
# past commands the $PATH changes we made may not be respected
|
||||||
|
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
|
||||||
|
hash -r 2> /dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then
|
||||||
|
PS1="${_OLD_VIRTUAL_PS1:-}"
|
||||||
|
export PS1
|
||||||
|
unset _OLD_VIRTUAL_PS1
|
||||||
|
fi
|
||||||
|
|
||||||
|
unset VIRTUAL_ENV
|
||||||
|
unset VIRTUAL_ENV_PROMPT
|
||||||
|
if [ ! "${1:-}" = "nondestructive" ] ; then
|
||||||
|
# Self destruct!
|
||||||
|
unset -f deactivate
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# unset irrelevant variables
|
||||||
|
deactivate nondestructive
|
||||||
|
|
||||||
|
VIRTUAL_ENV="/home/jonnybravo/Projekte/Python_Skripte/rclone"
|
||||||
|
export VIRTUAL_ENV
|
||||||
|
|
||||||
|
_OLD_VIRTUAL_PATH="$PATH"
|
||||||
|
PATH="$VIRTUAL_ENV/bin:$PATH"
|
||||||
|
export PATH
|
||||||
|
|
||||||
|
# unset PYTHONHOME if set
|
||||||
|
# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
|
||||||
|
# could use `if (set -u; : $PYTHONHOME) ;` in bash
|
||||||
|
if [ -n "${PYTHONHOME:-}" ] ; then
|
||||||
|
_OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}"
|
||||||
|
unset PYTHONHOME
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
|
||||||
|
_OLD_VIRTUAL_PS1="${PS1:-}"
|
||||||
|
PS1="(rclone) ${PS1:-}"
|
||||||
|
export PS1
|
||||||
|
VIRTUAL_ENV_PROMPT="(rclone) "
|
||||||
|
export VIRTUAL_ENV_PROMPT
|
||||||
|
fi
|
||||||
|
|
||||||
|
# This should detect bash and zsh, which have a hash command that must
|
||||||
|
# be called to get it to forget past commands. Without forgetting
|
||||||
|
# past commands the $PATH changes we made may not be respected
|
||||||
|
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
|
||||||
|
hash -r 2> /dev/null
|
||||||
|
fi
|
||||||
26
rclone/bin/activate.csh
Normal file
26
rclone/bin/activate.csh
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# This file must be used with "source bin/activate.csh" *from csh*.
|
||||||
|
# You cannot run it directly.
|
||||||
|
# Created by Davide Di Blasi <davidedb@gmail.com>.
|
||||||
|
# Ported to Python 3.3 venv by Andrew Svetlov <andrew.svetlov@gmail.com>
|
||||||
|
|
||||||
|
alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate'
|
||||||
|
|
||||||
|
# Unset irrelevant variables.
|
||||||
|
deactivate nondestructive
|
||||||
|
|
||||||
|
setenv VIRTUAL_ENV "/home/jonnybravo/Projekte/Python_Skripte/rclone"
|
||||||
|
|
||||||
|
set _OLD_VIRTUAL_PATH="$PATH"
|
||||||
|
setenv PATH "$VIRTUAL_ENV/bin:$PATH"
|
||||||
|
|
||||||
|
|
||||||
|
set _OLD_VIRTUAL_PROMPT="$prompt"
|
||||||
|
|
||||||
|
if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then
|
||||||
|
set prompt = "(rclone) $prompt"
|
||||||
|
setenv VIRTUAL_ENV_PROMPT "(rclone) "
|
||||||
|
endif
|
||||||
|
|
||||||
|
alias pydoc python -m pydoc
|
||||||
|
|
||||||
|
rehash
|
||||||
69
rclone/bin/activate.fish
Normal file
69
rclone/bin/activate.fish
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# This file must be used with "source <venv>/bin/activate.fish" *from fish*
|
||||||
|
# (https://fishshell.com/); you cannot run it directly.
|
||||||
|
|
||||||
|
function deactivate -d "Exit virtual environment and return to normal shell environment"
|
||||||
|
# reset old environment variables
|
||||||
|
if test -n "$_OLD_VIRTUAL_PATH"
|
||||||
|
set -gx PATH $_OLD_VIRTUAL_PATH
|
||||||
|
set -e _OLD_VIRTUAL_PATH
|
||||||
|
end
|
||||||
|
if test -n "$_OLD_VIRTUAL_PYTHONHOME"
|
||||||
|
set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME
|
||||||
|
set -e _OLD_VIRTUAL_PYTHONHOME
|
||||||
|
end
|
||||||
|
|
||||||
|
if test -n "$_OLD_FISH_PROMPT_OVERRIDE"
|
||||||
|
set -e _OLD_FISH_PROMPT_OVERRIDE
|
||||||
|
# prevents error when using nested fish instances (Issue #93858)
|
||||||
|
if functions -q _old_fish_prompt
|
||||||
|
functions -e fish_prompt
|
||||||
|
functions -c _old_fish_prompt fish_prompt
|
||||||
|
functions -e _old_fish_prompt
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
set -e VIRTUAL_ENV
|
||||||
|
set -e VIRTUAL_ENV_PROMPT
|
||||||
|
if test "$argv[1]" != "nondestructive"
|
||||||
|
# Self-destruct!
|
||||||
|
functions -e deactivate
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Unset irrelevant variables.
|
||||||
|
deactivate nondestructive
|
||||||
|
|
||||||
|
set -gx VIRTUAL_ENV "/home/jonnybravo/Projekte/Python_Skripte/rclone"
|
||||||
|
|
||||||
|
set -gx _OLD_VIRTUAL_PATH $PATH
|
||||||
|
set -gx PATH "$VIRTUAL_ENV/bin" $PATH
|
||||||
|
|
||||||
|
# Unset PYTHONHOME if set.
|
||||||
|
if set -q PYTHONHOME
|
||||||
|
set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME
|
||||||
|
set -e PYTHONHOME
|
||||||
|
end
|
||||||
|
|
||||||
|
if test -z "$VIRTUAL_ENV_DISABLE_PROMPT"
|
||||||
|
# fish uses a function instead of an env var to generate the prompt.
|
||||||
|
|
||||||
|
# Save the current fish_prompt function as the function _old_fish_prompt.
|
||||||
|
functions -c fish_prompt _old_fish_prompt
|
||||||
|
|
||||||
|
# With the original prompt function renamed, we can override with our own.
|
||||||
|
function fish_prompt
|
||||||
|
# Save the return status of the last command.
|
||||||
|
set -l old_status $status
|
||||||
|
|
||||||
|
# Output the venv prompt; color taken from the blue of the Python logo.
|
||||||
|
printf "%s%s%s" (set_color 4B8BBE) "(rclone) " (set_color normal)
|
||||||
|
|
||||||
|
# Restore the return status of the previous command.
|
||||||
|
echo "exit $old_status" | .
|
||||||
|
# Output the original/"old" prompt.
|
||||||
|
_old_fish_prompt
|
||||||
|
end
|
||||||
|
|
||||||
|
set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV"
|
||||||
|
set -gx VIRTUAL_ENV_PROMPT "(rclone) "
|
||||||
|
end
|
||||||
8
rclone/bin/markdown-it
Executable file
8
rclone/bin/markdown-it
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/home/jonnybravo/Projekte/Python_Skripte/rclone/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from markdown_it.cli.parse import main
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(main())
|
||||||
8
rclone/bin/pip
Executable file
8
rclone/bin/pip
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/home/jonnybravo/Projekte/Python_Skripte/rclone/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pip._internal.cli.main import main
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(main())
|
||||||
8
rclone/bin/pip3
Executable file
8
rclone/bin/pip3
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/home/jonnybravo/Projekte/Python_Skripte/rclone/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pip._internal.cli.main import main
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(main())
|
||||||
8
rclone/bin/pip3.11
Executable file
8
rclone/bin/pip3.11
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/home/jonnybravo/Projekte/Python_Skripte/rclone/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pip._internal.cli.main import main
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(main())
|
||||||
8
rclone/bin/pygmentize
Executable file
8
rclone/bin/pygmentize
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/home/jonnybravo/Projekte/Python_Skripte/rclone/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pygments.cmdline import main
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(main())
|
||||||
1
rclone/bin/python
Symbolic link
1
rclone/bin/python
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/usr/bin/python
|
||||||
1
rclone/bin/python3
Symbolic link
1
rclone/bin/python3
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
python
|
||||||
1
rclone/bin/python3.11
Symbolic link
1
rclone/bin/python3.11
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
python
|
||||||
222
rclone/lib/python3.11/site-packages/_distutils_hack/__init__.py
Normal file
222
rclone/lib/python3.11/site-packages/_distutils_hack/__init__.py
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
# don't import any costly modules
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
is_pypy = '__pypy__' in sys.builtin_module_names
|
||||||
|
|
||||||
|
|
||||||
|
def warn_distutils_present():
|
||||||
|
if 'distutils' not in sys.modules:
|
||||||
|
return
|
||||||
|
if is_pypy and sys.version_info < (3, 7):
|
||||||
|
# PyPy for 3.6 unconditionally imports distutils, so bypass the warning
|
||||||
|
# https://foss.heptapod.net/pypy/pypy/-/blob/be829135bc0d758997b3566062999ee8b23872b4/lib-python/3/site.py#L250
|
||||||
|
return
|
||||||
|
import warnings
|
||||||
|
|
||||||
|
warnings.warn(
|
||||||
|
"Distutils was imported before Setuptools, but importing Setuptools "
|
||||||
|
"also replaces the `distutils` module in `sys.modules`. This may lead "
|
||||||
|
"to undesirable behaviors or errors. To avoid these issues, avoid "
|
||||||
|
"using distutils directly, ensure that setuptools is installed in the "
|
||||||
|
"traditional way (e.g. not an editable install), and/or make sure "
|
||||||
|
"that setuptools is always imported before distutils."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def clear_distutils():
|
||||||
|
if 'distutils' not in sys.modules:
|
||||||
|
return
|
||||||
|
import warnings
|
||||||
|
|
||||||
|
warnings.warn("Setuptools is replacing distutils.")
|
||||||
|
mods = [
|
||||||
|
name
|
||||||
|
for name in sys.modules
|
||||||
|
if name == "distutils" or name.startswith("distutils.")
|
||||||
|
]
|
||||||
|
for name in mods:
|
||||||
|
del sys.modules[name]
|
||||||
|
|
||||||
|
|
||||||
|
def enabled():
|
||||||
|
"""
|
||||||
|
Allow selection of distutils by environment variable.
|
||||||
|
"""
|
||||||
|
which = os.environ.get('SETUPTOOLS_USE_DISTUTILS', 'local')
|
||||||
|
return which == 'local'
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_local_distutils():
|
||||||
|
import importlib
|
||||||
|
|
||||||
|
clear_distutils()
|
||||||
|
|
||||||
|
# With the DistutilsMetaFinder in place,
|
||||||
|
# perform an import to cause distutils to be
|
||||||
|
# loaded from setuptools._distutils. Ref #2906.
|
||||||
|
with shim():
|
||||||
|
importlib.import_module('distutils')
|
||||||
|
|
||||||
|
# check that submodules load as expected
|
||||||
|
core = importlib.import_module('distutils.core')
|
||||||
|
assert '_distutils' in core.__file__, core.__file__
|
||||||
|
assert 'setuptools._distutils.log' not in sys.modules
|
||||||
|
|
||||||
|
|
||||||
|
def do_override():
|
||||||
|
"""
|
||||||
|
Ensure that the local copy of distutils is preferred over stdlib.
|
||||||
|
|
||||||
|
See https://github.com/pypa/setuptools/issues/417#issuecomment-392298401
|
||||||
|
for more motivation.
|
||||||
|
"""
|
||||||
|
if enabled():
|
||||||
|
warn_distutils_present()
|
||||||
|
ensure_local_distutils()
|
||||||
|
|
||||||
|
|
||||||
|
class _TrivialRe:
|
||||||
|
def __init__(self, *patterns):
|
||||||
|
self._patterns = patterns
|
||||||
|
|
||||||
|
def match(self, string):
|
||||||
|
return all(pat in string for pat in self._patterns)
|
||||||
|
|
||||||
|
|
||||||
|
class DistutilsMetaFinder:
|
||||||
|
def find_spec(self, fullname, path, target=None):
|
||||||
|
# optimization: only consider top level modules and those
|
||||||
|
# found in the CPython test suite.
|
||||||
|
if path is not None and not fullname.startswith('test.'):
|
||||||
|
return
|
||||||
|
|
||||||
|
method_name = 'spec_for_{fullname}'.format(**locals())
|
||||||
|
method = getattr(self, method_name, lambda: None)
|
||||||
|
return method()
|
||||||
|
|
||||||
|
def spec_for_distutils(self):
|
||||||
|
if self.is_cpython():
|
||||||
|
return
|
||||||
|
|
||||||
|
import importlib
|
||||||
|
import importlib.abc
|
||||||
|
import importlib.util
|
||||||
|
|
||||||
|
try:
|
||||||
|
mod = importlib.import_module('setuptools._distutils')
|
||||||
|
except Exception:
|
||||||
|
# There are a couple of cases where setuptools._distutils
|
||||||
|
# may not be present:
|
||||||
|
# - An older Setuptools without a local distutils is
|
||||||
|
# taking precedence. Ref #2957.
|
||||||
|
# - Path manipulation during sitecustomize removes
|
||||||
|
# setuptools from the path but only after the hook
|
||||||
|
# has been loaded. Ref #2980.
|
||||||
|
# In either case, fall back to stdlib behavior.
|
||||||
|
return
|
||||||
|
|
||||||
|
class DistutilsLoader(importlib.abc.Loader):
|
||||||
|
def create_module(self, spec):
|
||||||
|
mod.__name__ = 'distutils'
|
||||||
|
return mod
|
||||||
|
|
||||||
|
def exec_module(self, module):
|
||||||
|
pass
|
||||||
|
|
||||||
|
return importlib.util.spec_from_loader(
|
||||||
|
'distutils', DistutilsLoader(), origin=mod.__file__
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def is_cpython():
|
||||||
|
"""
|
||||||
|
Suppress supplying distutils for CPython (build and tests).
|
||||||
|
Ref #2965 and #3007.
|
||||||
|
"""
|
||||||
|
return os.path.isfile('pybuilddir.txt')
|
||||||
|
|
||||||
|
def spec_for_pip(self):
|
||||||
|
"""
|
||||||
|
Ensure stdlib distutils when running under pip.
|
||||||
|
See pypa/pip#8761 for rationale.
|
||||||
|
"""
|
||||||
|
if self.pip_imported_during_build():
|
||||||
|
return
|
||||||
|
clear_distutils()
|
||||||
|
self.spec_for_distutils = lambda: None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def pip_imported_during_build(cls):
|
||||||
|
"""
|
||||||
|
Detect if pip is being imported in a build script. Ref #2355.
|
||||||
|
"""
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
return any(
|
||||||
|
cls.frame_file_is_setup(frame) for frame, line in traceback.walk_stack(None)
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def frame_file_is_setup(frame):
|
||||||
|
"""
|
||||||
|
Return True if the indicated frame suggests a setup.py file.
|
||||||
|
"""
|
||||||
|
# some frames may not have __file__ (#2940)
|
||||||
|
return frame.f_globals.get('__file__', '').endswith('setup.py')
|
||||||
|
|
||||||
|
def spec_for_sensitive_tests(self):
|
||||||
|
"""
|
||||||
|
Ensure stdlib distutils when running select tests under CPython.
|
||||||
|
|
||||||
|
python/cpython#91169
|
||||||
|
"""
|
||||||
|
clear_distutils()
|
||||||
|
self.spec_for_distutils = lambda: None
|
||||||
|
|
||||||
|
sensitive_tests = (
|
||||||
|
[
|
||||||
|
'test.test_distutils',
|
||||||
|
'test.test_peg_generator',
|
||||||
|
'test.test_importlib',
|
||||||
|
]
|
||||||
|
if sys.version_info < (3, 10)
|
||||||
|
else [
|
||||||
|
'test.test_distutils',
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
for name in DistutilsMetaFinder.sensitive_tests:
|
||||||
|
setattr(
|
||||||
|
DistutilsMetaFinder,
|
||||||
|
f'spec_for_{name}',
|
||||||
|
DistutilsMetaFinder.spec_for_sensitive_tests,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
DISTUTILS_FINDER = DistutilsMetaFinder()
|
||||||
|
|
||||||
|
|
||||||
|
def add_shim():
|
||||||
|
DISTUTILS_FINDER in sys.meta_path or insert_shim()
|
||||||
|
|
||||||
|
|
||||||
|
class shim:
|
||||||
|
def __enter__(self):
|
||||||
|
insert_shim()
|
||||||
|
|
||||||
|
def __exit__(self, exc, value, tb):
|
||||||
|
remove_shim()
|
||||||
|
|
||||||
|
|
||||||
|
def insert_shim():
|
||||||
|
sys.meta_path.insert(0, DISTUTILS_FINDER)
|
||||||
|
|
||||||
|
|
||||||
|
def remove_shim():
|
||||||
|
try:
|
||||||
|
sys.meta_path.remove(DISTUTILS_FINDER)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
__import__('_distutils_hack').do_override()
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
import os; var = 'SETUPTOOLS_USE_DISTUTILS'; enabled = os.environ.get(var, 'local') == 'local'; enabled and __import__('_distutils_hack').add_shim();
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
"""A Python port of Markdown-It"""
|
||||||
|
__all__ = ("MarkdownIt",)
|
||||||
|
__version__ = "3.0.0"
|
||||||
|
|
||||||
|
from .main import MarkdownIt
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
11
rclone/lib/python3.11/site-packages/markdown_it/_compat.py
Normal file
11
rclone/lib/python3.11/site-packages/markdown_it/_compat.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
import sys
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
DATACLASS_KWARGS: Mapping[str, Any]
|
||||||
|
if sys.version_info >= (3, 10):
|
||||||
|
DATACLASS_KWARGS = {"slots": True}
|
||||||
|
else:
|
||||||
|
DATACLASS_KWARGS = {}
|
||||||
67
rclone/lib/python3.11/site-packages/markdown_it/_punycode.py
Normal file
67
rclone/lib/python3.11/site-packages/markdown_it/_punycode.py
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
# Copyright 2014 Mathias Bynens <https://mathiasbynens.be/>
|
||||||
|
# Copyright 2021 Taneli Hukkinen
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
# a copy of this software and associated documentation files (the
|
||||||
|
# "Software"), to deal in the Software without restriction, including
|
||||||
|
# without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
# permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
# the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be
|
||||||
|
# included in all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
import codecs
|
||||||
|
import re
|
||||||
|
from typing import Callable
|
||||||
|
|
||||||
|
REGEX_SEPARATORS = re.compile(r"[\x2E\u3002\uFF0E\uFF61]")
|
||||||
|
REGEX_NON_ASCII = re.compile(r"[^\0-\x7E]")
|
||||||
|
|
||||||
|
|
||||||
|
def encode(uni: str) -> str:
|
||||||
|
return codecs.encode(uni, encoding="punycode").decode()
|
||||||
|
|
||||||
|
|
||||||
|
def decode(ascii: str) -> str:
|
||||||
|
return codecs.decode(ascii, encoding="punycode") # type: ignore
|
||||||
|
|
||||||
|
|
||||||
|
def map_domain(string: str, fn: Callable[[str], str]) -> str:
|
||||||
|
parts = string.split("@")
|
||||||
|
result = ""
|
||||||
|
if len(parts) > 1:
|
||||||
|
# In email addresses, only the domain name should be punycoded. Leave
|
||||||
|
# the local part (i.e. everything up to `@`) intact.
|
||||||
|
result = parts[0] + "@"
|
||||||
|
string = parts[1]
|
||||||
|
labels = REGEX_SEPARATORS.split(string)
|
||||||
|
encoded = ".".join(fn(label) for label in labels)
|
||||||
|
return result + encoded
|
||||||
|
|
||||||
|
|
||||||
|
def to_unicode(obj: str) -> str:
|
||||||
|
def mapping(obj: str) -> str:
|
||||||
|
if obj.startswith("xn--"):
|
||||||
|
return decode(obj[4:].lower())
|
||||||
|
return obj
|
||||||
|
|
||||||
|
return map_domain(obj, mapping)
|
||||||
|
|
||||||
|
|
||||||
|
def to_ascii(obj: str) -> str:
|
||||||
|
def mapping(obj: str) -> str:
|
||||||
|
if REGEX_NON_ASCII.search(obj):
|
||||||
|
return "xn--" + encode(obj)
|
||||||
|
return obj
|
||||||
|
|
||||||
|
return map_domain(obj, mapping)
|
||||||
Binary file not shown.
Binary file not shown.
109
rclone/lib/python3.11/site-packages/markdown_it/cli/parse.py
Normal file
109
rclone/lib/python3.11/site-packages/markdown_it/cli/parse.py
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
"""
|
||||||
|
CLI interface to markdown-it-py
|
||||||
|
|
||||||
|
Parse one or more markdown files, convert each to HTML, and print to stdout.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
from collections.abc import Iterable, Sequence
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from markdown_it import __version__
|
||||||
|
from markdown_it.main import MarkdownIt
|
||||||
|
|
||||||
|
version_str = "markdown-it-py [version {}]".format(__version__)
|
||||||
|
|
||||||
|
|
||||||
|
def main(args: Sequence[str] | None = None) -> int:
|
||||||
|
namespace = parse_args(args)
|
||||||
|
if namespace.filenames:
|
||||||
|
convert(namespace.filenames)
|
||||||
|
else:
|
||||||
|
interactive()
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def convert(filenames: Iterable[str]) -> None:
|
||||||
|
for filename in filenames:
|
||||||
|
convert_file(filename)
|
||||||
|
|
||||||
|
|
||||||
|
def convert_file(filename: str) -> None:
|
||||||
|
"""
|
||||||
|
Parse a Markdown file and dump the output to stdout.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
with open(filename, "r", encoding="utf8", errors="ignore") as fin:
|
||||||
|
rendered = MarkdownIt().render(fin.read())
|
||||||
|
print(rendered, end="")
|
||||||
|
except OSError:
|
||||||
|
sys.stderr.write(f'Cannot open file "{filename}".\n')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def interactive() -> None:
|
||||||
|
"""
|
||||||
|
Parse user input, dump to stdout, rinse and repeat.
|
||||||
|
Python REPL style.
|
||||||
|
"""
|
||||||
|
print_heading()
|
||||||
|
contents = []
|
||||||
|
more = False
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
prompt, more = ("... ", True) if more else (">>> ", True)
|
||||||
|
contents.append(input(prompt) + "\n")
|
||||||
|
except EOFError:
|
||||||
|
print("\n" + MarkdownIt().render("\n".join(contents)), end="")
|
||||||
|
more = False
|
||||||
|
contents = []
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\nExiting.")
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def parse_args(args: Sequence[str] | None) -> argparse.Namespace:
|
||||||
|
"""Parse input CLI arguments."""
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Parse one or more markdown files, "
|
||||||
|
"convert each to HTML, and print to stdout",
|
||||||
|
# NOTE: Remember to update README.md w/ the output of `markdown-it -h`
|
||||||
|
epilog=(
|
||||||
|
f"""
|
||||||
|
Interactive:
|
||||||
|
|
||||||
|
$ markdown-it
|
||||||
|
markdown-it-py [version {__version__}] (interactive)
|
||||||
|
Type Ctrl-D to complete input, or Ctrl-C to exit.
|
||||||
|
>>> # Example
|
||||||
|
... > markdown *input*
|
||||||
|
...
|
||||||
|
<h1>Example</h1>
|
||||||
|
<blockquote>
|
||||||
|
<p>markdown <em>input</em></p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
Batch:
|
||||||
|
|
||||||
|
$ markdown-it README.md README.footer.md > index.html
|
||||||
|
"""
|
||||||
|
),
|
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
|
)
|
||||||
|
parser.add_argument("-v", "--version", action="version", version=version_str)
|
||||||
|
parser.add_argument(
|
||||||
|
"filenames", nargs="*", help="specify an optional list of files to convert"
|
||||||
|
)
|
||||||
|
return parser.parse_args(args)
|
||||||
|
|
||||||
|
|
||||||
|
def print_heading() -> None:
|
||||||
|
print("{} (interactive)".format(version_str))
|
||||||
|
print("Type Ctrl-D to complete input, or Ctrl-C to exit.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
exit_code = main(sys.argv[1:])
|
||||||
|
sys.exit(exit_code)
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,4 @@
|
|||||||
|
"""HTML5 entities map: { name -> characters }."""
|
||||||
|
import html.entities
|
||||||
|
|
||||||
|
entities = {name.rstrip(";"): chars for name, chars in html.entities.html5.items()}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
"""List of valid html blocks names, according to commonmark spec
|
||||||
|
http://jgm.github.io/CommonMark/spec.html#html-blocks
|
||||||
|
"""
|
||||||
|
|
||||||
|
block_names = [
|
||||||
|
"address",
|
||||||
|
"article",
|
||||||
|
"aside",
|
||||||
|
"base",
|
||||||
|
"basefont",
|
||||||
|
"blockquote",
|
||||||
|
"body",
|
||||||
|
"caption",
|
||||||
|
"center",
|
||||||
|
"col",
|
||||||
|
"colgroup",
|
||||||
|
"dd",
|
||||||
|
"details",
|
||||||
|
"dialog",
|
||||||
|
"dir",
|
||||||
|
"div",
|
||||||
|
"dl",
|
||||||
|
"dt",
|
||||||
|
"fieldset",
|
||||||
|
"figcaption",
|
||||||
|
"figure",
|
||||||
|
"footer",
|
||||||
|
"form",
|
||||||
|
"frame",
|
||||||
|
"frameset",
|
||||||
|
"h1",
|
||||||
|
"h2",
|
||||||
|
"h3",
|
||||||
|
"h4",
|
||||||
|
"h5",
|
||||||
|
"h6",
|
||||||
|
"head",
|
||||||
|
"header",
|
||||||
|
"hr",
|
||||||
|
"html",
|
||||||
|
"iframe",
|
||||||
|
"legend",
|
||||||
|
"li",
|
||||||
|
"link",
|
||||||
|
"main",
|
||||||
|
"menu",
|
||||||
|
"menuitem",
|
||||||
|
"nav",
|
||||||
|
"noframes",
|
||||||
|
"ol",
|
||||||
|
"optgroup",
|
||||||
|
"option",
|
||||||
|
"p",
|
||||||
|
"param",
|
||||||
|
"section",
|
||||||
|
"source",
|
||||||
|
"summary",
|
||||||
|
"table",
|
||||||
|
"tbody",
|
||||||
|
"td",
|
||||||
|
"tfoot",
|
||||||
|
"th",
|
||||||
|
"thead",
|
||||||
|
"title",
|
||||||
|
"tr",
|
||||||
|
"track",
|
||||||
|
"ul",
|
||||||
|
]
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
"""Regexps to match html elements
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
attr_name = "[a-zA-Z_:][a-zA-Z0-9:._-]*"
|
||||||
|
|
||||||
|
unquoted = "[^\"'=<>`\\x00-\\x20]+"
|
||||||
|
single_quoted = "'[^']*'"
|
||||||
|
double_quoted = '"[^"]*"'
|
||||||
|
|
||||||
|
attr_value = "(?:" + unquoted + "|" + single_quoted + "|" + double_quoted + ")"
|
||||||
|
|
||||||
|
attribute = "(?:\\s+" + attr_name + "(?:\\s*=\\s*" + attr_value + ")?)"
|
||||||
|
|
||||||
|
open_tag = "<[A-Za-z][A-Za-z0-9\\-]*" + attribute + "*\\s*\\/?>"
|
||||||
|
|
||||||
|
close_tag = "<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>"
|
||||||
|
comment = "<!---->|<!--(?:-?[^>-])(?:-?[^-])*-->"
|
||||||
|
processing = "<[?][\\s\\S]*?[?]>"
|
||||||
|
declaration = "<![A-Z]+\\s+[^>]*>"
|
||||||
|
cdata = "<!\\[CDATA\\[[\\s\\S]*?\\]\\]>"
|
||||||
|
|
||||||
|
HTML_TAG_RE = re.compile(
|
||||||
|
"^(?:"
|
||||||
|
+ open_tag
|
||||||
|
+ "|"
|
||||||
|
+ close_tag
|
||||||
|
+ "|"
|
||||||
|
+ comment
|
||||||
|
+ "|"
|
||||||
|
+ processing
|
||||||
|
+ "|"
|
||||||
|
+ declaration
|
||||||
|
+ "|"
|
||||||
|
+ cdata
|
||||||
|
+ ")"
|
||||||
|
)
|
||||||
|
HTML_OPEN_CLOSE_TAG_STR = "^(?:" + open_tag + "|" + close_tag + ")"
|
||||||
|
HTML_OPEN_CLOSE_TAG_RE = re.compile(HTML_OPEN_CLOSE_TAG_STR)
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Callable
|
||||||
|
from contextlib import suppress
|
||||||
|
import re
|
||||||
|
from urllib.parse import quote, unquote, urlparse, urlunparse # noqa: F401
|
||||||
|
|
||||||
|
import mdurl
|
||||||
|
|
||||||
|
from .. import _punycode
|
||||||
|
|
||||||
|
RECODE_HOSTNAME_FOR = ("http:", "https:", "mailto:")
|
||||||
|
|
||||||
|
|
||||||
|
def normalizeLink(url: str) -> str:
|
||||||
|
"""Normalize destination URLs in links
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
[label]: destination 'title'
|
||||||
|
^^^^^^^^^^^
|
||||||
|
"""
|
||||||
|
parsed = mdurl.parse(url, slashes_denote_host=True)
|
||||||
|
|
||||||
|
# Encode hostnames in urls like:
|
||||||
|
# `http://host/`, `https://host/`, `mailto:user@host`, `//host/`
|
||||||
|
#
|
||||||
|
# We don't encode unknown schemas, because it's likely that we encode
|
||||||
|
# something we shouldn't (e.g. `skype:name` treated as `skype:host`)
|
||||||
|
#
|
||||||
|
if parsed.hostname and (
|
||||||
|
not parsed.protocol or parsed.protocol in RECODE_HOSTNAME_FOR
|
||||||
|
):
|
||||||
|
with suppress(Exception):
|
||||||
|
parsed = parsed._replace(hostname=_punycode.to_ascii(parsed.hostname))
|
||||||
|
|
||||||
|
return mdurl.encode(mdurl.format(parsed))
|
||||||
|
|
||||||
|
|
||||||
|
def normalizeLinkText(url: str) -> str:
|
||||||
|
"""Normalize autolink content
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
<destination>
|
||||||
|
~~~~~~~~~~~
|
||||||
|
"""
|
||||||
|
parsed = mdurl.parse(url, slashes_denote_host=True)
|
||||||
|
|
||||||
|
# Encode hostnames in urls like:
|
||||||
|
# `http://host/`, `https://host/`, `mailto:user@host`, `//host/`
|
||||||
|
#
|
||||||
|
# We don't encode unknown schemas, because it's likely that we encode
|
||||||
|
# something we shouldn't (e.g. `skype:name` treated as `skype:host`)
|
||||||
|
#
|
||||||
|
if parsed.hostname and (
|
||||||
|
not parsed.protocol or parsed.protocol in RECODE_HOSTNAME_FOR
|
||||||
|
):
|
||||||
|
with suppress(Exception):
|
||||||
|
parsed = parsed._replace(hostname=_punycode.to_unicode(parsed.hostname))
|
||||||
|
|
||||||
|
# add '%' to exclude list because of https://github.com/markdown-it/markdown-it/issues/720
|
||||||
|
return mdurl.decode(mdurl.format(parsed), mdurl.DECODE_DEFAULT_CHARS + "%")
|
||||||
|
|
||||||
|
|
||||||
|
BAD_PROTO_RE = re.compile(r"^(vbscript|javascript|file|data):")
|
||||||
|
GOOD_DATA_RE = re.compile(r"^data:image\/(gif|png|jpeg|webp);")
|
||||||
|
|
||||||
|
|
||||||
|
def validateLink(url: str, validator: Callable[[str], bool] | None = None) -> bool:
|
||||||
|
"""Validate URL link is allowed in output.
|
||||||
|
|
||||||
|
This validator can prohibit more than really needed to prevent XSS.
|
||||||
|
It's a tradeoff to keep code simple and to be secure by default.
|
||||||
|
|
||||||
|
Note: url should be normalized at this point, and existing entities decoded.
|
||||||
|
"""
|
||||||
|
if validator is not None:
|
||||||
|
return validator(url)
|
||||||
|
url = url.strip().lower()
|
||||||
|
return bool(GOOD_DATA_RE.search(url)) if BAD_PROTO_RE.search(url) else True
|
||||||
318
rclone/lib/python3.11/site-packages/markdown_it/common/utils.py
Normal file
318
rclone/lib/python3.11/site-packages/markdown_it/common/utils.py
Normal file
@@ -0,0 +1,318 @@
|
|||||||
|
"""Utilities for parsing source text
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import re
|
||||||
|
from typing import Match, TypeVar
|
||||||
|
|
||||||
|
from .entities import entities
|
||||||
|
|
||||||
|
|
||||||
|
def charCodeAt(src: str, pos: int) -> int | None:
|
||||||
|
"""
|
||||||
|
Returns the Unicode value of the character at the specified location.
|
||||||
|
|
||||||
|
@param - index The zero-based index of the desired character.
|
||||||
|
If there is no character at the specified index, NaN is returned.
|
||||||
|
|
||||||
|
This was added for compatibility with python
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return ord(src[pos])
|
||||||
|
except IndexError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def charStrAt(src: str, pos: int) -> str | None:
|
||||||
|
"""
|
||||||
|
Returns the Unicode value of the character at the specified location.
|
||||||
|
|
||||||
|
@param - index The zero-based index of the desired character.
|
||||||
|
If there is no character at the specified index, NaN is returned.
|
||||||
|
|
||||||
|
This was added for compatibility with python
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return src[pos]
|
||||||
|
except IndexError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
_ItemTV = TypeVar("_ItemTV")
|
||||||
|
|
||||||
|
|
||||||
|
def arrayReplaceAt(
|
||||||
|
src: list[_ItemTV], pos: int, newElements: list[_ItemTV]
|
||||||
|
) -> list[_ItemTV]:
|
||||||
|
"""
|
||||||
|
Remove element from array and put another array at those position.
|
||||||
|
Useful for some operations with tokens
|
||||||
|
"""
|
||||||
|
return src[:pos] + newElements + src[pos + 1 :]
|
||||||
|
|
||||||
|
|
||||||
|
def isValidEntityCode(c: int) -> bool:
|
||||||
|
# broken sequence
|
||||||
|
if c >= 0xD800 and c <= 0xDFFF:
|
||||||
|
return False
|
||||||
|
# never used
|
||||||
|
if c >= 0xFDD0 and c <= 0xFDEF:
|
||||||
|
return False
|
||||||
|
if ((c & 0xFFFF) == 0xFFFF) or ((c & 0xFFFF) == 0xFFFE):
|
||||||
|
return False
|
||||||
|
# control codes
|
||||||
|
if c >= 0x00 and c <= 0x08:
|
||||||
|
return False
|
||||||
|
if c == 0x0B:
|
||||||
|
return False
|
||||||
|
if c >= 0x0E and c <= 0x1F:
|
||||||
|
return False
|
||||||
|
if c >= 0x7F and c <= 0x9F:
|
||||||
|
return False
|
||||||
|
# out of range
|
||||||
|
if c > 0x10FFFF:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def fromCodePoint(c: int) -> str:
|
||||||
|
"""Convert ordinal to unicode.
|
||||||
|
|
||||||
|
Note, in the original Javascript two string characters were required,
|
||||||
|
for codepoints larger than `0xFFFF`.
|
||||||
|
But Python 3 can represent any unicode codepoint in one character.
|
||||||
|
"""
|
||||||
|
return chr(c)
|
||||||
|
|
||||||
|
|
||||||
|
# UNESCAPE_MD_RE = re.compile(r'\\([!"#$%&\'()*+,\-.\/:;<=>?@[\\\]^_`{|}~])')
|
||||||
|
# ENTITY_RE_g = re.compile(r'&([a-z#][a-z0-9]{1,31})', re.IGNORECASE)
|
||||||
|
UNESCAPE_ALL_RE = re.compile(
|
||||||
|
r'\\([!"#$%&\'()*+,\-.\/:;<=>?@[\\\]^_`{|}~])' + "|" + r"&([a-z#][a-z0-9]{1,31});",
|
||||||
|
re.IGNORECASE,
|
||||||
|
)
|
||||||
|
DIGITAL_ENTITY_BASE10_RE = re.compile(r"#([0-9]{1,8})")
|
||||||
|
DIGITAL_ENTITY_BASE16_RE = re.compile(r"#x([a-f0-9]{1,8})", re.IGNORECASE)
|
||||||
|
|
||||||
|
|
||||||
|
def replaceEntityPattern(match: str, name: str) -> str:
|
||||||
|
"""Convert HTML entity patterns,
|
||||||
|
see https://spec.commonmark.org/0.30/#entity-references
|
||||||
|
"""
|
||||||
|
if name in entities:
|
||||||
|
return entities[name]
|
||||||
|
|
||||||
|
code: None | int = None
|
||||||
|
if pat := DIGITAL_ENTITY_BASE10_RE.fullmatch(name):
|
||||||
|
code = int(pat.group(1), 10)
|
||||||
|
elif pat := DIGITAL_ENTITY_BASE16_RE.fullmatch(name):
|
||||||
|
code = int(pat.group(1), 16)
|
||||||
|
|
||||||
|
if code is not None and isValidEntityCode(code):
|
||||||
|
return fromCodePoint(code)
|
||||||
|
|
||||||
|
return match
|
||||||
|
|
||||||
|
|
||||||
|
def unescapeAll(string: str) -> str:
|
||||||
|
def replacer_func(match: Match[str]) -> str:
|
||||||
|
escaped = match.group(1)
|
||||||
|
if escaped:
|
||||||
|
return escaped
|
||||||
|
entity = match.group(2)
|
||||||
|
return replaceEntityPattern(match.group(), entity)
|
||||||
|
|
||||||
|
if "\\" not in string and "&" not in string:
|
||||||
|
return string
|
||||||
|
return UNESCAPE_ALL_RE.sub(replacer_func, string)
|
||||||
|
|
||||||
|
|
||||||
|
ESCAPABLE = r"""\\!"#$%&'()*+,./:;<=>?@\[\]^`{}|_~-"""
|
||||||
|
ESCAPE_CHAR = re.compile(r"\\([" + ESCAPABLE + r"])")
|
||||||
|
|
||||||
|
|
||||||
|
def stripEscape(string: str) -> str:
|
||||||
|
"""Strip escape \\ characters"""
|
||||||
|
return ESCAPE_CHAR.sub(r"\1", string)
|
||||||
|
|
||||||
|
|
||||||
|
def escapeHtml(raw: str) -> str:
|
||||||
|
"""Replace special characters "&", "<", ">" and '"' to HTML-safe sequences."""
|
||||||
|
# like html.escape, but without escaping single quotes
|
||||||
|
raw = raw.replace("&", "&") # Must be done first!
|
||||||
|
raw = raw.replace("<", "<")
|
||||||
|
raw = raw.replace(">", ">")
|
||||||
|
raw = raw.replace('"', """)
|
||||||
|
return raw
|
||||||
|
|
||||||
|
|
||||||
|
# //////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
REGEXP_ESCAPE_RE = re.compile(r"[.?*+^$[\]\\(){}|-]")
|
||||||
|
|
||||||
|
|
||||||
|
def escapeRE(string: str) -> str:
|
||||||
|
string = REGEXP_ESCAPE_RE.sub("\\$&", string)
|
||||||
|
return string
|
||||||
|
|
||||||
|
|
||||||
|
# //////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
def isSpace(code: int | None) -> bool:
|
||||||
|
"""Check if character code is a whitespace."""
|
||||||
|
return code in (0x09, 0x20)
|
||||||
|
|
||||||
|
|
||||||
|
def isStrSpace(ch: str | None) -> bool:
|
||||||
|
"""Check if character is a whitespace."""
|
||||||
|
return ch in ("\t", " ")
|
||||||
|
|
||||||
|
|
||||||
|
MD_WHITESPACE = {
|
||||||
|
0x09, # \t
|
||||||
|
0x0A, # \n
|
||||||
|
0x0B, # \v
|
||||||
|
0x0C, # \f
|
||||||
|
0x0D, # \r
|
||||||
|
0x20, # space
|
||||||
|
0xA0,
|
||||||
|
0x1680,
|
||||||
|
0x202F,
|
||||||
|
0x205F,
|
||||||
|
0x3000,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def isWhiteSpace(code: int) -> bool:
|
||||||
|
r"""Zs (unicode class) || [\t\f\v\r\n]"""
|
||||||
|
if code >= 0x2000 and code <= 0x200A:
|
||||||
|
return True
|
||||||
|
return code in MD_WHITESPACE
|
||||||
|
|
||||||
|
|
||||||
|
# //////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
UNICODE_PUNCT_RE = re.compile(
|
||||||
|
r"[!-#%-\*,-\/:;\?@\[-\]_\{\}\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4E\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD803[\uDF55-\uDF59]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDC4B-\uDC4F\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDF3C-\uDF3E]|\uD806[\uDC3B\uDE3F-\uDE46\uDE9A-\uDE9C\uDE9E-\uDEA2]|\uD807[\uDC41-\uDC45\uDC70\uDC71\uDEF7\uDEF8]|\uD809[\uDC70-\uDC74]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD81B[\uDE97-\uDE9A]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]|\uD83A[\uDD5E\uDD5F]" # noqa: E501
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Currently without astral characters support.
|
||||||
|
def isPunctChar(ch: str) -> bool:
|
||||||
|
"""Check if character is a punctuation character."""
|
||||||
|
return UNICODE_PUNCT_RE.search(ch) is not None
|
||||||
|
|
||||||
|
|
||||||
|
MD_ASCII_PUNCT = {
|
||||||
|
0x21, # /* ! */
|
||||||
|
0x22, # /* " */
|
||||||
|
0x23, # /* # */
|
||||||
|
0x24, # /* $ */
|
||||||
|
0x25, # /* % */
|
||||||
|
0x26, # /* & */
|
||||||
|
0x27, # /* ' */
|
||||||
|
0x28, # /* ( */
|
||||||
|
0x29, # /* ) */
|
||||||
|
0x2A, # /* * */
|
||||||
|
0x2B, # /* + */
|
||||||
|
0x2C, # /* , */
|
||||||
|
0x2D, # /* - */
|
||||||
|
0x2E, # /* . */
|
||||||
|
0x2F, # /* / */
|
||||||
|
0x3A, # /* : */
|
||||||
|
0x3B, # /* ; */
|
||||||
|
0x3C, # /* < */
|
||||||
|
0x3D, # /* = */
|
||||||
|
0x3E, # /* > */
|
||||||
|
0x3F, # /* ? */
|
||||||
|
0x40, # /* @ */
|
||||||
|
0x5B, # /* [ */
|
||||||
|
0x5C, # /* \ */
|
||||||
|
0x5D, # /* ] */
|
||||||
|
0x5E, # /* ^ */
|
||||||
|
0x5F, # /* _ */
|
||||||
|
0x60, # /* ` */
|
||||||
|
0x7B, # /* { */
|
||||||
|
0x7C, # /* | */
|
||||||
|
0x7D, # /* } */
|
||||||
|
0x7E, # /* ~ */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def isMdAsciiPunct(ch: int) -> bool:
|
||||||
|
"""Markdown ASCII punctuation characters.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
!, ", #, $, %, &, ', (, ), *, +, ,, -, ., /, :, ;, <, =, >, ?, @, [, \\, ], ^, _, `, {, |, }, or ~
|
||||||
|
|
||||||
|
See http://spec.commonmark.org/0.15/#ascii-punctuation-character
|
||||||
|
|
||||||
|
Don't confuse with unicode punctuation !!! It lacks some chars in ascii range.
|
||||||
|
|
||||||
|
""" # noqa: E501
|
||||||
|
return ch in MD_ASCII_PUNCT
|
||||||
|
|
||||||
|
|
||||||
|
def normalizeReference(string: str) -> str:
|
||||||
|
"""Helper to unify [reference labels]."""
|
||||||
|
# Trim and collapse whitespace
|
||||||
|
#
|
||||||
|
string = re.sub(r"\s+", " ", string.strip())
|
||||||
|
|
||||||
|
# In node v10 'ẞ'.toLowerCase() === 'Ṿ', which is presumed to be a bug
|
||||||
|
# fixed in v12 (couldn't find any details).
|
||||||
|
#
|
||||||
|
# So treat this one as a special case
|
||||||
|
# (remove this when node v10 is no longer supported).
|
||||||
|
#
|
||||||
|
# if ('ẞ'.toLowerCase() === 'Ṿ') {
|
||||||
|
# str = str.replace(/ẞ/g, 'ß')
|
||||||
|
# }
|
||||||
|
|
||||||
|
# .toLowerCase().toUpperCase() should get rid of all differences
|
||||||
|
# between letter variants.
|
||||||
|
#
|
||||||
|
# Simple .toLowerCase() doesn't normalize 125 code points correctly,
|
||||||
|
# and .toUpperCase doesn't normalize 6 of them (list of exceptions:
|
||||||
|
# İ, ϴ, ẞ, Ω, K, Å - those are already uppercased, but have differently
|
||||||
|
# uppercased versions).
|
||||||
|
#
|
||||||
|
# Here's an example showing how it happens. Lets take greek letter omega:
|
||||||
|
# uppercase U+0398 (Θ), U+03f4 (ϴ) and lowercase U+03b8 (θ), U+03d1 (ϑ)
|
||||||
|
#
|
||||||
|
# Unicode entries:
|
||||||
|
# 0398;GREEK CAPITAL LETTER THETA;Lu;0;L;;;;;N;;;;03B8
|
||||||
|
# 03B8;GREEK SMALL LETTER THETA;Ll;0;L;;;;;N;;;0398;;0398
|
||||||
|
# 03D1;GREEK THETA SYMBOL;Ll;0;L;<compat> 03B8;;;;N;GREEK SMALL LETTER SCRIPT THETA;;0398;;0398
|
||||||
|
# 03F4;GREEK CAPITAL THETA SYMBOL;Lu;0;L;<compat> 0398;;;;N;;;;03B8
|
||||||
|
#
|
||||||
|
# Case-insensitive comparison should treat all of them as equivalent.
|
||||||
|
#
|
||||||
|
# But .toLowerCase() doesn't change ϑ (it's already lowercase),
|
||||||
|
# and .toUpperCase() doesn't change ϴ (already uppercase).
|
||||||
|
#
|
||||||
|
# Applying first lower then upper case normalizes any character:
|
||||||
|
# '\u0398\u03f4\u03b8\u03d1'.toLowerCase().toUpperCase() === '\u0398\u0398\u0398\u0398'
|
||||||
|
#
|
||||||
|
# Note: this is equivalent to unicode case folding; unicode normalization
|
||||||
|
# is a different step that is not required here.
|
||||||
|
#
|
||||||
|
# Final result should be uppercased, because it's later stored in an object
|
||||||
|
# (this avoid a conflict with Object.prototype members,
|
||||||
|
# most notably, `__proto__`)
|
||||||
|
#
|
||||||
|
return string.lower().upper()
|
||||||
|
|
||||||
|
|
||||||
|
LINK_OPEN_RE = re.compile(r"^<a[>\s]", flags=re.IGNORECASE)
|
||||||
|
LINK_CLOSE_RE = re.compile(r"^</a\s*>", flags=re.IGNORECASE)
|
||||||
|
|
||||||
|
|
||||||
|
def isLinkOpen(string: str) -> bool:
|
||||||
|
return bool(LINK_OPEN_RE.search(string))
|
||||||
|
|
||||||
|
|
||||||
|
def isLinkClose(string: str) -> bool:
|
||||||
|
return bool(LINK_CLOSE_RE.search(string))
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
"""Functions for parsing Links
|
||||||
|
"""
|
||||||
|
__all__ = ("parseLinkLabel", "parseLinkDestination", "parseLinkTitle")
|
||||||
|
from .parse_link_destination import parseLinkDestination
|
||||||
|
from .parse_link_label import parseLinkLabel
|
||||||
|
from .parse_link_title import parseLinkTitle
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,86 @@
|
|||||||
|
"""
|
||||||
|
Parse link destination
|
||||||
|
"""
|
||||||
|
|
||||||
|
from ..common.utils import charCodeAt, unescapeAll
|
||||||
|
|
||||||
|
|
||||||
|
class _Result:
|
||||||
|
__slots__ = ("ok", "pos", "lines", "str")
|
||||||
|
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self.ok = False
|
||||||
|
self.pos = 0
|
||||||
|
self.lines = 0
|
||||||
|
self.str = ""
|
||||||
|
|
||||||
|
|
||||||
|
def parseLinkDestination(string: str, pos: int, maximum: int) -> _Result:
|
||||||
|
lines = 0
|
||||||
|
start = pos
|
||||||
|
result = _Result()
|
||||||
|
|
||||||
|
if charCodeAt(string, pos) == 0x3C: # /* < */
|
||||||
|
pos += 1
|
||||||
|
while pos < maximum:
|
||||||
|
code = charCodeAt(string, pos)
|
||||||
|
if code == 0x0A: # /* \n */)
|
||||||
|
return result
|
||||||
|
if code == 0x3C: # / * < * /
|
||||||
|
return result
|
||||||
|
if code == 0x3E: # /* > */) {
|
||||||
|
result.pos = pos + 1
|
||||||
|
result.str = unescapeAll(string[start + 1 : pos])
|
||||||
|
result.ok = True
|
||||||
|
return result
|
||||||
|
|
||||||
|
if code == 0x5C and pos + 1 < maximum: # \
|
||||||
|
pos += 2
|
||||||
|
continue
|
||||||
|
|
||||||
|
pos += 1
|
||||||
|
|
||||||
|
# no closing '>'
|
||||||
|
return result
|
||||||
|
|
||||||
|
# this should be ... } else { ... branch
|
||||||
|
|
||||||
|
level = 0
|
||||||
|
while pos < maximum:
|
||||||
|
code = charCodeAt(string, pos)
|
||||||
|
|
||||||
|
if code is None or code == 0x20:
|
||||||
|
break
|
||||||
|
|
||||||
|
# ascii control characters
|
||||||
|
if code < 0x20 or code == 0x7F:
|
||||||
|
break
|
||||||
|
|
||||||
|
if code == 0x5C and pos + 1 < maximum:
|
||||||
|
if charCodeAt(string, pos + 1) == 0x20:
|
||||||
|
break
|
||||||
|
pos += 2
|
||||||
|
continue
|
||||||
|
|
||||||
|
if code == 0x28: # /* ( */)
|
||||||
|
level += 1
|
||||||
|
if level > 32:
|
||||||
|
return result
|
||||||
|
|
||||||
|
if code == 0x29: # /* ) */)
|
||||||
|
if level == 0:
|
||||||
|
break
|
||||||
|
level -= 1
|
||||||
|
|
||||||
|
pos += 1
|
||||||
|
|
||||||
|
if start == pos:
|
||||||
|
return result
|
||||||
|
if level != 0:
|
||||||
|
return result
|
||||||
|
|
||||||
|
result.str = unescapeAll(string[start:pos])
|
||||||
|
result.lines = lines
|
||||||
|
result.pos = pos
|
||||||
|
result.ok = True
|
||||||
|
return result
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
"""
|
||||||
|
Parse link label
|
||||||
|
|
||||||
|
this function assumes that first character ("[") already matches
|
||||||
|
returns the end of the label
|
||||||
|
|
||||||
|
"""
|
||||||
|
from markdown_it.rules_inline import StateInline
|
||||||
|
|
||||||
|
|
||||||
|
def parseLinkLabel(state: StateInline, start: int, disableNested: bool = False) -> int:
|
||||||
|
labelEnd = -1
|
||||||
|
oldPos = state.pos
|
||||||
|
found = False
|
||||||
|
|
||||||
|
state.pos = start + 1
|
||||||
|
level = 1
|
||||||
|
|
||||||
|
while state.pos < state.posMax:
|
||||||
|
marker = state.src[state.pos]
|
||||||
|
if marker == "]":
|
||||||
|
level -= 1
|
||||||
|
if level == 0:
|
||||||
|
found = True
|
||||||
|
break
|
||||||
|
|
||||||
|
prevPos = state.pos
|
||||||
|
state.md.inline.skipToken(state)
|
||||||
|
if marker == "[":
|
||||||
|
if prevPos == state.pos - 1:
|
||||||
|
# increase level if we find text `[`,
|
||||||
|
# which is not a part of any token
|
||||||
|
level += 1
|
||||||
|
elif disableNested:
|
||||||
|
state.pos = oldPos
|
||||||
|
return -1
|
||||||
|
if found:
|
||||||
|
labelEnd = state.pos
|
||||||
|
|
||||||
|
# restore old state
|
||||||
|
state.pos = oldPos
|
||||||
|
|
||||||
|
return labelEnd
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
"""Parse link title
|
||||||
|
"""
|
||||||
|
from ..common.utils import charCodeAt, unescapeAll
|
||||||
|
|
||||||
|
|
||||||
|
class _Result:
|
||||||
|
__slots__ = ("ok", "pos", "lines", "str")
|
||||||
|
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self.ok = False
|
||||||
|
self.pos = 0
|
||||||
|
self.lines = 0
|
||||||
|
self.str = ""
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return self.str
|
||||||
|
|
||||||
|
|
||||||
|
def parseLinkTitle(string: str, pos: int, maximum: int) -> _Result:
|
||||||
|
lines = 0
|
||||||
|
start = pos
|
||||||
|
result = _Result()
|
||||||
|
|
||||||
|
if pos >= maximum:
|
||||||
|
return result
|
||||||
|
|
||||||
|
marker = charCodeAt(string, pos)
|
||||||
|
|
||||||
|
# /* " */ /* ' */ /* ( */
|
||||||
|
if marker != 0x22 and marker != 0x27 and marker != 0x28:
|
||||||
|
return result
|
||||||
|
|
||||||
|
pos += 1
|
||||||
|
|
||||||
|
# if opening marker is "(", switch it to closing marker ")"
|
||||||
|
if marker == 0x28:
|
||||||
|
marker = 0x29
|
||||||
|
|
||||||
|
while pos < maximum:
|
||||||
|
code = charCodeAt(string, pos)
|
||||||
|
if code == marker:
|
||||||
|
title = string[start + 1 : pos]
|
||||||
|
title = unescapeAll(title)
|
||||||
|
result.pos = pos + 1
|
||||||
|
result.lines = lines
|
||||||
|
result.str = title
|
||||||
|
result.ok = True
|
||||||
|
return result
|
||||||
|
elif code == 0x28 and marker == 0x29: # /* ( */ /* ) */
|
||||||
|
return result
|
||||||
|
elif code == 0x0A:
|
||||||
|
lines += 1
|
||||||
|
elif code == 0x5C and pos + 1 < maximum: # /* \ */
|
||||||
|
pos += 1
|
||||||
|
if charCodeAt(string, pos) == 0x0A:
|
||||||
|
lines += 1
|
||||||
|
|
||||||
|
pos += 1
|
||||||
|
|
||||||
|
return result
|
||||||
355
rclone/lib/python3.11/site-packages/markdown_it/main.py
Normal file
355
rclone/lib/python3.11/site-packages/markdown_it/main.py
Normal file
@@ -0,0 +1,355 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Callable, Generator, Iterable, Mapping, MutableMapping
|
||||||
|
from contextlib import contextmanager
|
||||||
|
from typing import Any, Literal, overload
|
||||||
|
|
||||||
|
from . import helpers, presets
|
||||||
|
from .common import normalize_url, utils
|
||||||
|
from .parser_block import ParserBlock
|
||||||
|
from .parser_core import ParserCore
|
||||||
|
from .parser_inline import ParserInline
|
||||||
|
from .renderer import RendererHTML, RendererProtocol
|
||||||
|
from .rules_core.state_core import StateCore
|
||||||
|
from .token import Token
|
||||||
|
from .utils import EnvType, OptionsDict, OptionsType, PresetType
|
||||||
|
|
||||||
|
try:
|
||||||
|
import linkify_it
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
linkify_it = None
|
||||||
|
|
||||||
|
|
||||||
|
_PRESETS: dict[str, PresetType] = {
|
||||||
|
"default": presets.default.make(),
|
||||||
|
"js-default": presets.js_default.make(),
|
||||||
|
"zero": presets.zero.make(),
|
||||||
|
"commonmark": presets.commonmark.make(),
|
||||||
|
"gfm-like": presets.gfm_like.make(),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class MarkdownIt:
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
config: str | PresetType = "commonmark",
|
||||||
|
options_update: Mapping[str, Any] | None = None,
|
||||||
|
*,
|
||||||
|
renderer_cls: Callable[[MarkdownIt], RendererProtocol] = RendererHTML,
|
||||||
|
):
|
||||||
|
"""Main parser class
|
||||||
|
|
||||||
|
:param config: name of configuration to load or a pre-defined dictionary
|
||||||
|
:param options_update: dictionary that will be merged into ``config["options"]``
|
||||||
|
:param renderer_cls: the class to load as the renderer:
|
||||||
|
``self.renderer = renderer_cls(self)
|
||||||
|
"""
|
||||||
|
# add modules
|
||||||
|
self.utils = utils
|
||||||
|
self.helpers = helpers
|
||||||
|
|
||||||
|
# initialise classes
|
||||||
|
self.inline = ParserInline()
|
||||||
|
self.block = ParserBlock()
|
||||||
|
self.core = ParserCore()
|
||||||
|
self.renderer = renderer_cls(self)
|
||||||
|
self.linkify = linkify_it.LinkifyIt() if linkify_it else None
|
||||||
|
|
||||||
|
# set the configuration
|
||||||
|
if options_update and not isinstance(options_update, Mapping):
|
||||||
|
# catch signature change where renderer_cls was not used as a key-word
|
||||||
|
raise TypeError(
|
||||||
|
f"options_update should be a mapping: {options_update}"
|
||||||
|
"\n(Perhaps you intended this to be the renderer_cls?)"
|
||||||
|
)
|
||||||
|
self.configure(config, options_update=options_update)
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"{self.__class__.__module__}.{self.__class__.__name__}()"
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def __getitem__(self, name: Literal["inline"]) -> ParserInline:
|
||||||
|
...
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def __getitem__(self, name: Literal["block"]) -> ParserBlock:
|
||||||
|
...
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def __getitem__(self, name: Literal["core"]) -> ParserCore:
|
||||||
|
...
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def __getitem__(self, name: Literal["renderer"]) -> RendererProtocol:
|
||||||
|
...
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def __getitem__(self, name: str) -> Any:
|
||||||
|
...
|
||||||
|
|
||||||
|
def __getitem__(self, name: str) -> Any:
|
||||||
|
return {
|
||||||
|
"inline": self.inline,
|
||||||
|
"block": self.block,
|
||||||
|
"core": self.core,
|
||||||
|
"renderer": self.renderer,
|
||||||
|
}[name]
|
||||||
|
|
||||||
|
def set(self, options: OptionsType) -> None:
|
||||||
|
"""Set parser options (in the same format as in constructor).
|
||||||
|
Probably, you will never need it, but you can change options after constructor call.
|
||||||
|
|
||||||
|
__Note:__ To achieve the best possible performance, don't modify a
|
||||||
|
`markdown-it` instance options on the fly. If you need multiple configurations
|
||||||
|
it's best to create multiple instances and initialize each with separate config.
|
||||||
|
"""
|
||||||
|
self.options = OptionsDict(options)
|
||||||
|
|
||||||
|
def configure(
|
||||||
|
self, presets: str | PresetType, options_update: Mapping[str, Any] | None = None
|
||||||
|
) -> MarkdownIt:
|
||||||
|
"""Batch load of all options and component settings.
|
||||||
|
This is an internal method, and you probably will not need it.
|
||||||
|
But if you will - see available presets and data structure
|
||||||
|
[here](https://github.com/markdown-it/markdown-it/tree/master/lib/presets)
|
||||||
|
|
||||||
|
We strongly recommend to use presets instead of direct config loads.
|
||||||
|
That will give better compatibility with next versions.
|
||||||
|
"""
|
||||||
|
if isinstance(presets, str):
|
||||||
|
if presets not in _PRESETS:
|
||||||
|
raise KeyError(f"Wrong `markdown-it` preset '{presets}', check name")
|
||||||
|
config = _PRESETS[presets]
|
||||||
|
else:
|
||||||
|
config = presets
|
||||||
|
|
||||||
|
if not config:
|
||||||
|
raise ValueError("Wrong `markdown-it` config, can't be empty")
|
||||||
|
|
||||||
|
options = config.get("options", {}) or {}
|
||||||
|
if options_update:
|
||||||
|
options = {**options, **options_update} # type: ignore
|
||||||
|
|
||||||
|
self.set(options) # type: ignore
|
||||||
|
|
||||||
|
if "components" in config:
|
||||||
|
for name, component in config["components"].items():
|
||||||
|
rules = component.get("rules", None)
|
||||||
|
if rules:
|
||||||
|
self[name].ruler.enableOnly(rules)
|
||||||
|
rules2 = component.get("rules2", None)
|
||||||
|
if rules2:
|
||||||
|
self[name].ruler2.enableOnly(rules2)
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
|
def get_all_rules(self) -> dict[str, list[str]]:
|
||||||
|
"""Return the names of all active rules."""
|
||||||
|
rules = {
|
||||||
|
chain: self[chain].ruler.get_all_rules()
|
||||||
|
for chain in ["core", "block", "inline"]
|
||||||
|
}
|
||||||
|
rules["inline2"] = self.inline.ruler2.get_all_rules()
|
||||||
|
return rules
|
||||||
|
|
||||||
|
def get_active_rules(self) -> dict[str, list[str]]:
|
||||||
|
"""Return the names of all active rules."""
|
||||||
|
rules = {
|
||||||
|
chain: self[chain].ruler.get_active_rules()
|
||||||
|
for chain in ["core", "block", "inline"]
|
||||||
|
}
|
||||||
|
rules["inline2"] = self.inline.ruler2.get_active_rules()
|
||||||
|
return rules
|
||||||
|
|
||||||
|
def enable(
|
||||||
|
self, names: str | Iterable[str], ignoreInvalid: bool = False
|
||||||
|
) -> MarkdownIt:
|
||||||
|
"""Enable list or rules. (chainable)
|
||||||
|
|
||||||
|
:param names: rule name or list of rule names to enable.
|
||||||
|
:param ignoreInvalid: set `true` to ignore errors when rule not found.
|
||||||
|
|
||||||
|
It will automatically find appropriate components,
|
||||||
|
containing rules with given names. If rule not found, and `ignoreInvalid`
|
||||||
|
not set - throws exception.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
md = MarkdownIt().enable(['sub', 'sup']).disable('smartquotes')
|
||||||
|
|
||||||
|
"""
|
||||||
|
result = []
|
||||||
|
|
||||||
|
if isinstance(names, str):
|
||||||
|
names = [names]
|
||||||
|
|
||||||
|
for chain in ["core", "block", "inline"]:
|
||||||
|
result.extend(self[chain].ruler.enable(names, True))
|
||||||
|
result.extend(self.inline.ruler2.enable(names, True))
|
||||||
|
|
||||||
|
missed = [name for name in names if name not in result]
|
||||||
|
if missed and not ignoreInvalid:
|
||||||
|
raise ValueError(f"MarkdownIt. Failed to enable unknown rule(s): {missed}")
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
|
def disable(
|
||||||
|
self, names: str | Iterable[str], ignoreInvalid: bool = False
|
||||||
|
) -> MarkdownIt:
|
||||||
|
"""The same as [[MarkdownIt.enable]], but turn specified rules off. (chainable)
|
||||||
|
|
||||||
|
:param names: rule name or list of rule names to disable.
|
||||||
|
:param ignoreInvalid: set `true` to ignore errors when rule not found.
|
||||||
|
|
||||||
|
"""
|
||||||
|
result = []
|
||||||
|
|
||||||
|
if isinstance(names, str):
|
||||||
|
names = [names]
|
||||||
|
|
||||||
|
for chain in ["core", "block", "inline"]:
|
||||||
|
result.extend(self[chain].ruler.disable(names, True))
|
||||||
|
result.extend(self.inline.ruler2.disable(names, True))
|
||||||
|
|
||||||
|
missed = [name for name in names if name not in result]
|
||||||
|
if missed and not ignoreInvalid:
|
||||||
|
raise ValueError(f"MarkdownIt. Failed to disable unknown rule(s): {missed}")
|
||||||
|
return self
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def reset_rules(self) -> Generator[None, None, None]:
|
||||||
|
"""A context manager, that will reset the current enabled rules on exit."""
|
||||||
|
chain_rules = self.get_active_rules()
|
||||||
|
yield
|
||||||
|
for chain, rules in chain_rules.items():
|
||||||
|
if chain != "inline2":
|
||||||
|
self[chain].ruler.enableOnly(rules)
|
||||||
|
self.inline.ruler2.enableOnly(chain_rules["inline2"])
|
||||||
|
|
||||||
|
def add_render_rule(
|
||||||
|
self, name: str, function: Callable[..., Any], fmt: str = "html"
|
||||||
|
) -> None:
|
||||||
|
"""Add a rule for rendering a particular Token type.
|
||||||
|
|
||||||
|
Only applied when ``renderer.__output__ == fmt``
|
||||||
|
"""
|
||||||
|
if self.renderer.__output__ == fmt:
|
||||||
|
self.renderer.rules[name] = function.__get__(self.renderer) # type: ignore
|
||||||
|
|
||||||
|
def use(
|
||||||
|
self, plugin: Callable[..., None], *params: Any, **options: Any
|
||||||
|
) -> MarkdownIt:
|
||||||
|
"""Load specified plugin with given params into current parser instance. (chainable)
|
||||||
|
|
||||||
|
It's just a sugar to call `plugin(md, params)` with curring.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
def func(tokens, idx):
|
||||||
|
tokens[idx].content = tokens[idx].content.replace('foo', 'bar')
|
||||||
|
md = MarkdownIt().use(plugin, 'foo_replace', 'text', func)
|
||||||
|
|
||||||
|
"""
|
||||||
|
plugin(self, *params, **options)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def parse(self, src: str, env: EnvType | None = None) -> list[Token]:
|
||||||
|
"""Parse the source string to a token stream
|
||||||
|
|
||||||
|
:param src: source string
|
||||||
|
:param env: environment sandbox
|
||||||
|
|
||||||
|
Parse input string and return list of block tokens (special token type
|
||||||
|
"inline" will contain list of inline tokens).
|
||||||
|
|
||||||
|
`env` is used to pass data between "distributed" rules and return additional
|
||||||
|
metadata like reference info, needed for the renderer. It also can be used to
|
||||||
|
inject data in specific cases. Usually, you will be ok to pass `{}`,
|
||||||
|
and then pass updated object to renderer.
|
||||||
|
"""
|
||||||
|
env = {} if env is None else env
|
||||||
|
if not isinstance(env, MutableMapping):
|
||||||
|
raise TypeError(f"Input data should be a MutableMapping, not {type(env)}")
|
||||||
|
if not isinstance(src, str):
|
||||||
|
raise TypeError(f"Input data should be a string, not {type(src)}")
|
||||||
|
state = StateCore(src, self, env)
|
||||||
|
self.core.process(state)
|
||||||
|
return state.tokens
|
||||||
|
|
||||||
|
def render(self, src: str, env: EnvType | None = None) -> Any:
|
||||||
|
"""Render markdown string into html. It does all magic for you :).
|
||||||
|
|
||||||
|
:param src: source string
|
||||||
|
:param env: environment sandbox
|
||||||
|
:returns: The output of the loaded renderer
|
||||||
|
|
||||||
|
`env` can be used to inject additional metadata (`{}` by default).
|
||||||
|
But you will not need it with high probability. See also comment
|
||||||
|
in [[MarkdownIt.parse]].
|
||||||
|
"""
|
||||||
|
env = {} if env is None else env
|
||||||
|
return self.renderer.render(self.parse(src, env), self.options, env)
|
||||||
|
|
||||||
|
def parseInline(self, src: str, env: EnvType | None = None) -> list[Token]:
|
||||||
|
"""The same as [[MarkdownIt.parse]] but skip all block rules.
|
||||||
|
|
||||||
|
:param src: source string
|
||||||
|
:param env: environment sandbox
|
||||||
|
|
||||||
|
It returns the
|
||||||
|
block tokens list with the single `inline` element, containing parsed inline
|
||||||
|
tokens in `children` property. Also updates `env` object.
|
||||||
|
"""
|
||||||
|
env = {} if env is None else env
|
||||||
|
if not isinstance(env, MutableMapping):
|
||||||
|
raise TypeError(f"Input data should be an MutableMapping, not {type(env)}")
|
||||||
|
if not isinstance(src, str):
|
||||||
|
raise TypeError(f"Input data should be a string, not {type(src)}")
|
||||||
|
state = StateCore(src, self, env)
|
||||||
|
state.inlineMode = True
|
||||||
|
self.core.process(state)
|
||||||
|
return state.tokens
|
||||||
|
|
||||||
|
def renderInline(self, src: str, env: EnvType | None = None) -> Any:
|
||||||
|
"""Similar to [[MarkdownIt.render]] but for single paragraph content.
|
||||||
|
|
||||||
|
:param src: source string
|
||||||
|
:param env: environment sandbox
|
||||||
|
|
||||||
|
Similar to [[MarkdownIt.render]] but for single paragraph content. Result
|
||||||
|
will NOT be wrapped into `<p>` tags.
|
||||||
|
"""
|
||||||
|
env = {} if env is None else env
|
||||||
|
return self.renderer.render(self.parseInline(src, env), self.options, env)
|
||||||
|
|
||||||
|
# link methods
|
||||||
|
|
||||||
|
def validateLink(self, url: str) -> bool:
|
||||||
|
"""Validate if the URL link is allowed in output.
|
||||||
|
|
||||||
|
This validator can prohibit more than really needed to prevent XSS.
|
||||||
|
It's a tradeoff to keep code simple and to be secure by default.
|
||||||
|
|
||||||
|
Note: the url should be normalized at this point, and existing entities decoded.
|
||||||
|
"""
|
||||||
|
return normalize_url.validateLink(url)
|
||||||
|
|
||||||
|
def normalizeLink(self, url: str) -> str:
|
||||||
|
"""Normalize destination URLs in links
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
[label]: destination 'title'
|
||||||
|
^^^^^^^^^^^
|
||||||
|
"""
|
||||||
|
return normalize_url.normalizeLink(url)
|
||||||
|
|
||||||
|
def normalizeLinkText(self, link: str) -> str:
|
||||||
|
"""Normalize autolink content
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
<destination>
|
||||||
|
~~~~~~~~~~~
|
||||||
|
"""
|
||||||
|
return normalize_url.normalizeLinkText(link)
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user