English translation
This commit is contained in:
parent
48650d1c3d
commit
17536b6986
493
Dropchat.py
493
Dropchat.py
@ -1,59 +1,59 @@
|
|||||||
import tkinter, tkinter.filedialog, tkinter.messagebox, tkinter.simpledialog
|
import re
|
||||||
import tempfile, json, datetime, re, sys
|
import sys
|
||||||
|
import tempfile
|
||||||
|
import json
|
||||||
|
import datetime
|
||||||
|
import tkinter
|
||||||
|
import tkinter.filedialog
|
||||||
|
import tkinter.messagebox
|
||||||
|
import tkinter.simpledialog
|
||||||
|
|
||||||
class Text(tkinter.Text):
|
class Text(tkinter.Text):
|
||||||
"""
|
"""
|
||||||
Tkinter Text Widget
|
Tkinter Text Widget
|
||||||
Override che permette di evidenziare il contenuto tramite
|
Override that allows to highlight words with regex.
|
||||||
espressioni regolari.
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
tkinter.Text.__init__(self, *args, **kwargs)
|
tkinter.Text.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
def evidenzia(self, pattern, tag, inizio="1.0", fine="end", regex=True):
|
def highlight(self, pattern, tag, start="1.0", stop="end", regex=True):
|
||||||
"""
|
"""
|
||||||
Evidenzia il testo selezionato da "pattern" e gli assegna
|
Highlight text matched by "pattern" and apply it the tag "tag"
|
||||||
il tag "tag". Specificare "inizio" e "fine" per ristringere
|
Specify "start" and "stop" in order to restrict the search and
|
||||||
il campo della ricerca e regex=False se non si utilizza un
|
regex=False if pattern is not a regex.
|
||||||
espressione regolare.
|
|
||||||
"""
|
"""
|
||||||
inizio = self.index(inizio)
|
start = self.index(start)
|
||||||
fine = self.index(fine)
|
stop = self.index(stop)
|
||||||
self.mark_set("matchStart", inizio)
|
self.mark_set("matchStart", start)
|
||||||
self.mark_set("matchEnd", inizio)
|
self.mark_set("matchEnd", start)
|
||||||
self.mark_set("searchLimit", fine)
|
self.mark_set("searchLimit", stop)
|
||||||
occorrenze = tkinter.IntVar()
|
occurrences = tkinter.IntVar()
|
||||||
while True:
|
while True:
|
||||||
indice = self.search(
|
index = self.search(
|
||||||
pattern,
|
pattern,
|
||||||
"matchEnd",
|
"matchEnd",
|
||||||
"searchLimit",
|
"searchLimit",
|
||||||
count=occorrenze,
|
count=occurrences,
|
||||||
regexp=regex
|
regexp=regex
|
||||||
)
|
)
|
||||||
if indice == "":
|
if index == "":
|
||||||
break
|
break
|
||||||
self.mark_set("matchStart", indice)
|
self.mark_set("matchStart", index)
|
||||||
self.mark_set("matchEnd", "%s+%sc" % (indice, occorrenze.get()))
|
self.mark_set("matchEnd", "%s+%sc" % (index, occurrences.get()))
|
||||||
self.tag_add(tag, "matchStart", "matchEnd")
|
self.tag_add(tag, "matchStart", "matchEnd")
|
||||||
|
|
||||||
|
class Application(tkinter.Frame):
|
||||||
|
"""Application class"""
|
||||||
|
def __init__(self):
|
||||||
|
tkinter.Frame.__init__(self, window)
|
||||||
|
window.iconify()
|
||||||
|
|
||||||
class Applicazione(tkinter.Frame):
|
#Vars
|
||||||
"""
|
|
||||||
Classe dell'applicazione
|
|
||||||
Inizializzarla con un finestra creata con Tk().
|
|
||||||
"""
|
|
||||||
def __init__(self, finestra):
|
|
||||||
tkinter.Frame.__init__(self, finestra)
|
|
||||||
finestra.iconify()
|
|
||||||
|
|
||||||
#Variabili
|
|
||||||
self.temp = tempfile.TemporaryFile(mode="w+t")
|
self.temp = tempfile.TemporaryFile(mode="w+t")
|
||||||
self.testo = tkinter.StringVar()
|
self.text = tkinter.StringVar()
|
||||||
self.file = ""
|
self.file = ""
|
||||||
self.opzionifile = {
|
self.opzionifile = {
|
||||||
"parent": finestra,
|
"parent": window,
|
||||||
"filetypes": [("text files", ".txt")],
|
"filetypes": [("text files", ".txt")],
|
||||||
"defaultextension": ".txt",
|
"defaultextension": ".txt",
|
||||||
"initialfile": "file.txt"
|
"initialfile": "file.txt"
|
||||||
@ -64,367 +64,296 @@ class Applicazione(tkinter.Frame):
|
|||||||
"highlightthickness": 0
|
"highlightthickness": 0
|
||||||
}
|
}
|
||||||
|
|
||||||
#Gestione delle preferenze
|
#pref management
|
||||||
try:
|
try:
|
||||||
self.preferenze = json.load(open("preferenze.json"))
|
self.prefs = json.load(open("prefs.json"))
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
tkinter.messagebox.showwarning(
|
tkinter.messagebox.showwarning(
|
||||||
"Dropchat",
|
"Dropchat",
|
||||||
"File delle preferenze non trovato!",
|
"Preferences file non found!",
|
||||||
detail="Preferenze di default ricostruite."
|
detail="Default preferences rebuilt.")
|
||||||
)
|
self.build_prefs()
|
||||||
self.creapreferenze()
|
|
||||||
|
|
||||||
#Gestione della finestra
|
#Gestione della window
|
||||||
finestra.geometry(self.preferenze["Geometria"])
|
window.geometry(self.prefs["geometry"])
|
||||||
finestra.configure(background="#a8a8a8")
|
window.configure(background="#a8a8a8")
|
||||||
finestra.columnconfigure(1, weight=1)
|
window.columnconfigure(1, weight=1)
|
||||||
finestra.rowconfigure(0, weight=1)
|
window.rowconfigure(0, weight=1)
|
||||||
finestra.protocol('WM_DELETE_WINDOW', self.chiudi)
|
window.protocol('WM_DELETE_WINDOW', self.close)
|
||||||
finestra.deiconify()
|
window.deiconify()
|
||||||
self.grid()
|
self.grid()
|
||||||
|
|
||||||
#Inizzializzazione
|
#Inizzializzazione
|
||||||
self.cambiatitolo()
|
self.set_title()
|
||||||
self.widgets()
|
self.widgets()
|
||||||
self.leggi()
|
self.read()
|
||||||
|
|
||||||
#Gestione delle ultime conversazioni
|
#Gestione delle ultime conversazioni
|
||||||
try:
|
try:
|
||||||
self.cancellanontrovati()
|
self.delete_not_found()
|
||||||
self.file = self.preferenze["Chat"][-1]
|
self.file = self.prefs["chat"][-1]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
risposta = tkinter.messagebox.askquestion(
|
response = tkinter.messagebox.askquestion(
|
||||||
"Dropchat",
|
"Dropchat",
|
||||||
"Nessuna conversazione trovata.",
|
"No conversations found.",
|
||||||
detail="Crearne una nuova ?"
|
detail="Make a new one?")
|
||||||
)
|
if response == "yes":
|
||||||
if risposta == "yes":
|
self.new_file()
|
||||||
self.nuovofile()
|
|
||||||
|
|
||||||
#Loop principale
|
#Loop principale
|
||||||
self.loop()
|
self.loop()
|
||||||
|
|
||||||
#Widget della finestra
|
#Widget della window
|
||||||
def widgets(self):
|
def widgets(self):
|
||||||
"""
|
"""
|
||||||
Creare e disegna i widgets della finestra.
|
Draw window widgets.
|
||||||
"""
|
"""
|
||||||
self.menubar = tkinter.Menu(finestra)
|
self.menubar = tkinter.Menu(window)
|
||||||
self.chat = Text(
|
self.chat = Text(window,
|
||||||
finestra,
|
width=100, height=30,
|
||||||
width=100,
|
|
||||||
height=30,
|
|
||||||
relief="sunken",
|
relief="sunken",
|
||||||
insertbackground="#fff",
|
insertbackground="#fff",
|
||||||
**self.opzionichat
|
**self.opzionichat)
|
||||||
)
|
|
||||||
self.sidebar = tkinter.Listbox(
|
self.sidebar = tkinter.Listbox(
|
||||||
finestra,
|
window, width=20,
|
||||||
width=20,
|
|
||||||
borderwidth=0,
|
borderwidth=0,
|
||||||
background="#dce0e8"
|
background="#dce0e8")
|
||||||
)
|
self.textbox = tkinter.Entry(
|
||||||
self.casella = tkinter.Entry(
|
window, textvariable=self.text,
|
||||||
finestra,
|
**self.opzionichat)
|
||||||
textvariable=self.testo,
|
|
||||||
**self.opzionichat
|
|
||||||
)
|
|
||||||
self.chat.grid(column=1, row=0, sticky="nswe", pady=(6, 3), padx=6)
|
self.chat.grid(column=1, row=0, sticky="nswe", pady=(6, 3), padx=6)
|
||||||
self.casella.grid(column=1, row=1, sticky="nswe", pady=(3, 6), padx=6)
|
self.textbox.grid(column=1, row=1, sticky="nswe", pady=(3, 6), padx=6)
|
||||||
self.sidebar.grid(column=0, row=0, sticky="nswe", rowspan=2)
|
self.sidebar.grid(column=0, row=0, sticky="nswe", rowspan=2)
|
||||||
|
|
||||||
#Bindings
|
#Bindings
|
||||||
self.chat.bind("<KeyPress>", "break")
|
self.chat.bind("<KeyPress>", "break")
|
||||||
self.sidebar.bind("<Double-Button-1>", self.cambiafile)
|
self.sidebar.bind("<Double-Button-1>", self.switch_file)
|
||||||
self.sidebar.bind("<Button-2>", self.mostramenu)
|
self.sidebar.bind("<Button-2>", self.show_menu)
|
||||||
self.casella.bind("<Return>", self.scrivi)
|
self.textbox.bind("<Return>", self.write)
|
||||||
|
|
||||||
#Barra dei menu
|
#Menu bar
|
||||||
self.menubar = tkinter.Menu(self)
|
self.menubar = tkinter.Menu(self)
|
||||||
menu = tkinter.Menu(self.menubar)
|
menu = tkinter.Menu(self.menubar)
|
||||||
|
|
||||||
#Primo menu
|
#Menu 1
|
||||||
self.menubar.add_cascade(label="Conversazione", menu=menu)
|
self.menubar.add_cascade(label="Conversation", menu=menu)
|
||||||
menu.add_command(label="Nuovo file", command=self.nuovofile)
|
menu.add_command(label="New file", command=self.new_file)
|
||||||
menu.add_command(label="Apri file...", command=self.aprifile)
|
menu.add_command(label="Open file...", command=self.open_file)
|
||||||
|
|
||||||
#Secondo menu
|
#Menu 2
|
||||||
menu = tkinter.Menu(self.menubar)
|
menu = tkinter.Menu(self.menubar)
|
||||||
self.menubar.add_cascade(label="Profilo", menu=menu)
|
self.menubar.add_cascade(label="Profile", menu=menu)
|
||||||
menu.add_command(
|
menu.add_command(
|
||||||
label="Nome utente",
|
label="User name",
|
||||||
command=lambda: self.modificapreferenza(
|
command=lambda: self.edit_prefs(
|
||||||
"Utente",
|
"username",
|
||||||
tkinter.simpledialog.askstring(
|
tkinter.simpledialog.askstring(
|
||||||
"Nome Utente",
|
"User name",
|
||||||
"Scrivi il nome:",
|
"Insert your name:",
|
||||||
initialvalue=self.preferenze["Utente"],
|
initialvalue=self.prefs["username"],
|
||||||
parent=finestra
|
parent=window)))
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
menu.add_command(
|
|
||||||
label="Chiave",
|
|
||||||
command=lambda: self.modificapreferenza(
|
|
||||||
"Chiave",
|
|
||||||
tkinter.filedialog.askopenfilename(
|
|
||||||
title="Scegli un file...",
|
|
||||||
message="Apri una chiave di decodifica.",
|
|
||||||
**self.opzionifile
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
#Terzo menu
|
#Menu 3
|
||||||
menu = tkinter.Menu(self.menubar)
|
menu = tkinter.Menu(self.menubar)
|
||||||
self.menubar.add_cascade(label="Modifica", menu=menu)
|
self.menubar.add_cascade(label="Edit", menu=menu)
|
||||||
menu.add_command(
|
menu.add_command(label="Cut",
|
||||||
label="Taglia",
|
command=lambda: window.focus_get().event_generate("<<Cut>>"))
|
||||||
command=lambda: finestra.focus_get().event_generate("<<Cut>>")
|
menu.add_command(label="Copy",
|
||||||
)
|
command=lambda: window.focus_get().event_generate("<<Copy>>"))
|
||||||
menu.add_command(
|
menu.add_command(label="Paste",
|
||||||
label="Copia",
|
command=lambda: window.focus_get().event_generate("<<Paste>>"))
|
||||||
command=lambda: finestra.focus_get().event_generate("<<Copy>>")
|
window.config(menu=self.menubar)
|
||||||
)
|
|
||||||
menu.add_command(
|
|
||||||
label="Incolla",
|
|
||||||
command=lambda: finestra.focus_get().event_generate("<<Paste>>")
|
|
||||||
)
|
|
||||||
finestra.config(menu=self.menubar)
|
|
||||||
|
|
||||||
#Menu contestuale 1
|
#Context menu 1
|
||||||
self.menu1 = tkinter.Menu(self)
|
self.menu1 = tkinter.Menu(self)
|
||||||
self.menu1.add_command(
|
self.menu1.add_command(label="Open", command=self.switch_file)
|
||||||
label="Apri",
|
self.menu1.add_command(label="Delete", command=self.delete_file)
|
||||||
command=self.cambiafile
|
|
||||||
)
|
|
||||||
self.menu1.add_command(
|
|
||||||
label="Cancella",
|
|
||||||
command=self.cancellafile
|
|
||||||
)
|
|
||||||
self.menu1.add_separator()
|
self.menu1.add_separator()
|
||||||
self.menu1.add_command(
|
self.menu1.add_command(label="New file", command=self.new_file)
|
||||||
label="Nuovo file",
|
self.menu1.add_command(label="Reload",
|
||||||
command=self.nuovofile
|
command=lambda: self.sidebar.delete(0, "end"))
|
||||||
)
|
|
||||||
self.menu1.add_command(
|
|
||||||
label="Ricarica",
|
|
||||||
command=lambda: self.sidebar.delete(0, "end")
|
|
||||||
)
|
|
||||||
|
|
||||||
#Menu contestuale 2
|
#Contextmenu 2
|
||||||
self.menu2 = tkinter.Menu(self)
|
self.menu2 = tkinter.Menu(self)
|
||||||
self.menu2.add_command(
|
self.menu2.add_command(label="New file", command=self.new_file)
|
||||||
label="Nuovo file",
|
self.menu2.add_command(label="Reload",
|
||||||
command=self.nuovofile
|
command=lambda: self.sidebar.delete(0, "end"))
|
||||||
)
|
|
||||||
self.menu2.add_command(
|
|
||||||
label="Ricarica",
|
|
||||||
command=lambda: self.sidebar.delete(0, "end")
|
|
||||||
)
|
|
||||||
|
|
||||||
def leggi(self):
|
def read(self):
|
||||||
"""Legge il file corrente dal buffer e lo scrive nella chat"""
|
"""
|
||||||
self.aggiorna()
|
Reads the current file from the buffer
|
||||||
|
and writes it into the chat.
|
||||||
|
"""
|
||||||
|
self.update()
|
||||||
self.temp.seek(0)
|
self.temp.seek(0)
|
||||||
self.chat.delete(0.0, "end")
|
self.chat.delete(0.0, "end")
|
||||||
self.chat.insert("end", self.temp.read())
|
self.chat.insert("end", self.temp.read())
|
||||||
self.colora()
|
self.highlight()
|
||||||
|
|
||||||
def scrivi(self, event):
|
def write(self, event):
|
||||||
"""Scrive un messaggio nel file"""
|
"""Write a message in the current file"""
|
||||||
if self.file != "":
|
if self.file != "":
|
||||||
with open(self.file, "a") as file:
|
with open(self.file, "a") as file:
|
||||||
if self.testo.get() != "":
|
if self.text.get() != "":
|
||||||
riga = "[%s] %s: %s\n" % (
|
row = "[%s] %s: %s\n" % (
|
||||||
datetime.datetime.now().strftime("%d-%m-%y %H:%M"),
|
datetime.datetime.now().strftime("%d-%m-%y %H:%M"),
|
||||||
self.preferenze["Utente"],
|
self.prefs["username"],
|
||||||
self.testo.get()
|
self.text.get())
|
||||||
)
|
self.text.set("")
|
||||||
self.testo.set("")
|
file.write(row)
|
||||||
file.write(riga)
|
|
||||||
|
|
||||||
def aggiorna(self):
|
def update(self):
|
||||||
"""Copia il file nel Buffer"""
|
"""Copy file into the buffer"""
|
||||||
self.temp.seek(0)
|
self.temp.seek(0)
|
||||||
self.temp.truncate()
|
self.temp.truncate()
|
||||||
if self.file != "":
|
if self.file != "":
|
||||||
with open(self.file) as testo:
|
with open(self.file) as text:
|
||||||
self.temp.write(testo.read())
|
self.temp.write(text.read())
|
||||||
|
|
||||||
def cambiatitolo(self):
|
def set_title(self):
|
||||||
"""
|
"""Update window's title to match current conversation"""
|
||||||
Aggiorna il titolo della finestra in modo che corrisponda
|
|
||||||
al file correntemente aperto.
|
|
||||||
"""
|
|
||||||
file = re.search("([^/]*)$", self.file)
|
file = re.search("([^/]*)$", self.file)
|
||||||
if self.file == "":
|
if self.file == "":
|
||||||
finestra.title("Dropchat")
|
window.title("Dropchat")
|
||||||
else:
|
else:
|
||||||
finestra.title("Dropchat - " + file.group(0))
|
window.title("Dropchat - " + file.group(0))
|
||||||
|
|
||||||
def colora(self):
|
def highlight(self):
|
||||||
"""
|
"""
|
||||||
Evidenzia parti semantiche nel testo della chat
|
Highlight semantic parts in the text chat.
|
||||||
(Data, proprio nome utente e di altri).
|
(Date, username and others)
|
||||||
"""
|
"""
|
||||||
self.chat.tag_configure("data", foreground="#005d8f")
|
self.chat.tag_configure("date", foreground="#005d8f")
|
||||||
self.chat.tag_configure("nome", foreground="#648f00")
|
self.chat.tag_configure("name", foreground="#648f00")
|
||||||
self.chat.tag_configure("altronome", foreground="#de7a31")
|
self.chat.tag_configure("other", foreground="#de7a31")
|
||||||
self.chat.evidenzia("\[\d+-\d+-\d+ \d+:\d+\]", "data")
|
self.chat.highlight("\[\d+-\d+-\d+ \d+:\d+\]", "data")
|
||||||
for nome in re.findall(" ([a-zA-Z]+): ", self.chat.get(0.0, "end")):
|
for name in re.findall(" ([a-zA-Z]+): ", self.chat.get(0.0, "end")):
|
||||||
if nome == self.preferenze["Utente"]:
|
if name == self.prefs["username"]:
|
||||||
self.chat.evidenzia(nome, "nome")
|
self.chat.highlight(name, "name")
|
||||||
else:
|
else:
|
||||||
self.chat.evidenzia(nome, "altronome")
|
self.chat.highlight(name, "other")
|
||||||
|
|
||||||
def mostramenu(self, event):
|
def show_menu(self, event):
|
||||||
"""
|
"""Manages the opening and positioning of context menu"""
|
||||||
Gestisce l'apertura e il posizionamento dei menu contestuali
|
self.sidebar.index = self.sidebar.nearest(event.y)
|
||||||
della sidebar.
|
if self.sidebar.index < 0:
|
||||||
"""
|
|
||||||
self.sidebar.indice = self.sidebar.nearest(event.y)
|
|
||||||
if self.sidebar.indice < 0:
|
|
||||||
self.menu2.post(event.x_root, event.y_root)
|
self.menu2.post(event.x_root, event.y_root)
|
||||||
return
|
return
|
||||||
self.sidebar.activate(self.sidebar.indice)
|
self.sidebar.activate(self.sidebar.index)
|
||||||
_, offset, _, altezza = self.sidebar.bbox(self.sidebar.indice)
|
_, offset, _, height = self.sidebar.bbox(self.sidebar.index)
|
||||||
if event.y > altezza + offset + self.sidebar.size():
|
if event.y > height + offset + self.sidebar.size():
|
||||||
self.menu2.post(event.x_root, event.y_root)
|
self.menu2.post(event.x_root, event.y_root)
|
||||||
else:
|
else:
|
||||||
self.menu1.post(event.x_root, event.y_root)
|
self.menu1.post(event.x_root, event.y_root)
|
||||||
|
|
||||||
def filerecenti(self):
|
def recent_files(self):
|
||||||
"""Inserisce nella sidebar i file recentemente aperti"""
|
"""Inserts recently opened files into the sidebar"""
|
||||||
for x, file in enumerate(self.preferenze["Chat"]):
|
for x, file in enumerate(self.prefs["chat"]):
|
||||||
file = " - " + re.search("([^/]*)$", file).group(0)
|
file = " - " + re.search("([^/]*)$", file).group(0)
|
||||||
if file not in self.sidebar.get(x):
|
if file not in self.sidebar.get(x):
|
||||||
self.sidebar.insert(x, file)
|
self.sidebar.insert(x, file)
|
||||||
|
|
||||||
def cancellafile(self):
|
def delete_file(self):
|
||||||
"""Rimuove dalla sidebar il file correntemente selezionato"""
|
"""Removes the currently selected file from the sidebar"""
|
||||||
if self.preferenze["Chat"][self.sidebar.indice] == self.file:
|
if self.prefs["Chat"][self.sidebar.index] == self.file:
|
||||||
self.file = ""
|
self.file = ""
|
||||||
del self.preferenze["Chat"][self.sidebar.indice]
|
del self.prefs["Chat"][self.sidebar.index]
|
||||||
json.dump(self.preferenze, open("preferenze.json", "w"))
|
json.dump(self.prefs, open("prefs.json", "w"))
|
||||||
self.leggi()
|
self.read()
|
||||||
self.cambiatitolo()
|
self.set_title()
|
||||||
|
|
||||||
def cambiafile(self, _=None):
|
def switch_file(self, _=None):
|
||||||
"""
|
"""Opens the currently selected file from the sidebar in the chat"""
|
||||||
Apre il file correntemente selezionato
|
file = self.prefs["chat"][int(self.sidebar.curselection()[0])]
|
||||||
dalla sidebar nella chat.
|
|
||||||
"""
|
|
||||||
file = self.preferenze["Chat"][int(self.sidebar.curselection()[0])]
|
|
||||||
if self.file != file:
|
if self.file != file:
|
||||||
self.file = file
|
self.file = file
|
||||||
self.leggi()
|
self.read()
|
||||||
self.cambiatitolo()
|
self.set_title()
|
||||||
|
|
||||||
def aprifile(self):
|
def open_file(self):
|
||||||
"""
|
"""Selects a new file and opens it in the chat."""
|
||||||
Gestisce la finestra di selezione di un nuovo file
|
|
||||||
e lo apre nella chat.
|
|
||||||
"""
|
|
||||||
if sys.platform == "darwin":
|
if sys.platform == "darwin":
|
||||||
file = tkinter.filedialog.askopenfilename(
|
file = tkinter.filedialog.askopenfilename(
|
||||||
title="Scegli un file...",
|
title="Choose a file...",
|
||||||
message="Apri una conversazione esistente.",
|
message="Open a conversation.",
|
||||||
**self.opzionifile
|
**self.opzionifile)
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
file = tkinter.filedialog.askopenfilename(
|
file = tkinter.filedialog.askopenfilename(
|
||||||
title="Scegli un file...",
|
title="Choose a file...",
|
||||||
**self.opzionifile
|
**self.opzionifile)
|
||||||
)
|
if file not in self.prefs["Chat"] and file != "":
|
||||||
if file not in self.preferenze["Chat"] and file != "":
|
self.prefs["chat"] += file,
|
||||||
self.preferenze["Chat"] += file,
|
json.dump(self.prefs, open("prefs.json", "w"))
|
||||||
json.dump(self.preferenze, open("preferenze.json", "w"))
|
|
||||||
self.file = file
|
self.file = file
|
||||||
self.leggi()
|
self.read()
|
||||||
self.cambiatitolo()
|
self.set_title()
|
||||||
|
|
||||||
def nuovofile(self):
|
def new_file(self):
|
||||||
"""
|
"""Creates a new file and opens it in the chat"""
|
||||||
Gestisce la finestra per la creazione di un nuovo file
|
|
||||||
e lo apre nella chat.
|
|
||||||
"""
|
|
||||||
if sys.platform == "darwin":
|
if sys.platform == "darwin":
|
||||||
file = tkinter.filedialog.asksaveasfilename(
|
file = tkinter.filedialog.asksaveasfilename(
|
||||||
title="Crea un file...",
|
title="Create a file...",
|
||||||
message="Scegli il nome della nuova conversazione.",
|
message="Select the name of the new conversation.",
|
||||||
**self.opzionifile
|
**self.opzionifile)
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
file = tkinter.filedialog.asksaveasfilename(
|
file = tkinter.filedialog.asksaveasfilename(
|
||||||
title="Crea un file...",
|
title="Creates a new file...",
|
||||||
**self.opzionifile
|
**self.opzionifile)
|
||||||
)
|
|
||||||
if file != "":
|
if file != "":
|
||||||
self.file = file
|
self.file = file
|
||||||
open(self.file, "w").close()
|
open(self.file, "w").close()
|
||||||
if self.file not in self.preferenze["Chat"]:
|
if self.file not in self.prefs["chat"]:
|
||||||
self.preferenze["Chat"] += self.file,
|
self.prefs["chat"] += self.file,
|
||||||
json.dump(self.preferenze, open("preferenze.json", "w"))
|
json.dump(self.prefs, open("prefs.json", "w"))
|
||||||
self.leggi()
|
self.read()
|
||||||
self.cambiatitolo()
|
self.set_title()
|
||||||
|
|
||||||
def cancellanontrovati(self):
|
def delete_not_found(self):
|
||||||
"""
|
"""Removes files that are no longer available"""
|
||||||
Rimuove i riferimenti dalla sidebar di tutti i file che
|
for x, file in enumerate(self.prefs["chat"]):
|
||||||
non sono più disponibili.
|
|
||||||
"""
|
|
||||||
for x, file in enumerate(self.preferenze["Chat"]):
|
|
||||||
try:
|
try:
|
||||||
open(file)
|
open(file)
|
||||||
self.file = file
|
self.file = file
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
del self.preferenze["Chat"][x]
|
del self.prefs["Chat"][x]
|
||||||
continue
|
continue
|
||||||
json.dump(self.preferenze, open("preferenze.json", "w"))
|
json.dump(self.prefs, open("prefs.json", "w"))
|
||||||
|
|
||||||
def creapreferenze(self):
|
def build_prefs(self):
|
||||||
"""
|
"""Rebuild default preferences"""
|
||||||
Ricrea le preferenze di default se non vengono trovate.
|
|
||||||
"""
|
|
||||||
default = {
|
default = {
|
||||||
"Utente": "Nomeutente",
|
"username": "user",
|
||||||
"Chat": ["chat.txt"],
|
"chat": ["chat.txt"],
|
||||||
"Chiave": "chiave.key",
|
"geometry": "800x500+500+250"
|
||||||
"Geometria": "800x500+500+250"
|
|
||||||
}
|
}
|
||||||
json.dump(default, open("preferenze.json", "w"))
|
json.dump(default, open("prefs.json", "w"))
|
||||||
self.preferenze = json.load(open("preferenze.json"))
|
self.prefs = json.load(open("prefs.json"))
|
||||||
|
|
||||||
def modificapreferenza(self, chiave, preferenza):
|
def edit_prefs(self, key, pref):
|
||||||
"""
|
"""Changing a preference and saves it into an external file."""
|
||||||
Modifica una preferenza e la salva nel file esterno.
|
if pref != "":
|
||||||
"""
|
self.prefs[key] = pref
|
||||||
if preferenza != "":
|
json.dump(self.prefs, open("prefs.json", "w"))
|
||||||
self.preferenze[chiave] = preferenza
|
|
||||||
json.dump(self.preferenze, open("preferenze.json", "w"))
|
|
||||||
|
|
||||||
def chiudi(self):
|
def close(self):
|
||||||
"""
|
"""
|
||||||
Salva la geometria della finestra per il prossimo avvio,
|
Save the geometry of the window for the next boot,
|
||||||
chiude ed elimina la cache,
|
closes and deletes the cache,
|
||||||
chiude la finestra ed esce.
|
closes the window and exits.
|
||||||
"""
|
"""
|
||||||
self.modificapreferenza("Geometria", finestra.geometry())
|
self.edit_prefs("geometry", window.geometry())
|
||||||
self.temp.close()
|
self.temp.close()
|
||||||
finestra.destroy()
|
window.destroy()
|
||||||
|
|
||||||
def loop(self):
|
def loop(self):
|
||||||
"""
|
"""
|
||||||
Loop principale
|
Main loop
|
||||||
Viene eseguito ogni 200 ms.
|
Update recent files and current covnersation.
|
||||||
Aggiorna i file recenti e il file aperto nella chat.
|
|
||||||
"""
|
"""
|
||||||
self.filerecenti()
|
self.recent_files()
|
||||||
self.leggi()
|
self.read()
|
||||||
self.after(200, self.loop)
|
self.after(200, self.loop)
|
||||||
|
|
||||||
finestra = tkinter.Tk()
|
window = tkinter.Tk()
|
||||||
app = Applicazione(finestra)
|
app = Application()
|
||||||
app.mainloop()
|
app.mainloop()
|
||||||
|
10
License.txt
10
License.txt
@ -1,10 +0,0 @@
|
|||||||
* Dropchat
|
|
||||||
*
|
|
||||||
* Chat tramite Dropbox in python 3.
|
|
||||||
*
|
|
||||||
* Dual licensed under the MIT and GPL licenses:
|
|
||||||
* http://www.opensource.org/licenses/mit-license.php
|
|
||||||
* http://www.gnu.org/licenses/gpl.html
|
|
||||||
*
|
|
||||||
* @author Michele Guerini Rocco aka Rnhmjoj
|
|
||||||
* @since 2013
|
|
44
README.md
44
README.md
@ -1,27 +1,31 @@
|
|||||||
Dropchat
|
# Dropchat
|
||||||
========
|
|
||||||
|
|
||||||
Chat tramite Dropbox in python 3.
|
## Chat with Dropbox.
|
||||||
---------------------------------
|
|
||||||
|
|
||||||
### Informazioni
|
|
||||||
Un chat client per chattare tramite le cartelle condivise di Dropbox.
|
|
||||||
Realizzato usando python 3 e l'interfaccia Tk.
|
|
||||||
|
|
||||||
### Istruzioni
|
### Info
|
||||||
Primo utilizzo:
|
A chat client that uses shared folders to Dropbox.
|
||||||
|
Made using python 3 and Tk interface.
|
||||||
|
|
||||||
Dalla barra dei menu selezionare:
|
### Instructions
|
||||||
* Profilo -> "Nome Utente" ed immettere il proprio nome.
|
First usage:
|
||||||
* Conversazione -> "Nuovo file" o "Apri file.." e scegliere un file di testo
|
|
||||||
Scrivere un messaggio nella casella di testo e dare invio per immetterlo nel file.
|
|
||||||
Una volta scritto il file viene sincronizzato con Dropbox in modo che altri possano rispondere.
|
|
||||||
|
|
||||||
I file recenti vengono elencati nella barra laterale e l'ultimo utilizzato viene riaperto all'avvio.
|
From the menu bar select:
|
||||||
Per cancellare definitivamente un file basta spostarlo nel cestino mentre per rimuovere il riferimento dall'applicazione fare click destro sul file nella barra laterale e selezionare "Cancella".
|
* Profile -> "User Name" and enter your name.
|
||||||
|
* Conversation -> "New File" or "Open File .." and choose a text file
|
||||||
|
Write a message in the text box and press return to enter it in the file.
|
||||||
|
Once written, the file is synced with Dropbox so that others can respond.
|
||||||
|
|
||||||
### Conversione
|
Recent files are listed in the sidebar and on the last used is reopened at startup.
|
||||||
È incluso un setup.py per convertire Dropchat.py in un binario tramite py2app o py2exe.
|
To permanently delete a file, simply move it to the trash while to remove the reference from the right-click on the file in the sidebar and select "Delete".
|
||||||
Utilizzo:
|
|
||||||
|
### Building
|
||||||
|
A setup is included to convert Dropchat into a binary using py2exe or py2app.
|
||||||
|
Usage:
|
||||||
|
|
||||||
python setup.py
|
python setup.py build
|
||||||
|
|
||||||
|
### License
|
||||||
|
Dual licensed under the MIT and GPL licenses:
|
||||||
|
http://www.opensource.org/licenses/mit-license.php
|
||||||
|
http://www.gnu.org/licenses/gpl.html
|
@ -1 +0,0 @@
|
|||||||
{"Utente": "Nomeutente", "Geometria": "800x500+538+299", "Chiave": "chiave.key", "Chat": []}
|
|
1
prefs.json
Normal file
1
prefs.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"username": null, "geometry": "871x526+487+291", "chat": ["/Users/Michele/Desktop/file.txt"]}
|
27
setup.py
27
setup.py
@ -1,14 +1,15 @@
|
|||||||
import sys, setuptools
|
import sys
|
||||||
|
import setuptools
|
||||||
|
|
||||||
opzioni = {
|
options = {
|
||||||
"name": "Dropchat",
|
"name": "Dropchat",
|
||||||
"version": "1.0",
|
"version": "1.0",
|
||||||
"description": "Chat tramite dropbox.",
|
"description": "Chat with dropbox.",
|
||||||
"author": "Rnhmjoj",
|
"author": "Rnhmjoj",
|
||||||
"author_email": "micheleguerinirocco@me.com",
|
"author_email": "micheleguerinirocco@me.com",
|
||||||
"license": "MIT-GPL",
|
"license": "MIT-GPL",
|
||||||
"app": ["Dropchat.py"],
|
"app": ["dropchat.py"],
|
||||||
"data_files": ["preferenze.json"],
|
"data_files": ["prefs.json"],
|
||||||
"options": {},
|
"options": {},
|
||||||
"setup_requires": [],
|
"setup_requires": [],
|
||||||
}
|
}
|
||||||
@ -17,21 +18,21 @@ if sys.platform == "darwin":
|
|||||||
try:
|
try:
|
||||||
import py2app
|
import py2app
|
||||||
sys.argv += "py2app",
|
sys.argv += "py2app",
|
||||||
opzioni["options"] = {"py2app": {"argv_emulation": False}}
|
options["options"] = {"py2app": {"argv_emulation": False}}
|
||||||
opzioni["setup_requires"] += "py2app",
|
options["setup_requires"] += "py2app",
|
||||||
except ImportError:
|
except ImportError:
|
||||||
exit("py2app non installato.")
|
sys.exit("py2app not installed")
|
||||||
|
|
||||||
elif sys.platform == "win32":
|
elif sys.platform == "win32":
|
||||||
try:
|
try:
|
||||||
import py2exe
|
import py2exe
|
||||||
sys.argv += "py2exe",
|
sys.argv += "py2exe",
|
||||||
opzioni["options"] = {"py2exe": {"bundle_files": 1, "compressed": True}}
|
options["options"] = {"py2exe": {"bundle_files": 1, "compressed": True}}
|
||||||
opzioni["setup_requires"] += "py2exe",
|
options["setup_requires"] += "py2exe",
|
||||||
except ImportError:
|
except ImportError:
|
||||||
exit("py2exe non installato.")
|
sys.exit("py2exe not installed")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
exit("Sistema non supportato")
|
sys.exit("OS not supported")
|
||||||
|
|
||||||
setuptools.setup(**opzioni)
|
setuptools.setup(**options)
|
||||||
|
Loading…
Reference in New Issue
Block a user