Compare commits

..

113 Commits

Author SHA1 Message Date
Ionel Andrei Cataon
546fc277a4 s 2026-02-19 19:19:14 +02:00
Ionel Andrei Cataon
f0b4466a76 s 2026-02-18 18:31:01 +02:00
Ionel Andrei Cataon
25ddd876d4 s 2026-02-18 18:21:25 +02:00
Ionel Andrei Cataon
0cde41ef6b s 2026-02-18 18:18:18 +02:00
Ionel Andrei Cataon
7e1581af5a s 2026-02-18 18:16:54 +02:00
Ionel Andrei Cataon
c88bc6ba28 s 2026-02-18 18:14:38 +02:00
Ionel Andrei Cataon
9e302f9778 s 2026-02-18 18:09:19 +02:00
Ionel Andrei Cataon
4ac65420b7 s 2026-02-18 18:05:54 +02:00
Ionel Andrei Cataon
f825104e35 s 2026-02-18 17:57:36 +02:00
Ionel Andrei Cataon
8d1442616d s 2026-02-18 17:54:11 +02:00
Ionel Andrei Cataon
c06257bef9 s 2026-02-18 17:51:35 +02:00
Ionel Andrei Cataon
e0ddd65f1d s 2026-02-18 17:48:47 +02:00
Ionel Andrei Cataon
1607cb2ffc s 2026-02-18 17:44:59 +02:00
Ionel Andrei Cataon
03281d71e4 s 2026-02-18 17:41:32 +02:00
Ionel Andrei Cataon
30f10e8430 s 2026-02-18 17:36:18 +02:00
Ionel Andrei Cataon
1b08c99047 s 2026-02-18 17:32:07 +02:00
Ionel Andrei Cataon
add9493e57 s 2026-02-18 17:27:33 +02:00
Ionel Andrei Cataon
a18da98a6f s 2026-02-18 17:23:58 +02:00
Ionel Andrei Cataon
d702f3294c s 2026-02-18 17:18:26 +02:00
Ionel Andrei Cataon
17c1091732 s 2026-02-18 17:12:08 +02:00
Ionel Andrei Cataon
fd3686650f s 2026-02-18 17:07:26 +02:00
Ionel Andrei Cataon
fad1943b5d s 2026-02-18 17:04:20 +02:00
Ionel Andrei Cataon
0ed5d4dbc6 s 2026-02-18 16:59:42 +02:00
Ionel Andrei Cataon
3051d9be60 s 2026-02-18 16:56:38 +02:00
Ionel Andrei Cataon
e192987648 s 2026-02-18 16:54:35 +02:00
Ionel Andrei Cataon
e30325ab5f s 2026-02-18 16:52:32 +02:00
Ionel Andrei Cataon
e4a8e9c388 s 2026-02-18 16:48:38 +02:00
Ionel Andrei Cataon
9adc71a26e s 2026-02-18 16:46:19 +02:00
Ionel Andrei Cataon
9c4a8cfa62 s 2026-02-18 16:42:50 +02:00
Ionel Andrei Cataon
9965f28ce1 s 2026-02-18 16:35:51 +02:00
Ionel Andrei Cataon
35b8279769 s 2026-02-18 16:33:35 +02:00
Ionel Andrei Cataon
40a0d44803 s 2026-02-18 16:30:27 +02:00
Ionel Andrei Cataon
64e4138e16 s 2026-02-18 16:27:01 +02:00
Ionel Andrei Cataon
9c4795741b s 2026-02-18 16:24:17 +02:00
Ionel Andrei Cataon
4cce5acf2d s 2026-02-18 16:19:13 +02:00
Ionel Andrei Cataon
1beeb14203 s 2026-02-18 16:10:54 +02:00
Ionel Andrei Cataon
7a3190ac69 s 2026-02-18 16:03:01 +02:00
Ionel Andrei Cataon
4383ff369e s 2026-02-18 15:59:34 +02:00
Ionel Andrei Cataon
b39feeb283 s 2026-02-18 15:54:54 +02:00
Ionel Andrei Cataon
3952fcfc16 w 2026-02-18 15:49:12 +02:00
Ionel Andrei Cataon
f435bdcd5a s 2026-02-18 15:44:19 +02:00
Ionel Andrei Cataon
9bad93edf7 m 2026-02-18 15:37:33 +02:00
Ionel Andrei Cataon
fda1f4777f p 2026-02-18 15:36:30 +02:00
Ionel Andrei Cataon
5f9c47b95d maven 2026-02-18 15:32:12 +02:00
Ionel Andrei Cataon
6b8d5d505c m 2026-02-18 15:20:28 +02:00
Ionel Andrei Cataon
d9285fb410 s 2026-02-18 15:14:04 +02:00
Ionel Andrei Cataon
e7a31edbc3 d 2026-02-18 15:08:34 +02:00
Ionel Andrei Cataon
966084e31b m 2026-02-18 15:04:19 +02:00
Ionel Andrei Cataon
360b6bfef6 u 2026-02-18 15:00:42 +02:00
Ionel Andrei Cataon
3794792e72 m 2026-02-17 17:51:31 +02:00
Ionel Andrei Cataon
043e60906a p2 2026-02-12 17:23:11 +02:00
Ionel Andrei Cataon
768f997044 p2 2026-02-12 17:20:40 +02:00
Ionel Andrei Cataon
f8261ffcf2 p2 2026-02-12 17:19:25 +02:00
Ionel Andrei Cataon
0f0f706960 [2 2026-02-12 17:17:23 +02:00
Ionel Andrei Cataon
2e1da76f1f p2 2026-02-12 17:13:45 +02:00
Ionel Andrei Cataon
84fe05d110 p2 2026-02-12 17:11:59 +02:00
Ionel Andrei Cataon
9d8d3bacc2 p2 2026-02-12 17:09:30 +02:00
Ionel Andrei Cataon
dbdcb575df p2 2026-02-12 17:07:52 +02:00
Ionel Andrei Cataon
3d25479a5c p2 2026-02-12 17:04:52 +02:00
Ionel Andrei Cataon
e2fce3a281 p2 2026-02-12 17:01:19 +02:00
Ionel Andrei Cataon
dceb142d68 p2 2026-02-12 16:59:20 +02:00
Ionel Andrei Cataon
73ecbc43d0 p2 2026-02-12 16:56:40 +02:00
Ionel Andrei Cataon
dc045aeb94 p2 2026-02-12 16:52:15 +02:00
Ionel Andrei Cataon
b58666ead4 p2 2026-02-12 16:50:19 +02:00
Ionel Andrei Cataon
f6b3f8ad85 p2 2026-02-12 16:47:46 +02:00
Ionel Andrei Cataon
ddce0166aa p2 2026-02-12 16:42:44 +02:00
Ionel Andrei Cataon
2c67a10d4a pj2 2026-02-12 16:40:23 +02:00
Ionel Andrei Cataon
8713c62e82 p2 2026-02-12 16:38:57 +02:00
Ionel Andrei Cataon
04f2f26561 pj2 2026-02-12 16:36:00 +02:00
Ionel Andrei Cataon
77604629d6 pj2 2026-02-12 16:32:01 +02:00
Ionel Andrei Cataon
eb6ab497de u2 2026-02-12 16:26:05 +02:00
Ionel Andrei Cataon
13c9543797 pj2 2026-02-12 16:24:27 +02:00
Ionel Andrei Cataon
7f61b029d4 pj2 2026-02-12 16:22:58 +02:00
Ionel Andrei Cataon
8b80461677 up1 2026-02-12 16:20:23 +02:00
Ionel Andrei Cataon
f507bf03b8 up3 2026-02-12 16:18:27 +02:00
Ionel Andrei Cataon
4a4ec72ffc u3 2026-02-12 16:17:02 +02:00
Ionel Andrei Cataon
dad7ec78e5 u2 2026-02-12 16:15:47 +02:00
Ionel Andrei Cataon
03b12f8beb up1 2026-02-12 16:14:23 +02:00
Ionel Andrei Cataon
166d263b76 u1 2026-02-12 16:11:26 +02:00
Ionel Andrei Cataon
76ee23a856 u3 2026-02-12 16:09:30 +02:00
Ionel Andrei Cataon
a605059fc5 up5 2026-02-12 16:06:27 +02:00
Ionel Andrei Cataon
7e5876822e fix1 2026-02-12 16:03:51 +02:00
Ionel Andrei Cataon
85f6f18181 uppp3 2026-02-12 15:57:28 +02:00
Ionel Andrei Cataon
9e874e259d up3 2026-02-12 15:53:35 +02:00
Ionel Andrei Cataon
464d267ea4 u2 2026-02-12 15:48:47 +02:00
Ionel Andrei Cataon
e08c486711 upd7 2026-02-12 15:44:12 +02:00
Ionel Andrei Cataon
89a88148a2 upd6 2026-02-12 15:42:52 +02:00
Ionel Andrei Cataon
712c7e4932 Update5 2026-02-12 15:39:15 +02:00
Ionel Andrei Cataon
ee532cdeff update4 2026-02-12 15:37:51 +02:00
Ionel Andrei Cataon
0528f7c837 updat21 2026-02-12 15:34:02 +02:00
Ionel Andrei Cataon
00cf4bb992 update1 2026-02-12 15:32:06 +02:00
Ionel Andrei Cataon
8b9dde2f8b proiect2 2026-02-12 15:28:21 +02:00
Ionel Andrei Cataon
56f05d2f13 test3 2026-02-12 15:19:08 +02:00
Ionel Andrei Cataon
a78ae478c3 test2 2026-02-12 15:11:57 +02:00
Ionel Andrei Cataon
c428e2d341 Test1 2026-02-12 15:10:36 +02:00
Ionel Andrei Cataon
e464c1ade7 update3 2026-02-12 14:58:15 +02:00
Ionel Andrei Cataon
8a2e2de0dc update2 2026-02-12 14:56:06 +02:00
Ionel Andrei Cataon
e917af1300 update1 2026-02-12 14:53:26 +02:00
Ionel Andrei Cataon
7960479684 update 2026-02-12 14:50:33 +02:00
Ionel Andrei Cataon
2566b0d036 update 2026-02-12 14:21:14 +02:00
Ionel Andrei Cataon
75e4958b5c Verificare 2026-02-12 14:19:32 +02:00
Ionel Andrei Cataon
ddb9425e44 Project1 2026-02-12 14:08:00 +02:00
Ionel Andrei Cataon
611c31c0a1 update
All checks were successful
It_School_001/pipeline/head This commit looks good
2026-02-05 11:26:27 +02:00
Ionel Andrei Cataon
f082bec56b update
Some checks failed
It_School_001/pipeline/head Something is wrong with the build of this commit
2026-02-05 10:40:53 +02:00
Ionel Andrei Cataon
2d3f686918 last update python 2026-01-29 18:05:15 +02:00
Ionel Andrei Cataon
80d368e4c5 Python lessons 2026-01-27 20:06:30 +02:00
Ionel Andrei Cataon
c4b2844895 new python update 2026-01-27 19:10:53 +02:00
Ionel Andrei Cataon
20260e4d1e python test 2026-01-27 18:59:56 +02:00
Ionel Andrei Cataon
86e6bdc400 saved 2026-01-15 19:19:23 +02:00
Ionel Andrei Cataon
933df5dc5f saing work 2026-01-15 19:13:31 +02:00
Ionel Andrei Cataon
9c64748f2f Updated 2026-01-15 19:09:39 +02:00
002d53928a Update README.md 2025-12-02 18:10:36 +00:00
edea8a9bd1 Merge pull request '# Acesta este un nou capitol' (#1) from feature_001 into main
Reviewed-on: ionelcataon/first_gitea#1
2025-12-02 17:31:41 +00:00
1070 changed files with 193748 additions and 5 deletions

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,18 @@
services:
jenkins:
container_name: my_jenkins_01
build:
context: .
dockerfile: dockerfile.jenkins
ports:
- "60199:8080"
- "5000:5000"
volumes:
- "jenkins:/var/jenkins_home"
- "/var/run/docker.sock:/var/run/docker.sock"
group_add:
- "999"
restart: unless-stopped
volumes:
jenkins:

View File

@@ -0,0 +1,13 @@
FROM jenkins/jenkins:lts
USER root
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
RUN curl -fsSL https://download.docker.com/linux/static/stable/x86_64/docker-27.5.1.tgz | tar xvz && \
mv docker/docker /usr/bin/docker && \
rm -rf docker
RUN groupadd -g 999 docker || true && \
usermod -aG docker jenkins
USER 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,3 +1,7 @@
<<<<<<< HEAD
Fara modificari
=======
Asa functioneaza[develop 7f2020f] Changes Asa functioneaza[develop 7f2020f] Changes
1 file changed, 10 insertions(+) 1 file changed, 10 insertions(+)
create mode 100644 myWorkspace 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

4
bandit.txt Normal file
View File

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

View File

@@ -1,5 +0,0 @@
d
f
g
h
h

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

18
my-test-app/pom.xml Normal file
View File

@@ -0,0 +1,18 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test.jenkins</groupId>
<artifactId>my-test-app</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>my-test-app</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,13 @@
package com.test.jenkins;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
}
}

