Things that can make macOS better

I use macOS as the main OS in my computer, actually the only one in my personal computer, but I have other computers with Linux as desktop too, but macOS is the one that I use the most. And over the time I have learned how to get more from the OS as the default installation.

For example, I currently don’t use Spotlight, I use another tool called “Alfred” you all might know it.

Alfred > Spotlight

Spotlight was a good thing back in the days were it was basically a search tool for the OS living in the corner, where nobody looks. But it was not good as a some sort of launcher, and having all my apps in the Dock was not a good idea. Then Alfred arrived and it came with other functionality like workflows and search in places where spotlight just don’t do, also the fuzzy word search (like GC and expect to get Google Chrome) works very well.

If Apple were smart enough to buy Alfred and use it instead of their current implementation of spotlight (GUI) that would make macOS much more useful.

Quick send mail

Email is my preferred way to send messages, pictures, documents to friends and colleagues, but I don’t want to keep the whole app open, It would be create to have a mini-composer ready to be used whenever you want to send a quick email.

In which cases you would want to use “Quick-email” ?.. well, in the “share” button there is “Mail” and it opens the whole app, you can use that mini-composer, you don’t want to read email, you want to send.

Another example, you just remembered you need to ask for some help to a partner, a quick workflow in “Alfred” could launch that mini-composer, write a small email, hit the send button (or a shortcut-key) and you are done.

Quick Calendar add.

Basically the same thing as Quick send mail but to add things in the calendar, you can quickly view your day or tomorrow in the today widgets.

Open new window in current fullscreen space

Full Screen mode is for me one of the best things that macOS have in the windows corner. I work mostly with full screen apps, this because it let me focus on the current task, is less cluttered and digging a bit on the os side, it allows background apps to take a nap and free resources.

Sometimes I want to open a new tab of safari but in a new window, but, it opens in a new fullscreen window, then I have to enter to mission control and then move the window near to the other an attach it to the space where the original window was, then I have a single space with two windows in fullscreen mode.

A quick way to to that would be great, like in the email composer, just open it in fullscreen mode, hit CMD+N and a new window appears next to the current without leaving the current space.

Flyover apps

This is common in iOS, you can have one app in flyover mode, is hidden in every space, but when you call it is a floating window in the current space with you can remove from flyover mode and attach to the current spate. wouldn’t that be great?. What if you can have several apps in flyover ? I would put mail in that mode.

Loading

Buenas practicas en Django

En un post anterior les comenté las buenas prácticas en Python, ahora toca hablar de Django, si bien Django esta hecho en el lenguaje Python tiene sus propias convenciones como framework, y seguir estos lineamientos permitirá que tengas proyectos organizados pero sobre todo, que tus compañeros de trabajo (si todos siguen estas recomendaciones) y tu funcionen mejor.

Estilo de código

Aquí no hay mucho que decir, estamos hablando de Python y por lo tanto aplican las reglas de estilo de Código de Python, debes escribir siguiendo la PEP8. Django también tiene sus propias convenciones para escribir código, estas las puedes encontrar aquí , coteja con las de Python, verás que son complementarias.

Settings

settings.py es uno de los módulos principales en tu app, en el se definen los parámetros con los que ha de funcionar tu aplicación, es importante mantener limpio este módulo, e incluso, quitar lo que no es básico para entender el funcionamiento de la aplicación o moverlo a otro lado.

Recordemos que estamos hablando de Python, podemos hacer nuestro settings.py muy modular, e importar lo que se necesita en el momento. Por ejemplo, las configuraciones de logging , o las configuraciones correspondientes al ambiente de desarrollo que son típicamente diferentes a las de producción.

Rutas

Nuestro ambiente de desarrollo esta en una ruta en el almacenamiento diferente de la que estará en producción, es por ello que debemos evitar usar rutas “duras”, en su lugar debemos referirnos a rutas relativas a una que Python nos proporcionará.

Es común ver en el settings.py la variable BASE_DIR y STATIC_ROOT que son variables donde se define la ruta absoluta del proyecto en disco duro, así como donde se guardan los archivos estáticos en disco duro. Estas variables las podemos definir mejor así:

BASE_DIR = os.path.dirname(__file__)
STATIC_ROOT = os.path.join(BASE_DIR, "static")

urls

En nuestro proyecto veremos un archivo urls.py que no es mas que un módulo que contiene la información de cada una e las URLs dentro de nuestro proyecto. Me ha tocado ver urls.py tan largos como la cuaresma, y no, no es nada bonito tener un módulo asi de grande, sobre todo porque es confuso.

Que podemos hacer entonces?. Bueno, en principio, tener un urls.py en cada app de tu proyecto, de esta forma cada app será independiente, se reducirá el tamaño del archivo principal y te será m as fácil ubicar las urls en caso de agregar/editar/borrar. La otra, en el caso de que nuestra app tenga muchas urls, es modularizar, puedes repartir las urls en mas módulos dependiendo de cada sección dentro de tu app.

Plantillas

Las plantillas en Django están en básicamente en dos lugares, en el directorio base de tu proyecto y en el de cada app, ahí deberá haber un directorio llamado templates. Lo importante aquí es que las plantillas de tu app deben estar en el directorio templates dentro de tu app. Las plantillas “base” o genéricas podrían estar en tu directorio templates en el directorio base.

BASE_DIR/
        /myproject/
                  /settings.py
                  /urls.py
        /templates/
                  /base.html
                  /header.html
                  /footer.html
        /my_app/
               /models.py
               /views.py
               /urls.py
               /admin.py

