def SearchProducts(self, res, doc): keys = [] for key in re.split(r'[,;\s]+', res.text): if key: keys.append(real_translit(key)) qlist = [] params = [] db = self._db for field in ('id', 'partno1', 'partno2'): qlist.append(sql.get_f('id', 'product', sql.fin(field, keys, True))) params += keys idl = db.fetchvals(sql.union(qlist), params) if not idl: return False res.count = len(idl) f = ['ps.id_product = p.id', 'pv.id_cat = ps.id_prop1'] q = sql.get_f('pv.id', ['pview pv', 'prop_set ps'], f) q = sql.order(q, 'pv.num') q = sql.limit(q, 0, 1) q = sql.get_f(['id', '(%s) AS id_view' % q], 'product p', sql.fin('id', idl)) for (idp, id) in db.fetchall(q): if id in res.filters: view = res.filters[id] else: view = classes.View(doc, id) view.k = doc.getk([view.id_cat], 'id') + [None] * 7 view.parsemap(view.k) view.products = [] res.filters[id] = view view.products.append(idp) for view in res.filters.itervalues(): view.frow = [sql.fin('id_product', view.products)] view.count = len(view.products)
def _getfrow(self, props, view): frow = [] def kd(keydata): return map(lambda s: s[0], keydata) #log('::::::::VIEW = %s' % view.id) for (key, groups) in props.iteritems(): log found = False keydata = [] for (gid, idl) in groups: if gid in view.groups: found = True k = (view.groups.index(gid) + 1) field = 'id_prop%d' % k #log((k, view.id_cat, idl)) row = sql.fin(field, idl) row = (field, idl) keydata.append(row) if not found: return None newkd = True #list1 = kd(keydata) #for keydata0 in frow: # if list_compare(list1, kd(keydata0)): # newkd = False # for i in xrange(len(keydata)): # pass #list_update(keydata[i][1], keydata0[i][1]) # break if newkd: frow.append(keydata) #log('----------- KEYDATA FOR %s -------------' % key) #log(keydata) #log('----------- END KEYDATA ----------------------') f = map(lambda x: sql.f_or(map(lambda y: sql.fin(y[0], y[1]), x)), frow) f.append('pview = "%s"' % view.pview) f.append('id_prop1 = %d' % view.id_cat) return f
def getprops(self, row): idl = map(lambda i: row['id_prop' + str(i + 1)], xrange(8)) f = sql.fin('id', vallist(idl)) props = db.fetchdic(sql.get_f(['id', 'translit'], 'prop', f)) dk = [] for id in idl: if id in props: dk.append(props[id]['translit']) else: dk.append(None) return dk
def adfloats(f): floats = [] tlist = dict(map(lambda x: (x.val1, x), filter(f, pdata))) keys = tlist.keys() if tlist: q = sql.get_f('*', 'prop', sql.fin('translit', keys, True)) for row in db.fetchobj(q, keys): prop = classes.Prop(doc, row) prop.evalname(self.ctx) prop.evalnote(self.ctx) prop.para = tlist[prop.translit] floats.append(prop) return floats
def img_addcrclist(db, alist): if not alist: return lst = {} for (param, id) in alist: lst[getcrc(param)] = id crclist = lst.keys() q = sql.get_f('crc', 'mem_image_crc', sql.fin('crc', crclist, True)) crclist = db.fetchvals(q, crclist) for crc in crclist: if crc in lst: del lst[crc] q = sql.insert(['crc', 'id_image'], 'mem_image_crc') for (crc, id) in lst.iteritems(): db.execute(q, [crc, id])
def __prodhint(self, db, view, pl): doc = self.doc fields = ['p.id'] tables = [doc.tpropset] k = len(view.groups) + 1 for i in xrange(1, k): tables.append('LEFT JOIN prop p%d ON ps.id_prop%d = p%d.id' % (i, i, i)) fields.append('p%d.name AS n%d' % (i, i)) fields.append('p%d.translit AS t%d' % (i, i)) tables = ["\n ".join(tables)] tables.append(doc.tproduct) f = [sql.fin('p.id', pl.keys())] f.append("p.id = ps.id_product") f.append("ps.pview = '%s'" % view.pview) f += doc.sqlppair(self.ppair) if doc('adfilter'): f += doc('adfilter') q = sql.get_f(fields, tables, f) kparams = map(lambda k: k.translit, doc.kseries) exc = eval(doc.cat.params('EXC_%s_HINTS' % view.pview) or '[]') for row in db.fetchobj(q): hints = [] rate = 0 for prop in xrange(1, k): if prop in exc: continue s = str(prop) h = row['n' + s] p = row['t' + s] if p in kparams: rate -= 1 hints.append(h) hint = Storage() hint.name = formatname(hints[1:]) hint.rate = rate pl[row.id].hints.append(hint) sz = 3 for p in pl.itervalues(): besthints = sorted(p.hints, key = lambda h: h.rate)[:sz] besthints = map(lambda h: h.name, besthints) if len(p.hints) > sz: besthints.append('...') p.hint = " / ".join(besthints)
def nonssql(self, pids): fields = ['p.id'] tables = [self.doc.tpropset] k = len(self.groups) + 1 for i in xrange(1, k): tables.append('LEFT JOIN prop p%d ON ps.id_prop%d = p%d.id' % (i, i, i)) fields.append('p%d.name AS n%d' % (i, i)) fields.append('p%d.translit AS t%d' % (i, i)) tables = ["\n ".join(tables)] tables.append(self.doc.tproduct) f = [sql.fin('p.id', pids)] f.append("p.id = ps.id_product") f.append("ps.pview = '%s'" % self.pview) return(fields, tables, f)
def clear(self, ftext): """Очистка наличия товаров на складе перед загрузкой новых данных о наличии""" # Получение идентификаторов товаров, данные о наличии которых # будут обновлятся f = self.parsefilter(ftext) q = sql.get_f('DISTINCT s.id_product', 'store s', f) idl = db.fetchvals(q) pcnt = len(idl) if pcnt: log("Found %d products" % pcnt) else: log("No products found, nothing to clear!", M_WARN) return # Вывод 5-ти случайных товаров из того списка, данные о наличии # которых будут очищены log('----------------------------') imax = min(pcnt, 5) for i in xrange(imax): index = random.randint(0, pcnt - 1) product = Product(None, idl[index]) log("Random product (%d of %d): %s" % (i + 1, imax, real_translit(product.name))) log('----------------------------') log('%d products will be deleted from store. Continue? (y/n)' % pcnt) # Подтверждение об удалении наличия (если требуется) if self.o.prompt: res = raw_input() else: res = "y" # Очистка наличия товаров из базы if res == 'y': idl = db.fetchvals(sql.get_f('id', 'store s', f)) q = sql.delete('store', sql.fin('id', idl)) db.execute(q) db.commit() log("Store records deleted") else: log("User abort, exiting...") sys.exit(0)
def __proddata(self, db, view, pids): doc = self.doc view = doc.view0 fields = ['p.id', 'p.partno1'] tables = [doc.tpropset] k = len(view.groups) + 1 for i in xrange(1, k): tables.append('LEFT JOIN prop p%d ON ps.id_prop%d = p%d.id' % (i, i, i)) fields.append('MAX(p%d.translit) AS t%d' % (i, i)) tables = ["\n ".join(tables)] fields += ['p.name, p.note, p.price, p.price_in, p.price_out, p.currency, p.eta'] fields += ['img.id AS id_img'] tables.append(doc.tproduct + ' LEFT JOIN ' + doc.timage + ' ON p.id_image = img.id') fq = sql.get_f(['ids.id_image'], 'image_deps ids', 'ids.id_obj = p.id') fq = sql.order(fq, 'ids.id') fq = sql.limit(fq, 0, 1) fq = '(%s) AS id_img_big' % fq fields.append(fq) fstore = sql.get_f('SUM(s.quantity)', 'store s', ['s.id_product = p.id', 's.quantity > 0']) fstore = '(%s) AS stored' % fstore fields += [fstore] f = [sql.fin('p.id', pids)] f.append("p.id = ps.id_product") f.append("ps.pview = '%s'" % view.pview) q = sql.get_f(fields, tables, f) q = sql.group(q, 'p.id') pl = {} iml = [] for (key, row) in db.fetchdic(q).iteritems(): param = [] for prop in xrange(1, k): param.append(row['t' + str(prop)]) row.param = param row.smallprice = doc('list_view') == "store" p = classes.Product(doc, row) p.hints = [] p.rates = [] p.view = view pl[key] = p iml.append(p.id_img) iml.append(p.id_img_big) iml = notemptylist(iml) if iml: f = sql.fin('id', iml) q = sql.get_f(['id', 'name', 'type', 'width', 'height', 'size'], 'image', f) images = db.fetchdic(q) else: images = {} crclist = [] for p in pl.itervalues(): p.img = doc.getimage(images.get(p.id_img, None), p, p.param, crclist = crclist) p.img_big = doc.getimage(images.get(p.id_img_big, None), p, p.param, 1, crclist = crclist) img_addcrclist(db, crclist) return pl
def parsefilter(self, ftext): """Метод, преобразовывающий метаописание в набор SQL-фильтров Функция преобразует созданный по определенным правилам текстовый шаблон в фильтр SQL-запроса (where), который обнулит наличие некоторых товаров на складе. Используется для удобного описания правил в заголовках Excel и Google Doc таблиц, по которым обновляется наличие товаров """ # список строк SQL-фильтра для отбора товаров # K - компоненты (свойства), характеризующие товар. # Таких свойств может быть до 7 на каждое представление (View) товара. # Например, товар относится к категории "звезды" (k1=zvezdi), # и характеризуется некоторыми свойствами k2-k7 - цвет, размер и т.п. # Один товар может иметь несколько представлений, т.е. обладать разным # набором свойств K kfilter = [] # список строк SQL-фильтра для отбора складов товаров sfilter = [] cat = False ftext = real_translit(ftext.lower()) # Объект <группа складов> - получается из базы вызовом # функции Get Property Group By Translit - # получить группу свойств по коду свойства whgroup = db.fetchval('SELECT getpgbytr("stores")') for val in re.split(r'\,\s*', ftext): # Если в метаописании найдена инструкция по компонентному фильтру, # накладываемому для ограничения выборки товаров - расшифровать эту # инструкцию, и привести ее к виду строк SQL-фильтра if re.match(r'k\d=', val): propindex = toint(val[1:2]) if propindex == 1: cat = True propname = val[3:] propt = real_translit(propname) prop = db.fetchobject('prop', propt, 'translit') if prop: log("FILTER [K%d], ID %d = %s" % (propindex, prop.id, translit(propname))) else: raise Exception("Property %s not found" % translit(propname)) kfilter.append('ps.id_prop%d = %s' % (propindex, prop.id)) # Если в метаописании найдена инструкция по очистке единиц хранения # товара перед загрузкой новых товаров - добавить ее в фильтр, # ограничивающий выбор товаров elif re.match(r'clear=', val): slist = [] for store in re.split(r';\s*', val[6:]): slist.append('translit RLIKE "%s"' % store) f = [sql.f_or(slist), 'id_group = %s' % whgroup] q = sql.get_f('id', 'prop', f) sfilter = db.fetchvals(q) # Если в метаописании найдена инструкция склада по умолчанию, # то установить склад по умолчанию elif re.match(r'default=', val): t = real_translit(val[8:]) self.whdef = db.fetchobject('prop', t, 'translit') # Ограничить список товаров их главным представлением kfilter.append('ps.pview = "%s"' % gvar.view.pview) if not cat: kfilter.append('ps.id_prop1 = %s' % gvar.cat.id) # Список строк итогового SQL-фильтра f = [] # Если есть ограничение по складам товаров - добавить его if sfilter: f.append(sql.fin('s.id_store', sfilter)) # Если есть ограничение по компонентному фильтру - добавить его if kfilter: q = sql.get_f('ps.id', 'prop_set ps', kfilter + ['ps.id_product = s.id_product']) f.append(sql.exists(q)) self.kfilter = kfilter return f