コード例 #1
0
    def __init__(self, username, parent=None):
        super(WeCaseWindow, self).__init__(parent)

        self.username = username
        LoginInfo().add_account(self.username)

        self.errorWindow = APIErrorWindow(self)
        self.setAttribute(QtCore.Qt.WA_QuitOnClose, True)
        self._iconPixmap = {}
        self.setupUi(self)
        self._setupSysTray()
        self.tweetViews = [
            self.homeView, self.mentionsView, self.commentsView,
            self.commentsMentionsTab
        ]
        self.info = WeRuntimeInfo()
        self.client = const.client
        self.loadConfig()
        self.init_account()
        self.setupModels()
        self.IMG_AVATAR = -2
        self.IMG_THUMB = -1
        self.notify = Notify(timeout=self.notify_timeout)
        self.applyConfig()
        self.download_lock = []
        self._last_reminds_count = 0
        self._setupUserTab(self.uid(), False, True)
コード例 #2
0
ファイル: NewpostWindow.py プロジェクト: sikisis/WeCase
 def __init__(self, parent=None, action="new", id=None, cid=None, text=""):
     QtGui.QDialog.__init__(self, parent)
     self.action = action
     self.id = id
     self.cid = cid
     self.setupUi(self)
     self.setupMyUi()
     self.textEdit.setText(text)
     self.textEdit.callback = self.mentions_suggest
     self.textEdit.mention_flag = "@"
     self.notify = Notify(timeout=1)
コード例 #3
0
def check_availabilty_pincode():
    from datetime import date
    for pincode, data in dict_pincode.items():
        # today_date = date.today().strftime('%d-%m-%Y')
        to = data[0]
        id_list = data[1]
        pin_obj = SlotAvailableByPincode(pincode=pincode)
        pin_obj.get_slot_availability()
        flag, index, slots, age, date = pin_obj.return_list[0], pin_obj.return_list[1], pin_obj.return_list[2], pin_obj.return_list[3],pin_obj.return_list[4]
        if flag == True:
            email_obj = Notify(to, index, slots, age, date)
            if email_obj.send_mail():
                remove_from_firebase(id_list, to)
コード例 #4
0
def check_availabilty_district():
    from datetime import date
    for district_id, data in dict_district.items():
        # today_date = date.today().strftime('%d-%m-%Y')
        to = data[0]
        id_list = data[1]
        dist_obj = SlotAvailableByDistrict(district_id=district_id)
        dist_obj.get_slot_availability()
        flag, index, slots, age, date = dist_obj.return_list[0], dist_obj.return_list[1], dist_obj.return_list[2], dist_obj.return_list[3], dist_obj.return_list[4]
        if flag == True:
            email_obj = Notify(to, index, slots, age, date)
            if email_obj.send_mail():
                remove_from_firebase(id_list, to)
コード例 #5
0
def check_availabilty_district():
    from datetime import date
    for district_id, data in dict_district.items():
        to = data[0]
        id_list = data[1]
        dist_obj = SlotAvailableByID(target=district_id, mode="District")
        dist_obj.get_slot_availability()
        flag, index, slots, age, date = dist_obj.return_list[
            0], dist_obj.return_list[1], dist_obj.return_list[
                2], dist_obj.return_list[3], dist_obj.return_list[4]
        if flag == True:
            email_obj = Notify(to, index, slots, age, date)
            if email_obj.send_mail():
                remove_from_firebase(id_list, to)
コード例 #6
0
ファイル: WeCaseWindow.py プロジェクト: sikisis/WeCase
 def __init__(self, client, parent=None):
     QtGui.QMainWindow.__init__(self, parent)
     self.setupUi(self)
     self.tweetViews = [
         self.homeView, self.mentionsView, self.commentsView, self.myView
     ]
     self.client = client
     self.setupModels()
     self.init_account()
     self.setupMyUi()
     self.loadConfig()
     self.IMG_AVATAR = -2
     self.IMG_THUMB = -1
     self.notify = Notify(timeout=self.notify_timeout)
     self.applyConfig()
     self.download_lock = []
コード例 #7
0
def main(totalEvents, test_num):
    doPlot = False
    configModule = "NuralTest"
    maxEvents = totalEvents
    maxTimeSec = 0
    runNumber = test_num
    outputFile = "data_sets/run{}_{}.bin".format(test_num, totalEvents)
    # Check argument validity
    ok = True
    if maxEvents < 0:
        print("Invalid number of events (can not be negative)")
        ok = False
    if maxTimeSec < 0:
        print("Invalid run time (can not be negative)")
        ok = False
    if not ok:
        print(__doc__)
        return 1
    global MUONRATE
    wtime = round(totalEvents * float(MUONRATE))
    print(25 * "=")
    print("\nRun {} for {} Events \n".format(test_num, totalEvents))
    print("Starting DAQ system....")
    # if wtime == 0:
    # print("Process will take roughly {} min".format(1))
    # else:
    # print("Process will take roughly {} mins".format(wtime))
    # Configure the histogram plotter.
    # The channels to plot: a tuple of (slot, channel) pairs.
    # "None" will take all channels configured in the DAQ.
    channels_to_plot = ((2, 0), (2, 1), (2, 3), (2, 4), (2, 6), (2, 7), (2, 9),
                        (2, 10))
    nBins = 100
    updateAfterHowManyEvents = 10
    verticalSpaceAdjustment = 0.4
    adcHisto = ADCHisto(nBins, updateAfterHowManyEvents,
                        verticalSpaceAdjustment, channels_to_plot)
    tdcHisto = TDCHisto(nBins, updateAfterHowManyEvents,
                        verticalSpaceAdjustment, channels_to_plot)

    plotUpdater = plotDiagnostics(doPlot, adcHisto, tdcHisto)
    n, t, s, err = runCAMAC(configModule, maxEvents, maxTimeSec, runNumber,
                            outputFile, plotUpdater)

    print('Processed %d events in %g sec' % (n, t))
    print('Run status is', s)
    if s == "Error":
        print('Error message:', err)
    if not (outputFile == "None" or outputFile == "none"):
        print('Run %d data is stored in the file "%s"' %
              (runNumber, outputFile))
    print("Uploading File to Quanah.....\n")
    os.system("upload.sh {}".format(outputFile))
    print("File {} has been successfully uploaded to Quanah\n".format(
        outputFile))
    print(25 * "=")
    print()
    fileName = outputFile.split("/")[1]
    Notify(fileName).sendEmail()
    return 0
コード例 #8
0
 def __init__(self, parent=None, action="new", id=None, cid=None, text=""):
     QtGui.QDialog.__init__(self, parent)
     self.action = action
     self.id = id
     self.cid = cid
     self.setupUi(self)
     self.setupMyUi()
     self.textEdit.setText(text)
     self.textEdit.callback = self.mentions_suggest
     self.textEdit.mention_flag = "@"
     self.notify = Notify(timeout=1)
コード例 #9
0
    def __init__(self, action="new", tweet=None, parent=None):
        super(NewpostWindow, self).__init__(parent)
        self.setAttribute(QtCore.Qt.WA_QuitOnClose, False)
        self.client = const.client
        self.tweet = tweet
        self.action = action
        self.setupUi(self)
        self.textEdit.callback = self.mentions_suggest
        self.textEdit.mention_flag = "@"
        self.notify = Notify(timeout=1)
        self._sent = False
        self.apiError.connect(self.showException)
        self.sendSuccessful.connect(self.sent)
        self.commonError.connect(self.showErrorMessage)
        self.errorWindow = APIErrorWindow(self)

        if self.action not in ["new", "reply"]:
            self.tweetRefreshed.connect(self._create_tweetWidget)
            self.tweetRejected.connect(
                lambda: self.pushButton_send.setEnabled(False))
            self._refresh()
コード例 #10
0
def quanahJob(outputFile):
    print("Uploading File to Quanah.....\n")
    os.system("upload.sh {}".format(outputFile))
    print(25 * "=")
    print()
    fileName = outputFile.split("/")[1]
    analyzeOnQuanah(fileName)
    Notify(fileName).sendEmail()
    print("File {} has been successfully uploaded to Quanah\n".format(
        outputFile))
    print()
    os.remove(outputFile)
コード例 #11
0
ファイル: NewpostWindow.py プロジェクト: lxg19880914/WeCase
 def __init__(self, action="new", tweet=None, parent=None):
     super(NewpostWindow, self).__init__(parent)
     self.setAttribute(QtCore.Qt.WA_QuitOnClose, False)
     self.client = const.client
     self.tweet = tweet
     self.action = action
     self.setupUi(self)
     self.textEdit.callback = self.mentions_suggest
     self.textEdit.mention_flag = "@"
     self.notify = Notify(timeout=1)
     self._sent = False
     self.apiError.connect(self.showException)
     self.sendSuccessful.connect(self.sent)
     self.commonError.connect(self.showErrorMessage)
コード例 #12
0
ファイル: WeCaseWindow.py プロジェクト: jueqingsizhe66/WeCase
 def __init__(self, client, parent=None):
     QtGui.QMainWindow.__init__(self, parent)
     self.setupUi(self)
     self.tweetViews = [self.homeView, self.mentionsView, self.commentsView, self.myView]
     self.client = client
     self.setupModels()
     self.init_account()
     self.setupMyUi()
     self.loadConfig()
     self.IMG_AVATAR = -2
     self.IMG_THUMB = -1
     self.notify = Notify(timeout=self.notify_timeout)
     self.applyConfig()
     self.download_lock = []
コード例 #13
0
ファイル: WeCaseWindow.py プロジェクト: lxg19880914/WeCase
 def __init__(self, parent=None):
     super(WeCaseWindow, self).__init__(parent)
     self.setAttribute(QtCore.Qt.WA_QuitOnClose, True)
     self._iconPixmap = {}
     self.setupUi(self)
     self._setupSysTray()
     self.tweetViews = [self.homeView, self.mentionsView, self.commentsView]
     self.info = WeRuntimeInfo()
     self.client = const.client
     self.loadConfig()
     self.init_account()
     self.setupModels()
     self.IMG_AVATAR = -2
     self.IMG_THUMB = -1
     self.notify = Notify(timeout=self.notify_timeout)
     self.applyConfig()
     self.download_lock = []
     self._last_reminds_count = 0
     self._setupUserTab(self.uid(), False, True)
コード例 #14
0
ファイル: NewpostWindow.py プロジェクト: EmbolismSoil/WeCase
    def __init__(self, action="new", tweet=None, parent=None):
        super(NewpostWindow, self).__init__(parent)
        self.setAttribute(QtCore.Qt.WA_QuitOnClose, False)
        self.client = const.client
        self.tweet = tweet
        self.action = action
        self.setupUi(self)
        self.textEdit.callback = self.mentions_suggest
        self.textEdit.mention_flag = "@"
        self.notify = Notify(timeout=1)
        self._sent = False
        self.apiError.connect(self.showException)
        self.sendSuccessful.connect(self.sent)
        self.commonError.connect(self.showErrorMessage)
        self.errorWindow = APIErrorWindow(self)

        if self.action not in ["new", "reply"]:
            self.tweetRefreshed.connect(self._create_tweetWidget)
            self.tweetRejected.connect(lambda: self.pushButton_send.setEnabled(False))
            self._refresh()
コード例 #15
0
ファイル: manage.py プロジェクト: floppydi5k/sample
def main():
    camvi = Camvi(timeout=1)
    notify = Notify()
    # start listener
    camvi.listen()
    # retrieve camvi token
    camvi_tok = camvi.retrieve_auth_token()
    while True:
        # enable
        msg = camvi.event()
        print(msg)
        if msg['type'] != 'ADD':
            continue
        persons = msg.get('persons')
        if persons is not None:
            for person in persons:
                onBlackList = False
                groups = person['groups']
                if groups is not None:
                    for group in groups:
                        if group['name'] == 'blacklist':
                            onBlackList = True

                if onBlackList:
                    print('Person on black list found!')
                    image_url = 'http://' + camvi_options[
                        'ip'] + ':' + camvi_options[
                            'port'] + '/log/image/' + str(person['log'])
                    # msg_to_send = "Person found, name: {}".format(str(person['name']))
                    # email
                    if email_options['enabled']:
                        msg_to_send = "<html><body>Black list person found, name {}, time {}, camera {}, <a href=\"{}\">picture</a></body></html>".format(
                            str(person['name']), msg['time'], msg['camera'],
                            image_url)
                        print(msg_to_send)
                        notify.send_email(subj="Black List Person Found",
                                          html=msg_to_send)
                    # text
                    if twilio_options['enabled']:
                        msg_to_send = "black list person found: {}, {}".format(
                            str(person['name']), image_url)
                        print(msg_to_send)
                        notify.send_text(msg=msg_to_send)
コード例 #16
0
from MuonDataFrame import *
from Notify import Notify

if __name__ == "__main__":
    try:
        ifile = sys.argv[1]
        iisNew = sys.argv[2]
    except:
        print("No File passed / Invalid File")
        iisNew = False
        print("\nAssuming the file has been analyzed before.")

    mdfo = MuonDataFrame(ifile, isNew=iisNew, d1="last")
    pdfName = mdfo.generateAnaReport()
    Notify().sendPdfEmail(pdfName)
    #mdf = mdfo.events_df
    #mdfo.getChannelStatusPlot()
    # mdfo.gui()
    # mdfo.show()
    #mdfo.getAnaReport()
    # mdfo.generateAnaReport()
    # mdfo.computeAssymetries()
    # mdfo.get2DHistogram()
    # mdfo.getScatterPlot(["L1_asym", "L2_asym"])
    # mdfo.getScatterPlot(["L3_asym", "L4_asym"])
    # mdfo.getScatterPlot(["L1_asym", "L3_asym"])
    # mdfo.getScatterPlot(["L2_asym", "L4_asym"])
    # # mdfo.getAssymetry1DPlots()

    # mdf = mdfo.events_df
コード例 #17
0
class NewpostWindow(QtGui.QDialog, Ui_NewPostWindow):
    client = None
    image = None
    apiError = QtCore.pyqtSignal(str)
    sendSuccessful = QtCore.pyqtSignal()

    def __init__(self, parent=None, action="new", id=None, cid=None, text=""):
        QtGui.QDialog.__init__(self, parent)
        self.action = action
        self.id = id
        self.cid = cid
        self.setupUi(self)
        self.setupMyUi()
        self.textEdit.setText(text)
        self.textEdit.callback = self.mentions_suggest
        self.textEdit.mention_flag = "@"
        self.notify = Notify(timeout=1)

    def setupMyUi(self):
        self.checkChars()
        if self.action == "new":
            self.chk_repost.setEnabled(False)
            self.chk_comment.setEnabled(False)
            self.chk_comment_original.setEnabled(False)
        elif self.action == "retweet":
            self.chk_repost.setEnabled(False)
            self.pushButton_picture.setEnabled(False)
        elif self.action == "comment":
            self.chk_comment.setEnabled(False)
            self.pushButton_picture.setEnabled(False)
        elif self.action == "reply":
            self.chk_repost.setEnabled(False)
            self.chk_comment.setEnabled(False)
            self.pushButton_picture.setEnabled(False)

    def mentions_suggest(self, text):
        ret_users = []
        try:
            word = re.findall('@[-a-zA-Z0-9_\u4e00-\u9fa5]+', text)[-1]
            word = word.replace('@', '')
        except IndexError:
            return []
        if not word.strip():
            return []
        users = self.client.search.suggestions.at_users.get(q=word, type=0)
        for user in users:
            ret_users.append("@" + user['nickname'])
        return ret_users

    def send(self):
        self.pushButton_send.setEnabled(False)
        if self.action == "new":
            threading.Thread(group=None, target=self.new).start()
        elif self.action == "retweet":
            threading.Thread(group=None, target=self.retweet).start()
        elif self.action == "comment":
            threading.Thread(group=None, target=self.comment).start()
        elif self.action == "reply":
            threading.Thread(group=None, target=self.reply).start()

    def retweet(self):
        text = str(self.textEdit.toPlainText())
        try:
            self.client.statuses.repost.post(id=int(self.id), status=text,
                                             is_comment=int((self.chk_comment.isChecked() +
                                             self.chk_comment_original.isChecked() * 2)))
            self.notify.showMessage(self.tr("WeCase"),
                                    self.tr("Retweet Success!"))
            self.sendSuccessful.emit()
        except APIError as e:
            self.apiError.emit(str(e))
            return

    def comment(self):
        text = str(self.textEdit.toPlainText())
        try:
            self.client.comments.create.post(id=int(self.id), comment=text,
                                             comment_ori=int(self.chk_comment_original.isChecked()))
            if self.chk_repost.isChecked():
                self.client.statuses.repost.post(id=int(self.id), status=text)
            self.notify.showMessage(self.tr("WeCase"),
                                    self.tr("Comment Success!"))
            self.sendSuccessful.emit()
        except APIError as e:
            self.apiError.emit(str(e))
            return

    def reply(self):
        text = str(self.textEdit.toPlainText())
        try:
            self.client.comments.reply.post(id=int(self.id), cid=int(self.cid),
                                            comment=text,
                                            comment_ori=int(self.chk_comment_original.isChecked()))
            if self.chk_repost.isChecked():
                self.client.statuses.repost.post(id=int(self.id), status=text)
            self.notify.showMessage(self.tr("WeCase"),
                                    self.tr("Reply Success!"))
            self.sendSuccessful.emit()
        except APIError as e:
            self.apiError.emit(str(e))
            return

    def new(self):
        text = str(self.textEdit.toPlainText())

        try:
            if self.image:
                self.client.statuses.upload.post(status=text,
                                                 pic=open(self.image, "rb"))
            else:
                self.client.statuses.update.post(status=text)

            self.notify.showMessage(self.tr("WeCase"),
                                    self.tr("Tweet Success!"))
            self.sendSuccessful.emit()
        except APIError as e:
            self.apiError.emit(str(e))
            return

        self.image = None

    def addImage(self):
        ACCEPT_TYPE = self.tr("Images") + "(*.png *.jpg *.bmp *.gif)"
        if self.image:
            self.image = None
            self.pushButton_picture.setText(self.tr("Picture"))
        else:
            self.image = QtGui.QFileDialog.getOpenFileName(self,
                                                           self.tr("Choose a"
                                                           " image"),
                                                           filter=ACCEPT_TYPE)
            # user may cancel the dialog, so check again
            if self.image:
                self.pushButton_picture.setText(self.tr("Remove the picture"))

    def showError(self, e):
        if "Text too long" in e:
            QtGui.QMessageBox.warning(None, self.tr("Text too long!"),
                                      self.tr("Please remove some text."))
        else:
            QtGui.QMessageBox.warning(None, self.tr("Unknown error!"), e)
        self.pushButton_send.setEnabled(True)

    def showSmiley(self):
        wecase_smiley = SmileyWindow()
        if wecase_smiley.exec_():
            self.textEdit.textCursor().insertText(wecase_smiley.smileyName)

    def checkChars(self):
        '''Check textEdit's characters.
        If it larger than 140, Send Button will be disabled
        and label will show red chars.'''

        text = self.textEdit.toPlainText()
        numLens = 140 - tweetLength(text)
        if numLens == 140 and (not self.action == "retweet"):
            # you can not send empty tweet, except retweet
            self.pushButton_send.setEnabled(False)
        elif numLens >= 0:
            # length is okay
            self.label.setStyleSheet("color:black;")
            self.pushButton_send.setEnabled(True)
        else:
            # text is too long
            self.label.setStyleSheet("color:red;")
            self.pushButton_send.setEnabled(False)
        self.label.setText(str(numLens))
