понеділок, 1 лютого 2016 р.

Accessing MS Access from python with Cyrillic table names

My today's issue is quite interesting and is related to the data migration from MS Access to some regular (and more widely-used) database, i.e. MySQL. So we have as input a database, created in the MS Access 2000 (supposed) with the Cyrillic tables, that contains near 5k of sensible records. And expected result should be any DB that is supported by SQL Alchemy (right now it is MySQL, but I believe it will be easy to migrate to any other). And here is the most complex part: "How"?

Firstly I needed some way to provide ODBC  support for my Linux (Windows users/developers are more lucky at this point) as well as driver for access to MDB files. These packages provide such support for Debian:
  • unixodbc
  • odbcinst
  • libodbc1
  • libiodbc2
  • odbc-mdbtools
I got this list of packages from amirkdv, who implemented ODBC module for PHP. [Note: later I found a plenty of other docs about this subject, so I'm not good at Googl'ing at all]. Among other drivers there was also a web-page for unixodbc.org and Easysoft's page, who asked near 500 pounds for their library. Maybe it worth that money, but I need such access for one-time operation, so that's not my case right now.

So final command on my Debian system looked like:
$sudo apt-get install unixodbc odbcinst odbc-mdbtools

Files /etc/odbc.ini and /etc/odbcinst.ini were created after the installation and the latter one contained following lines:
Description=MDBTools Driver

It was enough for my case. The line "[MDBTools]" in the mentioned above file states for the name of the used driver, that should be indicated for granting access to the database.

At this point system's preparation is over, and it is a time, to look around about libraries that should provide access to the DB from the python. I discovered few of them:
  • pyodbc - outdated and I discovered this a bit later;
  • pypyodbc;
  • sqlalchemy-access - outdated as well.
Unfortunately, pyodbc failed to connect to the database, so I've been forced to use pypyodbc as the only possible way at that moment. Being inspired by usage examples for pypyodbc I finished with something like this: 

import pypyodbc
from os.path import abspath

drv ='MDBTools'
db_file = abspath('./pl.mdb') # Here "pl.mdb" is my input file
con = pypyodbc.connect("DRIVER={};DBQ={}".format(drv, db_file))
cur = con.cursor()

tables = list(cur.tables())

# Get list of tables from the file
for tbl in tables:
  print tbl

And got something like that:
('', '', '\xd0\x92\xd1\x83\xd0\xbb\xd0\xb8\xd1\x86\xd1\x96\xd0\x9b\xd1\x8c\xd0\xb2\xd0\xbe\xd0\xb2\xd0\xb0', 'TABLE', '')
('', '', '\xd0\x9d\xd0\xb0\xd1\x81\xd0\x9f\xd1\x83\xd0\xbd\xd0\xba\xd1\x82\xd0\xb8\xd0\x9b\xd0\x9e', 'TABLE', '')
('', '', '\xd0\xa2\xd0\xb8\xd0\xbf\xd1\x8b', 'TABLE', '')
('', '', '\xd0\xa2\xd0\xbe\xd0\xb2\xd0\xb0\xd1\x80\xd1\x8b', 'TABLE', '')
('', '', '\xd0\xa4\xd1\x96\xd1\x80\xd0\xbc\xd0\xb8\xd0\x9f\xd0\xbe\xd1\x81\xd1\x82\xd0\xb0\xd1\x87\xd0\xb0\xd0\xbb\xd1\x8c\xd0\xbd\xd0\xb8\xd0\xba\xd0\xb8', 'TABLE', '')

Here I should shout "Hooray! I did it!", but unfortunately, there is no reason for joy. As you may notice, tables are named by Cyrillic names, so now I should deal with them in some way.
The only solution that came into my mind was to call SQL statement as Unicode string, with the table's name encoded as regular string, i.e.:

sql_statement = u'SELECT * FROM "\xd0\x92\xd1\x83\xd0\xbb\xd0\xb8\xd1\x86\xd1\x96\xd0\x9b\xd1\x8c\xd0\xb2\xd0\xbe\xd0\xb2\xd0\xb0"' 
res = cur.execute(sql_statement).fetchall()
for item in res:
  print item

