mylog.error("system failed in main")
        sys.exit("system failed in main")


if __name__ == '__main__':
    mylog = MyLog()
    '''
    Start initialize MFC Pressure
    '''
    try:
        config = configparser.ConfigParser()
        config.read('Config.ini')
        ip = config.get('Internet', 'IPconfig')  #GET "Value_ABC"
        print(ip)
    except:
        mylog.error("read config fail")
    '''
    Start Collect MFC Pressure
    '''
    try:
        sensorInstance = sensorProperty.sensorPropertyInstance(
        )  #just one instance bcz sync running
        MFCSensorCollectionThread = threading.Thread(target=main)
        MFCSensorCollectionThread.start()
        mylog.info("Start MFC-HG200 Sensor")
    except KeyboardInterrupt:
        if ser != None:
            mylog.error("Uart fail")
            ser.close()
    '''
    Start Modbus Server
class WizardAddJournal(QtWidgets.QDialog):
    def __init__(self, parent=None):

        super(WizardAddJournal, self).__init__(parent)

        self.TIMEOUT = 60

        self.setModal(True)

        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)

        self.parent = parent

        self.resource_dir, self.DATA_PATH = functions.getRightDirs()

        if parent is None:
            self.l = MyLog("activity.log")

            # Dummy file for saving if testing
            self.options = QtCore.QSettings("debug/options.ini",
                                            QtCore.QSettings.IniFormat)

            self.test = True
        else:
            self.l = self.parent.l
            self.options = self.parent.options
            self.test = False

        self.initUI()
        self.defineSlots()

    def defineSlots(self):
        """Establish the slots"""

        # When clicking OK, verify the user's input
        self.ok_button.clicked.connect(self.verifyInput)

        # Display help
        self.help_button.clicked.connect(self.showHelp)

    def _checkIsFeed(self, url: str, company: str,
                     feed: feedparser.util.FeedParserDict) -> bool:

        self.l.debug("Entering _checkIsFeed")

        # Check if the feed has a title
        try:
            journal = feed['feed']['title']
        except Exception as e:
            self.l.critical("verifyInput, can't access title {}".format(url),
                            exc_info=True)
            return False

        nbr_ok = 0
        for entry in feed.entries:

            try:
                doi = hosts.getDoi(company, journal, entry)
                url = hosts.refineUrl(company, journal, entry)
                self.l.debug("{}, {}".format(doi, url))
            except Exception as e:
                self.l.error(
                    "verifyInput, entry has no doi or no url".format(url),
                    exc_info=True)
                continue

            # Check if DOI and URL can be obtained
            if (doi.startswith('10.') and validators.url(url)
                    or validators.url(doi) and validators.url(url)):
                nbr_ok += 1

            # If 3 entries are OK, the feed is considered valid
            if nbr_ok == 3:
                self.l.debug("3 entries ok, valid feed")
                return True

        # If still here, the feed is NOT considered valid
        return False

    def _getFeed(self, url: str,
                 timeout: int) -> feedparser.util.FeedParserDict:

        self.l.debug("Entering _getFeed")

        # Try to dl the RSS feed page
        try:
            # Get the RSS page of the url provided
            feed = feedparser.parse(url, timeout=timeout)

            self.l.debug("Add journal, RSS page successfully dled")

            return feed

        except Exception as e:
            self.l.error(
                "Add journal feed {} could not be downloaded: {}".format(
                    url, e),
                exc_info=True)
            return None

    def verifyInput(self):
        """Verify the input. Dl the RSS page and check it belongs to a journal.
        Then, call the method to save the journal"""

        abb = self.line_abbreviation.text().strip()
        url = self.line_url_journal.text().strip()
        company = self.combo_publishers.currentText()

        self.l.debug("Starting verifyInput: {}, {}, {}".format(
            abb, url, company))

        feed = self._getFeed(url, timeout=self.TIMEOUT)

        if feed is None:
            self.l.critical("verifyInput, feed is None")

            # Create error message if RSS page can't be downloaded
            error_mes = "An error occured while downloading the RSS page.\
                         Are you sure you have the right URL ?\
                         Try again later, maybe ?"

            error_mes = error_mes.replace("    ", "")
            QtWidgets.QMessageBox.critical(
                self,
                "Error while adding new journal",
                error_mes,
                QtWidgets.QMessageBox.Ok,
                defaultButton=QtWidgets.QMessageBox.Ok)

        is_feed = self._checkIsFeed(url, company, feed)

        if not is_feed:
            self.l.critical("verifyInput, not a valid feed")

            # Create error message if RSS page can't be downloaded
            error_mes = "The URL you provided does not match a valid RSS feed.\
                         Are you sure you have the right URL ?"

            error_mes = error_mes.replace("    ", "")
            QtWidgets.QMessageBox.critical(
                self,
                "Error while adding new journal",
                error_mes,
                QtWidgets.QMessageBox.Ok,
                defaultButton=QtWidgets.QMessageBox.Ok)
            return

        title = feed['feed']['title']
        mes = "The following journal will be added to your selection:\n{}"
        mes = mes.format(title)

        self.l.debug("New journal {} about to be added".format(title))

        # Confirmation dialog box
        choice = QtWidgets.QMessageBox.information(
            self,
            "Verification",
            mes,
            QtWidgets.QMessageBox.Cancel | QtWidgets.QMessageBox.Ok,
            defaultButton=QtWidgets.QMessageBox.Cancel)

        if choice == QtWidgets.QMessageBox.Cancel:
            return
        else:
            self.l.debug("Try to save the new journal")
            self.saveJournal(title, abb, url, company)

    def showHelp(self):
        """Help displayed in a dialog box to help the user when adding
        a new journal"""

        mes = """Define the abbreviation of the journal you want to add.\n\n\
        Find the URL of the RSS page of the journal you want to add.\n\n\
        Publisher: to which publisher does the new journal belong ? This\
         choice will help ChemBrows to format the articles.\n\
        NOTE: Nature2 is for journals with a RSS feed formatted like Sci. Rep.
        """

        # Clean the tabs in the message (tabs are 4 spaces)
        mes = mes.replace("    ", "")

        QtWidgets.QMessageBox.information(self, "Information", mes,
                                          QtWidgets.QMessageBox.Ok)

    def initUI(self):
        """Handles the display"""

        self.setWindowTitle('Adding new journal')

        # Open a dialog box to explain how to add a journal
        self.help_button = QtWidgets.QPushButton("Help")

        # Validate. Triggers verification process
        self.ok_button = QtWidgets.QPushButton("Add journal")

        self.form_layout = QtWidgets.QFormLayout()

        self.line_abbreviation = QtWidgets.QLineEdit()
        self.line_abbreviation.setPlaceholderText("Ex: Chem. Commun.")

        self.line_url_journal = QtWidgets.QLineEdit()
        self.line_url_journal.setPlaceholderText("http://feeds.rsc.org/rss/cc")

        list_publishers = sorted(hosts.getCompanies())
        self.combo_publishers = QtWidgets.QComboBox()
        self.combo_publishers.addItems(list_publishers)

        self.form_layout.addRow(self.help_button)
        self.form_layout.addRow("Journal abbreviation:",
                                self.line_abbreviation)
        self.form_layout.addRow("URL RSS page:", self.line_url_journal)
        self.form_layout.addRow("Publisher:", self.combo_publishers)

        # ------------------------ ASSEMBLING -----------------------------------------

        self.vbox_global = QtWidgets.QVBoxLayout()

        self.vbox_global.addLayout(self.form_layout)
        self.vbox_global.addWidget(self.ok_button)

        self.setLayout(self.vbox_global)
        self.show()

    def saveJournal(self, title, abb, url, company):
        """Will save the new journal, in file company.ini located in
        the user directory"""

        mes = "Journal already in the catalog"

        # Check if the RSS page's URL is not present in any company file
        for company in hosts.getCompanies():
            data_company = hosts.getJournals(company)

            # If URL already present, display error dialog box
            if url in data_company[2]:
                QtWidgets.QMessageBox.critical(self, "Error", mes,
                                               QtWidgets.QMessageBox.Ok)
                self.l.debug("URL {} already in catalog".format(url))
                return

        try:
            # If still here, write the new journal
            with open(os.path.join(self.DATA_PATH,
                                   "journals/{}.ini".format(company)),
                      'a',
                      encoding='utf-8') as out:
                out.write("{} : {} : {}".format(title, abb, url))
            self.l.debug("New journal written user side")
            self.l.debug("{} : {} : {}".format(title, abb, url))
            self.l.info("{} added to the catalog".format(title))
        except Exception as e:
            self.l.error("saveJournal, error writing journal: {}".format(e),
                         exc_info=True)
            return

        # Refresh parent check boxes and close
        if self.parent is not None:
            self.parent.displayJournals()
            self.parent.saveSettings()

        self.close()
Beispiel #3
0
class MyTwit(QtWidgets.QDialog):

    """Module to authenticate the user on Twitter. Allows to tweet"""
    # http://www.adrianjock.com/twitter-myth-url-shorteners/
    # https://dev.twitter.com/faq#3
    # https://dev.twitter.com/rest/reference/get/help/configuration


    def __init__(self, title, link, graphical=None, parent=None):

        super(MyTwit, self).__init__(parent)

        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)

        self.parent = parent

        # Remove html tags from the title
        self.title = removeHtml(title)

        self.link = link
        self.graphical = graphical

        self.resource_dir, self.DATA_PATH = functions.getRightDirs()

        if parent is None:
            self.l = MyLog("activity.log")
        else:
            self.l = self.parent.l

        self.CONSUMER_KEY = 'IaTVXKtZ7uBjzcVWzsVmMYKtP'
        self.CONSUMER_SECRET = '8hsz0Zj3CupFfvJMAhpG3UjMLs7HZjGywRsjRJI8IcjIA4NrEk'

        self.MY_TWITTER_CREDS = self.DATA_PATH + '/config/twitter_credentials'

        self.initUI()
        self.defineSlots()

        # If no credentials, try to get them
        if not os.path.exists(self.MY_TWITTER_CREDS):
            authentified = self.openAuthPage()

            # No credentials obtained, exit
            if not authentified:
                return

        self.setTweetText()
        self.show()


    def openAuthPage(self):

        """Method to open the web page which gives the PIN code for
        authentication. When done, verify the pin code and write the
        keys into a local file. The user won't have to do the dance each
        time he wants to tweet"""

        twitter = Twitter(auth=OAuth('', '', self.CONSUMER_KEY,
                                     self.CONSUMER_SECRET),
                          format='', api_version=None)

        token, token_secret = self.parseOauthTokens(twitter.oauth.request_token(oauth_callback="oob"))

        self.l.debug("Opening authentication URL")

        oauth_url = ('https://api.twitter.com/oauth/authorize?oauth_token=' + token)

        try:
            r = webbrowser.open(oauth_url)

            # Sometimes the last command can print some
            # crap. Wait a bit so it doesn't mess up the next
            # prompt.
            time.sleep(2)

            if not r:
                raise Exception()
        except Exception as e:
            QtWidgets.QMessageBox.critical(self, "Authentication", "ChemBrows could not open a web page.\nVisit {} to get the PIN code".format(oauth_url),
                                           QtWidgets.QMessageBox.Ok,defaultButton=QtWidgets.QMessageBox.Ok)
            self.l.error("Authentication URL not opened")
            self.l.error("openAuthPage: {}".format(e), exc_info=True)
            return False


        pin = QtWidgets.QInputDialog.getText(self, "PIN verification","Enter the PIN to authenticate yourself")

        # If OK wasn't pressed, exit
        if not pin[1]:
            return False

        oauth_verifier = pin[0]
        twitter = Twitter(auth=OAuth(token, token_secret, self.CONSUMER_KEY,
                                     self.CONSUMER_SECRET),
                          format='', api_version=None)

        try:
            oauth_token, oauth_secret = self.parseOauthTokens(twitter.oauth.access_token(oauth_verifier=oauth_verifier))
        except Exception as e:
            QtWidgets.QMessageBox.critical(self, "Authentication", "Impossible to obtain tokens",
                                           QtWidgets.QMessageBox.Ok, defaultButton=QtWidgets.QMessageBox.Ok)
            self.l.error("openAuthPage, no tokens : {}".format(e),
                         exc_info=True)
            return False

        self.l.debug("Writing authentication file")
        write_token_file(self.MY_TWITTER_CREDS, oauth_token, oauth_secret)

        self.twitter = Twitter(auth=OAuth(oauth_token, oauth_secret,
                               self.CONSUMER_KEY, self.CONSUMER_SECRET))

        return True


    def parseOauthTokens(self, result):

        """Original function from the twitter.oauth_dance module.
        Don't really know what it does (probably parsing)..."""

        for r in result.split('&'):
            k, v = r.split('=')
            if k == 'oauth_token':
                oauth_token = v
            elif k == 'oauth_token_secret':
                oauth_token_secret = v
        return oauth_token, oauth_token_secret


    def setTweetText(self):

        """Method to shorten the title if it is too long"""

        # All links are 23 characters long, even the shorter ones
        len_data = 23

        # If graphical abstract included, shorten the title of 24 characters
        # https://dev.twitter.com/rest/reference/get/help/configuration
        try:
            if self.check_graphical.checkState() == 2:
                len_data += 24
        except AttributeError:
            pass

        LEN_TWEET = constants.LEN_TWEET

        # -1 for 1 space, -10 for #ChemBrows
        if len(self.title) >= LEN_TWEET - len_data - 1 - 10:
            title = self.title[:LEN_TWEET - len_data - 1 - 10 - 3].rstrip()
            title += "..."
        else:
            title = self.title + " "

        self.text_tweet.setText(title + self.link)


    def postTweet(self):

        """Simple method to post a tweet"""

        oauth_token, oauth_secret = read_token_file(self.MY_TWITTER_CREDS)

        try:
            if self.check_graphical.checkState() == 2:
                t_up = Twitter(domain='upload.twitter.com',
                               auth=OAuth(oauth_token, oauth_secret,
                                          self.CONSUMER_KEY,
                                          self.CONSUMER_SECRET))

                with open(self.DATA_PATH + "/graphical_abstracts/{}".format(self.graphical), "rb") as image:
                    imagedata = image.read()

                id_img = t_up.media.upload(media=imagedata)["media_id_string"]
            else:
                self.l.debug("No image, check box not checked")
                id_img = None

        except AttributeError:
            self.l.debug("No image, no check box at all")
            id_img = None

        twitter = Twitter(auth=OAuth(oauth_token, oauth_secret,
                                     self.CONSUMER_KEY, self.CONSUMER_SECRET))

        text = self.text_tweet.toPlainText() + " #ChemBrows"

        if id_img is None:
            try:
                twitter.statuses.update(status=text)
            except Exception as e:
                QtWidgets.QMessageBox.critical(self, "Twitter error", "ChemBrows could not tweet that.\nYour tweet is probably too long: {} chara.".format(len(text)),
                                           QtWidgets.QMessageBox.Ok, defaultButton=QtWidgets.QMessageBox.Ok)
                self.l.error('postTweet: {}'.format(e), exc_info=True)
        else:
            try:
                twitter.statuses.update(status=text, media_ids=id_img)
            except Exception as e:
                QtWidgets.QMessageBox.critical(self, "Twitter error", "ChemBrows could not tweet that.\nYour tweet is probably too long: {} chara.".format(len(text)),
                                           QtWidgets.QMessageBox.Ok, defaultButton=QtWidgets.QMessageBox.Ok)
                self.l.error("postTweet: {}".format(e), exc_info=True)

        self.close()


    def defineSlots(self):

        """Establish the slots"""

        # If next pressed, go to next slide
        self.ok_button.clicked.connect(self.postTweet)

        # Quit the tuto at any moment
        self.cancel_button.clicked.connect(self.done)


    def initUI(self):

        """Handles the display"""

        self.text_tweet = QtWidgets.QTextEdit()

        self.cancel_button = QtWidgets.QPushButton("Cancel", self)
        self.ok_button = QtWidgets.QPushButton("Tweet me !", self)

        self.hbox_buttons = QtWidgets.QHBoxLayout()
        self.vbox_global = QtWidgets.QVBoxLayout()

        # Display a check box to let the user choose
        # if he wants the graphical abstract to be displayed
        if self.graphical is not None:
            self.check_graphical = QtWidgets.QCheckBox("Include graphical abstract")
            self.check_graphical.setCheckState(2)
            self.check_graphical.stateChanged.connect(self.setTweetText)
            self.hbox_buttons.addWidget(self.check_graphical)

        self.hbox_buttons.addWidget(self.cancel_button)
        self.hbox_buttons.addWidget(self.ok_button)

        self.vbox_global.addWidget(self.text_tweet)
        self.vbox_global.addLayout(self.hbox_buttons)

        self.setLayout(self.vbox_global)