├── requirements.txt
├── logos
├── README.md
├── 32x32.png
└── 512x512.png
├── LICENSE
├── README.md
├── index.html
├── db.json
└── main.py
/requirements.txt:
--------------------------------------------------------------------------------
1 | colorama
2 | requests==2.20
3 |
--------------------------------------------------------------------------------
/logos/README.md:
--------------------------------------------------------------------------------
1 | # credits:
2 | - @0penrc
3 |
4 | # preview:
5 |
--------------------------------------------------------------------------------
/logos/32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abrik1/xpykg/HEAD/logos/32x32.png
--------------------------------------------------------------------------------
/logos/512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abrik1/xpykg/HEAD/logos/512x512.png
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Abhiraj Rik
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## xpykg - manage software packages for Windows XP
2 | xpykg is a script for Windows XP which is capable of installing software
3 | packages so that users don't have to look on random webpages for software.
4 |
5 | xpykg downloads the setup.exe of the software package and then runs it.
6 | It also keeps track of the location of the uninstaller executable so that
7 | the user may easily uninstall the package when they need to.
8 |
9 | ### requirements:
10 | - Python 3.4
11 | - requests 2.20
12 | - colorama (colors are cool)
13 | - wmi (for Un_A.exe detection)
14 |
15 | **NOTE**: Right now it works only on Service Pack 3 for x86 and Service Pack 2 for x64 (DB needs some changes).
16 |
17 | ### todo:
18 | - [x] implement search
19 | - [x] implement sync
20 | - [x] implement list
21 | - [x] implement installing via msi or exe
22 | - [x] implement uninstalling
23 | - WIP, needs some more testing
24 |
25 | ### software:
26 | see db.json
27 |
28 | ## docs:
29 | see [the wiki](https://github.com/abrik1/xpykg/wiki)
30 |
31 | # contact:
32 | Join the `#xpykg` channel on irc.libera.chat, or see the [${\color{purple}discord\ server\colon}$](https://discord.gg/5Jwd7Sch88)
33 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | xpykg
4 |
50 |
51 |
52 |
53 |
54 | xpykg - a package manager for Windows XP
55 |
56 |
57 |
58 | xpykg is a package manager for Windows XP/ReactOS. It downloads files, runs setup.exe, and handles upgrades/uninstallations.
59 |
60 |
61 |
62 | usage:
63 |
64 |
65 |
66 |
67 | help: view this page
68 | install: install {pkg}
69 | list: show all the available apps
70 | search: search {pkg}
71 | sync: sync software databases
72 | uninstall: uninstall {pkg}
73 | upgrade: upgrade packages installed using xpkg
74 | version: show xpkg version
75 |
76 |
77 |
78 | packages:
79 |
80 | refer to this table here
81 |
82 |
83 | download:
84 |
85 | this page will redirect you to the github downloads page
86 |
87 |
88 | credits:
89 |
90 | - @retroretard_ for helping out with colors
91 | - github - their render of README.md as inspiration
92 |
93 |
94 | True/False
423 | determines whether a package is installed
424 | """
425 | if isfile("C:\\Program Files\\xpykg\\installed-packages") == True:
426 | with open("C:\\Program Files\\xpykg\\installed-packages", "r") as database:
427 | contents = database.read()
428 | for i in contents.splitlines():
429 | try:
430 | if literal_eval(i)[0] == pkgname:
431 | database.close()
432 | return True
433 | except SyntaxError:
434 | continue
435 |
436 | database.close()
437 | return False
438 | else:
439 | return False
440 |
441 |
442 | def get_installed_package_version(pkgname: str):
443 | """
444 | get_installed_package_version(pkgname)
445 | if pkgname is installed by xpykg, return its version
446 | """
447 |
448 | if is_installed(pkgname) == True:
449 | with open("C:\\Program Files\\xpykg\\installed-packages", "r") as database:
450 | contents = database.read().splitlines()
451 | for i in contents:
452 | if literal_eval(i)[0] == pkgname:
453 | database.close()
454 | return literal_eval(i)[1] # good output
455 | else:
456 | return 1 # bad output
457 |
458 |
459 | def arr_to_str(arr, optchar: str):
460 | nstr = ""
461 | for i in arr:
462 | nstr = nstr + i + optchar
463 |
464 | return nstr
465 |
466 |
467 | def uninstall_package(pkgname: str):
468 | """
469 | uninstall_package(pkgname): remove pkgname if installed by xpykg
470 | """
471 | if is_installed(pkgname) == True:
472 | with open("C:\\Program Files\\xpykg\\installed-packages", "r+") as ipkg:
473 | contents = ipkg.read().splitlines()
474 | index = 0
475 | remover = ""
476 | uninstall_type = ""
477 | for i in contents:
478 | try:
479 | if literal_eval(i)[0] == pkgname:
480 | index = contents.index(i)
481 | remover = literal_eval(i)[2]
482 | uninstall_type = literal_eval(i)[3]
483 | break
484 | except SyntaxError:
485 | continue
486 |
487 | remove = remover.split("\\")
488 | remove.pop(len(remove) - 1)
489 | chdir(arr_to_str(remove, "\\"))
490 |
491 | remover = remover.split("\\")[len(remover.split("\\")) - 1]
492 |
493 | print(
494 | "{}{}[xpykg:note]:{} loading remover for package {}{}{}".format(
495 | Style.BRIGHT,
496 | Fore.BLUE,
497 | Fore.RESET,
498 | Fore.YELLOW,
499 | pkgname,
500 | Fore.RESET,
501 | )
502 | )
503 | remove_status = system(remover)
504 | pkg_removed = False
505 |
506 | if remove_status == 0 and uninstall_type == "Normal":
507 | pkg_removed = True
508 | elif remove_status == 0 and uninstall_type == "nullsoftUninstaller":
509 | # using wmi check that Un_A.exe is running or not
510 | sleep(5)
511 | bin = ""
512 | while True:
513 | prcs = [] # array to store processes running
514 | for process in wmi.Win32_Process():
515 | prcs.append(process.Name)
516 |
517 | if "Un_A.exe" in prcs:
518 | bin = "Un_A.exe"
519 | elif "Au_.exe" in prcs:
520 | bin = "Au_.exe"
521 | elif (
522 | "Uninst.exe" in prcs
523 | ): # 7zip has a very similar uninstller to NSIS Installers.
524 | bin = "Uninst.exe"
525 |
526 | if (bin in prcs) == False:
527 | break # assumption that it has been uninstalled..
528 |
529 | if isfile(remover) == True:
530 | pkg_removed = False
531 | else:
532 | pkg_removed = True
533 | else:
534 | print(
535 | "{}{}[xpykg:error]:{} {}{}{} not removed".format(
536 | Style.BRIGHT,
537 | Fore.RED,
538 | Fore.RESET,
539 | Fore.YELLOW,
540 | pkgname,
541 | Fore.RESET,
542 | )
543 | )
544 | ipkg.close()
545 | return 1
546 |
547 | if pkg_removed == False:
548 | print(
549 | "{}{}[xpykg:error]: {}{}{} not removed".format(
550 | Style.BRIGHT, Fore.RED, Fore.YELLOW, pkgname, Fore.RESET
551 | )
552 | )
553 | return 1
554 | else:
555 | print(
556 | "{}{}[xpykg:success]: {}{}{} removed".format(
557 | Style.BRIGHT, Fore.GREEN, Fore.YELLOW, pkgname, Fore.RESET
558 | )
559 | )
560 | contents.pop(index)
561 | ncontent = ""
562 | for j in contents:
563 | ncontent = ncontent + j + "\n"
564 |
565 | ipkg.seek(0)
566 | ipkg.write(ncontent)
567 | ipkg.truncate()
568 | ipkg.close()
569 | return 0
570 | else:
571 | print(
572 | "{}{}[xpykg:error]:{} package {}{}{} not installed".format(
573 | Style.BRIGHT, Fore.RED, Fore.RESET, Fore.YELLOW, pkgname, Fore.RESET
574 | )
575 | )
576 | return 1
577 |
578 |
579 | def vtoi(version: str):
580 | """
581 | vtoi(version): convert a version to an integer... 22.10 -> 2210
582 | """
583 |
584 | ver = ""
585 |
586 | for i in version:
587 | try:
588 | ver = ver + str(int(i))
589 | except ValueError:
590 | continue
591 |
592 | return int(ver)
593 |
594 |
595 | def upgrade_packages():
596 | """
597 | upgrade_packages(): this function is a dummy for the upgrade function in xpykg
598 | """
599 |
600 | print(
601 | "{}{}[xpykg:warning]:{} xpykg no longer supports upgrading. remove and install the program to upgrade it.".format(
602 | Style.BRIGHT, Fore.YELLOW, Fore.RESET
603 | )
604 | return 1
605 |
606 |
607 | if __name__ == "__main__":
608 | try:
609 | if argv[1] in ["-h", "help", "--help"]:
610 | print(
611 | """xpykg: a script for software management for Windows XP
612 | =====================================================
613 | help: view this page
614 | install: install
615 | list: show all the available apps
616 | search: search
617 | sync: sync software databases
618 | uninstall: uninstall
619 | upgrade: upgrade packages installed using xpykg
620 | version: show xpykg version"""
621 | )
622 | elif argv[1] in ["-v", "version", "--version"]:
623 | print("[xpykg:version]: {}".format(xpykg_version))
624 | elif argv[1] in ["-S", "sync", "--sync"]:
625 | sync_database()
626 | elif argv[1] in ["-l", "list", "--list"]:
627 | list_packages()
628 | elif argv[1] in ["-s", "search", "--search"] and len(argv) == 3:
629 | search_packages(argv[2])
630 | elif argv[1] in ["-i", "install", "--install"]:
631 | if len(argv) == 3:
632 | install_package(argv[2])
633 | else:
634 | for i in range(2, len(argv)):
635 | install_package(argv[i])
636 | elif argv[1] in ["-u", "uninstall", "--uninstall"]:
637 | if len(argv) == 3:
638 | uninstall_package(argv[2])
639 | else:
640 | for i in range(2, len(argv)):
641 | uninstall_package(argv[i])
642 | elif argv[1] in ["-U", "upgrade", "--upgrade"]:
643 | upgrade_packages()
644 | else:
645 | print(
646 | "{}{}[xpykg:error]:{} invalid argument or not sufficient arguements".format(
647 | Style.BRIGHT, Fore.RED, Fore.RESET
648 | )
649 | )
650 | exit(1)
651 | except IndexError:
652 | print(
653 | "{}{}[xpykg:error]:{} invalid argument or not sufficient arguments".format(
654 | Style.BRIGHT, Fore.RED, Fore.RESET
655 | )
656 | )
657 | exit(1)
658 | except KeyboardInterrupt:
659 | print(
660 | "{}{}[xpykg:error]:{} keyboard exit detected".format(
661 | Style.BRIGHT, Fore.RED, Fore.RESET
662 | )
663 | )
664 | exit(1)
665 | except PermissionError:
666 | print(
667 | "{}{}[xpykg:error]:{} please run xpykg as Administrator".format(
668 | Style.BRIGHT, Fore.RED, Fore.RESET
669 | )
670 | )
671 | exit(1)
672 |
--------------------------------------------------------------------------------