So, I got a list of tuples like this one (stripped version), from which records can be converted into regular Unocode.
('\xd0\x94\xd0\xb7\xd0\xb8\xd0\xbd\xd0\xb4\xd1\x80\xd0\xb8 \xd0\x84.',)

The converted version of the records is:

Дзиндри Є.

And now it is a time for "Hooray!!!!"

неділя, 14 червня 2015 р.

Processing flashed messages for different POST requests.

While been working on my project, I want to provide user with feedback messages. This is important i.e. if user tries to do something that is prohibbited, or allowed, and must be confirmed with the appropriate message. Trying to keep everything as simple as possible, I'm using two decorators, one of which checks if user logged in and another checks is user can access given page. Thus my typical method looks like:
@can_access(roles=['administration', 'administrator'])
def method():

In future I'll try to re-map everything from DB, so it will be more dynamic and more complex, but now it is OK with me. The problem I got today is about accessing flashed messages from POST request, which have been set in can_access().
def can_access(roles=[]):
    def decorator(f):
        def check_access(*args, **kwargs):
            user_rec = db_session.query(User).\
                filter(User.username == session["username"].lower()).\
            my_role = db_session.query(Role).filter(Role.id == user_rec.role).\
            if my_role.name.lower() not in roles and my_role.name != 'global':
                logger.debug("Access not allowed for this role.")
                flash(errors.get("access_denied"), "error")
                return  redirect(request.headers.get("Referer", None) or url_for('central'))
            return f(*args, **kwargs)
        return check_access
    return decorator
So the general idea was to turn user back to the previous page OR central (if no previous page) if he doesn't have access to the requested page. While I accessed page using GET requests it seems like everything has been worked OK, but with the POST requests no error message has been displayed. Firstly I thought the problem is that flash() sends signal that lives till the end of the current request, so I decided to create some global variable in the session, that will contain such errors. Indeed it wasn't the case, so I stucked with the problem if I need to re-write each of my methods in order to process the newly-found error. That was not acceptable, so there should be another way. Checking log I figured out there is double call to the same page:
13 06 2015 09:30:25 DEBUG: <Role(id='3', name='administrator')>
13 06 2015 09:30:25 DEBUG: Access not allowed for this role.
13 06 2015 09:30:26 INFO: - - [13/Jun/2015 21:30:26] "POST /customers/delete/3 HTTP/1.1" 302 -
13 06 2015 09:30:26 DEBUG: Calling list_customers
13 06 2015 09:30:26 DEBUG: GET params: 'name': None , 'page': None, 'rps': None
13 06 2015 09:30:26 DEBUG: Retrieving customers
13 06 2015 09:30:26 INFO: - - [13/Jun/2015 21:30:26] "GET /customers/ HTTP/1.1" 200 -
13 06 2015 09:30:26 DEBUG: Calling list_customers
13 06 2015 09:30:26 DEBUG: GET params: 'name': None , 'page': None, 'rps': None
13 06 2015 09:30:26 DEBUG: Retrieving customers
13 06 2015 09:30:26 INFO: - - [13/Jun/2015 21:30:26] "GET /customers/ HTTP/1.1" 200 -

That was not I wanted to have, so another guess was I just pop-up messages on the first request, and on the second I get nothing. And I don't see changes, because there is no delay between these requests. Such idea is correct, because each template has get_flashed_messages() method to display errors. So next step was to figure out where such update happens. I believed this has some connection to my Javascript, so I decided to re-check application's logic. In case of GET request situation is quite simple:
  • user asks for some page with GET request;
  • if page is accessible, server renders it and send it back to the user;
  • if page is not accessible, then server redirects user to its previous or initial page;
  • on the previous or initial page server once again tests if user can login and if user can get access to the page;
  • because this page is accessible by user, it is generated and returned to the user;
  • browser displays data.
