Sfoglia il codice sorgente

it_vacancies32_bot целиком, возьмем за основу

Pavel Yakushenko 3 anni fa
parent
commit
c456e35781
18 ha cambiato i file con 2349 aggiunte e 0 eliminazioni
  1. 1 0
      .htaccess
  2. 205 0
      best_read.wsgi
  3. 209 0
      best_vacancies.wsgi
  4. 286 0
      habr.html
  5. 74 0
      habr_log.wsgi
  6. 182 0
      habr_parser.wsgi
  7. 80 0
      hh_install.wsgi
  8. 117 0
      hh_log.wsgi
  9. 268 0
      hh_parser.wsgi
  10. BIN
      hhtm.db
  11. 105 0
      last_action.wsgi
  12. 145 0
      last_read.wsgi
  13. 167 0
      last_vacancies.wsgi
  14. 140 0
      next_read.wsgi
  15. 151 0
      next_vacancies.wsgi
  16. 32 0
      response.html
  17. 32 0
      response_1.html
  18. 155 0
      tm_bot.wsgi

+ 1 - 0
.htaccess

@@ -0,0 +1 @@
+AddHandler wsgi-script .wsgi

+ 205 - 0
best_read.wsgi

@@ -0,0 +1,205 @@
+# -*- encoding: utf-8 -*-
+# 
+import os, json, sys, subprocess, urllib.parse, traceback
+import random, time, datetime, re
+from urllib.parse import unquote
+
+virtual_env = os.path.expanduser('~/projects/world-it-planet/env')
+activate_this = os.path.join(virtual_env, 'bin/activate_this.py')
+exec(open(activate_this).read(), dict(__file__=activate_this))
+
+import requests
+#MySql
+from mysql.connector import connect, Error
+
+#декларативное определение SQLLite
+from sqlalchemy import Column, Integer, String, Text, create_engine
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import sessionmaker
+from sqlalchemy import desc
+
+
+#---------------------------------- Variables ----------
+
+
+
+
+#---------------------------------- Variables End ----------
+
+
+
+
+
+def application(env, start_response):
+    out_s = {}
+
+    """
+    for key in env:
+        out_s = out_s + str(key) + "=" + str(env[key]) + "<br>"
+    """
+    #получаем $_GET из запроса
+    get_query = env['QUERY_STRING']
+    get_json = get_query.replace("q=", "")
+    get_json = unquote(get_json)
+
+    get_dict = json.loads(get_json)
+    tm_id = str(get_dict['tm_id'])
+    vk_id = str(get_dict['vk_id'])
+    out_s["tm_id"] = tm_id
+    
+    #Инициализация MySQL
+    mysql_connection = connect(
+            host="localhost",
+            user="id35114350",
+            password="Hgatrdy5rTeq",
+            database="id35114350_steelfeet",
+            charset='utf8',
+            use_unicode=True            
+        )
+
+    #Инициализация SQLLite
+    basedir = os.path.abspath(os.path.dirname(__file__))
+    SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'habr.db')
+    engine = create_engine(SQLALCHEMY_DATABASE_URI, pool_pre_ping=True)
+
+    Base = declarative_base()
+    class Links(Base):
+        __tablename__ = 'links'
+        id = Column(Integer, primary_key=True, autoincrement=True)
+        title = Column(String(512))
+        href = Column(String(512))
+        donor = Column(String(255))
+        donor_link_id = Column(Integer) #внутренний идентификатор для донора, https://habr.com/ru/company/skillfactory/blog/578014/ -> 578014
+        parse_date = Column(Integer)
+        text = Column(Text)
+
+        def __init__(self, title, href, donor, donor_link_id, parse_date, text):
+            self.title = title
+            self.href = href
+            self.donor = donor
+            self.donor_link_id = donor_link_id
+            self.parse_date = parse_date
+            self.text = text
+
+        def __repr__(self):
+            return "<Link('%s', '%s')>" % (self.title, self.href)
+
+    Session = sessionmaker(bind=engine)
+    sqllite_session = Session()
+
+    #------------------------------------------ Основной цикл ------------------
+
+    #запрос wp_id по внешнему сервису
+    params = {
+        "action":"show_wp_id",
+        "tm_id":tm_id
+    }
+    params_json = json.dumps(params)
+    get_wp_url = "https://steelfeet.ru/app/get.php?q=" + params_json
+    out_s["get_wp_url"] = get_wp_url
+
+    response = requests.get(get_wp_url)
+    wp_id = int(response.text)
+    out_s["wp_id"] = wp_id
+
+    now = datetime.datetime.now()
+    #links = sqllite_session.query(Links).order_by(desc(Links.parse_date))[0:5]
+    #отбираем показанные вакансии (скорее, помеченные как прочитанные)
+    showed_read_query = "SELECT `data_1`, `data_3`, `weight` FROM `sf_log` WHERE (`code` = 'read') AND (`action` = 'show_next') AND (`user_id` = " + str(wp_id) + ");"
+    #out_s["showed_vacancies_query"] = showed_vacancies_query
+    with mysql_connection.cursor(buffered=True) as cursor:
+        cursor.execute(showed_read_query)
+        showed_read = cursor.fetchall()
+
+    showed_read_ids = []
+    for item in showed_read:
+        item_id, item_data_3, item_weight = item
+        
+        showed_read_ids.append(item_id)
+
+    out_s["showed_read_ids"] = showed_read_ids
+
+
+    #считаем статистику слов
+    #отбираем все уже показанные ссылки
+    all_read_query = "SELECT `data_1`, `data_3`, `weight` FROM `sf_log` WHERE (`code` = 'read') AND (`user_id` = " + str(wp_id) + ");"
+    with mysql_connection.cursor(buffered=True) as cursor:
+        cursor.execute(all_read_query)
+        all_read = cursor.fetchall()
+
+    words_stat = {}
+    for item in all_read:
+        item_id, item_data_3, item_weight = item
+        
+        words = str(item_data_3).replace('-',' ').replace('/',' ').replace('\\',' ').replace('(','').replace(')','').split(" ")
+        for word in words:
+            try:
+                if (len(word) > 0):
+                    words_stat[word] = words_stat[word] + item_weight
+            except:
+                words_stat[word] = item_weight
+        out_s["words"] = words_stat
+    
+    #считаем веса для непоказанных вакансий
+    reads = sqllite_session.query(Links).order_by(desc(Links.parse_date))[0:500]
+   
+    reads_list = []
+    for item in reads:
+        #непоказанные
+        if (not(item.id in showed_read_ids)):
+            words = str(item.title).replace('-',' ').replace('/',' ').replace('\\',' ').replace('(','').replace(')','').split(" ")
+            read_weight = 0
+            for word in words:
+                try:
+                    if (len(word) > 0):
+                        read_weight = read_weight + words_stat[word]
+                except:
+                    pass
+        
+            read_item = {
+                "id" : item.id,
+                "weight" : read_weight,
+                "title" : str(item.title),
+                "href" : item.href,
+            }
+            reads_list.append(read_item)
+
+    #сортируем по весу
+    reads_list = sorted(reads_list, key=lambda x: x["weight"], reverse=True)
+    #выводим лучшие 5
+    reads_list = reads_list[0:5]
+
+
+    for item in reads_list:
+        #добавляем показанные вакансии в лог
+        #INSERT INTO `sf_log` (`user_id`, `date`, `hour`, `action`, `data_1`, `data_2`, `data_3`, `data_4`, `data`, `weight`) VALUES ('', '', '', '', '', '', '', '', '', '');
+
+        exist_vacancies_query = "SELECT `id` FROM `sf_log` WHERE (`code` = 'read') AND (`data_1` = " + str(item["id"]) + ");"
+        with mysql_connection.cursor(buffered=True) as cursor:
+            cursor.execute(exist_vacancies_query)
+            exist_vacancies = cursor.fetchall()
+
+        mysql_query = ""
+        if (len(exist_vacancies) == 0):
+            mysql_query = "INSERT INTO `sf_log` (`user_id`, `date`, `hour`, `code`, `action`, `data_1`, `data_2`, `data_3`, `data_4`, `data`, `weight`) VALUES ('" + str(wp_id) + "', '" + str(int(time.time())) + "', '" + str(now.hour) + "', 'read', 'show_best', '" + str(item["id"]) + "', '', '" + str(item["title"]) + "', '', 'data_1=>read_id, data_3=>read_title', 0);"
+        
+            with mysql_connection.cursor() as cursor:
+                cursor.execute(mysql_query)
+
+        mysql_connection.commit()
+
+
+    out_s["reads"] = reads_list
+
+
+
+
+
+
+
+    start_response('200 OK', [('Content-Type','text/html')])
+    out_s = json.dumps(out_s)
+    b = out_s.encode('utf-8')
+    return [b]
+
+

+ 209 - 0
best_vacancies.wsgi

