Rehber Güç Planı Yöneticisi

  • Konuyu başlatan Konuyu başlatan saydut
  • Başlangıç Tarihi Başlangıç Tarihi
  • Mesaj Mesaj 8
  • Görüntüleme Görüntüleme 537
Merhaba bir diğer projemi siz değerli arkadaşlarım ile paylaşmak istiyorum.
Program Windows'ta ayarladığınız (veya özelleştirdiğiniz) güç seçeneklerini hızlı bir şekilde değiştirmenize olanak sağlıyor.

Laptopumda etkin bir şekilde kullanmaktayım mesela oyun oynarken nihai performansta Web'de gezinirken ya da iş yaparken güç tasarrufunda çalışıyorum bu da sıcaklık ve güç kazancı olarak fayda sağlıyor. Özelikle laptop kullanan arkadaşlarıma öneririm.

Program yine açık kaynak kodlu kendi isteğinize göre özelleştirebilirsiniz.

İndirme linki: https://gitlab.com/saydut/power-plans-with-python/-/raw/main/mysetup.zip?ref_type=heads&inline=false

Kaynak kodları:
Python:
import os
import subprocess
import requests
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QGridLayout, QPushButton, QLineEdit, QMessageBox, QLabel
import re
import functools
import tempfile
import zipfile
import sys

class UpdateManager:
    def __init__(self, version_label):
        self.version_label = version_label
        self.parent = version_label.parent() if version_label else None  # Ebeveyn pencereyi almak için
        self.prog_ver_check()

    def apply_update(self, temp_exe_path, current_exe_path):
        try:
            os.replace(temp_exe_path, current_exe_path)
            return True
        except Exception as e:
            print(f"Hata: {e}")
            return False

    def download_update(self, url, dest_path):
        try:
            response = requests.get(url, stream=True)
            with open(dest_path, 'wb') as file:
                for chunk in response.iter_content(chunk_size=1024):
                    if chunk:
                        file.write(chunk)
        except Exception as e:
            print(f"Hata: {e}")

    def extract_zip(self, zip_path, extract_path):
        try:
            with zipfile.ZipFile(zip_path, 'r') as zip_ref:
                zip_ref.extractall(extract_path)
            return extract_path
        except Exception as e:
            print(f"Hata: {e}")
            return None

    def get_single_exe_in_directory(self, directory):
        exe_files = [f for f in os.listdir(directory) if f.lower().endswith('.exe') and os.path.isfile(os.path.join(directory, f))]

        if len(exe_files) == 1:
            return os.path.join(directory, exe_files[0])
        else:
            return None

    def create_update_script(self, temp_exe_path, current_exe_path):
        # Bat dosyasını oluştur
        bat_content = f'@echo off\n'
        bat_content += f'taskkill /IM "{os.path.basename(current_exe_path)}" /F\n'  # Uygulama kapat
        bat_content += f'ping 127.0.0.1 -n 2 > nul\n'  # Kısa bir bekleme
        bat_content += f'start "" "{temp_exe_path}"\n'
        bat_content += f'exit\n'  # Bat dosyasından çık
        bat_path = os.path.join(tempfile.gettempdir(), "update_script.bat")
        with open(bat_path, 'w') as bat_file:
            bat_file.write(bat_content)
        return bat_path

    def run_update_script(self, bat_path):
        try:
            subprocess.run(bat_path, shell=True)
            return True
        except Exception as e:
            print(f"Hata: {e}")
            return False

    def prog_ver_check(self):
        gitlab_url = "https://gitlab.com/saydut/power-plans-with-python/-/raw/main/version.txt?ref_type=heads"

        local_version = self.version_label.text().split(":")[-1].strip()

        try:
            response = requests.get(gitlab_url)
            remote_version_info = response.text.strip().split('\n')
            remote_version = remote_version_info[0]
            release_notes_start = response.text.find('*')
            release_notes = response.text[release_notes_start:].split('link=')[0].strip()
            update_link_start = response.text.find('link=')
            update_link = response.text[update_link_start + 5:].strip()

            if remote_version > local_version:
                # Yeni sürüm mevcut! Güncelleme yapılabilir.
                notes_response = requests.get(gitlab_url)
                release_notes = self.extract_release_notes(notes_response.text)

                result = QMessageBox.question(self.parent, "Yeni Sürüm", f"Yeni bir sürüm mevcut!\nGüncelleme yapmak ister misiniz?\n\n{release_notes}", QMessageBox.Yes | QMessageBox.No)

                if result == QMessageBox.Yes:
                    # Kullanıcı evet dediği durum
                    print("Güncelleme işlemleri burada başlayacak.")
                    temp_zip_path = os.path.join(tempfile.gettempdir(), "temp_update.zip")
                    temp_exe_path = os.path.join(tempfile.gettempdir(), "temp_update.exe")

                    # Zip dosyasını indir ve çıkar
                    self.download_update(update_link, temp_zip_path)
                    extracted_path = self.extract_zip(temp_zip_path, tempfile.gettempdir())  # Zip dosyasını çıkar
                    exe_path = self.get_single_exe_in_directory(extracted_path)  # Çıkarılan dizindeki tek exe dosyasını al

                    # Bat dosyasını oluştur ve çalıştır
                    bat_path = self.create_update_script(exe_path, sys.executable)
                    self.run_update_script(bat_path)
                   
                    # Güncelleme script'i çalıştıktan sonra programı kapat
                    sys.exit()
            else:
                print("Güncelleme yok.")
        except requests.RequestException as e:
            print(f"Hata: {e}")

    def extract_release_notes(self, version_txt_content):
        # version.txt içinden yenilik notlarını çıkar
        start_index = version_txt_content.find('*')
        if start_index != -1:
            end_index = version_txt_content.find('\n', start_index)
            if end_index != -1:
                release_notes = version_txt_content[start_index:end_index].strip('* \t\n')
                return release_notes
        return "Yenilik notları bulunamadı."

