search

Wednesday, April 29, 2015

fedora: How to automatically shutdown your system

The easiest way to shutdown your system is to use shutdown command:
sudo shutdown

It will start shutdown process immediaetely.

To shutdown your system in specific time use this command:
sudo shutdown 11:50


And to shutdown your system in 2 hours (120 mins) use this command:
sudo shutdown +120

Monday, March 23, 2015

fedora: How to find out which package provides a specific file

If you need to find out, for example, which package in fedora provides htpasswd command, you may do it with the command:
yum provides \*bin/htpasswd


How to set up authentication for your website with nginx

You can set up basic authentication with nginx to restrict access to your website:

Install httpd-tools package first:
sudo yum install httpd-tools

If you are on Ubuntu install that package:
sudo apt-get install apache2-utils

Add to your nginx config:
server {
...
auth_basic "closed site";
auth_basic_user_file conf/htpasswd;
}

Go to /etc/nginx and create folder conf:
cd /etc/nginx
sudo mkdir conf

Then you need to generate file htpasswd that contains authentication data:
sudo htpasswd -c htpasswd admin

Sunday, March 22, 2015

byobu: Vertical window split issue

Vertical split with default keys configuration in byobu (which is Shift+F2) doesn't work. I decided to change it to Ctrl+F1 instead. To do it open keybinding file:
sudo vim /usr/share/byobu/keybindings/f-keys.tmux

And replace line
bind-key -n S-F2 display-panes \; split-window -v

with
bind-key -n C-F1 display-panes \; split-window -v

Make sure that tmux keybinding is active and default one. Open file
/usr/share/byobu/keybindings/f-keys

and check that it contains
source $BYOBU_PREFIX/share/byobu/keybindings/f-keys.tmux

How to create git commit template

At work we integrated git with JIRA. If commit starts with our project name in JIRA and contains issue id, it will be automatically linked to that issue. For example:

PROJECT-10 Fix timezone

That pattern requires that every commit starts with the same characters "PROJECT-". Git supports commit templates, so every new commit message will include text from this template.

To make it work you just need to create a simple text file and configure git to use this file:
git config --local commit.template /path/to/git-commit-template.txt

How to find outdated python packages in your environment

The easiest way to find out if updated version of any installed package is available is to run that command:
pip list --outdated


There is also a special package for that task which is called pip-tools

Tuesday, December 9, 2014

bash: Colourful side-by-side command line diff

I have never liked default linux diff command. The more changes you make, the less informative it becomes. When you work with git it would be nice to have side-by-side comparison of original file and a new file with changes. Graphical tools like smartgit and meld do it really impressive.

But sometimes it is more comfortable to use command line tools. For colourful side-by-side git diff you can use cdiff. The simpliest way to install it is with pip package manager:
pip install cdiff

Then in your repository run:
cdiff -s

And the result is gorgeous!

The next tool is called icdiff. It does basicly the same, but with files. Install it with that command:
curl -s https://raw.githubusercontent.com/jeffkaufman/icdiff/release-1.2.0/icdiff \
| sudo tee /usr/local/bin/icdiff > /dev/null \
&& sudo chmod ugo+rx /usr/local/bin/icdiff


Use it like this:
icdiff file1 file2

Tuesday, November 18, 2014

fedora 20: How to install latest geary from copr

Fedora corp is a storage for unofficial repositories for fedora enthusiasts. For example the latest geary version in the official fedora 20 repository is 0.6.1, which is quite old. The easiest way to update it to the latest available is to install it from copr. I found at least 3 repositories which provide update to 0.8.1.

First of all we need to install yum-plugin-copr plugin:
sudo yum install yum-plugin-copr

There is a missing dependency for that package. If you run yum and see:
Plugin "copr" can't be imported

Try to install python-requests package:
sudo yum install package-requests

Then we need to add a repository with newwest geary version. It is as simple as that:
sudo yum copr enable thm/geary

Run next command to update your geary from newly installed copr repository:
sudo yum update

Friday, November 7, 2014

python: Precompile nunjucks files on change

Preface

I have been writing an Firefox extension for some time. It generates HTML content which depends on the context. When I started, I decided to do it with JavaScript:
var container = document.createElement("div");
document.getElementById("items-list").appendChild(container);

