Refacere repo

This commit is contained in:
Ionel Andrei Cataon
2026-02-12 14:14:46 +02:00
parent 002d53928a
commit ad4a4cf8f6
1059 changed files with 193216 additions and 1 deletions

6
Bash_scripting/1st_script.sh Executable file
View File

@@ -0,0 +1,6 @@
#!/bin/bash
WORD="Hello world"
echo $WORD
echo $USER

17
Bash_scripting/autogit.sh Executable file
View File

@@ -0,0 +1,17 @@
#!/bin/bash
# Script to add all changes, commit with the message "updated", and push to repo.
git add .
# Check if there are changes to commit
if git diff-index --quiet HEAD --; then
echo "No changes to commit."
exit 0
fi
git commit -m "updated"
git push
echo "Changes committed and pushed successfully!"

78
Bash_scripting/myproject.sh Executable file
View File

@@ -0,0 +1,78 @@
#!/bin/bash
RED='\e[1;31m'
GREEN='\e[1;32m'
YELLOW='\e[1;33m'
BLUE='\e[1;34m'
NC='\e[0m'
user=$(whoami)
echo -e "Welcome, ${BLUE}$user${NC}. Please enjoy this short presentation! "
read -p "Please enter a number:" num
if ((num % 2 == 0))
then
echo "$num is even"
else
echo "$num is odd"
fi
attempts=3
for ((i = 0; i < 3; i++, --attempts))
do
read -p "You have $attempts attempts left to find the secret recipe, so please enter another number between 1 and 10: " num2
secret=1
if ((num2 == secret))
then
i=3
echo -e "${GREEN}You have found the secret recipe of Coca Cola!! ^_^${NC}"
else
echo -e "${YELLOW}You were so close to finding the secret recipe :(${NC}"
fi
done
echo -e "${BLUE}Let's try something else. Please answer with a *yes* or *no*.${NC}"
yes=0
no=1
for ((j = 0; j <= 2; ++j))
do
if ((j == 0))
then
read -p "Are there any fish with legs?: " Answer
if ((Answer == 0))
then
echo -e "${GREEN}Your answer is correct! Mudskippers are the champions of land-walking fish, but we also have the Lungfish, Walking Catfish, Sea Robins, Frogfish or Handifsh.${NC} Visit: https://factanimal.com/wp-content/uploads/2023/07/mudskipper-breathing.jpg"
else
echo -e "${RED}Your answer is not correct, but don't worry, you are not the only one :D.${NC} Visit: https://encrypted-tbn0.gstatic.com/licensed-image?q=tbn:ANd9GcR9laMdCqTkfxW005yPkIED-dHsWvq3IcjPToZi130LpKQVlS5JT9W6u-w2ZMCa7JdDPYXUoqwQKakceVaUotuOA6_RCZF1wSfl2Mvoau2PUKen-0U"
fi
elif ((j == 1))
then
read -p "Are there any animals with no toes?: " Answer
if ((Answer != 0))
then
echo -e "${GREEN}Your answer is correct! Horses are commonly known for having just a toe under their hooves, but one toe is still more than none!${NC} Visit: https://i.chzbgr.com/full/10509587456/h1B5A4D29/this-actually-is-my-first-rodeo"
else
echo -e "${RED}Your answer is not correct. There is no animal without any toes. Hooves are modified toenails covering the tips of toes.${NC} Visit: https://cdn.britannica.com/28/85428-050-40FEA973/Hoof-horse.jpg"
fi
else
read -p "Is the blue whale the heaviest animal on this planet?: " Answer
if ((Answer == 0))
then
echo -e "${GREEN}Your answer is correct! The second heaviest animal ever to have existed on Earth is the fin whale (Balaenoptera physalus), with some historical estimates reaching up to 130 tons.${NC} Visit: https://www.reddit.com/media?url=https%3A%2F%2Fexternal-preview.redd.it%2FU7IzglHNEVnaT_F58bDjHwB8WqMZDyRNeujcpLqP25s.jpg%3Fwidth%3D1080%26crop%3Dsmart%26auto%3Dwebp%26s%3Df77ae8f9652158dd102218fbb58e1bf665b5a1ab"
else
echo -e "${RED}Your answer is not correct. Blue whales are widely regarded as the heaviest animals to have ever existed on Earth, with recorded weights up to 190 - 200 tons.${NC} Visit: https://familylifetips.com/wp-content/uploads/2021/07/Whale-Meme-Whale-Hello-There-Family-Life-Tips-Magazine.jpg"
fi
fi
done

21
Bash_scripting/test.sh Executable file
View File

@@ -0,0 +1,21 @@
#!/bin/bash
user=$(whoami)
echo "outputul de la comanda whoami este: " $user
user="myuser"
echo "valoarea variabilei user este acum: " $user
echo "Ai introdus primul argument: $1"
echo "Ai introdus al doilea argument: $2"
VREME=("ploua" "innorat" "furtuna" "soare")
echo "Starea vremii este: $(VREME[0])"
echo "Starea vremii este: $(VREME[1])"
echo "Starea vremii este: $(VREME[2])"
echo "Starea vremii este: $(VREME[3])"
read nume
echo "Numele introus este: $nume"
read -p "Introdu un nume: " nume
echo "Numele introdus este: $nume"
echo "Numele introdus este: $(nume:-"Niciun nume introdus")"

27
Bash_scripting/updates.sh Executable file
View File

@@ -0,0 +1,27 @@
#!/bin/bash
release_file=/etc/os-release
logfile=/var/log/updater.log
errorlog=/var/log/updater_errors.log
check_exit_status() {
local status=$1
local command_name=$2
if [ $status -ne 0 ]
then
echo "An error occurred during $command_name, please check the $errorlog file."
exit 1
fi
}
if grep -q "Ubuntu" $release_file || grep -q "Debian" $release_file
then
# The host is Debian or Ubuntu
# Run the apt version of the command
sudo apt update 1>>$logfile 2>>$errorlog
check_exit_status $? "apt update"
sudo apt dist-upgrade -y 1>>$logfile 2>>$errorlog
check_exit_status $? "apt dist-upgrade"
echo "Update completed successfully!"
fi

39
Bash_scripting/updates2.sh Executable file
View File

@@ -0,0 +1,39 @@
#!/bin/bash
release_file=/etc/os-release
logfile=/var/log/updater.log
errorlog=/var/log/updater_errors.log
check_exit_status() {
local status=$?
local command_name=$1
if [ $status -ne 0 ]; then
echo "$(date): An error occurred during $command_name (exit code: $status). Check $errorlog." | tee -a $logfile
exit 1
fi
}
echo "$(date): Starting update process..." >> $logfile
if grep -q "Ubuntu" $release_file || grep -q "Debian" $release_file; then
apt update >> $logfile 2>> $errorlog
check_exit_status "apt update"
apt dist-upgrade -y >> $logfile 2>> $errorlog
check_exit_status "apt dist-upgrade"
apt autoremove -y >> $logfile 2>> $errorlog
check_exit_status "apt autoremove"
apt autoclean >> $logfile 2>> $errorlog
check_exit_status "apt autoclean"
echo "$(date): Update completed successfully!" | tee -a $logfile
# Optional: Check if reboot needed
if [ -f /var/run/reboot-required ]; then
echo "$(date): Reboot required for updates to take effect." | tee -a $logfile
fi
else
echo "This system is not Ubuntu or Debian-based. Exiting." | tee -a $logfile
exit 0
fi

20
Bash_scripting/while.sh Executable file
View File