コード例 #18
0
ファイル: WeCaseWindow.py プロジェクト: jueqingsizhe66/WeCase
class WeCaseWindow(QtGui.QMainWindow, Ui_frm_MainWindow):
    client = None
    uid = None
    imageLoaded = QtCore.pyqtSignal(str)
    tabTextChanged = QtCore.pyqtSignal(int, str)

    def __init__(self, client, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        self.setupUi(self)
        self.tweetViews = [self.homeView, self.mentionsView, self.commentsView, self.myView]
        self.client = client
        self.setupModels()
        self.init_account()
        self.setupMyUi()
        self.loadConfig()
        self.IMG_AVATAR = -2
        self.IMG_THUMB = -1
        self.notify = Notify(timeout=self.notify_timeout)
        self.applyConfig()
        self.download_lock = []

    def init_account(self):
        self.get_uid()

    def loadConfig(self):
        self.config = ConfigParser()
        self.config.read(const.config_path)

        if not self.config.has_section("main"):
            self.config["main"] = {}

        self.main_config = self.config["main"]
        self.timer_interval = int(self.main_config.get("notify_interval", 30))
        self.notify_timeout = int(self.main_config.get("notify_timeout", 5))
        self.remindMentions = self.main_config.getboolean("remind_mentions", 1)
        self.remindComments = self.main_config.getboolean("remind_comments", 1)

    def applyConfig(self):
        try:
            self.timer.stop_event.set()
        except AttributeError:
            pass

        self.timer = WTimer(self.timer_interval, self.show_notify)
        self.timer.start()
        self.notify.timeout = self.notify_timeout

    def setupMyUi(self):
        for tweetView in self.tweetViews:
            tweetView.setResizeMode(tweetView.SizeRootObjectToView)
            tweetView.setSource(QtCore.QUrl.fromLocalFile(const.myself_path + "/ui/TweetList.qml"))
            tweetView.rootContext().setContextProperty("mainWindow", self)

    @QtCore.pyqtSlot()
    def load_more(self):
        model = self.get_current_model()
        model.next()

    def setupModels(self):
        self.all_timeline = TweetCommonModel(TweetItem(), self.client.statuses.home_timeline, self)
        self.all_timeline.load()
        self.homeView.rootContext().setContextProperty("mymodel", self.all_timeline)
        self.mentions = TweetCommonModel(TweetItem(), self.client.statuses.mentions, self)
        self.mentions.load()
        self.mentionsView.rootContext().setContextProperty("mymodel", self.mentions)
        self.comment_to_me = TweetCommentModel(TweetItem(), self.client.comments.to_me, self)
        self.comment_to_me.load()
        self.commentsView.rootContext().setContextProperty("mymodel", self.comment_to_me)
        self.my_timeline = TweetCommonModel(TweetItem(), self.client.statuses.user_timeline, self)
        self.my_timeline.load()
        self.myView.rootContext().setContextProperty("mymodel", self.my_timeline)

    def reset_remind(self):
        if self.tabWidget.currentIndex() == 0:
            self.tabWidget.setTabText(0, self.tr("Weibo"))
        elif self.tabWidget.currentIndex() == 1:
            self.client.remind.set_count.post(type="mention_status")
            self.tabWidget.setTabText(1, self.tr("@Me"))
        elif self.tabWidget.currentIndex() == 2:
            self.client.remind.set_count.post(type="cmt")
            self.tabWidget.setTabText(2, self.tr("Comments"))

    def get_remind(self, uid):
        """this function is used to get unread_count
        from Weibo API. uid is necessary."""

        reminds = self.client.remind.unread_count.get(uid=uid)
        return reminds

    def get_uid(self):
        """How can I get my uid? here it is"""
        try:
            self.uid = self.client.account.get_uid.get().uid
        except AttributeError:
            return None

    def show_notify(self):
        # This function is run in another thread by WTimer.
        # Do not modify UI directly. Send signal and react it in a slot only.
        # We use SIGNAL self.tabTextChanged and SLOT self.setTabText()
        # to display unread count

        reminds = self.get_remind(self.uid)
        msg = self.tr("You have:") + "\n"
        num_msg = 0

        if reminds["status"] != 0:
            # Note: do NOT send notify here, or users will crazy.
            self.tabTextChanged.emit(0, self.tr("Weibo(%d)") % reminds["status"])

        if reminds["mention_status"] and self.remindMentions:
            msg += self.tr("%d unread @ME") % reminds["mention_status"] + "\n"
            self.tabTextChanged.emit(1, self.tr("@Me(%d)") % reminds["mention_status"])
            num_msg += 1

        if reminds["cmt"] and self.remindComments:
            msg += self.tr("%d unread comment(s)") % reminds["cmt"] + "\n"
            self.tabTextChanged.emit(2, self.tr("Comments(%d)") % reminds["cmt"])
            num_msg += 1

        if num_msg:
            return
            self.notify.showMessage(self.tr("WeCase"), msg)

    def setTabText(self, index, string):
        self.tabWidget.setTabText(index, string)

    def moveToTop(self):
        self.get_current_tweetView().rootObject().positionViewAtBeginning()

    def setLoaded(self, tweetid):
        self.get_current_tweetView().rootObject().imageLoaded(tweetid)

    def showSettings(self):
        wecase_settings = WeSettingsWindow()
        if wecase_settings.exec_():
            self.loadConfig()
            self.applyConfig()

    def showAbout(self):
        wecase_about = AboutWindow()
        wecase_about.exec_()

    def logout(self):
        self.close()
        # This is a model dialog, if we exec it before we close MainWindow
        # MainWindow won't close
        from LoginWindow import LoginWindow

        wecase_login = LoginWindow()
        wecase_login.exec_()

    def postTweet(self):
        wecase_new = NewpostWindow()
        wecase_new.client = self.client
        wecase_new.exec_()

    @QtCore.pyqtSlot(str)
    def comment(self, idstr):
        wecase_new = NewpostWindow(action="comment", id=int(idstr))
        wecase_new.client = self.client
        wecase_new.exec_()

    @QtCore.pyqtSlot(str, str)
    def repost(self, idstr, text):
        wecase_new = NewpostWindow(action="retweet", id=int(idstr), text=text)
        wecase_new.client = self.client
        wecase_new.exec_()

    @QtCore.pyqtSlot(str, result=int)
    def favorite(self, idstr):
        try:
            self.client.favorites.create.post(id=int(idstr))
            return True
        except:
            return False

    @QtCore.pyqtSlot(str, result=bool)
    def un_favorite(self, idstr):
        try:
            self.client.favorites.destroy.post(id=int(idstr))
            return True
        except:
            return False

    @QtCore.pyqtSlot(str, str)
    def reply(self, idstr, cidstr):
        wecase_new = NewpostWindow(action="reply", id=int(idstr), cid=int(cidstr))
        wecase_new.client = self.client
        wecase_new.exec_()

    @QtCore.pyqtSlot(str, str)
    def look_orignal_pic(self, thumbnail_pic, tweetid):
        threading.Thread(group=None, target=self.fetch_open_original_pic, args=(thumbnail_pic, tweetid)).start()

    def fetch_open_original_pic(self, thumbnail_pic, tweetid):
        """Fetch and open original pic from thumbnail pic url.
           Pictures will stored in cache directory. If we already have a same
           name in cache directory, just open it. If we don't, then download it
           first."""

        if tweetid in self.download_lock:
            return
        self.download_lock.append(tweetid)
        original_pic = thumbnail_pic.replace("thumbnail", "large")  # A simple trick ... ^_^
        localfile = const.cache_path + original_pic.split("/")[-1]
        if not os.path.exists(localfile):
            urllib.request.urlretrieve(original_pic, localfile)

        self.download_lock.remove(tweetid)
        os.popen("xdg-open " + localfile)  # xdg-open is common?
        self.imageLoaded.emit(tweetid)

    def refresh(self):
        model = self.get_current_model()
        model.timelineLoaded.connect(self.moveToTop)
        # model.clear()
        # model.load()
        model.new()
        self.reset_remind()

    def get_current_tweetView(self):
        tweetViews = {0: self.homeView, 1: self.mentionsView, 2: self.commentsView, 3: self.myView}
        return tweetViews[self.tabWidget.currentIndex()]

    def get_current_model(self):
        models = {0: self.all_timeline, 1: self.mentions, 2: self.comment_to_me, 3: self.my_timeline}
        return models[self.tabWidget.currentIndex()]

    def get_current_function(self):
        functions = {
            0: self.get_all_timeline,
            1: self.get_mentions_timeline,
            2: self.get_comment_to_me,
            3: self.get_my_timeline,
        }
        return functions[self.tabWidget.currentIndex()]

    def closeEvent(self, event):
        self.timer.stop_event.set()
コード例 #19
0
ファイル: test_email.py プロジェクト: shanto268/CrateCode
from Emailer import Emailer
from Notify import Notify
import time

Notify("run8_100.bin").sendEmail()
Notify().sendPdfEmail("events_data_frame_800.pdf")
コード例 #20
0
ファイル: WeCaseWindow.py プロジェクト: cthbleachbit/WeCase
class WeCaseWindow(QtGui.QMainWindow):

    client = None
    uid = None
    timelineLoaded = QtCore.pyqtSignal(int)
    imageLoaded = QtCore.pyqtSignal(str)
    tabBadgeChanged = QtCore.pyqtSignal(int, int)
    tabAvatarFetched = QtCore.pyqtSignal(str)

    def __init__(self, parent=None):
        super(WeCaseWindow, self).__init__(parent)
        self.errorWindow = APIErrorWindow(self)
        self.setAttribute(QtCore.Qt.WA_QuitOnClose, True)
        self._iconPixmap = {}
        self.setupUi(self)
        self._setupSysTray()
        self.tweetViews = [self.homeView, self.mentionsView, self.commentsView, self.commentsMentionsTab]
        self.info = WeRuntimeInfo()
        self.client = const.client
        self.loadConfig()
        self.init_account()
        self.setupModels()
        self.IMG_AVATAR = -2
        self.IMG_THUMB = -1
        self.notify = Notify(timeout=self.notify_timeout)
        self.applyConfig()
        self.download_lock = []
        self._last_reminds_count = 0
        self._setupUserTab(self.uid(), False, True)

    def _setupTab(self, view):
        tab = QtGui.QWidget()
        layout = QtGui.QGridLayout(tab)
        layout.addWidget(view)
        view.setParent(tab)
        return tab

    def _setupCommonTab(self, timeline, view, switch=True, protect=False):
        self._prepareTimeline(timeline)
        view.setModel(timeline)
        view.userClicked.connect(self.userClicked)
        view.tagClicked.connect(self.tagClicked)
        tab = self._setupTab(view)
        self.tabWidget.addTab(tab, "")
        if switch:
            self.tabWidget.setCurrentWidget(tab)
        if protect:
            self.tabWidget.tabBar().setProtectTab(tab, True)
        return tab

    def _getSameTab(self, attr, value):
        for i in range(self.tabWidget.count()):
            try:
                tab = self.tabWidget.widget(i).layout().itemAt(0).widget()
                _value = getattr(tab.model(), attr)()
                if _value == value:
                    return i
            except AttributeError:
                pass
        return False

    def _setupUserTab(self, uid, switch=True, myself=False):
        index = self._getSameTab("uid", uid)
        if index:
            if switch:
                self.tabWidget.setCurrentIndex(index)
            return

        view = TweetListWidget()
        _timeline = TweetUserModel(self.client.statuses.user_timeline, uid,
                                   view)
        timeline = TweetFilterModel(_timeline)
        timeline.setModel(_timeline)
        tab = self._setupCommonTab(timeline, view, switch, myself)

        def setAvatar(f):
            self._setTabIcon(tab, WObjectCache().open(QtGui.QPixmap, f))

        fetcher = AsyncFetcher("".join((path.cache_path, str(self.info["uid"]))))
        fetcher.addTask(self.client.users.show.get(uid=uid)["profile_image_url"], setAvatar)

    def _setupTopicTab(self, topic, switch=True):
        index = self._getSameTab("topic", topic)
        if index:
            if switch:
                self.tabWidget.setCurrentIndex(index)
            return

        view = TweetListWidget()
        timeline = TweetTopicModel(self.client.search.topics, topic, view)
        tab = self._setupCommonTab(timeline, view, switch, protect=False)
        self._setTabIcon(tab, WObjectCache().open(
            QtGui.QPixmap, ":/IMG/img/topic.jpg"
        ))

    def userClicked(self, userItem, openAtBackend):
        try:
            self._setupUserTab(userItem.id, switch=(not openAtBackend))
        except APIError as e:
            self.errorWindow.raiseException.emit(e)

    def tagClicked(self, str, openAtBackend):
        try:
            self._setupTopicTab(str, switch=(not openAtBackend))
        except APIError as e:
            self.errorWindow.raiseException.emit(e)

    def setupUi(self, mainWindow):
        mainWindow.setWindowIcon(QtGui.QIcon(":/IMG/img/WeCase.svg"))
        mainWindow.setDocumentMode(False)
        mainWindow.setDockOptions(QtGui.QMainWindow.AllowTabbedDocks |
                                  QtGui.QMainWindow.AnimatedDocks)

        self.centralwidget = QtGui.QWidget(mainWindow)
        self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget)

        self.tabWidget = QtGui.QTabWidget(self.centralwidget)
        self.tabWidget.setTabBar(WTabBar(self.tabWidget))
        self.tabWidget.setTabPosition(QtGui.QTabWidget.West)
        self.tabWidget.setTabShape(QtGui.QTabWidget.Rounded)
        self.tabWidget.setDocumentMode(False)
        self.tabWidget.setMovable(True)
        self.tabWidget.tabCloseRequested.connect(self.closeTab)

        self.homeView = TweetListWidget()
        self.homeView.userClicked.connect(self.userClicked)
        self.homeView.tagClicked.connect(self.tagClicked)
        self.homeTab = self._setupTab(self.homeView)
        self.tabWidget.addTab(self.homeTab, "")
        self.tabWidget.tabBar().setProtectTab(self.homeTab, True)

        self.mentionsView = TweetListWidget()
        self.mentionsView.userClicked.connect(self.userClicked)
        self.mentionsView.tagClicked.connect(self.tagClicked)
        self.mentionsTab = self._setupTab(self.mentionsView)
        self.tabWidget.addTab(self.mentionsTab, "")
        self.tabWidget.tabBar().setProtectTab(self.mentionsTab, True)

        self.commentsView = TweetListWidget()
        self.commentsView.userClicked.connect(self.userClicked)
        self.commentsView.tagClicked.connect(self.tagClicked)
        self.commentsTab = self._setupTab(self.commentsView)
        self.tabWidget.addTab(self.commentsTab, "")
        self.tabWidget.tabBar().setProtectTab(self.commentsTab, True)

        self.commentsMentionsView = TweetListWidget()
        self.commentsMentionsView.userClicked.connect(self.userClicked)
        self.commentsMentionsView.tagClicked.connect(self.tagClicked)
        self.commentsMentionsTab = self._setupTab(self.commentsMentionsView)
        self.tabWidget.addTab(self.commentsMentionsTab, "")
        self.tabWidget.tabBar().setProtectTab(self.commentsMentionsTab, True)

        self.verticalLayout.addWidget(self.tabWidget)

        self.widget = QtGui.QWidget(self.centralwidget)
        self.verticalLayout.addWidget(self.widget)

        mainWindow.setCentralWidget(self.centralwidget)

        self.aboutAction = QtGui.QAction(mainWindow)
        self.refreshAction = QtGui.QAction(mainWindow)
        self.logoutAction = QtGui.QAction(mainWindow)
        self.exitAction = QtGui.QAction(mainWindow)
        self.settingsAction = QtGui.QAction(mainWindow)

        self.aboutAction.setIcon(QtGui.QIcon(QtGui.QPixmap("./IMG/img/where_s_my_weibo.svg")))
        self.exitAction.setIcon(QtGui.QIcon(QtGui.QPixmap(":/IMG/img/application-exit.svg")))
        self.settingsAction.setIcon(QtGui.QIcon(QtGui.QPixmap(":/IMG/img/preferences-other.png")))
        self.refreshAction.setIcon(QtGui.QIcon(QtGui.QPixmap(":/IMG/img/refresh.png")))

        self.menubar = QtGui.QMenuBar(mainWindow)
        self.menubar.setEnabled(True)
        self.menubar.setDefaultUp(False)
        mainWindow.setMenuBar(self.menubar)

        self.mainMenu = QtGui.QMenu(self.menubar)
        self.helpMenu = QtGui.QMenu(self.menubar)
        self.optionsMenu = QtGui.QMenu(self.menubar)

        self.mainMenu.addAction(self.refreshAction)
        self.mainMenu.addSeparator()
        self.mainMenu.addAction(self.logoutAction)
        self.mainMenu.addAction(self.exitAction)
        self.helpMenu.addAction(self.aboutAction)
        self.optionsMenu.addAction(self.settingsAction)
        self.menubar.addAction(self.mainMenu.menuAction())
        self.menubar.addAction(self.optionsMenu.menuAction())
        self.menubar.addAction(self.helpMenu.menuAction())

        self.exitAction.triggered.connect(mainWindow.close)
        self.aboutAction.triggered.connect(mainWindow.showAbout)
        self.settingsAction.triggered.connect(mainWindow.showSettings)
        self.logoutAction.triggered.connect(mainWindow.logout)
        self.refreshAction.triggered.connect(mainWindow.refresh)

        self.pushButton_refresh = QtGui.QPushButton(self.widget)
        self.pushButton_new = QtGui.QPushButton(self.widget)
        self.pushButton_refresh.clicked.connect(mainWindow.refresh)
        self.pushButton_new.clicked.connect(mainWindow.postTweet)
        self.timelineLoaded.connect(self.moveToTop)
        self.tabBadgeChanged.connect(self.drawNotifyBadge)

        self.refreshAction.setShortcut(QtGui.QKeySequence("F5"))
        self.pushButton_refresh.setIcon(QtGui.QIcon(":/IMG/img/refresh.png"))
        self.pushButton_new.setIcon(QtGui.QIcon(":/IMG/img/new.png"))

        if self.isGlobalMenu():
            self._setupToolBar()
        else:
            self._setupButtonWidget()

        self._setTabIcon(self.homeTab, QtGui.QPixmap(":/IMG/img/sina.png"))
        self._setTabIcon(self.mentionsTab, QtGui.QPixmap(":/IMG/img/mentions.png"))
        self._setTabIcon(self.commentsTab, QtGui.QPixmap(":/IMG/img/comments2.png"))
        self._setTabIcon(self.commentsMentionsTab, QtGui.QPixmap(":/IMG/img/mentions_comments.svg"))

        self.retranslateUi(mainWindow)

    def isGlobalMenu(self):
        if os.environ.get("TOOLBAR") == "1":
            return True
        elif os.environ.get("TOOLBAR") == "0":
            return False
        elif os.environ.get('DESKTOP_SESSION') in ["ubuntu", "ubuntu-2d"]:
            if not os.environ.get("UBUNTU_MENUPROXY"):
                return False
            elif os.environ.get("APPMENU_DISPLAY_BOTH"):
                return False
            else:
                return True
        elif os.environ.get("DESKTOP_SESSION") == "kde-plasma" and platform.linux_distribution()[0] == "Ubuntu":
            return True
        elif platform.system() == "Darwin":
            return True
        return False

    def _setupToolBar(self):
        self.toolBar = QtGui.QToolBar()
        self.toolBar.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
        empty = QtGui.QWidget()
        empty.setSizePolicy(QtGui.QSizePolicy.Expanding,
                            QtGui.QSizePolicy.Preferred)
        self.toolBar.addWidget(empty)
        self.toolBar.addAction(self.refreshAction)
        newAction = self.toolBar.addAction(QtGui.QIcon(":/IMG/img/new.png"),
                                           "New")
        newAction.triggered.connect(self.pushButton_new.clicked)
        self.addToolBar(self.toolBar)

    def _setupButtonWidget(self):
        self.buttonWidget = QtGui.QWidget(self)
        self.buttonLayout = QtGui.QHBoxLayout(self.buttonWidget)
        self.horizontalSpacer = QtGui.QSpacerItem(40, 20,
                                                  QtGui.QSizePolicy.Expanding,
                                                  QtGui.QSizePolicy.Minimum)
        self.buttonLayout.addSpacerItem(self.horizontalSpacer)
        self.buttonLayout.addWidget(self.pushButton_refresh)
        self.buttonLayout.addWidget(self.pushButton_new)

    def resizeEvent(self, event):
        # This is a hack!!!
        if self.isGlobalMenu():
            return
        self.buttonWidget.resize(self.menubar.sizeHint().width(),
                                 self.menubar.sizeHint().height() + 12)
        self.buttonWidget.move(self.width() - self.buttonWidget.width(),
                               self.menubar.geometry().topRight().y() - 5)

    def retranslateUi(self, frm_MainWindow):
        frm_MainWindow.setWindowTitle(self.tr("WeCase"))
        self.mainMenu.setTitle(self.tr("&WeCase"))
        self.helpMenu.setTitle(self.tr("&Help"))
        self.optionsMenu.setTitle(self.tr("&Options"))
        self.aboutAction.setText(self.tr("&About..."))
        self.refreshAction.setText(self.tr("Refresh"))
        self.logoutAction.setText(self.tr("&Log out"))
        self.exitAction.setText(self.tr("&Exit"))
        self.settingsAction.setText(self.tr("&Settings"))

    def _setupSysTray(self):
        self.systray = QtGui.QSystemTrayIcon()
        self.systray.activated.connect(self.clickedSystray)
        self.systray.setToolTip("WeCase")
        self.systray.setIcon(QtGui.QIcon(":/IMG/img/WeCase.svg"))
        self.systray.show()

        self.visibleAction = QtGui.QAction(self)
        self.visibleAction.setText(self.tr("&Hide"))
        self.visibleAction.triggered.connect(self._switchVisibility)

        self.sysMenu = QtGui.QMenu(self)
        self.sysMenu.addAction(self.visibleAction)
        self.sysMenu.addAction(self.logoutAction)
        self.sysMenu.addAction(self.exitAction)

        self.systray.setContextMenu(self.sysMenu)

    def clickedSystray(self, reason):
        if reason == QtGui.QSystemTrayIcon.Trigger:
            self._switchVisibility()
        elif reason == QtGui.QSystemTrayIcon.Context:
            pass

    def _switchVisibility(self):
        if self.isVisible():
            self.hide()
            self.visibleAction.setText(self.tr("&Show"))
        else:
            self.show()
            self.visibleAction.setText(self.tr("&Hide"))

    def _setTabIcon(self, tab, icon):
        pixmap = icon.transformed(QtGui.QTransform().rotate(90))
        icon = QtGui.QIcon(pixmap)
        self._iconPixmap[icon.cacheKey()] = pixmap
        self.tabWidget.setTabIcon(self.tabWidget.indexOf(tab), icon)
        self.tabWidget.setIconSize(QtCore.QSize(24, 24))

    def _prepareTimeline(self, timeline):
        try:
            timeline.setUsersBlacklist(self.usersBlacklist)
            timeline.setTweetsKeywordsBlacklist(self.tweetKeywordsBlacklist)
            timeline.setWordWarKeywords(self.wordWarKeywords)
            timeline.setBlockWordwars(self.blockWordwars)
        except AttributeError:
            pass
        timeline.load()

    def closeTab(self, index):
        widget = self.tabWidget.widget(index)
        self.tabWidget.removeTab(index)
        widget.deleteLater()

    def init_account(self):
        self.uid()

    def loadConfig(self):
        self.config = WConfigParser(path.myself_path + "WMetaConfig",
                                    path.config_path, "main")
        self.notify_interval = self.config.notify_interval
        self.notify_timeout = self.config.notify_timeout
        self.usersBlacklist = self.config.usersBlacklist
        self.tweetKeywordsBlacklist = self.config.tweetsKeywordsBlacklist
        self.remindMentions = self.config.remind_mentions
        self.remindComments = self.config.remind_comments
        self.wordWarKeywords = self.config.wordWarKeywords
        self.blockWordwars = self.config.blockWordwars
        self.maxRetweets = self.config.maxRetweets
        self.maxTweetsPerUser = self.config.maxTweetsPerUser
        self.mainWindow_geometry = self.config.mainwindow_geometry

    def applyConfig(self):
        try:
            self.timer.stop()
        except AttributeError:
            pass

        self.timer = WTimer(self.show_notify, self.notify_interval)
        self.timer.start()
        self.notify.timeout = self.notify_timeout
        setGeometry(self, self.mainWindow_geometry)

    def setupModels(self):
        self._all_timeline = TweetCommonModel(self.client.statuses.home_timeline, self)
        self.all_timeline = TweetFilterModel(self._all_timeline)
        self.all_timeline.setModel(self._all_timeline)
        self._prepareTimeline(self.all_timeline)

        # extra rules
        self.all_timeline.setMaxRetweets(self.maxRetweets)
        self.all_timeline.setMaxTweetsPerUser(self.maxTweetsPerUser)

        self.homeView.setModel(self.all_timeline)

        self._mentions = TweetCommonModel(self.client.statuses.mentions, self)
        self.mentions = TweetFilterModel(self._mentions)
        self.mentions.setModel(self._mentions)
        self._prepareTimeline(self.mentions)
        self.mentionsView.setModel(self.mentions)

        self._comment_to_me = TweetCommentModel(self.client.comments.to_me, self)
        self.comment_to_me = TweetFilterModel(self._comment_to_me)
        self.comment_to_me.setModel(self._comment_to_me)
        self._prepareTimeline(self.comment_to_me)
        self.commentsView.setModel(self.comment_to_me)

        self._comment_mentions = TweetCommentModel(self.client.comments.mentions, self)
        self.comment_mentions = TweetFilterModel(self._comment_mentions)
        self.comment_mentions.setModel(self._comment_mentions)
        self._prepareTimeline(self.comment_mentions)
        self.commentsMentionsView.setModel(self.comment_mentions)

    @async
    def reset_remind(self):
        typ = ""
        if self.currentTweetView() == self.homeView:
            self.tabBadgeChanged.emit(self.tabWidget.currentIndex(), 0)
        elif self.currentTweetView() == self.mentionsView:
            typ = "mention_status"
            self.tabBadgeChanged.emit(self.tabWidget.currentIndex(), 0)
        elif self.currentTweetView() == self.commentsView:
            typ = "cmt"
            self.tabBadgeChanged.emit(self.tabWidget.currentIndex(), 0)
        elif self.currentTweetView() == self.commentsMentionsView:
            typ = "mention_cmt"
            self.tabBadgeChanged.emit(self.tabWidget.currentIndex(), 0)

        if typ:
            self.client.remind.set_count.post(type=typ)

    def get_remind(self, uid):
        """this function is used to get unread_count
        from Weibo API. uid is necessary."""

        reminds = self.client.remind.unread_count.get(uid=uid)
        return reminds

    def uid(self):
        """How can I get my uid? here it is"""
        if not self.info.get("uid"):
            self.info["uid"] = self.client.account.get_uid.get().uid
        return self.info["uid"]

    def show_notify(self):
        # This function is run in another thread by WTimer.
        # Do not modify UI directly. Send signal and react it in a slot only.
        # We use SIGNAL self.tabTextChanged and SLOT self.setTabText()
        # to display unread count

        reminds = self.get_remind(self.uid())
        msg = self.tr("You have:") + "\n"
        reminds_count = 0

        if reminds['status'] != 0:
            # Note: do NOT send notify here, or users will crazy.
            self.tabBadgeChanged.emit(self.tabWidget.indexOf(self.homeTab),
                                      reminds['status'])

        if reminds['mention_status'] and self.remindMentions:
            msg += self.tr("%d unread @ME") % reminds['mention_status'] + "\n"
            self.tabBadgeChanged.emit(self.tabWidget.indexOf(self.mentionsTab),
                                      reminds['mention_status'])
            reminds_count += 1
        else:
            self.tabBadgeChanged.emit(self.tabWidget.indexOf(self.mentionsTab), 0)

        if reminds['cmt'] and self.remindComments:
            msg += self.tr("%d unread comment(s)") % reminds['cmt'] + "\n"
            self.tabBadgeChanged.emit(self.tabWidget.indexOf(self.commentsTab),
                                      reminds['cmt'])
            reminds_count += 1
        else:
            self.tabBadgeChanged.emit(self.tabWidget.indexOf(self.commentsTab), 0)

        if reminds["mention_cmt"] and self.remindMentions:
            msg += self.tr("%d unread @ME comment(s)") % reminds["mention_cmt"] + "\n"
            self.tabBadgeChanged.emit(self.tabWidget.indexOf(self.commentsMentionsTab),
                                      reminds["mention_cmt"])
            reminds_count += 1
        else:
            self.tabBadgeChanged.emit(self.tabWidget.indexOf(self.commentsMentionsTab), 0)

        if reminds_count and reminds_count != self._last_reminds_count:
            self.notify.showMessage(self.tr("WeCase"), msg)
            self._last_reminds_count = reminds_count

    def drawNotifyBadge(self, index, count):
        tabIcon = self.tabWidget.tabIcon(index)
        _tabPixmap = self._iconPixmap[tabIcon.cacheKey()]
        tabPixmap = _tabPixmap.transformed(QtGui.QTransform().rotate(-90))
        icon = NotifyBadgeDrawer().draw(tabPixmap, str(count))
        icon = icon.transformed(QtGui.QTransform().rotate(90))
        icon = QtGui.QIcon(icon)
        self._iconPixmap[icon.cacheKey()] = _tabPixmap
        self.tabWidget.setTabIcon(index, icon)

    def moveToTop(self):
        self.currentTweetView().moveToTop()

    def showSettings(self):
        wecase_settings = WeSettingsWindow()
        if wecase_settings.exec_():
            self.loadConfig()
            self.applyConfig()

    def showAbout(self):
        wecase_about = AboutWindow()
        wecase_about.exec_()

    def logout(self):
        self.close()
        # This is a model dialog, if we exec it before we close MainWindow
        # MainWindow won't close
        from LoginWindow import LoginWindow
        wecase_login = LoginWindow(allow_auto_login=False)
        wecase_login.exec_()

    def postTweet(self):
        self.wecase_new = NewpostWindow()
        self.wecase_new.userClicked.connect(self.userClicked)
        self.wecase_new.tagClicked.connect(self.tagClicked)
        self.wecase_new.show()

    def refresh(self):
        tweetView = self.currentTweetView()
        tweetView.model().timelineLoaded.connect(self.moveToTop)
        tweetView.refresh()
        self.reset_remind()

    def currentTweetView(self):
        # The most tricky part of MainWindow.
        return self.tabWidget.currentWidget().layout().itemAt(0).widget()

    def saveConfig(self):
        self.config.mainwindow_geometry = getGeometry(self)
        self.config.save()

    def closeEvent(self, event):
        self.systray.hide()
        self.hide()
        self.saveConfig()
        self.timer.stop(True)
        # Reset uid when the thread exited.
        self.info["uid"] = None
        logging.info("Die")