@@ -0,0 +1,209 @@
+# -*- encoding: utf-8 -*-
+# 
+import os, json, sys, subprocess, urllib.parse, traceback
+import random, time, datetime, re
+from urllib.parse import unquote
+
+virtual_env = os.path.expanduser('~/projects/world-it-planet/env')
+activate_this = os.path.join(virtual_env, 'bin/activate_this.py')
+exec(open(activate_this).read(), dict(__file__=activate_this))
+
+import requests
+#MySql
+from mysql.connector import connect, Error
+
+#декларативное определение SQLLite
+from sqlalchemy import Column, Integer, String, create_engine
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import sessionmaker
+from sqlalchemy import desc
+
+
+#---------------------------------- Variables ----------
+
+
+
+
+#---------------------------------- Variables End ----------
+
+
+
+
+
+def application(env, start_response):
+    out_s = {}
+
+    """
+    for key in env:
+        out_s = out_s + str(key) + "=" + str(env[key]) + "<br>"
+    """
+    #получаем $_GET из запроса
+    get_query = env['QUERY_STRING']
+    get_json = get_query.replace("q=", "")
+    get_json = unquote(get_json)
+
+    get_dict = json.loads(get_json)
+    tm_id = str(get_dict['tm_id'])
+    out_s["tm_id"] = tm_id
+    
+    #Инициализация MySQL
+    mysql_connection = connect(
+            host="localhost",
+            user="id35114350",
+            password="Hgatrdy5rTeq",
+            database="id35114350_steelfeet",
+            charset='utf8',
+            use_unicode=True            
+        )
+
+    #Инициализация SQLLite
+    basedir = os.path.abspath(os.path.dirname(__file__))
+    SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'hhtm.db')
+    engine = create_engine(SQLALCHEMY_DATABASE_URI, pool_pre_ping=True)
+
+    Base = declarative_base()
+    class Vacancies(Base):
+        __tablename__ = 'vacancies'
+        id = Column(Integer, primary_key=True, autoincrement=True)
+        title = Column(String(512))
+        city = Column(String(20))
+        specialization = Column(String(255))
+        href = Column(String(512))
+        donor = Column(String(255))
+        vacancy_id = Column(Integer)
+        vacancy_date = Column(Integer)
+        parse_date = Column(Integer)
+        employer = Column(String(255))
+        canal_city_id = Column(Integer)
+        canal_city_date = Column(Integer)
+        canal_spec_id = Column(Integer)
+        canal_spec_date = Column(Integer)
+
+        def __init__(self, title, city, specialization, href, donor, vacancy_id, vacancy_date, parse_date, employer, canal_city_id, canal_city_date, canal_spec_id, canal_spec_date):
+            self.title = title
+            self.city = city
+            self.specialization = specialization
+            self.href = href
+            self.donor = donor
+            self.vacancy_id = vacancy_id
+            self.vacancy_date = vacancy_date
+            self.parse_date = parse_date
+            self.employer = employer
+            self.canal_city_id = canal_city_id
+            self.canal_city_date = canal_city_date
+            self.canal_spec_id = canal_spec_id
+            self.canal_spec_date = canal_spec_date
+
+        def __repr__(self):
+            return "<Vacancy('%s','%s', '%s')>" % (self.title, self.specialization, self.href)
+
+    Session = sessionmaker(bind=engine)
+    sqllite_session = Session()
+
+    #------------------------------------------ Основной цикл ------------------
+
+    #запрос wp_id по внешнему сервису
+    params = {
+        "action":"show_wp_id",
+        "tm_id":tm_id
+    }
+    params_json = json.dumps(params)
+    get_wp_url = "https://steelfeet.ru/app/get.php?q=" + params_json
+    out_s["get_wp_url"] = get_wp_url
+
+    response = requests.get(get_wp_url)
+    wp_id = int(response.text)
+    out_s["wp_id"] = wp_id
+
+    now = datetime.datetime.now()
+    #просто последние пять спарсенных
+    #vacancies = sqllite_session.query(Vacancies).order_by(desc(Vacancies.parse_date))[0:5]
+
+    #отбираем показанные вакансии
+    showed_vacancies_query = "SELECT `data_1`, `data_3`, `weight` FROM `sf_log` WHERE (`code` = 'vacancy') AND (`action` = 'show_next') AND (`user_id` = " + str(wp_id) + ");"
+    #out_s["showed_vacancies_query"] = showed_vacancies_query
+    with mysql_connection.cursor(buffered=True) as cursor:
+        cursor.execute(showed_vacancies_query)
+        showed_vacancies = cursor.fetchall()
+
+    showed_vacancies_ids = []
+    for item in showed_vacancies:
+        item_id, item_data_3, item_weight = item
+        showed_vacancies_ids.append(item_id)
+
+
+    #считаем статистику слов
+    #отбираем все вакансии
+    all_vacancies_query = "SELECT `data_1`, `data_3`, `weight` FROM `sf_log` WHERE (`code` = 'vacancy') AND (`user_id` = " + str(wp_id) + ");"
+    with mysql_connection.cursor(buffered=True) as cursor:
+        cursor.execute(all_vacancies_query)
+        all_vacancies = cursor.fetchall()
+
+    words_stat = {}
+    for item in all_vacancies:
+        item_id, item_data_3, item_weight = item
+        
+        words = str(item_data_3).replace('-',' ').replace('/',' ').replace('\\',' ').replace('(','').replace(')','').split(" ")
+        for word in words:
+            try:
+                if (len(word) > 0):
+                    words_stat[word] = words_stat[word] + item_weight
+            except:
+                words_stat[word] = item_weight
+        out_s["words"] = words_stat
+    
+    #считаем веса для непоказанных вакансий
+    vacancies = sqllite_session.query(Vacancies).order_by(desc(Vacancies.parse_date))[0:500]
+   
+    vacancies_list = []
+    for item in vacancies:
+        #непоказанные
+        if (not(item.id in showed_vacancies_ids)):
+            words = str(item.title).replace('-',' ').replace('/',' ').replace('\\',' ').replace('(','').replace(')','').split(" ")
+            vacancy_weight = 0
+            for word in words:
+                try:
+                    if (len(word) > 0):
+                        vacancy_weight = vacancy_weight + words_stat[word]
+                except:
+                    pass
+        
+            vacancy_item = {
+                "id" : item.id,
+                "weight" : vacancy_weight,
+                "title" : str(item.title),
+                "href" : item.href,
+            }
+            vacancies_list.append(vacancy_item)
+
+    #сортируем по весу
+    vacancies_list = sorted(vacancies_list, key=lambda x: x["weight"], reverse=True)
+    #выводим лучшие 5
+    vacancies_list = vacancies_list[0:5]
+
+
+    for item in vacancies_list:
+        #добавляем показанные вакансии в лог
+        #INSERT INTO `sf_log` (`user_id`, `date`, `hour`, `action`, `data_1`, `data_2`, `data_3`, `data_4`, `data`, `weight`) VALUES ('', '', '', '', '', '', '', '', '', '');
+
+        exist_vacancies_query = "SELECT `id` FROM `sf_log` WHERE (`code` = 'vacancy') AND (`data_1` = " + str(item["id"]) + ");"
+        with mysql_connection.cursor(buffered=True) as cursor:
+            cursor.execute(exist_vacancies_query)
+            exist_vacancies = cursor.fetchall()
+
+        if (len(exist_vacancies) == 0):
+            mysql_query = "INSERT INTO `sf_log` (`user_id`, `date`, `hour`, `code`, `action`, `data_1`, `data_2`, `data_3`, `data_4`, `data`, `weight`) VALUES ('" + str(wp_id) + "', '" + str(int(time.time())) + "', '" + str(now.hour) + "', 'vacancy', 'show_best', '" + str(item["id"]) + "', '', '" + str(item["title"]) + "', '', 'data_1=>vacancy_id, data_3=>vacancy_title', '');"
+        
+            with mysql_connection.cursor() as cursor:
+                cursor.execute(mysql_query)
+
+        mysql_connection.commit()
+
+
+    out_s["vacancies"] = vacancies_list
+    start_response('200 OK', [('Content-Type','text/html')])
+    out_s = json.dumps(out_s)
+    b = out_s.encode('utf-8')
+    return [b]
+
+

File diff suppressed because it is too large
+ 286 - 0
habr.html


+ 74 - 0
habr_log.wsgi

@@ -0,0 +1,74 @@
+# -*- encoding: utf-8 -*-
+# 
+import os, urllib.parse, traceback
+
+virtual_env = os.path.expanduser('~/projects/world-it-planet/env')
+activate_this = os.path.join(virtual_env, 'bin/activate_this.py')
+exec(open(activate_this).read(), dict(__file__=activate_this))
+
+
+import random, time
+from datetime import datetime
+
+#декларативное определение
+from sqlalchemy import Column, Integer, String, create_engine
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import sessionmaker
+from sqlalchemy import desc
+
+#---------------------------------- Variables ----------
+
+
+#---------------------------------- Variables End ----------
+
+
+def application(env, start_response):
+    out_s = ""
+    #Инициализация SQLLite
+    basedir = os.path.abspath(os.path.dirname(__file__))
+    SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'habr.db')
+    engine = create_engine(SQLALCHEMY_DATABASE_URI, pool_pre_ping=True)
+
+    
+    Base = declarative_base()
+    class Log(Base):
+        __tablename__ = 'log'
+        id = Column(Integer, primary_key=True, autoincrement=True)
+        action = Column(String(64))
+        status = Column(String(64))
+        time = Column(Integer)
+        donor = Column(String(64))
+
+        def __init__(self, action, status, time, donor):
+            self.action = action
+            self.status = status
+            self.time = time
+            self.donor = donor
+
+        def __repr__(self):
+            return "<Log('%s','%s', '%s')>" % (self.action, self.status)
+
+
+    # Создание таблицы
+    Base.metadata.create_all(engine)
+
+
+    Session = sessionmaker(bind=engine)
+    sqllite_session = Session()
+
+
+ 
+    out_s += "<table align=left cellspacing=8 cellpading=2 border=0><tr align=center><td>Date</td><td>Action</td><td>Status</td><td>Donor</td></tr>"
+    log = sqllite_session.query(Log).order_by(desc(Log.id))[0:50]
+    for item in log:
+        date_time = datetime.fromtimestamp(item.time)
+        s_date = date_time.strftime("%d %m %Y %H:%M:%S")
+        out_s += f"<tr align=center><td>{s_date}</td><td>{item.action}</td><td>{item.status}</td><td>{item.donor}</td></tr>"
+
+    out_s += "<br>"
+
+    start_response('200 OK', [('Content-Type','text/html')])
+    b = out_s.encode('utf-8')
+    return [b]
+
+