However, JavaScript quickly became messy. Another problem was that I didn't have HTML in front of me to create stylesheet.

I have used JavaScript template engine in one of my projects recently. It would be nice to do it in the Firefox extension. There will be at least two benefits: my JavaScript will be shorter and cleaner to read and I will be able to see HTML to easy write css.

I choose nunjucks template engine by Mozilla. It is fast, feature rich and copies Jinja2 syntax. To be honest, the last reason was the most important for me. I have developed several web applications in Django and Flask and really like django templates and jinja2 syntax.



Nunjucks easy integrates in the webpage. It is as simple as that:
1. Load script in you HTML:
<script src="nunjucks.js"></script>

2. Render template with context and append it to the page:
var rendered_html = nunjucks.render('templates/index.html', { foo: 'bar' });
document.getElementById("container").innerHTML = rendered_html;

I tried the same approach in the Firefox extension. I needed to append HTML in the toggle button popup container. So I loaded nunjucks.js inside popup (it is called panel in the Firefox) by passing it to contentScriptFile option.

Problem

Unfortunately, nunjucks wasn't able to find template I wanted it to render. As far as I know It makes Ajax request to your server (what server in case of Firefox extension, ha?) to retrieve HTML file and then renders it. Nunjucks also supports precompiled templates (which indeed it renders much faster). Precompiled templates are preferable in the production and are represented as JavaScript files. So my idea was to precompile templates and pass these JavaScript files with contentScriptFile option. In the nunjucks.render function it looks for the array instance with the same name as path to the Ajax request('templates/index.html' in the example above) and if it exists it starts to render it without downloading an html template. Exactly what we need!

Templates are compiled into JavaScript files by precompile bash script. It is inside bin folder of the nunjucks git repository. Lets clone the repository:
cd /home/jsn/app/git_projects/
git clone https://github.com/mozilla/nunjucks.git

We also need to install some dependencies. Firstly, we install nodejs package and nodejs package manager:
sudo yum install nodejs npm

Then two nodejs packages:
npm install chokidar optimist

No we are able to compile template into JavaScript file with command:
/home/jsn/app/git_projects/nunjucks/bin/precompile path_to_html >> path_to_js

There is a problem with that command: it looks ugly because it demands absolute paths to the HTML and JavaScript files. If you run it and open compiled file you will see that precompile script used absolute path_to_template to identify template. That is not what we need as we are going to use just filename as identifier ("index.html"). To fix last problem we can pass --name to the precompile command:
/home/jsn/app/git_projects/nunjucks/bin/precompile --name index.html path_to_the_index.html >> path_to_the_index.js

Now we have the command which we are supposed to execute on every HTML file change. It would be nice to automate that step. So we need a script which will check every template in our templates folder and if a file was changed it would compile the file.

Solution

We are going to write that script in Python. First of all we need list of all files inside template folder. We will use listdir method of os package:
file_list = os.listdir(templates_dir)

File modification time we can check with os.getmtime() method. We will create global dictionary FILES. The keys of that dictionary will be file names and values will be last modification time. All we need to do is to fill that dictionary on the script start up and run precompile command if last modification time was changed.
FILES = {}
TIMER = 1

COLOUR_END = '\033[0m'
COLOUR_GREEN = '\033[92m'
COLOUR_BLUE = '\033[94m'


def check_templates(templates_dir=TEMPLATES_DIR):
    file_list = os.listdir(templates_dir)
    for item in file_list:
        if item.split(".")[-1] == "html":
            modified = os.path.getmtime(templates_dir + "/" + item)
            if item in FILES:
                if FILES[item] != modified:
                    FILES[item] = modified
                    precompile(templates_dir, item)
            else:
                print (COLOUR_BLUE + item + " is being watched" + COLOUR_END)
                FILES[item] = modified
                precompile(templates_dir, item)

We also filter files in our template directory by extension (as we are interested only in the html files). I use print function to inform myself when script finds new file in directory. Note, that these lines will be blue. It will make that event more noticeable.

We will check files for changes every second (TIMER variable):
if __name__ == '__main__':
    while True:
        check_templates()
        sleep(TIMER)