コード例 #21
0
ファイル: WeCaseWindow.py プロジェクト: xuefu/WeCase
class WeCaseWindow(QtGui.QMainWindow, Ui_frm_MainWindow):
    client = None
    uid = None
    imageLoaded = QtCore.pyqtSignal(str)
    tabTextChanged = QtCore.pyqtSignal(int, str)

    def __init__(self, parent=None):
        super(WeCaseWindow, self).__init__(parent)
        self.setupUi(self)
        self.tweetViews = [self.homeView, self.mentionsView,
                           self.commentsView, self.myView]
        self.client = const.client
        self.loadConfig()
        self.setupModels()
        self.init_account()
        self.IMG_AVATAR = -2
        self.IMG_THUMB = -1
        self.notify = Notify(timeout=self.notify_timeout)
        self.applyConfig()
        self.download_lock = []

    def init_account(self):
        self.get_uid()

    def loadConfig(self):
        self.config = WeCaseConfig(const.config_path)
        self.notify_interval = self.config.notify_interval
        self.notify_timeout = self.config.notify_timeout
        self.usersBlacklist = self.config.usersBlacklist
        self.tweetKeywordsBlacklist = self.config.tweetsKeywordsBlacklist
        self.remindMentions = self.config.remind_mentions
        self.remindComments = self.config.remind_comments

    def applyConfig(self):
        try:
            self.timer.stop_event.set()
        except AttributeError:
            pass

        self.timer = WTimer(self.notify_interval, self.show_notify)
        self.timer.start()
        self.notify.timeout = self.notify_timeout

    def setupModels(self):
        self.all_timeline = TweetCommonModel(self.client.statuses.home_timeline, self)
        self.all_timeline.setUsersBlacklist(self.usersBlacklist)
        self.all_timeline.setTweetsKeywordsBlacklist(self.tweetKeywordsBlacklist)
        self.all_timeline.load()
        self.homeView.setModel(self.all_timeline)

        self.mentions = TweetCommonModel(self.client.statuses.mentions, self)
        self.mentions.setUsersBlacklist(self.usersBlacklist)
        self.mentions.setTweetsKeywordsBlacklist(self.tweetKeywordsBlacklist)
        self.mentions.load()
        self.mentionsView.setModel(self.mentions)

        self.comment_to_me = TweetCommentModel(self.client.comments.to_me, self)
        self.comment_to_me.setUsersBlacklist(self.usersBlacklist)
        self.comment_to_me.setTweetsKeywordsBlacklist(self.tweetKeywordsBlacklist)
        self.comment_to_me.load()
        self.commentsView.setModel(self.comment_to_me)

        self.my_timeline = TweetCommonModel(self.client.statuses.user_timeline, self)
        self.my_timeline.setUsersBlacklist(self.usersBlacklist)
        self.my_timeline.setTweetsKeywordsBlacklist(self.tweetKeywordsBlacklist)
        self.my_timeline.load()
        self.myView.setModel(self.my_timeline)

    def reset_remind(self):
        if self.tabWidget.currentIndex() == 0:
            self.tabWidget.setTabText(0, self.tr("Weibo"))
        elif self.tabWidget.currentIndex() == 1:
            self.client.remind.set_count.post(type="mention_status")
            self.tabWidget.setTabText(1, self.tr("@Me"))
        elif self.tabWidget.currentIndex() == 2:
            self.client.remind.set_count.post(type="cmt")
            self.tabWidget.setTabText(2, self.tr("Comments"))

    def get_remind(self, uid):
        """this function is used to get unread_count
        from Weibo API. uid is necessary."""

        while 1:
            try:
                reminds = self.client.remind.unread_count.get(uid=uid)
                break
            except http.client.BadStatusLine:
                sleep(0.2)
                continue
        return reminds

    def get_uid(self):
        """How can I get my uid? here it is"""
        try:
            self.uid = self.client.account.get_uid.get().uid
        except AttributeError:
            return None

    def show_notify(self):
        # This function is run in another thread by WTimer.
        # Do not modify UI directly. Send signal and react it in a slot only.
        # We use SIGNAL self.tabTextChanged and SLOT self.setTabText()
        # to display unread count

        reminds = self.get_remind(self.uid)
        msg = self.tr("You have:") + "\n"
        num_msg = 0

        if reminds['status'] != 0:
            # Note: do NOT send notify here, or users will crazy.
            self.tabTextChanged.emit(0, self.tr("Weibo(%d)")
                                     % reminds['status'])

        if reminds['mention_status'] and self.remindMentions:
            msg += self.tr("%d unread @ME") % reminds['mention_status'] + "\n"
            self.tabTextChanged.emit(1, self.tr("@Me(%d)")
                                     % reminds['mention_status'])
            num_msg += 1

        if reminds['cmt'] and self.remindComments:
            msg += self.tr("%d unread comment(s)") % reminds['cmt'] + "\n"
            self.tabTextChanged.emit(2, self.tr("Comments(%d)")
                                     % reminds['cmt'])
            num_msg += 1

        if num_msg:
            self.notify.showMessage(self.tr("WeCase"), msg)

    def setTabText(self, index, string):
        self.tabWidget.setTabText(index, string)

    def moveToTop(self):
        self.get_current_tweetView().moveToTop()

    def setLoaded(self):
        pass

    def showSettings(self):
        wecase_settings = WeSettingsWindow()
        if wecase_settings.exec_():
            self.loadConfig()
            self.applyConfig()

    def showAbout(self):
        wecase_about = AboutWindow()
        wecase_about.exec_()

    def logout(self):
        self.close()
        # This is a model dialog, if we exec it before we close MainWindow
        # MainWindow won't close
        from LoginWindow import LoginWindow
        wecase_login = LoginWindow(allow_auto_login=False)
        wecase_login.exec_()

    def postTweet(self):
        wecase_new = NewpostWindow()
        wecase_new.exec_()

    def refresh(self):
        tweetView = self.get_current_tweetView()
        tweetView.model().timelineLoaded.connect(self.moveToTop)
        tweetView.refresh()
        self.reset_remind()

    def get_current_tweetView(self):
        tweetViews = {0: self.homeView, 1: self.mentionsView,
                      2: self.commentsView, 3: self.myView}
        return tweetViews[self.tabWidget.currentIndex()]

    def closeEvent(self, event):
        self.timer.stop_event.set()
