diff options
Diffstat (limited to 'python.patch')
-rw-r--r-- | python.patch | 893 |
1 files changed, 893 insertions, 0 deletions
diff --git a/python.patch b/python.patch new file mode 100644 index 0000000..1ca451b --- /dev/null +++ b/python.patch @@ -0,0 +1,893 @@ +--- + clients/urwid/main.py | 473 +++++++++++++++++++++++++----------------- + 1 file changed, 279 insertions(+), 194 deletions(-) + +diff --git a/clients/urwid/main.py b/clients/urwid/main.py +index 3adeeff..a8a5e57 100644 +--- a/clients/urwid/main.py ++++ b/clients/urwid/main.py +@@ -87,7 +87,7 @@ obnoxious_logo = """ + 8 888888888P 8 888888888P `Y888888 ' . + % %""" + +-welcome = """>>> Bienvenido al BBS de Texto-Plano! ------------------@ ++welcome = """>>> -------- Bienvenido al BBS de Texto-Plano! -----------@ + | BBJ es un muro de discusión persistente y ordenado | + | temporalmente para tildes. Puedes ingresar | + | registrar un usuario nuevo, or participar anónimamente | +@@ -97,7 +97,7 @@ welcome = """>>> Bienvenido al BBS de Texto-Plano! ------------------@ + @_________________________________________________________@ + """ + +-anon_warn = """>>> \033[1;31mSolo un recordatorio!\033[0m ----------------------------------@ ++anon_warn = """>>> \033[1;31m¡Solo un recordatorio!\033[0m ----------------------------@ + | No estás logueado en BBJ, y estás posteando | + | tu mensaje anónimamente. Si no ingresas con usuario | + | no podrás borrar o editar este mensaje | +@@ -106,102 +106,186 @@ anon_warn = """>>> \033[1;31mSolo un recordatorio!\033[0m ---------------------- + """ + + format_help = [ +- "Quick reminder: \[rainbow: expressions work like this]. You may scroll " +- "this message, or press Q or escape to close it.\n\n" +- +- "BBJ supports **bolding**, __underlining__, and [rainbow: coloring] text " +- "using markdown-style symbols as well as tag-like expressions. Markdown " +- "is **NOT** fully implemented, but several of the more obvious concepts " +- "have been brought over. Additionally, we have chan-style greentext and " +- "numeric post referencing, ala >>3 for the third reply.", +- +- "[red: Whitespace]", +- +- "When you're composing, it is desirable to not include your own linebreaks " +- "into paragraphs of your post, because clients handle text wrapping on their " +- "own. Adding them yourself can cause your posts to look very strange. You can " +- "always edit your posts after submitting them if you do this by accident, as " +- "long as you are not anonymous.", +- +- "In previous versions of BBJ, linebreaks were joined into sentences if they " +- "occured in the same paragraph, however this confused many users and has been " +- "reverted to just use whatever was submitted, as-is.", +- +- +- "[red: Colors, Bold, Underline & Expressions]", +- +- "You can use [rainbow: rainbow], [red: red], [yellow: yellow], [green: green], " +- "[blue: blue], [cyan: cyan], [magenta: and magenta], [dim: dim], **bold**, and __underline__ " +- "inside of your posts. \**bold works like this\**, \__and underlines like this\__. " +- "You can escape these expressions \\\**like this\\\**. They can span up to the full width " +- "of the same line. They are best used on shorter phrases. " +- "However, you can use a different syntax for it, which is also required to use " +- "colors: these expressions \[bold: look like this] and have less restrictions.", +- +- "The colon and the space following it are important. When you use these " +- "expressions, the __first__ space is not part of the content, but any characters, " +- "including spaces, that follow it are included in the body. The formatting will " +- "apply until the closing ]. You can escape such an expression \\\[cyan: like this] " +- "and can also \\[blue: escape \\\] other closing brackets] inside of it. Only " +- "closing brackets need to be escaped within an expression. Any backslashes used " +- "for escaping will not show in the body unless you use two slashes.", +- +- "This peculiar syntax elimiates false positives. You never have to escape [normal] " +- "brackets when using the board. Only expressions with **valid and defined** directives " +- "will be affected. [so: this is totally valid and requires no escapes] because 'so' is " +- "not a directive. [red this will pass too] because the colon is missing.", +- +- "The following directives may be used in this form: red, yellow, green, blue, cyan, " +- "magenta, bold, underline, dim, and rainbow. Nesting expressions into eachother will " +- "override the parent directives until the innermost expression closes. Thus, nesting " +- "is valid but doesn't produce layered results on the command line client.", +- +- "[red: Quotes & Greentext]", +- +- "You can refer to a post number using two angle brackets pointing into a number. >>432 " +- "like this. You can color a whole line green by proceeding it with a '>'. Note that " +- "this violates the sentence structure outlined in the **Whitespace** section above, " +- "so you may introduce >greentext without splicing into seperate paragraphs. The '>' " +- "must be the first character on the line with no whitespace before it.\n>it looks like this\n" +- "and the paragraph doesnt have to break on either side. The formatter is smart enough to " +- "differentiate between >>greentext with multiple arrows and numeric quotes (outlined below) " +- "given that the text doesn't start with any numbers.", +- +- "When using numeric quotes, they are highlighted and the author's name will show " +- "next to them in the thread. You can press enter when focused on a message to view " +- "the parent posts. You may insert these directives manually or use the <Reply> function " +- "on post menus.", +- +- "Quoting directives cannot be escaped." ++ "Recordatorio rápido: \[rainbow: las expresiones se ven así]. Puedes " ++ "desplazar este mensaje, o presionar Q o Escape para cerrarlo.\n\n" ++ ++# "Quick reminder: \[rainbow: expressions work like this]. You may scroll " ++# "this message, or press Q or escape to close it.\n\n" ++ ++ "BBJ soporta texto en **negrita**, __subrayado__ y [rainbow: coloreado] " ++ "usando símbolos a lo Markdown al igual que expresiones de " ++ "tipo tag. Markdown **NO** está implementado por completo, sin embargo " ++ "se adoptaron varios conceptos clave de allí. Adicionalmente, trajimos " ++ "de los chanes el texto verde y referencias numéricas, ej. >>3 para la " ++ "tercera respuesta.", ++ ++# "BBJ supports **bolding**, __underlining__, and [rainbow: coloring] text " ++# "using markdown-style symbols as well as tag-like expressions. Markdown " ++# "is **NOT** fully implemented, but several of the more obvious concepts " ++# "have been brought over. Additionally, we have chan-style greentext and " ++# "numeric post referencing, ala >>3 for the third reply.", ++ ++ "[red: Espaciado]", ++ ++# "[red: Whitespace]", ++ ++ "Cuando estás escribiendo, se desea no incluír tus propios saltos de " ++ "línea en los párrafos de tu post, porque los clientes manejan las " ++ "líneas de texto por su cuenta. Añadirlas tú mismo puede causar que tus " ++ "posts se vean muy extraños. Siempre puedes editar tus posts después de " ++ "publicarlos si haces esto por accidente, siempre y cuando no seas " ++ "anónimo.", ++ ++# "When you're composing, it is desirable to not include your own linebreaks " ++# "into paragraphs of your post, because clients handle text wrapping on their " ++# "own. Adding them yourself can cause your posts to look very strange. You can " ++# "always edit your posts after submitting them if you do this by accident, as " ++# "long as you are not anonymous.", ++ ++ "En versiones anteriores de BBJ, los saltos de línea se unían en " ++ "oraciones si estaban en el mismo párrafo, sin embargo esto confundió a " ++ "varios usuarios y ha sido revertido a publicar lo que sea que se haya " ++ "escrito, tal y como es.", ++ ++# "In previous versions of BBJ, linebreaks were joined into sentences if they " ++# "occured in the same paragraph, however this confused many users and has been " ++# "reverted to just use whatever was submitted, as-is.", ++ ++ "[red: Colores, Negrita, Subrayado y Expresiones]", ++ ++# "[red: Colors, Bold, Underline & Expressions]", ++ ++ "Puedes usar [rainbow: rainbow], [red: red], [yellow: " ++ "yellow], [green: green], [blue: blue], [cyan: " ++ "cyan] [magenta: y magenta], [dim: dim], **bold** y " ++ "__underline__ dentro de tus posts. \**bold se usa así\* " ++ "\__y underline así\__. Puedes escapar estas expresiones " ++ "\\\**así\\\**. Pueden abarcar hasta todo el ancho de la misma línea. " ++ "Funcionan mejor para frases más cortas. " ++ "Sin embargo, puedes usar una sintáxis distinta, que se utiliza también " ++ "para usar colores: estas expresiones \[bold: se ven así] y tienen menos " ++ "restricciones.", ++ ++# "You can use [rainbow: rainbow], [red: red], [yellow: yellow], [green: green], " ++# "[blue: blue], [cyan: cyan], [magenta: and magenta], [dim: dim], **bold**, and __underline__ " ++# "inside of your posts. \**bold works like this\**, \__and underlines like this\__. " ++# "You can escape these expressions \\\**like this\\\**. They can span up to the full width " ++# "of the same line. They are best used on shorter phrases. " ++# "However, you can use a different syntax for it, which is also required to use " ++# "colors: these expressions \[bold: look like this] and have less restrictions.", ++ ++ "Los dos puntos y el espacio siguiéndole son importantes. Cuando usas " ++ "estas expresiones, el __primer__ espacio no forma parte del contenido, " ++ "sino cualquier caracter, incluyendo espacios, que lo siguen, se " ++ "incluyen en el cuerpo. El formateo se aplicará hasta el ] final. Puedes " ++ "escaparla \\\[cyan: así], y también \\[blue: escapar \\\] otros " ++ "corchetes finales dentro de ella. Solo los corchetes finales se " ++ "necesitan escapar en una expresión. Cualquier barra diagonal inversa " ++ "que se use para escapar no se mostrará en el cuerpo a menos que uses " ++ "dos barras.", ++ ++# "The colon and the space following it are important. When you use these " ++# "expressions, the __first__ space is not part of the content, but any characters, " ++# "including spaces, that follow it are included in the body. The formatting will " ++# "apply until the closing ]. You can escape such an expression \\\[cyan: like this] " ++# "and can also \\[blue: escape \\\] other closing brackets] inside of it. Only " ++# "closing brackets need to be escaped within an expression. Any backslashes used " ++# "for escaping will not show in the body unless you use two slashes.", ++ ++ "Esta sintáxis peculiar elimina falsos positivos. Nunca tienes que " ++ "escapar corchetes [normales] cuando se usa el tablón. Solo las " ++ "expresiones con directivas **válidas y definidas** se ven afectadas. " ++ "[entonces: esto es totalmente válido y no requiere escapes] porque " ++ "'entonces' no es una directiva. [red esto también pasa de largo] porque faltan " ++ "los dos puntos.", ++ ++# "This peculiar syntax elimiates false positives. You never have to escape [normal] " ++# "brackets when using the board. Only expressions with **valid and defined** directives " ++# "will be affected. [so: this is totally valid and requires no escapes] because 'so' is " ++# "not a directive. [red this will pass too] because the colon is missing.", ++ ++ "Las siguientes directivas se pueden usar de esta forma: red, yellow, " ++ "green, blue, cyan, magenta, bold, underline, dim y rainbow. Las " ++ "expresiones que se anidan una adentro de la otra van a anular la " ++ "directiva padre hasta que la expresión de más adentro se cierre. Por " ++ "tanto, anidar es válido pero no produce resultados combinados en el " ++ "cliente de la línea de comandos.", ++ ++# "The following directives may be used in this form: red, yellow, green, blue, cyan, " ++# "magenta, bold, underline, dim, and rainbow. Nesting expressions into eachother will " ++# "override the parent directives until the innermost expression closes. Thus, nesting " ++# "is valid but doesn't produce layered results on the command line client.", ++ ++ "[red: Citas y Texto verde]", ++ ++# "[red: Quotes & Greentext]", ++ ++ "Puedes referirte al número de un post usando dos flechas 'mayor que' " ++ "apuntando a un número. >>432 como esto. Puedes colorear una línea " ++ "entera de verde precediéndola con un '>'. Nótese que esto viola la " ++ "estructura de oración en la sección **Espaciado** mencionada " ++ "anteriormente, por lo que podrías introducir >texto verde sin " ++ "escribirlo en párrafos separados. El '>' debe ser el primer caracter en " ++ "la línea, sin espacios antes de él.\n>se ve como esto\n" ++ "y el párrafo no tiene que romperse en ningún lado. El formateador es " ++ "suficientemente inteligente para diferenciar entre >>texto verde con " ++ "múltiples flechas y citas numéricas (mencionadas más abajo) dado que el " ++ "texto no comienza con ningún número.", ++ ++# "You can refer to a post number using two angle brackets pointing into a number. >>432 " ++# "like this. You can color a whole line green by proceeding it with a '>'. Note that " ++# "this violates the sentence structure outlined in the **Whitespace** section above, " ++# "so you may introduce >greentext without splicing into seperate paragraphs. The '>' " ++# "must be the first character on the line with no whitespace before it.\n>it looks like this\n" ++# "and the paragraph doesnt have to break on either side. The formatter is smart enough to " ++# "differentiate between >>greentext with multiple arrows and numeric quotes (outlined below) " ++# "given that the text doesn't start with any numbers.", ++ ++ "Cuando se usan citas numéricas, éstas se resaltan y el nombre del autor " ++ "se mostrará al lado de ellas en el hilo. Puedes presionar Enter cuando " ++ "se está enfocado en un mensaje para ver los posts padre. Puedes " ++ "insertar estas directivas manualmente o usar la función <Responder> en " ++ "los menúes del post.", ++ ++# "When using numeric quotes, they are highlighted and the author's name will show " ++# "next to them in the thread. You can press enter when focused on a message to view " ++# "the parent posts. You may insert these directives manually or use the <Reply> function " ++# "on post menus.", ++ ++ "Las directivas de citado no se pueden escapar." ++# "Quoting directives cannot be escaped." + ] + + general_help = [ +- ("bold", "use the arrow keys, j/k, or n/p to scroll down this menu\n\n"), +- ("bold", "use q or escape to close dialogs and menus (including this one)\n\n"), +- ("10", "use q, escape, or a left directional key to go back at any point" +- " from just about anywhere.\n\n"), +- ("20", "use the o key to change your settings when this dialog is closed\n\n"), +- +- "You may use the arrow keys, or use ", ("button", "jk/np/Control-n|p"), +- " to move up and down by " +- "an element. If an element is overflowing the screen, it will scroll only one line. " +- "To make scrolling faster, ", ("button", "hold shift"), " when using a control: it " +- "will repeat 5 times by default, and you can change this number in your settings.\n\n" +- +- "In threads, The ", ("button", "<"), " and ", ("button", ">"), " keys will jump by " +- "a chosen number of post headers. You can see the count inside of the footer line at " +- "the far right side: press ", ("button", "x"), " to cycle it upwards or ", +- ("button", "X"), " to cycle it downwards.\n\n" +- +- "In the thread index and any open thread, the ", ("button", "b"), " and ", ("button", "t "), +- "keys may be used to go to very top or bottom.\n\n" +- +- "To go back and forth between threads, you may also use the left/right arrow keys, " +- "or ", ("button", "h"), "/", ("button", "l"), " to do it vi-style.\n\n" +- +- "Aside from those, primary controls are shown on the very bottom of the screen " +- "in the footer line, or may be placed in window titles for other actions like " +- "dialogs or composers." ++ ("bold", "usa las flechas, j/k o n/p para desplazar este menú\n\n"), ++ ("bold", "usa q o escape para cerrar diálogos y menúes (incluyendo éste)\n\n"), ++ ("10", "usa q, escape o una flecha izquierda para volver a cualquier punto" ++ " desde cualquier lado.\n\n"), ++ ("20", "usa la tecla o para cambiar tus opciones cuando este diálogo esté cerrado\n\n"), ++ ++ "Puedes usar las flechas, o usar ", ("button", "jk/np/Control-n|p"), ++ " para moverte arriba y abajo por " ++ "cada elemento. Si un elemento excede la pantalla, se moverá solo una línea. " ++ ++ "Para moverte más rápido, ", ("button", "mantén presionado shift "), ++ "cuando uses un control: ", ++ ++ "por defecto se repetirá 5 veces, y puedes cambiar este número en tus opciones.\n\n" ++ ++ "En hilos, las teclas ", ("button", "<"), " y ", ("button", ">"), " saltan un " ++ "elegido número de cabeceras de post. Puedes ver la cuenta dentro del pie de pantalla en " ++ "la línea de abajo: presiona ", ("button", "x"), " para aumentarlo o ", ++ ("button", "X"), " para bajarlo.\n\n" ++ ++ "En el índice de hilos y en cualquier hilo abierto, las teclas ", ("button", "t"), " y ", ("button", "b "), ++ "se pueden usar para ir al inicio o al fin del contenido.\n\n" ++ ++ "Para ir y volver entre hilos, también puedes usar las teclas izquierda/derecha, " ++ "o ", ("button", "h"), "/", ("button", "l"), " para hacerlo al estilo vi.\n\n" ++ ++ "Fuera de ellos, los controles primarios se muestran en la parte baja en " ++ "el pie de la pantalla, o también se colocan en títulos de ventana para " ++ "otras acciones como diálogos o compositores." + ] + + colors = [ +@@ -221,11 +305,11 @@ default_prefs = { + "integrate_external_editor": True, + "index_spacing": False, + "dramatic_exit": True, +- "date": "%Y/%m/%d", ++ "date": "%d/%m/%Y", + "time": "%H:%M", + "frame_theme": "tilde", + "custom_divider_char": False, +- "frame_title": "BBJ", ++ "frame_title": "BBJ - Texto-Plano", + "use_custom_frame_title": False, + "max_text_width": 80, + "confirm_anon": True, +@@ -237,9 +321,10 @@ default_prefs = { + } + + bars = { +- "index": "[RET]Open [/]Search [C]ompose [R]efresh [*]Bookmark [O]ptions [?]Help [Q]uit", +- "thread": "[Q]Back [RET]Menu [C]ompose [^R]eply [R]efresh [0-9]Goto [B/T]End [</>]Jump[X]%d [/]Search", +- "edit_window": "[{}]Abort [{}]Swap [{}]Formatting Help [save/quit to send] {}" ++ ++ "index": "[RET]Abrir [/]Buscar Es[C]ribir [R]efres. [*]Marc. [O]pciones [?]Ayuda [Q]uitar", ++ "thread": "[Q]Atrás [RET]Menú Es[C]ribir [^R]esponder [R]efrescar [0-9]Ir [T/B]Inicio/Fin [<>]Saltar[X]%d [/]Buscar", ++ "edit_window": "[{}]Abortar [{}]Cambiar [{}]Ayuda formato [guardar/quitar para enviar] {}" + } + + colormap = [ +@@ -343,8 +428,8 @@ class App(object): + if isinstance(self.prefs["custom_divider_char"], str): + self.theme["divider"] = self.prefs["custom_divider_char"] + except KeyError: +- exit("Selected theme does not exist. Please check " +- "the `frame_theme` value in ~/.bbjrc") ++ exit("El tema elegido no existe. Por favor revisa " ++ "el valor `frame_theme` en ~/.bbjrc") + + self.mode = None + self.thread = None +@@ -414,7 +499,7 @@ class App(object): + name = self.usermap[self.thread["author"]]["user_name"] + self.set_header("~{}: {}", name, self.thread["title"]) + else: +- self.set_header("{} threads", len(self.walker)) ++ self.set_header("{} hilos", len(self.walker)) + + + def set_default_footer(self, clobber_composer=False): +@@ -427,7 +512,7 @@ class App(object): + elif self.mode == "thread": + footer = bars["thread"] % self.prefs["jump_count"] + if self.match_data["matches"]: +- footer += " [@#] Search Control" ++ footer += " [@#] Control Búsq." + + else: + footer = bars["index"] +@@ -489,11 +574,11 @@ class App(object): + + elif pos == "body": + self.loop.widget.focus_position = "footer" +- focus = "[focused on editor]" ++ focus = "[enfocado en editor]" + + else: + self.loop.widget.focus_position = "body" +- focus = "[focused on thread]" ++ focus = "[enfocado en hilo]" + attr.reverse() + + self.loop.widget.footer[0].set_text( +@@ -522,13 +607,13 @@ class App(object): + if hours > 48: + return self.timestring(modified) + elif hours > 1: +- return "%d hours ago" % hours ++ return "hace %d horas" % hours + elif hours == 1: +- return "about an hour ago" ++ return "hace una hora" + minutes, remainder = divmod(remainder, 60) + if minutes > 1: +- return "%d minutes ago" % minutes +- return "less than a minute ago" ++ return "hace %d minutos" % minutes ++ return "hace menos de un minuto" + + + def quote_view_action(self, button, message): +@@ -575,7 +660,7 @@ class App(object): + + widget = OptionsMenu( + urwid.ListBox(urwid.SimpleFocusListWalker(buttons)), +- **self.frame_theme("View a Quote") ++ **self.frame_theme("Ver una Cita") + ) + + self.loop.widget = urwid.Overlay( +@@ -613,9 +698,9 @@ class App(object): + """ + op = message["post_id"] == 0 + buttons = [ +- urwid.Text(("bold", "Delete this %s?" % ("whole thread" if op else "post"))), ++ urwid.Text(("bold", "¿Borrar %s?" % ("hilo entero" if op else "post"))), + urwid.Divider(), +- cute_button(("10" , ">> Yes"), lambda _: [ ++ cute_button(("10" , ">> Sí"), lambda _: [ + network.message_delete(message["thread_id"], message["post_id"]), + self.remove_overlays(), + self.index() if op else self.refresh() +@@ -648,28 +733,28 @@ class App(object): + buttons = [] + + if not self.window_split: +- buttons.append(urwid.Button("Reply", self.reply, message)) ++ buttons.append(urwid.Button("Responder", self.reply, message)) + + if quotes and message["post_id"] != 0: + buttons.append(urwid.Button( +- "View %sQuote" % ("a " if len(quotes) != 1 else ""), ++ "Ver %sCita" % ("a " if len(quotes) != 1 else ""), + self.quote_view_menu, quotes)) + + if network.can_edit(message["thread_id"], message["post_id"]) \ + and not self.window_split: + + if message["post_id"] == 0: +- msg = "Thread" ++ msg = "Hilo" + else: msg = "Post" + + raw = message["send_raw"] +- buttons.insert(0, urwid.Button("Delete %s" % msg, self.deletion_dialog, message)) ++ buttons.insert(0, urwid.Button("Borrar %s" % msg, self.deletion_dialog, message)) + buttons.insert(0, urwid.Button( +- "Enable Formatting" if raw else "Disable Formatting", ++ "Activar formateado" if raw else "Desactivar formateado", + self.toggle_formatting, message)) +- buttons.insert(0, urwid.Button("Edit Post", self.edit_post, message)) ++ buttons.insert(0, urwid.Button("Editar Post", self.edit_post, message)) + if network.user["is_admin"]: +- buttons.insert(0, urwid.Text(("20", "Reminder: You're an admin!"))) ++ buttons.insert(0, urwid.Text(("20", "Recordatorio: ¡eres admin!"))) + + if not buttons: + return +@@ -711,19 +796,19 @@ class App(object): + """ + button = cute_button(">>", self.thread_load, thread["thread_id"]) + if pinned == "server": +- title = urwid.AttrWrap(urwid.Text("[STICKY] " + thread["title"]), "20") ++ title = urwid.AttrWrap(urwid.Text("[FIJADO] " + thread["title"]), "20") + elif pinned == "client": + title = urwid.AttrWrap(urwid.Text("[*] " + thread["title"]), "50") + else: + title = urwid.Text(thread["title"]) + user = self.usermap[thread["author"]] + dateline = [ +- ("default", "by "), ++ ("default", "por "), + (str(user["color"]), "~%s " % user["user_name"]), + ("dim", "@ %s" % self.timestring(thread["created"])) + ] + +- infoline = "%d replies; active %s" % ( ++ infoline = "%d respuestas; activo %s" % ( + thread["reply_count"], + self.timestring(thread["last_mod"], "delta")) + +@@ -733,7 +818,7 @@ class App(object): + urwid.Text(dateline), + urwid.Text(("dim", infoline)), + urwid.Text([ +- ("dim", "last post by "), ++ ("dim", "último post por "), + (str(last_author["color"]), "~" + last_author["user_name"]) + ]), + urwid.AttrMap(urwid.Divider(self.theme["divider"]), "dim") +@@ -760,7 +845,7 @@ class App(object): + + if no_action: + callback = ignore +- name = urwid_rainbows("~SYSTEM", True) ++ name = urwid_rainbows("~SISTEMA", True) + color = "0" + else: + callback = self.on_post +@@ -906,9 +991,9 @@ class App(object): + if results: + self.index(threads=results) + if query: +- self.set_header("Searching for '{}'", query) ++ self.set_header("Buscando '{}'", query) + else: +- self.temp_footer_message("No results for '{}'".format(query)) ++ self.temp_footer_message("No se encontró nada para '{}'".format(query)) + + + def search_thread_callback(self, query): +@@ -925,7 +1010,7 @@ class App(object): + # self.highlight_query() + self.do_search_result() + else: +- self.temp_footer_message("No results for '{}'".format(query)) ++ self.temp_footer_message("No se encontró nada para '{}'".format(query)) + + + def do_search_result(self, forward=True): +@@ -941,7 +1026,7 @@ class App(object): + self.match_data["position"] = length - 1 + self.goto_post(self.match_data["matches"][self.match_data["position"]]["post_id"]) + self.temp_footer_message( +- "({}/{}) Searching for {} [#]Next [@]Previous".format( ++ "({}/{}) Buscando para {} [#]Siguiente [@]Anterior".format( + self.match_data["position"] + 1, length, self.match_data["query"] + ), 5) + +@@ -979,9 +1064,9 @@ class App(object): + popup = OptionsMenu( + urwid.ListBox( + urwid.SimpleFocusListWalker([ +- urwid.Text(("button", "Enter a query:")), ++ urwid.Text(("button", "Ingresa pedido:")), + urwid.AttrMap(StringPrompt(callback), "opt_prompt"), +- urwid.Text("Use a blank query to reset the {}.".format(self.mode)) ++ urwid.Text("Pon un pedido en blanco para reiniciar el {}.".format(self.mode)) + ])), + **self.frame_theme()) + +@@ -1004,7 +1089,7 @@ class App(object): + thread = self.thread["thread_id"] + self.thread_load(None, thread) + self.goto_post(mark(thread)) +- self.temp_footer_message("Refreshed content!", 1) ++ self.temp_footer_message("¡Fresco como una lechuga!", 1) + + + def back(self, terminate=False): +@@ -1017,9 +1102,9 @@ class App(object): + elif self.window_split: + # display a confirmation dialog before killing off an in-progress post + buttons = [ +- urwid.Text(("bold", "Discard current post?")), ++ urwid.Text(("bold", "¿Descartar post actual?")), + urwid.Divider(), +- cute_button(("10" , ">> Yes"), lambda _: [ ++ cute_button(("10" , ">> Sí"), lambda _: [ + self.remove_overlays(), + self.index() + ]), +@@ -1082,7 +1167,7 @@ class App(object): + size, new_pos, coming_from= + "below" if (cur_pos < new_pos) else "above") + except IndexError: +- self.temp_footer_message("OUT OF BOUNDS") ++ self.temp_footer_message("FUERA DE LÍMITES") + + + def goto_post_prompt(self, init): +@@ -1093,9 +1178,9 @@ class App(object): + live_display = urwid.Text("") + edit = JumpPrompt(count, lambda x: self.goto_post(x)) + items = [ +- urwid.Text(("button", " Jump to post")), ++ urwid.Text(("button", " Ir al post")), + urwid.AttrMap(edit, "opt_prompt"), +- urwid.Text(("bold", ("(max %d)" % count).center(18, " "))), ++ urwid.Text(("bold", ("(máx. %d)" % count).center(18, " "))), + live_display + ] + +@@ -1205,11 +1290,11 @@ class App(object): + urwid.ListBox( + urwid.SimpleFocusListWalker([ + urwid_rainbows( +- "This is BBJ, a client/server textboard made for tildes!", ++ "Esto es BBJ, ¡un tablón de texto cliente/servidor para tildes!", + True), + urwid.Text(("dim", "...by ~desvox")), + urwid.Divider(self.theme["divider"]), +- urwid.Button("Post Formatting Help", self.formatting_help), ++ urwid.Button("Ayuda de Formateo de Post", self.formatting_help), + urwid.Divider(self.theme["divider"]), + urwid.Text(general_help) + ])), +@@ -1236,7 +1321,7 @@ class App(object): + + widget = OptionsMenu( + urwid.ListBox(urwid.SimpleFocusListWalker(app.make_message_body(message, True))), +- **self.frame_theme("Formatting Help") ++ **self.frame_theme("Ayuda de Formateo") + ) + + va = 5 if self.window_split else 50 +@@ -1282,9 +1367,9 @@ class App(object): + self.loop.stop() + call("clear", shell=True) + try: +- name = nameloop("Choose a new username", True) ++ name = nameloop("Elige un nuevo nombre de usuario", True) + network.user_update(user_name=name) +- motherfucking_rainbows("~~hello there %s~~" % name) ++ motherfucking_rainbows("~~qué tal, %s~~" % name) + sleep(0.8) + self.loop.start() + self.loop.widget = self.loop.widget[0] +@@ -1298,9 +1383,9 @@ class App(object): + self.loop.stop() + call("clear", shell=True) + try: +- password = password_loop("Choose a new password. Can be empty", True) ++ password = password_loop("Elige una nueva clave. Puede estar vacía", True) + network.user_update(auth_hash=network._hash(password)) +- motherfucking_rainbows("SET NEW PASSWORD") ++ motherfucking_rainbows("ELIGE NUEVA CLAVE") + sleep(0.8) + self.loop.start() + self.loop.widget = self.loop.widget[0] +@@ -1317,7 +1402,7 @@ class App(object): + self.prefs[key] = text + bbjrc("update", **self.prefs) + except: +- rendered = ("1", "Invalid Input") ++ rendered = ("1", "Entrada Inválida") + widget.set_text(rendered) + + +@@ -1343,13 +1428,13 @@ class App(object): + mode = args[0] + widget = OptionsMenu( + urwid.ListBox(urwid.SimpleFocusListWalker([ +- urwid.Text("Press Enter when done"), ++ urwid.Text("Presiona Enter cuando termines"), + urwid.AttrMap(KeyPrompt( + self.prefs["edit_escapes"][mode], + self.save_escape_key, + [mode] + ), "opt_prompt")])), +- **self.frame_theme("Set key for " + mode) ++ **self.frame_theme("Elige tecla para " + mode) + ) + + app.loop.widget = urwid.Overlay( +@@ -1396,16 +1481,16 @@ class App(object): + edit_mode = [] + + if network.user_auth: +- account_message = "Logged in as %s." % network.user_name ++ account_message = "Sesión iniciada como %s." % network.user_name + account_stuff = [ +- urwid.Button("Relog", on_press=self.relog), +- urwid.Button("Go anonymous", on_press=self.unlog), +- urwid.Button("Change username", on_press=self.change_username), +- urwid.Button("Change password", on_press=self.change_password), ++ urwid.Button("Cerrar sesión", on_press=self.relog), ++ urwid.Button("Volverse anónimo", on_press=self.unlog), ++ urwid.Button("Editar nombre de usuario", on_press=self.change_username), ++ urwid.Button("Editar clave", on_press=self.change_password), + urwid.Divider(), +- urwid.Text(("button", "Your color:")), +- urwid.Text(("default", "This color will show on your " +- "post headers and when people quote you.")), ++ urwid.Text(("button", "Tu color:")), ++ urwid.Text(("default", "Este color se mostrará en tus " ++ "cabeceras de post y cuando te citen.")), + urwid.Divider() + ] + +@@ -1420,8 +1505,8 @@ class App(object): + account_stuff.append(item) + + else: +- account_message = "You're browsing anonymously, and cannot set account preferences." +- account_stuff = [urwid.Button("Login/Register", on_press=self.relog)] ++ account_message = "Estás navegando anónimamente, no puedes cambiar opciones de cuenta." ++ account_stuff = [urwid.Button("Ingresar/Registrarse", on_press=self.relog)] + + theme_buttons = [] + for name, theme in themes.items(): +@@ -1440,10 +1525,10 @@ class App(object): + urwid.connect_signal(date_edit, "change", self.live_time_render, (date_box, "date")) + + time_stuff = [ +- urwid.Text(("button", "Time Format")), ++ urwid.Text(("button", "Formato de Tiempo")), + time_box, urwid.AttrMap(time_edit, "opt_prompt"), + urwid.Divider(), +- urwid.Text(("button", "Date Format")), ++ urwid.Text(("button", "Formato de Fecha")), + date_box, urwid.AttrMap(date_edit, "opt_prompt"), + ] + +@@ -1463,17 +1548,17 @@ class App(object): + user_data=(editor, editor_display)) + + urwid.RadioButton( +- edit_mode, "Integrate", ++ edit_mode, "Integrar", + state=self.prefs["integrate_external_editor"], + on_state_change=self.set_editor_mode) + + urwid.RadioButton( +- edit_mode, "Overthrow", ++ edit_mode, "Sobreponer", + state=not self.prefs["integrate_external_editor"]) + + content = [] + +- for item in [urwid.Text(("opt_header", "Account"), 'center'), ++ for item in [urwid.Text(("opt_header", "Cuenta"), 'center'), + urwid.Text(account_message), + urwid.Divider()]: + content.append(item) +@@ -1482,33 +1567,33 @@ class App(object): + content.append(item) + + for item in [urwid.Divider(self.theme["divider"]), +- urwid.Text(("opt_header", "App"), 'center'), ++ urwid.Text(("opt_header", "Aplicación"), 'center'), + urwid.Divider(), + urwid.CheckBox( +- "Dump rainbows on exit", ++ "Tirar arcoiris al salir", + state=self.prefs["dramatic_exit"], + on_state_change=self.toggle_exit + ), + urwid.CheckBox( +- "Warn when posting anonymously", ++ "Advertir cuando se postea anónimamente", + state=self.prefs["confirm_anon"], + on_state_change=self.toggle_anon_warn + ), + urwid.CheckBox( +- "Increase index padding", ++ "Aumentar espaciado del índice", + state=self.prefs["index_spacing"], + on_state_change=self.toggle_spacing + ), + urwid.CheckBox( +- "Handle mouse (disrupts URL clicking)", ++ "Usar ratón (perturba cliquear URLs)", + state=self.prefs["mouse_integration"], + on_state_change=self.toggle_mouse + ), + urwid.Divider()]: + content.append(item) + +- for item in [urwid.Text(("button", "Border Theme")), +- urwid.Text("Restart to fully apply.")]: ++ for item in [urwid.Text(("button", "Tema de Borde")), ++ urwid.Text("Reinicia para aplicar completamente.")]: + content.append(item) + + for item in theme_buttons: +@@ -1520,14 +1605,14 @@ class App(object): + content.append(item) + + for item in [urwid.Divider(), +- urwid.Text(("button", "Max message width:")), ++ urwid.Text(("button", "Ancho máximo de mensaje:")), + urwid.AttrMap(width_edit, "opt_prompt"), + urwid.Divider(), +- urwid.Text(("button", "Scroll multiplier when holding shift or scrolling with the mouse:")), ++ urwid.Text(("button", "Multiplicador de despl. cuando se aprieta shift o se mueve con mouse:")), + urwid.AttrMap(shift_edit, "opt_prompt"), + urwid.Divider(), +- urwid.Text(("button", "Text editor:")), +- urwid.Text("You can type in your own command or use one of these presets."), ++ urwid.Text(("button", "Editor de texto:")), ++ urwid.Text("Puedes poner tu propio comando o usar alguno de éstos predefinidos."), + urwid.Divider(), + urwid.AttrMap(editor_display, "opt_prompt")]: + content.append(item) +@@ -1536,20 +1621,20 @@ class App(object): + content.append(item) + + for item in [urwid.Divider(), +- urwid.Text(("button", "Internal Editor Escape Keys:")), +- urwid.Text("You can change these keybinds to whatever " +- "you want. Just remember that these will " +- "shadow over the text editor itself."), ++ urwid.Text(("button", "Teclas de escape del Editor Interno:")), ++ urwid.Text("Puedes cambiarlas a cualquiera que " ++ "prefieras. Solo recuerda que se aplicarán " ++ "encima del programa de edición de texto."), + urwid.Divider(), +- urwid.Button("Abort", self.set_escape_key, ["abort"]), +- urwid.Button("Change Focus", self.set_escape_key, ["focus"]), +- urwid.Button("Formatting Help", self.set_escape_key, ["fhelp"])]: ++ urwid.Button("Abortar", self.set_escape_key, ["abort"]), ++ urwid.Button("Cambiar Foco", self.set_escape_key, ["focus"]), ++ urwid.Button("Ayuda de Formateo", self.set_escape_key, ["fhelp"])]: + content.append(item) + + for item in [urwid.Divider(), +- urwid.Text(("button", "External text editor mode:")), +- urwid.Text("If you have problems using an external text editor, " +- "set this to Overthrow."), ++ urwid.Text(("button", "Modo de editor de texto externo:")), ++ urwid.Text("Si tienes problemas usando un editor de texto externo, " ++ "elige Sobreponer."), + urwid.Divider()]: + content.append(item) + +@@ -1560,7 +1645,7 @@ class App(object): + + widget = OptionsMenu( + urwid.ListBox(urwid.SimpleFocusListWalker(content)), +- **self.frame_theme("Options")) ++ **self.frame_theme("Opciones")) + + self.loop.widget = urwid.Overlay( + widget, self.loop.widget, +@@ -1618,7 +1703,7 @@ class App(object): + descriptor, path = tempfile.mkstemp() + with open(path, "w") as _: + _.write(init_body) +- call("export LANG=en_US.UTF-8; %s %s" % (self.prefs["editor"], path), shell=True) ++ call("export LANG=es_ES.UTF-8; %s %s" % (self.prefs["editor"], path), shell=True) + with open(path) as _: + body = _.read() + os.remove(path) +@@ -1632,18 +1717,18 @@ class App(object): + context and user preferences. + """ + if self.mode == "index" and not title: +- return self.footer_prompt("Title", self.compose) ++ return self.footer_prompt("Título", self.compose) + + elif title: + try: network.validate("title", title) + except AssertionError as e: + return self.footer_prompt( +- "Title", self.compose, extra_text=e.description) ++ "Título", self.compose, extra_text=e.description) + + if not self.prefs["integrate_external_editor"]: + body = self.overthrow_ext_edit(init_body) + if not body or re.search("^>>[0-9]+$", body): +- return self.temp_footer_message("EMPTY POST DISCARDED") ++ return self.temp_footer_message("POST VACÍO DESCARTADO") + params = {"body": body} + + if self.mode == "thread" and not edit: +@@ -1674,8 +1759,8 @@ class App(object): + return + + if self.mode == "index": +- self.set_header('Composing "{}"', title) +- self.set_footer("[{}]Abort [{}]Formatting Help [Save and quit to submit your thread]".format( ++ self.set_header('Escribiendo "{}"', title) ++ self.set_footer("[{}]Abortar [{}]Ayuda de Formateo [Guarda y sal para publicar el hilo]".format( + self.prefs["edit_escapes"]["abort"].upper(), self.prefs["edit_escapes"]["fhelp"].upper() + )) + self.loop.widget = urwid.Overlay( +@@ -1977,7 +2062,7 @@ class ExternalEditor(urwid.Terminal): + # behalf. Users who take issue to programs trying to supress unicode + # should use the options menu to switch to Overthrow mode. + env.update({"LANG": "POSIX"}) +- command = ["bash", "-c", "{} {}; echo Press any key to kill this window...".format( ++ command = ["bash", "-c", "{} {}; echo Presione cualquier tecla para matar esta ventana...".format( + app.prefs["editor"], self.path)] + super(ExternalEditor, self).__init__(command, env, app.loop, app.prefs["edit_escapes"]["abort"]) + urwid.connect_signal(self, "closed", self.exterminate) +@@ -2027,7 +2112,7 @@ class ExternalEditor(urwid.Terminal): + call("clear", shell=True) + print(anon_warn) + choice = paren_prompt( +- "Publicar anónimamente?", default="si", choices=["Sí", "no"] ++ "¿Publicar anónimamente?", default="s", choices=["s", "n"] + ) + if choice == "n": + log_in(True) +@@ -2464,9 +2549,9 @@ def log_in(relog=False): + elif response == "n": + raise InterruptedError + +- password = password_loop("Enter a password. It can be empty if you want") ++ password = password_loop("Ingresa una clave. Puede estar vacía si quieres") + network.user_register(name, password) +- motherfucking_rainbows("~~welcome to the party, %s!~~" % network.user_name) ++ motherfucking_rainbows("~~¡bienvenido a la fiesta, %s!~~" % network.user_name) + sleep(0.5) # let that confirmation message shine + + + + |