diff --git a/LanguageCodes.json b/LanguageCodes.json new file mode 100644 index 0000000..4c4aac6 --- /dev/null +++ b/LanguageCodes.json @@ -0,0 +1,738 @@ +[ + { + "code": "ab", + "name": "Abkhaz" + }, + { + "code": "aa", + "name": "Afar" + }, + { + "code": "af", + "name": "Afrikaans" + }, + { + "code": "ak", + "name": "Akan" + }, + { + "code": "sq", + "name": "Albanian" + }, + { + "code": "am", + "name": "Amharic" + }, + { + "code": "ar", + "name": "Arabic" + }, + { + "code": "an", + "name": "Aragonese" + }, + { + "code": "hy", + "name": "Armenian" + }, + { + "code": "as", + "name": "Assamese" + }, + { + "code": "av", + "name": "Avaric" + }, + { + "code": "ae", + "name": "Avestan" + }, + { + "code": "ay", + "name": "Aymara" + }, + { + "code": "az", + "name": "Azerbaijani" + }, + { + "code": "bm", + "name": "Bambara" + }, + { + "code": "ba", + "name": "Bashkir" + }, + { + "code": "eu", + "name": "Basque" + }, + { + "code": "be", + "name": "Belarusian" + }, + { + "code": "bn", + "name": "Bengali; Bangla" + }, + { + "code": "bh", + "name": "Bihari" + }, + { + "code": "bi", + "name": "Bislama" + }, + { + "code": "bs", + "name": "Bosnian" + }, + { + "code": "br", + "name": "Breton" + }, + { + "code": "bg", + "name": "Bulgarian" + }, + { + "code": "my", + "name": "Burmese" + }, + { + "code": "ca", + "name": "Catalan; Valencian" + }, + { + "code": "ch", + "name": "Chamorro" + }, + { + "code": "ce", + "name": "Chechen" + }, + { + "code": "ny", + "name": "Chichewa; Chewa; Nyanja" + }, + { + "code": "zh", + "name": "Chinese" + }, + { + "code": "cv", + "name": "Chuvash" + }, + { + "code": "kw", + "name": "Cornish" + }, + { + "code": "co", + "name": "Corsican" + }, + { + "code": "cr", + "name": "Cree" + }, + { + "code": "hr", + "name": "Croatian" + }, + { + "code": "cs", + "name": "Czech" + }, + { + "code": "da", + "name": "Danish" + }, + { + "code": "dv", + "name": "Divehi; Dhivehi; Maldivian;" + }, + { + "code": "nl", + "name": "Dutch" + }, + { + "code": "dz", + "name": "Dzongkha" + }, + { + "code": "en", + "name": "English" + }, + { + "code": "eo", + "name": "Esperanto" + }, + { + "code": "et", + "name": "Estonian" + }, + { + "code": "ee", + "name": "Ewe" + }, + { + "code": "fo", + "name": "Faroese" + }, + { + "code": "fj", + "name": "Fijian" + }, + { + "code": "fi", + "name": "Finnish" + }, + { + "code": "fr", + "name": "French" + }, + { + "code": "ff", + "name": "Fula; Fulah; Pulaar; Pular" + }, + { + "code": "gl", + "name": "Galician" + }, + { + "code": "ka", + "name": "Georgian" + }, + { + "code": "de", + "name": "German" + }, + { + "code": "el", + "name": "Greek, Modern" + }, + { + "code": "gn", + "name": "Guaraní" + }, + { + "code": "gu", + "name": "Gujarati" + }, + { + "code": "ht", + "name": "Haitian; Haitian Creole" + }, + { + "code": "ha", + "name": "Hausa" + }, + { + "code": "he", + "name": "Hebrew (modern)" + }, + { + "code": "hz", + "name": "Herero" + }, + { + "code": "hi", + "name": "Hindi" + }, + { + "code": "ho", + "name": "Hiri Motu" + }, + { + "code": "hu", + "name": "Hungarian" + }, + { + "code": "ia", + "name": "Interlingua" + }, + { + "code": "id", + "name": "Indonesian" + }, + { + "code": "ie", + "name": "Interlingue" + }, + { + "code": "ga", + "name": "Irish" + }, + { + "code": "ig", + "name": "Igbo" + }, + { + "code": "ik", + "name": "Inupiaq" + }, + { + "code": "io", + "name": "Ido" + }, + { + "code": "is", + "name": "Icelandic" + }, + { + "code": "it", + "name": "Italian" + }, + { + "code": "iu", + "name": "Inuktitut" + }, + { + "code": "ja", + "name": "Japanese" + }, + { + "code": "jv", + "name": "Javanese" + }, + { + "code": "kl", + "name": "Kalaallisut, Greenlandic" + }, + { + "code": "kn", + "name": "Kannada" + }, + { + "code": "kr", + "name": "Kanuri" + }, + { + "code": "ks", + "name": "Kashmiri" + }, + { + "code": "kk", + "name": "Kazakh" + }, + { + "code": "km", + "name": "Khmer" + }, + { + "code": "ki", + "name": "Kikuyu, Gikuyu" + }, + { + "code": "rw", + "name": "Kinyarwanda" + }, + { + "code": "ky", + "name": "Kyrgyz" + }, + { + "code": "kv", + "name": "Komi" + }, + { + "code": "kg", + "name": "Kongo" + }, + { + "code": "ko", + "name": "Korean" + }, + { + "code": "ku", + "name": "Kurdish" + }, + { + "code": "kj", + "name": "Kwanyama, Kuanyama" + }, + { + "code": "la", + "name": "Latin" + }, + { + "code": "lb", + "name": "Luxembourgish, Letzeburgesch" + }, + { + "code": "lg", + "name": "Ganda" + }, + { + "code": "li", + "name": "Limburgish, Limburgan, Limburger" + }, + { + "code": "ln", + "name": "Lingala" + }, + { + "code": "lo", + "name": "Lao" + }, + { + "code": "lt", + "name": "Lithuanian" + }, + { + "code": "lu", + "name": "Luba-Katanga" + }, + { + "code": "lv", + "name": "Latvian" + }, + { + "code": "gv", + "name": "Manx" + }, + { + "code": "mk", + "name": "Macedonian" + }, + { + "code": "mg", + "name": "Malagasy" + }, + { + "code": "ms", + "name": "Malay" + }, + { + "code": "ml", + "name": "Malayalam" + }, + { + "code": "mt", + "name": "Maltese" + }, + { + "code": "mi", + "name": "MÄori" + }, + { + "code": "mr", + "name": "Marathi (MarÄá¹­hÄ«)" + }, + { + "code": "mh", + "name": "Marshallese" + }, + { + "code": "mn", + "name": "Mongolian" + }, + { + "code": "na", + "name": "Nauru" + }, + { + "code": "nv", + "name": "Navajo, Navaho" + }, + { + "code": "nb", + "name": "Norwegian BokmÃ¥l" + }, + { + "code": "nd", + "name": "North Ndebele" + }, + { + "code": "ne", + "name": "Nepali" + }, + { + "code": "ng", + "name": "Ndonga" + }, + { + "code": "nn", + "name": "Norwegian Nynorsk" + }, + { + "code": "no", + "name": "Norwegian" + }, + { + "code": "ii", + "name": "Nuosu" + }, + { + "code": "nr", + "name": "South Ndebele" + }, + { + "code": "oc", + "name": "Occitan" + }, + { + "code": "oj", + "name": "Ojibwe, Ojibwa" + }, + { + "code": "cu", + "name": "Old Church Slavonic, Church Slavic, Church Slavonic, Old Bulgarian, Old Slavonic" + }, + { + "code": "om", + "name": "Oromo" + }, + { + "code": "or", + "name": "Oriya" + }, + { + "code": "os", + "name": "Ossetian, Ossetic" + }, + { + "code": "pa", + "name": "Panjabi, Punjabi" + }, + { + "code": "pi", + "name": "PÄli" + }, + { + "code": "fa", + "name": "Persian (Farsi)" + }, + { + "code": "pl", + "name": "Polish" + }, + { + "code": "ps", + "name": "Pashto, Pushto" + }, + { + "code": "pt", + "name": "Portuguese" + }, + { + "code": "qu", + "name": "Quechua" + }, + { + "code": "rm", + "name": "Romansh" + }, + { + "code": "rn", + "name": "Kirundi" + }, + { + "code": "ro", + "name": "Romanian, [])" + }, + { + "code": "ru", + "name": "Russian" + }, + { + "code": "sa", + "name": "Sanskrit (Saá¹ská¹›ta)" + }, + { + "code": "sc", + "name": "Sardinian" + }, + { + "code": "sd", + "name": "Sindhi" + }, + { + "code": "se", + "name": "Northern Sami" + }, + { + "code": "sm", + "name": "Samoan" + }, + { + "code": "sg", + "name": "Sango" + }, + { + "code": "sr", + "name": "Serbian" + }, + { + "code": "gd", + "name": "Scottish Gaelic; Gaelic" + }, + { + "code": "sn", + "name": "Shona" + }, + { + "code": "si", + "name": "Sinhala, Sinhalese" + }, + { + "code": "sk", + "name": "Slovak" + }, + { + "code": "sl", + "name": "Slovene" + }, + { + "code": "so", + "name": "Somali" + }, + { + "code": "st", + "name": "Southern Sotho" + }, + { + "code": "es", + "name": "Spanish; Castilian" + }, + { + "code": "su", + "name": "Sundanese" + }, + { + "code": "sw", + "name": "Swahili" + }, + { + "code": "ss", + "name": "Swati" + }, + { + "code": "sv", + "name": "Swedish" + }, + { + "code": "ta", + "name": "Tamil" + }, + { + "code": "te", + "name": "Telugu" + }, + { + "code": "tg", + "name": "Tajik" + }, + { + "code": "th", + "name": "Thai" + }, + { + "code": "ti", + "name": "Tigrinya" + }, + { + "code": "bo", + "name": "Tibetan Standard, Tibetan, Central" + }, + { + "code": "tk", + "name": "Turkmen" + }, + { + "code": "tl", + "name": "Tagalog" + }, + { + "code": "tn", + "name": "Tswana" + }, + { + "code": "to", + "name": "Tonga (Tonga Islands)" + }, + { + "code": "tr", + "name": "Turkish" + }, + { + "code": "ts", + "name": "Tsonga" + }, + { + "code": "tt", + "name": "Tatar" + }, + { + "code": "tw", + "name": "Twi" + }, + { + "code": "ty", + "name": "Tahitian" + }, + { + "code": "ug", + "name": "Uyghur, Uighur" + }, + { + "code": "uk", + "name": "Ukrainian" + }, + { + "code": "ur", + "name": "Urdu" + }, + { + "code": "uz", + "name": "Uzbek" + }, + { + "code": "ve", + "name": "Venda" + }, + { + "code": "vi", + "name": "Vietnamese" + }, + { + "code": "vo", + "name": "Volapük" + }, + { + "code": "wa", + "name": "Walloon" + }, + { + "code": "cy", + "name": "Welsh" + }, + { + "code": "wo", + "name": "Wolof" + }, + { + "code": "fy", + "name": "Western Frisian" + }, + { + "code": "xh", + "name": "Xhosa" + }, + { + "code": "yi", + "name": "Yiddish" + }, + { + "code": "yo", + "name": "Yoruba" + }, + { + "code": "za", + "name": "Zhuang, Chuang" + }, + { + "code": "zu", + "name": "Zulu" + } +] diff --git a/WikiSearch.iss b/WikiSearch.iss new file mode 100644 index 0000000..22b21e8 --- /dev/null +++ b/WikiSearch.iss @@ -0,0 +1,51 @@ +#define MyAppName "WikiSearch" +#define MyAppVersion "1.0.0" +#define MyAppPublisher "Tecwindow" +#define MyAppURL "https://t.me/tecwindow" +#define MyAppExeName "WikiSearch.exe" + +[Setup] +AppName={#myAppName} +AppVersion={#MyAppVersion} +VersionInfoDescription=WikiSearch setup +VersionInfoVersion={#MyAppVersion} +VersionInfoCompany=tecwindow +VersionInfoCopyright=copyright, ©2022; tecwindow +VersionInfoProductName=WikiSearch +VersionInfoProductVersion={#MyAppVersion} +VersionInfoOriginalFileName=WikiSearch_Setup.exe +AppPublisherURL={#MyAppURL} +AppSupportURL={#MyAppURL} +AppUpdatesURL={#MyAppURL} +AppId={{F3679719-7471-4B3A-A60D-A9BF0B44E7B3} + +DefaultDirName={autopf}\{#MyAppName} +DisableProgramGroupPage=yes +; Uncomment the following line to run in non administrative install mode (install for current user only.) +PrivilegesRequired=admin +OutputDir=D:\python\æíßíÈíÏíÇ\dist\ahm +OutputBaseFilename=WikiSearchSetup +Compression=lzma +CloseApplications=force +restartApplications=yes +SolidCompression=yes +WizardStyle=modern + +[Languages] +Name: "english"; MessagesFile: "compiler:Default.isl" + +[Tasks] +Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}" + +[Files] +Source: "D:\python\æíßíÈíÏíÇ\dist\WikiSearch\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion +Source: "D:\python\æíßíÈíÏíÇ\dist\WikiSearch\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs +; NOTE: Don't use "Flags: ignoreversion" on any shared system files + +[Icons] +Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" +Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon + +[Run] +Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall + diff --git a/WikiSearch.py b/WikiSearch.py new file mode 100644 index 0000000..42b35a8 --- /dev/null +++ b/WikiSearch.py @@ -0,0 +1,168 @@ +#-*- coding: utf-8 -*- +# import project libraries. +import wx +import json +import nlpia2_wikipedia as wikipedia +import threading +import webbrowser +import os +from urllib.request import urlopen +from view_search_dialog import ViewSearch +from update_dialog import UpdateDialog + +# Create app with wx. +app= wx.App() + +# Include List of languages in JSON format. +# Check existence of file before running program. +try: + with open('LanguageCodes.json') as json_file: + data = json.load(json_file) +except FileNotFoundError: + wx.MessageBox("Some required files are missing.", "Error", style=wx.ICON_ERROR) + Exit() + +# Create empty list +name = [] +code = [] + +# Include json file content and add it to list. +for w in data: + name.append(w["name"]) + code.append(w["code"]) + +# information of program +CurrntVersion = 1.0 +ProgramName = "WikiSearch" +ProgramDescription = "With this program, you can search or browse any Wikipedia article. site: https://t.me/tecwindow" + +# Create main window with wx. + +class window(wx.Frame): + def __init__(self): + super().__init__(None, title = ProgramName, size=(400, 335)) + #make window in center. + self.Center() + #make window Minimum size. + self.Maximize(False) + self.EnableMaximizeButton(False) + + + # Creating panel + Panel = wx.Panel(self) + + # Creating ComboBox for languages + wx.StaticText(Panel, -1, "Choose the search language:", pos=(15,70), size=(380, 30)) + self.LanguageSearch = wx.ComboBox(Panel, -1, pos=(15, 100), size=(120, 40), style=wx.CB_READONLY+wx.CB_SORT) + self.LanguageSearch.SetItems(name) + self.LanguageSearch.Selection = 6 + + # Creating search edit + wx.StaticText(Panel, -1, "Enter your search", pos=(160,70), size=(380, 30)) + self.SearchText = wx.TextCtrl(Panel, -1, pos=(160, 100), size=(200, 30)) + + # Creating Buttons + self.StartSearch = wx.Button(Panel, -1, "start search", pos=(10,235), size=(120,30)) + self.StartSearch.SetDefault() + self.StartSearch.Enabled = False + self.Close = wx.Button(Panel, -1, "Close the program", pos=(250,235), size=(120,30)) + + #creating menu bar + menubar = wx.MenuBar() + Help = wx.Menu() + HelpFile = Help.Append(-1, "Help file \tF1") + AboutProgramItem = Help.Append(-1, "About") + ContactMenu = wx.Menu() + TecWindow=ContactMenu.Append(-1, "TecWindow on Telegram") + QaisAlrefai=ContactMenu.Append(-1, "Qais Alrefai on Telegram") + MahmoodAtef=ContactMenu.Append(-1, "mahmoodatef on Telegram") + MesterPerfect = ContactMenu.Append(-1, "MesterPerfect on Telegram") + Help.AppendSubMenu(ContactMenu, "Contact us") + self.CheckForItem = Help.Append(-1, "Check for update") + menubar.Append(Help, "help") + self.SetMenuBar(menubar) + + # Show Main window + self.Show() + + # events for buttons + self.StartSearch.Bind(wx.EVT_BUTTON, self.OnViewSearch) + self.Close.Bind(wx.EVT_BUTTON, self.OnClose) + #events for menu items + self.Bind(wx.EVT_MENU, self.OnAboutProgram, AboutProgramItem) + self.Bind(wx.EVT_MENU, self.OnCheckForItem, self.CheckForItem) + self.Bind(wx.EVT_MENU, lambda event: webbrowser.open_new("https://t.me/TecWindow"), TecWindow) + self.Bind(wx.EVT_MENU, lambda event: webbrowser.open_new("https://t.me/QaisAlrefai"), QaisAlrefai) + self.Bind(wx.EVT_MENU, lambda event: webbrowser.open_new("https://t.me/MahmoodAtef"), MahmoodAtef) + self.Bind(wx.EVT_MENU, lambda event: webbrowser.open_new("https://t.me/MesterPerfect"), MesterPerfect) + self.Bind(wx.EVT_MENU, lambda event: os.startfile("help me.html"), HelpFile) + self.Bind(wx.EVT_CLOSE, self.OnClose) + self.SearchText.Bind(wx.EVT_TEXT, lambda event: check().start()) + + + #creating OnClose function to Close Program. + def OnClose(self, event): + wx.Exit() + + #creating OnAboutProgram function to show information about this program. + def OnAboutProgram(self, event): + wx.MessageBox(F"""{ProgramName} Version {CurrntVersion}. +{ProgramDescription} + This program was developed by: +Ahmed Bakr. +Qais Alrifai. +Mahmoud Atef.""", "About the program") + + #creating OnViewSearch function to show search results + def OnViewSearch(self, event): + #Set language for search + try: + wikipedia.set_lang(code[self.LanguageSearch.GetSelection()]) + except: + wx.MessageBox("there is no internet connection ", "Connection error", style=wx.ICON_ERROR) + return None + + #geting text of search + TextSearch = self.SearchText.Value + #Show dialog of search results + dialog1 = ViewSearch(self, TextSearch) + #start thread function to add search results for list box in dialog. + thread1 = threading.Thread(target=dialog1.OpenThread, daemon=True) + thread1.start() + + #creating function to check for update + def OnCheckForItem(self, event): + #geting the recent version from online info file. + url = "https://raw.githubusercontent.com/tecwindow/WikiSearch/main/WikiSearch.json" + try: + response = urlopen(url) + except: + wx.MessageBox("there is no internet connection ", "Connection error", style=wx.ICON_ERROR) + return None + data_json = json.loads(response.read()) + RecentVersion = float(data_json["version"]) + #Show the update dialog if there is new version. + if RecentVersion > CurrntVersion: + UpdateDialog(self) + #if there is no new version show MessageBox tell that. + else: + wx.MessageBox(f"You are using version {CurrntVersion} which is the latest version.", "No update available") + +# creating thread to disable start search buttion if search edit is empty. +class check(threading.Thread): + def __init__(self): + super(check, self).__init__() + + def run(self): + if main_window.SearchText.IsEmpty(): + main_window.StartSearch.Enabled = False + else: + main_window.StartSearch.Enabled = True + + + + + + +main_window = window() +app.MainLoop() \ No newline at end of file diff --git a/change_theme_dialog.py b/change_theme_dialog.py new file mode 100644 index 0000000..c765cd1 --- /dev/null +++ b/change_theme_dialog.py @@ -0,0 +1,26 @@ +#-*- coding: utf-8 -*- +# import project libraries. +import wx + +colourList = ["Aquamarine", "Black", "Blue", "Blue Violet", "Brown", "Cadet Blue", "Coral", "Cornflower Blue", "Cyan", "Dark Grey", "Dark Green", "Brown"] + +class ChangeTheme(wx.Dialog): + + def __init__(self): + super().__init__(None, title = "change theme", size=(200, 200)) + self.Center() + self.Maximize(False) + Panel = wx.Panel(self) + wx.StaticText(Panel, -1, "Choose theme", pos=(20,20), size=(80, 30)) + self.ChangeTheme = wx.ComboBox(Panel, -1, pos=(20, 50), size=(140, 40), style=wx.CB_READONLY+wx.CB_SORT) + self.ChangeTheme.SetItems(colourList) + # Create Buttons + self.Change = wx.Button(Panel, -1, "change", pos=(20,100), size=(60,30)) + self.Change.SetDefault() + self.Close = wx.Button(Panel, wx.ID_CANCEL, "Cancel", pos=(90,100), size=(60,30)) + + self.Change.Bind(wx.EVT_BUTTON, self.OnChangeTheme) + + def OnChangeTheme(self, event): + self.EndModal(self.ChangeTheme.Selection) + diff --git a/file_version_info.py b/file_version_info.py new file mode 100644 index 0000000..e5fa819 --- /dev/null +++ b/file_version_info.py @@ -0,0 +1,12 @@ +import pyinstaller_versionfile + +pyinstaller_versionfile.create_versionfile( + output_file="versionfile.txt", + version="1.0", + company_name="TecWindow", + file_description="With this program, you can search or browse any Wikipedia article. site: https://t.me/tecwindow", + internal_name="WikiSearch", + legal_copyright="© My TecWindow Company. All rights reserved.", + original_filename="WikiSearch.exe", + product_name="WikiSearch" +) diff --git a/help me.html b/help me.html new file mode 100644 index 0000000..0f39aa2 --- /dev/null +++ b/help me.html @@ -0,0 +1,29 @@ +