コード例 #22
0
ファイル: heybuddy.py プロジェクト: yamatt/python-hellobuddy
class application :
	def __init__(self):
		#init threading
		gobject.threads_init()
		#keep track of the window size
		self.window_height=0
		self.window_width=0
		self.window_is_hidden = False
		self.has_status_icon = False
		#keep track of the initial conversation id so that conversations don't colide
		self.conversation_id="0"
		#keep track of the filters
		self.filters ={'users':[],'strings':[]}
		self.options={'run_as_tray_app':False,'context_backwards':False,'no_avatars':False,'notifications':True,'notify_replies':False}
		#keep track of the direct_message requests
		self.last_direct_message_time=0
		#something something direct message
		self.is_direct_message_mode=False
		self.direct_message_to=None
		self.waiting_requests=0
		self.is_first_dents = True
		#keep track of the respond to id
		self.respond_to_id=0
		self.pre_group_page=None
		self.pre_user_page=None
		#keep track of the last time statuses where pulled
		self.last_get_statuses = 0
		#what are the assets?
		asset_dir = 'assets'
		heybuddy_dir = os.path.dirname( os.path.realpath( __file__ ) )
		self.readme_file = os.path.join(heybuddy_dir,'README.txt')
		self.standard_icon_path = os.path.join(heybuddy_dir,asset_dir,'icon.png')
		self.direct_icon_path = os.path.join(heybuddy_dir,asset_dir,'direct_icon.png')
		self.networking_icon_path = os.path.join(heybuddy_dir,asset_dir,'icon1.png')
		self.throbber_icon_path = os.path.join(heybuddy_dir,asset_dir,'throbber.gif')
		self.default_icon_path = self.standard_icon_path
		self.conf = Configuration(app_name)
		#has the account info been authenticated?
		self.credentials_verified = self.conf.get_bool('access', 'credentials_verified')
		self.xmlprocessor = XMLProcessor()
		#create a regex to replace parts of a dent
		self.regex_tag = re.compile("(^| )#([\w-]+)", re.UNICODE)
		self.regex_group = re.compile("(^| )!([\w-]+)")
		self.regex_user=re.compile("(^|[^A-z0-9])@(\w+)")
		self.regex_url=re.compile("(http[s]?://.*?)(\.$|\. |\s|$)",re.IGNORECASE)
		#get the initial dents
		self.initial_dents = self.conf.get('settings','initial_dents',default='20' )
		self.dent_limit = int(self.initial_dents)*2
		#get the pull time
		self.pull_time = self.conf.get('settings','pull_time',default='60')
		self.pull_time_changed_bool = False
		self.pull_time_mentions = False
		#build the gui
		self.build_gui()
		
		#where is the certs file?
		ca_certs_files = [
			"/etc/ssl/certs/ca-certificates.crt",
			"/etc/ssl/certs/ca-bundle.crt",
			]
		#what if there isn't a cert_file
		cert_file=None
		#determine the certs_file
		for f in ca_certs_files:
			if os.path.exists(f):
				cert_file=f
				break	
		
		#create the communicator
		self.comm = Communicator(app_name, cert_file)
		self.comm.connect('statusesXML',self.process_statusesXML,self.dentspage)
		self.comm.connect('mentionsXML',self.process_statusesXML,self.mentionspage)
		self.comm.connect('favoritesXML', self.process_statusesXML,self.favoritespage)
		self.comm.connect('group-statusesXML',self.process_statusesXML,self.grouppage)
		self.comm.connect('user-statusesXML',self.process_statusesXML,self.userpage)
		self.comm.connect('direct_messagesXML',self.process_statusesXML,self.directspage,True)
		self.comm.connect('conversationXML',self.process_conversationXML)
		self.comm.connect('userXML',self.process_userXML)
		self.comm.connect('groupXML',self.process_groupXML)
		self.comm.connect('new-statusXML',self.process_new_statusXML)
		self.comm.connect('redent-statusXML',self.process_new_statusXML)
		self.comm.connect('user_is_friendXML',self.process_user_is_friendXML)
		self.comm.connect('user_is_memberXML',self.process_user_is_memberXML)
		self.comm.connect('friendshipXML',self.process_friendshipXML)
		self.comm.connect('exception-caught',self.process_communication_exception)
		self.comm.connect('widget-image',self.process_widget_image)
		self.comm.connect('direct-messageXML',self.process_new_directXML)
		self.comm.connect('verify_credentialsXML',self.process_verifycredentialsXML)
		self.comm.connect('configXML',self.process_configXML)
		#create an image cacher thingy
		self.imagecache = ImageCache()
		self.imagecache.set_disabled( self.conf.get_bool_option('no_avatars') )
		self.imagecache.connect('get-widget-image', self.get_widget_image)
	
		#Create notify-er if has pynotify
		if has_pynotify:
			self.notify = Notify()

		#align the window
		self.align_window()
		# do we need to create the status icon
		if self.conf.get_bool_option('run_as_tray_app'):
			self.create_status_icon()
		
	def build_gui(self):
		#build the GUI 
		self.mainwindow=MainWindow.MainWindow(app_name,version,branch)
		try:
			self.mainwindow.set_icon_from_file(self.default_icon_path)
		except:
			pass
		self.mainwindow.set_textlimit( self.conf.textlimit() )	
		self.mainwindow.set_ctrl_enter( self.conf.get_bool_option('ctrl_enter') )
		self.mainwindow.connect('quit', self.quit_triggered )
		self.mainwindow.connect('window-to-tray', self.window_to_tray )
		self.mainwindow.connect('update-status',self.update_status)
		self.mainwindow.connect('get-conversation',self.get_conversation)
		self.mainwindow.connect('show-user',self.get_user_info)
		self.mainwindow.connect('show-group',self.get_group_info)
		self.mainwindow.connect('notebook-page-change',self.page_change)
		self.mainwindow.connect('follow-user',self.follow_user)
		self.mainwindow.connect('join-group',self.join_group)
		self.mainwindow.connect('clear-respond-to-id',self.clear_respond_to_id)
		#keep track of the window size
		self.mainwindow.connect('size-allocate', self.window_size_allocate)
		#self.mainwindow.connect('window-state-event', self.mainwindow_state_event)
		self.mainwindow.connect('delete-event', self.mainwindow_delete_event)
		
		# local function to create a closeable tab label for closeable tabs
		def closeable_tab_label(caption, tab):
			tablabel = gtk.HBox(False,2)
			tablabel.pack_start(gtk.Label(caption),False,False,0)
			closebutton = gtk.Button()
			closeicon = gtk.Image()
			closeicon.set_from_stock(gtk.STOCK_CLOSE,gtk.ICON_SIZE_MENU)
			closebutton.set_image(closeicon)
			closebutton.set_relief(gtk.RELIEF_NONE)
			tinybutton_style = gtk.RcStyle()
			tinybutton_style.xthickness = 0
			tinybutton_style.ythickness = 0
			closebutton.modify_style(tinybutton_style)
			if tab != None:	# if this isn't a mock-add
				closebutton.connect('clicked',tab.close)
			#don't show a tooltip on maemo
			if not has_hildon:
				closebutton.set_tooltip_text(_("Close"))
			tablabel.pack_start(closebutton,False,False,0)
			tablabel.show_all()
			return tablabel

		# do a mock add of dentspage, with a close label, so as to determine height needed for uncloseable tabs' labels, then break it all down again
		# this is ridiculously hacky, but it works, and doesn't leave anything behind
		self.dentspage = ScrollPage()
		self.mock_label = closeable_tab_label(_("Dents"),None)
		self.mainwindow.notebook.append_page(self.dentspage,self.mock_label)
		self.mainwindow.show_all() # we have to do this so the tab gets actualised, and thus gets a height
		min_tab_height = self.mock_label.allocation.height
		self.mainwindow.hide_all()
		self.mainwindow.notebook.remove_page(-1)
		del self.mock_label
		
		# local function to create a label the same height as the closeable tabs' labels
		def uncloseable_tab_label(caption):
			tablabel = gtk.Label(caption)
			tablabel.set_size_request(-1,min_tab_height)
			tablabel.show()
			return tablabel
		
		# create and add all of the pages
		self.dentspage = ScrollPage()
		self.mainwindow.notebook.append_page(self.dentspage,uncloseable_tab_label(_("Dents") ) )
		
		self.mentionspage = ScrollPage()
		self.mainwindow.notebook.append_page(self.mentionspage,uncloseable_tab_label(_("Mentions")) )

		self.favoritespage = ScrollPage()
		self.mainwindow.notebook.append_page(self.favoritespage,uncloseable_tab_label(_("Favorites")) )
		
		self.directspage = ScrollPage()
		self.mainwindow.notebook.append_page(self.directspage,uncloseable_tab_label(_("Directs")) )
		
		#make the conversation page
		self.contextpage=ContextPage()
		self.contextpage.connect('context-page-hide',self.hide_contextpage)
		#add the contextpage
		context_label = closeable_tab_label(_("Context"), self.contextpage)
		self.mainwindow.notebook.append_page(self.contextpage, context_label)
		
		#create a user page
		self.userpage=UserPage()
		self.userpage.connect('user-page-hide',self.hide_userpage)
		self.userpage.connect('follow-user',self.follow_user)
		self.userpage.connect('direct-clicked',self.direct_clicked)
		self.userpage.connect('open-link',self.open_link)
		self.userpage.connect('block-create',self.block_create)
		self.userpage.connect('block-destroy',self.block_destroy)
		
		#add the userpage
		user_label = closeable_tab_label(_("User"),self.userpage ) 
		self.mainwindow.notebook.append_page(self.userpage, user_label)
		
		#create a Group page
		self.grouppage=GroupPage()
		self.grouppage.connect('group-page-hide',self.hide_grouppage)
		self.grouppage.connect('join-group',self.join_group)
		self.grouppage.connect('open-link',self.open_link)

		#add the Grouppage
		group_label = closeable_tab_label(_("Group"),self.grouppage ) 
		self.mainwindow.notebook.append_page(self.grouppage, group_label)
		
		#create and add the account page
		self.settingspage = SettingsPage(has_hildon,has_pynotify)
		self.settingspage.set_initial_dents( self.initial_dents )
		self.settingspage.set_pull_time(self.pull_time)
		#update the configuration of the settings
		self.settingspage.connect('update-account',self.update_account)
		self.options['ctrl_enter'] = self.conf.get_bool_option('ctrl_enter')
		self.settingspage.set_ctrl_enter( self.options['ctrl_enter']	)
		self.options['run_as_tray_app'] = self.conf.get_bool_option('run_as_tray_app')
		self.settingspage.set_run_as_tray_app( self.options['run_as_tray_app']	)
		self.options['context_backwards']	= self.conf.get_bool_option('context_backwards')
		self.settingspage.set_context_backwards( self.options['context_backwards'] )
		self.options['no_avatar']= self.conf.get_bool_option('no_avatars')
		self.settingspage.set_no_avatars( self.options['no_avatar'] )
		self.options['api_retweet'] = self.conf.get_bool_option('api_retweet')
		self.settingspage.set_api_retweet( self.options['api_retweet']	)
		self.options['notifications']= self.conf.get_bool_option('notifications')
		self.settingspage.set_notifications( self.options['notifications'] )
		self.options['notify_replies']= self.conf.get_bool_option('notify_replies')
		self.settingspage.set_notify_replies( self.options['notify_replies'] )
		link_color = self.conf.get('settings','link_color',default='blue')
		self.settingspage.set_link_color( link_color )
		self.theme_link_color(link_color)
		#connect the setting signals
		self.settingspage.connect('option-run-as-tray-app', self.option_changed, 'run_as_tray_app')
		self.settingspage.connect('option-ctrl-enter', self.option_changed, 'ctrl_enter')
		self.settingspage.connect('option-context-backwards',self.option_changed, 'context_backwards')
		self.settingspage.connect('option-no-avatars',self.option_changed, 'no_avatars')
		self.settingspage.connect('option-api-retweet', self.option_changed, 'api_retweet')
		self.settingspage.connect('option-notifications',self.option_changed, 'notifications')
		self.settingspage.connect('option-notify-replies',self.option_changed, 'notify_replies')
		self.settingspage.connect('initial-dents',self.set_initial_dents)
		self.settingspage.connect('pull-time',self.set_pull_time)
		self.settingspage.connect('link-color',self.set_link_color)
		self.settingspage.connect('add-string-filter', self.add_string_filter )
		self.settingspage.connect('remove-string-filter', self.remove_string_filter )
		self.settingspage.connect('add-user-filter', self.add_user_filter )
		self.settingspage.connect('remove-user-filter', self.remove_user_filter )
		#add the settings to the mainwindow
		self.mainwindow.add_notebook_page(self.settingspage,uncloseable_tab_label(_("Settings") ) )
		#create and add the about page
		about = About(version,branch,self.standard_icon_path,self.readme_file)
		about.connect('open-link',self.open_link)
		self.mainwindow.add_notebook_page( about, uncloseable_tab_label(_("About") ) )
		self.mainwindow.show_some()
		#hide some stuff
		self.grouppage.hide_all()
		self.userpage.hide_all()
		self.contextpage.hide_all()
		
	def align_window(self):
		#try to set the mainwindows size based on conf info
		try:
			w = int( self.conf.get('window_info','width') )
			h = int( self.conf.get('window_info','height') )
			self.mainwindow.resize(w,h)
		except:
			pass
		try:
			x = int( self.conf.get('window_info','x') )
			y = int( self.conf.get('window_info','y') )
			self.mainwindow.move(x,y)
		except:
			pass
		
		#get the filters
		try: 
			#read the filters
			filters = self.conf.get('settings','filters',True)
			#the filters should be an array
			if len(filters):
				#self.filters = filters
				self.filters['users']	= filters['users']
				self.filters['strings']	= filters['strings']
				#set the filters
				self.settingspage.set_string_filters( self.filters['strings'] )
				self.settingspage.set_user_filters( self.filters['users'] )
		except:
			pass
	
	def create_status_icon(self):
		if not self.has_status_icon:
			#create the statusicon
			self.statusicon = StatusIcon()
			self.statusicon.connect('activate', self.status_clicked )
			self.statusicon.connect('quit-selected',self.quit_app)
			self.statusicon.set_icon( self.standard_icon_path )
		self.statusicon.set_property("visible",True)
		self.has_status_icon=True
	
	def destroy_status_icon(self):
		self.statusicon.set_property("visible",False)
		self.has_status_icon=False
		
	def update_account(self, widget, n, p, s):
		#check if these are valid
		self.mainwindow.set_message(_("Authenticating account..."))
		self.increment_requests()
		self.comm.verify_credentials(n, p, s)
			
	def increment_requests(self):
		self.waiting_requests+=1
		if self.waiting_requests==1:
			try:
				self.mainwindow.set_icon_from_file(self.networking_icon_path)
			except:
				pass
			try:
				self.mainwindow.set_throbber(self.throbber_icon_path)
			except:
				pass
			if self.has_status_icon:
				self.statusicon.set_icon( self.networking_icon_path)
				
	def decrement_requests(self):
		self.waiting_requests-=1
		if self.waiting_requests==0:
			try:
				self.mainwindow.set_icon_from_file(self.default_icon_path)
			except:
				pass
			try:
				self.mainwindow.set_throbber(self.default_icon_path)
			except:
				pass
			if self.has_status_icon:
				self.statusicon.set_icon( self.default_icon_path )
		if self.waiting_requests<0:
			self.waiting_requests=0
	
	def valid_account_info(self, n, p, s):
		self.conf.name( n )
		self.conf.password( p )
		self.conf.service( s )
		self.conf.save()
		#update the comm
		self.comm.set_name_and_password( n,p )
		self.comm.set_service( s )
		
	def get_statuses(self,count="20"):
		if self.credentials_verified:
			#do some time handling for the good doctor
			now = time.time()
			if now - self.last_get_statuses > 2*self.pull_time:
				count = self.initial_dents
			self.last_get_statuses = now
			self.increment_requests()
			self.comm.get_statuses(count=count, since=highest_id['dent_previous'])
			#clean up the garbage
			gc.collect()
	
	def get_mentions(self,count="20"):
		if self.credentials_verified:
			self.increment_requests()
			self.comm.get_mentions(count=count,since=highest_id['mention_previous'])

	def get_favorites(self):
		if self.credentials_verified:
			self.increment_requests()
			self.comm.get_favorites()
	
	def get_direct_messages(self):
		if self.credentials_verified:
			now = time.time()
			#NOTE this could be changed to 3 minutes just setting it 
			#this way for now
			#has it been 3 times the pull time?
			if now - (3 * int(self.pull_time) ) > self.last_direct_message_time:
				self.increment_requests()
				self.comm.get_direct_messages(highest_id['direct_previous'])	
				self.last_direct_message_time=now
	
	def run(self, enable_logging=False):
		self.logging = enable_logging
		#start the communicator
		self.comm.start()
		self.main_loop = gobject.MainLoop()
		
		#we have to temporarily show the various pages or nothing works
		''' why the f**k do I need to do this? '''
		self.mainwindow.set_notebook_page(DIRECT)
		self.mainwindow.set_notebook_page(MENTION)
		self.mainwindow.set_notebook_page(FAVORITE)
		self.mainwindow.set_notebook_page(DENT)
		#send the service to the settings page
		self.settingspage.set_service(self.conf.service() )
		#did the conf read a name and password?
		if( self.conf.name() !="" and self.conf.password()!=""):
			if self.credentials_verified:
				self.comm.set_name_and_password( self.conf.name(),self.conf.password() )
				self.comm.set_service( self.conf.service() )
				#fill the Account tab name/pw fields to show the user that they're logged in
				self.settingspage.set_name(self.conf.name())
				self.settingspage.set_password(self.conf.password())
				#add a function to the main loop
				gobject.timeout_add(int(self.pull_time)*1000, self.update_statuses )
				gobject.timeout_add(int(self.pull_time)*1500, self.update_mentions )
				#add a timout to get dents
				gobject.timeout_add(500,self.get_statuses,self.initial_dents )
				gobject.timeout_add(600,self.get_mentions,self.initial_dents )
			#gobject.timeout_add(1000,self.get_direct_messages )
		else:
			#set the focus on the account page; the last page
			self.mainwindow.set_notebook_page(ACCOUNT)
		
		self.mainwindow.run()
		self.main_loop.run()
		#if we ever get here, we should quit

	def update_statuses(self):
		self.get_statuses()
		if(self.pull_time_changed_bool):
			self.pull_time_changed_bool= False
			gobject.timeout_add(int(self.pull_time)*1000, self.update_statuses)
			return False
		return True
	
	def update_mentions(self):
		self.get_mentions()
		if(self.pull_time_mentions):
			self.pull_time_mentions=False
			gobject.timeout_add(int(self.pull_time)*1500, self.update_mentions)
			return False
		return True
	
	def update_direct_messages(self):
		self.get_direct_messages()
		return True
	
	def update_status(self,widget,text):
		self.increment_requests()
		#remove newlines from text
		text=text.replace("\n","")
		#is this direct message mode?
		if self.is_direct_message_mode:
			self.comm.send_direct_message(text,self.direct_message_to)
			self.set_is_direct_message_mode(False)
		else:
			self.comm.send_update_status(text,self.respond_to_id)
		self.clear_respond_to_id()
		
	def quit_app(self,widget=None):
		#quit the communicator loop
		self.comm.quit()
		#quit the main loop
		self.main_loop.quit()
		
	def get_widget_image(self,imagecache,image):
		self.comm.get_widget_image(image)
	
	def get_conversation(self,id,conversation_id):
		if self.credentials_verified:
			self.increment_requests()
			self.comm.get_conversation(id,conversation_id)
	
	def parse_profile(self, profile=None, name=None ):
		#is this a remote user?
		remote_user = True
		service = ''
		#did we get a name?
		if profile!=None:
			bits = profile.rsplit("/")
			service = bits[2]
			if name==None:
				name = bits[3]
				#if there is no name, use the first subdomain as a name
				if name==None:
					dot_split = service.split(".")
					name = dot_split[0]
			if service==self.conf.service():
				remote_user = False
		else:
			remote_user = False
		return {'service':service, 'remote':remote_user,'name':name}
	
	def get_user_info(self, profile=None, name=None):
		#parse the info
		result = self.parse_profile( profile, name )
		#is this a remote user?
		remote_user = result['remote']
		name = result['name']
		service = result['service']
		
		#is this not a remote user?
		if not remote_user:
			if self.credentials_verified:
				self.increment_requests()
				self.comm.get_user_info(name)
				self.increment_requests()
				self.comm.get_user_statuses(name)
			return
	
		self.increment_requests()
		self.comm.get_remote_user_info(service,name)
		self.increment_requests()
		self.comm.get_remote_user_statuses(service,name)
		
	
	def get_group_info(self,name):
		if self.credentials_verified:
			self.increment_requests()
			self.comm.get_group_info(name)
	
	def follow_user(self,widget,name,bool):
		if self.credentials_verified:
			if bool:
				self.comm.friendship_create(name)
			else:
				self.comm.friendship_destroy(name)
	
	def join_group(self,widget,name,bool):
		if self.credentials_verified:
			if bool:
				self.comm.group_join(name)
			else:
				self.comm.group_leave(name)
	
	def process_friendshipXML(self,widget,text):
		pass
	
	def page_change(self,widget,old_id,new_id):
		if new_id==MainWindow.DIRECT:
			self.get_direct_messages()
		elif new_id==MainWindow.FAVORITE:
		    self.get_favorites()
		else:
			if self.is_direct_message_mode:
				self.set_is_direct_message_mode(False)
		#should we clear any warning message?
		self.mainwindow.clear_message()
	
	def process_userXML(self,comm,text):
		self.decrement_requests()
		data = self.xmlprocessor.get_user_info(text)
		if data['profile_image_url']!=None:
			self.imagecache.add_image_to_widget(data['profile_image_url'],self.userpage)
		self.userpage.set_user_data(data)
	
	def process_groupXML(self,comm,text):
		self.decrement_requests()
		data = self.xmlprocessor.get_group_info(text)
		if data['stream_logo']!=None:
			self.imagecache.add_image_to_widget(data['stream_logo'],self.grouppage)
		'''#is this user a member of this group
		self.increment_requests()
		self.comm.get_user_is_member(data['id'])'''
		self.increment_requests()
		self.comm.get_group_statuses(data['id'])
		self.grouppage.set_group_data(data)
	
	def process_user_is_friendXML(self,comm,text):
		self.decrement_requests()
		is_friend = self.xmlprocessor.get_user_is_friend(text)
		self.mainwindow.display_user_is_friend( is_friend )
	
	def process_user_is_memberXML(self,comm,text):
		self.decrement_requests()
		is_member = self.xmlprocessor.get_user_is_member(text)
		self.mainwindow.display_user_is_member( is_member )
	
	def process_new_directXML(self,comm,text):
		#a update status was sent
		self.decrement_requests()
		#clear the textview thing
		self.mainwindow.emit_update_textview_responsed()
	
	def process_new_statusXML(self,comm,text):
		#a update status was sent
		self.decrement_requests()
		#clear the textview thing
		self.mainwindow.emit_update_textview_responsed()
		#there is one status and it is the DOM
		status = self.xmlprocessor.get_dom(text)
		data = self.xmlprocessor.get_dent_data(status)
		data['markup'] = self.markup_dent_text(data['text'])
		#add the dent
		dent = self.connect_dent(data,self.dentspage)

	def process_verifycredentialsXML(self, object, text, data):
		#actually, if we are here, the authorization worked!
		self.conf.set('access', 'credentials_verified', True)
		self.credentials_verified = True
		self.mainwindow.message_label.hide()
		(n, p, s) = data
		self.valid_account_info(n, p, s)
		#get the config
		self.comm.get_config()
		#switch to the dents page
		self.mainwindow.set_notebook_page(DENT) 
		self.get_statuses()
		self.get_mentions()

	def process_conversationXML(self,object,text,conversation_id):
		self.decrement_requests()
		#is this the current conversation Id? if not, then do nothing
		#convert to int because there is a problem with string comparison
		'''is one of the strings unicode?'''
		if int(self.conversation_id)==int(conversation_id):
			#get the status
			status = self.xmlprocessor.get_dom(text)
			data = self.xmlprocessor.get_dent_data(status)
			data['markup']=self.markup_dent_text(data['text'])
			#since this is a conversation, we can get rid of the in_reply_to_screen_name
			data['in_reply_to_screen_name']=None
			#tell the mainWindow to add the dent
			dent = self.connect_dent(data,self.contextpage,True, self.options['context_backwards'] )
			if data['in_reply_to_id']!=None:
				#recursively get in_reply_to_ids
				self.get_conversation(id=data['in_reply_to_id'],conversation_id=conversation_id)

	def process_configXML(self, object, text):
		self.decrement_requests()
		server = self.xmlprocessor.get_server_config(text)
		print server
		self.conf.textlimit( server['textlimit'] )
		self.conf.save()
		self.mainwindow.set_textlimit( server['textlimit'] )

	def connect_dent(self,data,target_page,is_conv=False,conv_backwards=False,is_direct_dent=False):
		#make the dent
		dent = Dent(data,is_direct=is_direct_dent)
		if target_page.dentScroller.add_dent( dent, is_conv, conv_backwards ):
			dent.connect('group-clicked', self.view_group)
			dent.connect('reply-clicked', self.reply_clicked)
			dent.connect('direct-clicked', self.direct_clicked)
			dent.connect('view-conversation-clicked', self.view_conversation)
			dent.connect('user-clicked', self.view_user_name)
			dent.connect('profile-clicked', self.view_user_profile)
			dent.connect('id-clicked', self.view_id)
			dent.connect('text-label-clicked',self.dent_text_clicked)
			dent.connect('redent-clicked',self.redent_clicked)
			dent.connect('favorite-clicked',self.favorite_clicked)
			dent.connect('unfavorite-clicked',self.unfavorite_clicked)
			dent.connect('open-link',self.open_link)
			if target_page!=self.userpage:
				#get the image for this dent
				self.imagecache.add_image_to_widget(data['profile_image_url'],dent)
			return True
		else:
			dent.destroy()
			del dent
			return False
			
	def reply_clicked(self,dent,name):
		#set the text buffer
		self.mainwindow.update_textbuffer.set_text("@%s " % (name) )
		self.mainwindow.update_textview.grab_focus()
		#set the respond_to_id
		self.respond_to_id=dent.id

	
	def favorite_clicked(self,dent):
		id=dent.id
		self.comm.favorite(id)
	
	def unfavorite_clicked(self,dent):
		id=dent.id
		self.comm.unfavorite(id)
	
	def direct_clicked(self,widget,name):
		self.direct_message_to = name
		if type(widget).__name__=="Dent":
			self.respond_to_id=widget.id
		else:
			self.respond_to_id=None
		self.set_is_direct_message_mode(True,name)
		#we should be on the directs page
		self.mainwindow.set_notebook_page(DIRECT)
		#set the text buffer
		self.mainwindow.update_textbuffer.set_text("")
		self.mainwindow.update_textview.grab_focus()
	
	def view_conversation(self,dent,id):
		self.conversation_id=id
		self.pre_context_page=self.mainwindow.notebook_current_page
		self.contextpage.dentScroller.clear()
		self.contextpage.show_all()
		#get conversation starting with id
		self.get_conversation(id,id)
		self.mainwindow.notebook.set_current_page(CONTEXT)
		
	def view_user_profile(self, widget, profile_url, screen_name):
		self.get_user_info(profile=profile_url, name=screen_name)
		#self.get_user_info(screen_name)
		self.pre_user_page=self.mainwindow.notebook_current_page
		#make the user page checkbox insensitive
		self.userpage.disable()
		#show the page 
		self.userpage.show_all()
		#rehide its collapsed widgetbox, that doesn't need to be visible yet
		self.userpage.widgetbox_collapsed.hide()
		#clear the userpage stuff
		self.userpage.clear()
		#change to the user page
		self.mainwindow.set_notebook_page(USER)
			
	def view_id(self, widget, id):
		url = 'http://%s/notice/%s' % (self.conf.service(), id)
		self.open_link(None, url)
		
	def view_user_name(self, widget, screen_name):
		#TODO: merge this function with view_user_profile
		self.get_user_info(name=screen_name)
		#self.get_user_info(screen_name)
		self.pre_user_page=self.mainwindow.notebook_current_page
		#make the user page checkbox insensitive
		self.userpage.disable()
		#show the page 
		self.userpage.show_all()
		#rehide its collapsed widgetbox, that doesn't need to be visible yet
		self.userpage.widgetbox_collapsed.hide()
		#clear the userpage stuff
		self.userpage.clear()
		#change to the user page
		self.mainwindow.set_notebook_page(USER)	
			
	#does this function even get called? get rid of it
	def get_dent_time(self,text):
		#print text
		pass
		
	def markup_dent_text(self,text,is_notification=False):
		#process the text to markup
		#xmlencode the string
		text = self.xmlprocessor.xmlentities(text)
		#regex find the highlights
		markup = self.regex_tag.sub(r'\1#<b>\2</b>',text)
		#regex find users
		if has_hildon or links_unavailable or is_notification:
			markup = self.regex_group.sub(r'\1!<b>\2</b>',markup)
			markup = self.regex_user.sub(r'\1@<b>\2</b>',markup)
		else:
			#find urls
			markup = self.regex_url.sub(r'<a href="\1">\1</a>\2',markup)
			markup = self.regex_user.sub(r'\1@<a href="@\2">\2</a>',markup)
			markup = self.regex_group.sub(r'\1!<a href="!\2">\2</a>',markup)
		return markup
	
	def process_statusesXML(self,object,text,target_page,is_direct=False):
		#based on the target, what is the counting thingy?
		count_ref=None
		if target_page==self.dentspage:
			count_ref = "dent"
		elif target_page==self.mentionspage:
			count_ref = "mention"
		elif target_page==self.directspage:
			count_ref = "direct"
		self.decrement_requests()
		#set the "previous" count ref, do this now and get data twice
		if count_ref!=None:
			highest_id[count_ref+"_previous"] = highest_id[count_ref]
		#get a list of the statuses
		statuses = self.xmlprocessor.get_statuses(text,is_direct)
		#if there aren't any statuses, return
		if len(statuses)==0:
			return
		#reverse the statuses list
		statuses.reverse()
		dent_count=0
		reply_count=0
		#what is the highest id of the target index?	
		for status in statuses:
			filtered_status = False
			data = self.xmlprocessor.get_dent_data(status)

			if target_page==self.dentspage:
				#we should check for filtration
				filtered = self.check_filtered( data )
				filtered_status=filtered[0]
			if not filtered_status:
				#get the markup
				data['markup'] = self.markup_dent_text(data['text'])
				#did this dent connect
				if not self.connect_dent(data,target_page,is_direct_dent=is_direct):
					continue

				#if the target_page = 0 and not first_dents and not is_conf
				if target_page==self.dentspage and not self.is_first_dents:
					if "@"+self.conf.name() in data['markup']:					
						dent=self.connect_dent(data, self.mentionspage )
						reply_count+=1
						if self.options['notify_replies'] and has_pynotify:
							user = data['screen_name']
							#the message shouldn't be marked up if the server doesn't understand markup
							if notifier_reads_markup:
								message = self.markup_dent_text(data['text'],True)
							else:
								message = data['text']
							avatar = self.imagecache.get_image_path(data['profile_image_url'])
							self.notify.notify_reply(user,message,avatar)
					else:
						dent_count+=1
			else:
				self.log("filter #%s %s" %(data['status_id'], filtered[1] ) )
		
		#keep track of the last status_id			
		if count_ref!=None and data!=None:
				highest_id[count_ref]=data['status_id']
				
		self.is_first_dents=False
		#get the related images
		self.imagecache.get_images()
		#do we notify?
		if (dent_count!=0 or reply_count!=0) and has_pynotify and target_page==self.dentspage:
			if self.options['notifications']:
				if not self.options['notify_replies']:
					self.notify.notify_updates_replies(dent_count,reply_count,self.standard_icon_path)
				else:
					if dent_count!=0:
						self.notify.notify_updates(dent_count,self.standard_icon_path)
		#prune off the extra dents
		target_page.dentScroller.prune(self.dent_limit)
		
	def process_widget_image(self,comm,data,name):
		self.imagecache.widget_image_add(data,name)	
		
	def process_communication_exception(self,communicator,code,data,signal=None):
		if self.logging:
			self.log("code:%s, signal:%s" % (code,signal) )
		self.decrement_requests()
		#is there an error message?
		try:
			error_message = self.xmlprocessor.get_error_message(data)
		except:
			error_message = False
		if error_message and not code:
			self.mainwindow.set_message( error_message, MainWindow.ERROR_MESSAGE)
		elif code=='401': 
			#bad authorization
			self.mainwindow.set_notebook_page(MainWindow.ACCOUNT)
			error_message = _("Invalid Authorization: Your name or password is incorrect")
		elif code == '404':
			error_message = _("Service Not Found")
		elif code == '503':
			error_message = _("Service Unavailable")
		elif code == 'unknown error':
			error_message = _("Unknown Error")
		else:
			error_message = code
		#send the error message
		self.mainwindow.set_message(error_message, MainWindow.ERROR_MESSAGE)
		
		#a signal may have been passed from the comm
		if signal == "new-statusXML":
			#a dent was sent but it failed
			self.mainwindow.emit_update_textview_responsed(error=True)
	
	#functions to handle the filtration system
	def add_string_filter(self,winder,string):
		if not string in self.filters['strings']:
			self.filters['strings'].append(string)
			self.filters['strings'].sort()
			self.settingspage.set_string_filters( self.filters['strings'] )
		
	def remove_string_filter(self,winder,string):
		if string in self.filters['strings']:
			self.filters['strings'].remove(string)
			self.settingspage.set_string_filters( self.filters['strings'] )
			
	def add_user_filter(self,winder,user):
		if not user in self.filters['users']:
			self.filters['users'].append(user)
			self.filters['users'].sort()
			self.settingspage.set_user_filters( self.filters['users'] )
		
	def remove_user_filter(self,winder,user):
		if user in self.filters['users']:
			self.filters['users'].remove(user)
			self.settingspage.set_user_filters( self.filters['users'] )
	
	def check_filtered(self,data):
		if len(self.filters['users'])!=0 :
			#filter against the user
			for user in self.filters['users']:
				if data['screen_name'].lower()==user.lower():
					return (True, "user: %s" % data['screen_name'] )
		
		if len(self.filters['strings'])!=0:
			#filter against the strings
			#get the dent text
			text = data['text']
			#loop through the filter strings
			for string in self.filters['strings']:
				if re.search(string,text, flags=re.IGNORECASE):
					return (True, "string: %s" % string )
		#if we get this far, just return
		return (False, None)		
	
	def status_clicked(self,widget):
		if self.window_is_hidden==True:
			self.window_is_hidden=False
			self.mainwindow.show()
			self.align_window()
			self.mainwindow.present()
		else:
			self.window_to_tray(widget)

	def window_size_allocate(self,widget,size):
		self.window_width = size[2]
		self.window_height = size[3]
			
	def save_app_info(self):
		#save the filters
		self.conf.set('settings','filters', self.filters ,True)
		#save the window info
		self.conf.set('window_info','width', self.window_width )
		self.conf.set('window_info','height', self.window_height )
		try:
			#some themes don't pass root origin?
			origin = self.mainwindow.window.get_root_origin()
			self.window_x = origin[0]
			self.window_y = origin[1]
			self.conf.set('window_info','x', self.window_x )
			self.conf.set('window_info','y', self.window_y )
		except:
			pass
		self.conf.save()
		
	def mainwindow_delete_event(self,window,event=None):
		self.save_app_info()
		#are we in tray mode?
		if self.conf.get_bool_option('run_as_tray_app') or self.has_status_icon:
			#is the status icon embedded?
			if self.statusicon.is_embedded():
				self.window_is_hidden=True
				self.mainwindow.hide_on_delete()
				#do not propogate the signal
				return True
		else:
			#we need to quit
			self.quit_app()
			
	def quit_triggered(self,widget):
		self.save_app_info()
		self.quit_app()
	
	def option_changed(self,widget,value,option):
		#save the option change in the configuration
		self.conf.set('options',option,value)
		self.options[option]=value
		self.conf.save()
		#is this the run_tray_app:
		if option=='run_as_tray_app':
			if value:
				self.create_status_icon()
			else:
				self.destroy_status_icon()
		elif option=='no_avatars':
			self.imagecache.set_disabled(value)
		elif option=='ctrl_enter':
			self.mainwindow.set_ctrl_enter(value)
		 
	def redent_clicked(self,dent,name,text):
		if self.options['api_retweet']:
			self.comm.send_redent(dent.id)
		else:
			self.respond_to_id=dent.id
			#formatted_text= u'\u267A @%s: %s' % (name,text)
			formatted_text= u'\u267A @%s: %s' % (name,text)
			self.mainwindow.update_textbuffer.set_text(formatted_text )
			self.mainwindow.update_textview.grab_focus()
	 
	def view_group(self,widget,group_name):
		#where were we?
		self.pre_group_page=self.mainwindow.notebook_current_page
		#make some flags
		self.grouppage.joined_checkbutton.set_sensitive(False)
		#make the grouppage visible
		self.grouppage.show_all()
		#rehide its collapsed widgetbox, that doesn't need to be visible yet
		self.grouppage.widgetbox_collapsed.hide()
		#clear the grouppage
		self.grouppage.clear()
		#switch to the group page
		self.mainwindow.set_notebook_page(GROUP)
		#get the group info
		self.get_group_info(group_name)

	def hide_contextpage(self,widget):
		#end any conversation in progress
		self.conversation_id="0"
		self.mainwindow.set_notebook_page( self.pre_context_page )
		self.contextpage.hide()

	def hide_grouppage(self,widget):
		self.mainwindow.set_notebook_page( self.pre_group_page )
		self.grouppage.hide()

	def hide_userpage(self,widget):
		self.mainwindow.set_notebook_page( self.pre_user_page )
		self.userpage.hide()

	def dent_text_clicked(self,dent,text_label):
		self.mainwindow.last_clicked_label = text_label

	def clear_respond_to_id(self,widget=None):
		self.respond_to_id=0
		
	def set_initial_dents(self,widget,value):
		self.initial_dents=value
		self.dent_limit = int(self.initial_dents)*2
		self.conf.set('settings','initial_dents',value)
		
		
	def set_pull_time(self, widget,value):
		"""A method for setting the time between pulls. obvious comment
		is obvious. Very possible everything will die now that I've added
		this. 
		--Muel Kiel (aka samsnotunix)"""
		self.pull_time=value
		self.conf.set('settings','pull_time',value)
		self.pull_time_changed_bool = True
		self.pull_time_mentions = True
	
	def set_link_color(self,widget,string):
		self.conf.set('settings','link_color',string)
		self.theme_link_color(string)
		
	def theme_link_color(self,color):
		style='''
		style "label" {
			GtkLabel::link-color="%s"
		}
		widget_class "*GtkLabel" style "label"
		''' % (color)
		gtk.rc_parse_string(style)
		#f**k you GTK for not make this work, more than once!
	
	#functions for blocking/unblocking
	def block_create(self,widget,user_id):
		self.comm.block_create(user_id)
		
	def block_destroy(self,widget,user_id):
		self.comm.block_destroy(user_id)
		
		
	def set_is_direct_message_mode(self,mode,user=None):
		self.is_direct_message_mode=mode
		self.mainwindow.set_is_direct_message_mode(mode,user)
		if mode:
			self.default_icon_path=self.direct_icon_path
		else:
			self.default_icon_path=self.standard_icon_path
		#if we aren't waiting on any requests, swap the graphic
		if self.waiting_requests==0:
			try:
				self.mainwindow.set_icon_from_file(self.default_icon_path)
			except:
				pass
			try:
				self.mainwindow.set_throbber(self.default_icon_path)
			except:
				pass
			
	def simple_decrement(self,text=None,data=None):
		self.decrement_requests()

	'''
	function window_to_tray
	sets the run_as_tray_app to true and minimizes the app
	'''
	def window_to_tray(self,window):
		if self.options['run_as_tray_app']:
			self.mainwindow_delete_event(window)
			
			
	def open_link(self, widget, uri):
		webbrowser.open(uri)
		return True
		'''
		command = "xdg-open '%s'" % ( uri )
		#print command
		subprocess.Popen(command,shell=True)
		return True
		'''

	def log(self,string):
		if self.logging:
			now = time.strftime("%H:%M:%S")
			file = os.path.join( os.path.expanduser("~"),"heybuddy.log")
			f = open(file,'a')
			f.write("%s %s\n" % (now,string) )
			f.close() 