+ 182 - 0
habr_parser.wsgi

@@ -0,0 +1,182 @@
+# -*- encoding: utf-8 -*-
+# 
+import os, urllib.parse, traceback
+virtual_env = os.path.expanduser('~/projects/world-it-planet/env')
+activate_this = os.path.join(virtual_env, 'bin/activate_this.py')
+exec(open(activate_this).read(), dict(__file__=activate_this))
+
+
+from bs4 import BeautifulSoup
+import random, time, datetime
+import requests
+from requests.exceptions import ProxyError
+
+#декларативное определение
+from sqlalchemy import Column, Integer, String, Text, create_engine
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import sessionmaker
+
+#---------------------------------- Variables ----------
+
+user_agents = [
+    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:45.0) Gecko/20100101 Firefox/45.0",
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0",
+    "Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0",
+    "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.62 Safari/537.36",
+    "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)",
+    "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)",
+    "Mozilla/5.0 (Windows NT 6.1; rv:23.0) Gecko/20100101 Firefox/23.0",
+    "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.62 Safari/537.36",
+    "Opera/9.80 (Windows NT 5.1) Presto/2.12.388 Version/12.16",
+    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.62 Safari/537.36",
+    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 YaBrowser/1.7.1364.21027 Safari/537.22",
+    "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.16",
+    "Mozilla/5.0 (iPad; CPU OS 6_1_3 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10B329 Safari/8536.25",
+    "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.15",
+    "Mozilla / 5.0 (Macintosh; Intel Mac OS X 10.14; rv: 75.0) Gecko / 20100101 Firefox / 75.0",
+    "Mozilla / 5.0 (Windows NT 6.1; Win64; x64; rv: 74.0) Gecko / 20100101 Firefox / 74.0",
+    "Mozilla / 5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit / 537.36 (KHTML, как Gecko) Chrome / 80.0.3987.163 Safari / 537.36",
+    "Dalvik/2.1.0 (Linux; U; Android 10; Mi 9T MIUI/V12.0.5.0.QFJMIXM)"
+]
+
+
+#---------------------------------- Variables End ----------
+
+
+
+
+def application(env, start_response):
+    out_s = ""
+    #Инициализация SQLLite
+    basedir = os.path.abspath(os.path.dirname(__file__))
+    SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'habr.db')
+    engine = create_engine(SQLALCHEMY_DATABASE_URI, pool_pre_ping=True)
+
+
+    Base = declarative_base()
+    class Links(Base):
+        __tablename__ = 'links'
+        id = Column(Integer, primary_key=True, autoincrement=True)
+        title = Column(String(512))
+        href = Column(String(512))
+        donor = Column(String(255))
+        donor_link_id = Column(Integer) #внутренний идентификатор для донора, https://habr.com/ru/company/skillfactory/blog/578014/ -> 578014
+        parse_date = Column(Integer)
+        text = Column(Text)
+
+        def __init__(self, title, href, donor, donor_link_id, parse_date, text):
+            self.title = title
+            self.href = href
+            self.donor = donor
+            self.donor_link_id = donor_link_id
+            self.parse_date = parse_date
+            self.text = text
+
+        def __repr__(self):
+            return "<Link('%s', '%s')>" % (self.title, self.href)
+
+
+    class Log(Base):
+        __tablename__ = 'log'
+        id = Column(Integer, primary_key=True, autoincrement=True)
+        action = Column(String(64))
+        status = Column(String(64))
+        time = Column(Integer)
+        donor = Column(String(64))
+
+        def __init__(self, action, status, time, donor):
+            self.action = action
+            self.status = status
+            self.time = time
+            self.donor = donor
+
+        def __repr__(self):
+            return "<Log('%s','%s', '%s')>" % (self.action, self.status)
+
+    # Создание таблицы
+    Base.metadata.create_all(engine)
+
+
+    Session = sessionmaker(bind=engine)
+    sqllite_session = Session()
+
+
+    #"""
+    #формируем запрос
+    user_agent = random.choice(user_agents)
+    url = "https://habr.com/ru/all/"
+    referer = "https://habr.com/ru/all/"
+
+    headers = {
+            "Host": str("habr.com"),
+            'User-Agent': str(user_agent),
+            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
+            'Accept-Language': 'ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3',
+            'Accept-Encoding': 'gzip, deflate, br',
+            'Referer': str(referer),
+            'Upgrade-Insecure-Requests': '1',
+            'Connection': 'keep-alive'}
+
+
+    response = requests.get(url, headers=headers)
+    post_html = response.text
+
+    with open(os.path.join(basedir, 'habr.html'), 'w', encoding="utf-8") as f:
+        f.write(post_html)
+
+    #Парсим ссылки habr.com
+    soup = BeautifulSoup(post_html, "lxml")
+    vacancies = soup.find_all('div', {'class': 'tm-article-snippet'})
+    for vacancy in vacancies:
+        try:
+            link_title = str(vacancy.find('h2', {'class': 'tm-article-snippet__title_h2'}).text).strip()
+            link_href = str(vacancy.find('a', {'class': 'tm-article-snippet__title-link'}).get('href')).strip()
+            link_href = "https://habr.com" + link_href
+
+            #donor_link_id - предпоследнее число из link_href
+            donor_link_ids = link_href.split("/")
+            donor_link_id = donor_link_ids[len(donor_link_ids)-2]
+
+            out_s += str(link_title) + "<br>"
+            out_s += str(link_href + " :: " + str(donor_link_id)) + "<br>"
+
+            #уникальность ссылки
+            out_s += "Проверяем уникальность\n" + "<br>"
+            link_n = sqllite_session.query(Links).filter(Links.donor_link_id == donor_link_id).count()
+            out_s += "link_n: " + str(link_n) + "<br>"
+            if (link_n == 0):
+                out_s += "Добавляем в базу" + "<br>"
+                new_link = Links(
+                    title = link_title, 
+                    href = link_href,
+                    donor = 'habr.ru', 
+                    donor_link_id = donor_link_id, 
+                    parse_date = int(time.time()), 
+                    text = ""
+                    )
+                sqllite_session.add(new_link)
+            else:
+                out_s += "В базе ссылка есть" + "<br>"
+
+            out_s += "<br>"
+            status = 'Ok'
+
+        except Exception as e:
+            out_s += str(traceback.format_exc())
+            status = str(traceback.format_exc())
+
+    new_log = Log(
+        action = "parse", 
+        status = status, 
+        time = int(time.time()),
+        donor = 'habr.ru', 
+        )
+    sqllite_session.add(new_log)
+
+    sqllite_session.commit()
+    out_s += "<br>success"
+    start_response('200 OK', [('Content-Type','text/html')])
+    b = out_s.encode('utf-8')
+    return [b]
+
+

+ 80 - 0
hh_install.wsgi

@@ -0,0 +1,80 @@
+# -*- encoding: utf-8 -*-
+# 
+import os
+
+"""
+DATABASE_USER = 'id35114350'
+DATABASE_PASSWORD = 'e4bq9KYzEuPCh4s'
+DATABASE_HOST = '/var/run/postgresql'
+DATABASE_PORT = '5432'
+DATABASE_NAME = 'id35114350_hh'
+"""
+
+DATABASE_USER = 'id35114350'
+DATABASE_PASSWORD = 'Hgatrdy5rTeq'
+DATABASE_HOST = 'localhost'
+DATABASE_NAME = 'id35114350_hh'
+
+
+virtual_env = os.path.expanduser('~/projects/world-it-planet/env')
+activate_this = os.path.join(virtual_env, 'bin/activate_this.py')
+exec(open(activate_this).read(), dict(__file__=activate_this))
+
+from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
+from sqlalchemy import create_engine
+from sqlalchemy.orm import sessionmaker
+
+
+def application(env, start_response):
+    out_s = ""
+
+    """
+    engine = create_engine(
+            f'postgresql://{DATABASE_USER}:{DATABASE_PASSWORD}@{DATABASE_HOST}:{DATABASE_PORT}/{DATABASE_NAME}',
+            pool_pre_ping=True
+        )
+    """
+    engine = create_engine(
+            f'mysql+pymysql://{DATABASE_USER}:{DATABASE_PASSWORD}@{DATABASE_HOST}/{DATABASE_NAME}',
+            pool_pre_ping=True
+        )
+
+
+    metadata = MetaData()
+    vacancies_table = Table('vacancies', metadata,
+        Column('id', Integer, primary_key=True, autoincrement=True),
+        Column('title', String(512)),
+        Column('city', String(20)),
+        Column('specialization', String(255)),
+        Column('href', String(512)),
+        Column('donor', String(255)),
+        Column('vacancy_id', Integer),
+        Column('vacancy_date', Integer),
+        Column('parse_date', Integer),
+        Column('employer', String(255)),
+        Column('canal_city_id', Integer),
+        Column('canal_city_date', Integer),
+        Column('canal_spec_id', Integer),
+        Column('canal_spec_date', Integer)
+    )
+
+    """
+    log_table = Table('log', metadata,
+        Column('id', Integer, primary_key=True, autoincrement=True),
+        Column('action', String(64)),
+        Column('time', Integer),
+        Column('donor', String(64)),
+        Column('city', String(20)),
+        Column('vacancies_count', Integer),
+        Column('status', String(64)),
+        Column('canal_id', Integer),
+    )
+    """
+
+
+    metadata.create_all(engine)
+
+    out_s = "success"
+    start_response('200 OK', [('Content-Type','text/html')])
+    b = out_s.encode('utf-8')
+    return [b]