As for the POST requests, I use them for 2 different cases: to process forms and to process individual requests like activate/deactivate items, delete items etc. Form processing is similar to the GET requests, so the above case is valid here. But individual requests need another processing logic. These requests are generating by JavaScript code, that expects JSON string as response, and looks like:
result = {
        "performed": False,
        "msg": ""
where result["performed"] contains True if request has been completed by server correctly and request["msg"] contains any support message. There can be other fields as well, but these are mandatory, so tracking if request contains form or not, can be performed by testing "Content-Type" of HTTP header. So, decorator "can_access" needs following changes:
def can_access(roles=[]):
    def decorator(f):
        def check_access(*args, **kwargs):
            user_rec = db_session.query(User).\
                filter(User.username == session["username"].lower()).\
            my_role = db_session.query(Role).filter(Role.id == user_rec.role).\
            if my_role.name.lower() not in roles and my_role.name != 'global':
                logger.debug("Access not allowed for this role.")
                flash(errors.get("access_denied"), "error")
                if request.method == "POST" and \
                        "text/plain" in request.headers["Content-Type"]:
                    result = {
                        "performed": False,
                        "msg": errors.get("access_denied")
                    return jsonify(result)
                return  redirect(request.headers.get("Referer", None) or url_for('central'))
            return f(*args, **kwargs)
        return check_access
    return decorator
From this point GET and POST requests process flashed messages correctly. Any programming, architecture, pythonizing and other tips are welcomed. :)

середа, 22 квітня 2015 р.

Forcing MySQL schema to use UTF-8

Being enough lazy, I'd like to have a possibility to control my SQL schema (where I store all my data), under some parameters. The tutorial for Flask and SQLAlchemy says I must create schema and afterwards it can be managed by extensions. Meantime, one of the biggest problem until today was that received data didn't sorted correctly. I mean they really didn't sort correctly. Today I figured out, this has been caused by CHARACTER SET settings in my Database. I should mention, that SQL Alchemy performs on the fly transformation of received data from latin1 to utf8. So my initial idea was to understand how to avoid such behaviour, and (IMHO) this was the reason of improper sorting. So outside of the Python the data has been looked like:

mysql> SELECT id, name FROM divisions ORDER BY name;

| id | name                                                  |
|  4 | Clinic No.4                                           |
|  6 | Абсолютно нова клініка              |
|  5 | Нова клініка                                |
|  7 | Ще одна клініка                          |
|  1 | global                                                |

Well it is not the sorting I wanted, at least because "Clinic No.4" and "global" should be together, and sorting should ignore letter cases. For the last thing, there is a collate call, that should solve my problem. But it didn't (because of the encoding problem). So in order to get proper encoding there were some prosper ways:
  • edit MySQL config so it started to process data correctly (can be done on DB level);
  • force somehow data connection to process data on-the-fly (can be done on connection level);
  • trying to tell database how data should be stored, so I didn't think about them.
After some readings finally I figured out the correct way for forcing MySQL to process Unicode data correctly.

Firstly I should stress I use pymysql dialect for connection cause it is targets 100% compatibility. So, correct forcing connection to use Unicode on client side is to add "?charset=utf8" to the connection string. So our target will look like: mysql+pymysql://username:password@localhost/db_name?charset=utf8.

Secondly, we should set unicode conversion globally. For this add convertunicode=True and encoding=utf8 as params to sqlalchemy.createengine().

Thirdly we should create MySQL schema with the proper character set and collation. As my DB is entitled clinic, so SQL statement is:

Indeed, I decided to create default schema, by simple statement CREATE SCHEMA clinic; and tune it on initialization DB from the app, by running the following code:

from sqlalchemy import create_engine

engine = create_engine("mysql+pymysql://username:password@localhost/db_name?charset=utf8", encoding=utf8, convert_unicode=True)
SCHEMA = "db_name"

connection = engine.connect()
result = connection.execute("SHOW CREATE SCHEMA " + SCHEMA)
for key in result:
    import re
    charset_pattern = re.compile("DEFAULT CHARACTER SET (?P[A-Za-z0-9]*?) ", re.I)
    charset = re.search(charset_pattern, str(key))
    if charset and 'utf' not in charset.group("charset"):
        connection.execute("ALTER SCHEMA " + SCHEMA +
                           " DEFAULT CHARACTER SET 'utf8'"
                           " DEFAULT COLLATE 'utf8_unicode_ci'")

Here we check if our Schema encoding is UTF8, and set it to correct value if it is not.
And here are the results:

mysql> SELECT * FROM divisions ORDER BY name ASC;
| id | name                        | builtin |
|  5 | Booble                      |       0 |
|  6 | Bubble                      |       0 |
|  1 | global                      |       1 |
|  4 | Друга клініка               |       0 |
|  3 | Перша клініка               |       0 |
|  2 | Типова клініка              |       1 |
6 rows in set (0.00 sec)

mysql> SELECT * FROM divisions ORDER BY name DESC;
| id | name                        | builtin |
|  2 | Типова клініка              |       1 |
|  3 | Перша клініка               |       0 |
|  4 | Друга клініка               |       0 |
|  1 | global                      |       1 |
|  6 | Bubble                      |       0 |
|  5 | Booble                      |       0 |
6 rows in set (0.00 sec)

вівторок, 21 квітня 2015 р.

Intro to my pet project

They say, each old or new programmer must have its own pet project, where he can study some new tricks. After a year, I finally, decided to start my own project: tiny CMS for managing small-size clinic. Before that I tried myself with Java, C and C++. About a year and a half ago I decided to switch myself to Python so I finished some Python courses (indeed there were two of them: Google's Python Class and Introduction to Interactive Programming on Coursera), and now I'n trying to improve my skills in python using Flask micro-framework, MySQL and some other simple stuff for building web-pages in order to get more comfortable with these technologies.

I have to say, that indeed, I am "working" on this project near 4 monthes. And under "working" I mean it is not so regular as I'd like it to be, but I'm trying to work on it each day for 1-2 hours in order to make some progress.

So, what are the objectives for it?

  • Study more deeply Python
  • Study SQL, and related Python-library: SQL Alchemy.
  • Study new (at least for me) technologies like: HTML, CSS (incl. CSS3), JavaScript (Ajax), and jQuery
  • Study Web-oriented Python framework Flask and its extensions.
  • Study some version control system (currently it is git, but I also liked mercurial).

I have no scope to make any deep research in Web or Computer design, and I believe that good design can be made by good designer, but as the present stage it is not so important. Right now I'm re-writing my present code (that I store in private archive at bitbucket) in order to allow people to use it from different places.

In this blog under the category "Pet Project", I'm going to leave some notes that may be usefull for other people, and also describe my own experience until this project will be released.


вівторок, 4 листопада 2014 р.

«О донецком "быдле"», «Ватники, чо»

Під таким заголовком сьогодні розноситься по соц.мережах інформація, яка супроводжується наступним малюнком і багатозначним «ню-ню, біндеровци»…

Після невеличкого оправдання, зразу ж карта міняється на:

Ну, вам все зрозуміло? Мені - ні. Слава Богу, що в тому ж дописі ми знаходимо інформацію про те, звідки взялися дані. А саме дані про населення: http://ukrstat.gov.ua/operativ/operativ2012/ds/kn/kn_r/kn1212_r.html і дані про кількість публікацій: http://ukrstat.gov.ua/druk/publicat/kat_u/2014/zb/09/zb_nayk_13.zip

Побіжний перелік і аналіз даних, які подані у дописі співпадає по наведених коефіцієнтах. Однак, мою увагу привернуло дещо інше, а саме перелік публікацій. Отже, якщо вірити цим даним, то в Тернопільській області за 2012 рік було опубліковано 182 наукові праці. А у Донецькій - 4035. Люди, які хоч трошки знайомі з нашою системою освіти запідозрять щось не ладне, адже наприклад аспірант передостаннього і останнього навчального років повинні включити у свій річний план щонайменше одну публікацію. Насправді аспірант мав би щороку публікувати принаймні одну статтю. Тобто, на основі цих даних виходить, що у прогресивній Донецькій області є аж чотири тисячі тридцять п’ять аспірантів? На 31 вуз? тобто 130 аспірантів на кожен вуз? Малувато буде… Ну, Бог з ним.

Повертаємось до публікацій. Отже, статистику (яка є неповною і неточною) можна взяти отут, відкрити на 134 сторінці і побачити, що усього в Україні за 2012 рік опубліковано 374.897 наукових праць, а за 2013 - 391.398. Так вже веселіше. Тим не менше, спробуємо побудувати реальну картину співвідношення кількості наукових праць на десять тисяч населення. По-перше, задля цікавості, а по-друге, щоб подивитися не тільки хто як і кого кормить™, але і хто і як публікується.
Важливим фактором є також кількість населення, яка проживає у даному регіоні. Для того, щоб бути геть дотошним, то дані ми візьмемо з статистичного збірника «Чисельність наявного населення України», що його опублікував Деркомстат. От тільки, на відміну від опонентів рахувати населення ми будемо відповідно станом на 1 січня 2013 року і 1 січня 2014 року, оскільки рахувати станом на 1 грудня є некоректно, оскільки упускаємо один додатковий місяць. Отже, дані за 2012 рік:
Кількість друкованих працьНаселення
Кількість друкованих праць
на 10 тис. чол.
(менше - краще)
Вінницька80001627038 49,1718
Волинська66851039958 64,289
Дніпропетровська260093307795 78,636
Донецька257614375442 58,8813
Житомирська36141268903 28,4824
Закарпатська29331254393 23,3825
Запорізька101661785243 56,9414
Івано-Франківська72031381788 52,1215
Київська (без м. Київ)19491722052 11,3127
Кіровоградська2238995171 22,4926
Луганська133972256551 59,3712
Львівська231892540702 91,273
Миколаївська55791173481 47,5420
Одеська144992395160 60,5311
Полтавська91511467821 62,3410
Рівненська36231156868 31,3223
Сумська91041143249 79,635
Тернопільська84301077327 78,247
Харківська528462744419 192,562
Херсонська38451078232 35,6622
Хмельницька52511313964 39,9621
Черкаська64521268888 50,8416
Чернівецька7891907163 86,974
Чернігівська53301077802 49,4517
АР Крим (без Севастополя)96561965177 49,1719
м. Київ995292845023 349,841
м. Севастополь2567383437 66,958
Україна37489745553047 82,30
Дані за 2013 рік:
Кількість друкованих працьНаселення
Кількість друкованих праць
на 10 тис. чол.
(менше - краще)
Вінницька81661618262 50,4618
Волинська52861041303 50,7616
Дніпропетровська255353292431 77,567
Донецька272874343882 62,8210
Житомирська33481262512 26,5224
Закарпатська24811256850 19,7426
Запорізька79721775833 44,8920
Івано-Франківська81921382096 59,2712
Київська (без м. Київ)25901725478 15,0127
Кіровоградська3249987565 32,9023
Луганська140022239473 62,5211
Львівська247032538436 97,323
Миколаївська68771168372 58,8613
Одеська177702396493 74,158
Полтавська115921458205 79,506
Рівненська40341158851 34,8121
Сумська92491132957 81,635
Тернопільська74601073327 69,509
Харківська573802737242 209,632
Херсонська28361072567 26,4425
Хмельницька43081306992 32,9622
Черкаська66861259957 53,0715
Чернівецька8152908508 89,734
Чернігівська51001066826 47,8119
АР Крим (без Севастополя)99791967259 50,4617
м. Київ1050492868702 366,191
м. Севастополь2115385870 54,8114
Україна39139845426249 86,16

І щоб все сприймалося значно легше - та ж сама інформація але у вигляді контурних карт:
Тому прихильників правильної статистики чекає невеличке розчарування (не дотягнули до Тернополя у Донецьку, а шо ж робить…), а решті панства нагадую, що статистика - це ще один з видів брехні. Справедливості заради, мушу зазначити, що дані, які наведено у опонентів, насправді зазначено у тому ж таки збірнику Держкомстату, однак це інші дані. З області, яка є дуже заполітизованою. Що це таке - самостійна робота.
Наразі у мене все. Критика (конструктивна) вітається.

середа, 29 жовтня 2014 р.

Limiting chrome's memory usage per tab

Last two weeks I observed that one of my favorite games - eRepublik, uses abnormally huge amount of memory if you leave chrome for few hours opened. Finally page becomes unrespondable, and you may observe a usage per page near 1-2Gbs of memory. In the example below, my chrome decided to occupy a bit smaller amount of RAM just in 15 minues of site browsing.
Top of my chrome's task manager with "memory leak" 
Indeed, such situation didn't make happy neither me nor other people around the world. Some of them suggested, they would like to have a possibility to limit chrome's memory usage. Indeed, the reason for such strange behaviour is caused by design in chrome, that keeps in memory major part of elements for given tab, until you change website. I perfectly understand Googlers' desire to make everything "smoothing" and fast, but indeed present situation looks quite dangerous for some people, that use webpages as their workplace, or if they need to update pages time to time.
Most of the existing solution you may find on the web, provide you with a possibility to limit overall chrome's memory usage by suspending tabs, by "parking" them etc. Yes, in general cases, it helps, cause chrome uses separate process for each tab, so limiting amount of tabs improves overall picture. But in case when one web-page uses extra-and-extra-and-extra memory this is not the solution. Indeed this is not the solution if you need to work with the site, and you don't intend to check old info, but your main purpose is to grab new one. Perfect solution for such situation was if chrome tried to limit its internal memory per page, let's say by 2 or 3 last complete snapshots, but until this, the only possible way is either to close tab with extended memory usage and open new one, or kill it from Chrome's task manager.
The only solution, that solves this problem in the way, described above is python solution at superuser.com. It is a bit old, so I modified it in order to work with python 2.7.8 (that is default on my system) and psutils 2.1.1 (they don't include into python distro, so you should get them by yourself).
It's main feature is it kills ANY tab that overcomes 800 Mb of real memory. You can put your own value if this one is too small for you.
The main disadvantage is it really kills really ANY tab, and some times it kills other tabs assigned with the renderer. So you will loose all your input forms. Therefore I recommend use this script just if you really need such feature. Otherwise, write to Google HQ and ask them to add this feature to browser.
Source code for solution at github.

середа, 1 жовтня 2014 р.

Αποτελέσματα της ημέρας από 30 Σεπτεμβρίου 2014

Αδερφοί και αδερφές, διαβάστε τα αποτελέσματα από 30 Σεπτεμβρίου.


Τα κακά νέα:

1. Τις 30 Σεπτεμβρίου, ακριβώς πριν 11 χρόνια, η Ρωσία προσπάθησε να κλεφτεί ένα μέρος της Ουκρανίας, και άρχισε να κατασκευάζει το πρόχωμα από δικό της Κρασνοντάρσιι κράι προς το Ουκρανικό νησί Τούζλα. Ο σκοπός της ήταν να «προσαρτά» το νησί στην Ρωσία. Αφού πριν 1925 η Τούζλα ήταν ένα μέρος της χερσόνησο Ταμάνσκιι, και έγινε το νησί μετά από την μεγάλη φουρτούνα. Δηλαδή βάλτε πίσω.

Εκείνη τη φορά λύσαμε το πρόβλημα χωρίς οπλισμένη σύγκρουση. Αλλά η λογική της διαδικασία είναι η εξής: άμα ένα κράτος άνοιξε το στόμα του για να πάρει το έδαφος του αλλού κράτος - τότε δεν θα το κλείνει μέχρι να το χτυπήσουν στο στόμα του. Ακριβώς αυτό είδαμε σήμερα.

Το τεράστιος λάθος είναι να μην διαβάζεις από τα μαθήματα της ιστορίας. Με ο,τι και θα τελειώσουμε την σημερινή εποποιία με την Ρώσικη εισβολή - εμείς πρέπει να το θυμηθούμε κάθε στιγμή. Τρομερή οικονομική κατάσταση, κοινωνικά προβλήματα κ.τ.λ. δεν μπορούν να είναι εξηγήσεις για να αφήσουμε το στρατό μας στο τέλος. Αλλιώς θα έχουμε κλεμμένη Κριμαία και το φλεγόμενο Ντονπάς.

2. Η Ρωσία συνεχίζει να φέρει τους στρατούς της στο σύνορο με την Ουκρανία. Τώρα εκεί βρίσκονται καινούργιες ομάδες για σαμποτάζ και ανίχνευση των Ρώσικων ιδιαίτερων δυνάμεων, οι οποίες αύριο μάλλον θα είναι στο έδαφος της Ουκρανίας.

Σήμερα εμείς πήραμε στοιχεία ότι φέρανε προς το σύνορο καινούργιες Ρώσικες πυραυλικές εγκαταστάσεις. Για την πρώτη φορά οι πηγές μας μας είπανε ότι αυτές είναι επιχειρησιακές και τακτικές πυραυλικές εγκαταστάσεις. Μετά από το έλεγχος ανακαλύψαμε ότι οι Ρώσοι φέρανε στο σύνορο την μπαταρία τακτικών εγκαταστάσεων «Τότσκα-Ου».

Μάλιστα. Από εκείνες τις θέσεις των, που βρίσκονται κοντά το τόπο Πετρόφκα, περιφέρεια του Ροστόφ, οι Ρώσικοι στρατοί μπορούν να πυροβολούν μόνο στους σκοπούς που είναι στο έδαφος το οποίο ελέγχουν οι μαχητές. Αυτό σημαίνει ότι οι Ρώσοι θα συνεχίσουν να καταστρέφουν τα σπίτια αμάχητων κάτοικων του Ντονμπάς, και ταυτόχρονα θα φωνάζει ότι όλα απ' αυτά είναι «εγκλήματα των Ουκρανικών στρατιωτών».


Τα καλά νέα:

1. Στο Σλοβιάνσκ οι τοπικές εθελοντές μπλοκάρανε την δημαρχία διαμαρτυρόμενος εναντίων του διορισμού του κ. Β. Ράνττσενκο και του βουλευτή από το κόμμα Περιοχών του κ. Β. Λγιαχ ως αναπληρωτές του δήμαρχου. Οι μαχητές από το εθελοντικό τάγμα «Σίτς» στήριξε τους εθελοντές.

Να σας πω, είναι ο ίδιος Ράνττσενκο ο οποίος ήταν αρχηγό αστυνομίας στην Κριμαία στο καιρό του τέλος αυτοκρατορίας του Γιανουκόβιτς. Εκείνος με την τύχη έδωσε την Ρώσικη αστυνομία στους Ρώσικους κατακτητές του Μαρτίου, και μετά έτρεξε στην πατρίδα του - στο Σλοβιάνσκ, για να βλάπτει την Ουκρανία από της θέση του αναπληρωτή του δήμαρχου. Θαυμαστικά, τι άλλο να πω.

Εκείνα τα γεγονότα έγιναν αμέσως μετά από την δημοσίευση του δελτίου της ομάδας «Πληροφοριακή Αντίδραση» σχετικά τις «απελευθερωμένες περιοχές», όπου εμείς δείξαμε για την πραγματική απειλή «γυρισμού» παλιών δημόσιων στις θέσεις τοπικού επίπεδου. Αλλά άμα οι τοπικές πατριώτες θα αντιδρούν σε εκείνη τη απειλή - τότε δεν χάσαμε όλα.

Επίσης, μόλις εγώ έμαθα για τα γεγονότα στην πόλη, τότε πήρα τηλέφωνο στους εθελοντές του Σλοβιάνσκ. Και εκείνοι λένε: ο Ράνττσενκο και ο Λγιαχ είναι μόνο κορυφή του παγόβουνου, και εκείνος ο βάλτος χρειάζεται καλή καθαρισμό. Επίσης ο ίδιοι ομολογούν ότι χωρίς την στήριξη του τάγματος «Σιτς» θα είχανε πολλά προβλήματα - οι τοπικές αστυνόμοι θα σκοτώσουν καθένα για το χατίρι του Ράνττσενκο. Παιδιά κρατηθείτε, το δικό σας μέτωπο είναι τόσο σημαντικό όσο και η πρώτη γραμμή. Με την τύχη!

Επίσης έχω ερώτηση στην εξουσία: μήπως πρέπει να περιμένουμε το γυρισμό του Γιανουκόβιτς στην θέση του πρόεδρου, ή μήπως κάποιος «πάνω» τελικά θα αρχίσει να αντιδράει στην «ανάσταση» των τσιρακιών της προηγούμενης εξουσίας;

2. Η Εθνική Φρουρά πήρε 100 μονάδες καινούργιων μέσων, και σε λίγο θεωρούν να αγοράσουν έκτακτα 500. Μεταξύ των μέσων - φορτηγά, θωρακισμένα αυτοκίνητα «Κουγουάρ» και «Σπαρτάκ», θωρακισμένα ΚρΑΖ. Επίσης η κυβέρνηση υποσχέθηκε, ότι θα εφοδιάσουν τους στρατιώτες της Εθνικής Φρουράς με χειμερινά ρούχα μέχρι τις 10 Οκτωβρίου.

Ουδέν σχόλιο όσων σχετικά τα μέσα - τα λείπεις στους στρατιώτες μας από την πρώτη ημέρα σύγκρουσης, για αυτό 100 μονάδες - είναι επιτυχία. Όσων για την προετοιμασία στο χειμόνα, ακόμα είναι νωρίς να χαιρόμαστε. Πριν απ' αυτό και Υπουργείο Άμυνας υποσχέθηκε ότι θα ετοιμαστεί το στρατό μας για το χειμώνα πριν 10 Οκτωβρίου. Και σύμφωνα με τα στοιχεία μας, δεν είμαστε σίγουρη ότι αυτό είναι πραγματοποιήσιμο.

Τέλος πάντων, θα το δούμε. Και άμα θα ανατρέπουν την προετοιμασία για το χειμώνα - τότε όλες οι συζητήσεις του στρατιωτικής-πολιτικής και στρατιωτικής διοίκησης σε τις οποίες λένε για θετικές αλλαγές στο Υπουργείο Άμυνας δεν αξίζουν τίποτα. Αυτό θα σημαίνει ότι κανένας ούτε δεν προσπάθησε να καθαρίσει το κόπρος του Αυγεία.

3. Η Κοινοβουλευτική Συνέλευση του Συμβουλίου της Ευρώπης (ΚΣΣΕ) με περισσότερους ψήφους απόρριψε την πρόταση της Ρωσίας για την απόφαση της ΚΣΣΕ, σε την οποία έπρεπε να τονίζει «την δραστηριοποίηση του ναζισμού» στην Ουκρανία.

Δηλαδή, η ΚΣΣΕ έστειλε την Ρώσικη βουλευτή την κ. Ο. Καζακόβα στην γνωστή διεύθυνση, η οποία ζήτησε επίμονα να εκφράζουν «την ανησυχία σχετικά την δραστηριοποίηση της στήριξης των ναζιστικών οργανισμών» στην Ουκρανία. Στην Ευρώπη δεν κατάλαβαν της προσπάθειες της ρήτορα από το ναζιστικό κράτος, απεσταλμένου του σωσία του Χίτλερ ο οποίος έχει επώνυμο Πούτιν, για να φταίει στο «ναζισμό» την θυσία εισβολής του Πούτιν την Ουκρανία.


Το πρωτότυπο