如何自动开启微信通知?

如何自动开启微信通知?

自动开启微信通知

微信有一个很贴心的功能,当你在电脑上登录的时候,你可以选择不通知手机。但是这个很贴心的功能很笨,没办法再我锁定的时候自动开启通知……怎么办呢?自己解决吧!

背景

因为Mac上开了微信,手机上可以设置不提示,但我暂时离开的时候总是忘记开启微信通知。

购买了米动手表就是为了避免这样的事情发生,但是偶尔忘记打开手机上的通知会错过重要的事情。

当然,我已经将不重要的通知全部设置为消息免打扰了。

需求

因此需要在我离开笔记本之前设置手机开启通知,在我回到笔记本旁边后关闭手机通知。

分析

整个过程是如何呢?

  1. 我离开电脑,合盖/锁定;

  2. 微信进入手机通知状态(退出);

  3. 我来到电脑前,打开/解锁;

  4. 微信进入手机静音状态(登录);

那么关键的步骤就在于:

  1. 如何判断电脑锁定解锁/睡眠唤醒了呢?

  2. 如何关闭微信或者退出微信?

  3. 如何启动微信或者登录微信?

如何关闭/启动程序

查了下,下面这条命令可以通知Chrome正常关闭。


osascript -e 'tell app "/Applications/WeChat.app" to quit'

而下面这条命令可以启动Chrome。


open "/Applications/WeChat.app"

如何判断电脑睡眠

至于如何在离开电脑和回到电脑前进行操作,在参考5中看到了这么一句话:

You can schedule your Macintosh to wake up in the Energy Saver preference panel. See the Schedule button.

也就是说在电源管理中,有对应的计划任务可以管理。

在Alfred中输入EnergySaver,打开节能面板,然而,并没有计划这个按钮。

节能面板

在不进行其他程序安装的情况下,貌似这条路堵死了。

如何判断屏幕锁定

上面的内容是在5月31日更新的,今天9月14日,继续。

考虑了一下,实际上我需要在电脑锁屏后就自动转入微信通知,这样手表可以收到具体的通知信息。

那么,怎么来获取到屏幕锁定呢?在stackoverflow上找到了这么一条信息:


#!/usr/bin/python

import Quartz

d = Quartz.CGSessionCopyCurrentDictionary()

if d.get("CGSSessionScreenIsLocked", 0):

    print 'Screen locked.'

else:

    print 'Screen unocked.'

上面的代码基本上就可以判定了,那么后面的解决方案就很好办了。

解决方案

将下面的内容保存为wechat_auto.py


#!/bin/env python

# -*- coding=utf-8 -*-

import sys, os, subprocess

import logging, logging.handlers

def main():

    import time

    fn = sys._getframe().f_code.co_name

    logger.debug(u"%s()." % fn)

    while True:

        if is_system_locked():

            if is_app_running(app_name):

                control_app(app_name, 'stop')

            continue

        if not is_app_running(app_name):

            control_app(app_name, 'start')

        time.sleep(10)

def is_system_locked():

    fn = sys._getframe().f_code.co_name

    logger.debug(u"%s()." % fn)

    import Quartz

    system_locked = False

    d = Quartz.CGSessionCopyCurrentDictionary()

    result = d and \

             d.get("CGSSessionScreenIsLocked", 0) == 0 and \

             d.get("kCGSSessionOnConsoleKey", 0) == 1

    logger.debug(u'%s: CGSessionCopyCurrentDictionary is %s.' % (fn, d))

    logger.debug(u'%s: result is %s.' % (fn, result))

    if result == 0: system_locked = True

    logger.debug(u'%s: system is %slocked.' % (fn,

        '' if system_locked else 'not '))

    return system_locked

def is_app_running(app_name=None):

    fn = sys._getframe().f_code.co_name

    logger.debug(u"%s()." % fn)

    import commands

    if app_name:

        output = commands.getoutput('pgrep %s' % app_name)

        if output:

            logger.debug(u'%s: app %s is running.' % (fn, app_name))

            return True

        else:

            logger.debug(u'%s: app %s is not running.' % (fn, app_name))

            return False

    else:

        logger.error(u'%s: params is not set.' % fn)