+ 117 - 0
hh_log.wsgi

@@ -0,0 +1,117 @@
+# -*- encoding: utf-8 -*-
+# 
+import os, urllib.parse, traceback
+
+virtual_env = os.path.expanduser('~/projects/world-it-planet/env')
+activate_this = os.path.join(virtual_env, 'bin/activate_this.py')
+exec(open(activate_this).read(), dict(__file__=activate_this))
+
+
+import random, time
+from datetime import datetime
+
+#декларативное определение
+from sqlalchemy import Column, Integer, String, create_engine
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import sessionmaker
+from sqlalchemy import desc
+
+#---------------------------------- Variables ----------
+
+
+#---------------------------------- Variables End ----------
+
+
+def application(env, start_response):
+    out_s = ""
+    #Инициализация SQLLite
+    basedir = os.path.abspath(os.path.dirname(__file__))
+    SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'hhtm.db')
+    engine = create_engine(SQLALCHEMY_DATABASE_URI, pool_pre_ping=True)
+
+    
+    Base = declarative_base()
+    class Vacancies(Base):
+        __tablename__ = 'vacancies'
+        id = Column(Integer, primary_key=True, autoincrement=True)
+        title = Column(String(512))
+        city = Column(String(20))
+        specialization = Column(String(255))
+        href = Column(String(512))
+        donor = Column(String(255))
+        vacancy_id = Column(Integer)
+        vacancy_date = Column(Integer)
+        parse_date = Column(Integer)
+        employer = Column(String(255))
+        canal_city_id = Column(Integer)
+        canal_city_date = Column(Integer)
+        canal_spec_id = Column(Integer)
+        canal_spec_date = Column(Integer)
+
+        def __init__(self, title, city, specialization, href, donor, vacancy_id, vacancy_date, parse_date, employer, canal_city_id, canal_city_date, canal_spec_id, canal_spec_date):
+            self.title = title
+            self.city = city
+            self.specialization = specialization
+            self.href = href
+            self.donor = donor
+            self.vacancy_id = vacancy_id
+            self.vacancy_date = vacancy_date
+            self.parse_date = parse_date
+            self.employer = employer
+            self.canal_city_id = canal_city_id
+            self.canal_city_date = canal_city_date
+            self.canal_spec_id = canal_spec_id
+            self.canal_spec_date = canal_spec_date
+
+        def __repr__(self):
+            return "<Vacancy('%s','%s', '%s')>" % (self.title, self.specialization, self.href)
+
+
+    class Log(Base):
+        __tablename__ = 'log'
+        id = Column(Integer, primary_key=True, autoincrement=True)
+        action = Column(String(64))
+        status = Column(String(64))
+        time = Column(Integer)
+        donor = Column(String(64))
+        city = Column(String(20))
+        specialization = Column(String(20))
+        vacancies_count = Column(Integer)
+        canal_id = Column(String(64))
+
+        def __init__(self, action, status, time, donor, city, specialization, vacancies_count, canal_id):
+            self.action = action
+            self.status = status
+            self.time = time
+            self.donor = donor
+            self.city = city
+            self.specialization = specialization
+            self.vacancies_count = vacancies_count
+            self.canal_id = canal_id
+
+        def __repr__(self):
+            return "<Log('%s','%s', '%s')>" % (self.action, self.status)
+
+    # Создание таблицы
+    Base.metadata.create_all(engine)
+
+
+    Session = sessionmaker(bind=engine)
+    session = Session()
+
+
+ 
+    out_s += "<table align=left cellspacing=8 cellpading=2 border=0><tr align=center><td>Date</td><td>Action</td><td>Status</td><td>Donor</td><td>Сity</td><td>Specialization</td><td>Vacancies Count</td><td>Canal ID</td></tr>"
+    log = session.query(Log).order_by(desc(Log.id))[0:50]
+    for item in log:
+        date_time = datetime.fromtimestamp(item.time)
+        s_date = date_time.strftime("%d %m %Y %H:%M:%S")
+        out_s += f"<tr align=center><td>{s_date}</td><td>{item.action}</td><td>{item.status}</td><td>{item.donor}</td><td>{item.city}</td><td>{item.specialization}</td><td>{item.vacancies_count}</td><td>{item.canal_id}</td></tr>"
+
+    out_s += "<br>"
+
+    start_response('200 OK', [('Content-Type','text/html')])
+    b = out_s.encode('utf-8')
+    return [b]
+
+

+ 268 - 0
hh_parser.wsgi

