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!!