View File

@@ -0,0 +1,38 @@
package com.test.jenkins;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Unit test for simple App.
*/
public class AppTest
extends TestCase
{
/**
* Create the test case
*
* @param testName name of the test case
*/
public AppTest( String testName )
{
super( testName );
}
/**
* @return the suite of tests being tested
*/
public static Test suite()
{
return new TestSuite( AppTest.class );
}
/**
* Rigourous Test :-)
*/
public void testApp()
{
assertTrue( true );
}
}

View File

@@ -0,0 +1,9 @@
FROM tomcat:9.0-jdk11-openjdk-slim
RUN rm -rf /usr/local/tomcat/webapps/*
COPY target/nutritie.war /usr/local/tomcat/webapps/ROOT.war
EXPOSE 8080
CMD ["catalina.sh", "run"]

30
proiect-nutritie-java/Jenkinsfile vendored Normal file
View File

@@ -0,0 +1,30 @@
pipeline {
agent any
tools {
maven 'MVN-WSL'
}
stages {
stage('Maven Build (WAR)') {
steps {
dir('proiect-nutritie-java') {
sh 'mvn clean package'
}
}
}
stage('Docker Build & Deploy (Tomcat)') {
steps {
dir('proiect-nutritie-java') {
sh 'docker build -t nutritie-java-war .'
sh '''
docker stop container-java || true
docker rm container-java || true
docker run -d -p 8086:8080 --name container-java nutritie-java-war
'''
}
}
}
}
}

View File

@@ -0,0 +1,57 @@
# ⚡ NutriAI Elite - Sistem Inteligent de Nutriție
NutriAI Elite este o aplicație web avansată care combină calculul biometric precis cu puterea inteligenței artificiale (Groq API) pentru a genera planuri alimentare personalizate și verificate matematic.
---
## 🏗️ Arhitectura Pipeline-ului (Highlights)
Proiectul folosește un flux modern de tip **CI/CD** (Continuous Integration / Continuous Deployment) pentru a asigura stabilitatea și ușurința în scalare.
### 1. Front-end & Logică (HTML/JS)
* **Core:** Calculează necesarul caloric folosind formula **Mifflin-St Jeor**.
* **UI:** Interfață adaptivă cu suport pentru unități Metrice/Imperiale și sistem de teme (Onyx, Emerald, Midnight, Titanium).
* **API Integration:** Comunică direct cu modelul Llama 3.3 via Groq pentru generarea dietelor.
### 2. Managementul Dependențelor (Maven - `pom.xml`)
* Gestionează toate librăriile externe necesare.
* Compilează codul sursă și rulează testele unitare.
* Ambalează aplicația într-un format executabil pregătit pentru containerizare.
### 3. Containerizare (Dockerfile)
* Izolează aplicația într-un container **Docker**.
* Garantează că aplicația rulează identic în orice mediu (Local, Testing, Producție).
* Reduce conflictele de versiuni între biblioteci.
### 4. Automatizare (Jenkins - CI/CD)
* **Orchestrare:** Jenkins monitorizează repository-ul de Git.
* **Flux:** La fiecare *push*, Jenkins execută automat:
`Maven Build` ➔ `Docker Build Image` ➔ `Push to Registry` ➔ `Deploy on Server`.
---
## 🧬 Logica de Verificare AI (Groq Patch)
Pentru a elimina erorile clasice ale modelelor LLM, pipeline-ul include un **Prompt de Sistem** strict care impune:
* **Truth Table:** Valori calorice fixe pentru ingrediente brute (ex: 100g Orez = 360 kcal).
* **Scaling Dinamic:** Ajustarea gramajelor reale pentru a atinge ținta calorică, în loc de inventarea unor valori false.
* **Diversitate:** Autorizarea utilizării de proteine diverse (Steak, Somon, Avocado) pentru a evita monotonia.
---
## 🚀 Cum se rulează proiectul
1. **Local:** Deschide `index.html` într-un browser modern.
2. **Docker:**
```bash
docker build -t nutriai-elite .
docker run -p 8080:80 nutriai-elite
```
3. **Jenkins:** Adaugă URL-ul repository-ului în Jenkins și configurează `Jenkinsfile`-ul pentru automatizare completă.
---
*Creat și optimizat pentru performanță nutrițională și rigoare matematică.*

View File

@@ -0,0 +1,23 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.nutritie</groupId>
<artifactId>nutritie-webapp</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>Nutritie Java Edition</name>
<build>
<finalName>nutritie</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.4.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,225 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>NutriAI Elite v22.0</title>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;600;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<style>
:root { --primary: #3b82f6; --bg: #020617; --sidebar: #0f172a; --card: #1e293b; --accent: #60a5fa; --text: #ffffff; }
body.theme-dark { --bg: #020617; --sidebar: #0f172a; --primary: #3b82f6; }
body.theme-emerald { --bg: #064e3b; --sidebar: #065f46; --primary: #10b981; }
body.theme-midnight { --bg: #1e1b4b; --sidebar: #312e81; --primary: #818cf8; }
body.theme-titanium { --bg: #111827; --sidebar: #1f2937; --primary: #94a3b8; --card: #374151; --accent: #f8fafc; }
body { background-color: var(--bg); color: var(--text); font-family: 'Outfit', sans-serif; height: 100dvh; overflow: hidden; transition: 0.3s; }
.main-wrapper { display: flex; height: 100dvh; flex-direction: row; }
@media (max-width: 991px) {
.main-wrapper { flex-direction: column; overflow-y: auto; height: auto; }
.sidebar { width: 100% !important; height: auto !important; border-right: none !important; border-bottom: 1px solid rgba(255,255,255,0.1); }
.chat-section { height: 600px !important; }
body { overflow-y: auto; }
}
.sidebar { width: 360px; background: var(--sidebar); border-right: 1px solid rgba(255,255,255,0.1); padding: 1.5rem; overflow-y: auto; flex-shrink: 0; }
.chat-section { flex-grow: 1; display: flex; flex-direction: column; background: rgba(0,0,0,0.2); position: relative; }
.label-pro { color: var(--accent); font-weight: 800; font-size: 0.75rem; text-transform: uppercase; margin-bottom: 5px; display: block; }
.glass-input { background: #fff !important; color: #000 !important; border: 3px solid var(--primary) !important; border-radius: 12px; font-weight: 800 !important; }
.stat-panel { background: linear-gradient(145deg, var(--primary), #1e3a8a); border-radius: 20px; padding: 1rem; margin: 10px 0; text-align: center; }
.water-hub { background: rgba(59, 130, 246, 0.1); border: 2px solid var(--primary); border-radius: 15px; padding: 12px; margin: 10px 0; text-align: center; }
.macro-hub { background: rgba(255,255,255,0.05); border-radius: 20px; padding: 15px; margin-top: 10px; }
.chat-container { flex-grow: 1; overflow-y: auto; padding: 1.5rem; display: flex; flex-direction: column; }
.msg { padding: 1.2rem; border-radius: 1.2rem; margin-bottom: 1rem; font-size: 1rem; max-width: 90%; color: #fff !important; word-wrap: break-word; }
.ai { background: var(--card); border-left: 6px solid var(--primary); align-self: flex-start; }
.user { background: var(--primary); align-self: flex-end; }
.top-ctrl { padding: 10px; display: flex; justify-content: flex-end; gap: 8px; background: rgba(0,0,0,0.3); }
.input-area { padding: 15px; background: var(--sidebar); border-top: 1px solid rgba(255,255,255,0.1); display: flex; gap: 10px; }
.btn-shop { background: #f59e0b; color: #000; font-weight: 800; border: none; border-radius: 12px; padding: 0 15px; white-space: nowrap; }
.btn-reset { background: rgba(239, 68, 68, 0.15); color: #fca5a5; border: 1px solid #ef4444; border-radius: 12px; padding: 8px; font-weight: 700; width: 100%; margin-top: 15px; }
table { width: 100%; display: block; overflow-x: auto; color: #fff; border-collapse: collapse; margin-top: 10px; }
th, td { border: 1px solid rgba(255,255,255,0.2); padding: 8px; text-align: left; }
</style>
</head>
<body class="theme-dark">
<div class="main-wrapper">
<div class="sidebar">
<h3 class="fw-extrabold mb-3"><i class="fas fa-bolt text-primary"></i> NUTRI ELITE</h3>
<div class="row g-2">
<div class="col-6"><label class="label-pro" id="txtW">Weight</label><input type="number" id="w" class="form-control glass-input" placeholder="--" oninput="update()"></div>
<div class="col-6"><label class="label-pro" id="txtT">Target</label><input type="number" id="t" class="form-control glass-input" placeholder="--" oninput="update()"></div>
<div class="col-6"><label class="label-pro" id="txtH">Height</label><input type="number" id="h" class="form-control glass-input" placeholder="--" oninput="update()"></div>
<div class="col-6"><label class="label-pro">Age</label><input type="number" id="age" class="form-control glass-input" placeholder="--" oninput="update()"></div>
<div class="col-12">
<label class="label-pro">Activity</label>
<select id="act" class="form-select glass-input" onchange="update()">
<option value="" disabled selected>Select activity...</option>
<option value="1.2">Sedentary</option>
<option value="1.375">Lightly Active</option>
<option value="1.55">Moderately Active</option>
<option value="1.725">Very Active</option>
<option value="1.9">Extra Active</option>
</select>
</div>
<div class="col-12">
<label class="label-pro d-flex justify-content-between">Adjustment <span id="aggDisp">0 kcal</span></label>
<input type="range" id="agg" class="form-range" min="-1000" max="1000" step="50" value="0" oninput="update()">
</div>
</div>
<div class="stat-panel"><h1 class="fw-bold mb-0" id="kcal">0</h1><p class="text-uppercase fw-bold m-0 opacity-75 small">Target Calories</p></div>
<div class="water-hub">
<h2 class="fw-bold text-info mb-0" id="h2o">0.0L</h2>
<span class="label-pro" id="txtH2O"><i class="fas fa-droplet me-1"></i> Daily Hydration</span>
</div>
<div class="macro-hub">
<canvas id="mChart" style="max-height: 120px;"></canvas>
<div class="row mt-2 text-center fw-bold small">
<div class="col-4 text-info">P: <span id="pG">0g</span></div>
<div class="col-4 text-danger">C: <span id="cG">0g</span></div>
<div class="col-4 text-warning">F: <span id="fG">0g</span></div>
</div>
</div>
<button class="btn-reset" onclick="resetAll()"><i class="fas fa-sync me-2"></i> RESET SYSTEM</button>
</div>
<div class="chat-section">
<div class="top-ctrl">
<button id="btnMetric" class="btn btn-primary btn-sm active" onclick="setUnits('metric')">METRIC</button>
<button id="btnImperial" class="btn btn-outline-primary btn-sm" onclick="setUnits('imperial')">IMP</button>
<div class="dropdown">
<button class="btn btn-light btn-sm rounded-pill px-3" data-bs-toggle="dropdown"><i class="fas fa-palette"></i></button>
<ul class="dropdown-menu dropdown-menu-end shadow">
<li><a class="dropdown-item" href="#" onclick="setTheme('dark')">Onyx</a></li>
<li><a class="dropdown-item" href="#" onclick="setTheme('emerald')">Emerald</a></li>
<li><a class="dropdown-item" href="#" onclick="setTheme('midnight')">Midnight</a></li>
<li><a class="dropdown-item" href="#" onclick="setTheme('titanium')">Titanium</a></li>
</ul>
</div>
</div>
<div id="chat" class="chat-container">
<div class="msg ai shadow">
<h5 class="fw-bold text-primary">System Refined.</h5>
Shopping lists will only be generated upon button request. All units are synced.
</div>
</div>
<div class="input-area">
<div class="input-group input-group-lg flex-grow-1">
<input type="text" id="uIn" class="form-control bg-dark text-white border-primary" placeholder="Type and press ENTER..." onkeydown="if(event.key === 'Enter') talk()">
<button class="btn btn-primary" onclick="talk()"><i class="fas fa-paper-plane"></i></button>
</div>
<button class="btn-shop shadow-sm" onclick="talk('GENERATE_SHOPPING_LIST')">
<i class="fas fa-shopping-basket me-1"></i> SHOPPING LIST
</button>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
let isMetric = true, mChart;
const API = "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";
function setTheme(t) { document.body.className = 'theme-' + t; }
function setUnits(mode) {
if((mode==='metric' && !isMetric) || (mode==='imperial' && isMetric)) {
isMetric = !isMetric;
const w = document.getElementById('w'), t = document.getElementById('t'), h = document.getElementById('h');
if(w.value) w.value = isMetric ? (w.value/2.205).toFixed(0) : (w.value*2.205).toFixed(0);
if(t.value) t.value = isMetric ? (t.value/2.205).toFixed(0) : (t.value*2.205).toFixed(0);
if(h.value) h.value = isMetric ? (h.value*2.54).toFixed(0) : (h.value/2.54).toFixed(0);
document.getElementById('txtW').innerText = isMetric ? "Weight (kg)" : "Weight (lb)";
document.getElementById('txtT').innerText = isMetric ? "Target (kg)" : "Target (lb)";
document.getElementById('txtH').innerText = isMetric ? "Height (cm)" : "Height (in)";
document.getElementById('btnMetric').className = isMetric ? "btn btn-primary active btn-sm" : "btn btn-outline-primary btn-sm";
document.getElementById('btnImperial').className = !isMetric ? "btn btn-primary active btn-sm" : "btn btn-outline-primary btn-sm";
update();
}
}
function update() {
const wv = parseFloat(document.getElementById('w').value)||0, hv = parseFloat(document.getElementById('h').value)||0;
const av = parseFloat(document.getElementById('age').value)||0, act = parseFloat(document.getElementById('act').value)||1;
const agg = parseInt(document.getElementById('agg').value);
if(!wv || !hv || !av) return;
const wc = isMetric ? wv : wv/2.205, hc = isMetric ? hv : hv*2.54;
const bmr = (10 * wc) + (6.25 * hc) - (5 * av) + 5;
const total = Math.round((bmr * act) + agg);
document.getElementById('kcal').innerText = total;
document.getElementById('h2o').innerText = isMetric ? (wc * 0.035).toFixed(1) + "L" : (wv * 0.6).toFixed(0) + "oz";
document.getElementById('aggDisp').innerText = (agg>0?'+':'')+agg+" kcal";
const pG = Math.round((total * 0.3)/4), cG = Math.round((total * 0.4)/4), fG = Math.round((total * 0.3)/9);
document.getElementById('pG').innerText = pG+"g"; document.getElementById('cG').innerText = cG+"g"; document.getElementById('fG').innerText = fG+"g";
if(mChart) { mChart.data.datasets[0].data = [pG*4, cG*4, fG*9]; mChart.update(); }
}
function resetAll() {
['w','t','h','age','agg'].forEach(id => document.getElementById(id).value = id === 'agg' ? 0 : "");
document.getElementById('act').selectedIndex = 0;
document.getElementById('kcal').innerText = "0";
document.getElementById('h2o').innerText = isMetric ? "0.0L" : "0oz";
document.getElementById('chat').innerHTML = `<div class="msg ai shadow">System reset. Unit system: ${isMetric?'Metric':'Imperial'}.</div>`;
if(mChart) { mChart.data.datasets[0].data = [1,1,1]; mChart.update(); }
}
async function talk(custom) {
const box = document.getElementById('chat'), input = document.getElementById('uIn');
const isShopReq = custom === 'GENERATE_SHOPPING_LIST';
const text = isShopReq ? "Please generate a shopping list for the current meal plan." : (custom || input.value);
if(!text) return;
if(!custom) { box.innerHTML += `<div class="msg user shadow-sm">${text}</div>`; input.value=""; }
const id = 'ai-'+Date.now(); box.innerHTML += `<div id="${id}" class="msg ai shadow">Processing...</div>`;
box.scrollTop = box.scrollHeight;
try {
const res = await fetch("https://api.groq.com/openai/v1/chat/completions", {
method: "POST", headers: {"Content-Type":"application/json", "Authorization":`Bearer ${API}`},
body: JSON.stringify({ model:"llama-3.3-70b-versatile", messages:[
{role:"system", content: `Math-Strict Expert Nutritionist. Target: ${document.getElementById('kcal').innerText} kcal. SYSTEM: ${isMetric ? 'METRIC' : 'IMPERIAL'}.
MANDATORY RULES:
1. MATH AUDIT: 100g RAW Brown Rice = 360 kcal. 100g RAW Oats = 380 kcal. DO NOT hallucinate lower calories.
2. SCALING: If the total plan is below ${document.getElementById('kcal').innerText} kcal, INCREASE gram weights of ingredients. Do not lie about density.
3. VARIETY: Use Steak, Salmon, Whole Eggs, Avocado, Nuts, and Greek Yogurt. Do not default to just chicken and rice.
4. USER PREFERENCE: If user asks for "High Protein" or specific foods, prioritize them and adjust portions to hit the calorie target exactly.
5. RAW WEIGHTS: Always specify RAW weights for all ingredients.
6. SHOPPING LIST: Only generate if explicitly requested via the specific prompt. Units: ${isMetric ? 'grams/kilograms' : 'ounces/lbs'}.`},
{role:"user", content:text}
]})
});
const d = await res.json();
document.getElementById(id).innerHTML = marked.parse(d.choices[0].message.content);
} catch(e) { document.getElementById(id).innerText = "Connection error."; }
box.scrollTop = box.scrollHeight;
}
window.onload = () => {
mChart = new Chart(document.getElementById('mChart').getContext('2d'), {
type: 'doughnut', data: { datasets: [{ data: [1,1,1], backgroundColor: ['#0dcaf0','#dc3545','#ffc107'], borderWeight:0 }] },
options: { plugins: { legend: { display: false } }, cutout: '75%' }
});
resetAll();
}
</script>
</body>
</html>

View File

@@ -0,0 +1,16 @@
# Docker va descărca singur Python și Pip în interiorul imaginii
FROM python:3.9-slim
WORKDIR /app
# Copiem fișierul de dependințe
COPY requirements.txt .
# Aici Docker va rula 'pip install' în interiorul lui, nu pe Ubuntu al tău
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "app/main.py"]

40
proiect-nutritie/Jenkinsfile vendored Normal file
View File

@@ -0,0 +1,40 @@
pipeline {
agent any
tools {
maven 'MVN-WSL'
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Maven Analysis') {
steps {
sh 'mvn --version'
echo 'Maven a fost integrat cu succes în pipeline-ul de Python!'
}
}
stage('Build Docker Image') {
steps {
dir('proiect-nutritie') {
sh 'docker build -t dieta-app-jenkins .'
}
}
}
stage('Deploy') {
steps {
sh '''
docker stop test-dieta || true
docker rm test-dieta || true
docker run -d -p 8085:5000 --name test-dieta dieta-app-jenkins
'''
}
}
}
}

View File

@@ -0,0 +1,52 @@
import os
from flask import Flask, render_template, request
# import openai # Dezactivează comentariul când ai cheia API
app = Flask(__name__, template_folder='templates')
def calculeaza_target(data):
try:
w = float(data.get('weight'))
h = float(data.get('height'))
a = int(data.get('age'))
gen = data.get('gender')
act = float(data.get('activity'))
scop = data.get('goal')
if gen == 'masculin':
bmr = (10 * w) + (6.25 * h) - (5 * a) + 5
else:
bmr = (10 * w) + (6.25 * h) - (5 * a) - 161
tdee = bmr * act
if scop == 'slabire':
return round(tdee - 500)
elif scop == 'ingrasare':
return round(tdee + 500)
return round(tdee)
except:
return 2000
@app.route('/')
def index():
return render_template('index.html')
@app.route('/calculate', methods=['POST'])
def calculate():
data = request.form
kcal_final = calculeaza_target(data)
# Simulare AI dacă nu avem API Key configurat încă
preferinte = data.get('preferences', 'fără preferințe')
meniu_exemplu = f"""
🤖 Meniu Sugerat ({kcal_final} kcal):
- Mic dejun: Omletă cu 3 ouă și avocado.
- Prânz: Piept de pui (200g) cu orez sălbatic.
- Cină: Salată de ton cu măsline.
- Preferințe procesate: {preferinte}
"""
return render_template('index.html', rezultat=kcal_final, meniu_ai=meniu_exemplu)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)

View File

@@ -0,0 +1,81 @@
<!DOCTYPE html>
<html lang="ro">
<head>
<meta charset="UTF-8">
<title>Nutriție AI Pro</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="p-5 bg-light">
<div class="container" style="max-width: 600px;">
<h1 class="mb-4 text-center">Calculator Kcal & AI Menu</h1>
<div class="card p-4 shadow-sm">
<form action="/calculate" method="post">
<div class="mb-3">
<label class="form-label">Greutate actuală (kg)</label>
<input type="number" name="weight" class="form-control" required>
</div>
<div class="mb-3">
<label class="form-label">Înălțime (cm)</label>
<input type="number" name="height" class="form-control" required>
</div>
<div class="mb-3">
<label class="form-label">Vârstă</label>
<input type="number" name="age" class="form-control" required>
</div>
<div class="mb-3">
<label class="form-label">Sex</label>
<select name="gender" class="form-select">
<option value="masculin">Masculin</option>
<option value="feminin">Feminin</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">Nivel activitate</label>
<select name="activity" class="form-select">
<option value="1.2">Sedentar (birou)</option>
<option value="1.55">Activ (3-5 zile sport)</option>
<option value="1.9">Extrem (muncă fizică/sport zilnic)</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">Obiectiv</label>
<select name="goal" class="form-select">
<option value="mentinere">Menținere</option>
<option value="slabire">Slăbire (-500 kcal)</option>
<option value="ingrasare">Îngrășare (+500 kcal)</option>
</select>
</div>
<button type="submit" class="btn btn-success w-100">Calculează</button>
</form>
{% if rezultat %}
<div class="mt-4 alert alert-info text-center">
<h4>Ținta ta: {{ rezultat }} kcal / zi</h4>
</div>
<hr>
<h5>🤖 Cere meniu de la AI</h5>
<form action="/calculate" method="post">
<input type="hidden" name="weight" value="{{ request.form.weight }}">
<input type="hidden" name="height" value="{{ request.form.height }}">
<input type="hidden" name="age" value="{{ request.form.age }}">
<input type="hidden" name="gender" value="{{ request.form.gender }}">
<input type="hidden" name="activity" value="{{ request.form.activity }}">
<input type="hidden" name="goal" value="{{ request.form.goal }}">
<textarea name="preferences" class="form-control mb-2" placeholder="Ex: Sunt vegetarian, nu îmi place peștele..."></textarea>
<button type="submit" class="btn btn-outline-primary btn-sm w-100">Generează Meniu Personalizat</button>
</form>
{% endif %}
{% if meniu_ai %}
<div class="mt-4 p-3 border rounded bg-white">
<h6 class="text-primary font-weight-bold">Meniul tău generat:</h6>
<p style="white-space: pre-line;">{{ meniu_ai }}</p>
</div>
{% endif %}
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,2 @@
flask
openai==0.28.0

15
project1/Dockerfile Normal file
View File

@@ -0,0 +1,15 @@
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"]

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/")

49
project1/jenkinsfile Normal file
View File

@@ -0,0 +1,49 @@
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 'cd project1 && docker build -f Dockerfile -t web-checker-app .'
}
}
}
stage('Run Checker') {
steps {
script {
// Rulăm containerul
sh 'docker run --rm web-checker-app'
}
}
}
}
post {
failure {
script {
def discordUrl = "https://discord.com/api/webhooks/1471492658336891013/T5s6ZKZjJjDMHXc3k3jjZdk6m5EV12bKF1wda9d5I_gZJrsDZQ1m1m078IiLJWK38mqa"
def payload = """
{
"content": "🚨 **ALERTA JENKINS** 🚨\\n**Proiect:** ${env.JOB_NAME}\\n**Status:** FAILED ❌\\n**Build Nr:** ${env.BUILD_NUMBER}\\n**Detalii:** ${env.BUILD_URL}"
}
"""
// Trimitem notificarea folosind curl
sh "curl -H 'Content-Type: application/json' -d '${payload}' ${discordUrl}"
}
}
success {
echo "Totul a functionat perfect! Nu trimitem notificare pe Discord (ca sa nu facem spam)."
}
}
}

View File

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

11
project2/Dockerfile Normal file
View File

@@ -0,0 +1,11 @@
FROM python:3.9-slim
WORKDIR /app
RUN pip install --no-cache-dir requests
COPY famousquotes.py .
RUN touch quote.txt && chmod 666 quote.txt
CMD ["python", "famousquotes.py"]

28
project2/famousquotes.py Normal file
View File

@@ -0,0 +1,28 @@
import requests
def get_quote():
# API alternativ foarte stabil
url = "http://api.forismatic.com/api/1.0/?method=getQuote&format=json&lang=en"
try:
print(f"Obținem citat real de la {url}...")
response = requests.get(url, timeout=10)
response.raise_for_status()
data = response.json()
text = data.get('quoteText', 'Keep pushing forward.')
author = data.get('quoteAuthor', 'Unknown')
if not author.strip(): author = "Anonim"
output = f"📜 *\"{text}\"*\n\n✍️ **Autor:** {author}"
except Exception as e:
print(f"API indisponibil ({e}). Folosim rezerva locală...")
# Rezervă de calitate în caz de eroare rețea
output = "📜 *\"Success is not final, failure is not fatal: it is the courage to continue that counts.\"*\n\n✍️ **Autor:** Winston Churchill"
with open("quote.txt", "w", encoding="utf-8") as f:
f.write(output)
if __name__ == "__main__":
get_quote()

84
project2/jenkinsfile Normal file
View File

@@ -0,0 +1,84 @@
pipeline {
agent any
// Programarea automată a rulării la fiecare 5 minute
triggers {
cron('*/5 * * * *')
}
stages {
stage('Build') {
steps {
script {
dir('project2') {
// --no-cache asigură că Docker preia mereu ultima variantă a codului Python
sh "docker build --no-cache -t quotes-app ."
}
}
}
}
stage('Run & Extract') {
steps {
script {
dir('project2') {
// Curățăm preventiv containerul anterior
sh "docker rm -f quotes-worker || true"
try {
// Rulăm containerul cu DNS setat pentru a evita erorile de Name Resolution
sh "docker run --name quotes-worker --dns 8.8.8.8 quotes-app"
// Copiem fișierul generat din container în workspace-ul Jenkins
sh "docker cp quotes-worker:/app/quote.txt ."
} catch (e) {
echo "⚠️ Eroare la execuție, dar verificăm fișierul pentru notificare."
} finally {
sh "docker rm -f quotes-worker || true"
}
}
}
}
}
}
post {
always {
script {
def discordUrl = "https://discord.com/api/webhooks/1471492658336891013/T5s6ZKZjJjDMHXc3k3jjZdk6m5EV12bKF1wda9d5I_gZJrsDZQ1m1m078IiLJWK38mqa"
// Citirea citatului și gestionarea erorilor de fișier
def quoteContent = "Nu am putut citi citatul."
if (fileExists('project2/quote.txt')) {
quoteContent = readFile('project2/quote.txt').trim()
// Escapăm caracterele speciale pentru a nu strica formatul JSON
quoteContent = quoteContent.replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n')
}
def resultStatus = currentBuild.result ?: 'SUCCESS'
def statusEmoji = (resultStatus == 'SUCCESS') ? "✅" : "⚠️"
def header = "${statusEmoji} **Pipeline Automat (Build #${env.BUILD_NUMBER})**"
echo "🚀 Trimitere notificare către Discord..."
// Crearea payload-ului JSON manual (fără a depinde de plugin-ul writeJSON)
sh """
cat << 'EOF' > discord_payload.json
{
"content": "${header}\\n\\n${quoteContent}"
}
EOF
"""
// Trimiterea către Discord folosind curl
sh "curl -X POST -H 'Content-Type: application/json' --data-binary @discord_payload.json '${discordUrl}'"
// CURĂȚARE: Ștergem imaginile Docker inutile (dangling images) pentru a nu umple discul
sh "docker image prune -f"
// Curățăm workspace-ul curent
deleteDir()
}
}
}
}

View File

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

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

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