class PowerPlanChanger(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle("Güç Planı Değiştirici")
        self.setGeometry(100, 100, 250, 120)

        main_layout = QVBoxLayout()

        self.filter_edit = QLineEdit()
        self.filter_edit.setPlaceholderText("Filtreleme metni girin")
        self.filter_edit.hide()
        self.filter_edit.setReadOnly(True)
        self.filter_edit.setText("guid")
        self.filter_edit.textChanged.connect(self.refresh_power_plans)

        main_layout.addWidget(self.filter_edit)

        self.plan_layout = QGridLayout()

        main_layout.addLayout(self.plan_layout)

        self.setLayout(main_layout)

        self.selected_button = None  # Seçili buton için referans

        # Güncelleme işlevi ekleniyor
        self.version_label = QLabel("Sürüm: 2.1", parent=self)
        self.version_label.hide()  # Sürüm etiketini gizle

        self.update_manager = UpdateManager(self.version_label)
        self.refresh_power_plans()

    def refresh_power_plans(self):
        try:
            self.clear_plan_layout()

            output = subprocess.check_output(['powercfg', '/l'], shell=True, stderr=subprocess.STDOUT)
            plans = output.decode('utf-8', errors='ignore').split('\r\n')
            plans = [plan.strip() for plan in plans if plan.strip()]

            filter_text = self.filter_edit.text().strip().lower()

            row = 0
            col = 0
            marked_plan = None
            for plan in plans:
                if self.is_guid(filter_text) and filter_text in plan.lower():
                    plan_name = re.search(r'\((.*?)\)', plan).group(1)  # Parantez içindeki kısmı alıyoruz
                    btn = QPushButton(plan_name)
                    btn.clicked.connect(lambda checked, p=plan: self.on_button_clicked(btn, p))
                    self.plan_layout.addWidget(btn, row, col)
                    if '*' in plan:  # Eğer plan işaretlenmişse
                        marked_plan = btn
                    row += 1
                    if row > 5:
                        row = 0
                        col += 1
                elif not self.is_guid(filter_text) and filter_text in plan.lower():
                    plan_name = re.search(r'\((.*?)\)', plan).group(1)
                    btn = QPushButton(plan_name)
                    on_button_click = functools.partial(self.on_button_clicked, btn, plan)
                    btn.clicked.connect(on_button_click)
                    self.plan_layout.addWidget(btn, row, col)
                    if '*' in plan:
                        marked_plan = btn
                    row += 1
                    if row > 5:
                        row = 0
                        col += 1

            if marked_plan:  # İşaretli plan varsa
                self.change_button_color(marked_plan)

        except subprocess.CalledProcessError as e:
            print(f"Hata: {e.output}")

    def clear_plan_layout(self):
        for i in reversed(range(self.plan_layout.count())):
            widget = self.plan_layout.itemAt(i).widget()
            if widget is not None:
                widget.deleteLater()

    def is_guid(self, text):
        pattern = re.compile(r'^[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$')
        return bool(pattern.match(text))

    def apply_power_plan(self, plan):
        try:
            plan_guid = plan.split()[3]
            subprocess.run(['powercfg', '/setactive', plan_guid], capture_output=True)
            print(f"{plan} planı aktif edildi.")
        except Exception as e:
            print(f"Hata: {e}")

    def on_button_clicked(self, button, plan):
        self.apply_power_plan(plan)  # Güç planını uygula
   
        # Tüm butonların arka plan rengini varsayılan yap
        for row in range(self.plan_layout.rowCount()):
            for col in range(self.plan_layout.columnCount()):
                item = self.plan_layout.itemAtPosition(row, col)
                if item and item.widget():
                    item.widget().setStyleSheet("")

        # Tıklanan butonun arka plan rengini yeşil yap
        button.setStyleSheet("background-color: green; color: white;")

    def change_button_color(self, button):
        if self.selected_button and self.selected_button != button:
            self.selected_button.setStyleSheet("")
        self.selected_button = button
        self.selected_button.setStyleSheet("background-color: green; color: white;")

def main():
    app = QApplication(sys.argv)
    window = PowerPlanChanger()
    window.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()
 

Dosya Ekleri

  • Ekran görüntüsü 2024-01-24 003056.webp
    2,4 KB · Görüntüleme: 137
  • Ekran görüntüsü 2024-01-24 003108.webp
    2,6 KB · Görüntüleme: 141
  • Ekran görüntüsü 2024-01-24 003120.webp
    2,6 KB · Görüntüleme: 168
Windows 7 desteği var mıdır acaba?
 
Vallahi denemeniz gerek. Windows 11 ve 10 da kesin çalışır ama Windows 7 için bir şey diyemem. Eğer deneyip sonucu bildirirseniz sevinirim.
 
Program yine açık kaynak kodlu kendi isteğinize göre özelleştirebilirsiniz.
Amaç güzel, ellerinize sağlık ama bu kısım maalesef yanlış, her açık kaynak kodlu yazılım özgür yazılım değildir. Çünkü sizin projenizde bir lisans yok ve benim özelleştirmeleri yaparken uyacağım şartlar yok. Bu yüzden özelleştirmem mümkün değil, suç gibi bir şey olur.
Kaynaklar: Lisanssızlar, Neden Açık Kaynak Özgür Yazılımın Noktasını Kaçırıyor
 

Yorumunuz için teşekkür ederim bilmediğim bir şey öğrendim. Bu işlerde acemiyim henüz birkaç aydır bu işteyim biraz yardımcı olur musunuz nasıl bir lisans yapmam gerek? Şimdi sizin attıklarınızı inceledim söylediğiniz gibi özgür olmuyormuş. Bildiğiniz bir lisans var mı bunları özgür yazılım yapmak için?
 
Öncelikle kek gününüz kutlu olsun.

Bu tarz projeler için MIT, GPLv3, GPLv2 kullanabilirsiniz. Buradaki lisansları da inceleyebilirsiniz. Bir lisansı koymak için lisans içeriği kopyalayın ve LICENSE.txt diye bir dosyaya yapıştırın. Ayrıca projenizin hakkında bölümünde de seçtiğiniz lisansı belirtin. MIT kullanacaksanız gerekli yerleri (yıl ve holder yerini) değiştirmeyi unutmayın.
Örnek projeler:

Hasteneden çıktım, telefondayım anca yazabildim. Siz de çevrim dışı olmuşsunuz.
 

Öncelikle geçmiş olsun ve teşekkür ederim. Projelerime lisans textlerini ekledim. Gitlab üzerinde şu an projelerde "this project is licensed under the GNU general public license v3.0 or later" ibaresi var. Bütün projelerde şu an lisans görünüyor ama bir readme dosyası ekleme gereği hissetmedim umarım bir sorun olmaz. Buyurun link bu: saydut · GitLab umarım doğru yapmışımdır.
 
Rica ederim, sağ olun. Bir ara projelerinizin hakkında kısmına da "GPLv3 veya sonrası ile lisanslanmıştır." ibaresi eklerseniz daha da iyi olabilir. Ve README dosyası da şart değil, ileride ekleyip eklememek sizd kalmış ama eklerseniz yine lisans ibaresini yazarsınız. Bir de projenizin başına yorum satırı olarak şöyle bir şey eklemeniz iyi olabilir:
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <https: //www.gnu.org/licenses/>.
Ve her dosya da en başta yorum satırıyla şuna sahip olmalı:
Satır 1: Copyright (C) <year> <name of author>
Satır 2 Yöntem 1: <tam bildirimin olduğu yer>
Satır 2 Yöntem 2: This file is part of <program>.
Elbette <> olanların içini kendinize göre ayarlayın ve <> işaretini sonrasında kullanmayın. Örnek:
Copyright (C) 2024 MuKonqi
Bir de düzenleme yaptım, Xenforo otomatik link yapmış, onu düzelttim. Https'den sonraki boşluk olmayacak tabii ki. @saydut
 
Tamamdır teşekkür ederim şimdi bende hastaneye gideceğim en kısa zamanda ilgileneceğim tekrardan teşekkürler ilginiz için.
 
İfadeler: 320
Bu siteyi kullanmak için çerezler gereklidir. Siteyi kullanmaya devam etmek için çerezleri kabul etmelisiniz. Daha Fazlasını Öğren.…