We can ask Python to execute for us any command we would normally execute in bash. Call method of the subprocess package helps to do it.
def precompile(tempates_dir, filename):
    compiled_filename = filename.replace("html", "js")
    path_to_js = tempates_dir + "/" + compiled_filename
    path_to_html = tempates_dir + "/" + filename
    if os.path.exists(path_to_js):
        call("rm -f " + path_to_js, shell=True)
    command = NUNJUCKS_REPO + "/bin/precompile --name " + filename + " " + path_to_html
    command = command + " >> " + path_to_js
    call(command, shell=True)
    print(COLOUR_GREEN + datetime.now().strftime("%X" + " " + filename + " ...OK") + COLOUR_END)

By default if compiled JavaScript exists, precompile command will add newly compiled data to it, so we have to check if compiled file exists with os.path.exists() method and remove it with bash rm -f command. NUNJUCKS_REPO is the path to the cloned nunjucks repository.

There is still a thing we can improve in the script. I will store that script in the project repository and I would like to use it on different machines. So hard coded template and nunjucks directory paths is not the option. I would like to set them as commands arguments to our script or maybe I will set these paths as environment variables. Anyway, full version of the script is below:
#!/usr/bin/python

# This script will monitor templates folder and automatically compile nunjucks html templates on change

import os
import sys
from datetime import datetime
from subprocess import call
from time import sleep

try:
    NUNJUCKS_REPO = sys.argv[1]
except IndexError:
    NUNJUCKS_REPO = os.getenv("NUNJUCKS_REPO")
try:
    TEMPLATES_DIR = sys.argv[2]
except IndexError:
    TEMPLATES_DIR = os.getenv("TEMPLATES_DIR")

FILES = {}
TIMER = 1

COLOUR_END = '\033[0m'
COLOUR_GREEN = '\033[92m'
COLOUR_BLUE = '\033[94m'


def check_templates(templates_dir=TEMPLATES_DIR):
    file_list = os.listdir(templates_dir)
    for item in file_list:
        if item.split(".")[-1] == "html":
            modified = os.path.getmtime(templates_dir + "/" + item)
            if item in FILES:
                if FILES[item] != modified:
                    FILES[item] = modified
                    precompile(templates_dir, item)
            else:
                print (COLOUR_BLUE + item + " is being watched" + COLOUR_END)
                FILES[item] = modified
                precompile(templates_dir, item)


def precompile(tempates_dir, filename):
    compiled_filename = filename.replace("html", "js")
    path_to_js = tempates_dir + "/" + compiled_filename
    path_to_html = tempates_dir + "/" + filename
    if os.path.exists(path_to_js):
        call("rm -f " + path_to_js, shell=True)
    command = NUNJUCKS_REPO + "/bin/precompile --name " + filename + " " + path_to_html
    command = command + " >> " + path_to_js
    call(command, shell=True)
    print(COLOUR_GREEN + datetime.now().strftime("%X" + " " + filename + " ...OK") + COLOUR_END)


if __name__ == '__main__':
    while True:
        check_templates()
        sleep(TIMER)




As we use only precompiled JavaScript templates we can switch to nunjucks-slim.js. Slim version is smaller and works only with precompiled templates.

If you have any suggestions or questions, please let me know in the comments.

Monday, October 20, 2014

fedora 20: Установка mysql

С версии 19 в fedora MySQL база данных заменена на MariaDB, которая обеспечивает полную совместимость.

Установим базу данных:
sudo yum install mariadb mariadb-server

Стартуем сервис:
sudo service mysqld start

И запускаем настройку:
mysql_secure_installation

При первом запуске программа запросит ввести root пароль, просто нажмите Enter, а вот на 2ом шаге введите реальный пароль. Ответьте на остальные вопросы.

Запускаем sql консоль для создания базы данных:
mysql -u root -p

Новая база данных создается командой:
CREATE DATABASE techtips
DEFAULT CHARACTER SET utf8
DEFAULT COLLATE utf8_general_ci;

Выйти из консоли можно командой:
\q

Пример настроек для Flask + SQLAlchemy:
SQLALCHEMY_DATABASE_URI = 'mysql+mysqldb://root:12345@localhost/techtips?charset=utf8&use_unicode=0'

Как сделать GET запрос с помощью gjs

const Soup = imports.gi.Soup;

var _httpSession = new Soup.Session();

