Best Python code snippet using playwright-python
vcs.py
Source:vcs.py  
...736        else:737            self.lines += event.lines738    def event_del_cb(self, exe, event):739        if callable(self.done_cb):740            self.done_cb(self.lines, (event.exit_code == 0), *self.args)741class GitCmdRAW(Exe):742    def __init__(self, local_path, cmd, done_cb=None, line_cb=None, *args):743        self.local_path = local_path744        self.done_cb = done_cb745        self.line_cb = line_cb746        self.args = args747        if options.review_git_commands and \748           cmd.startswith(CMD_TO_REVIEW) and not cmd.startswith(CMD_TO_EXCLUDE):749            CmdReviewDialog(cmd, self.start)750        else:751            self.start(cmd)752    753    def start(self, cmd):754        if self.local_path:755            git_dir = os.path.join(self.local_path, '.git')756            real_cmd = 'git --git-dir="%s" --work-tree="%s" %s' % \757                       (git_dir, self.local_path, cmd)758        else:759            real_cmd = 'git %s' % (cmd)760        print("=== GIT " + cmd) # just for debug761        Exe.__init__(self, real_cmd,762                     ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR)763        self.on_data_event_add(self.event_data_cb)764        self.on_error_event_add(self.event_data_cb)765        self.on_del_event_add(self.event_del_cb)766        767    def event_data_cb(self, exe, event):768        p1 = p2 = 0769        for c in event.data:770            if c == '\n' or c == '\r':771                self.line_cb(event.data[p1:p2].strip(), c)772                p1 = p2773            p2 += 1774        if p1 != p2-1:775            self.line_cb(event.data[p1:p2].strip(), None)776    777    def event_del_cb(self, exe, event):778        if callable(self.done_cb):779            self.done_cb((event.exit_code == 0), *self.args)780def git_clone(done_cb, progress_cb, url, folder, shallow=False):781    """782    Clone the given url in the given folder783    Args:784        done_cb:785            Function to call when the operation finish.786            signature: cb(success, repo_folder)787        progress_cb:788            Function to call on each line of output.789            signature: cb(line)790        url:791            Path or url to clone792        folder:793            The folder to clone into (must be empty)794        shallow:795            If True than no history will be cloned796    """797    def _cmd_done_cb(success):798        done_cb(success, folder)799    cmd = 'clone -v --progress %s %s "%s"' % ('--depth 1' if shallow else '',800                                              url, folder)801    GitCmdRAW(None, cmd, _cmd_done_cb, progress_cb)802class GitBackend(Repository):803    def __init__(self):804        self._url = ""805        self._name = ""806        self._description = ""807        self._status = None808        self._branches = []809        self._remote_branches = []810        self._tags = []811        self._remotes = []812        self._stash = []813    def check_url(self, url):814        if url and os.path.isdir(os.path.join(url, '.git')):815            return True816        return False817    def load_from_url(self, url, done_cb, *args):818        if url.endswith(os.sep):819            url = url[:-len(os.sep)]820        self._url = url821        self._name = self._url.split(os.sep)[-1]822        desc_file = os.path.join(self._url, '.git', 'description')823        self._description = file_get_contents(desc_file)824        if self._description.startswith('Unnamed repository'):825            self._description = ''826        os.chdir(url) # to make git diff works :/827        self.refresh(done_cb, *args)828    def refresh(self, done_cb, *args):829        """ Async implementation, all commands spawned at the same time """830        print('\n======== Refreshing repo =========================')831        startup_time = time.time()832        833        self._status = Status()834        sha = open(os.path.join(self._url,'.git','HEAD')).read().strip()835        self._status.head_to_commit = sha836        def _multi_done_cb(success, *args):837            self._op_count -= 1838            if self._op_count == 0:839                print('======== Refresh done in %.3f seconds ===========\n' % \840                      (time.time() - startup_time))841                done_cb(True, *args)842        self._op_count = 6843        self._fetch_status(_multi_done_cb, *args)844        self._fetch_status_text(_multi_done_cb, *args)845        self._fetch_branches_and_tags(_multi_done_cb, *args)846        self._fetch_local_config(_multi_done_cb, *args)847        self._fetch_head_tag(_multi_done_cb, *args)848        self._fetch_stash(_multi_done_cb, *args)849    """850    def refresh(self, done_cb, *args):851        "" Sync implementation, one command after the other ""852        print('\n======== Refreshing repo =========================')853        startup_time = time.time()854        ops = [self._fetch_status, self._fetch_status_text,855               self._fetch_branches_and_tags, self._fetch_local_config,856               self._fetch_stash]857        self._status = Status()858        def _multi_done_cb(success):859            if len(ops) > 0:860                func = ops.pop(0)861                func(_multi_done_cb)862            else:863                print('======== Refresh done in %.3f seconds ===========\n' % \864                      (time.time() - startup_time))865                done_cb(True, *args)866        _multi_done_cb(True)867    """868    def _fetch_status(self, done_cb, *args):869        def _cmd_done_cb(lines, success):870            if len(lines) < 1 or not lines[0].startswith('## '):871                done_cb(False)872                return873            # parse the first line (branch info)874            # ex: "## master"875            # ex: "## master...origin/master"876            # ex  "## master...origin/master [ahead 1]"877            # ex: "## HEAD (nessun branch)"878            line = lines.pop(0)[3:]879            if line.startswith('HEAD'):880                self._status.head_detached = True881            elif '[ahead' in line:882                self._status.ahead = int(line.split('[ahead')[1][:-1])883            elif '[behind' in line:884                self._status.behind = int(line.split('[behind')[1][:-1])885            # parse the list of changed files886            for line in lines:887                fname = line[3:]888                if line[0] == '?':   # untracked (added not staged)889                    self._status.changes[fname] = ('?', False, fname, None)890                elif line[0] == 'A': # added and staged891                    self._status.changes[fname] = ('A', True, fname, None)892                elif line[0] == 'D': # deleted and staged893                    self._status.changes[fname] = ('D', True, fname, None)894                elif line[1] == 'D': # deleted not staged895                    self._status.changes[fname] = ('D', False, fname, None)896                elif line[0] == 'M': # modified and staged897                    self._status.changes[fname] = ('M', True, fname, None)898                elif line[1] == 'M': # modified not staged899                    self._status.changes[fname] = ('M', False, fname, None)900                elif line[0] == 'U': # unmerged901                    self._status.changes[fname] = ('U', False, fname, None)902                elif line[0] == 'R': # renamed903                    name, new_name = fname.split(' -> ')904                    self._status.changes[name] = ('R', True, name, new_name)905            # special statuses906            self._status.is_merging = \907                os.path.exists(os.path.join(self._url, '.git', 'MERGE_HEAD'))908            self._status.is_cherry = \909                os.path.exists(os.path.join(self._url, '.git', 'CHERRY_PICK_HEAD'))910            self._status.is_reverting = \911                os.path.exists(os.path.join(self._url, '.git', 'REVERT_HEAD'))912            self._status.is_bisecting = \913                os.path.exists(os.path.join(self._url, '.git', 'BISECT_LOG'))914            done_cb(success, *args)915        GitCmd(self._url, 'status --porcelain -b -u', done_cb=_cmd_done_cb)916    def _fetch_status_text(self, done_cb, *args):917        def _cmd_done_cb(lines, success):918            self._status.textual = '<br>'.join(lines)919            done_cb(success, *args)920        GitCmd(self._url, 'status', done_cb=_cmd_done_cb)921    def _fetch_head_tag(self, done_cb, *args):922        def _cmd_done_cb(lines, success):923            if success:924                self._status.head_to_tag = lines[0]925            done_cb(success, *args)926        cmd = 'describe --tags --exact-match HEAD'927        GitCmd(self._url, cmd, done_cb=_cmd_done_cb)928    def _fetch_branches_and_tags(self, done_cb, *args):929        def _cmd_line_cb(line):930            objtype, head, refname, upstream = line.split('|')931            # tags932            if refname.startswith('refs/tags/'):933                self._tags.append(Tag(refname))934            # local branches935            elif refname.startswith('refs/heads/'):936                bname = refname[11:] # remove 'refs/heads/'937                b = Branch(refname, bname, is_current=(head == '*'))938                if upstream:939                    split = upstream.split('/')940                    b.remote = split[2]941                    b.remote_branch = '/'.join(split[3:])942                if b.is_current:943                    self.status.current_branch = b944                self._branches.append(b)945            # remote branches946            elif refname.startswith('refs/remotes'):947                self._remote_branches.append(refname[13:]) # remove'refs/remotes/'948        def _cmd_done_cb(lines, success):949            done_cb(success, *args)950        del self._branches[:]951        del self._remote_branches[:]952        del self._tags[:]953        del self._stash[:]954        cmd = 'for-each-ref --format="%(objecttype)|%(HEAD)|%(refname)|%(upstream)"'955        GitCmd(self._url, cmd, _cmd_done_cb, _cmd_line_cb)956    def _fetch_stash(self, done_cb, *args):957        def _cmd_line_cb(line):958            self._stash.append(StashItem(*line.split('|')))# sha, ref, desc, ts959        def _cmd_done_cb(lines, success):960            done_cb(success, *args)961        cmd = 'stash list --format="%H|%gd|%gs|%ct|%an|%ae"'962        GitCmd(self._url, cmd, _cmd_done_cb, _cmd_line_cb)963    def _fetch_local_config(self, done_cb, *args):964        def _cmd_done_cb(lines, success):965            for line in lines:966                key, val = line.split(' ', 1)967                key, name, prop = key.split('.')968                if key == 'remote':969                    r = self.remote_get_by_name(name) 970                    if not r:971                        r = Remote(name)972                        self._remotes.append(r)973                    if prop in ('url', 'fetch'):974                        setattr(r, prop, val)975            done_cb(success, *args)976        del self._remotes[:]977        cmd = 'config --local --get-regexp "remote."'978        GitCmd(self._url, cmd, _cmd_done_cb)979    @property980    def url(self):981        return self._url982    @property983    def name(self):984        return self._name985    # name_set(self, name, done_cb, *args) not implemented986    @property987    def description(self):988        return self._description989    def description_set(self, description, done_cb, *args):990        desc_file = os.path.join(self._url, '.git', 'description')991        if file_put_contents(desc_file, description) is True:992            self._description = description993            done_cb(True, *args)994        else:995            done_cb(False, *args)996    @property997    def status(self):998        return self._status999    def checkout(self, done_cb, ref, *args):1000        def _cmd_done_cb(lines, success):1001            if success:1002                self.refresh(done_cb, *args)1003            else:1004                done_cb(success, '\n'.join(lines))1005        cmd = "checkout %s" % (ref)1006        GitCmd(self._url, cmd, _cmd_done_cb)1007    @property1008    def branches(self):1009        return self._branches1010    @property1011    def remote_branches(self):1012        return self._remote_branches1013    @property1014    def tags(self):1015        return self._tags1016    @property1017    def stash(self):1018        return self._stash1019    def request_commits(self, done_cb, prog_cb, ref1=None, ref2=None,1020                        max_count=0, skip=0):1021        def _cmd_done_cb(lines, success, lines_buf):1022            if success:1023                done_cb(success)1024            else:1025                done_cb(success, '\n'.join(lines_buf))1026        def _cmd_line_cb(line, lines_buf):1027            lines_buf.append(line)1028            if line and line[-1] == chr(0x03):1029                _parse_commit('\n'.join(lines_buf)[:-1])1030                del lines_buf[:]1031        def _parse_commit(buf):1032            c = Commit()1033            (c.sha, c.parents, c.author, c.author_email, c.committer,1034             c.committer_email,c.commit_date, 1035             c.title, c.message, refs) = buf.split(chr(0x00))1036            if c.parents:1037                c.parents = c.parents.split(' ')1038            if c.commit_date:1039                c.commit_date = datetime.fromtimestamp(int(c.commit_date))1040            if refs:1041                refs = refs.strip().strip(')(').split(', ')1042                for ref in refs:1043                    if ref.startswith('tag: refs/tags/'):1044                        c.tags.append(ref[15:])1045                    elif ref.startswith('refs/tags/'):1046                        c.tags.append(ref[10:])1047                    elif ref == 'HEAD':1048                        c.heads.append(ref)1049                    elif ref.startswith(('refs/heads/')):1050                        c.heads.append(ref[11:])1051                    elif ref.startswith('refs/remotes/'):1052                        c.remotes.append(ref[13:])1053                    else:1054                        c.heads.append(ref) # TODO REMOVE ME1055                        LOG("UNKNOWN REF: %s" % ref)1056            prog_cb(c)1057        # fmt = 'format:{"sha":"%H", "parents":"%P", 1058        #                "author":"%an", "author_email":"%ae",1059        #                "committer":"%cn", "committer_email":"%ce", 1060        #                "commit_ts":%ct, "title":"%s",1061        #                "body": "%b", "refs":"%d"}'1062        # Use ascii char 00 as field separator and char 03 as commits separator1063        fmt = '%x00'.join(('%H','%P','%an','%ae','%cn','%ce','%ct','%s','%b','%d')) + '%x03'1064        cmd = "log --pretty='tformat:%s' --decorate=full" % (fmt)1065        if ref1 and ref2:1066            cmd += ' %s..%s' % (ref1, ref2)1067        elif ref1:1068            cmd += ' %s' % ref11069        else:1070            cmd += ' --all'1071            1072        if max_count > 0: cmd += ' --max-count %d' % max_count1073        if skip > 0: cmd += ' --skip %d' % skip1074        GitCmd(self._url, cmd, _cmd_done_cb, _cmd_line_cb, list())1075    def request_diff(self, done_cb, prog_cb=None, ref1=None, ref2=None,1076                     path=None, only_staged=False, revert=False, compare=False):1077        cmd = 'diff --no-prefix'1078        if only_staged:1079            cmd += ' --staged'1080        if ref2 and ref1:1081            if compare:1082                cmd += ' %s...%s' % (ref1, ref2)1083            else:1084                cmd += ' %s..%s' % (ref1, ref2)1085        elif revert and ref1:1086            cmd += ' %s..%s^' % (ref1, ref1)1087        elif ref1:1088            cmd += ' %s^..%s' % (ref1, ref1)1089        else:1090            cmd += ' HEAD'1091        if path is not None:1092            cmd += " -- '%s'" % path1093        GitCmd(self._url, cmd, done_cb, prog_cb)1094    def request_changes(self, done_cb, commit1=None, commit2=None):1095        def _cmd_done_cb(lines, success):1096            L = []1097            for line in lines:1098                split = line.split('\t')1099                if line[0] == 'R':1100                    L.append(('R', split[1], split[2]))1101                else:1102                    L.append((split[0], split[1], None))1103            # A: addition of a file1104            # C: copy of a file into a new one1105            # D: deletion of a file1106            # M: modification of the contents or mode of a file1107            # R: renaming of a file1108            # T: change in the type of the file1109            # U: file is unmerged (you must complete the merge before it can be committed)1110            # X: "unknown" change type (most probably a bug, please report it)1111            # TODO handle unmerged ??1112            done_cb(success, L)1113        cmd = 'diff --name-status --find-renames'1114        if commit2 and commit2.sha and commit1 and commit1.sha:1115            cmd += ' %s %s' % (commit1.sha, commit2.sha)1116        elif commit1 is not None and commit1.sha:1117            cmd += ' %s^ %s' % (commit1.sha, commit1.sha)1118        else:1119            cmd += ' HEAD'1120        GitCmd(self._url, cmd, _cmd_done_cb)1121    @property1122    def remotes(self):1123        return self._remotes1124    def remote_get_by_name(self, name):1125        for r in self._remotes:1126            if r.name == name:1127                return r1128    def request_remote_info(self, done_cb, remote_name):1129        def _cmd_done_cb(lines, success):1130            if success:1131                done_cb(success, '\n'.join(lines))1132            else:1133                done_cb(success, None, '\n'.join(lines))1134        cmd = 'remote show %s' % remote_name1135        GitCmd(self._url, cmd, _cmd_done_cb)1136    def remote_add(self, done_cb, name, url):1137        def _cmd_done_cb(lines, success):1138            self._fetch_local_config(done_cb)1139        cmd = 'remote add %s %s' % (name, url)1140        GitCmd(self._url, cmd, _cmd_done_cb)1141    def remote_del(self, done_cb, name):1142        def _cmd_done_cb(lines, success):1143            self._fetch_local_config(done_cb)1144        cmd = 'remote remove %s' % (name)1145        GitCmd(self._url, cmd, _cmd_done_cb)1146    def remote_url_set(self, done_cb, name, new_url):1147        def _cmd_done_cb(lines, success):1148            self._fetch_local_config(done_cb)1149        cmd = 'remote set-url %s %s' % (name, new_url)1150        GitCmd(self._url, cmd, _cmd_done_cb)1151    def stage_file(self, done_cb, path, *args):1152        def _cmd_done_cb(lines, success):1153            self.refresh(done_cb, *args)1154        _mod, _staged, _path, _new = self._status.changes[path]1155        cmd = '%s "%s"' % ('rm' if _mod == 'D' else 'add', path)1156        GitCmd(self._url, cmd, _cmd_done_cb)1157    def unstage_file(self, done_cb, path, *args):1158        def _cmd_done_cb(lines, success):1159            self.refresh(done_cb, *args)1160        cmd = 'reset HEAD "%s"' % path1161        GitCmd(self._url, cmd, _cmd_done_cb)1162    def commit(self, done_cb, msg):1163        def _cmd_done_cb(lines, success):1164            if success:1165                self.refresh(done_cb)1166            else:1167                done_cb(success, '\n'.join(lines))1168        cmd = 'commit -m "{}"'.format(msg.replace('"', '\\"'))1169        GitCmd(self._url, cmd, _cmd_done_cb)1170    def revert(self, done_cb, commit, auto_commit=False, commit_msg=None):1171        def _cmd_done_cb(lines, success):1172            if success and auto_commit:1173                self.commit(done_cb, commit_msg)1174            elif success:1175                self.refresh(done_cb)1176            else:1177                done_cb(success, '\n'.join(lines))1178        cmd = 'revert --no-edit --no-commit %s' % commit.sha1179        GitCmd(self._url, cmd, _cmd_done_cb)1180    def cherrypick(self, done_cb, commit, auto_commit=False, commit_msg=None):1181        def _cmd_done_cb(lines, success):1182            if success and auto_commit:1183                self.commit(done_cb, commit_msg)1184            elif success:1185                self.refresh(done_cb)1186            else:1187                done_cb(success, '\n'.join(lines))1188        cmd = 'cherry-pick --no-commit %s' % commit.sha1189        GitCmd(self._url, cmd, _cmd_done_cb)1190    def discard(self, done_cb, files=[]):1191        def _cmd_done_cb(lines, success):1192            if success:1193                self.refresh(done_cb)1194            else:1195                done_cb(success, '\n'.join(lines))1196        if files:1197            cmd = 'checkout %s' % (' '.join(files))1198        else:1199            cmd = 'reset --hard HEAD'1200        GitCmd(self._url, cmd, _cmd_done_cb)1201    def pull(self, done_cb, progress_cb, remote, rbranch, lbranch):1202        cmd = 'pull -v --progress %s %s:%s' % (remote, rbranch, lbranch)1203        GitCmdRAW(self._url, cmd, done_cb, progress_cb)1204    def push(self, done_cb, progress_cb, remote, rbranch, lbranch, dry=False):1205        cmd = 'push -v --progress %s %s %s:%s ' % ('--dry-run' if dry else '',1206                                                   remote, lbranch, rbranch)1207        GitCmdRAW(self._url, cmd, done_cb, progress_cb)1208    def branch_create(self, done_cb, name, revision, track=False):1209        def _cmd_done_cb(lines, success):1210            if success:1211                self.refresh(done_cb)1212            else:1213                done_cb(success, '\n'.join(lines))1214        track = '--track' if track else '--no-track'1215        cmd = 'branch %s %s %s' % (track, name, revision)1216        GitCmd(self._url, cmd, _cmd_done_cb)1217    def branch_delete(self, done_cb, name, force=False):1218        def _cmd_done_cb(lines, success):1219            if success:1220                self.refresh(done_cb)1221            else:1222                done_cb(success, '\n'.join(lines))1223        cmd = 'branch %s %s' % ('-D' if force else '-d', name)1224        GitCmd(self._url, cmd, _cmd_done_cb)1225    def branch_merge(self, done_cb, name, fast_forward):1226        def _cmd_done_cb(lines, success):1227            if success:1228                self.refresh(done_cb)1229            else:1230                done_cb(success, '\n'.join(lines))1231        cmd = 'merge --no-commit --%s %s' % (fast_forward, name)1232        GitCmd(self._url, cmd, _cmd_done_cb)1233    def tag_delete(self, done_cb, name):1234        def _cmd_done_cb(lines, success):1235            if success:1236                self.refresh(done_cb)1237            else:1238                done_cb(success, '\n'.join(lines))1239        GitCmd(self._url, 'tag --delete "%s"' % name, _cmd_done_cb)1240    def tag_create(self, done_cb, name, annotated=True, msg=None):1241        def _cmd_done_cb(lines, success):1242            if success:1243                self.refresh(done_cb)1244            else:1245                done_cb(success, '\n'.join(lines))1246        if annotated:1247            cmd = 'tag -a "%s" -m "%s"' % (name, msg)1248        else:1249            cmd = 'tag "%s"' % (name)1250        GitCmd(self._url, cmd, _cmd_done_cb)1251    def _common_done_cb(self, lines, success, user_cb):1252        if success:1253            self.refresh(user_cb)1254        else:1255            user_cb(success, '\n'.join(lines))1256    def stash_save(self, done_cb, msg=None, include_untracked=False):1257        cmd = 'stash save %s %s' % (1258              '--include-untracked' if include_untracked else '', msg or '')1259        GitCmd(self._url, cmd, self._common_done_cb, None, done_cb)1260    def stash_clear(self, done_cb):1261        GitCmd(self._url, 'stash clear', self._common_done_cb, None, done_cb)1262    def stash_request_diff(self, done_cb, stash_item):1263        cmd = 'stash show -p "%s"' % stash_item.ref1264        GitCmd(self._url, cmd, done_cb)1265    def stash_drop(self, done_cb, stash_item):...address_book.py
Source:address_book.py  
1# -*- coding: utf-8 -*-2#3# Copyright (C) 2006-2007 Ali Sabil <ali.sabil@gmail.com>4# Copyright (C) 2007-2008 Johann Prieur <johann.prieur@gmail.com>5# Copyright (C) 2007 Ole André Vadla Ravnås <oleavr@gmail.com>6#7# This program is free software; you can redistribute it and/or modify8# it under the terms of the GNU General Public License as published by9# the Free Software Foundation; either version 2 of the License, or10# (at your option) any later version.11#12# This program is distributed in the hope that it will be useful,13# but WITHOUT ANY WARRANTY; without even the implied warranty of14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the15# GNU General Public License for more details.16#17# You should have received a copy of the GNU General Public License18# along with this program; if not, write to the Free Software19# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA20#21import ab22import sharing23import scenario24import papyon25import papyon.profile as profile26from papyon.profile import Membership, NetworkID, Contact27from papyon.util.decorator import rw_property28from papyon.profile import ContactType29from papyon.service.AddressBook.constants import *30from papyon.service.description.AB.constants import *31from papyon.service.AddressBook.scenario.contacts import *32from papyon.util.async import run33import gobject34import logging35logger = logging.getLogger('papyon.service.address_book')36__all__ = ['AddressBook', 'AddressBookState']37class AddressBookStorage(set):38    def __init__(self, initial_set=()):39        set.__init__(self, initial_set)40    def __repr__(self):41        return "AddressBook : %d contact(s)" % len(self)42    def __getitem__(self, key):43        i = 044        for contact in self:45            if i == key:46                return contact47            i += 148        raise IndexError("Index out of range")49    def __getattr__(self, name):50        if name.startswith("search_by_"):51            field = name[10:]52            def search_by_func(criteria):53                return self.search_by(field, criteria)54            search_by_func.__name__ = name55            return search_by_func56        elif name.startswith("group_by_"):57            field = name[9:]58            def group_by_func():59                return self.group_by(field)60            group_by_func.__name__ = name61            return group_by_func62        else:63            raise AttributeError, name64    def search_by_memberships(self, memberships):65        result = []66        for contact in self:67            if contact.is_member(memberships):68                result.append(contact)69                # Do not break here, as the account70                # might exist in multiple networks71        return AddressBookStorage(result)72    def search_by_groups(self, *groups):73        result = []74        groups = set(groups)75        for contact in self:76            if groups <= contact.groups:77                result.append(contact)78        return AddressBookStorage(result)79    def group_by_group(self):80        result = {}81        for contact in self:82            groups = contact.groups83            for group in groups:84                if group not in result:85                    result[group] = set()86                result[group].add(contact)87        return result88    def search_by_predicate(self, predicate):89        result = []90        for contact in self:91            if predicate(contact):92                result.append(contact)93        return AddressBookStorage(result)94    def search_by(self, field, value):95        result = []96        if isinstance(value, basestring):97            value = value.lower()98        for contact in self:99            contact_field_value = getattr(contact, field)100            if isinstance(contact_field_value, basestring):101                contact_field_value = contact_field_value.lower()102            if contact_field_value == value:103                result.append(contact)104                # Do not break here, as the account105                # might exist in multiple networks106        return AddressBookStorage(result)107    def group_by(self, field):108        result = {}109        for contact in self:110            value = getattr(contact, field)111            if value not in result:112                result[value] = AddressBookStorage()113            result[value].add(contact)114        return result115class AddressBook(gobject.GObject):116    __gsignals__ = {117            "error" : (gobject.SIGNAL_RUN_FIRST,118                gobject.TYPE_NONE,119                (object,)),120            "sync"  : (gobject.SIGNAL_RUN_FIRST,121                gobject.TYPE_NONE,122                ()),123            "contact-added"           : (gobject.SIGNAL_RUN_FIRST,124                gobject.TYPE_NONE,125                (object,)),126            "messenger-contact-added" : (gobject.SIGNAL_RUN_FIRST,127                gobject.TYPE_NONE,128                (object,)),129            "contact-pending"         : (gobject.SIGNAL_RUN_FIRST,130                gobject.TYPE_NONE,131                 (object,)),132            "contact-deleted"         : (gobject.SIGNAL_RUN_FIRST,133                gobject.TYPE_NONE,134                 (object,)),135            # FIXME: those signals will be removed in the future and will be136            # moved to profile.Contact137            "contact-accepted"         : (gobject.SIGNAL_RUN_FIRST,138                gobject.TYPE_NONE,139                (object,)),140            "contact-rejected"       : (gobject.SIGNAL_RUN_FIRST,141                gobject.TYPE_NONE,142                (object,)),143            "contact-blocked"         : (gobject.SIGNAL_RUN_FIRST,144                gobject.TYPE_NONE,145                (object,)),146            "contact-unblocked"       : (gobject.SIGNAL_RUN_FIRST,147                gobject.TYPE_NONE,148                (object,)),149            "contact-allowed"         : (gobject.SIGNAL_RUN_FIRST,150                gobject.TYPE_NONE,151                (object,)),152            "contact-disallowed"      : (gobject.SIGNAL_RUN_FIRST,153                gobject.TYPE_NONE,154                (object,)),155            "group-added"             : (gobject.SIGNAL_RUN_FIRST,156                gobject.TYPE_NONE,157                (object,)),158            "group-deleted"           : (gobject.SIGNAL_RUN_FIRST,159                gobject.TYPE_NONE,160                (object,)),161            "group-renamed"           : (gobject.SIGNAL_RUN_FIRST,162                gobject.TYPE_NONE,163                (object,)),164            "group-contact-added"     : (gobject.SIGNAL_RUN_FIRST,165                gobject.TYPE_NONE,166                (object, object)),167            "group-contact-deleted"   : (gobject.SIGNAL_RUN_FIRST,168                gobject.TYPE_NONE,169                (object, object))170            }171    __gproperties__ = {172        "state":  (gobject.TYPE_INT,173                   "State",174                   "The state of the addressbook.",175                   0, 2, AddressBookState.NOT_SYNCHRONIZED,176                   gobject.PARAM_READABLE)177        }178    def __init__(self, sso, client, proxies=None):179        """The address book object."""180        gobject.GObject.__init__(self)181        self.__frozen = 0182        self.__signal_queue = []183        self._ab = ab.AB(sso, client, proxies)184        self._sharing = sharing.Sharing(sso, proxies)185        self._client = client186        self.__state = AddressBookState.NOT_SYNCHRONIZED187        self.groups = set()188        self.contacts = AddressBookStorage()189        self._profile = None190        self.connect_after('contact-deleted', lambda self, contact: contact._reset())191    # Properties192    @property193    def state(self):194        return self.__state195    @rw_property196    def _state():197        def fget(self):198            return self.__state199        def fset(self, state):200            self.__state = state201            self.notify("state")202        return locals()203    @property204    def profile(self):205        return self._profile206    def sync(self, delta_only=False, done_cb=None):207        # Avoid race conditions.208        if self._state in \209        (AddressBookState.INITIAL_SYNC, AddressBookState.RESYNC):210            return211        if self._state == AddressBookState.NOT_SYNCHRONIZED:212            self._state = AddressBookState.INITIAL_SYNC213        else:214            self._state = AddressBookState.RESYNC215        def callback(ab_storage, memberships):216            self.__log_sync_request(ab_storage, memberships)217            self.__freeze_address_book()218            self.__update_address_book(ab_storage)219            self.__update_memberships(memberships)220            self.__unfreeze_address_book()221            self._state = AddressBookState.SYNCHRONIZED222            self.__common_callback('sync', done_cb)223        sc = scenario.SyncScenario(self._ab, self._sharing,224                (callback,),225                (self.__common_errback,),226                delta_only)227        sc()228    # Public API229    def search_contact(self, account, network_id):230        if account.lower() == self._client.profile.account.lower() and \231                network_id == NetworkID.MSN:232            return self._client.profile233        contacts = self.contacts.search_by_network_id(network_id).\234                search_by_account(account)235        if len(contacts) == 0:236            return None237        return contacts[0]238    def search_or_build_contact(self, account, network_id, display_name=None):239        contact = self.search_contact(account, network_id)240        if contact is None:241            if not display_name:242                display_name = account243            contact = profile.Contact(None, network_id, account, display_name)244        return contact245    def accept_contact_invitation(self, pending_contact, add_to_contact_list=True,246            done_cb=None, failed_cb=None):247        if not pending_contact.is_member(Membership.PENDING) \248        and pending_contact.is_member(Membership.REVERSE):249            return250        def callback(memberships, contact):251            self.__update_contact(contact, memberships)252            self.__common_callback('contact-accepted', done_cb, contact)253        def contact_added(pending_contact):254            ai = scenario.AcceptInviteScenario(self._sharing,255                     (callback, pending_contact),256                     (self.__common_errback, failed_cb),257                     pending_contact.account,258                     pending_contact.memberships,259                     pending_contact.network_id)260            ai()261        if add_to_contact_list \262        and not pending_contact.memberships & Membership.FORWARD:263            self.add_messenger_contact(account=pending_contact.account,264                                       network_id=pending_contact.network_id,265                                       done_cb=(contact_added,))266        else:267            contact_added(pending_contact)268    def decline_contact_invitation(self, pending_contact, block=True,269            done_cb=None, failed_cb=None):270        def callback(memberships):271            pending_contact._set_memberships(memberships)272            self.__common_callback('contact-rejected', done_cb, pending_contact)273        di = scenario.DeclineInviteScenario(self._sharing,274                 (callback,),275                 (self.__common_errback, failed_cb))276        di.account = pending_contact.account277        di.network = pending_contact.network_id278        di.memberships = pending_contact.memberships279        di.block = block280        di()281    def add_messenger_contact(self, account, invite_display_name='',282            invite_message='', groups=[], network_id=NetworkID.MSN,283            auto_allow=True, done_cb=None, failed_cb=None):284        def contact_added(was_hidden):285            new_contact = None286            for contact in self.contacts:287                if contact.account == account:288                    new_contact = contact289                    break290            if new_contact is not None:291                allowed_or_blocked = new_contact.memberships & \292                    (Membership.BLOCK | Membership.ALLOW)293                if auto_allow and not allowed_or_blocked:294                    new_contact._add_membership(Membership.ALLOW)295                if not was_hidden:296                    new_contact._remove_membership(Membership.PENDING)297                if new_contact.id != Contact.BLANK_ID:298                    if not new_contact.is_member(Membership.PENDING):299                        new_contact._add_membership(Membership.FORWARD)300                    self.__common_callback('messenger-contact-added',301                                           done_cb, new_contact)302                for group in groups:303                    self.add_contact_to_group(group, new_contact)304            self.__unfreeze_address_book()305        def sync(contact_guid, was_hidden=False):306            self.__freeze_address_book()307            self.sync(True, (contact_added, was_hidden))308        contact = self.search_contact(account, network_id)309        if contact is self._client.profile:310            return # can't add ourself to the address book311        old_memberships = (contact and contact.memberships) or Membership.NONE312        if contact is not None and contact.is_mail_contact():313            self.upgrade_mail_contact(contact, groups, done_cb, failed_cb)314        elif contact is None or not contact.is_member(Membership.FORWARD):315            scenario_class = MessengerContactAddScenario316            s = scenario_class(self._ab,317                    (sync,),318                    (self.__common_errback, failed_cb),319                    account, network_id)320            s.auto_manage_allow_list = auto_allow321            s.invite_display_name = invite_display_name322            s.invite_message = invite_message323            s()324    def upgrade_mail_contact(self, contact, groups=[],325            done_cb=None, failed_cb=None):326        logger.info('upgrade mail contact: %s' % str(contact))327        def callback():328            contact._add_membership(Membership.ALLOW)329            for group in groups:330                self.add_contact_to_group(group, contact)331            self.__common_callback(None, done_cb, contact)332        up = scenario.ContactUpdatePropertiesScenario(self._ab,333                (callback,), (self.__common_errback, failed_cb))334        up.contact_guid = contact.id335        up.contact_properties = { 'is_messenger_user' : True }336        up.enable_allow_list_management = True337        up()338    def delete_contact(self, contact, done_cb=None, failed_cb=None):339        def callback():340            self.__remove_contact(contact, Membership.FORWARD, done_cb)341        dc = scenario.ContactDeleteScenario(self._sharing,342                self._ab,343                (callback,),344                (self.__common_errback, failed_cb))345        dc.contact_guid = contact.id346        dc.account = contact.account347        dc.memberships = contact.memberships348        dc.network = contact.network_id349        dc()350    def update_contact_infos(self, contact, infos, done_cb=None, failed_cb=None):351        def callback():352            contact._server_infos_changed(infos)353            self.__common_callback(None, done_cb, contact)354        up = scenario.ContactUpdatePropertiesScenario(self._ab,355                (callback,),356                (self.__common_errback, failed_cb))357        up.contact_guid = contact.id358        up.contact_properties = infos359        up()360    def block_contact(self, contact, done_cb=None, failed_cb=None):361        def callback(memberships):362            contact._set_memberships(memberships)363            self.__common_callback('contact-blocked', done_cb, contact)364        bc = scenario.BlockContactScenario(self._sharing,365                (callback,),366                (self.__common_errback, failed_cb))367        bc.account = contact.account368        bc.network = contact.network_id369        bc.membership = contact.memberships370        bc()371    def unblock_contact(self, contact, done_cb=None, failed_cb=None):372        def callback(memberships):373            contact._set_memberships(memberships)374            self.__common_callback('contact-unblocked', done_cb, contact)375        uc = scenario.UnblockContactScenario(self._sharing,376                (callback,),377                (self.__common_errback, failed_cb))378        uc.account = contact.account379        uc.network = contact.network_id380        uc.membership = contact.memberships381        uc()382    def allow_contact(self, account, network_id=NetworkID.MSN,383            done_cb=None, failed_cb=None):384        def callback(memberships):385            c = self.__build_or_update_contact(account, network_id, memberships)386            self.__common_callback('contact-allowed', done_cb, c)387        contact = self.search_contact(account, network_id)388        old_memberships = (contact and contact.memberships) or Membership.NONE389        if old_memberships & Membership.BLOCK:390            self.unblock_contact(contact, done_cb, failed_cb)391        else:392            ac = scenario.AllowContactScenario(self._sharing,393                     (callback,),394                     (self.__common_errback, failed_cb))395            ac.account = account396            ac.network = network_id397            ac.membership = old_memberships398            ac()399    def disallow_contact(self, contact, done_cb=None, failed_cb=None):400        def callback(memberships):401            contact._remove_membership(Membership.ALLOW)402            self.__common_callback('contact-disallowed', done_cb, contact)403            if contact.memberships == Membership.NONE:404                self.contacts.discard(contact)405        dc = scenario.DisallowContactScenario(self._sharing,406                (callback,),407                (self.__common_errback, failed_cb))408        dc.account = contact.account409        dc.network = contact.network_id410        dc.membership = contact.memberships411        dc()412    def add_group(self, group_name, done_cb=None, failed_cb=None):413        def callback(group_id):414            group = profile.Group(group_id, group_name)415            self.groups.add(group)416            self.__common_callback('group-added', done_cb, group)417        ag = scenario.GroupAddScenario(self._ab,418                (callback,),419                (self.__common_errback, failed_cb))420        ag.group_name = group_name421        ag()422    def delete_group(self, group, done_cb=None, failed_cb=None):423        def callback():424            self.__remove_group(group, done_cb)425        dg = scenario.GroupDeleteScenario(self._ab,426                (callback,),427                (self.__common_errback, failed_cb))428        dg.group_guid = group.id429        dg()430    def rename_group(self, group, new_name, done_cb=None, failed_cb=None):431        def callback():432            group._name = new_name433            self.__common_callback('group-renamed', done_cb, group)434        rg = scenario.GroupRenameScenario(self._ab,435                (callback,),436                (self.__common_errback, failed_cb))437        rg.group_guid = group.id438        rg.group_name = new_name439        rg()440    def add_contact_to_group(self, group, contact, done_cb=None, failed_cb=None):441        def callback():442            contact._add_group_ownership(group)443            self.__common_callback('group-contact-added', done_cb, group, contact)444        ac = scenario.GroupContactAddScenario(self._ab,445                (callback,),446                (self.__common_errback, failed_cb))447        ac.group_guid = group.id448        ac.contact_guid = contact.id449        ac()450    def delete_contact_from_group(self, group, contact,451            done_cb=None, failed_cb=None):452        def callback():453            contact._delete_group_ownership(group)454            self.__common_callback('group-contact-deleted', done_cb, group, contact)455        dc = scenario.GroupContactDeleteScenario(self._ab,456                (callback,),457                (self.__common_errback, failed_cb))458        dc.group_guid = group.id459        dc.contact_guid = contact.id460        dc()461    def emit(self, detailed_signal, *args, **kwargs):462        if self.__frozen:463            self.__signal_queue.append((detailed_signal, args, kwargs))464        else:465            super(AddressBook, self).emit(detailed_signal, *args, **kwargs)466    # End of public API467    def __freeze_address_book(self):468        """Disable all AB notifications and events until we unfreeze."""469        if not self.__frozen:470            self.freeze_notify()471            for group in self.groups:472                group.freeze_notify()473            for contact in self.contacts:474                contact.freeze_notify()475        self.__frozen += 1476    def __unfreeze_address_book(self):477        """Emit all queued AB notifications and events."""478        if self.__frozen:479            self.__frozen -= 1480            if not self.__frozen:481                for contact in self.contacts:482                    contact.thaw_notify()483                for group in self.groups:484                    group.thaw_notify()485                self.thaw_notify()486                for signal in self.__signal_queue:487                    super(AddressBook, self).emit(signal[0], *signal[1], **signal[2])488                self.__signal_queue = []489    def __build_contact(self, contact=None, memberships=Membership.NONE):490        external_email = None491        is_messenger_enabled = False492        for email in contact.Emails:493            if email.Type == ContactEmailType.EXTERNAL:494                external_email = email495            if email.IsMessengerEnabled:496                is_messenger_enabled = True497        if (not contact.IsMessengerUser) and (external_email is not None):498            display_name = contact.DisplayName499            if not display_name:500                display_name = external_email.Email501            if not is_messenger_enabled:502                memberships = Membership.NONE503            c = profile.Contact(contact.Id,504                    NetworkID.EXTERNAL,505                    external_email.Email.encode("utf-8"),506                    display_name.encode("utf-8"),507                    contact.CID,508                    memberships,509                    contact.Type)510            contact_infos = contact.contact_infos511            c._server_infos_changed(contact_infos)512            for group in self.groups:513                if group.id in contact.Groups:514                    c._add_group_ownership(group)515            return c516        elif contact.PassportName == "":517            # FIXME : mobile phone and mail contacts here518            return None519        else:520            display_name = contact.DisplayName521            if not display_name:522                display_name = contact.QuickName523            if not display_name:524                display_name = contact.PassportName525            if not contact.IsMessengerUser:526                memberships = Membership.NONE527            c = profile.Contact(contact.Id,528                    NetworkID.MSN,529                    contact.PassportName.encode("utf-8"),530                    display_name.encode("utf-8"),531                    contact.CID,532                    memberships)533            contact_infos = contact.contact_infos534            c._server_infos_changed(contact_infos)535            for group in self.groups:536                if group.id in contact.Groups:537                    c._add_group_ownership(group)538            return c539        return None540    def __update_contact(self, contact, memberships=None, infos=None):541        contact.freeze_notify()542        if memberships is not None:543            contact._set_memberships(memberships)544        if infos is not None:545            contact._id = infos.Id546            contact._cid = infos.CID547            if infos.DisplayName:548                contact._display_name = infos.DisplayName549            if not isinstance(contact, profile.Profile):550                contact._server_infos_changed(infos.contact_infos)551                for group in self.groups:552                    if group.id in infos.Groups:553                        contact._add_group_ownership(group)554                    if group.id in infos.DeletedGroups:555                        contact._delete_group_ownership(group)556        contact.thaw_notify()557    def __build_or_update_contact(self, account, network_id=NetworkID.MSN,558            memberships=None, infos=None):559        contact = self.search_contact(account, network_id)560        if contact is not None:561            self.__update_contact(contact, memberships, infos)562        else:563            if infos is None:564                display_name = ""565                contact = profile.Contact(None, network_id, account,566                        display_name, memberships)567            else:568                contact = self.__build_contact(infos, memberships)569            self.contacts.add(contact)570            self.emit('contact-added', contact)571        return contact572    def __remove_contact(self, contact, removed_memberships, done_cb=None):573        emit_deleted = False574        if removed_memberships & Membership.FORWARD \575        and contact.is_member(Membership.FORWARD):576            emit_deleted = True577        contact._remove_membership(removed_memberships)578        # Do not use __common_callback() here to avoid race579        # conditions with the event-triggered contact._reset().580        run(done_cb, contact)581        if contact.memberships == Membership.NONE:582            self.contacts.discard(contact)583        if emit_deleted:584            self.emit('contact-deleted', contact)585    def __remove_group(self, group, done_cb=None):586        for contact in self.contacts:587            contact._delete_group_ownership(group)588        self.groups.discard(group)589        self.__common_callback('group-deleted', done_cb, group)590    def __log_sync_request(self, ab_storage, memberships):591        myself = '???' if not self._profile else self._profile.account592        contacts = ['%s-%s' % ('D' if contact.Deleted else 'A',593                                   contact.PassportName)594                        for contact in ab_storage.contacts]595        groups = ['%s-%s' % ('D' if group.Deleted else 'A',596                                   group.Name)597                      for group in ab_storage.groups]598        members = []599        for member in memberships:600            member_repr = member.Account601            for role, deleted in member.Roles.items():602                member_repr += ' %s-%s' % ('D' if deleted else 'A', role)603            members.append(member_repr)604        logger.info('[%s] Received sync request:\n'605                     '...contacts: %s\n'606                     '...groups: %s\n'607                     '...memberships: %s'608                     % (myself, str(contacts), str(groups), str(members)))609    def __update_address_book(self, ab_storage):610        for group_infos in ab_storage.groups:611            group = None612            for g in self.groups:613                if g.id == group_infos.Id:614                    group = g615                    break616            if group_infos.Deleted:617                if group is not None:618                    self.__remove_group(group)619            else:620                group_name = group_infos.Name.encode("utf-8")621                if group:622                    group._server_property_changed('name', group_name)623                else:624                    group = profile.Group(group_infos.Id, group_name)625                    group.freeze_notify()626                    self.groups.add(group)627                    if self.state != AddressBookState.INITIAL_SYNC:628                        self.emit('group-added', group)629        for contact_infos in ab_storage.contacts:630            new_contact = self.__build_contact(contact_infos, Membership.FORWARD)631            if new_contact is None:632                continue633            new_contact.freeze_notify()634            contact = self.search_contact(new_contact.account,635                                          new_contact.network_id)636            if contact_infos.Type == ContactType.ME:637                if self._profile is None:638                    self._profile = new_contact639                else:640                    self.__update_contact(self._profile, infos=contact_infos)641                continue642            if contact_infos.Deleted:643                if contact:644                    self.__remove_contact(contact, Membership.FORWARD)645            else:646                new_contact_added = False647                if not contact \648                or contact.id == Contact.BLANK_ID:649                    new_contact_added = True650                if contact:651                    self.__update_contact(contact, infos=contact_infos)652                else:653                    contact = new_contact654                    self.contacts.add(contact)655                if new_contact_added and not isinstance(contact, profile.Profile):656                    if not contact.is_member(Membership.PENDING):657                        contact._add_membership(Membership.FORWARD)658                    if self.state != AddressBookState.INITIAL_SYNC:659                        self.emit('contact-added', contact)660    def __update_memberships(self, members):661        role_to_membership = {662            "Allow"   : Membership.ALLOW,663            "Block"   : Membership.BLOCK,664            "Reverse" : Membership.REVERSE,665            "Pending" : Membership.PENDING666        }667        membership_conflicts = {668            Membership.ALLOW: Membership.BLOCK,669            Membership.BLOCK: Membership.ALLOW,670            Membership.FORWARD: Membership.PENDING,671            Membership.PENDING: Membership.FORWARD672        }673        for member in members:674            if isinstance(member, sharing.PassportMember):675                network = NetworkID.MSN676            elif isinstance(member, sharing.EmailMember):677                network = NetworkID.EXTERNAL678            else:679                continue680            if network == NetworkID.MSN and member.IsPassportNameHidden:681                continue # ignore contacts with hidden passport name682            contact = self.search_contact(member.Account, network)683            new_contact = False684            if contact is None:685                member_deleted = True686                for role, deleted in member.Roles.items():687                    if not deleted:688                        member_deleted = False689                        break690                if member_deleted:691                    continue692                new_contact = True693                cid = getattr(member, "CID", None)694                account = member.Account.encode("utf-8")695                display_name = (member.DisplayName or member.Account).encode("utf-8")696                msg = member.Annotations.get('MSN.IM.InviteMessage', u'')697                contact = profile.Contact(None, network, account, display_name, cid)698                contact.freeze_notify()699                contact._server_attribute_changed('invite_message', msg.encode("utf-8"))700                self.contacts.add(contact)701            if contact is self._client.profile:702                continue # don't update our own memberships703            # TODO: Check whether the contact's membership was changed704            # after member.LastChanged and if so ignore this member.705            # To implement this papyon has to save full membership info706            # for contacts.707            deleted_memberships = Membership.NONE708            for role, deleted in member.Roles.items():709                membership = role_to_membership.get(role, None)710                if membership is None:711                    raise NotImplementedError("Unknown Membership:" + membership)712                if deleted:713                    deleted_memberships |= membership714                else:715                    conflicting_memberships = membership_conflicts.get(membership, Membership.NONE)716                    contact._remove_membership(conflicting_memberships)717                    contact._add_membership(membership)718            if deleted_memberships:719                self.__remove_contact(contact, deleted_memberships)720            if self.state != AddressBookState.INITIAL_SYNC:721                if contact.is_member(Membership.PENDING):722                    self.emit('contact-pending', contact)723                if new_contact:724                    self.emit('contact-added', contact)725    # Callbacks726    def __common_callback(self, signal, callback, *args):727        if signal is not None:728            self.emit(signal, *args)729        run(callback, *args)730    def __common_errback(self, error, errback=None):731        run(errback, error)732        while self.__frozen:733            self.__unfreeze_address_book()734        self.emit('error', error)735gobject.type_register(AddressBook)736if __name__ == '__main__':737    def get_proxies():738        import urllib739        proxies = urllib.getproxies()740        result = {}741        if 'https' not in proxies and \742                'http' in proxies:743            url = proxies['http'].replace("http://", "https://")744            result['https'] = papyon.Proxy(url)745        for type, url in proxies.items():746            if type == 'no': continue747            if type == 'https' and url.startswith('http://'):748                url = url.replace('http://', 'https://', 1)749            result[type] = papyon.Proxy(url)750        return result751    import sys752    import getpass753    import signal754    import gobject755    import logging756    from papyon.service.SingleSignOn import *757    from papyon.service.description.AB.constants import ContactGeneral758    logging.basicConfig(level=logging.DEBUG)759    if len(sys.argv) < 2:760        account = raw_input('Account: ')761    else:762        account = sys.argv[1]763    if len(sys.argv) < 3:764        password = getpass.getpass('Password: ')765    else:766        password = sys.argv[2]767    mainloop = gobject.MainLoop(is_running=True)768    signal.signal(signal.SIGTERM,769            lambda *args: gobject.idle_add(mainloop.quit()))770    def address_book_state_changed(address_book, pspec):771        if address_book.state == AddressBookState.SYNCHRONIZED:772            for group in address_book.groups:773                print "Group : %s " % group.name774            for contact in address_book.contacts:775                print "Contact : %s (%s) %s" % \776                    (contact.account,777                     contact.display_name,778                     contact.network_id)779            print address_book.contacts[0].account780            address_book.update_contact_infos(address_book.contacts[0], {ContactGeneral.FIRST_NAME : "lolibouep"})781            #address_book.sync(True)782            #address_book.accept_contact_invitation(address_book.pending_contacts.pop())783            #print address_book.pending_contacts.pop()784            #address_book.accept_contact_invitation(address_book.pending_contacts.pop())785            #address_book.add_group("ouch2")786            #address_book.add_group("callback test6")787            #group = address_book.groups.values()[0]788            #address_book.delete_group(group)789            #address_book.delete_group(group)790            #address_book.rename_group(address_book.groups.values()[0], "ouch")791            #address_book.add_contact_to_group(address_book.groups.values()[1],792            #                                  address_book.contacts[0])793            #contact = address_book.contacts[0]794            #address_book.delete_contact_from_group(address_book.groups.values()[0],795            #                                       contact)796            #address_book.delete_contact_from_group(address_book.groups.values()[0],797            #                                       contact)798            #address_book.block_contact(address_book.contacts.search_by_account('papyon.rewrite@yahoo.com')[0])799            #address_book.block_contact(address_book.contacts.search_by_account('papyon.rewrite@yahoo.com')[0])800            #address_book.unblock_contact(address_book.contacts[0])801            #address_book.block_contact(address_book.contacts[0])802            #contact = address_book.contacts[2]803            #address_book.delete_contact(contact)804            #address_book.delete_contact(contact)805            #g=list(address_book.groups)806            #address_book.add_messenger_contact("wikipedia-bot@hotmail.com",groups=g)807            #for i in range(5):808            #    address_book.delete_contact(address_book.contacts[i])809            #address_book.add_messenger_contact("johanssn.prieur@gmail.com")810    def messenger_contact_added(address_book, contact):811        print "Added contact : %s (%s) %s %s" % (contact.account,812                                                 contact.display_name,813                                                 contact.network_id,814                                                 contact.memberships)815    sso = SingleSignOn(account, password, proxies=get_proxies())816    address_book = AddressBook(sso, proxies=get_proxies())817    address_book.connect("notify::state", address_book_state_changed)818    address_book.connect("messenger-contact-added", messenger_contact_added)819    address_book.sync()820    while mainloop.is_running():821        try:822            mainloop.run()823        except KeyboardInterrupt:...network.py
Source:network.py  
...155        """156        self._tid += 1157        def dcb(packet):158            try:159                done_cb(packet[b'success'])160            except KeyError:161                done_cb(False)162        self._sendRequest(msgpack.packb({163            DhtNetworkSubProcess.REQUEST : True,164            'tid' : self._tid,165            'req' : DhtNetworkSubProcess.PING_REQ166        }), self._tid, dcb)167    def sendGetMessageStats(self, done_cb=None):168        """169        Sends DhtNetwork sub process statistics request about nodes messages170        sent.171        @param done_cb: A function taking as parameter the returned list of172                        stats.173        @type  done_cb: function174        @return: A list [num_nodes, ping, find, get, put, listen].175        @rtype : list176        """177        self._tid += 1178        def dcb(packet):179            nonlocal done_cb180            if not done_cb:181                return182            try:183                stats = packet[b'stats']184                done_cb([] if not isinstance(stats, list) else done_cb(stats))185            except KeyError:186                done_cb([])187        self._sendRequest(msgpack.packb({188            DhtNetworkSubProcess.REQUEST : True,189            'tid' : self._tid,190            'req' : DhtNetworkSubProcess.MESSAGE_STATS191        }), self._tid, dcb)192    def sendClusterPutRequest(self, _hash, value, done_cb=None):193        """194        Sends a put operation request.195        @param _hash: the hash of the value.196        @type  _hash: bytes.197        @param value: the value.198        @type  value: bytes.199        @param done_cb: A function taking as parameter a boolean "success".200        @type  done_cb: function201        """202        self._tid += 1203        def dcb(packet):204            nonlocal done_cb205            if not done_cb:206                return207            try:208                done_cb(packet[b'success'])209            except KeyError:210                done_cb(False)211        self._sendRequest(msgpack.packb({212            DhtNetworkSubProcess.REQUEST : True,213            'tid' : self._tid,214            'req'   : DhtNetworkSubProcess.NODE_PUT_REQ,215            'hash'  : _hash,216            'value' : value217        }), self._tid, dcb)218    def sendClusterRequest(self, request, ids=[], done_cb=None):219        """220        Send request to a list of nodes or the whole cluster.221        @param request: The request. Possible values are:222            DhtNetworkSubProcess.REMOVE_NODE_REQ223            DhtNetworkSubProcess.SHUTDOWN_NODE_REQ224            DhtNetworkSubProcess.SHUTDOWN_REPLACE_NODE_REQ225            DhtNetworkSubProcess.SHUTDOWN_CLUSTER_REQ226            DhtNetworkSubProcess.DUMP_STORAGE_REQ227        @type request: bytes228        @param ids: The list of ids concerned by the request.229        @type  ids: list230        """231        self._tid += 1232        def dcb(packet):233            nonlocal done_cb234            if not done_cb:235                return236            try:237                done_cb(packet[b'success'])238            except KeyError:239                done_cb(False)240        self._sendRequest(msgpack.packb({241            DhtNetworkSubProcess.REQUEST : True,242            'tid' : self._tid,243            'req' : request,244            'ids' : ids245        }), self._tid, dcb)246class DhtNetwork(object):247    nodes = []248    class Log(object):249        BOLD   = "\033[1m"250        NORMAL = "\033[0m"251        WHITE  = "\033[97m"252        RED    = "\033[31m"253        YELLOW = "\033[33m"...head_bak.py
Source:head_bak.py  
...175        def _handle_transition(gh):176            gh_goal = gh.comm_state_machine.action_goal.goal177            if done_cb is not None and (id(self._eyes_goal) == id(gh_goal) or id(self._head_goal) == id(gh_goal)):178                if gh.get_comm_state() == CommState.DONE:179                    done_cb(gh.get_goal_status(), gh.get_result())180            return181        def _handle_feedback(gh, feedback):182            gh_goal = gh.comm_state_machine.action_goal.goal183            if feedback_cb is not None and (id(self._eyes_goal) == id(gh_goal) or id(self._head_goal) == id(gh_goal)):184                feedback_cb(feedback)185            return186        if self.JOINT_EYES in traj.joint_names:187            if not self._eyes_ac:188                return False189            self._eyes_goal = goal190            # send the goal191            self.wait_for_server()192            self._eyes_gh = self._eyes_ac.send_goal(goal, _handle_transition, _handle_feedback)193            self.wait_for_done(5)...LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!