Contenido estatico

Lo mismo que con las plantillas. Cada app debe mantener su contenido estático para cada una de ellas, con esto mantienes la independencia de la app y permites que pueda ser usada en otros proyectos.

El contenido estático pueden ser:

  • imágenes
  • JavaScript
  • CSS

Ojo, no se debe confundir el contenido estático con el contenido que sube el usuario final, este contenido que sube el usuario va al directorio “Media”

Otras convenciones que aplico yo

Estas no están dentro de las convenciones de las buenas prácticas en Django, pero las he usado y me han servido muy bien:

Convertir views.py /forms.py en un paquete

Con esto puedo seccionar las partes de mi app, así tengo Views para cada sección y son generalmente archivos pequeños. Con esto evito tener un “views” de mas de 1000 lineas.

BASE_DIR/
        /myproject/
        /my_app/
               /models.py
               /urls.py
               /admin.py
               /views/
                     /customers.py
                     /products.py
                     /reports.py

Usar siempre Class Views

Django desde hace buen tiempo ya cuenta con las Class Views. Antes estábamos acostumbrados a que cada vista era una función, pero los Class Views tienen muchas ventajas sobre las funciones.

Lo que mas me gusta es que puedo crear una clase base y solo extender su uso dependiendo de la sección, por ejemplo, tengo la sección Customers, entonces creo una vista básica de “customers”:

class CustomerBasicView(LoginRequiredMixin ,TemplateView):
    template_name = "blank.html"
    # Esta variable de clase se llenará con el valor delcliente en turno.
    customer = None

    def get_context_data(self, *args, **kwargs):
        # Crear el contexto y llenar lo "General"

    def get(self, request, *args, **kwargs):
        # Llamar get_context_data
        # Llamar una función en las clases hijas para complementar el contexto
        # Ejecutar una función anexa a "get" para finalizar get
        # Si no existe dicha función retrnar
        return self.render_to_response(self.context)

Y las demás clases solo necesitan heredar de CustomerBasicView

class Dashboard(CustomerBasicView):
    template_name="customers/dashboard.html"

class View(CustomerBasicVIew):
    template_name="customers/view.html"

class Edit(CusotmerBasicView):
    template_name="customers/edit.html"

Como ven?. Dejaré una explicación mas detallada de esto que hago para otro post. Tal vez mañana.


Si te gustó el articulo, compartelo en tus redes sociales, si tienes algo que agregar con toda confianza hazlo en los comentarios.

Loading

How to move some files but preserve the directory tree?

So, I have a bunch of ogg files that I moved to mp3 (I don’t want to start a format/encoder war, I just did it), I wanted to move the old ogg files, I didn’t delete them because probably I need them in the future. To move the files apart the easiest way could be using find and xargs:


find . -iname "*ogg" -print0 |xargs -0 -I {} mv {} /dest/folder/

The problem with this is that all those ogg files would be in /dest/folder/ all together, and I want to have them each in the corresponding subfolder, I was looking and found that some uses “cp –parents” unfortunately it seems that the cp in OS X does not include that.

What I ended up doing.

If you create a package file (.tar for example), the directories are preserved, so, for me the trick was using tar for that purpose.


find . -name "*ogg" -print0 | xargs -0 tar cvf - |(cd /dest/folder/ ; tar xfp -)

You’ll see all those ogg files in the screen as they are “copied” to the destination folder. later you can remove the files with find again.


find . -iname "*ogg" -delete

 

I assume there is a way to remove the files as soon as they have been added to the tar file.

Loading

Find (and remove files) with find

terminal

find is a great tool to find things, but not only to find them, but to work on them. I have a small collection of music, which I presume at some point will be removed from my computer hard drive (maybe if I can get a new one it won’t be there at all) because I mostly listen to music from internet and I have a copy of the music in a external hard drive.

Today I imported the folder where the music is to iTunes again, and it created playlists that I don’t remember to have them before. That is because there were several m3u files there (winamp playlists), there are around 5k files in that directory tree and I don’t want to spend my time looking for m3u files, so, let the computer do the job.

With find is easy to find files, not by their name but by their type the f is for file.

find . -type f

Ok, but that will include all the “mp3” which are files, so if I make use of -iname to find by name,  how can I do the opposite?, well, like in most programming languages, you can negate by using the exclamation symbol !.

find . -type f ! -iname "*mp3"

And add some more extensions.

find . -type f ! -iname "*mp3" ! -iname "*ogg" ! -iname "*m4a" ! -iname "*wma"

That will give me all files that are not mp3, ogg, m4a or wma. Then just use the -delete parameter to as find to delete them.

find . -type f ! -iname "*mp3" ! -iname "*ogg" ! -iname "*m4a" ! -iname "*wma" -delete

And… they are gone.

How would you do it?. Share it in the comments.

Loading

Vim Pro tip – Edit the current buffer in a new tab

Vim_logo

Quite often I found in vim that I would like the current buffer in a new tab, I use a lot the vertical and horizontal splits in vim, then I reach the limit (my screen limit) for the vertical/horizontal splits, this means: if I add a new vertical split the code looks ugly even if it respects the 80 columns width, or if add a new horizontal split there would be just too few lines that is not worth to keep the buffer.

Then I used open a new tab, type

:e

then type the path to the buffer I like to edit. Until now, now I open a new tab, then type

:ls

check then number of the buffer I want in this new tab and then type

:bX

being “X” the number of the buffer, ej “:b2“. Another trick is to type

:bn

for the next buffer or

:bp

for the previous.

Loading