@@ -0,0 +1,268 @@
+# -*- encoding: utf-8 -*-
+# 
+import os, urllib.parse, traceback
+virtual_env = os.path.expanduser('~/projects/world-it-planet/env')
+activate_this = os.path.join(virtual_env, 'bin/activate_this.py')
+exec(open(activate_this).read(), dict(__file__=activate_this))
+
+
+from bs4 import BeautifulSoup
+import random, time, datetime
+import requests
+from requests.exceptions import ProxyError
+
+#декларативное определение
+from sqlalchemy import Column, Integer, String, create_engine
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import sessionmaker
+
+#---------------------------------- Variables ----------
+
+areas = {"bryansk":19}
+specializations = ['программист', 'стажер', 'стажировка']
+
+proxies = [
+                {
+                'http': 'http://linbergsergey_gmail_:56c2134eac@212.81.34.171:30013',
+                'https': 'http://linbergsergey_gmail_:56c2134eac@212.81.34.171:30013',
+                },
+                {
+                'http': 'http://linbergsergey_gmail_:56c2134eac@212.81.33.230:30013',
+                'https': 'http://linbergsergey_gmail_:56c2134eac@212.81.33.230:30013',
+                },
+                {},
+            ]
+
+user_agents = [
+    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:45.0) Gecko/20100101 Firefox/45.0",
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0",
+    "Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0",
+    "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.62 Safari/537.36",
+    "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)",
+    "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)",
+    "Mozilla/5.0 (Windows NT 6.1; rv:23.0) Gecko/20100101 Firefox/23.0",
+    "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.62 Safari/537.36",
+    "Opera/9.80 (Windows NT 5.1) Presto/2.12.388 Version/12.16",
+    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.62 Safari/537.36",
+    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 YaBrowser/1.7.1364.21027 Safari/537.22",
+    "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.16",
+    "Mozilla/5.0 (iPad; CPU OS 6_1_3 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10B329 Safari/8536.25",
+    "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.15",
+    "Mozilla / 5.0 (Macintosh; Intel Mac OS X 10.14; rv: 75.0) Gecko / 20100101 Firefox / 75.0",
+    "Mozilla / 5.0 (Windows NT 6.1; Win64; x64; rv: 74.0) Gecko / 20100101 Firefox / 74.0",
+    "Mozilla / 5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit / 537.36 (KHTML, как Gecko) Chrome / 80.0.3987.163 Safari / 537.36",
+    "Dalvik/2.1.0 (Linux; U; Android 10; Mi 9T MIUI/V12.0.5.0.QFJMIXM)"
+]
+
+
+#---------------------------------- Variables End ----------
+
+
+
+
+def application(env, start_response):
+    out_s = ""
+    #Инициализация SQLLite
+    basedir = os.path.abspath(os.path.dirname(__file__))
+    SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'hhtm.db')
+    engine = create_engine(SQLALCHEMY_DATABASE_URI, pool_pre_ping=True)
+
+
+    Base = declarative_base()
+    class Vacancies(Base):
+        __tablename__ = 'vacancies'
+        id = Column(Integer, primary_key=True, autoincrement=True)
+        title = Column(String(512))
+        city = Column(String(20))
+        specialization = Column(String(255))
+        href = Column(String(512))
+        donor = Column(String(255))
+        vacancy_id = Column(Integer)
+        vacancy_date = Column(Integer)
+        parse_date = Column(Integer)
+        employer = Column(String(255))
+        canal_city_id = Column(Integer)
+        canal_city_date = Column(Integer)
+        canal_spec_id = Column(Integer)
+        canal_spec_date = Column(Integer)
+
+        def __init__(self, title, city, specialization, href, donor, vacancy_id, vacancy_date, parse_date, employer, canal_city_id, canal_city_date, canal_spec_id, canal_spec_date):
+            self.title = title
+            self.city = city
+            self.specialization = specialization
+            self.href = href
+            self.donor = donor
+            self.vacancy_id = vacancy_id
+            self.vacancy_date = vacancy_date
+            self.parse_date = parse_date
+            self.employer = employer
+            self.canal_city_id = canal_city_id
+            self.canal_city_date = canal_city_date
+            self.canal_spec_id = canal_spec_id
+            self.canal_spec_date = canal_spec_date
+
+        def __repr__(self):
+            return "<Vacancy('%s','%s', '%s')>" % (self.title, self.specialization, self.href)
+
+
+    class Log(Base):
+        __tablename__ = 'log'
+        id = Column(Integer, primary_key=True, autoincrement=True)
+        action = Column(String(64))
+        status = Column(String(64))
+        time = Column(Integer)
+        donor = Column(String(64))
+        city = Column(String(20))
+        specialization = Column(String(20))
+        vacancies_count = Column(Integer)
+        canal_id = Column(String(64))
+
+        def __init__(self, action, status, time, donor, city, specialization, vacancies_count, canal_id):
+            self.action = action
+            self.status = status
+            self.time = time
+            self.donor = donor
+            self.city = city
+            self.specialization = specialization
+            self.vacancies_count = vacancies_count
+            self.canal_id = canal_id
+
+        def __repr__(self):
+            return "<Log('%s','%s', '%s')>" % (self.action, self.status)
+
+    # Создание таблицы
+    Base.metadata.create_all(engine)
+
+
+    Session = sessionmaker(bind=engine)
+    session = Session()
+
+
+    #"""
+    #формируем запрос
+    city, area = random.choice(list(areas.items())) 
+    host = city + ".hh.ru"
+    #t = random.choice([0,1])
+    t = 1
+    if (t == 1):
+        specialization = random.choice(specializations)
+    else:
+        specialization = ""
+    user_agent = random.choice(user_agents)
+
+    params = {
+            'clusters': 'true',
+            'area': area,
+            'enable_snippets': 'true',
+            'salary': '',
+            'st': 'searchVacancy',
+            'text': specialization
+        }
+
+    url = "https://" + host + "/search/vacancy?"+urllib.parse.urlencode(params)
+    referer = "https://" + host + "/search/vacancy?"+urllib.parse.urlencode(params) + "&customDomain=1"
+
+    headers = {
+            "Host": str(host),
+            'User-Agent': str(user_agent),
+            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
+            'Accept-Language': 'ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3',
+            'Accept-Encoding': 'gzip, deflate, br',
+            'Referer': str(referer),
+            'Upgrade-Insecure-Requests': '1',
+            'Connection': 'keep-alive'}
+
+
+    response = requests.get(url, headers=headers, params=params)
+    post_html = response.text
+
+    with open(os.path.join(basedir, 'response.html'), 'w', encoding="utf-8") as f:
+        f.write(post_html)
+
+
+    """
+    with open(os.path.dirname(os.path.abspath(__file__)) + '/response.html', 'r', encoding='utf-8') as f:
+        post_html = f.read()
+    """
+    
+    
+    #Парсим вакансии
+    vacancies_count = 0
+    soup = BeautifulSoup(post_html, "lxml")
+    vacancies = soup.find_all('div', {'class': 'vacancy-serp-item'})
+    for vacancy in vacancies:
+        try:
+            vacancy_title = str(vacancy.find('a', {'data-qa': 'vacancy-serp__vacancy-title'}).text).strip()
+            vacancy_href = str(vacancy.find('a', {'data-qa': 'vacancy-serp__vacancy-title'}).get('href')).strip()
+            vacancy_href = vacancy_href.split("?")[0]
+
+            vacancy_id = vacancy_href.split("/")
+            vacancy_id = int(vacancy_id[len(vacancy_id) - 1])
+
+            #<span class="vacancy-serp-item__publication-date vacancy-serp-item__publication-date_s-only">24.03.21</span>
+            """
+            vacancy_date = str(vacancy.find('span', {'class': 'vacancy-serp-item__publication-date vacancy-serp-item__publication-date_s-only'}).text).strip()
+            vacancy_date = int(time.mktime(datetime.datetime.strptime(vacancy_date, "%d.%m.%y").timetuple()))
+            """
+
+            #<a href="/employer/2936112" class="bloko-link bloko-link_secondary" data-qa="vacancy-serp__vacancy-employer"> Квадратный метр</a>
+            vacancy_employer = str(vacancy.find('a', {'class': 'bloko-link bloko-link_secondary'}).text).strip()
+            vacancy_employer_id = str(vacancy.find('a', {'class': 'bloko-link bloko-link_secondary'}).get('href')).strip()
+            vacancy_employer_id = vacancy_employer_id.replace('/employer/', '')
+            
+
+            out_s += str(vacancy_title) + "<br>"
+            out_s += str(vacancy_href + " :: " + str(vacancy_id)) + "<br>"
+            #out_s += str(vacancy_date) + "<br>"
+            out_s += str(vacancy_employer + " :: " + vacancy_employer_id) + "<br>"
+
+            #уникальность вакансии
+            out_s += "Проверяем уникальность\n" + "<br>"
+            vacancy_n = session.query(Vacancies).filter(Vacancies.href == vacancy_href).count()
+            out_s += str(vacancy_n) + "<br>"
+            if (vacancy_n == 0):
+                out_s += "Добавляем в базу" + "<br>"
+                new_vacancy = Vacancies(
+                    title = vacancy_title, 
+                    city = city, 
+                    specialization = specialization, 
+                    href = vacancy_href,
+                    donor = 'hh.ru', 
+                    vacancy_id = vacancy_id, 
+                    vacancy_date = int(time.time()), 
+                    parse_date = int(time.time()), 
+                    employer=vacancy_employer, 
+                    canal_city_id = 0, 
+                    canal_city_date = 0, 
+                    canal_spec_id = 0,
+                    canal_spec_date = 0
+                    )
+                session.add(new_vacancy)
+                vacancies_count += 1
+            out_s += "<br>"
+            status = 'Ok'
+        except Exception as e:
+            out_s += str(traceback.format_exc())
+            status = str(traceback.format_exc())
+
+    new_log = Log(
+        action = "parse", 
+        status = status, 
+        time = int(time.time()),
+        donor = 'hh.ru', 
+        city = city, 
+        specialization = specialization,
+        vacancies_count = vacancies_count, 
+        canal_id = 0, 
+        )
+    session.add(new_log)
+
+
+
+    session.commit()
+    out_s += "<br>success"
+    start_response('200 OK', [('Content-Type','text/html')])
+    b = out_s.encode('utf-8')
+    return [b]
+
+

BIN
hhtm.db


+ 105 - 0
last_action.wsgi

@@ -0,0 +1,105 @@
+# -*- encoding: utf-8 -*-
+# 
+import os, json, sys, subprocess, urllib.parse, traceback
+import random, time, datetime, re
+from urllib.parse import unquote
+
+virtual_env = os.path.expanduser('~/projects/world-it-planet/env')
+activate_this = os.path.join(virtual_env, 'bin/activate_this.py')
+exec(open(activate_this).read(), dict(__file__=activate_this))
+
+import requests
+#MySql
+from mysql.connector import connect, Error
+
+#декларативное определение SQLLite
+from sqlalchemy import Column, Integer, String, Text, create_engine
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import sessionmaker
+from sqlalchemy import desc
+
+
+#---------------------------------- Variables ----------
+
+
+
+
+#---------------------------------- Variables End ----------
+
+
+
+
+
+def application(env, start_response):
+    out_s = {}
+
+    """
+    for key in env:
+        out_s = out_s + str(key) + "=" + str(env[key]) + "<br>"
+    """
+    #получаем $_GET из запроса
+    get_query = env['QUERY_STRING']
+    get_json = get_query.replace("q=", "")
+    get_json = unquote(get_json)
+
+    get_dict = json.loads(get_json)
+    tm_id = str(get_dict['tm_id'])
+    vk_id = str(get_dict['vk_id'])
+    out_s["tm_id"] = tm_id
+    
+    #Инициализация MySQL
+    mysql_connection = connect(
+            host="localhost",
+            user="id35114350",
+            password="Hgatrdy5rTeq",
+            database="id35114350_steelfeet",
+            charset='utf8',
+            use_unicode=True            
+        )
+
+
+    #------------------------------------------ Основной цикл ------------------
+
+    #запрос wp_id по внешнему сервису
+    params = {
+        "action":"show_wp_id",
+        "tm_id":tm_id
+    }
+    params_json = json.dumps(params)
+    get_wp_url = "https://steelfeet.ru/app/get.php?q=" + params_json
+    out_s["get_wp_url"] = get_wp_url
+
+    response = requests.get(get_wp_url)
+    wp_id = int(response.text)
+    out_s["wp_id"] = wp_id
+
+
+
+
+    now = datetime.datetime.now()
+    for item in links_list:
+        #добавляем показанные вакансии в лог
+        #INSERT INTO `sf_log` (`user_id`, `date`, `hour`, `code`, `action`, `data_1`, `data_2`, `data_3`, `data_4`, `data`, `weight`) VALUES ('', '', '', '', '', '', '', '', '', '');
+
+        exist_vacancies_query = "SELECT `id` FROM `sf_log` WHERE (`code` = 'read') AND (`data_1` = " + str(item["id"]) + ");"
+        with mysql_connection.cursor(buffered=True) as cursor:
+            cursor.execute(exist_vacancies_query)
+            exist_vacancies = cursor.fetchall()
+
+
+        if (len(exist_vacancies) == 0):
+            mysql_query = "INSERT INTO `sf_log` (`user_id`, `date`, `hour`, `code`, `action`, `data_1`, `data_2`, `data_3`, `data_4`, `data`, `weight`) VALUES ('" + str(wp_id) + "', '" + str(int(time.time())) + "', '" + str(now.hour) + "', 'read', 'show_last', '" + str(item["id"]) + "', '', '" + str(item["title"]) + "', '', 'data_1=>read_id, data_3=>read_title', '');"
+            
+            with mysql_connection.cursor() as cursor:
+                cursor.execute(mysql_query)
+                
+        mysql_connection.commit()
+
+
+
+    start_response('200 OK', [('Content-Type','text/html')])
+    out_s = json.dumps(out_s)
+    b = out_s.encode('utf-8')
+    return [b]
+
+