WikiSearch

+

repository: https://github.com/tecwindow/WikiSearch

+

Program function:

+

This simple program enables you to search Wikipedia, the free encyclopedia, without having to open your browser.

+

Features

+ +

Notes:

+ +

Program developers:

+ + \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..d702143 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +wxpython +nlpia2_wikipedia +pyperclip \ No newline at end of file diff --git a/update_dialog.py b/update_dialog.py new file mode 100644 index 0000000..d5701ff --- /dev/null +++ b/update_dialog.py @@ -0,0 +1,96 @@ +#-*- coding: utf-8 -*- +# import project libraries. +import wx +import threading +import requests +from urllib.request import urlopen +import os +import json +import subprocess + +#geting what's new and download ling from online info file. +try: +# url = "https://mx-blind.com/WikiSearch/WikiSearch.json" + url = "https://raw.githubusercontent.com/tecwindow/WikiSearch/main/WikiSearch.json" + response = urlopen(url) + data_json = json.loads(response.read()) + whatIsNew = data_json["What's new"] + DownloadLink = data_json["url"] +except: + pass + +#extracting the name file and geting temp path. +try: + file_name = DownloadLink.split('/')[-1] + temp = os.getenv("temp") + path = str(temp+"/"+file_name) +except: + path = "" + +#Delete setup file if is found in temp. +if os.path.exists(path): + os.remove(path) + + + +#creating update dialog +class UpdateDialog(wx.Dialog): + def __init__(self, parent): + super().__init__(None, title = "there is an update", size=(300, 300)) + self.Center() + self.Maximize(False) + + #creating panel + Panel = wx.Panel(self) + + #creating field to show what's new. + wx.StaticText(Panel, -1, "What's new in this version?", pos=(20,20), size=(170, 30)) + self.WhatsNew = wx.TextCtrl(Panel, -1, value=f"{whatIsNew}", pos=(10,60), size=(250,90)) + + # Creating Buttons + self.Update = wx.Button(Panel, -1, "Update", pos=(20,200), size=(60,30)) + self.Update.SetDefault() + self.Close = wx.Button(Panel, wx.ID_CANCEL, "Cancel", pos=(90,200), size=(60,30)) + + #show the dialog + self.Show() + + #event for update button + self.Update.Bind(wx.EVT_BUTTON, self.OnDownloadUpdate) + + #creating OnDownloadUpdate function to show progress dialog. + def OnDownloadUpdate(self, event): + ProgressDialog = progress_dialog("downloading update", "please wait", maximum=100, parent=self, style=wx.PD_CAN_ABORT) + + +#creating progress dialog +class progress_dialog(wx.ProgressDialog): + def __init__(self, *args, **kwargs): + wx.ProgressDialog.__init__(self, *args, **kwargs) + + self.handle = kwargs["parent"] + + #making downloading function in thread to download update. + threading.Thread(target=self.downloading, daemon=True).start() + + #creating downloading function + def downloading(self): + f = open(path, 'wb') + with requests.get(DownloadLink, stream=True) as r: + downloaded=0 + total = int(r.headers['content-length']) + for i in r.iter_content(chunk_size=1024): + if self.WasCancelled(): + self.Destroy() + f.close() + os.remove(path) + self.handle.Destroy() + return None + downloaded+=len(i) + progress = int((downloaded/total)*100) + f.write(i) + if progress == 100: + f.close() + subprocess.run([path, "/SILENT", "/VERYSILENT", "/SUPPRESSMSGBOXES"]) + self.Update(progress) + diff --git a/view_article_window.py b/view_article_window.py new file mode 100644 index 0000000..009ea35 --- /dev/null +++ b/view_article_window.py @@ -0,0 +1,122 @@ +#-*- coding: utf-8 -*- +# import project libraries. +import wx +import nlpia2_wikipedia as wikipedia +import pyperclip +from change_theme_dialog import ChangeTheme +import os + +colourList = ["Aquamarine", "Black", "Blue", "Blue Violet", "Brown", "Cadet Blue", "Coral", "Cornflower Blue", "Cyan", "Dark Grey", "Dark Green", "Brown"] + +#View Article window +class ViewArticleWindow(wx.Frame): + def __init__(self, parent, GetValues, handle): + super().__init__(parent, title="View Article", size=(560, 600)) + self.Center() + self.EnableMaximizeButton(False) + self.GetValues = GetValues + self.Content = "" + self.url = "" + self.title = "" + self.handle = handle + + + Panel = wx.Panel(self) + # Create Menus. + menubar = wx.MenuBar() + actions = wx.Menu() + CopyArticleItem = actions.Append(-1, "Copy article ctrl+1") + CopyArticleLinkItem = actions.Append(-1, "Copy article link ctrl+2") + SaveArticleItem = actions.Append(-1, "save article ctrl+3") + ChangeThemeItem = actions.Append(-1, "change Theme ctrl+4") + CloseArticleItem = actions.Append(-1, "close article window ctrl+5") + CloseProgramItem = actions.Append(-1, "Close the program ctrl+6") + menubar.Append(actions, "Actions") + self.SetMenuBar(menubar) + + # Create RichEdit to View Article Content + self.ArticleTitle = wx.StaticText(Panel, -1, "please wait:", pos=(10,10), size=(380,30)) + self.ViewArticle = wx.TextCtrl(Panel, -1, pos=(30,40), size=(480,420), style=wx.TE_RICH2+wx.TE_MULTILINE+wx.TE_READONLY) + + + # Create Buttons + self.CopyArticle = wx.Button(Panel, -1, "Copy article", pos=(10,500), size=(120,30)) + self.SaveArticle = wx.Button(Panel, -1, "save article", pos=(140,500), size=(120,30)) + self.SaveArticle.SetDefault() + self.CopyArticleLink = wx.Button(Panel, -1, "Copy article link", pos=(270,500), size=(120,30)) + self.CloseArticle = wx.Button(Panel, -1, "Close", pos=(400,500), size=(120,30)) + + # Show Article window + self.Show() + + # events for buttons + self.CopyArticle.Bind(wx.EVT_BUTTON, self.OnCopyArticle) + self.SaveArticle.Bind(wx.EVT_BUTTON, self.OnSaveArticle) + self.CopyArticleLink.Bind(wx.EVT_BUTTON, self.OnCopyArticleLink) + self.CloseArticle.Bind(wx.EVT_BUTTON, self.OnCloseArticle) + + # events for Menus + self.Bind(wx.EVT_MENU, self.OnCopyArticle, CopyArticleItem) + self.Bind(wx.EVT_MENU, self.OnCopyArticleLink, CopyArticleLinkItem) + self.Bind(wx.EVT_MENU, self.OnSaveArticle, SaveArticleItem) + self.Bind(wx.EVT_MENU, self.OnCloseArticle, CloseArticleItem) + self.Bind(wx.EVT_MENU, self.OnChangeTheme, ChangeThemeItem) + self.Bind(wx.EVT_MENU, self.OnCloseProgram, CloseProgramItem) + + def OpenThread(self): + try: + self.Content = wikipedia.page(self.GetValues).content + except wikipedia.exceptions.DisambiguationError as e: + mgb = wx.MessageDialog(self, """This article is no longer available. +do you want to show similar results for this article? +""", "warning", style=wx.YES_NO+wx.YES_DEFAULT+wx.ICON_QUESTION) + if mgb.ShowModal() == wx.ID_YES: + self.Destroy() +# wx.Window.Close(self.handle) + self.handle.ListResults.SetItems(e.options) + else: + self.Destroy() + return None + self.url = wikipedia.page(self.GetValues).url + self.title = wikipedia.page(self.GetValues).title + self.ViewArticle.Value = self.Content + self.SetTitle(f"View {self.title}") + self.ArticleTitle.SetLabel(self.title) + + # Copy Article Content + def OnCopyArticle(self, event): + pyperclip.copy(self.Content) + + # Copy Article Link + def OnCopyArticleLink(self, event): + pyperclip.copy(self.url) + + # Save Article On a New File. + def OnSaveArticle(self, event): + SaveFile = wx.FileDialog(self, F"Save {self.title}:", "self.FilePath", F"{self.title}", style=wx.FD_SAVE+wx.FD_OVERWRITE_PROMPT) + SaveFile.Wildcard = "Text files (.txt)|*.txt" + SaveFileResult = SaveFile.ShowModal() + if SaveFileResult == wx.ID_OK: + FilePath = SaveFile.Path + #FileName = SaveFile.Filename + file = open(FilePath, "w", encoding="utf-8") + file.write(self.ViewArticle.Value) + file.close() + else: + return + + def OnChangeTheme(self, event): + dialog2 = ChangeTheme() + GetTheme = dialog2.ShowModal() + self.SetBackgroundColour(wx.Colour(colourList[GetTheme])) + self.ViewArticle.SetBackgroundColour(wx.Colour(colourList[GetTheme])) + self.Refresh() + + # Close Article Window + def OnCloseArticle(self, event): + self.Destroy() + + + # Close Program + def OnCloseProgram(self, event): + wx.Exit() diff --git a/view_search_dialog.py b/view_search_dialog.py new file mode 100644 index 0000000..d4de621 --- /dev/null +++ b/view_search_dialog.py @@ -0,0 +1,71 @@ +#-*- coding: utf-8 -*- +# import project libraries. +import wx +import nlpia2_wikipedia as wikipedia +import threading +import pyperclip +import webbrowser +from view_article_window import ViewArticleWindow + +#create View Search Dialog +class ViewSearch(wx.Dialog): + def __init__(self, parent, TextSearch): + super().__init__(parent, title="search results", size=(300, 400)) + self.Center() + self.TextSearch = TextSearch + + # Create panel + Panel = wx.Panel(self) + + # Create ListBox + wx.StaticText(Panel, -1, "search results", pos=(10,10), size=(380,30)) + self.ListResults = wx.ListBox(Panel, -1, pos=(10,30), size=(290,170)) + + # Create Buttons + self.ViewArticle = wx.Button(Panel, -1, "View Article", pos=(10,235), size=(120,30)) + self.ViewArticle.SetDefault() + self.OpenInWebBrowser = wx.Button(Panel, -1, "Open in browser", pos=(140,235), size=(120,30)) + self.CopyArticleLink = wx.Button(Panel, -1, "Copy the article link", pos=(10,280), size=(120,30)) + self.GoBack = wx.Button(Panel, wx.ID_CANCEL, "GoBack", pos=(140,280), size=(120,30)) + + # Show List Results + self.Show() + + # events for buttons + self.ViewArticle.Bind(wx.EVT_BUTTON, self.OnViewArticleWindow) + self.OpenInWebBrowser.Bind(wx.EVT_BUTTON, self.OnOpenInBrowser) + self.CopyArticleLink.Bind(wx.EVT_BUTTON, self.OnCopyArticleLink) + + #create thread function to show results in list box + def OpenThread(self): + try: + self.ViewResults = wikipedia.search(self.TextSearch, results=20) + except: + wx.MessageBox("there is no internet connection ", "Connection error", style=wx.ICON_ERROR) + return None + + self.ListResults.SetItems(self.ViewResults) + try: + self.ListResults.Selection = 0 + except: + self.Destroy() + wx.MessageBox("We couldn't find any articles that match your search", "Error", style=wx.ICON_ERROR) + + #creating OnOpenInBrowser function to open Article Link On Default Browser + def OnOpenInBrowser(self, event): + GetValues = self.ViewResults[self.ListResults.GetSelection()] + url = wikipedia.page(GetValues, auto_suggest=False).url + webbrowser.open_new(url) + + #Creating OnCopyArticleLink function to copy Article Link to Clipboard + def OnCopyArticleLink(self, event): + GetValues = self.ViewResults[self.ListResults.GetSelection()] + url = wikipedia.page(GetValues).url + pyperclip.copy(url) + + #creating OnViewArticleWindow function View Article On a New Window + def OnViewArticleWindow(self, event): + GetValues = self.ListResults.GetString(self.ListResults.GetSelection()) + window1 = ViewArticleWindow(None, GetValues, self) + thread1 = threading.Thread(target=window1.OpenThread, daemon=True) + thread1.start()