var message = Soup.form_request_new_from_hash('GET', "http://google.com", {});
_httpSession.queue_message(message, function(_httpSession, message) {
log(message.status_code);
log(message.response_body.data);
});

PythonAnywhere: Настройка MySQL

В данный момент PythonAnywhere поддерживает только MySQL как бесплатную базу данных (обещают скоро добавить поддержку Postgresql ). Начнем с создания базы данных. Для этого необходимо перейти на вкладку Databases и в поле Create database ввести имя базы данных:

Также надо установить пароль для доступа к базе данных. Путь базы данных для sqlalchemy будет выглядеть так:
SQLALCHEMY_DATABASE_URI = 'mysql+mysqldb://pa_username:db_password@mysql.server/db_name'

где pa_username - имя пользователя на PythonAnywhere, db_password - пароль к базе данных, db_name - имя базы данных (например, jsnjack$main-mysql).

Для того, чтобы sqlalchemy работала с mysql надо установить пакет:
pip install MySQL-python

PythonAnywhere: Настройка wsgi для приложения Flask

Предположим, что используется virtualenv. *wsgi.py выглядит следующим образом:
activate_this = '/home/jsnjack/jsn-techtips/env/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))

import sys

path = '/home/jsnjack/jsn-techtips'
if path not in sys.path:
sys.path.append(path)

from app import create_app
application = create_app('pythonanywhere')


Первые 2 строки - эквиваленты source ./env/bin/activate на локальной копии. Path - путь к приложению. create_app() - функция, которая возвращает flask-приложение (и это едиственное условие для правильной конфигурации - присвоить переменной application приложение Flask), "pythonanywhere" - профиль конфигурации.

Код для create_app и профилей создан на основе flasky

Saturday, October 18, 2014

fedora 20: Как установить atom

Atom - это бесплатный текстовый редактор, который разрабатывает та же компания что и github. На официальном сайте доступен только пакет для Ubuntu. В интернете есть инструкция по установке atom для fedora 20 из исходников.

Инструкция достаточно подробная и я по ней уже когда-то устанавливал atom. Но! Есть более простой способ - воспользоваться *.deb пакетом. Последнюю версию можно скачать тут.

Итак, копируем скачанный пакет в папку куда хотим установить atom и выполняем команду:
ar p atom-amd64.deb data.tar.gz | tar zx

Запускаем atom командой:
./usr/bin/atom

Friday, October 17, 2014

bash: Как изменить командную строку в bash

В bash командную строку можно изменить присвоив значение PS1 в терминале. Вот эта команда добавит время, полный путь в запрос, а также выведет его на следующую строку:
$ PS1="\[\033[01;32m\]\t \[\033[01;34m\]\w\[\033[00m\]\[\033[1;32m\]\n\$ \[\033[m\]"
Чтобы изменения сохранились после перезагрузки, добавьте эту строку в файл ~/.bashrc:
# Configure prompt
export PS1="\[\033[01;31m\]\$([ \$? == 0 ] || echo \"!\$? \" )\[\033[00m\]\[\033[01;32m\]\t \[\033[01;34m\]\w\[\033[00m\]\[\033[1;32m\]\n\$ \[\033[m\]"
Список специальных символов:

\d The date, in "Weekday Month Date" format (e.g., "Tue May 26").

\h The hostname, up to the first . (e.g. deckard)

\H The hostname. (e.g. deckard.SS64.com)

\j The number of jobs currently managed by the shell.

\l The basename of the shell's terminal device name.

\s The name of the shell, the basename of $0 (the portion following the final slash).

\t The time, in 24-hour HH:MM:SS format.

\T The time, in 12-hour HH:MM:SS format.

\@ The time, in 12-hour am/pm format.

\u The username of the current user.

\v The version of Bash (e.g., 2.00)

\V The release of Bash, version + patchlevel (e.g., 2.00.0)

\w The current working directory.

\W The basename of $PWD.

\! The history number of this command.

\# The command number of this command.

\$ If you are not root, inserts a "$"; if you are root, you get a "#" (root uid = 0)

\nnn The character whose ASCII code is the octal value nnn.

\n A newline.

\r A carriage return.

\e An escape character.

\a A bell character.

\\ A backslash.

\[ Begin a sequence of non-printing characters. (like color escape sequences). This allows bash to calculate word wrapping correctly.

\] End a sequence of non-printing characters.