+ 145 - 0
last_read.wsgi

@@ -0,0 +1,145 @@
+# -*- encoding: utf-8 -*-
+# 
+import os, json, sys, subprocess, urllib.parse, traceback
+import random, time, datetime, re
+from urllib.parse import unquote
+
+virtual_env = os.path.expanduser('~/projects/world-it-planet/env')
+activate_this = os.path.join(virtual_env, 'bin/activate_this.py')
+exec(open(activate_this).read(), dict(__file__=activate_this))
+
+import requests
+#MySql
+from mysql.connector import connect, Error
+
+#декларативное определение SQLLite
+from sqlalchemy import Column, Integer, String, Text, create_engine
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import sessionmaker
+from sqlalchemy import desc
+
+
+#---------------------------------- Variables ----------
+
+
+
+
+#---------------------------------- Variables End ----------
+
+
+
+
+
+def application(env, start_response):
+    out_s = {}
+
+    """
+    for key in env:
+        out_s = out_s + str(key) + "=" + str(env[key]) + "<br>"
+    """
+    #получаем $_GET из запроса
+    get_query = env['QUERY_STRING']
+    get_json = get_query.replace("q=", "")
+    get_json = unquote(get_json)
+
+    get_dict = json.loads(get_json)
+    tm_id = str(get_dict['tm_id'])
+    vk_id = str(get_dict['vk_id'])
+    out_s["tm_id"] = tm_id
+    
+    #Инициализация MySQL
+    mysql_connection = connect(
+            host="localhost",
+            user="id35114350",
+            password="Hgatrdy5rTeq",
+            database="id35114350_steelfeet",
+            charset='utf8',
+            use_unicode=True            
+        )
+
+    #Инициализация SQLLite
+    basedir = os.path.abspath(os.path.dirname(__file__))
+    SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'habr.db')
+    engine = create_engine(SQLALCHEMY_DATABASE_URI, pool_pre_ping=True)
+
+    Base = declarative_base()
+    class Links(Base):
+        __tablename__ = 'links'
+        id = Column(Integer, primary_key=True, autoincrement=True)
+        title = Column(String(512))
+        href = Column(String(512))
+        donor = Column(String(255))
+        donor_link_id = Column(Integer) #внутренний идентификатор для донора, https://habr.com/ru/company/skillfactory/blog/578014/ -> 578014
+        parse_date = Column(Integer)
+        text = Column(Text)
+
+        def __init__(self, title, href, donor, donor_link_id, parse_date, text):
+            self.title = title
+            self.href = href
+            self.donor = donor
+            self.donor_link_id = donor_link_id
+            self.parse_date = parse_date
+            self.text = text
+
+        def __repr__(self):
+            return "<Link('%s', '%s')>" % (self.title, self.href)
+
+    Session = sessionmaker(bind=engine)
+    sqllite_session = Session()
+
+    #------------------------------------------ Основной цикл ------------------
+
+    #запрос wp_id по внешнему сервису
+    params = {
+        "action":"show_wp_id",
+        "tm_id":tm_id
+    }
+    params_json = json.dumps(params)
+    get_wp_url = "https://steelfeet.ru/app/get.php?q=" + params_json
+    out_s["get_wp_url"] = get_wp_url
+
+    response = requests.get(get_wp_url)
+    wp_id = int(response.text)
+    out_s["wp_id"] = wp_id
+
+
+    links = sqllite_session.query(Links).order_by(desc(Links.parse_date))[0:5]
+    links_list = []
+    for item in links:
+        link_item = {
+            "id" : str(item.id),
+            "title" : str(item.title),
+            "href" : item.href,
+        }
+        links_list.append(link_item)
+
+    out_s["reads"] = links_list
+
+
+    now = datetime.datetime.now()
+    for item in links_list:
+        #добавляем показанные вакансии в лог
+        #INSERT INTO `sf_log` (`user_id`, `date`, `hour`, `code`, `action`, `data_1`, `data_2`, `data_3`, `data_4`, `data`, `weight`) VALUES ('', '', '', '', '', '', '', '', '', '');
+
+        exist_vacancies_query = "SELECT `id` FROM `sf_log` WHERE (`code` = 'read') AND (`data_1` = " + str(item["id"]) + ");"
+        with mysql_connection.cursor(buffered=True) as cursor:
+            cursor.execute(exist_vacancies_query)
+            exist_vacancies = cursor.fetchall()
+
+
+        if (len(exist_vacancies) == 0):
+            mysql_query = "INSERT INTO `sf_log` (`user_id`, `date`, `hour`, `code`, `action`, `data_1`, `data_2`, `data_3`, `data_4`, `data`, `weight`) VALUES ('" + str(wp_id) + "', '" + str(int(time.time())) + "', '" + str(now.hour) + "', 'read', 'show_last', '" + str(item["id"]) + "', '', '" + str(item["title"]) + "', '', 'data_1=>read_id, data_3=>read_title', '');"
+            
+            with mysql_connection.cursor() as cursor:
+                cursor.execute(mysql_query)
+                
+        mysql_connection.commit()
+
+
+
+    start_response('200 OK', [('Content-Type','text/html')])
+    out_s = json.dumps(out_s)
+    b = out_s.encode('utf-8')
+    return [b]
+
+

+ 167 - 0
last_vacancies.wsgi

@@ -0,0 +1,167 @@
+# -*- encoding: utf-8 -*-
+# 
+import os, json, sys, subprocess, urllib.parse, traceback
+import random, time, datetime, re
+from urllib.parse import unquote
+
+virtual_env = os.path.expanduser('~/projects/world-it-planet/env')
+activate_this = os.path.join(virtual_env, 'bin/activate_this.py')
+exec(open(activate_this).read(), dict(__file__=activate_this))
+
+import requests
+#MySql
+from mysql.connector import connect, Error
+
+#декларативное определение SQLLite
+from sqlalchemy import Column, Integer, String, create_engine
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import sessionmaker
+from sqlalchemy import desc
+
+
+#---------------------------------- Variables ----------
+
+
+
+
+#---------------------------------- Variables End ----------
+
+
+
+
+
+def application(env, start_response):
+    out_s = {}
+
+    """
+    for key in env:
+        out_s = out_s + str(key) + "=" + str(env[key]) + "<br>"
+    """
+    #получаем $_GET из запроса
+    get_query = env['QUERY_STRING']
+    get_json = get_query.replace("q=", "")
+    get_json = unquote(get_json)
+
+    get_dict = json.loads(get_json)
+    tm_id = str(get_dict['tm_id'])
+    out_s["tm_id"] = tm_id
+    
+    #Инициализация MySQL
+    mysql_connection = connect(
+            host="localhost",
+            user="id35114350",
+            password="Hgatrdy5rTeq",
+            database="id35114350_steelfeet",
+            charset='utf8',
+            use_unicode=True            
+        )
+
+    #Инициализация SQLLite
+    basedir = os.path.abspath(os.path.dirname(__file__))
+    SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'hhtm.db')
+    engine = create_engine(SQLALCHEMY_DATABASE_URI, pool_pre_ping=True)
+
+    Base = declarative_base()
+    class Vacancies(Base):
+        __tablename__ = 'vacancies'
+        id = Column(Integer, primary_key=True, autoincrement=True)
+        title = Column(String(512))
+        city = Column(String(20))
+        specialization = Column(String(255))
+        href = Column(String(512))
+        donor = Column(String(255))
+        vacancy_id = Column(Integer)
+        vacancy_date = Column(Integer)
+        parse_date = Column(Integer)
+        employer = Column(String(255))
+        canal_city_id = Column(Integer)
+        canal_city_date = Column(Integer)
+        canal_spec_id = Column(Integer)
+        canal_spec_date = Column(Integer)
+
+        def __init__(self, title, city, specialization, href, donor, vacancy_id, vacancy_date, parse_date, employer, canal_city_id, canal_city_date, canal_spec_id, canal_spec_date):
+            self.title = title
+            self.city = city
+            self.specialization = specialization
+            self.href = href
+            self.donor = donor
+            self.vacancy_id = vacancy_id
+            self.vacancy_date = vacancy_date
+            self.parse_date = parse_date
+            self.employer = employer
+            self.canal_city_id = canal_city_id
+            self.canal_city_date = canal_city_date
+            self.canal_spec_id = canal_spec_id
+            self.canal_spec_date = canal_spec_date
+
+        def __repr__(self):
+            return "<Vacancy('%s','%s', '%s')>" % (self.title, self.specialization, self.href)
+
+    Session = sessionmaker(bind=engine)
+    sqllite_session = Session()
+
+    #------------------------------------------ Основной цикл ------------------
+
+    #запрос wp_id по внешнему сервису
+    params = {
+        "action":"show_wp_id",
+        "tm_id":tm_id
+    }
+    params_json = json.dumps(params)
+    get_wp_url = "https://steelfeet.ru/app/get.php?q=" + params_json
+    out_s["get_wp_url"] = get_wp_url
+
+    #response = requests.get(get_wp_url)
+    #wp_id = int(response.text)
+    wp_id = 2
+    out_s["wp_id"] = wp_id
+
+    now = datetime.datetime.now()
+    #просто последние пять спарсенных
+    vacancies = sqllite_session.query(Vacancies).order_by(desc(Vacancies.parse_date))[0:5]
+
+    vacancies_list = []
+    for item in vacancies:
+        vacancy_item = {
+            "id" : item.id,
+            "title" : str(item.title),
+            "href" : item.href,
+        }
+        vacancies_list.append(vacancy_item)
+    vacancies_list = vacancies_list[0:5]
+
+    #выводим  5
+    for item in vacancies_list:
+        #добавляем показанные вакансии в лог
+        #INSERT INTO `sf_log` (`user_id`, `date`, `hour`, `code`, `action`, `data_1`, `data_2`, `data_3`, `data_4`, `data`, `weight`) VALUES ('', '', '', '', '', '', '', '', '', '');
+
+        exist_vacancies_query = "SELECT `id` FROM `sf_log` WHERE (`code` = 'vacancy') AND (`data_1` = " + str(item["id"]) + ");"
+        with mysql_connection.cursor(buffered=True) as cursor:
+            cursor.execute(exist_vacancies_query)
+            exist_vacancies = cursor.fetchall()
+
+
+        if (len(exist_vacancies) == 0):
+            mysql_query = "INSERT INTO `sf_log` (`user_id`, `date`, `hour`, `code`, `action`, `data_1`, `data_2`, `data_3`, `data_4`, `data`, `weight`) VALUES ('" + str(wp_id) + "', '" + str(int(time.time())) + "', '" + str(now.hour) + "', 'vacancy', 'show_last', '" + str(item["id"]) + "', '', '" + str(item["title"]) + "', '', 'data_1=>vacancy_id, data_3=>vacancy_title', '');"
+            
+            with mysql_connection.cursor() as cursor:
+                cursor.execute(mysql_query)
+                
+        mysql_connection.commit()
+
+    
+
+
+
+    out_s["vacancies"] = vacancies_list
+
+
+
+
+
+    start_response('200 OK', [('Content-Type','text/html')])
+    out_s = json.dumps(out_s)
+    b = out_s.encode('utf-8')
+    return [b]
+
+

