def mod_tag(self, guid, name=None, type=None, valuetype=None): cmd = u"MTG" + _uniw(guid) for init, field in ((u" N", name), (u" T", type), (u" V", valuetype)): if field: cmd += init + _uniw(field) self._writeline(cmd) res = self._readline() if res != u"OK": raise ResponseError(res)
def add_tag(self, name, type=None, guid=None, valuetype=None): cmd = u"ATN" + _uniw(name) if type: cmd += u" T" + _uniw(type) if guid: cmd += u" G" + _uniw(guid) if valuetype: cmd += u" V" + _uniw(valuetype) self._writeline(cmd) res = self._readline() if res != u"OK": raise ResponseError(res)
def _tag2spec(self, t, value_allowed=True): if type(t) in (tuple, list): assert len(t) in (2, 3) g = _uniw(t[0]) if t[-1] is None: return g assert value_allowed if len(t) == 2: return g + u"=" + t[1].format() else: return g + t[1] + t[2].format() else: return _uniw(t)
def modify_post(self, md5, **kwargs): fspec = self._fieldspec(**kwargs) if fspec: cmd = u"MP" + _uniw(md5) + fspec self._writeline(cmd) res = self._readline() if res != u"OK": raise ResponseError(res)
def post_rels(self, md5): cmd = u"RS" + _uniw(md5) self._writeline(cmd) rels = {} while not self._parse_rels(self._readline(), rels): pass if not md5 in rels: return None return rels[md5]
def add_post(self, md5, **kwargs): cmd = u"AP" + _uniw(md5) assert "width" in kwargs assert "height" in kwargs assert "ext" in kwargs cmd += self._fieldspec(**kwargs) self._writeline(cmd) res = self._readline() if res != u"OK": raise ResponseError(res)
def get_post(self, md5, separate_implied=False, wanted=None): if wanted is None: wanted = ["tagname", "tagguid", "tagdata", "datatags", "ext", "created", "width", "height"] if separate_implied and "implied" not in wanted: wanted = ["implied"] + wanted search = u"SPM" + _uniw(md5) + " F".join([""] + self._filter_wanted(wanted)) posts = self._search_post(search, wanted) if not posts: return None assert posts[0].md5 == md5 return posts[0]
def metalist(self, name): cmd = u"L" + _uniw(name) self._writeline(cmd) res = self._readline() names = [] while res != u"OK": if res[:2] != u"RN": raise ResponseError(res) names.append(res[2:]) res = self._readline() return names
def find_tags(self, matchtype, name, range=None, order=None, flags=None, **kw): if kw: filter = self._build_search(**kw) if filter: filter = u" :" + filter else: filter = u"" matchtype = _uniw(matchtype) name = _uniw(name) cmd = [u"ST", matchtype, name] for o in self._list(order, _uniw): cmd.append(u" O" + o) for f in self._list(flags, _uniw): cmd.append(u" F" + f) if range is not None: assert len(range) == 2 cmd.append(u" R%x:%x" % tuple(range)) cmd.append(filter) self._writeline(u"".join(cmd)) tags = [] while self._parse_tagres(tags): pass return tags
def _find_tag(self, matchtype, name, with_prefix): name = _uniw(name) if with_prefix and name[0] in u"~-!": prefix = name[0] name = name[1:] else: prefix = u"" tags = self.find_tags(matchtype, name) if not tags: return None assert len(tags) == 1 tag = tags[0] tag.pname = prefix + tag.name tag.pguid = prefix + tag.guid return tag
def _addrem_implies(self, addrem, set_tag, implied_tag, datastr, filter, value=None): set_tag = self._tag2spec(set_tag) implied_tag = self._tag2spec(implied_tag) assert u" " not in set_tag assert u" " not in implied_tag if implied_tag[0] == u"-": add = u" i" + implied_tag[1:] else: add = u" I" + implied_tag if filter: assert isinstance(filter, tuple) and len(filter) == 2 filter = _uniw(filter[0]) + filter[1].format() assert u" " not in filter set_tag += filter if value: datastr += " V" + value.format() cmd = u"I" + addrem + set_tag + add + datastr self._writeline(cmd) res = self._readline() if res != u"OK": raise ResponseError(res)
def tag_post(self, md5, full_tags=None, weak_tags=None, remove_tags=None): tags = self._list(full_tags, lambda s: u" T" + self._tag2spec(s)) tags += self._list(weak_tags, lambda s: u" T~" + self._tag2spec(s)) tags += self._list(remove_tags, lambda s: u" t" + self._tag2spec(s, False)) init = u"TP" + _uniw(md5) cmd = [init] clen = len(init) for tag in tags: assert u" " not in tag[1:] clen += len(tag.encode("utf-8")) if clen >= self._prot_max_len: self._writeline(u"".join(cmd)) res = self._readline() if res != u"OK": raise ResponseError(res) cmd = [init] clen = len(init) + len(tag.encode("utf-8")) cmd.append(tag) if len(cmd) > 1: self._writeline(u"".join(cmd)) res = self._readline() if res != u"OK": raise ResponseError(res)
def order(self, tag, posts): init = u"OG" + _uniw(tag) cmd = [init] dolen = 2 clen = len(init) for post in map(_uniw, posts): post = u" P" + post cmd.append(post) clen += len(post.encode("utf-8")) if clen >= self._prot_max_len - 35: self._writeline(u"".join(cmd)) res = self._readline() if res != u"OK": raise ResponseError(res) # Overlap one, so previous ordering doesn't mess us up. cmd = [init, post] dolen = 3 clen = len(init) + len(post.encode("utf-8")) if len(cmd) >= dolen: self._writeline(u"".join(cmd)) res = self._readline() if res != u"OK": raise ResponseError(res)
def tag_implies(self, tag, reverse=False): tag = _uniw(tag) cmd = u"IR" if reverse else u"IS" self._writeline(cmd + tag) data = {} while self._parse_implies(data): pass if reverse: rev = [] for itag in data: for impl in data[itag]: assert len(impl) >= 2 ttag = impl[0] if ttag[0] == "-": assert ttag[1:] == tag rev.append(impl._replace(guid="-" + itag)) else: assert ttag == tag rev.append(impl._replace(guid=itag)) return rev if tag in data: return data[tag] return []
def _p_date(val): if isinstance(val, basestring): return _uniw(val) return val.format()
def pngthumb_path(self, md5, ft, size): fn = _uniw(md5) + u"." + _uniw(ft) md5 = hashlib.md5(fn.encode("utf-8")).hexdigest() return os.path.join(self.cfg.thumb_base, str(size), md5[0], md5[1:3], md5)
def delete_post(self, md5): assert " " not in md5 cmd = u"DP" + _uniw(md5) self._writeline(cmd) res = self._readline() if res != u"OK": raise ResponseError(res)
def _fieldspec(self, **kwargs): f = [_uniw(f) + u"=" + _field_cparser[f](kwargs[f]) for f in kwargs] if not f: return u"" return u" ".join([u""] + f)
def add_alias(self, name, origin_guid): cmd = u"AAG" + _uniw(origin_guid) + u" N" + _uniw(name) self._writeline(cmd) res = self._readline() if res != u"OK": raise ResponseError(res)
def remove_alias(self, name): cmd = u"DAN" + _uniw(name) self._writeline(cmd) res = self._readline() if res != u"OK": raise ResponseError(res)
def merge_tags(self, into_t, from_t): cmd = u"MTG" + _uniw(into_t) + u" M" + _uniw(from_t) self._writeline(cmd) res = self._readline() if res != u"OK": raise ResponseError(res)