@@ -0,0 +1,20 @@
#!/bin/bash
x=1
while (( $x < "10" ))
do
echo "Valoarea lui x este: $x"
x=$(( x+1 ))
done
ar=(11 15 86 23 45 78)
Lenght=${#ar[@]}
echo "Lungimea array-ului este: $lenght"
ar=(32 10 132 32 5 7 43 104)
i=0
lenght=${#ar[@]}
while [ $i -lt $lenght ];
do
echo "Elementul $i din array este: ${ar[$i]}"
i=$(( i+1))
done

View File

@@ -0,0 +1,8 @@
FROM nginx:alpine
COPY index.html /usr/share/nginx/html/
styles.css
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

View File

@@ -0,0 +1,16 @@
services:
jenkins:
container_name: my_jenkins_01
image: jenkins/jenkins:latest
environment:
TZ: "Europe/Bucharest"
ports:
- "60199:8080"
- "5000:5000"
volumes:
- "jenkins:/var/jenkins_home"
- "/var/run/docker.sock:/var/run/docker.sock"
restart: unless-stopped
volumes:
jenkins:

25
Jenkins_jobs/jenkinsfile Normal file
View File

@@ -0,0 +1,25 @@
pipeline {
agent any
stages {
stage ('scm checkout') {
steps {
checkout scm
}
}
stage ('primul job') {
steps {
sh 'pwd'
sh 'echo "Hello! Bine ai venit la It_School Jenkins startup!" > jenkins.txt'
sh 'ls -alh'
}
}
stage ('job doi') {
steps {
script {
def Age=21
echo "I have ${Age} years old"
}
}
}
}
}

5
Project/Dockerfile Normal file
View File

@@ -0,0 +1,5 @@
FROM nginx:1.29.4
WORKDIR /usr/share/nginx/html
COPY project.html index.html
EXPOSE 80

248
Project/project.html Normal file
View File

@@ -0,0 +1,248 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Professional Calculator</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.container {
background: white;
border-radius: 20px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
padding: 40px;
max-width: 600px;
width: 100%;
}
h1 {
text-align: center;
color: #667eea;
margin-bottom: 10px;
font-size: 2.5em;
}
.progress {
text-align: center;
color: #666;
margin-bottom: 30px;
font-size: 1.1em;
}
.equation-box {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 30px;
border-radius: 15px;
text-align: center;
margin-bottom: 30px;
}
.equation-box h2 {
font-size: 2.5em;
margin-bottom: 10px;
}
.input-group {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
#answer {
flex: 1;
padding: 15px;
font-size: 1.1em;
border: 2px solid #667eea;
border-radius: 10px;
outline: none;
transition: border-color 0.3s;
}
#answer:focus {
border-color: #764ba2;
}
button {
padding: 15px 30px;
font-size: 1.1em;
background: #667eea;
color: white;
border: none;
border-radius: 10px;
cursor: pointer;
transition: background 0.3s;
font-weight: bold;
}
button:hover {
background: #764ba2;
}
.feedback {
padding: 20px;
border-radius: 10px;
margin-bottom: 20px;
text-align: center;
font-size: 1.1em;
font-weight: bold;
min-height: 80px;
display: flex;
flex-direction: column;
justify-content: center;
}
.feedback.correct {
background: #d4edda;
color: #155724;
border: 2px solid #28a745;
}
.feedback.incorrect {
background: #f8d7da;
color: #721c24;
border: 2px solid #f5c6cb;
}
.fun-fact {
margin-top: 10px;
font-style: italic;
font-size: 0.95em;
opacity: 0.9;
}
.completion {
text-align: center;
padding: 30px;
background: linear-gradient(135deg, #28a745 0%, #20c997 100%);
color: white;
border-radius: 15px;
display: none;
}
.completion h2 {
font-size: 2em;
margin-bottom: 15px;
}
.completion button {
background: white;
color: #28a745;
margin-top: 20px;
}
.completion button:hover {
background: #f0f0f0;
}
</style>
</head>
<body>
<div class="container">
<h1>🧮 Professional Calculator</h1>
<div class="progress">Question <span id="current">1</span> of 10</div>
<div id="game">
<div class="equation-box">
<h2 id="equation"></h2>
</div>
<div id="feedback" class="feedback" style="display: none;"></div>
<div class="input-group">
<input type="number" id="answer" placeholder="Enter your answer" autocomplete="off">
<button onclick="checkAnswer()">Submit</button>
</div>
</div>
<div id="completion" class="completion">
<h2>🎉 Congratulations!</h2>
<p>You've completed all 10 equations!</p>
<button onclick="location.reload()">Play Again</button>
</div>
</div>
<script>
const equations = [
{ problem: '25 + 15', answer: 40, fact: '40 is the number of days and nights of the Great Flood in the Bible!' },
{ problem: '100 - 37', answer: 63, fact: '63 is the atomic number of Europium, a rare earth element!' },
{ problem: '12 × 6', answer: 72, fact: '72 is the number of virgins promised in Islamic tradition!' },
{ problem: '144 ÷ 12', answer: 12, fact: '12 is one of the most significant numbers - 12 months, 12 hours, 12 apostles!' },
{ problem: '7 × 8', answer: 56, fact: '56 is the number of playing cards in a standard deck plus jokers!' },
{ problem: '200 - 85', answer: 115, fact: '115 is the atomic number of Moscovium, a synthetic element!' },
{ problem: '9 × 9', answer: 81, fact: '81 is a perfect square - the fourth power of 3!' },
{ problem: '256 ÷ 4', answer: 64, fact: '64 is the number of squares on a chessboard!' },
{ problem: '50 + 50', answer: 100, fact: '100 is a perfect square and the base for our decimal system!' },
{ problem: '99 - 54', answer: 45, fact: '45 is a triangular number - the sum of 1+2+3+4+5+6+7+8+9!' }
];
let currentQuestion = 0;
const answerInput = document.getElementById('answer');
const feedbackDiv = document.getElementById('feedback');
function loadQuestion() {
const eq = equations[currentQuestion];
document.getElementById('equation').textContent = eq.problem + ' = ?';
document.getElementById('current').textContent = currentQuestion + 1;
answerInput.value = '';
answerInput.focus();
feedbackDiv.style.display = 'none';
}
function checkAnswer() {
const userAnswer = parseInt(answerInput.value);
const correctAnswer = equations[currentQuestion].answer;
if (isNaN(userAnswer)) {
feedbackDiv.className = 'feedback incorrect';
feedbackDiv.textContent = '⚠️ Please enter a valid number!';
feedbackDiv.style.display = 'flex';
return;
}
if (userAnswer === correctAnswer) {
feedbackDiv.className = 'feedback correct';
feedbackDiv.innerHTML = `✅ Correct!<div class="fun-fact">💡 ${equations[currentQuestion].fact}</div>`;
feedbackDiv.style.display = 'flex';
currentQuestion++;
if (currentQuestion < equations.length) {
setTimeout(loadQuestion, 3000);
} else {
setTimeout(showCompletion, 3000);
}
} else {
feedbackDiv.className = 'feedback incorrect';
feedbackDiv.textContent = '❌ Study some more! Try again.';
feedbackDiv.style.display = 'flex';
answerInput.value = '';
}
}
function showCompletion() {
document.getElementById('game').style.display = 'none';
document.getElementById('completion').style.display = 'block';
}
answerInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') checkAnswer();
});
loadQuestion();
</script>
</body>
</html>

View File

@@ -0,0 +1,6 @@
cd ~ && \
mkdir venv && \
cd venv && \
sudo apt install python3-venv -y && \
python3 -m venv it_school_python && \
source ~/venv/it_school_python/bin/activate

View File

@@ -0,0 +1,15 @@
#!/home/andrei/it_school/bin/python3
# declaram variabile
numar = 25
numar_2 = 30
suma = numar + numar_2
print("Hello, World! From It_school")
print("This is the first Python module. Va saluta Don'Python!")
print('hello world ' * 3)
print("variabila numar are valoarea:", numar)
print("variabila numar_2 are valoarea:", numar_2)
print("suma celor doua numere este:")
print(suma)
print("Afisam si varianta veche: suma celor doua numere este", suma)

View File

@@ -0,0 +1,5 @@
#!/home/andrei/it_school/bin/python3
varsta = input("Introduceti varsta dumneavoastra: ")
nume = input("Introduceti numele dumneavoastra: ")
print("Salut,", nume + "!", "Ai", varsta, "ani.")

View File

@@ -0,0 +1,22 @@
#!/home/andrei/it_school/bin/python3
text = "De aici incepe si aici se termina!!"
print(text)
print(text[0])
print(text[1])
print(text[2])
print(text[-1])
print(text[-2])
print(text[5:11])
x = "It School"
y = "Python"
print(x + y)
print(len(text))
print(find := text.find("incepe"))
print(replace := text.replace("si", "&"))
print(text.upper())
print(text.lower())
print(text.capitalize())
print(text.count("i"))

View File

@@ -0,0 +1,12 @@
#!/home/andrei/it_school/bin/python3
ListaNume = ["Ion", "Gigel", "Dorel", "Maria", "Ionut"]
print("Punem nume:", ListaNume [4])
print("Numarul de nume din lista este:", len(ListaNume))
print(ListaNume.count("Ion"))
ListaNume.insert(-1, ("Ion"))
print("Afisam lista de unme:", ListaNume)
ListaNume.reverse()
print("Afisam lista inversata:", ListaNume)
ListaNume.sort()
print("Afisam lista sortata:", ListaNume)

View File

@@ -0,0 +1,7 @@
#!/home/andrei/it_school/bin/python3
x = int(input("Introduceti un numar x: "))
if x > 5:
print("x este mai mare decat 5")
else:
print("x nu este mai mare decat 5")

View File

@@ -0,0 +1,7 @@
#!/home/andrei/it_school/bin/python3
x = int(input("Introduceti o varsta: "))
if ((x >= 0) and (x <= 18)):
print("Nu poti vota.")
else:
print("Poti vota.")

View File

@@ -0,0 +1,6 @@
#!/home/andrei/it_school/bin/python3
i = 1
while i <= 10:
print("Valoarea lui i este:", i)
i += 1

View File

@@ -0,0 +1,9 @@
#!/home/andrei/it_school/bin/python3
x = 0
while x < 10:
if x == 5:
print("Am ajuns la valoarea 5, iesim din bucla.")
break
print("Valoarea lui x este:", x)
x += 1

View File

@@ -0,0 +1,18 @@
#!/home/andrei/it_school/bin/python3
x = 0
while x < 10:
if x == 5:
print("Am ajuns la 5, iesim din bucla.")
break
print("Valoarea lui x este:", x)
x += 1
y = 0
while y < 10:
y += 1
if y == 2:
print("Sărim peste valoarea 2.")
continue
print("Valoarea lui y este:", y)
print("Am iesit din bucla.")

View File

@@ -0,0 +1,18 @@
#!/home/andrei/it_school/bin/python3
lista = [1, 43, 53, 67, 98]
for i in lista:
print(i)
for j in range(3):
print(j)
print("-----")
for v in range(1, 5):
print(v)
print("-----")
for z in range(0, 10, 3):
print(z)

View File

@@ -0,0 +1,23 @@
#!/home/andrei/it_school/bin/python3
T = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
print(T[0][0]) # 1
print(T[1][2]) # 6
print(T[2][1]) # 8
print("---")
for i in T:
print(i)
print("---")
for j in T:
for v in j:
print(v)
print("---")

View File

@@ -0,0 +1,19 @@
#!/home/andrei/it_school/bin/python3
Tuplu = ("apa","paine","suc","fructe")
for i in Tuplu:
print(i)
print("--------")
mytuples = {"brand", "model", "year"}
for j in mytuples:
print(j)
print("--------")
Mydictionary = { "cetatentie": "roman", "datanasterii": "1 Oct 1996", "inaltime": 190}
print(Mydictionary)
print("--------")
for key, value in Mydictionary.items():
print(key, ";", value)
print("--------")
print ("Cetatentia e:", Mydictionary["cetatentie"])
print ("Data nasterii e:", Mydictionary["datanasterii"])
print ("Inaltimea e:", Mydictionary["inaltime"])

View File

@@ -0,0 +1,22 @@
#!/home/andrei/it_school/bin/python3
def functie_test():
print("Aceasta este o functie de test")
def functie_nume(nume):
print("Numele meu este:", nume)
def adunare(a, b):
return a + b
# creeaza o functie care primeste ca parametrii o lista si vrem sa afiseze fiecare element din lista pe o linine noua
def afisare_lista(lista):
for element in lista:
print(element)
functie_test()
functie_nume("Andrei")
print("Suma este:", adunare(5, 7))
lista_de_test = [100, 200, 300, 400]
afisare_lista(lista_de_test)

View File

@@ -0,0 +1,15 @@
#!/home/andrei/it_school/bin/python3
mynumber = 3
mystring = "Salutare"
mylist = [10, 20, 30]
mytuple =("a", "b", "c",43,54)
mydictionary = {"nume":"Andrei", "varsta":43, "oras":"Bucuresti"}
bolean_var = True
print(type(mynumber))
print(type(mystring))
print(type(mylist))
print(type(mytuple))
print(type(mydictionary))
print(type(bolean_var))

View File

@@ -0,0 +1,12 @@
#!/home/andrei/it_school/bin/python3
import math
rezultat = math.sqrt(16)
print("Radical din 16 este:", rezultat)
print("Valoarea lui pi este:", math.pi)
rezultat_putere = math.pow(2, 5)
print("2 la puterea 5 este:", rezultat_putere)
print("Link catre match module: https://docs.python.org/3/library/math.html")

View File

@@ -0,0 +1,13 @@
#!/home/andrei/it_school/bin/python3
class Student:
def __init__(self, nume, varsta, nota):
self.nume = nume
self.varsta = varsta
self.nota = nota
def display_info(self):
print(f"Nume: {self.nume}, Varsta: {self.varsta}, Nota: {self.nota}")
student1 = Student("Andrei", 20, 9.5)
student1.display_info()

View File

@@ -0,0 +1,27 @@
#!/home/andrei/it_school/bin/python3
import os
import sys
def gestioneaza_fiesere(director):
# Verificam daca directorul exista
if os.path.exists(director):
print(f"Directorul '{director}' exista. Fisierele din acest director sunt:")
# Listam fisierele din director
for nume_fisier in os.listdir(director):
cale_fisier = os.path.join(director, nume_fisier)
if os.path.isfile(cale_fisier):
dimensiune_kb = os.path.getsize(cale_fisier) / 1024
print(f"- {nume_fisier} ({dimensiune_kb:.2f} KB)")
else:
print(f"Directorul '{nume_fisier}' nu este un fisier.")
else:
os.mkdir(director)
print(f"Directorul '{director}' nu exista. A fost creat.")
if __name__ == "__main__":
if len(sys.argv) > 1:
director_de_gestionat = sys.argv[1]
gestioneaza_fiesere(director_de_gestionat)
else:
print("Va rugam sa specficati un director ca argument la linia de comanda.")