+ 140 - 0
next_read.wsgi

@@ -0,0 +1,140 @@
+# -*- encoding: utf-8 -*-
+# 
+import os, json, sys, subprocess, urllib.parse, traceback
+import random, time, datetime, re
+from urllib.parse import unquote
+
+virtual_env = os.path.expanduser('~/projects/world-it-planet/env')
+activate_this = os.path.join(virtual_env, 'bin/activate_this.py')
+exec(open(activate_this).read(), dict(__file__=activate_this))
+
+import requests
+#MySql
+from mysql.connector import connect, Error
+
+#декларативное определение SQLLite
+from sqlalchemy import Column, Integer, String, Text, create_engine
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import sessionmaker
+from sqlalchemy import desc
+
+
+#---------------------------------- Variables ----------
+
+
+
+
+#---------------------------------- Variables End ----------
+
+
+
+
+
+def application(env, start_response):
+    out_s = {}
+
+    """
+    for key in env:
+        out_s = out_s + str(key) + "=" + str(env[key]) + "<br>"
+    """
+    #получаем $_GET из запроса
+    get_query = env['QUERY_STRING']
+    get_json = get_query.replace("q=", "")
+    get_json = unquote(get_json)
+
+    get_dict = json.loads(get_json)
+    tm_id = str(get_dict['tm_id'])
+    vk_id = str(get_dict['vk_id'])
+    out_s["tm_id"] = tm_id
+    
+    #Инициализация MySQL
+    mysql_connection = connect(
+            host="localhost",
+            user="id35114350",
+            password="Hgatrdy5rTeq",
+            database="id35114350_steelfeet",
+            charset='utf8',
+            use_unicode=True            
+        )
+
+    #Инициализация SQLLite
+    basedir = os.path.abspath(os.path.dirname(__file__))
+    SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'habr.db')
+    engine = create_engine(SQLALCHEMY_DATABASE_URI, pool_pre_ping=True)
+
+    Base = declarative_base()
+    class Links(Base):
+        __tablename__ = 'links'
+        id = Column(Integer, primary_key=True, autoincrement=True)
+        title = Column(String(512))
+        href = Column(String(512))
+        donor = Column(String(255))
+        donor_link_id = Column(Integer) #внутренний идентификатор для донора, https://habr.com/ru/company/skillfactory/blog/578014/ -> 578014
+        parse_date = Column(Integer)
+        text = Column(Text)
+
+        def __init__(self, title, href, donor, donor_link_id, parse_date, text):
+            self.title = title
+            self.href = href
+            self.donor = donor
+            self.donor_link_id = donor_link_id
+            self.parse_date = parse_date
+            self.text = text
+
+        def __repr__(self):
+            return "<Link('%s', '%s')>" % (self.title, self.href)
+
+    Session = sessionmaker(bind=engine)
+    sqllite_session = Session()
+
+    #------------------------------------------ Основной цикл ------------------
+
+    #запрос wp_id по внешнему сервису
+    params = {
+        "action":"show_wp_id",
+        "tm_id":tm_id
+    }
+    params_json = json.dumps(params)
+    get_wp_url = "https://steelfeet.ru/app/get.php?q=" + params_json
+    out_s["get_wp_url"] = get_wp_url
+
+    response = requests.get(get_wp_url)
+    wp_id = int(response.text)
+    out_s["wp_id"] = wp_id
+
+    """
+    now = datetime.datetime.now()
+    showed_read = get_dict["showed_read"]
+    for item in showed_read:
+        #добавляем показанные вакансии в лог
+        #INSERT INTO `sf_log` (`user_id`, `date`, `hour`, `action`, `data_1`, `data_2`, `data_3`, `data_4`, `data`, `weight`) VALUES ('', '', '', '', '', '', '', '', '', '');
+
+        exist_vacancies_query = "SELECT `id` FROM `sf_log` WHERE (`code` = 'read') AND (`data_1` = " + str(item["id"]) + ") AND (`action` = 'show_next') AND (`user_id` = " + str(wp_id) + ") ;"
+        with mysql_connection.cursor(buffered=True) as cursor:
+            cursor.execute(exist_vacancies_query)
+            exist_vacancies = cursor.fetchall()
+
+        out_s["exist_vacancies_query"] = exist_vacancies_query
+        if (len(exist_vacancies) == 0):
+            mysql_query = "INSERT INTO `sf_log` (`user_id`, `date`, `hour`, `code`, `action`, `data_1`, `data_2`, `data_3`, `data_4`, `data`, `weight`) VALUES ('" + str(wp_id) + "', '" + str(int(time.time())) + "', '" + str(now.hour) + "', 'read', 'show_next',  '" + str(item["id"]) + "', '', '" + str(item["title"]) + "', '', 'data_1=>read_id, data_3=>read_title', '');"
+        
+        with mysql_connection.cursor() as cursor:
+            cursor.execute(mysql_query)
+
+        mysql_connection.commit()
+    """
+
+    mysql_query = "UPDATE `sf_log` SET `action` = 'show_next' WHERE `user_id` = '" + str(wp_id) + "' AND `code` = 'read';"
+    with mysql_connection.cursor() as cursor:
+        cursor.execute(mysql_query)
+
+    mysql_connection.commit()
+
+
+
+    start_response('200 OK', [('Content-Type','text/html')])
+    out_s = json.dumps(out_s)
+    b = out_s.encode('utf-8')
+    return [b]
+
+

+ 151 - 0
next_vacancies.wsgi