コード例 #23
0
def localJob(outputFile):
    fileName = outputFile.split("/")[1]
    Notify(fileName).sendLocalStorageEmail()
    print("Saving raw data file locally....\n")
コード例 #24
0
ファイル: heybuddy.py プロジェクト: yamatt/python-hellobuddy
	def __init__(self):
		#init threading
		gobject.threads_init()
		#keep track of the window size
		self.window_height=0
		self.window_width=0
		self.window_is_hidden = False
		self.has_status_icon = False
		#keep track of the initial conversation id so that conversations don't colide
		self.conversation_id="0"
		#keep track of the filters
		self.filters ={'users':[],'strings':[]}
		self.options={'run_as_tray_app':False,'context_backwards':False,'no_avatars':False,'notifications':True,'notify_replies':False}
		#keep track of the direct_message requests
		self.last_direct_message_time=0
		#something something direct message
		self.is_direct_message_mode=False
		self.direct_message_to=None
		self.waiting_requests=0
		self.is_first_dents = True
		#keep track of the respond to id
		self.respond_to_id=0
		self.pre_group_page=None
		self.pre_user_page=None
		#keep track of the last time statuses where pulled
		self.last_get_statuses = 0
		#what are the assets?
		asset_dir = 'assets'
		heybuddy_dir = os.path.dirname( os.path.realpath( __file__ ) )
		self.readme_file = os.path.join(heybuddy_dir,'README.txt')
		self.standard_icon_path = os.path.join(heybuddy_dir,asset_dir,'icon.png')
		self.direct_icon_path = os.path.join(heybuddy_dir,asset_dir,'direct_icon.png')
		self.networking_icon_path = os.path.join(heybuddy_dir,asset_dir,'icon1.png')
		self.throbber_icon_path = os.path.join(heybuddy_dir,asset_dir,'throbber.gif')
		self.default_icon_path = self.standard_icon_path
		self.conf = Configuration(app_name)
		#has the account info been authenticated?
		self.credentials_verified = self.conf.get_bool('access', 'credentials_verified')
		self.xmlprocessor = XMLProcessor()
		#create a regex to replace parts of a dent
		self.regex_tag = re.compile("(^| )#([\w-]+)", re.UNICODE)
		self.regex_group = re.compile("(^| )!([\w-]+)")
		self.regex_user=re.compile("(^|[^A-z0-9])@(\w+)")
		self.regex_url=re.compile("(http[s]?://.*?)(\.$|\. |\s|$)",re.IGNORECASE)
		#get the initial dents
		self.initial_dents = self.conf.get('settings','initial_dents',default='20' )
		self.dent_limit = int(self.initial_dents)*2
		#get the pull time
		self.pull_time = self.conf.get('settings','pull_time',default='60')
		self.pull_time_changed_bool = False
		self.pull_time_mentions = False
		#build the gui
		self.build_gui()
		
		#where is the certs file?
		ca_certs_files = [
			"/etc/ssl/certs/ca-certificates.crt",
			"/etc/ssl/certs/ca-bundle.crt",
			]
		#what if there isn't a cert_file
		cert_file=None
		#determine the certs_file
		for f in ca_certs_files:
			if os.path.exists(f):
				cert_file=f
				break	
		
		#create the communicator
		self.comm = Communicator(app_name, cert_file)
		self.comm.connect('statusesXML',self.process_statusesXML,self.dentspage)
		self.comm.connect('mentionsXML',self.process_statusesXML,self.mentionspage)
		self.comm.connect('favoritesXML', self.process_statusesXML,self.favoritespage)
		self.comm.connect('group-statusesXML',self.process_statusesXML,self.grouppage)
		self.comm.connect('user-statusesXML',self.process_statusesXML,self.userpage)
		self.comm.connect('direct_messagesXML',self.process_statusesXML,self.directspage,True)
		self.comm.connect('conversationXML',self.process_conversationXML)
		self.comm.connect('userXML',self.process_userXML)
		self.comm.connect('groupXML',self.process_groupXML)
		self.comm.connect('new-statusXML',self.process_new_statusXML)
		self.comm.connect('redent-statusXML',self.process_new_statusXML)
		self.comm.connect('user_is_friendXML',self.process_user_is_friendXML)
		self.comm.connect('user_is_memberXML',self.process_user_is_memberXML)
		self.comm.connect('friendshipXML',self.process_friendshipXML)
		self.comm.connect('exception-caught',self.process_communication_exception)
		self.comm.connect('widget-image',self.process_widget_image)
		self.comm.connect('direct-messageXML',self.process_new_directXML)
		self.comm.connect('verify_credentialsXML',self.process_verifycredentialsXML)
		self.comm.connect('configXML',self.process_configXML)
		#create an image cacher thingy
		self.imagecache = ImageCache()
		self.imagecache.set_disabled( self.conf.get_bool_option('no_avatars') )
		self.imagecache.connect('get-widget-image', self.get_widget_image)
	
		#Create notify-er if has pynotify
		if has_pynotify:
			self.notify = Notify()

		#align the window
		self.align_window()
		# do we need to create the status icon
		if self.conf.get_bool_option('run_as_tray_app'):
			self.create_status_icon()