24
Python_module_2/python_002.py Executable file
View File

@@ -0,0 +1,24 @@
#!/home/andrei/it_school/bin/python3
import sys
def main():
if len(sys.argv) < 4:
print("Eroare: Trebuie sa furnizati cel putin trei argumente numerice.")
numbers = []
for arg in sys.argv[1:]:
try:
num = float(arg)
numbers.append(num)
except ValueError:
print(f"Eroare: '{arg}' nu este un numar valid.")
return
total = sum(numbers)
average = total / len(numbers)
print(f"Suma: {total}")
print(f"Media: {average}")
if __name__ == "__main__":
main()

14
Python_module_2/python_003.py Executable file
View File

@@ -0,0 +1,14 @@
#!/home/andrei/it_school/bin/python3
import sys
import subprocess
def check_service_status(service_name):
try:
# Run the systemctl command to check the service status
result = subprocess.run(['systemctl', 'is-active', service_name], capture_output=True, text=True)
return result.stdout.strip() == 'active'
except Exception as e:
print(f"Error checking service status: {e}")
return False

View File

@@ -1 +1,7 @@
<<<<<<< HEAD
Fara modificari Fara modificari
=======
Asa functioneaza[develop 7f2020f] Changes
1 file changed, 10 insertions(+)
create mode 100644 myWorkspace
>>>>>>> c23a81d8e13da84a423b1a32ad9e7411675d5fba

View File

@@ -0,0 +1,22 @@
FROM ubuntu:24.04
RUN apt-get update && \
apt-get dist-upgrade -y && \
apt-get install -y \
net-tools \
vim \
ca-certificates \
iputils-ping \
iputils-tracepath \
iproute2 \
curl \
wget \
git \
telnet \
dnsutils
RUN useradd -ms /bin/bash netops
USER netops
WORKDIR /home/netops

17
autogit.sh Executable file
View File

@@ -0,0 +1,17 @@
#!/bin/bash
# Simple script to add all changes, commit with message "updated", and push
git add .
# Check if there are changes to commit
if git diff-index --quiet HEAD --; then
echo "No changes to commit."
exit 0
fi
git commit -m "updated"
git push
echo "Changes committed and pushed successfully!"

4
bandit.txt Normal file
View File

@@ -0,0 +1,4 @@
SSH info:
Host: bandit5@bandit.labs.overthewire.org
PW: 4oQYVPkxZOOEOO5pTW81FB8j8lxXGUQw

0
dockerUS/Dockerfile Normal file
View File

186
dockerUS/index.html Normal file
View File