@@ -0,0 +1,151 @@
+# -*- encoding: utf-8 -*-
+# 
+import os, json, sys, subprocess, urllib.parse, traceback
+import random, time, datetime, re
+from urllib.parse import unquote
+
+virtual_env = os.path.expanduser('~/projects/world-it-planet/env')
+activate_this = os.path.join(virtual_env, 'bin/activate_this.py')
+exec(open(activate_this).read(), dict(__file__=activate_this))
+
+import requests
+#MySql
+from mysql.connector import connect, Error
+
+#декларативное определение SQLLite
+from sqlalchemy import Column, Integer, String, create_engine
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import sessionmaker
+from sqlalchemy import desc
+
+
+#---------------------------------- Variables ----------
+
+
+
+
+#---------------------------------- Variables End ----------
+
+
+
+
+
+def application(env, start_response):
+    out_s = {}
+
+    """
+    for key in env:
+        out_s = out_s + str(key) + "=" + str(env[key]) + "<br>"
+    """
+    #получаем $_GET из запроса
+    get_query = env['QUERY_STRING']
+    get_json = get_query.replace("q=", "")
+    get_json = unquote(get_json)
+
+    get_dict = json.loads(get_json)
+    tm_id = str(get_dict['tm_id'])
+    out_s["tm_id"] = tm_id
+    
+    #Инициализация MySQL
+    mysql_connection = connect(
+            host="localhost",
+            user="id35114350",
+            password="Hgatrdy5rTeq",
+            database="id35114350_steelfeet",
+            charset='utf8',
+            use_unicode=True            
+        )
+
+    #Инициализация SQLLite
+    basedir = os.path.abspath(os.path.dirname(__file__))
+    SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'hhtm.db')
+    engine = create_engine(SQLALCHEMY_DATABASE_URI, pool_pre_ping=True)
+
+    Base = declarative_base()
+    class Vacancies(Base):
+        __tablename__ = 'vacancies'
+        id = Column(Integer, primary_key=True, autoincrement=True)
+        title = Column(String(512))
+        city = Column(String(20))
+        specialization = Column(String(255))
+        href = Column(String(512))
+        donor = Column(String(255))
+        vacancy_id = Column(Integer)
+        vacancy_date = Column(Integer)
+        parse_date = Column(Integer)
+        employer = Column(String(255))
+        canal_city_id = Column(Integer)
+        canal_city_date = Column(Integer)
+        canal_spec_id = Column(Integer)
+        canal_spec_date = Column(Integer)
+
+        def __init__(self, title, city, specialization, href, donor, vacancy_id, vacancy_date, parse_date, employer, canal_city_id, canal_city_date, canal_spec_id, canal_spec_date):
+            self.title = title
+            self.city = city
+            self.specialization = specialization
+            self.href = href
+            self.donor = donor
+            self.vacancy_id = vacancy_id
+            self.vacancy_date = vacancy_date
+            self.parse_date = parse_date
+            self.employer = employer
+            self.canal_city_id = canal_city_id
+            self.canal_city_date = canal_city_date
+            self.canal_spec_id = canal_spec_id
+            self.canal_spec_date = canal_spec_date
+
+        def __repr__(self):
+            return "<Vacancy('%s','%s', '%s')>" % (self.title, self.specialization, self.href)
+
+    Session = sessionmaker(bind=engine)
+    sqllite_session = Session()
+
+    #------------------------------------------ Основной цикл ------------------
+
+    #запрос wp_id по внешнему сервису
+    params = {
+        "action":"show_wp_id",
+        "tm_id":tm_id
+    }
+    params_json = json.dumps(params)
+    get_wp_url = "https://steelfeet.ru/app/get.php?q=" + params_json
+
+    response = requests.get(get_wp_url)
+    wp_id = int(response.text)
+    out_s["wp_id"] = wp_id
+
+    """
+    now = datetime.datetime.now()
+    showed_vacancies = get_dict["showed_vacancies"]
+    for item in showed_vacancies:
+        #добавляем показанные вакансии в лог
+        #INSERT INTO `sf_log` (`user_id`, `date`, `hour`, `action`, `data_1`, `data_2`, `data_3`, `data_4`, `data`, `weight`) VALUES ('', '', '', '', '', '', '', '', '', '');
+
+        exist_vacancies_query = "SELECT `id` FROM `sf_log` WHERE (`code` = 'vacancy') AND (`data_1` = " + str(item["id"]) + ");"
+        with mysql_connection.cursor(buffered=True) as cursor:
+            cursor.execute(exist_vacancies_query)
+            exist_vacancies = cursor.fetchall()
+
+        if (len(exist_vacancies) == 0):
+            mysql_query = "INSERT INTO `sf_log` (`user_id`, `date`, `hour`, `code`, `action`, `data_1`, `data_2`, `data_3`, `data_4`, `data`, `weight`) VALUES ('" + str(wp_id) + "', '" + str(int(time.time())) + "', '" + str(now.hour) + "', 'vacancy', 'show_next',  '" + str(item["id"]) + "', '', '" + str(item["title"]) + "', '', 'data_1=>vacancy_id, data_3=>vacancy_title', '');"
+        
+        with mysql_connection.cursor() as cursor:
+            cursor.execute(mysql_query)
+
+    mysql_connection.commit()
+
+    """
+    mysql_query = "UPDATE `sf_log` SET `action` = 'show_next' WHERE `user_id` = '" + str(wp_id) + "' AND `code` = 'vacancy';"
+    with mysql_connection.cursor() as cursor:
+        cursor.execute(mysql_query)
+
+    mysql_connection.commit()
+
+
+
+    start_response('200 OK', [('Content-Type','text/html')])
+    out_s = json.dumps(out_s)
+    b = out_s.encode('utf-8')
+    return [b]
+
+

File diff suppressed because it is too large
+ 32 - 0
response.html


File diff suppressed because it is too large
+ 32 - 0
response_1.html


+ 155 - 0
tm_bot.wsgi

@@ -0,0 +1,155 @@
+# -*- encoding: utf-8 -*-
+# 
+import os, json, sys, subprocess, urllib.parse, traceback
+
+virtual_env = os.path.expanduser('~/projects/world-it-planet/env')
+activate_this = os.path.join(virtual_env, 'bin/activate_this.py')
+exec(open(activate_this).read(), dict(__file__=activate_this))
+
+
+import random, time, datetime, os, re
+import telegram
+
+#декларативное определение
+from sqlalchemy import Column, Integer, String, create_engine
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import sessionmaker
+
+#---------------------------------- Variables ----------
+areas = {"bryansk":19}
+specializations = ['программист', 'стажер', 'стажировка']
+
+#максимальное количество публикуемых вакансий за 1 раз
+max_vacancies = 3
+
+access_token = "1775925477:AAH1Wlk22hxjSghqOH_IEuolj_FWO2k_YUs"
+chat_id = "-1001166215020"
+#---------------------------------- Variables End ----------
+
+
+
+
+def application(env, start_response):
+    out_s = ""
+    #Инициализация SQLLite
+    basedir = os.path.abspath(os.path.dirname(__file__))
+    SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'hhtm.db')
+    engine = create_engine(SQLALCHEMY_DATABASE_URI, pool_pre_ping=True)
+
+    Base = declarative_base()
+    class Vacancies(Base):
+        __tablename__ = 'vacancies'
+        id = Column(Integer, primary_key=True, autoincrement=True)
+        title = Column(String(512))
+        city = Column(String(20))
+        specialization = Column(String(255))
+        href = Column(String(512))
+        donor = Column(String(255))
+        vacancy_id = Column(Integer)
+        vacancy_date = Column(Integer)
+        parse_date = Column(Integer)
+        employer = Column(String(255))
+        canal_city_id = Column(Integer)
+        canal_city_date = Column(Integer)
+        canal_spec_id = Column(Integer)
+        canal_spec_date = Column(Integer)
+
+        def __init__(self, title, city, specialization, href, donor, vacancy_id, vacancy_date, parse_date, employer, canal_city_id, canal_city_date, canal_spec_id, canal_spec_date):
+            self.title = title
+            self.city = city
+            self.specialization = specialization
+            self.href = href
+            self.donor = donor
+            self.vacancy_id = vacancy_id
+            self.vacancy_date = vacancy_date
+            self.parse_date = parse_date
+            self.employer = employer
+            self.canal_city_id = canal_city_id
+            self.canal_city_date = canal_city_date
+            self.canal_spec_id = canal_spec_id
+            self.canal_spec_date = canal_spec_date
+
+        def __repr__(self):
+            return "<Vacancy('%s','%s', '%s')>" % (self.title, self.specialization, self.href)
+
+
+    class Log(Base):
+        __tablename__ = 'log'
+        id = Column(Integer, primary_key=True, autoincrement=True)
+        action = Column(String(64))
+        status = Column(String(64))
+        time = Column(Integer)
+        donor = Column(String(64))
+        city = Column(String(20))
+        specialization = Column(String(20))
+        vacancies_count = Column(Integer)
+        canal_id = Column(String(64))
+
+        def __init__(self, action, status, time, donor, city, specialization, vacancies_count, canal_id):
+            self.action = action
+            self.status = status
+            self.time = time
+            self.donor = donor
+            self.city = city
+            self.specialization = specialization
+            self.vacancies_count = vacancies_count
+            self.canal_id = canal_id
+
+        def __repr__(self):
+            return "<Log('%s','%s', '%s')>" % (self.action, self.status)
+
+
+    Session = sessionmaker(bind=engine)
+    session = Session()
+
+    city, area = random.choice(list(areas.items())) 
+    specialization = random.choice(specializations)
+
+    now = datetime.datetime.now()
+    hour_now = int(now.strftime("%H"))
+
+    if ((hour_now > 8) and (hour_now < 20)):
+        vacancy = session.query(Vacancies).filter(Vacancies.canal_city_date == 0).first()
+        try:
+            bot = telegram.Bot(token=access_token)
+            text = vacancy.title + ": <a href='" + vacancy.href + "'>" + vacancy.href + "</a>"
+            tm_response = str(bot.sendMessage(chat_id=chat_id, text=text, parse_mode=telegram.ParseMode.HTML))
+            #ответ не стандартный json
+            tm_response = tm_response.replace("\\", "\\\\")
+            tm_response = tm_response.strip("'<>() ").replace("\'", "\"")
+            tm_response = tm_response.replace("False", "\"False\"")
+            message_id = int(json.loads(tm_response)["message_id"])
+            #удаляем следующее сообщение
+            time.sleep(3)
+            message_id = message_id + 1
+            bot.delete_message(chat_id=chat_id, message_id=message_id)
+            status = "Ok test"
+            vacancy.canal_city_date = int(time.time())
+        except:
+            status = str(traceback.format_exc())
+            out_s = str(status)
+            out_s = out_s + "<br>" + tm_response
+
+
+
+
+        new_log = Log(
+            action = "post", 
+            status = status, 
+            time = int(time.time()),
+            donor = 'hh.ru', 
+            city = city, 
+            specialization = specialization,
+            vacancies_count = 0,
+            canal_id = chat_id, 
+            )
+        session.add(new_log)
+
+
+
+    session.commit()
+    start_response('200 OK', [('Content-Type','text/html')])
+    b = out_s.encode('utf-8')
+    return [b]
+
+

Some files were not shown because too many files changed in this diff