コード例 #25
0
class NewpostWindow(QtGui.QDialog, Ui_NewPostWindow):
    image = None
    apiError = QtCore.pyqtSignal(Exception)
    commonError = QtCore.pyqtSignal(str, str)
    sendSuccessful = QtCore.pyqtSignal()
    userClicked = QtCore.pyqtSignal(UserItem, bool)
    tagClicked = QtCore.pyqtSignal(str, bool)
    tweetRefreshed = QtCore.pyqtSignal()
    tweetRejected = QtCore.pyqtSignal()

    def __init__(self, action="new", tweet=None, parent=None):
        super(NewpostWindow, self).__init__(parent)
        self.setAttribute(QtCore.Qt.WA_QuitOnClose, False)
        self.client = const.client
        self.tweet = tweet
        self.action = action
        self.setupUi(self)
        self.textEdit.callback = self.mentions_suggest
        self.textEdit.mention_flag = "@"
        self.notify = Notify(timeout=1)
        self._sent = False
        self.apiError.connect(self.showException)
        self.sendSuccessful.connect(self.sent)
        self.commonError.connect(self.showErrorMessage)
        self.errorWindow = APIErrorWindow(self)

        if self.action not in ["new", "reply"]:
            self.tweetRefreshed.connect(self._create_tweetWidget)
            self.tweetRejected.connect(
                lambda: self.pushButton_send.setEnabled(False))
            self._refresh()

    def setupUi(self, widget):
        super(NewpostWindow, self).setupUi(widget)
        self.sendAction = QtGui.QAction(self)
        self.sendAction.triggered.connect(self.send)
        self.sendAction.setShortcut(QtGui.QKeySequence("Ctrl+Return"))
        self.addAction(self.sendAction)

        self.checkChars()
        self.setupButtons()

    def setupButtons(self):
        # Disabled is the default state of buttons
        self.pushButton_picture.setEnabled(False)
        self.chk_repost.setEnabled(False)
        self.chk_comment.setEnabled(False)
        self.chk_comment_original.setEnabled(False)

        if self.action == "new":
            assert (not self.tweet)  # Shouldn't have a tweet object.
            self.pushButton_picture.setEnabled(True)
        elif self.action == "retweet":
            self.chk_comment.setEnabled(True)
            if self.tweet.type == TweetItem.RETWEET:
                self.textEdit.setText(self.tweet.append_existing_replies())
                self.chk_comment_original.setEnabled(True)
        elif self.action == "comment":
            self.chk_repost.setEnabled(True)
            if self.tweet.type == TweetItem.RETWEET:
                self.chk_comment_original.setEnabled(True)
        elif self.action == "reply":
            self.chk_repost.setEnabled(True)
            if self.tweet.original.type == TweetItem.RETWEET:
                self.chk_comment_original.setEnabled(True)
        else:
            assert False

    @async
    def _refresh(self):
        # The read count is not a real-time value. So refresh it now.
        try:
            self.tweet.refresh()
        except APIError as e:
            self.errorWindow.raiseException.emit(e)
            self.tweetRejected.emit()
            return
        self.tweetRefreshed.emit()

    def _create_tweetWidget(self):
        if self.action == "comment" and self.tweet.comments_count:
            self.tweetWidget = SingleTweetWidget(self.tweet,
                                                 ["image", "original"], self)
            self.replyModel = TweetUnderCommentModel(
                self.client.api("comments/show"), self.tweet.id, self)
        elif self.action == "retweet" and self.tweet.retweets_count:
            if self.tweet:
                self.tweetWidget = SingleTweetWidget(self.tweet,
                                                     ["image", "original"],
                                                     self)
            elif self.tweet.original:
                self.tweetWidget = SingleTweetWidget(self.tweet.original,
                                                     ["image", "original"],
                                                     self)
            self.replyModel = TweetRetweetModel(
                self.client.api("statuses/repost_timeline"), self.tweet.id,
                self)
        else:
            return
        self.replyModel.load()

        self.splitter = QtGui.QSplitter(self)
        self.splitter.setOrientation(QtCore.Qt.Vertical)
        self.verticalLayout.insertWidget(0, self.splitter)
        self.tweetWidget.setSizePolicy(QtGui.QSizePolicy.Expanding,
                                       QtGui.QSizePolicy.Expanding)
        self.splitter.addWidget(self.tweetWidget)

        self.commentsWidget = TweetListWidget(self, ["image", "original"])
        self.commentsWidget.setModel(self.replyModel)
        self.commentsWidget.scrollArea.setMinimumSize(20, 200)
        self.commentsWidget.userClicked.connect(self.userClicked)
        self.commentsWidget.tagClicked.connect(self.tagClicked)
        self.splitter.addWidget(self.commentsWidget)
        self.splitter.addWidget(self.textEdit)

    def mentions_suggest(self, text):
        ret_users = []
        try:
            word = text.split(' ')[-1]
            word = word.split('@')[-1]
        except IndexError:
            return []
        if not word.strip():
            return []
        users = self.client.api("search/suggestions/at_users").get(q=word,
                                                                   type=0)
        for user in users:
            ret_users.append("@" + user['nickname'])
        return ret_users

    def sent(self):
        self._sent = True
        self.close()

    def send(self):
        self.pushButton_send.setEnabled(False)
        if self.action == "new":
            self.new()
        elif self.action == "retweet":
            self.retweet()
        elif self.action == "comment":
            self.comment()
        elif self.action == "reply":
            self.reply()
        else:
            # If action is in other types, it must be a mistake.
            assert False

    @async
    def retweet(self):
        text = self.textEdit.toPlainText()
        comment = int(self.chk_comment.isChecked())
        comment_ori = int(self.chk_comment_original.isChecked())
        try:
            self.tweet.retweet(text, comment, comment_ori)
        except APIError as e:
            self.apiError.emit(e)
            return
        self.notify.showMessage(self.tr("WeCase"), self.tr("Retweet Success!"))
        self.sendSuccessful.emit()

    @async
    def comment(self):
        text = self.textEdit.toPlainText()
        retweet = int(self.chk_repost.isChecked())
        comment_ori = int(self.chk_comment_original.isChecked())
        try:
            self.tweet.comment(text, comment_ori, retweet)
        except APIError as e:
            self.apiError.emit(e)
            return
        self.notify.showMessage(self.tr("WeCase"), self.tr("Comment Success!"))
        self.sendSuccessful.emit()

    @async
    def reply(self):
        text = self.textEdit.toPlainText()
        comment_ori = int(self.chk_comment_original.isChecked())
        retweet = int(self.chk_repost.isChecked())
        try:
            self.tweet.reply(text, comment_ori, retweet)
        except APIError as e:
            self.apiError.emit(e)
            return
        self.notify.showMessage(self.tr("WeCase"), self.tr("Reply Success!"))
        self.sendSuccessful.emit()

    @async
    def new(self):
        text = self.textEdit.toPlainText()

        try:
            if self.image:
                try:
                    if getsize(self.image) > const.MAX_IMAGE_BYTES:
                        raise ValueError
                    with open(self.image, "rb") as image:
                        self.client.api("statuses/upload").post(status=text,
                                                                pic=image)
                except (OSError, IOError):
                    self.commonError.emit(
                        self.tr("File not found"),
                        self.tr("No such file: %s") % self.image)
                    self.addImage()  # In fact, remove image...
                    return
                except ValueError:
                    self.commonError.emit(
                        self.tr("Too large size"),
                        self.tr("This image is too large to upload: %s") %
                        self.image)
                    self.addImage()  # In fact, remove image...
                    return
            else:
                self.client.api("statuses/update").post(status=text)

            self.notify.showMessage(self.tr("WeCase"),
                                    self.tr("Tweet Success!"))
            self.sendSuccessful.emit()
        except APIError as e:
            self.apiError.emit(e)
            return

        self.image = None

    def addImage(self):
        ACCEPT_TYPE = self.tr("Images") + "(*.png *.jpg *.jpeg *.bmp *.gif)"
        if self.image:
            self.image = None
            self.pushButton_picture.setText(self.tr("&Picture"))
        else:
            self.image = QtGui.QFileDialog.getOpenFileName(self,
                                                           self.tr("Choose a"
                                                                   " image"),
                                                           filter=ACCEPT_TYPE)
            # user may cancel the dialog, so check again
            if self.image:
                self.pushButton_picture.setText(self.tr("Remove the picture"))
        self.textEdit.setFocus()

    def showException(self, e):
        if "Text too long" in str(e):
            QtGui.QMessageBox.warning(None, self.tr("Text too long!"),
                                      self.tr("Please remove some text."))
        else:
            self.errorWindow.raiseException.emit(e)
        self.pushButton_send.setEnabled(True)

    def showErrorMessage(self, title, text):
        QtGui.QMessageBox.warning(self, title, text)

    def showSmiley(self):
        wecase_smiley = FaceWindow()
        if wecase_smiley.exec_():
            self.textEdit.textCursor().insertText(wecase_smiley.faceName)
        self.textEdit.setFocus()

    def checkChars(self):
        """Check textEdit's characters.
        If it larger than 140, Send Button will be disabled
        and label will show red chars."""

        text = self.textEdit.toPlainText()
        numLens = 140 - tweetLength(text)
        if numLens == 140 and (not self.action == "retweet"):
            # you can not send empty tweet, except retweet
            self.pushButton_send.setEnabled(False)
        elif numLens >= 0:
            # length is okay
            self.label.setStyleSheet("color:black;")
            self.pushButton_send.setEnabled(True)
        else:
            # text is too long
            self.label.setStyleSheet("color:red;")
            self.pushButton_send.setEnabled(False)
        self.label.setText(str(numLens))

    def reject(self):
        self.close()

    def closeEvent(self, event):
        # We have unsend text.
        if (not self._sent) and (self.textEdit.toPlainText()):
            choice = QtGui.QMessageBox.question(
                self, self.tr("Close?"), self.tr("All unpost text will lost."),
                QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
            if choice == QtGui.QMessageBox.No:
                event.ignore()
            else:
                self.setParent(None)
コード例 #26
0
ファイル: WeCaseWindow.py プロジェクト: sikisis/WeCase
class WeCaseWindow(QtGui.QMainWindow, Ui_frm_MainWindow):
    client = None
    uid = None
    imageLoaded = QtCore.pyqtSignal(str)
    tabTextChanged = QtCore.pyqtSignal(int, str)

    def __init__(self, client, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        self.setupUi(self)
        self.tweetViews = [
            self.homeView, self.mentionsView, self.commentsView, self.myView
        ]
        self.client = client
        self.setupModels()
        self.init_account()
        self.setupMyUi()
        self.loadConfig()
        self.IMG_AVATAR = -2
        self.IMG_THUMB = -1
        self.notify = Notify(timeout=self.notify_timeout)
        self.applyConfig()
        self.download_lock = []

    def init_account(self):
        self.get_uid()

    def loadConfig(self):
        self.config = ConfigParser()
        self.config.read(const.config_path)

        if not self.config.has_section('main'):
            self.config['main'] = {}

        self.main_config = self.config['main']
        self.timer_interval = int(self.main_config.get('notify_interval', 30))
        self.notify_timeout = int(self.main_config.get('notify_timeout', 5))
        self.remindMentions = self.main_config.getboolean('remind_mentions', 1)
        self.remindComments = self.main_config.getboolean('remind_comments', 1)

    def applyConfig(self):
        try:
            self.timer.stop_event.set()
        except AttributeError:
            pass

        self.timer = WTimer(self.timer_interval, self.show_notify)
        self.timer.start()
        self.notify.timeout = self.notify_timeout

    def setupMyUi(self):
        for tweetView in self.tweetViews:
            tweetView.setResizeMode(tweetView.SizeRootObjectToView)
            tweetView.setSource(
                QtCore.QUrl.fromLocalFile(const.myself_path +
                                          "/ui/TweetList.qml"))
            tweetView.rootContext().setContextProperty("mainWindow", self)

    @QtCore.pyqtSlot()
    def load_more(self):
        model = self.get_current_model()
        model.next()

    def setupModels(self):
        self.all_timeline = TweetCommonModel(
            TweetItem(), self.client.statuses.home_timeline, self)
        self.all_timeline.load()
        self.homeView.rootContext().setContextProperty("mymodel",
                                                       self.all_timeline)
        self.mentions = TweetCommonModel(TweetItem(),
                                         self.client.statuses.mentions, self)
        self.mentions.load()
        self.mentionsView.rootContext().setContextProperty(
            "mymodel", self.mentions)
        self.comment_to_me = TweetCommentModel(TweetItem(),
                                               self.client.comments.to_me,
                                               self)
        self.comment_to_me.load()
        self.commentsView.rootContext().setContextProperty(
            "mymodel", self.comment_to_me)
        self.my_timeline = TweetCommonModel(TweetItem(),
                                            self.client.statuses.user_timeline,
                                            self)
        self.my_timeline.load()
        self.myView.rootContext().setContextProperty("mymodel",
                                                     self.my_timeline)

    def reset_remind(self):
        if self.tabWidget.currentIndex() == 0:
            self.tabWidget.setTabText(0, self.tr("Weibo"))
        elif self.tabWidget.currentIndex() == 1:
            self.client.remind.set_count.post(type="mention_status")
            self.tabWidget.setTabText(1, self.tr("@Me"))
        elif self.tabWidget.currentIndex() == 2:
            self.client.remind.set_count.post(type="cmt")
            self.tabWidget.setTabText(2, self.tr("Comments"))

    def get_remind(self, uid):
        '''this function is used to get unread_count
        from Weibo API. uid is necessary.'''

        reminds = self.client.remind.unread_count.get(uid=uid)
        return reminds

    def get_uid(self):
        '''How can I get my uid? here it is'''
        try:
            self.uid = self.client.account.get_uid.get().uid
        except AttributeError:
            return None

    def show_notify(self):
        # This function is run in another thread by WTimer.
        # Do not modify UI directly. Send signal and react it in a slot only.
        # We use SIGNAL self.tabTextChanged and SLOT self.setTabText()
        # to display unread count

        reminds = self.get_remind(self.uid)
        msg = self.tr("You have:") + "\n"
        num_msg = 0

        if reminds['status'] != 0:
            # Note: do NOT send notify here, or users will crazy.
            self.tabTextChanged.emit(0,
                                     self.tr("Weibo(%d)") % reminds['status'])

        if reminds['mention_status'] and self.remindMentions:
            msg += self.tr("%d unread @ME") % reminds['mention_status'] + "\n"
            self.tabTextChanged.emit(
                1,
                self.tr("@Me(%d)") % reminds['mention_status'])
            num_msg += 1

        if reminds['cmt'] and self.remindComments:
            msg += self.tr("%d unread comment(s)") % reminds['cmt'] + "\n"
            self.tabTextChanged.emit(2,
                                     self.tr("Comments(%d)") % reminds['cmt'])
            num_msg += 1

        if num_msg:
            return
            self.notify.showMessage(self.tr("WeCase"), msg)

    def setTabText(self, index, string):
        self.tabWidget.setTabText(index, string)

    def moveToTop(self):
        self.get_current_tweetView().rootObject().positionViewAtBeginning()

    def setLoaded(self, tweetid):
        self.get_current_tweetView().rootObject().imageLoaded(tweetid)

    def showSettings(self):
        wecase_settings = WeSettingsWindow()
        if wecase_settings.exec_():
            self.loadConfig()
            self.applyConfig()

    def showAbout(self):
        wecase_about = AboutWindow()
        wecase_about.exec_()

    def logout(self):
        self.close()
        # This is a model dialog, if we exec it before we close MainWindow
        # MainWindow won't close
        from LoginWindow import LoginWindow
        wecase_login = LoginWindow()
        wecase_login.exec_()

    def postTweet(self):
        wecase_new = NewpostWindow()
        wecase_new.client = self.client
        wecase_new.exec_()

    @QtCore.pyqtSlot(str)
    def comment(self, idstr):
        wecase_new = NewpostWindow(action="comment", id=int(idstr))
        wecase_new.client = self.client
        wecase_new.exec_()

    @QtCore.pyqtSlot(str, str)
    def repost(self, idstr, text):
        wecase_new = NewpostWindow(action="retweet", id=int(idstr), text=text)
        wecase_new.client = self.client
        wecase_new.exec_()

    @QtCore.pyqtSlot(str, result=int)
    def favorite(self, idstr):
        try:
            self.client.favorites.create.post(id=int(idstr))
            return True
        except:
            return False

    @QtCore.pyqtSlot(str, result=bool)
    def un_favorite(self, idstr):
        try:
            self.client.favorites.destroy.post(id=int(idstr))
            return True
        except:
            return False

    @QtCore.pyqtSlot(str, str)
    def reply(self, idstr, cidstr):
        wecase_new = NewpostWindow(action="reply",
                                   id=int(idstr),
                                   cid=int(cidstr))
        wecase_new.client = self.client
        wecase_new.exec_()

    @QtCore.pyqtSlot(str, str)
    def look_orignal_pic(self, thumbnail_pic, tweetid):
        threading.Thread(group=None,
                         target=self.fetch_open_original_pic,
                         args=(thumbnail_pic, tweetid)).start()

    def fetch_open_original_pic(self, thumbnail_pic, tweetid):
        """Fetch and open original pic from thumbnail pic url.
           Pictures will stored in cache directory. If we already have a same
           name in cache directory, just open it. If we don't, then download it
           first."""

        if tweetid in self.download_lock:
            return
        self.download_lock.append(tweetid)
        original_pic = thumbnail_pic.replace("thumbnail",
                                             "large")  # A simple trick ... ^_^
        localfile = const.cache_path + original_pic.split("/")[-1]
        if not os.path.exists(localfile):
            urllib.request.urlretrieve(original_pic, localfile)

        self.download_lock.remove(tweetid)
        os.popen("xdg-open " + localfile)  # xdg-open is common?
        self.imageLoaded.emit(tweetid)

    def refresh(self):
        model = self.get_current_model()
        model.timelineLoaded.connect(self.moveToTop)
        #model.clear()
        #model.load()
        model.new()
        self.reset_remind()

    def get_current_tweetView(self):
        tweetViews = {
            0: self.homeView,
            1: self.mentionsView,
            2: self.commentsView,
            3: self.myView
        }
        return tweetViews[self.tabWidget.currentIndex()]

    def get_current_model(self):
        models = {
            0: self.all_timeline,
            1: self.mentions,
            2: self.comment_to_me,
            3: self.my_timeline
        }
        return models[self.tabWidget.currentIndex()]

    def get_current_function(self):
        functions = {
            0: self.get_all_timeline,
            1: self.get_mentions_timeline,
            2: self.get_comment_to_me,
            3: self.get_my_timeline
        }
        return functions[self.tabWidget.currentIndex()]

    def closeEvent(self, event):
        self.timer.stop_event.set()
コード例 #27
0
ファイル: NewpostWindow.py プロジェクト: EmbolismSoil/WeCase
class NewpostWindow(QtGui.QDialog, Ui_NewPostWindow):
    image = None
    apiError = QtCore.pyqtSignal(Exception)
    commonError = QtCore.pyqtSignal(str, str)
    sendSuccessful = QtCore.pyqtSignal()
    userClicked = QtCore.pyqtSignal(UserItem, bool)
    tagClicked = QtCore.pyqtSignal(str, bool)
    tweetRefreshed = QtCore.pyqtSignal()
    tweetRejected = QtCore.pyqtSignal()

    def __init__(self, action="new", tweet=None, parent=None):
        super(NewpostWindow, self).__init__(parent)
        self.setAttribute(QtCore.Qt.WA_QuitOnClose, False)
        self.client = const.client
        self.tweet = tweet
        self.action = action
        self.setupUi(self)
        self.textEdit.callback = self.mentions_suggest
        self.textEdit.mention_flag = "@"
        self.notify = Notify(timeout=1)
        self._sent = False
        self.apiError.connect(self.showException)
        self.sendSuccessful.connect(self.sent)
        self.commonError.connect(self.showErrorMessage)
        self.errorWindow = APIErrorWindow(self)

        if self.action not in ["new", "reply"]:
            self.tweetRefreshed.connect(self._create_tweetWidget)
            self.tweetRejected.connect(lambda: self.pushButton_send.setEnabled(False))
            self._refresh()

    def setupUi(self, widget):
        super(NewpostWindow, self).setupUi(widget)
        self.sendAction = QtGui.QAction(self)
        self.sendAction.triggered.connect(self.send)
        self.sendAction.setShortcut(QtGui.QKeySequence("Ctrl+Return"))
        self.addAction(self.sendAction)

        self.checkChars()
        self.setupButtons()

    def setupButtons(self):
        # Disabled is the default state of buttons
        self.pushButton_picture.setEnabled(False)
        self.chk_repost.setEnabled(False)
        self.chk_comment.setEnabled(False)
        self.chk_comment_original.setEnabled(False)

        if self.action == "new":
            assert (not self.tweet)  # Shouldn't have a tweet object.
            self.pushButton_picture.setEnabled(True)
        elif self.action == "retweet":
            self.chk_comment.setEnabled(True)
            if self.tweet.type == TweetItem.RETWEET:
                self.textEdit.setText(self.tweet.append_existing_replies())
                self.chk_comment_original.setEnabled(True)
        elif self.action == "comment":
            self.chk_repost.setEnabled(True)
            if self.tweet.type == TweetItem.RETWEET:
                self.chk_comment_original.setEnabled(True)
        elif self.action == "reply":
            self.chk_repost.setEnabled(True)
            if self.tweet.original.type == TweetItem.RETWEET:
                self.chk_comment_original.setEnabled(True)
        else:
            assert False

    @async
    def _refresh(self):
        # The read count is not a real-time value. So refresh it now.
        try:
            self.tweet.refresh()
        except APIError as e:
            self.errorWindow.raiseException.emit(e)
            self.tweetRejected.emit()
            return
        self.tweetRefreshed.emit()

    def _create_tweetWidget(self):
        if self.action == "comment" and self.tweet.comments_count:
            self.tweetWidget = SingleTweetWidget(self.tweet, ["image", "original"], self)
            self.replyModel = TweetUnderCommentModel(self.client.api("comments/show"), self.tweet.id, self)
        elif self.action == "retweet" and self.tweet.retweets_count:
            if self.tweet:
                self.tweetWidget = SingleTweetWidget(self.tweet, ["image", "original"], self)
            elif self.tweet.original:
                self.tweetWidget = SingleTweetWidget(self.tweet.original, ["image", "original"], self)
            self.replyModel = TweetRetweetModel(self.client.api("statuses/repost_timeline"), self.tweet.id, self)
        else:
            return
        self.replyModel.load()

        self.splitter = QtGui.QSplitter(self)
        self.splitter.setOrientation(QtCore.Qt.Vertical)
        self.verticalLayout.insertWidget(0, self.splitter)
        self.tweetWidget.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
        self.splitter.addWidget(self.tweetWidget)

        self.commentsWidget = TweetListWidget(self, ["image", "original"])
        self.commentsWidget.setModel(self.replyModel)
        self.commentsWidget.scrollArea.setMinimumSize(20, 200)
        self.commentsWidget.userClicked.connect(self.userClicked)
        self.commentsWidget.tagClicked.connect(self.tagClicked)
        self.splitter.addWidget(self.commentsWidget)
        self.splitter.addWidget(self.textEdit)

    def mentions_suggest(self, text):
        ret_users = []
        try:
            word = text.split(' ')[-1]
            word = word.split('@')[-1]
        except IndexError:
            return []
        if not word.strip():
            return []
        users = self.client.api("search/suggestions/at_users").get(q=word, type=0)
        for user in users:
            ret_users.append("@" + user['nickname'])
        return ret_users

    def sent(self):
        self._sent = True
        self.close()

    def send(self):
        self.pushButton_send.setEnabled(False)
        if self.action == "new":
            self.new()
        elif self.action == "retweet":
            self.retweet()
        elif self.action == "comment":
            self.comment()
        elif self.action == "reply":
            self.reply()
        else:
            # If action is in other types, it must be a mistake.
            assert False

    @async
    def retweet(self):
        text = self.textEdit.toPlainText()
        comment = int(self.chk_comment.isChecked())
        comment_ori = int(self.chk_comment_original.isChecked())
        try:
            self.tweet.retweet(text, comment, comment_ori)
        except APIError as e:
            self.apiError.emit(e)
            return
        self.notify.showMessage(self.tr("WeCase"), self.tr("Retweet Success!"))
        self.sendSuccessful.emit()

    @async
    def comment(self):
        text = self.textEdit.toPlainText()
        retweet = int(self.chk_repost.isChecked())
        comment_ori = int(self.chk_comment_original.isChecked())
        try:
            self.tweet.comment(text, comment_ori, retweet)
        except APIError as e:
            self.apiError.emit(e)
            return
        self.notify.showMessage(self.tr("WeCase"), self.tr("Comment Success!"))
        self.sendSuccessful.emit()

    @async
    def reply(self):
        text = self.textEdit.toPlainText()
        comment_ori = int(self.chk_comment_original.isChecked())
        retweet = int(self.chk_repost.isChecked())
        try:
            self.tweet.reply(text, comment_ori, retweet)
        except APIError as e:
            self.apiError.emit(e)
            return
        self.notify.showMessage(self.tr("WeCase"), self.tr("Reply Success!"))
        self.sendSuccessful.emit()

    @async
    def new(self):
        text = self.textEdit.toPlainText()

        try:
            if self.image:
                try:
                    if getsize(self.image) > const.MAX_IMAGE_BYTES:
                        raise ValueError
                    with open(self.image, "rb") as image:
                        self.client.api("statuses/upload").post(status=text, pic=image)
                except (OSError, IOError):
                    self.commonError.emit(self.tr("File not found"),
                                          self.tr("No such file: %s")
                                          % self.image)
                    self.addImage()  # In fact, remove image...
                    return
                except ValueError:
                    self.commonError.emit(self.tr("Too large size"),
                                          self.tr("This image is too large to upload: %s")
                                          % self.image)
                    self.addImage()  # In fact, remove image...
                    return
            else:
                self.client.api("statuses/update").post(status=text)

            self.notify.showMessage(self.tr("WeCase"),
                                    self.tr("Tweet Success!"))
            self.sendSuccessful.emit()
        except APIError as e:
            self.apiError.emit(e)
            return

        self.image = None

    def addImage(self):
        ACCEPT_TYPE = self.tr("Images") + "(*.png *.jpg *.jpeg *.bmp *.gif)"
        if self.image:
            self.image = None
            self.pushButton_picture.setText(self.tr("&Picture"))
        else:
            self.image = QtGui.QFileDialog.getOpenFileName(self,
                                                           self.tr("Choose a"
                                                                   " image"),
                                                           filter=ACCEPT_TYPE)
            # user may cancel the dialog, so check again
            if self.image:
                self.pushButton_picture.setText(self.tr("Remove the picture"))
        self.textEdit.setFocus()

    def showException(self, e):
        if "Text too long" in str(e):
            QtGui.QMessageBox.warning(None, self.tr("Text too long!"),
                                      self.tr("Please remove some text."))
        else:
            self.errorWindow.raiseException.emit(e)
        self.pushButton_send.setEnabled(True)

    def showErrorMessage(self, title, text):
        QtGui.QMessageBox.warning(self, title, text)

    def showSmiley(self):
        wecase_smiley = FaceWindow()
        if wecase_smiley.exec_():
            self.textEdit.textCursor().insertText(wecase_smiley.faceName)
        self.textEdit.setFocus()

    def checkChars(self):
        """Check textEdit's characters.
        If it larger than 140, Send Button will be disabled
        and label will show red chars."""

        text = self.textEdit.toPlainText()
        numLens = 140 - tweetLength(text)
        if numLens == 140 and (not self.action == "retweet"):
            # you can not send empty tweet, except retweet
            self.pushButton_send.setEnabled(False)
        elif numLens >= 0:
            # length is okay
            self.label.setStyleSheet("color:black;")
            self.pushButton_send.setEnabled(True)
        else:
            # text is too long
            self.label.setStyleSheet("color:red;")
            self.pushButton_send.setEnabled(False)
        self.label.setText(str(numLens))

    def reject(self):
        self.close()

    def closeEvent(self, event):
        # We have unsend text.
        if (not self._sent) and (self.textEdit.toPlainText()):
            choice = QtGui.QMessageBox.question(
                self, self.tr("Close?"),
                self.tr("All unpost text will lost."),
                QtGui.QMessageBox.Yes,
                QtGui.QMessageBox.No)
            if choice == QtGui.QMessageBox.No:
                event.ignore()
            else:
                self.setParent(None)
コード例 #28
0
class WeCaseWindow(QtGui.QMainWindow):

    client = None
    uid = None
    timelineLoaded = QtCore.pyqtSignal(int)
    imageLoaded = QtCore.pyqtSignal(str)
    tabBadgeChanged = QtCore.pyqtSignal(int, int)
    tabAvatarFetched = QtCore.pyqtSignal(str)

    def __init__(self, username, parent=None):
        super(WeCaseWindow, self).__init__(parent)

        self.username = username
        LoginInfo().add_account(self.username)

        self.errorWindow = APIErrorWindow(self)
        self.setAttribute(QtCore.Qt.WA_QuitOnClose, True)
        self._iconPixmap = {}
        self.setupUi(self)
        self._setupSysTray()
        self.tweetViews = [
            self.homeView, self.mentionsView, self.commentsView,
            self.commentsMentionsTab
        ]
        self.info = WeRuntimeInfo()
        self.client = const.client
        self.loadConfig()
        self.init_account()
        self.setupModels()
        self.IMG_AVATAR = -2
        self.IMG_THUMB = -1
        self.notify = Notify(timeout=self.notify_timeout)
        self.applyConfig()
        self.download_lock = []
        self._last_reminds_count = 0
        self._setupUserTab(self.uid(), False, True)

    def _setupTab(self, view):
        tab = QtGui.QWidget()
        layout = QtGui.QGridLayout(tab)
        layout.addWidget(view)
        view.setParent(tab)
        return tab

    def _setupCommonTab(self, timeline, view, switch=True, protect=False):
        self._prepareTimeline(timeline)
        view.setModel(timeline)
        view.userClicked.connect(self.userClicked)
        view.tagClicked.connect(self.tagClicked)
        tab = self._setupTab(view)
        self.tabWidget.addTab(tab, "")
        if switch:
            self.tabWidget.setCurrentWidget(tab)
        if protect:
            self.tabWidget.tabBar().setProtectTab(tab, True)
        return tab

    def _getSameTab(self, attr, value):
        for i in range(self.tabWidget.count()):
            try:
                tab = self.tabWidget.widget(i).layout().itemAt(0).widget()
                _value = getattr(tab.model(), attr)()
                if _value == value:
                    return i
            except AttributeError:
                pass
        return False

    def _setupUserTab(self, uid, switch=True, myself=False):
        index = self._getSameTab("uid", uid)
        if index:
            if switch:
                self.tabWidget.setCurrentIndex(index)
            return

        view = TweetListWidget()
        _timeline = TweetUserModel(self.client.api("statuses/user_timeline"),
                                   uid, view)
        timeline = TweetFilterModel(_timeline)
        timeline.setModel(_timeline)
        tab = self._setupCommonTab(timeline, view, switch, myself)

        def setAvatar(f):
            self._setTabIcon(tab, WObjectCache().open(QtGui.QPixmap, f))

        fetcher = AsyncFetcher("".join(
            (path.cache_path, str(self.info["uid"]))))
        fetcher.addTask(
            self.client.api("users/show").get(uid=uid)["profile_image_url"],
            setAvatar)

    def _setupTopicTab(self, topic, switch=True):
        index = self._getSameTab("topic", topic)
        if index:
            if switch:
                self.tabWidget.setCurrentIndex(index)
            return

        view = TweetListWidget()
        timeline = TweetTopicModel(self.client.api("search/topics"), topic,
                                   view)
        tab = self._setupCommonTab(timeline, view, switch, protect=False)
        self._setTabIcon(
            tab,
            WObjectCache().open(QtGui.QPixmap, ":/IMG/img/topic.jpg"))

    def userClicked(self, userItem, openAtBackend):
        try:
            self._setupUserTab(userItem.id, switch=(not openAtBackend))
        except APIError as e:
            self.errorWindow.raiseException.emit(e)

    def tagClicked(self, str, openAtBackend):
        try:
            self._setupTopicTab(str, switch=(not openAtBackend))
        except APIError as e:
            self.errorWindow.raiseException.emit(e)

    def setupUi(self, mainWindow):
        mainWindow.setWindowIcon(QtGui.QIcon(":/IMG/img/WeCase.svg"))
        mainWindow.setDocumentMode(False)
        mainWindow.setDockOptions(QtGui.QMainWindow.AllowTabbedDocks
                                  | QtGui.QMainWindow.AnimatedDocks)

        self.centralwidget = QtGui.QWidget(mainWindow)
        self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget)

        self.tabWidget = QtGui.QTabWidget(self.centralwidget)
        self.tabWidget.setTabBar(WTabBar(self.tabWidget))
        self.tabWidget.setTabPosition(QtGui.QTabWidget.West)
        self.tabWidget.setTabShape(QtGui.QTabWidget.Rounded)
        self.tabWidget.setDocumentMode(False)
        self.tabWidget.setMovable(True)
        self.tabWidget.tabCloseRequested.connect(self.closeTab)

        self.homeView = TweetListWidget()
        self.homeView.userClicked.connect(self.userClicked)
        self.homeView.tagClicked.connect(self.tagClicked)
        self.homeTab = self._setupTab(self.homeView)
        self.tabWidget.addTab(self.homeTab, "")
        self.tabWidget.tabBar().setProtectTab(self.homeTab, True)

        self.mentionsView = TweetListWidget()
        self.mentionsView.userClicked.connect(self.userClicked)
        self.mentionsView.tagClicked.connect(self.tagClicked)
        self.mentionsTab = self._setupTab(self.mentionsView)
        self.tabWidget.addTab(self.mentionsTab, "")
        self.tabWidget.tabBar().setProtectTab(self.mentionsTab, True)

        self.commentsView = TweetListWidget()
        self.commentsView.userClicked.connect(self.userClicked)
        self.commentsView.tagClicked.connect(self.tagClicked)
        self.commentsTab = self._setupTab(self.commentsView)
        self.tabWidget.addTab(self.commentsTab, "")
        self.tabWidget.tabBar().setProtectTab(self.commentsTab, True)

        self.commentsMentionsView = TweetListWidget()
        self.commentsMentionsView.userClicked.connect(self.userClicked)
        self.commentsMentionsView.tagClicked.connect(self.tagClicked)
        self.commentsMentionsTab = self._setupTab(self.commentsMentionsView)
        self.tabWidget.addTab(self.commentsMentionsTab, "")
        self.tabWidget.tabBar().setProtectTab(self.commentsMentionsTab, True)

        self.verticalLayout.addWidget(self.tabWidget)

        self.widget = QtGui.QWidget(self.centralwidget)
        self.verticalLayout.addWidget(self.widget)

        mainWindow.setCentralWidget(self.centralwidget)

        self.aboutAction = QtGui.QAction(mainWindow)
        self.refreshAction = QtGui.QAction(mainWindow)
        self.logoutAction = QtGui.QAction(mainWindow)
        self.exitAction = QtGui.QAction(mainWindow)
        self.settingsAction = QtGui.QAction(mainWindow)

        self.aboutAction.setIcon(
            QtGui.QIcon(QtGui.QPixmap("./IMG/img/where_s_my_weibo.svg")))
        self.exitAction.setIcon(
            QtGui.QIcon(QtGui.QPixmap(":/IMG/img/application-exit.svg")))
        self.settingsAction.setIcon(
            QtGui.QIcon(QtGui.QPixmap(":/IMG/img/preferences-other.png")))
        self.refreshAction.setIcon(
            QtGui.QIcon(QtGui.QPixmap(":/IMG/img/refresh.png")))

        self.menubar = QtGui.QMenuBar(mainWindow)
        self.menubar.setEnabled(True)
        self.menubar.setDefaultUp(False)
        mainWindow.setMenuBar(self.menubar)

        self.mainMenu = QtGui.QMenu(self.menubar)
        self.helpMenu = QtGui.QMenu(self.menubar)
        self.optionsMenu = QtGui.QMenu(self.menubar)

        self.mainMenu.addAction(self.refreshAction)
        self.mainMenu.addSeparator()
        self.mainMenu.addAction(self.logoutAction)
        self.mainMenu.addAction(self.exitAction)
        self.helpMenu.addAction(self.aboutAction)
        self.optionsMenu.addAction(self.settingsAction)
        self.menubar.addAction(self.mainMenu.menuAction())
        self.menubar.addAction(self.optionsMenu.menuAction())
        self.menubar.addAction(self.helpMenu.menuAction())

        self.exitAction.triggered.connect(mainWindow.close)
        self.aboutAction.triggered.connect(mainWindow.showAbout)
        self.settingsAction.triggered.connect(mainWindow.showSettings)
        self.logoutAction.triggered.connect(mainWindow.logout)
        self.refreshAction.triggered.connect(mainWindow.refresh)

        self.pushButton_refresh = QtGui.QPushButton(self.widget)
        self.pushButton_new = QtGui.QPushButton(self.widget)
        self.pushButton_refresh.clicked.connect(mainWindow.refresh)
        self.pushButton_new.clicked.connect(mainWindow.postTweet)
        self.timelineLoaded.connect(self.moveToTop)
        self.tabBadgeChanged.connect(self.drawNotifyBadge)

        self.refreshAction.setShortcut(QtGui.QKeySequence("F5"))
        self.pushButton_refresh.setIcon(QtGui.QIcon(":/IMG/img/refresh.png"))
        self.pushButton_new.setIcon(QtGui.QIcon(":/IMG/img/new.png"))

        if self.isGlobalMenu():
            self._setupToolBar()
        else:
            self._setupButtonWidget()

        self._setTabIcon(self.homeTab, QtGui.QPixmap(":/IMG/img/sina.png"))
        self._setTabIcon(self.mentionsTab,
                         QtGui.QPixmap(":/IMG/img/mentions.png"))
        self._setTabIcon(self.commentsTab,
                         QtGui.QPixmap(":/IMG/img/comments2.png"))
        self._setTabIcon(self.commentsMentionsTab,
                         QtGui.QPixmap(":/IMG/img/mentions_comments.svg"))

        self.retranslateUi(mainWindow)

    def isGlobalMenu(self):
        if os.environ.get("TOOLBAR") == "1":
            return True
        elif os.environ.get("TOOLBAR") == "0":
            return False
        elif os.environ.get('DESKTOP_SESSION') in ["ubuntu", "ubuntu-2d"]:
            if not os.environ.get("UBUNTU_MENUPROXY"):
                return False
            elif os.environ.get("APPMENU_DISPLAY_BOTH"):
                return False
            else:
                return True
        elif os.environ.get(
                "DESKTOP_SESSION"
        ) == "kde-plasma" and platform.linux_distribution()[0] == "Ubuntu":
            return True
        elif platform.system() == "Darwin":
            return True
        return False

    def _setupToolBar(self):
        self.toolBar = QtGui.QToolBar()
        self.toolBar.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
        empty = QtGui.QWidget()
        empty.setSizePolicy(QtGui.QSizePolicy.Expanding,
                            QtGui.QSizePolicy.Preferred)
        self.toolBar.addWidget(empty)
        self.toolBar.addAction(self.refreshAction)
        newAction = self.toolBar.addAction(QtGui.QIcon(":/IMG/img/new.png"),
                                           "New")
        newAction.triggered.connect(self.pushButton_new.clicked)
        self.addToolBar(self.toolBar)

    def _setupButtonWidget(self):
        self.buttonWidget = QtGui.QWidget(self)
        self.buttonLayout = QtGui.QHBoxLayout(self.buttonWidget)
        self.horizontalSpacer = QtGui.QSpacerItem(40, 20,
                                                  QtGui.QSizePolicy.Expanding,
                                                  QtGui.QSizePolicy.Minimum)
        self.buttonLayout.addSpacerItem(self.horizontalSpacer)
        self.buttonLayout.addWidget(self.pushButton_refresh)
        self.buttonLayout.addWidget(self.pushButton_new)

    def resizeEvent(self, event):
        # This is a hack!!!
        if self.isGlobalMenu():
            return
        self.buttonWidget.resize(self.menubar.sizeHint().width(),
                                 self.menubar.sizeHint().height() + 12)
        self.buttonWidget.move(self.width() - self.buttonWidget.width(),
                               self.menubar.geometry().topRight().y() - 5)

    def retranslateUi(self, frm_MainWindow):
        frm_MainWindow.setWindowTitle(self.tr("WeCase"))
        self.mainMenu.setTitle(self.tr("&WeCase"))
        self.helpMenu.setTitle(self.tr("&Help"))
        self.optionsMenu.setTitle(self.tr("&Options"))
        self.aboutAction.setText(self.tr("&About..."))
        self.refreshAction.setText(self.tr("Refresh"))
        self.logoutAction.setText(self.tr("&Log out"))
        self.exitAction.setText(self.tr("&Exit"))
        self.settingsAction.setText(self.tr("&Settings"))

    def _setupSysTray(self):
        self.systray = QtGui.QSystemTrayIcon()
        self.systray.activated.connect(self.clickedSystray)
        self.systray.setToolTip("WeCase")
        self.systray.setIcon(QtGui.QIcon(":/IMG/img/WeCase.svg"))
        self.systray.show()

        self.visibleAction = QtGui.QAction(self)
        self.visibleAction.setText(self.tr("&Hide"))
        self.visibleAction.triggered.connect(self._switchVisibility)

        self.sysMenu = QtGui.QMenu(self)
        self.sysMenu.addAction(self.visibleAction)
        self.sysMenu.addAction(self.logoutAction)
        self.sysMenu.addAction(self.exitAction)

        self.systray.setContextMenu(self.sysMenu)

    def clickedSystray(self, reason):
        if reason == QtGui.QSystemTrayIcon.Trigger:
            self._switchVisibility()
        elif reason == QtGui.QSystemTrayIcon.Context:
            pass

    def _switchVisibility(self):
        if self.isVisible():
            self.hide()
            self.visibleAction.setText(self.tr("&Show"))
        else:
            self.show()
            self.visibleAction.setText(self.tr("&Hide"))

    def _setTabIcon(self, tab, icon):
        pixmap = icon.transformed(QtGui.QTransform().rotate(90))
        icon = QtGui.QIcon(pixmap)
        self._iconPixmap[icon.cacheKey()] = pixmap
        self.tabWidget.setTabIcon(self.tabWidget.indexOf(tab), icon)
        self.tabWidget.setIconSize(QtCore.QSize(24, 24))

    def _prepareTimeline(self, timeline):
        try:
            timeline.setUsersBlacklist(self.usersBlacklist)
            timeline.setTweetsKeywordsBlacklist(self.tweetKeywordsBlacklist)
            timeline.setWordWarKeywords(self.wordWarKeywords)
            timeline.setBlockWordwars(self.blockWordwars)
            timeline.setKeywordsAsRegexs(self.keywordsAsRegex)
        except AttributeError:
            pass
        timeline.load()

    def closeTab(self, index):
        widget = self.tabWidget.widget(index)
        self.tabWidget.removeTab(index)
        widget.deleteLater()

    def init_account(self):
        self.uid()

    def loadConfig(self):
        self.config = WConfigParser(path.myself_path + "WMetaConfig",
                                    path.config_path, "main")
        self.notify_interval = self.config.notify_interval
        self.notify_timeout = self.config.notify_timeout
        self.usersBlacklist = self.config.usersBlacklist
        self.tweetKeywordsBlacklist = self.config.tweetsKeywordsBlacklist
        self.remindMentions = self.config.remind_mentions
        self.remindComments = self.config.remind_comments
        self.wordWarKeywords = self.config.wordWarKeywords
        self.blockWordwars = self.config.blockWordwars
        self.maxRetweets = self.config.maxRetweets
        self.maxTweetsPerUser = self.config.maxTweetsPerUser
        self.mainWindow_geometry = self.config.mainwindow_geometry
        self.keywordsAsRegex = self.config.keywordsAsRegex

    def applyConfig(self):
        try:
            self.timer.stop()
        except AttributeError:
            pass

        self.timer = WTimer(self.show_notify, self.notify_interval)
        self.timer.start()
        self.notify.timeout = self.notify_timeout
        setGeometry(self, self.mainWindow_geometry)

    def setupModels(self):
        self._all_timeline = TweetCommonModel(
            self.client.api("statuses/home_timeline"), self)
        self.all_timeline = TweetFilterModel(self._all_timeline)
        self.all_timeline.setModel(self._all_timeline)
        self._prepareTimeline(self.all_timeline)

        # extra rules
        self.all_timeline.setMaxRetweets(self.maxRetweets)
        self.all_timeline.setMaxTweetsPerUser(self.maxTweetsPerUser)

        self.homeView.setModel(self.all_timeline)

        self._mentions = TweetCommonModel(self.client.api("statuses/mentions"),
                                          self)
        self.mentions = TweetFilterModel(self._mentions)
        self.mentions.setModel(self._mentions)
        self._prepareTimeline(self.mentions)
        self.mentionsView.setModel(self.mentions)

        self._comment_to_me = TweetCommentModel(
            self.client.api("comments/to_me"), self)
        self.comment_to_me = TweetFilterModel(self._comment_to_me)
        self.comment_to_me.setModel(self._comment_to_me)
        self._prepareTimeline(self.comment_to_me)
        self.commentsView.setModel(self.comment_to_me)

        self._comment_mentions = TweetCommentModel(
            self.client.api("comments/mentions"), self)
        self.comment_mentions = TweetFilterModel(self._comment_mentions)
        self.comment_mentions.setModel(self._comment_mentions)
        self._prepareTimeline(self.comment_mentions)
        self.commentsMentionsView.setModel(self.comment_mentions)

    @async
    def reset_remind(self):
        typ = ""
        if self.currentTweetView() == self.homeView:
            self.tabBadgeChanged.emit(self.tabWidget.currentIndex(), 0)
        elif self.currentTweetView() == self.mentionsView:
            typ = "mention_status"
            self.tabBadgeChanged.emit(self.tabWidget.currentIndex(), 0)
        elif self.currentTweetView() == self.commentsView:
            typ = "cmt"
            self.tabBadgeChanged.emit(self.tabWidget.currentIndex(), 0)
        elif self.currentTweetView() == self.commentsMentionsView:
            typ = "mention_cmt"
            self.tabBadgeChanged.emit(self.tabWidget.currentIndex(), 0)

        if typ:
            self.client.api("remind/set_count").post(type=typ)

    def get_remind(self, uid):
        """this function is used to get unread_count
        from Weibo API. uid is necessary."""

        reminds = self.client.api("remind/unread_count").get(uid=uid)
        return reminds

    def uid(self):
        """How can I get my uid? here it is"""
        if not self.info.get("uid"):
            self.info["uid"] = self.client.api("account/get_uid").get().uid
        return self.info["uid"]

    def show_notify(self):
        # This function is run in another thread by WTimer.
        # Do not modify UI directly. Send signal and react it in a slot only.
        # We use SIGNAL self.tabTextChanged and SLOT self.setTabText()
        # to display unread count

        reminds = self.get_remind(self.uid())
        msg = self.tr("You have:") + "\n"
        reminds_count = 0

        if reminds['status'] != 0:
            # Note: do NOT send notify here, or users will crazy.
            self.tabBadgeChanged.emit(self.tabWidget.indexOf(self.homeTab),
                                      reminds['status'])

        if reminds['mention_status'] and self.remindMentions:
            msg += self.tr("%d unread @ME") % reminds['mention_status'] + "\n"
            self.tabBadgeChanged.emit(self.tabWidget.indexOf(self.mentionsTab),
                                      reminds['mention_status'])
            reminds_count += 1
        else:
            self.tabBadgeChanged.emit(self.tabWidget.indexOf(self.mentionsTab),
                                      0)

        if reminds['cmt'] and self.remindComments:
            msg += self.tr("%d unread comment(s)") % reminds['cmt'] + "\n"
            self.tabBadgeChanged.emit(self.tabWidget.indexOf(self.commentsTab),
                                      reminds['cmt'])
            reminds_count += 1
        else:
            self.tabBadgeChanged.emit(self.tabWidget.indexOf(self.commentsTab),
                                      0)

        if reminds["mention_cmt"] and self.remindMentions:
            msg += self.tr(
                "%d unread @ME comment(s)") % reminds["mention_cmt"] + "\n"
            self.tabBadgeChanged.emit(
                self.tabWidget.indexOf(self.commentsMentionsTab),
                reminds["mention_cmt"])
            reminds_count += 1
        else:
            self.tabBadgeChanged.emit(
                self.tabWidget.indexOf(self.commentsMentionsTab), 0)

        if reminds_count and reminds_count != self._last_reminds_count:
            self.notify.showMessage(self.tr("WeCase"), msg)
            self._last_reminds_count = reminds_count

    def drawNotifyBadge(self, index, count):
        tabIcon = self.tabWidget.tabIcon(index)
        _tabPixmap = self._iconPixmap[tabIcon.cacheKey()]
        tabPixmap = _tabPixmap.transformed(QtGui.QTransform().rotate(-90))
        icon = NotifyBadgeDrawer().draw(tabPixmap, str(count))
        icon = icon.transformed(QtGui.QTransform().rotate(90))
        icon = QtGui.QIcon(icon)
        self._iconPixmap[icon.cacheKey()] = _tabPixmap
        self.tabWidget.setTabIcon(index, icon)

    def moveToTop(self):
        self.currentTweetView().moveToTop()

    def showSettings(self):
        wecase_settings = WeSettingsWindow()
        if wecase_settings.exec_():
            self.loadConfig()
            self.applyConfig()

    def showAbout(self):
        wecase_about = AboutWindow()
        wecase_about.exec_()

    def logout(self):
        self.close()
        # This is a model dialog, if we exec it before we close MainWindow
        # MainWindow won't close
        from LoginWindow import LoginWindow
        wecase_login = LoginWindow(allow_auto_login=False)
        wecase_login.exec_()

    def postTweet(self):
        self.wecase_new = NewpostWindow()
        self.wecase_new.userClicked.connect(self.userClicked)
        self.wecase_new.tagClicked.connect(self.tagClicked)
        self.wecase_new.show()

    def refresh(self):
        tweetView = self.currentTweetView()
        tweetView.model().timelineLoaded.connect(self.moveToTop)
        tweetView.refresh()
        self.reset_remind()

    def currentTweetView(self):
        # The most tricky part of MainWindow.
        return self.tabWidget.currentWidget().layout().itemAt(0).widget()

    def saveConfig(self):
        self.config.mainwindow_geometry = getGeometry(self)
        self.config.save()

    def closeEvent(self, event):
        self.systray.hide()
        self.hide()
        self.saveConfig()
        self.timer.stop(True)
        # Reset uid when the thread exited.
        self.info["uid"] = None
        LoginInfo().remove_account(self.username)
        logging.info("Die")
コード例 #29
0
ファイル: NewpostWindow.py プロジェクト: sikisis/WeCase
class NewpostWindow(QtGui.QDialog, Ui_NewPostWindow):
    client = None
    image = None
    apiError = QtCore.pyqtSignal(str)
    sendSuccessful = QtCore.pyqtSignal()

    def __init__(self, parent=None, action="new", id=None, cid=None, text=""):
        QtGui.QDialog.__init__(self, parent)
        self.action = action
        self.id = id
        self.cid = cid
        self.setupUi(self)
        self.setupMyUi()
        self.textEdit.setText(text)
        self.textEdit.callback = self.mentions_suggest
        self.textEdit.mention_flag = "@"
        self.notify = Notify(timeout=1)

    def setupMyUi(self):
        self.checkChars()
        if self.action == "new":
            self.chk_repost.setEnabled(False)
            self.chk_comment.setEnabled(False)
            self.chk_comment_original.setEnabled(False)
        elif self.action == "retweet":
            self.chk_repost.setEnabled(False)
            self.pushButton_picture.setEnabled(False)
        elif self.action == "comment":
            self.chk_comment.setEnabled(False)
            self.pushButton_picture.setEnabled(False)
        elif self.action == "reply":
            self.chk_repost.setEnabled(False)
            self.chk_comment.setEnabled(False)
            self.pushButton_picture.setEnabled(False)

    def mentions_suggest(self, text):
        ret_users = []
        try:
            word = re.findall('@[-a-zA-Z0-9_\u4e00-\u9fa5]+', text)[-1]
            word = word.replace('@', '')
        except IndexError:
            return []
        if not word.strip():
            return []
        users = self.client.search.suggestions.at_users.get(q=word, type=0)
        for user in users:
            ret_users.append("@" + user['nickname'])
        return ret_users

    def send(self):
        self.pushButton_send.setEnabled(False)
        if self.action == "new":
            threading.Thread(group=None, target=self.new).start()
        elif self.action == "retweet":
            threading.Thread(group=None, target=self.retweet).start()
        elif self.action == "comment":
            threading.Thread(group=None, target=self.comment).start()
        elif self.action == "reply":
            threading.Thread(group=None, target=self.reply).start()

    def retweet(self):
        text = str(self.textEdit.toPlainText())
        try:
            self.client.statuses.repost.post(
                id=int(self.id),
                status=text,
                is_comment=int((self.chk_comment.isChecked() +
                                self.chk_comment_original.isChecked() * 2)))
            self.notify.showMessage(self.tr("WeCase"),
                                    self.tr("Retweet Success!"))
            self.sendSuccessful.emit()
        except APIError as e:
            self.apiError.emit(str(e))
            return

    def comment(self):
        text = str(self.textEdit.toPlainText())
        try:
            self.client.comments.create.post(
                id=int(self.id),
                comment=text,
                comment_ori=int(self.chk_comment_original.isChecked()))
            if self.chk_repost.isChecked():
                self.client.statuses.repost.post(id=int(self.id), status=text)
            self.notify.showMessage(self.tr("WeCase"),
                                    self.tr("Comment Success!"))
            self.sendSuccessful.emit()
        except APIError as e:
            self.apiError.emit(str(e))
            return

    def reply(self):
        text = str(self.textEdit.toPlainText())
        try:
            self.client.comments.reply.post(
                id=int(self.id),
                cid=int(self.cid),
                comment=text,
                comment_ori=int(self.chk_comment_original.isChecked()))
            if self.chk_repost.isChecked():
                self.client.statuses.repost.post(id=int(self.id), status=text)
            self.notify.showMessage(self.tr("WeCase"),
                                    self.tr("Reply Success!"))
            self.sendSuccessful.emit()
        except APIError as e:
            self.apiError.emit(str(e))
            return

    def new(self):
        text = str(self.textEdit.toPlainText())

        try:
            if self.image:
                self.client.statuses.upload.post(status=text,
                                                 pic=open(self.image, "rb"))
            else:
                self.client.statuses.update.post(status=text)

            self.notify.showMessage(self.tr("WeCase"),
                                    self.tr("Tweet Success!"))
            self.sendSuccessful.emit()
        except APIError as e:
            self.apiError.emit(str(e))
            return

        self.image = None

    def addImage(self):
        ACCEPT_TYPE = self.tr("Images") + "(*.png *.jpg *.bmp *.gif)"
        if self.image:
            self.image = None
            self.pushButton_picture.setText(self.tr("Picture"))
        else:
            self.image = QtGui.QFileDialog.getOpenFileName(self,
                                                           self.tr("Choose a"
                                                                   " image"),
                                                           filter=ACCEPT_TYPE)
            # user may cancel the dialog, so check again
            if self.image:
                self.pushButton_picture.setText(self.tr("Remove the picture"))

    def showError(self, e):
        if "Text too long" in e:
            QtGui.QMessageBox.warning(None, self.tr("Text too long!"),
                                      self.tr("Please remove some text."))
        else:
            QtGui.QMessageBox.warning(None, self.tr("Unknown error!"), e)
        self.pushButton_send.setEnabled(True)

    def showSmiley(self):
        wecase_smiley = SmileyWindow()
        if wecase_smiley.exec_():
            self.textEdit.textCursor().insertText(wecase_smiley.smileyName)

    def checkChars(self):
        '''Check textEdit's characters.
        If it larger than 140, Send Button will be disabled
        and label will show red chars.'''

        text = self.textEdit.toPlainText()
        numLens = 140 - tweetLength(text)
        if numLens == 140 and (not self.action == "retweet"):
            # you can not send empty tweet, except retweet
            self.pushButton_send.setEnabled(False)
        elif numLens >= 0:
            # length is okay
            self.label.setStyleSheet("color:black;")
            self.pushButton_send.setEnabled(True)
        else:
            # text is too long
            self.label.setStyleSheet("color:red;")
            self.pushButton_send.setEnabled(False)
        self.label.setText(str(numLens))