def control_app(app_name=None, action=None):

    fn = sys._getframe().f_code.co_name

    logger.debug(u"%s()." % fn)

    if app_name and action:

        if action == 'start':

            if app_name == 'WeChat':

                p = subprocess.Popen(

                    ['osascript','%s%swechat_login.scpt' % (os.getcwd(), os.sep)],

                    stdout=subprocess.PIPE)

            else:

                p = subprocess.Popen(

                    ['osascript' '-e', 'tell "%s" to activate' % app_path],

                    stdout=subprocess.PIPE)

            logger.debug(u'%s: %s started.' % (fn, app_name))

        if action == 'stop':

            p = subprocess.Popen(

                ['osascript','-e','tell application "%s" to quit' % app_path]

                , stdout=subprocess.PIPE)

            logger.debug(u'%s: wechat stopped.' % fn)

    else:

        logger.error(u'%s: params is not set.' % fn)

def init_log(log_name='custom', log_level='info', log_files=3):

    '''

    Initialize the logger.

    '''

    log_file = u"%s%s%s.log" % (os.getcwd(), os.sep, log_name)

    logger = logging.getLogger(log_name)

    logger.setLevel(log_level.upper())

    handler = logging.handlers.RotatingFileHandler(log_file, \

        maxBytes = 1024*1024*50, backupCount = log_files)

    fmt = '%(asctime)s %(levelname)-6s %(filename)s:%(lineno)s - ' \

        + '%(message)s'

    formatter = logging.Formatter(fmt)

    handler.setFormatter(formatter)

    logger.addHandler(handler)

    return logger

prog_name = 'wechat_auto'

log_level = 'debug'

logger = init_log(prog_name, log_level)

app_name = 'WeChat'

app_path = '/Applications/WeChat.app'

main()

因为微信启动时需要登录,为了方便,我们借助AppleScript的强大功能,去帮助我们点击这个按钮。


tell application "WeChat" to activate

delay 1

tell application "System Events"

    tell application process "WeChat"

        click button "登录" of window "Window"

    end tell

end tell

随后在terminal中执行下述命令:


python wechat_auto.py &

如果执行正常的话,脚本中的log_level就可以修改为'info'了。

其他

在使用过程中遇到了两个问题,解决如下,其实是很简单的问题。

无法打开指定文件


/usr/bin/python: can't open file './system_locked.py': [Errno 2] No such file or directory

解决很简单,就是在shell脚本中使用绝对路径就好了。

微信报错

昨天在使用上述命令进行微信的启动和关闭测试时,会报一个错,然后微信关闭。

但是在后续测试中无法重现,因此这里只是做一个记录。

无法获取CGSessionCopyCurrentDictionary

因为当前进程没有对应的Session,比如我们通过crontab执行就会出现这种问题。

参考

  1. How can I quit the application opened from terminal in Mac OS X?

  2. Possible to run scripts on sleep and wake?

  3. How to Run an AppleScript On Wake Up

4. Open an application after wake from sleep

  1. OSX: check if the screen is locked

  2. How to check in Mac OSX with Python if a process is RUNNING or not

  3. python subprocess: how to run an app on OS X?

  4. Automating the User Interface

  5. 手把手教你用 AppleScript 模拟鼠标键盘操作,实现 macOS 系统的自动化操作

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 224,509评论 6 522
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 96,093评论 3 402
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 171,632评论 0 366
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 60,848评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 69,855评论 6 399
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,353评论 1 314
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,738评论 3 428
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,706评论 0 279
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,240评论 1 324
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,268评论 3 345
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,398评论 1 354
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 37,012评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,709评论 3 337
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,178评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,312评论 1 275
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,932评论 3 381
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,464评论 2 365

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,119评论 1 32
  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 12,759评论 2 59
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,418评论 25 707
  • 萤火虫整理 、 第1章 赵 百家串,祟也。声如坞,形似鼠,喜食童子耳油,脑乳,涎水等物。 吴越国赵氏妇...
    東爺DY阅读 176评论 0 0
  • 那些年错过的大雨,那些年错过的爱情,好想告诉你,告诉你我没有忘记…… ...
    竹溪晴雨阅读 374评论 2 2