Firefox: NS_ERROR_FILE_CORRUPTED
Столкнулся сегодня с этой ошибкой в консоли фокса.
Причина проста: повреждение хранилища localStorage. Подробнее можно посмотреть официальную документацию.
Решается удалением файла ``` webappsstore.sqlite
В коде же это исключение так же следует обрабатывать корректно (чтобы не пугать пользователя).
```javascript
try {
setLocalStorageItem(key, value);
} catch(e) {
if(e.name == "NS_ERROR_FILE_CORRUPTED") {
showMessageSomehow("Sorry, it looks like your browser storage has been corrupted. Please clear your storage by going to Tools -> Clear Recent History -> Cookies and set time range to 'Everything'. This will remove the corrupted browser storage across all sites.");
}
}
Странно, но в моем случае чистка всего-всего таки не помогла. Помогло ручное удаление файла.
Разработка на Python с использованием virtualenv
Virtual Environment - полезный инструмент, который позволет держать различные конфигурации зависимостей проектов в разных директориях. Например он решает проблему когда одному приложению требуется версия 1.0 пакета X, а другому - 2.0.
vitrualenv
Главным инструментов будет virtualenv.
$ sudo yum install python-virtualenv
Использование
Создадим окружение
$ cd project_dir
$ virtualenv proj_env
Этими командами мы создадим папку proj_env, которая будет содержать наше новое окружение. В этой папке будет набор скриптов и копия интерпретатора python, который будет использоваться в окружении (окружение использует свой интерпретатор, а не общесистемный).
При создании окружения можно указать, какая версия python нам нужна.
Возможно, что в системе параллельно стоит как python2, так и python3. Выбирать версию при создании окружения мы можем ключем -p. Если ключ не указан, то будет выбрана версия /usr/bin/python.
$ virtualenv -p /usr/bin/python3.4 proj_env
Для того, чтобы попасть в наше новое окружение используем
$ source proj_env/bin/activate
Теперь мы внутри окружения.
Определеить это можно по изменившемуся приглашению:
(proj_env)тут_старое_приглашение_из_$PS1
Все. Мы внутри окружения. Можно ставить зависимости для нашего приложения.
$ pip install flask flask-bootsrap rq rq-scheduler pymysql
Выйти из окружения можно при помощи
$ deactivate
Теперь мы попали обратно в систему с дефолтными интерпретаторами.
Сохранение информации о зависимостях
Опция –no-site-packages отключает использование глобально-установленных пакетов, что может быть полезно (сейчас это дефолтное поведение virtualenv).
Хорошей идей будет сохранить информацию об установленных в окружении пакетов.
{code lang=”shell”]$ pip freeze > requirements.txt
После развертывание окружения в новой системе можно поднять все пакеты сразу.
```shell
$ pip install -r requirements.txt
Не забываем добавить папку окружения в .gitignore.
virtualenverapper
Еще один полезный инструмент (скорее для разработчиков, а не для деплоя), который позволяет обращаться со со множеством окружений и переключаться между ними.
$ sudo yum install python-virtualenvwrapper
Применение
Добавляем в .bashrc
export WORKON_HOME=~/.envs
source /usr/bin/virtualenvwrapper.sh
Теперь можно создавать окружения.
$ mkvirtualenv proj_env
Активировать окружения.
$ workon proj_env
Выходить из окружения можно так же как это делалось в кготом virtualenv.
$ deactivate
Удалять окружения.
$ rmvirtualenv proj_env
При этом все папки окружений будет расположены в одном месте: папке, которая задана через $WORKON_HOME.
Дополнительные команды
Есть несколько дополнительных команд
- lsvirtualenv - покажет список созданных окружений
- cdvirtualenv - перейдет непосрественно в папку окружения
- cdsitepackages - переведет в site-packages выбранного окруженияч
- lssitepackages - сделает ls для папки site-packages
Посмотреть полный список команд.
autoenv
Утилита позволяет активировать окружение при входе в папку, и деактивировать при выходе.
$ git clone git://github.com/kennethreitz/autoenv.git ~/.autoenv
$ echo 'source ~/.autoenv/activate.sh' >> ~/.bashrc
Tmux - лучшая альтернатива screen
Довольно долго пытался пересесть с GNU Screen на tmux, но вот только сдерживало несколько вещей в нем.
На сайте проекта можно найти описание всех фич, я же опишу лишь те, которые для меня оказались самыми полезными.
- Улучшенная модель отрисовки (да-да screen периодически подключивал)
- Содержимое терминала не теряется, когда мып ользуемся редакторами (открыли vim, закрыли, история осталась а месте и можно прокрутить до нее)
- Конфигурирование на лету
C-b
Ага. Это сочетание клавишь из vim.
Переключим tmux на работу с C-a
set-option -g prefix C-a
Задержка между контрольными клавишами C-b и непосредственным вводом команды (например n).
Решается просто
set -s escape-time 0
Сочетание клавиш для управления tmux внутри tmux
Бывает такое, что приходится внутри tmux запустить вложенную сессию tmux. Значит надо как-то пробросить этой вложенной сессии команды. Например C-a a command
bind-key a send-prefix
Начинаме считать окна с 1, а не 0
Это удобно, так как 0 находится где-то на отшибе. И к нему надо тянуться.
set -g base-index 1
Агрессивный ресайз терминалов
Дефолтно при подключении к сессии нескольких клиентов рамер окна выбирается по размеру самого маленького клиента. Это неинтересно. Поэтому позволим терминалу для каждого клиента иметь собственный размер.
setw -g aggressive-resize on
После завершения команды можно ввести другую команду не нажимая C-b
Для меня эта проблема была самой неприятно. Воспроизвести ее просто: нужно на готом tmux создать два региона.
C-b "
А затем переключаться между ними.
C-b Up Down Up Down
Вы заметите, что нажав один раз C-b, а потом быстро нажимая вверх-вниз окна переключаются.
Это неприятно когда пытаешься переключить вкладку и начать тут же вводить что-то.
За такое поведение отвечает repeat-time
repeat-time time
Allow multiple commands to be entered without pressing
the prefix-key again in the specified time milliseconds
(the default is 500). Whether a key repeats may be set
when it is bound using the -r flag to bind-key. Repeat
is enabled for the default keys bound to the resize-pane
command.
Можно отключить repeat для команд переключения между панелями и окнами просто переобъявив команду без флага -r. Например так:
bind-key Up select-pane -U
Но я же предпочитаю эту фичу отключить вовсе.
set-option -g repeat-time 0
Базовый ~/.tmux.conf
# C-b не подходит - так как используется в vim
set-option -g prefix C-a
bind-key C-a last-window
# Начинам нумерацию окон с 1
set -g base-index 1
# Добавляем отзывчивости в реакции на команды
set -s escape-time 0
# Отключаем ожидание дополнительных команд
set-option -g repeat-time 0
# Или можно забиндить команды отдельно отключая repeat только для нужных
#bind-key Up select-pane -U
# Цветовая схема
set -g status-bg black
set -g status-fg white
set -g status-left ""
set -g status-right "#[fg=green]#H"
# Ресайзим содержимое окна индивидуально для каждого клиента
setw -g aggressive-resize on
# Позволим пробрасывать команды внутрь вложенной сессии tmux
# при помощи C-a a <command>
bind-key a send-prefix
# Мониторинг активности
#setw -g monitor-activity on
#set -g visual-activity on
# Пример использования команды оболочки в статусной строке
#set -g status-right "#[fg=yellow]#(uptime | cut -d ',' -f 2-)"
# Подсвечиваем активное окно
set-window-option -g window-status-current-bg green
За кадром осталось использование tmuxinator для запуска tmux c определенной заранее раскладкой окон.
Ну и еще про настройку можно почитать в Arch-wiki.
Python 3+ и окончания строк в файлах
Столкнулся одного теста, который был перенесен с python 2+ на python 3+.
Тест делал следующее:
скачивал файл через python.requests и сравнивал его с эталонным содержимым на диске (посимвольно).
Выглядело приблизительно так
import requests
import sys
response = requests.get(sys.argv[1])
if response.code == 200:
with open(sys.argv[2]) as f:
from_storage = f.read()
from_web = response.text
assert from_web == from_storage
Да. Все верно. Этот тест не проходил.
И тут была замечена одна странность: файл на диске содержал последовательность crlf, а в coдержимом from_storage этой последовательности не оказало.
А дело все в том, что в python 3+ было введено соглашение на обработку символов перевода строки. И управление работой осуществляется манипулированием параметром newline.
- On input, if newline is None, universal newlines mode is enabled. Lines in the input can end in
\n
,\r
, or\r\n
, and these are translated into\n
before being returned to the caller. If it is ‘’, universal newline mode is enabled, but line endings are returned to the caller untranslated. If it has any of the other legal values, input lines are only terminated by the given string, and the line ending is returned to the caller untranslated. - On output, if newline is None, any
\n
characters written are translated to the system default line separator, os.linesep. If newline is ‘’, no translation takes place. If newline is any of the other legal values, any ‘\n’ characters written are translated to the given string.
В итоге достаточно было указать newline=’’ как CRLF появились.
BeautifulSoup innerHTML
Функция в рамках браузеров по сей день остается недокументированной. А значит на стороне большинства парсеров она не реализована.
Но как быть если хочется?
def innerHTML(element):
return element.decode_contents(formatter="html")