@@ -0,0 +1,186 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>News - January 15, 2026</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
line-height: 1.6;
color: #333;
background-color: #f4f4f4;
}
header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 2rem 1rem;
text-align: center;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
header h1 {
font-size: 2.5rem;
margin-bottom: 0.5rem;
}
header p {
font-size: 1.1rem;
opacity: 0.9;
}
main {
max-width: 900px;
margin: 2rem auto;
padding: 0 1rem;
}
article {
background: white;
margin-bottom: 2rem;
padding: 1.5rem;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
article:hover {
transform: translateY(-5px);
box-shadow: 0 5px 15px rgba(0,0,0,0.15);
}
article h2 {
color: #667eea;
margin-bottom: 0.8rem;
font-size: 1.5rem;
}
article p {
color: #555;
margin-bottom: 1rem;
line-height: 1.8;
}
article a {
display: inline-block;
background-color: #667eea;
color: white;
padding: 0.6rem 1.2rem;
text-decoration: none;
border-radius: 4px;
transition: background-color 0.3s ease;
font-weight: 500;
}
article a:hover {
background-color: #764ba2;
}
footer {
background-color: #333;
color: white;
text-align: center;
padding: 2rem 1rem;
margin-top: 3rem;
}
footer p {
margin: 0.5rem 0;
}
@media (max-width: 768px) {
header h1 {
font-size: 1.8rem;
}
article {
padding: 1rem;
}
article h2 {
font-size: 1.2rem;
}
}
</style>
</head>
<body>
<header>
<h1>Daily News</h1>
<p>Top 10 Stories - January 15, 2026</p>
</header>
<main>
<article>
<h2>Global Climate Summit Reaches Historic Agreement</h2>
<p>World leaders have unanimously approved a groundbreaking climate accord aimed at accelerating carbon neutrality by 2040, marking a significant milestone in international environmental cooperation.</p>
<a href="#article1">Read More</a>
</article>
<article>
<h2>AI Breakthrough in Medical Diagnostics</h2>
<p>A new artificial intelligence system has demonstrated 99% accuracy in early cancer detection, promising to revolutionize medical screening processes worldwide.</p>
<a href="#article2">Read More</a>
</article>
<article>
<h2>Space Exploration: First Crewed Mars Base Operational</h2>
<p>The international space community celebrates as the first permanently inhabited base on Mars becomes fully operational with 12 astronauts from various nations.</p>
<a href="#article3">Read More</a>
</article>
<article>
<h2>Quantum Computing Milestone Achieved</h2>
<p>Researchers have successfully demonstrated the first practical quantum computer capable of solving real-world problems faster than classical supercomputers.</p>
<a href="#article4">Read More</a>
</article>
<article>
<h2>Global Economic Recovery Accelerates</h2>
<p>International markets show strong growth as emerging economies lead recovery efforts, with GDP growth exceeding predictions across all major regions.</p>
<a href="#article5">Read More</a>
</article>
<article>
<h2>Revolutionary Battery Technology Extends EV Range</h2>
<p>A new solid-state battery design allows electric vehicles to travel over 1000 miles on a single charge, accelerating global automotive transformation.</p>
<a href="#article6">Read More</a>
</article>
<article>
<h2>Breakthrough in Renewable Energy Storage</h2>
<p>Scientists announce a new method for storing renewable energy that is 40% more efficient than existing solutions, addressing the intermittency challenge.</p>
<a href="#article7">Read More</a>
</article>
<article>
<h2>Global Education Initiative Bridges Digital Divide</h2>
<p>A new international program provides free high-speed internet access to over 500 million students in underserved communities across 150 countries.</p>
<a href="#article8">Read More</a>
</article>
<article>
<h2>Major Disease Eradication Campaign Succeeds</h2>
<p>Public health officials announce the successful eradication of a major infectious disease, marking only the second disease to be completely eliminated in human history.</p>
<a href="#article9">Read More</a>
</article>
<article>
<h2>Sustainable Agriculture Transforms Food Production</h2>
<p>New agricultural techniques increase crop yields by 60% while reducing water consumption and environmental impact, offering solutions to global food security challenges.</p>
<a href="#article10">Read More</a>
</article>
</main>
<footer>
<p>&copy; 2026 Daily News. All rights reserved.</p>
<p>Contact us | Privacy Policy | Terms of Service</p>
</footer>
</body>
</html>

View File

@@ -0,0 +1,16 @@
services:
db:
image: mysql:8.4.4
container_name: mysql8_db
restart: always
command: --mysql_native_password=on
environment:
- TZ: "Europe/Bucharest"
- MYSQL_ROOT_PASSWORD: 5tUd3nT
db_editor:
image: phpmyadmin
container_name: phpmyadmin
restart: always
environment:
- TZ: "Europe/Bucharest"
- PMA_HOST: db

1
first_gitea Submodule

Submodule first_gitea added at c23a81d8e1

16
project1/checker.py Normal file
View File

@@ -0,0 +1,16 @@
import requests
import sys
def check_site(url):
try:
response = requests.get(url, timeout=5)
if response.status_code == 200:
print(f"✅ Succes! {url} este online.")
else:
print(f"⚠️ Atentie! {url} a raspuns cu status: {response.status_code}")
except Exception as e:
print(f"❌ Eroare: Nu am putut accesa {url}. Motiv: {e}")
sys.exit(1)
if __name__ == "__main__":
check_site("https://www.youtube.com/")

14
project1/dockerfile Normal file
View File

@@ -0,0 +1,14 @@
FROM python:3.11
# Setez directorul de lucru in container
WORKDIR /the/workdir/path
# Copiez fisierul de requirements in container
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copiez restul codului sursa in container
COPY checker.py .
# Comanda de rulare a aplicatiei
CMD ["python", "checker.py"]

30
project1/jenkinsfile Normal file
View File

@@ -0,0 +1,30 @@
pipeline {
agent any
stages {
stage('Checkout') {
steps {
// Jenkins va prelua codul sursă din depozitul Git
echo 'Se descarca codul...'
}
}
stage('Build Docker Image') {
steps {
script {
// Construim imaginea și îi dăm un nume (tag)
sh 'docker build -t web-checker-app .'
}
}
}
stage('Run Checker') {
steps {
script {
// Rulăm containerul
sh 'docker run --rm web-checker-app'
}
}
}
}
}

View File

@@ -0,0 +1 @@
requests==2.31.0

4
txt.md Normal file
View File

@@ -0,0 +1,4 @@
*Never back down, never what?!*
>>>
<<<

View 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"

View File

@@ -0,0 +1,70 @@
# 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
# Call hash to forget past commands. Without forgetting
# past commands the $PATH changes we made may not be respected
hash -r 2> /dev/null
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
# on Windows, a path can contain colons and backslashes and has to be converted:
if [ "${OSTYPE:-}" = "cygwin" ] || [ "${OSTYPE:-}" = "msys" ] ; then
# transform D:\path\to\venv to /d/path/to/venv on MSYS
# and to /cygdrive/d/path/to/venv on Cygwin
export VIRTUAL_ENV=$(cygpath /home/andrei/it_school/venv/it_school_python)
else
# use the path as-is
export VIRTUAL_ENV=/home/andrei/it_school/venv/it_school_python
fi
_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='(it_school_python) '"${PS1:-}"
export PS1
VIRTUAL_ENV_PROMPT='(it_school_python) '
export VIRTUAL_ENV_PROMPT
fi
# Call hash to forget past commands. Without forgetting
# past commands the $PATH changes we made may not be respected
hash -r 2> /dev/null

View File

@@ -0,0 +1,27 @@
# 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/andrei/it_school/venv/it_school_python
set _OLD_VIRTUAL_PATH="$PATH"
setenv PATH "$VIRTUAL_ENV/"bin":$PATH"
set _OLD_VIRTUAL_PROMPT="$prompt"
if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then
set prompt = '(it_school_python) '"$prompt"
setenv VIRTUAL_ENV_PROMPT '(it_school_python) '
endif
alias pydoc python -m pydoc
rehash

View 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/andrei/it_school/venv/it_school_python
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) '(it_school_python) ' (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 '(it_school_python) '
end

8
venv/it_school_python/bin/pip Executable file
View File

@@ -0,0 +1,8 @@
#!/home/andrei/it_school/venv/it_school_python/bin/python3
# -*- 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
venv/it_school_python/bin/pip3 Executable file
View File

@@ -0,0 +1,8 @@
#!/home/andrei/it_school/venv/it_school_python/bin/python3
# -*- 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())

View File

@@ -0,0 +1,8 @@
#!/home/andrei/it_school/venv/it_school_python/bin/python3
# -*- 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())

View File

@@ -0,0 +1 @@
python3

View File

@@ -0,0 +1 @@
/usr/bin/python3

View File

@@ -0,0 +1 @@
python3

View File

@@ -0,0 +1,760 @@
@Switch01
A_Rog
Aakanksha Agrawal
Abhinav Sagar
ABHYUDAY PRATAP SINGH
abs51295
AceGentile
Adam Chainz
Adam Tse
Adam Wentz
admin
Adrien Morison
ahayrapetyan
Ahilya
AinsworthK
Akash Srivastava
Alan Yee
Albert Tugushev
Albert-Guan
albertg
Alberto Sottile
Aleks Bunin
Ales Erjavec
Alethea Flowers
Alex Gaynor
Alex Grönholm
Alex Hedges
Alex Loosley
Alex Morega
Alex Stachowiak
Alexander Shtyrov
Alexandre Conrad
Alexey Popravka
Aleš Erjavec
Alli
Ami Fischman
Ananya Maiti
Anatoly Techtonik
Anders Kaseorg
Andre Aguiar
Andreas Lutro
Andrei Geacar
Andrew Gaul
Andrew Shymanel
Andrey Bienkowski
Andrey Bulgakov
Andrés Delfino
Andy Freeland
Andy Kluger
Ani Hayrapetyan
Aniruddha Basak
Anish Tambe
Anrs Hu
Anthony Sottile
Antoine Musso
Anton Ovchinnikov
Anton Patrushev
Antonio Alvarado Hernandez
Antony Lee
Antti Kaihola
Anubhav Patel
Anudit Nagar
Anuj Godase
AQNOUCH Mohammed
AraHaan
Arindam Choudhury
Armin Ronacher
Artem
Arun Babu Neelicattu
Ashley Manton
Ashwin Ramaswami
atse
Atsushi Odagiri
Avinash Karhana
Avner Cohen
Awit (Ah-Wit) Ghirmai
Baptiste Mispelon
Barney Gale
barneygale
Bartek Ogryczak
Bastian Venthur
Ben Bodenmiller
Ben Darnell
Ben Hoyt
Ben Mares
Ben Rosser
Bence Nagy
Benjamin Peterson
Benjamin VanEvery
Benoit Pierre
Berker Peksag
Bernard
Bernard Tyers
Bernardo B. Marques
Bernhard M. Wiedemann
Bertil Hatt
Bhavam Vidyarthi
Blazej Michalik
Bogdan Opanchuk
BorisZZZ
Brad Erickson
Bradley Ayers
Brandon L. Reiss
Brandt Bucher
Brett Randall
Brett Rosen
Brian Cristante
Brian Rosner
briantracy
BrownTruck
Bruno Oliveira
Bruno Renié
Bruno S
Bstrdsmkr
Buck Golemon
burrows
Bussonnier Matthias
bwoodsend
c22
Caleb Martinez
Calvin Smith
Carl Meyer
Carlos Liam
Carol Willing
Carter Thayer
Cass
Chandrasekhar Atina
Chih-Hsuan Yen
Chris Brinker
Chris Hunt
Chris Jerdonek
Chris Kuehl
Chris McDonough
Chris Pawley
Chris Pryer
Chris Wolfe
Christian Clauss
Christian Heimes
Christian Oudard
Christoph Reiter
Christopher Hunt
Christopher Snyder
cjc7373
Clark Boylan
Claudio Jolowicz
Clay McClure
Cody
Cody Soyland
Colin Watson
Collin Anderson
Connor Osborn
Cooper Lees
Cooper Ry Lees
Cory Benfield
Cory Wright
Craig Kerstiens
Cristian Sorinel
Cristina
Cristina Muñoz
Curtis Doty
cytolentino
Daan De Meyer
Dale
Damian
Damian Quiroga
Damian Shaw
Dan Black
Dan Savilonis
Dan Sully
Dane Hillard
daniel
Daniel Collins
Daniel Hahler
Daniel Holth
Daniel Jost
Daniel Katz
Daniel Shaulov
Daniele Esposti
Daniele Nicolodi
Daniele Procida
Daniil Konovalenko
Danny Hermes
Danny McClanahan
Darren Kavanagh
Dav Clark
Dave Abrahams
Dave Jones
David Aguilar
David Black
David Bordeynik
David Caro
David D Lowe
David Evans
David Hewitt
David Linke
David Poggi
David Pursehouse
David Runge
David Tucker
David Wales
Davidovich
ddelange
Deepak Sharma
Deepyaman Datta
Denise Yu
dependabot[bot]
derwolfe
Desetude
Devesh Kumar Singh
Diego Caraballo
Diego Ramirez
DiegoCaraballo
Dimitri Merejkowsky
Dimitri Papadopoulos
Dirk Stolle
Dmitry Gladkov
Dmitry Volodin
Domen Kožar
Dominic Davis-Foster
Donald Stufft
Dongweiming
doron zarhi
Dos Moonen
Douglas Thor
DrFeathers
Dustin Ingram
Dwayne Bailey
Ed Morley
Edgar Ramírez
Edgar Ramírez Mondragón
Ee Durbin
Efflam Lemaillet
efflamlemaillet
Eitan Adler
ekristina
elainechan
Eli Schwartz
Elisha Hollander
Ellen Marie Dash
Emil Burzo
Emil Styrke
Emmanuel Arias
Endoh Takanao
enoch
Erdinc Mutlu
Eric Cousineau
Eric Gillingham
Eric Hanchrow
Eric Hopper
Erik M. Bray
Erik Rose
Erwin Janssen
Eugene Vereshchagin
everdimension
Federico
Felipe Peter
Felix Yan
fiber-space
Filip Kokosiński
Filipe Laíns
Finn Womack
finnagin
Flavio Amurrio
Florian Briand
Florian Rathgeber
Francesco
Francesco Montesano
Frost Ming
Gabriel Curio
Gabriel de Perthuis
Garry Polley
gavin
gdanielson
Geoffrey Sneddon
George Song
Georgi Valkov
Georgy Pchelkin
ghost
Giftlin Rajaiah
gizmoguy1
gkdoc
Godefroid Chapelle
Gopinath M
GOTO Hayato
gousaiyang
gpiks
Greg Roodt
Greg Ward
Guilherme Espada
Guillaume Seguin
gutsytechster
Guy Rozendorn
Guy Tuval
gzpan123
Hanjun Kim
Hari Charan
Harsh Vardhan
harupy
Harutaka Kawamura
hauntsaninja
Henrich Hartzer
Henry Schreiner
Herbert Pfennig
Holly Stotelmyer
Honnix
Hsiaoming Yang
Hugo Lopes Tavares
Hugo van Kemenade
Hugues Bruant
Hynek Schlawack
Ian Bicking
Ian Cordasco
Ian Lee
Ian Stapleton Cordasco
Ian Wienand
Igor Kuzmitshov
Igor Sobreira
Ilan Schnell
Illia Volochii
Ilya Baryshev
Inada Naoki
Ionel Cristian Mărieș
Ionel Maries Cristian
Itamar Turner-Trauring
Ivan Pozdeev
J. Nick Koston
Jacob Kim
Jacob Walls
Jaime Sanz
jakirkham
Jakub Kuczys
Jakub Stasiak
Jakub Vysoky
Jakub Wilk
James Cleveland
James Curtin
James Firth
James Gerity
James Polley
Jan Pokorný
Jannis Leidel
Jarek Potiuk
jarondl
Jason Curtis
Jason R. Coombs
JasonMo
JasonMo1
Jay Graves
Jean Abou Samra
Jean-Christophe Fillion-Robin
Jeff Barber
Jeff Dairiki
Jeff Widman
Jelmer Vernooij
jenix21
Jeremy Stanley
Jeremy Zafran
Jesse Rittner
Jiashuo Li
Jim Fisher
Jim Garrison
Jiun Bae
Jivan Amara
Joe Bylund
Joe Michelini
John Paton
John T. Wodder II
John-Scott Atlakson
johnthagen
Jon Banafato
Jon Dufresne
Jon Parise
Jonas Nockert
Jonathan Herbert
Joonatan Partanen
Joost Molenaar
Jorge Niedbalski
Joseph Bylund
Joseph Long
Josh Bronson
Josh Hansen
Josh Schneier
Joshua
Juan Luis Cano Rodríguez
Juanjo Bazán
Judah Rand
Julian Berman
Julian Gethmann
Julien Demoor
Jussi Kukkonen
jwg4
Jyrki Pulliainen
Kai Chen
Kai Mueller
Kamal Bin Mustafa
kasium
kaustav haldar
keanemind
Keith Maxwell
Kelsey Hightower
Kenneth Belitzky
Kenneth Reitz
Kevin Burke
Kevin Carter
Kevin Frommelt
Kevin R Patterson
Kexuan Sun
Kit Randel
Klaas van Schelven
KOLANICH
kpinc
Krishna Oza
Kumar McMillan
Kurt McKee
Kyle Persohn
lakshmanaram
Laszlo Kiss-Kollar
Laurent Bristiel
Laurent LAPORTE
Laurie O
Laurie Opperman
layday
Leon Sasson
Lev Givon
Lincoln de Sousa
Lipis
lorddavidiii
Loren Carvalho
Lucas Cimon
Ludovic Gasc
Lukas Geiger
Lukas Juhrich
Luke Macken
Luo Jiebin
luojiebin
luz.paz
László Kiss Kollár
M00nL1ght
Marc Abramowitz
Marc Tamlyn
Marcus Smith
Mariatta
Mark Kohler
Mark Williams
Markus Hametner
Martey Dodoo
Martin Fischer
Martin Häcker
Martin Pavlasek
Masaki
Masklinn
Matej Stuchlik
Mathew Jennings
Mathieu Bridon
Mathieu Kniewallner
Matt Bacchi
Matt Good
Matt Maker
Matt Robenolt
matthew
Matthew Einhorn
Matthew Feickert
Matthew Gilliard
Matthew Iversen
Matthew Treinish
Matthew Trumbell
Matthew Willson
Matthias Bussonnier
mattip
Maurits van Rees
Max W Chase
Maxim Kurnikov
Maxime Rouyrre
mayeut
mbaluna
mdebi
memoselyk
meowmeowcat
Michael
Michael Aquilina
Michael E. Karpeles
Michael Klich
Michael Mintz
Michael Williamson
michaelpacer
Michał Górny
Mickaël Schoentgen
Miguel Araujo Perez
Mihir Singh
Mike
Mike Hendricks
Min RK
MinRK
Miro Hrončok
Monica Baluna
montefra
Monty Taylor
Muha Ajjan
Nadav Wexler
Nahuel Ambrosini
Nate Coraor
Nate Prewitt
Nathan Houghton
Nathaniel J. Smith
Nehal J Wani
Neil Botelho
Nguyễn Gia Phong
Nicholas Serra
Nick Coghlan
Nick Stenning
Nick Timkovich
Nicolas Bock
Nicole Harris
Nikhil Benesch
Nikhil Ladha
Nikita Chepanov
Nikolay Korolev
Nipunn Koorapati
Nitesh Sharma
Niyas Sait
Noah
Noah Gorny
Nowell Strite
NtaleGrey
nvdv
OBITORASU
Ofek Lev
ofrinevo
Oliver Freund
Oliver Jeeves
Oliver Mannion
Oliver Tonnhofer
Olivier Girardot
Olivier Grisel
Ollie Rutherfurd
OMOTO Kenji
Omry Yadan
onlinejudge95
Oren Held
Oscar Benjamin
Oz N Tiram
Pachwenko
Patrick Dubroy
Patrick Jenkins
Patrick Lawson
patricktokeeffe
Patrik Kopkan
Paul Ganssle
Paul Kehrer
Paul Moore
Paul Nasrat
Paul Oswald
Paul van der Linden
Paulus Schoutsen
Pavel Safronov
Pavithra Eswaramoorthy
Pawel Jasinski
Paweł Szramowski
Pekka Klärck
Peter Gessler
Peter Lisák
Peter Waller
petr-tik
Phaneendra Chiruvella
Phil Elson
Phil Freo
Phil Pennock
Phil Whelan
Philip Jägenstedt
Philip Molloy
Philippe Ombredanne
Pi Delport
Pierre-Yves Rofes
Pieter Degroote
pip
Prabakaran Kumaresshan
Prabhjyotsing Surjit Singh Sodhi
Prabhu Marappan
Pradyun Gedam
Prashant Sharma
Pratik Mallya
pre-commit-ci[bot]
Preet Thakkar
Preston Holmes
Przemek Wrzos
Pulkit Goyal
q0w
Qiangning Hong
Qiming Xu
Quentin Lee
Quentin Pradet
R. David Murray
Rafael Caricio
Ralf Schmitt
Razzi Abuissa
rdb
Reece Dunham
Remi Rampin
Rene Dudfield
Riccardo Magliocchetti
Riccardo Schirone
Richard Jones
Richard Si
Ricky Ng-Adam
Rishi
RobberPhex
Robert Collins
Robert McGibbon
Robert Pollak
Robert T. McGibbon
robin elisha robinson
Roey Berman
Rohan Jain
Roman Bogorodskiy
Roman Donchenko
Romuald Brunet
ronaudinho
Ronny Pfannschmidt
Rory McCann
Ross Brattain
Roy Wellington Ⅳ
Ruairidh MacLeod
Russell Keith-Magee
Ryan Shepherd
Ryan Wooden
ryneeverett
Sachi King
Salvatore Rinchiera
sandeepkiran-js
Sander Van Balen
Savio Jomton
schlamar
Scott Kitterman
Sean
seanj
Sebastian Jordan
Sebastian Schaetz
Segev Finer
SeongSoo Cho
Sergey Vasilyev
Seth Michael Larson
Seth Woodworth
Shahar Epstein
Shantanu
shireenrao
Shivansh-007
Shlomi Fish
Shovan Maity
Simeon Visser
Simon Cross
Simon Pichugin
sinoroc
sinscary
snook92
socketubs
Sorin Sbarnea
Srinivas Nyayapati
Stavros Korokithakis
Stefan Scherfke
Stefano Rivera
Stephan Erb
Stephen Rosen
stepshal
Steve (Gadget) Barnes
Steve Barnes
Steve Dower
Steve Kowalik
Steven Myint
Steven Silvester
stonebig
studioj
Stéphane Bidoul
Stéphane Bidoul (ACSONE)
Stéphane Klein
Sumana Harihareswara
Surbhi Sharma
Sviatoslav Sydorenko
Swat009
Sylvain
Takayuki SHIMIZUKAWA
Taneli Hukkinen
tbeswick
Thiago
Thijs Triemstra
Thomas Fenzl
Thomas Grainger
Thomas Guettler
Thomas Johansson
Thomas Kluyver
Thomas Smith
Thomas VINCENT
Tim D. Smith
Tim Gates
Tim Harder
Tim Heap
tim smith
tinruufu
Tobias Hermann
Tom Forbes
Tom Freudenheim
Tom V
Tomas Hrnciar
Tomas Orsava
Tomer Chachamu
Tommi Enenkel | AnB
Tomáš Hrnčiar
Tony Beswick
Tony Narlock
Tony Zhaocheng Tan
TonyBeswick
toonarmycaptain
Toshio Kuratomi
toxinu
Travis Swicegood
Tushar Sadhwani
Tzu-ping Chung
Valentin Haenel
Victor Stinner
victorvpaulo
Vikram - Google
Viktor Szépe
Ville Skyttä
Vinay Sajip
Vincent Philippon
Vinicyus Macedo
Vipul Kumar
Vitaly Babiy
Vladimir Fokow
Vladimir Rutsky
W. Trevor King
Wil Tan
Wilfred Hughes
William Edwards
William ML Leslie
William T Olson
William Woodruff
Wilson Mo
wim glenn
Winson Luk
Wolfgang Maier
Wu Zhenyu
XAMES3
Xavier Fernandez
xoviat
xtreak
YAMAMOTO Takashi
Yen Chi Hsuan
Yeray Diaz Diaz
Yoval P
Yu Jian
Yuan Jing Vincent Yan
Yusuke Hayashi
Zearin
Zhiping Deng
ziebam
Zvezdan Petkovic
Łukasz Langa
Роман Донченко
Семён Марьясин
rekcäH nitraM

View File

@@ -0,0 +1,20 @@
Copyright (c) 2008-present The pip developers (see AUTHORS.txt file)
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.

View File

@@ -0,0 +1,88 @@
Metadata-Version: 2.1
Name: pip
Version: 24.0
Summary: The PyPA recommended tool for installing Python packages.
Author-email: The pip developers <distutils-sig@python.org>
License: MIT
Project-URL: Homepage, https://pip.pypa.io/
Project-URL: Documentation, https://pip.pypa.io
Project-URL: Source, https://github.com/pypa/pip
Project-URL: Changelog, https://pip.pypa.io/en/stable/news/
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Topic :: Software Development :: Build Tools
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Requires-Python: >=3.7
Description-Content-Type: text/x-rst
License-File: LICENSE.txt
License-File: AUTHORS.txt
pip - The Python Package Installer
==================================
.. image:: https://img.shields.io/pypi/v/pip.svg
:target: https://pypi.org/project/pip/
:alt: PyPI
.. image:: https://img.shields.io/pypi/pyversions/pip
:target: https://pypi.org/project/pip
:alt: PyPI - Python Version
.. image:: https://readthedocs.org/projects/pip/badge/?version=latest
:target: https://pip.pypa.io/en/latest
:alt: Documentation
pip is the `package installer`_ for Python. You can use pip to install packages from the `Python Package Index`_ and other indexes.
Please take a look at our documentation for how to install and use pip:
* `Installation`_
* `Usage`_
We release updates regularly, with a new version every 3 months. Find more details in our documentation:
* `Release notes`_
* `Release process`_
If you find bugs, need help, or want to talk to the developers, please use our mailing lists or chat rooms:
* `Issue tracking`_
* `Discourse channel`_
* `User IRC`_
If you want to get involved head over to GitHub to get the source code, look at our development documentation and feel free to jump on the developer mailing lists and chat rooms:
* `GitHub page`_
* `Development documentation`_
* `Development IRC`_
Code of Conduct
---------------
Everyone interacting in the pip project's codebases, issue trackers, chat
rooms, and mailing lists is expected to follow the `PSF Code of Conduct`_.
.. _package installer: https://packaging.python.org/guides/tool-recommendations/
.. _Python Package Index: https://pypi.org
.. _Installation: https://pip.pypa.io/en/stable/installation/
.. _Usage: https://pip.pypa.io/en/stable/
.. _Release notes: https://pip.pypa.io/en/stable/news.html
.. _Release process: https://pip.pypa.io/en/latest/development/release-process/
.. _GitHub page: https://github.com/pypa/pip
.. _Development documentation: https://pip.pypa.io/en/latest/development
.. _Issue tracking: https://github.com/pypa/pip/issues
.. _Discourse channel: https://discuss.python.org/c/packaging
.. _User IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa
.. _Development IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa-dev
.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,5 @@
Wheel-Version: 1.0
Generator: bdist_wheel (0.42.0)
Root-Is-Purelib: true
Tag: py3-none-any

View File

@@ -0,0 +1,4 @@
[console_scripts]
pip = pip._internal.cli.main:main
pip3 = pip._internal.cli.main:main
pip3.12 = pip._internal.cli.main:main

View File

@@ -0,0 +1,13 @@
from typing import List, Optional
__version__ = "24.0"
def main(args: Optional[List[str]] = None) -> int:
"""This is an internal API only meant for use by pip's own console scripts.
For additional details, see https://github.com/pypa/pip/issues/7498.
"""
from pip._internal.utils.entrypoints import _wrapper
return _wrapper(args)

View File

@@ -0,0 +1,24 @@
import os
import sys
# Remove '' and current working directory from the first entry
# of sys.path, if present to avoid using current directory
# in pip commands check, freeze, install, list and show,
# when invoked as python -m pip <command>
if sys.path[0] in ("", os.getcwd()):
sys.path.pop(0)
# If we are running from a wheel, add the wheel to sys.path
# This allows the usage python pip-*.whl/pip install pip-*.whl
if __package__ == "":
# __file__ is pip-*.whl/pip/__main__.py
# first dirname call strips of '/__main__.py', second strips off '/pip'
# Resulting path is the name of the wheel itself
# Add that to sys.path so we can import pip
path = os.path.dirname(os.path.dirname(__file__))
sys.path.insert(0, path)
if __name__ == "__main__":
from pip._internal.cli.main import main as _main
sys.exit(_main())

View File

@@ -0,0 +1,50 @@
"""Execute exactly this copy of pip, within a different environment.
This file is named as it is, to ensure that this module can't be imported via
an import statement.
"""
# /!\ This version compatibility check section must be Python 2 compatible. /!\
import sys
# Copied from setup.py
PYTHON_REQUIRES = (3, 7)
def version_str(version): # type: ignore
return ".".join(str(v) for v in version)
if sys.version_info[:2] < PYTHON_REQUIRES:
raise SystemExit(
"This version of pip does not support python {} (requires >={}).".format(
version_str(sys.version_info[:2]), version_str(PYTHON_REQUIRES)
)
)
# From here on, we can use Python 3 features, but the syntax must remain
# Python 2 compatible.
import runpy # noqa: E402
from importlib.machinery import PathFinder # noqa: E402
from os.path import dirname # noqa: E402
PIP_SOURCES_ROOT = dirname(dirname(__file__))
class PipImportRedirectingFinder:
@classmethod
def find_spec(self, fullname, path=None, target=None): # type: ignore
if fullname != "pip":
return None
spec = PathFinder.find_spec(fullname, [PIP_SOURCES_ROOT], target)
assert spec, (PIP_SOURCES_ROOT, fullname)
return spec
sys.meta_path.insert(0, PipImportRedirectingFinder())
assert __name__ == "__main__", "Cannot run __pip-runner__.py as a non-main module"
runpy.run_module("pip", run_name="__main__", alter_sys=True)

View File

@@ -0,0 +1,18 @@
from typing import List, Optional
from pip._internal.utils import _log
# init_logging() must be called before any call to logging.getLogger()
# which happens at import of most modules.
_log.init_logging()
def main(args: (Optional[List[str]]) = None) -> int:
"""This is preserved for old console scripts that may still be referencing
it.
For additional details, see https://github.com/pypa/pip/issues/7498.
"""
from pip._internal.utils.entrypoints import _wrapper
return _wrapper(args)

View File

@@ -0,0 +1,311 @@
"""Build Environment used for isolation during sdist building
"""
import logging
import os
import pathlib
import site
import sys
import textwrap
from collections import OrderedDict
from types import TracebackType
from typing import TYPE_CHECKING, Iterable, List, Optional, Set, Tuple, Type, Union
from pip._vendor.certifi import where
from pip._vendor.packaging.requirements import Requirement
from pip._vendor.packaging.version import Version
from pip import __file__ as pip_location
from pip._internal.cli.spinners import open_spinner
from pip._internal.locations import get_platlib, get_purelib, get_scheme
from pip._internal.metadata import get_default_environment, get_environment
from pip._internal.utils.subprocess import call_subprocess
from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds
if TYPE_CHECKING:
from pip._internal.index.package_finder import PackageFinder
logger = logging.getLogger(__name__)
def _dedup(a: str, b: str) -> Union[Tuple[str], Tuple[str, str]]:
return (a, b) if a != b else (a,)
class _Prefix:
def __init__(self, path: str) -> None:
self.path = path
self.setup = False
scheme = get_scheme("", prefix=path)
self.bin_dir = scheme.scripts
self.lib_dirs = _dedup(scheme.purelib, scheme.platlib)
def get_runnable_pip() -> str:
"""Get a file to pass to a Python executable, to run the currently-running pip.
This is used to run a pip subprocess, for installing requirements into the build
environment.
"""
source = pathlib.Path(pip_location).resolve().parent
if not source.is_dir():
# This would happen if someone is using pip from inside a zip file. In that
# case, we can use that directly.
return str(source)
return os.fsdecode(source / "__pip-runner__.py")
def _get_system_sitepackages() -> Set[str]:
"""Get system site packages
Usually from site.getsitepackages,
but fallback on `get_purelib()/get_platlib()` if unavailable
(e.g. in a virtualenv created by virtualenv<20)
Returns normalized set of strings.
"""
if hasattr(site, "getsitepackages"):
system_sites = site.getsitepackages()
else:
# virtualenv < 20 overwrites site.py without getsitepackages
# fallback on get_purelib/get_platlib.
# this is known to miss things, but shouldn't in the cases
# where getsitepackages() has been removed (inside a virtualenv)
system_sites = [get_purelib(), get_platlib()]
return {os.path.normcase(path) for path in system_sites}
class BuildEnvironment:
"""Creates and manages an isolated environment to install build deps"""
def __init__(self) -> None:
temp_dir = TempDirectory(kind=tempdir_kinds.BUILD_ENV, globally_managed=True)
self._prefixes = OrderedDict(
(name, _Prefix(os.path.join(temp_dir.path, name)))
for name in ("normal", "overlay")
)
self._bin_dirs: List[str] = []
self._lib_dirs: List[str] = []
for prefix in reversed(list(self._prefixes.values())):
self._bin_dirs.append(prefix.bin_dir)
self._lib_dirs.extend(prefix.lib_dirs)
# Customize site to:
# - ensure .pth files are honored
# - prevent access to system site packages
system_sites = _get_system_sitepackages()
self._site_dir = os.path.join(temp_dir.path, "site")
if not os.path.exists(self._site_dir):
os.mkdir(self._site_dir)
with open(
os.path.join(self._site_dir, "sitecustomize.py"), "w", encoding="utf-8"
) as fp:
fp.write(
textwrap.dedent(
"""
import os, site, sys
# First, drop system-sites related paths.
original_sys_path = sys.path[:]
known_paths = set()
for path in {system_sites!r}:
site.addsitedir(path, known_paths=known_paths)
system_paths = set(
os.path.normcase(path)
for path in sys.path[len(original_sys_path):]
)
original_sys_path = [
path for path in original_sys_path
if os.path.normcase(path) not in system_paths
]
sys.path = original_sys_path
# Second, add lib directories.
# ensuring .pth file are processed.
for path in {lib_dirs!r}:
assert not path in sys.path
site.addsitedir(path)
"""
).format(system_sites=system_sites, lib_dirs=self._lib_dirs)
)
def __enter__(self) -> None:
self._save_env = {
name: os.environ.get(name, None)
for name in ("PATH", "PYTHONNOUSERSITE", "PYTHONPATH")
}
path = self._bin_dirs[:]
old_path = self._save_env["PATH"]
if old_path:
path.extend(old_path.split(os.pathsep))
pythonpath = [self._site_dir]
os.environ.update(
{
"PATH": os.pathsep.join(path),
"PYTHONNOUSERSITE": "1",
"PYTHONPATH": os.pathsep.join(pythonpath),
}
)
def __exit__(
self,
exc_type: Optional[Type[BaseException]],
exc_val: Optional[BaseException],
exc_tb: Optional[TracebackType],
) -> None:
for varname, old_value in self._save_env.items():
if old_value is None:
os.environ.pop(varname, None)
else:
os.environ[varname] = old_value
def check_requirements(
self, reqs: Iterable[str]
) -> Tuple[Set[Tuple[str, str]], Set[str]]:
"""Return 2 sets:
- conflicting requirements: set of (installed, wanted) reqs tuples
- missing requirements: set of reqs
"""
missing = set()
conflicting = set()
if reqs:
env = (
get_environment(self._lib_dirs)
if hasattr(self, "_lib_dirs")
else get_default_environment()
)
for req_str in reqs:
req = Requirement(req_str)
# We're explicitly evaluating with an empty extra value, since build
# environments are not provided any mechanism to select specific extras.
if req.marker is not None and not req.marker.evaluate({"extra": ""}):
continue
dist = env.get_distribution(req.name)
if not dist:
missing.add(req_str)
continue
if isinstance(dist.version, Version):
installed_req_str = f"{req.name}=={dist.version}"
else:
installed_req_str = f"{req.name}==={dist.version}"
if not req.specifier.contains(dist.version, prereleases=True):
conflicting.add((installed_req_str, req_str))
# FIXME: Consider direct URL?
return conflicting, missing
def install_requirements(
self,
finder: "PackageFinder",
requirements: Iterable[str],
prefix_as_string: str,
*,
kind: str,
) -> None:
prefix = self._prefixes[prefix_as_string]
assert not prefix.setup
prefix.setup = True
if not requirements:
return
self._install_requirements(
get_runnable_pip(),
finder,
requirements,
prefix,
kind=kind,
)
@staticmethod
def _install_requirements(
pip_runnable: str,
finder: "PackageFinder",
requirements: Iterable[str],
prefix: _Prefix,
*,
kind: str,
) -> None:
args: List[str] = [
sys.executable,
pip_runnable,
"install",
"--ignore-installed",
"--no-user",
"--prefix",
prefix.path,
"--no-warn-script-location",
]
if logger.getEffectiveLevel() <= logging.DEBUG:
args.append("-v")
for format_control in ("no_binary", "only_binary"):
formats = getattr(finder.format_control, format_control)
args.extend(
(
"--" + format_control.replace("_", "-"),
",".join(sorted(formats or {":none:"})),
)
)
index_urls = finder.index_urls
if index_urls:
args.extend(["-i", index_urls[0]])
for extra_index in index_urls[1:]:
args.extend(["--extra-index-url", extra_index])
else:
args.append("--no-index")
for link in finder.find_links:
args.extend(["--find-links", link])
for host in finder.trusted_hosts:
args.extend(["--trusted-host", host])
if finder.allow_all_prereleases:
args.append("--pre")
if finder.prefer_binary:
args.append("--prefer-binary")
args.append("--")
args.extend(requirements)
extra_environ = {"_PIP_STANDALONE_CERT": where()}
with open_spinner(f"Installing {kind}") as spinner:
call_subprocess(
args,
command_desc=f"pip subprocess to install {kind}",
spinner=spinner,
extra_environ=extra_environ,
)
class NoOpBuildEnvironment(BuildEnvironment):
"""A no-op drop-in replacement for BuildEnvironment"""
def __init__(self) -> None:
pass
def __enter__(self) -> None:
pass
def __exit__(
self,
exc_type: Optional[Type[BaseException]],
exc_val: Optional[BaseException],
exc_tb: Optional[TracebackType],
) -> None:
pass
def cleanup(self) -> None:
pass
def install_requirements(
self,
finder: "PackageFinder",
requirements: Iterable[str],
prefix_as_string: str,
*,
kind: str,
) -> None:
raise NotImplementedError()

View File

@@ -0,0 +1,290 @@
"""Cache Management
"""
import hashlib
import json
import logging
import os
from pathlib import Path
from typing import Any, Dict, List, Optional
from pip._vendor.packaging.tags import Tag, interpreter_name, interpreter_version
from pip._vendor.packaging.utils import canonicalize_name
from pip._internal.exceptions import InvalidWheelFilename
from pip._internal.models.direct_url import DirectUrl
from pip._internal.models.link import Link
from pip._internal.models.wheel import Wheel
from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds
from pip._internal.utils.urls import path_to_url
logger = logging.getLogger(__name__)
ORIGIN_JSON_NAME = "origin.json"
def _hash_dict(d: Dict[str, str]) -> str:
"""Return a stable sha224 of a dictionary."""
s = json.dumps(d, sort_keys=True, separators=(",", ":"), ensure_ascii=True)
return hashlib.sha224(s.encode("ascii")).hexdigest()
class Cache:
"""An abstract class - provides cache directories for data from links
:param cache_dir: The root of the cache.
"""
def __init__(self, cache_dir: str) -> None:
super().__init__()
assert not cache_dir or os.path.isabs(cache_dir)
self.cache_dir = cache_dir or None
def _get_cache_path_parts(self, link: Link) -> List[str]:
"""Get parts of part that must be os.path.joined with cache_dir"""
# We want to generate an url to use as our cache key, we don't want to
# just re-use the URL because it might have other items in the fragment
# and we don't care about those.
key_parts = {"url": link.url_without_fragment}
if link.hash_name is not None and link.hash is not None:
key_parts[link.hash_name] = link.hash
if link.subdirectory_fragment:
key_parts["subdirectory"] = link.subdirectory_fragment
# Include interpreter name, major and minor version in cache key
# to cope with ill-behaved sdists that build a different wheel
# depending on the python version their setup.py is being run on,
# and don't encode the difference in compatibility tags.
# https://github.com/pypa/pip/issues/7296
key_parts["interpreter_name"] = interpreter_name()
key_parts["interpreter_version"] = interpreter_version()
# Encode our key url with sha224, we'll use this because it has similar
# security properties to sha256, but with a shorter total output (and
# thus less secure). However the differences don't make a lot of
# difference for our use case here.
hashed = _hash_dict(key_parts)
# We want to nest the directories some to prevent having a ton of top
# level directories where we might run out of sub directories on some
# FS.
parts = [hashed[:2], hashed[2:4], hashed[4:6], hashed[6:]]
return parts
def _get_candidates(self, link: Link, canonical_package_name: str) -> List[Any]:
can_not_cache = not self.cache_dir or not canonical_package_name or not link
if can_not_cache:
return []
path = self.get_path_for_link(link)
if os.path.isdir(path):
return [(candidate, path) for candidate in os.listdir(path)]
return []
def get_path_for_link(self, link: Link) -> str:
"""Return a directory to store cached items in for link."""
raise NotImplementedError()
def get(
self,
link: Link,
package_name: Optional[str],
supported_tags: List[Tag],
) -> Link:
"""Returns a link to a cached item if it exists, otherwise returns the
passed link.
"""
raise NotImplementedError()
class SimpleWheelCache(Cache):
"""A cache of wheels for future installs."""
def __init__(self, cache_dir: str) -> None:
super().__init__(cache_dir)
def get_path_for_link(self, link: Link) -> str:
"""Return a directory to store cached wheels for link
Because there are M wheels for any one sdist, we provide a directory
to cache them in, and then consult that directory when looking up
cache hits.
We only insert things into the cache if they have plausible version
numbers, so that we don't contaminate the cache with things that were
not unique. E.g. ./package might have dozens of installs done for it
and build a version of 0.0...and if we built and cached a wheel, we'd
end up using the same wheel even if the source has been edited.
:param link: The link of the sdist for which this will cache wheels.
"""
parts = self._get_cache_path_parts(link)
assert self.cache_dir
# Store wheels within the root cache_dir
return os.path.join(self.cache_dir, "wheels", *parts)
def get(
self,
link: Link,
package_name: Optional[str],
supported_tags: List[Tag],
) -> Link:
candidates = []
if not package_name:
return link
canonical_package_name = canonicalize_name(package_name)
for wheel_name, wheel_dir in self._get_candidates(link, canonical_package_name):
try:
wheel = Wheel(wheel_name)
except InvalidWheelFilename:
continue
if canonicalize_name(wheel.name) != canonical_package_name:
logger.debug(
"Ignoring cached wheel %s for %s as it "
"does not match the expected distribution name %s.",
wheel_name,
link,
package_name,
)
continue
if not wheel.supported(supported_tags):
# Built for a different python/arch/etc
continue
candidates.append(
(
wheel.support_index_min(supported_tags),
wheel_name,
wheel_dir,
)
)
if not candidates:
return link
_, wheel_name, wheel_dir = min(candidates)
return Link(path_to_url(os.path.join(wheel_dir, wheel_name)))
class EphemWheelCache(SimpleWheelCache):
"""A SimpleWheelCache that creates it's own temporary cache directory"""
def __init__(self) -> None:
self._temp_dir = TempDirectory(
kind=tempdir_kinds.EPHEM_WHEEL_CACHE,
globally_managed=True,
)
super().__init__(self._temp_dir.path)
class CacheEntry:
def __init__(
self,
link: Link,
persistent: bool,
):
self.link = link
self.persistent = persistent
self.origin: Optional[DirectUrl] = None
origin_direct_url_path = Path(self.link.file_path).parent / ORIGIN_JSON_NAME
if origin_direct_url_path.exists():
try:
self.origin = DirectUrl.from_json(
origin_direct_url_path.read_text(encoding="utf-8")
)
except Exception as e:
logger.warning(
"Ignoring invalid cache entry origin file %s for %s (%s)",
origin_direct_url_path,
link.filename,
e,
)
class WheelCache(Cache):
"""Wraps EphemWheelCache and SimpleWheelCache into a single Cache
This Cache allows for gracefully degradation, using the ephem wheel cache
when a certain link is not found in the simple wheel cache first.
"""
def __init__(self, cache_dir: str) -> None:
super().__init__(cache_dir)
self._wheel_cache = SimpleWheelCache(cache_dir)
self._ephem_cache = EphemWheelCache()
def get_path_for_link(self, link: Link) -> str:
return self._wheel_cache.get_path_for_link(link)
def get_ephem_path_for_link(self, link: Link) -> str:
return self._ephem_cache.get_path_for_link(link)
def get(
self,
link: Link,
package_name: Optional[str],
supported_tags: List[Tag],
) -> Link:
cache_entry = self.get_cache_entry(link, package_name, supported_tags)
if cache_entry is None:
return link
return cache_entry.link
def get_cache_entry(
self,
link: Link,
package_name: Optional[str],
supported_tags: List[Tag],
) -> Optional[CacheEntry]:
"""Returns a CacheEntry with a link to a cached item if it exists or
None. The cache entry indicates if the item was found in the persistent
or ephemeral cache.
"""
retval = self._wheel_cache.get(
link=link,
package_name=package_name,
supported_tags=supported_tags,
)
if retval is not link:
return CacheEntry(retval, persistent=True)
retval = self._ephem_cache.get(
link=link,
package_name=package_name,
supported_tags=supported_tags,
)
if retval is not link:
return CacheEntry(retval, persistent=False)
return None
@staticmethod
def record_download_origin(cache_dir: str, download_info: DirectUrl) -> None:
origin_path = Path(cache_dir) / ORIGIN_JSON_NAME
if origin_path.exists():
try:
origin = DirectUrl.from_json(origin_path.read_text(encoding="utf-8"))
except Exception as e:
logger.warning(
"Could not read origin file %s in cache entry (%s). "
"Will attempt to overwrite it.",
origin_path,
e,
)
else:
# TODO: use DirectUrl.equivalent when
# https://github.com/pypa/pip/pull/10564 is merged.
if origin.url != download_info.url:
logger.warning(
"Origin URL %s in cache entry %s does not match download URL "
"%s. This is likely a pip bug or a cache corruption issue. "
"Will overwrite it with the new value.",
origin.url,
cache_dir,
download_info.url,
)
origin_path.write_text(download_info.to_json(), encoding="utf-8")

View File

@@ -0,0 +1,4 @@
"""Subpackage containing all of pip's command line interface related code
"""
# This file intentionally does not import submodules

View File

@@ -0,0 +1,172 @@
"""Logic that powers autocompletion installed by ``pip completion``.
"""
import optparse
import os
import sys
from itertools import chain
from typing import Any, Iterable, List, Optional
from pip._internal.cli.main_parser import create_main_parser
from pip._internal.commands import commands_dict, create_command
from pip._internal.metadata import get_default_environment
def autocomplete() -> None:
"""Entry Point for completion of main and subcommand options."""
# Don't complete if user hasn't sourced bash_completion file.
if "PIP_AUTO_COMPLETE" not in os.environ:
return
cwords = os.environ["COMP_WORDS"].split()[1:]
cword = int(os.environ["COMP_CWORD"])
try:
current = cwords[cword - 1]
except IndexError:
current = ""
parser = create_main_parser()
subcommands = list(commands_dict)
options = []
# subcommand
subcommand_name: Optional[str] = None
for word in cwords:
if word in subcommands:
subcommand_name = word
break
# subcommand options
if subcommand_name is not None:
# special case: 'help' subcommand has no options
if subcommand_name == "help":
sys.exit(1)
# special case: list locally installed dists for show and uninstall
should_list_installed = not current.startswith("-") and subcommand_name in [
"show",
"uninstall",
]
if should_list_installed:
env = get_default_environment()
lc = current.lower()
installed = [
dist.canonical_name
for dist in env.iter_installed_distributions(local_only=True)
if dist.canonical_name.startswith(lc)
and dist.canonical_name not in cwords[1:]
]
# if there are no dists installed, fall back to option completion
if installed:
for dist in installed:
print(dist)
sys.exit(1)
should_list_installables = (
not current.startswith("-") and subcommand_name == "install"
)
if should_list_installables:
for path in auto_complete_paths(current, "path"):
print(path)
sys.exit(1)
subcommand = create_command(subcommand_name)
for opt in subcommand.parser.option_list_all:
if opt.help != optparse.SUPPRESS_HELP:
options += [
(opt_str, opt.nargs) for opt_str in opt._long_opts + opt._short_opts
]
# filter out previously specified options from available options
prev_opts = [x.split("=")[0] for x in cwords[1 : cword - 1]]
options = [(x, v) for (x, v) in options if x not in prev_opts]
# filter options by current input
options = [(k, v) for k, v in options if k.startswith(current)]
# get completion type given cwords and available subcommand options
completion_type = get_path_completion_type(
cwords,
cword,
subcommand.parser.option_list_all,
)
# get completion files and directories if ``completion_type`` is
# ``<file>``, ``<dir>`` or ``<path>``
if completion_type:
paths = auto_complete_paths(current, completion_type)
options = [(path, 0) for path in paths]
for option in options:
opt_label = option[0]
# append '=' to options which require args
if option[1] and option[0][:2] == "--":
opt_label += "="
print(opt_label)
else:
# show main parser options only when necessary
opts = [i.option_list for i in parser.option_groups]
opts.append(parser.option_list)
flattened_opts = chain.from_iterable(opts)
if current.startswith("-"):
for opt in flattened_opts:
if opt.help != optparse.SUPPRESS_HELP:
subcommands += opt._long_opts + opt._short_opts
else:
# get completion type given cwords and all available options
completion_type = get_path_completion_type(cwords, cword, flattened_opts)
if completion_type:
subcommands = list(auto_complete_paths(current, completion_type))
print(" ".join([x for x in subcommands if x.startswith(current)]))
sys.exit(1)
def get_path_completion_type(
cwords: List[str], cword: int, opts: Iterable[Any]
) -> Optional[str]:
"""Get the type of path completion (``file``, ``dir``, ``path`` or None)
:param cwords: same as the environmental variable ``COMP_WORDS``
:param cword: same as the environmental variable ``COMP_CWORD``
:param opts: The available options to check
:return: path completion type (``file``, ``dir``, ``path`` or None)
"""
if cword < 2 or not cwords[cword - 2].startswith("-"):
return None
for opt in opts:
if opt.help == optparse.SUPPRESS_HELP:
continue
for o in str(opt).split("/"):
if cwords[cword - 2].split("=")[0] == o:
if not opt.metavar or any(
x in ("path", "file", "dir") for x in opt.metavar.split("/")
):
return opt.metavar
return None
def auto_complete_paths(current: str, completion_type: str) -> Iterable[str]:
"""If ``completion_type`` is ``file`` or ``path``, list all regular files
and directories starting with ``current``; otherwise only list directories
starting with ``current``.
:param current: The word to be completed
:param completion_type: path completion type(``file``, ``path`` or ``dir``)
:return: A generator of regular files and/or directories
"""
directory, filename = os.path.split(current)
current_path = os.path.abspath(directory)
# Don't complete paths if they can't be accessed
if not os.access(current_path, os.R_OK):
return
filename = os.path.normcase(filename)
# list all files that start with ``filename``
file_list = (
x for x in os.listdir(current_path) if os.path.normcase(x).startswith(filename)
)
for f in file_list:
opt = os.path.join(current_path, f)
comp_file = os.path.normcase(os.path.join(directory, f))
# complete regular files when there is not ``<dir>`` after option
# complete directories when there is ``<file>``, ``<path>`` or
# ``<dir>``after option
if completion_type != "dir" and os.path.isfile(opt):
yield comp_file
elif os.path.isdir(opt):
yield os.path.join(comp_file, "")

View File

@@ -0,0 +1,236 @@
"""Base Command class, and related routines"""
import functools
import logging
import logging.config
import optparse
import os
import sys
import traceback
from optparse import Values
from typing import Any, Callable, List, Optional, Tuple
from pip._vendor.rich import traceback as rich_traceback
from pip._internal.cli import cmdoptions
from pip._internal.cli.command_context import CommandContextMixIn
from pip._internal.cli.parser import ConfigOptionParser, UpdatingDefaultsHelpFormatter
from pip._internal.cli.status_codes import (
ERROR,
PREVIOUS_BUILD_DIR_ERROR,
UNKNOWN_ERROR,
VIRTUALENV_NOT_FOUND,
)
from pip._internal.exceptions import (
BadCommand,
CommandError,
DiagnosticPipError,
InstallationError,
NetworkConnectionError,
PreviousBuildDirError,
UninstallationError,
)
from pip._internal.utils.filesystem import check_path_owner
from pip._internal.utils.logging import BrokenStdoutLoggingError, setup_logging
from pip._internal.utils.misc import get_prog, normalize_path
from pip._internal.utils.temp_dir import TempDirectoryTypeRegistry as TempDirRegistry
from pip._internal.utils.temp_dir import global_tempdir_manager, tempdir_registry
from pip._internal.utils.virtualenv import running_under_virtualenv
__all__ = ["Command"]
logger = logging.getLogger(__name__)
class Command(CommandContextMixIn):
usage: str = ""
ignore_require_venv: bool = False
def __init__(self, name: str, summary: str, isolated: bool = False) -> None:
super().__init__()
self.name = name
self.summary = summary
self.parser = ConfigOptionParser(
usage=self.usage,
prog=f"{get_prog()} {name}",
formatter=UpdatingDefaultsHelpFormatter(),
add_help_option=False,
name=name,
description=self.__doc__,
isolated=isolated,
)
self.tempdir_registry: Optional[TempDirRegistry] = None
# Commands should add options to this option group
optgroup_name = f"{self.name.capitalize()} Options"
self.cmd_opts = optparse.OptionGroup(self.parser, optgroup_name)
# Add the general options
gen_opts = cmdoptions.make_option_group(
cmdoptions.general_group,
self.parser,
)
self.parser.add_option_group(gen_opts)
self.add_options()
def add_options(self) -> None:
pass
def handle_pip_version_check(self, options: Values) -> None:
"""
This is a no-op so that commands by default do not do the pip version
check.
"""
# Make sure we do the pip version check if the index_group options
# are present.
assert not hasattr(options, "no_index")
def run(self, options: Values, args: List[str]) -> int:
raise NotImplementedError
def parse_args(self, args: List[str]) -> Tuple[Values, List[str]]:
# factored out for testability
return self.parser.parse_args(args)
def main(self, args: List[str]) -> int:
try:
with self.main_context():
return self._main(args)
finally:
logging.shutdown()
def _main(self, args: List[str]) -> int:
# We must initialize this before the tempdir manager, otherwise the
# configuration would not be accessible by the time we clean up the
# tempdir manager.
self.tempdir_registry = self.enter_context(tempdir_registry())
# Intentionally set as early as possible so globally-managed temporary
# directories are available to the rest of the code.
self.enter_context(global_tempdir_manager())
options, args = self.parse_args(args)
# Set verbosity so that it can be used elsewhere.
self.verbosity = options.verbose - options.quiet
level_number = setup_logging(
verbosity=self.verbosity,
no_color=options.no_color,
user_log_file=options.log,
)
always_enabled_features = set(options.features_enabled) & set(
cmdoptions.ALWAYS_ENABLED_FEATURES
)
if always_enabled_features:
logger.warning(
"The following features are always enabled: %s. ",
", ".join(sorted(always_enabled_features)),
)
# Make sure that the --python argument isn't specified after the
# subcommand. We can tell, because if --python was specified,
# we should only reach this point if we're running in the created
# subprocess, which has the _PIP_RUNNING_IN_SUBPROCESS environment
# variable set.
if options.python and "_PIP_RUNNING_IN_SUBPROCESS" not in os.environ:
logger.critical(
"The --python option must be placed before the pip subcommand name"
)
sys.exit(ERROR)
# TODO: Try to get these passing down from the command?
# without resorting to os.environ to hold these.
# This also affects isolated builds and it should.
if options.no_input:
os.environ["PIP_NO_INPUT"] = "1"
if options.exists_action:
os.environ["PIP_EXISTS_ACTION"] = " ".join(options.exists_action)
if options.require_venv and not self.ignore_require_venv:
# If a venv is required check if it can really be found
if not running_under_virtualenv():
logger.critical("Could not find an activated virtualenv (required).")
sys.exit(VIRTUALENV_NOT_FOUND)
if options.cache_dir:
options.cache_dir = normalize_path(options.cache_dir)
if not check_path_owner(options.cache_dir):
logger.warning(
"The directory '%s' or its parent directory is not owned "
"or is not writable by the current user. The cache "
"has been disabled. Check the permissions and owner of "
"that directory. If executing pip with sudo, you should "
"use sudo's -H flag.",
options.cache_dir,
)
options.cache_dir = None
def intercepts_unhandled_exc(
run_func: Callable[..., int]
) -> Callable[..., int]:
@functools.wraps(run_func)
def exc_logging_wrapper(*args: Any) -> int:
try:
status = run_func(*args)
assert isinstance(status, int)
return status
except DiagnosticPipError as exc:
logger.error("%s", exc, extra={"rich": True})
logger.debug("Exception information:", exc_info=True)
return ERROR
except PreviousBuildDirError as exc:
logger.critical(str(exc))
logger.debug("Exception information:", exc_info=True)
return PREVIOUS_BUILD_DIR_ERROR
except (
InstallationError,
UninstallationError,
BadCommand,
NetworkConnectionError,
) as exc:
logger.critical(str(exc))
logger.debug("Exception information:", exc_info=True)
return ERROR
except CommandError as exc:
logger.critical("%s", exc)
logger.debug("Exception information:", exc_info=True)
return ERROR
except BrokenStdoutLoggingError:
# Bypass our logger and write any remaining messages to
# stderr because stdout no longer works.
print("ERROR: Pipe to stdout was broken", file=sys.stderr)
if level_number <= logging.DEBUG:
traceback.print_exc(file=sys.stderr)
return ERROR
except KeyboardInterrupt:
logger.critical("Operation cancelled by user")
logger.debug("Exception information:", exc_info=True)
return ERROR
except BaseException:
logger.critical("Exception:", exc_info=True)
return UNKNOWN_ERROR
return exc_logging_wrapper
try:
if not options.debug_mode:
run = intercepts_unhandled_exc(self.run)
else:
run = self.run
rich_traceback.install(show_locals=True)
return run(options, args)
finally:
self.handle_pip_version_check(options)

View File

@@ -0,0 +1,27 @@
from contextlib import ExitStack, contextmanager
from typing import ContextManager, Generator, TypeVar
_T = TypeVar("_T", covariant=True)
class CommandContextMixIn:
def __init__(self) -> None:
super().__init__()
self._in_main_context = False
self._main_context = ExitStack()
@contextmanager
def main_context(self) -> Generator[None, None, None]:
assert not self._in_main_context
self._in_main_context = True
try:
with self._main_context:
yield
finally:
self._in_main_context = False
def enter_context(self, context_provider: ContextManager[_T]) -> _T:
assert self._in_main_context
return self._main_context.enter_context(context_provider)

View File

@@ -0,0 +1,79 @@
"""Primary application entrypoint.
"""
import locale
import logging
import os
import sys
import warnings
from typing import List, Optional
from pip._internal.cli.autocompletion import autocomplete
from pip._internal.cli.main_parser import parse_command
from pip._internal.commands import create_command
from pip._internal.exceptions import PipError
from pip._internal.utils import deprecation
logger = logging.getLogger(__name__)
# Do not import and use main() directly! Using it directly is actively
# discouraged by pip's maintainers. The name, location and behavior of
# this function is subject to change, so calling it directly is not
# portable across different pip versions.
# In addition, running pip in-process is unsupported and unsafe. This is
# elaborated in detail at
# https://pip.pypa.io/en/stable/user_guide/#using-pip-from-your-program.
# That document also provides suggestions that should work for nearly
# all users that are considering importing and using main() directly.
# However, we know that certain users will still want to invoke pip
# in-process. If you understand and accept the implications of using pip
# in an unsupported manner, the best approach is to use runpy to avoid
# depending on the exact location of this entry point.
# The following example shows how to use runpy to invoke pip in that
# case:
#
# sys.argv = ["pip", your, args, here]
# runpy.run_module("pip", run_name="__main__")
#
# Note that this will exit the process after running, unlike a direct
# call to main. As it is not safe to do any processing after calling
# main, this should not be an issue in practice.
def main(args: Optional[List[str]] = None) -> int:
if args is None:
args = sys.argv[1:]
# Suppress the pkg_resources deprecation warning
# Note - we use a module of .*pkg_resources to cover
# the normal case (pip._vendor.pkg_resources) and the
# devendored case (a bare pkg_resources)
warnings.filterwarnings(
action="ignore", category=DeprecationWarning, module=".*pkg_resources"
)
# Configure our deprecation warnings to be sent through loggers
deprecation.install_warning_logger()
autocomplete()
try:
cmd_name, cmd_args = parse_command(args)
except PipError as exc:
sys.stderr.write(f"ERROR: {exc}")
sys.stderr.write(os.linesep)
sys.exit(1)
# Needed for locale.getpreferredencoding(False) to work
# in pip._internal.utils.encoding.auto_decode
try:
locale.setlocale(locale.LC_ALL, "")
except locale.Error as e:
# setlocale can apparently crash if locale are uninitialized
logger.debug("Ignoring error %s when setting locale", e)
command = create_command(cmd_name, isolated=("--isolated" in cmd_args))
return command.main(cmd_args)

Some files were not shown because too many files have changed in this diff Show More