def retrieve_words(request): frob = request.GET.get('frob') api = Rtm(settings.RTM_API_KEY, settings.RTM_API_SECRET, "read", None) api.retrieve_token(frob) if not api.token_valid(): raise ValueError("not a valid token") result = api.rtm.tasks.getList(list_id=settings.RTM_WORD_LIST_ID) flashcards = [] quotes = [] for tasklist in result.tasks: for taskseries in tasklist: parts = taskseries.name.split(':') if len(parts) == 1: quotes.append(''.join(parts)) if len(parts) > 1: flashcards.append((parts[0], ':'.join(parts[1:]))) context = { "rtw_data": json.dumps({"flashcards": flashcards, "quotes": quotes}), "api_token": api.token, } return render(request, 'rtw.html', context=context)
def main(): api_key = "910f700cc0ff23ed2462312c250bc560" shared_secret = "b7be4d2a824b42b1" token = sys.argv[2] if len(sys.argv) == 3 else None task_name = sys.argv[1] api = Rtm(api_key, shared_secret, "delete", token) if not api.token_valid(): url, frob = api.authenticate_desktop() webbrowser.open(url) input("Continue?") # Get the token for the frob assert (api.retrieve_token(frob)) print("New token: {}".format(api.token)) result = api.rtm.timelines.create() timeline = result.timeline.value # Add task - default is Inbox result = api.rtm.tasks.add(timeline=timeline, parse="1", name=task_name) task_id = result.list.taskseries.id print("Create task, id: {}".format(task_id))
def connect(api_key=None, shared_secret=None, token=None, frob=None): api_key = api_key or os.environ.get("RTM_KEY") shared_secret = shared_secret or os.environ.get("RTM_SECRET") token = token or os.environ.get("RTM_TOKEN") if not api_key or not shared_secret or not (token or frob): raise ValueError( "Expected an API key, app secret, and either a token or frob.") api = Rtm(api_key, shared_secret, "delete", token) if frob: api.retrieve_token(frob) print("New token: ", api.token) else: # authenication block, see http://www.rememberthemilk.com/services/api/authentication.rtm # check for valid token if not api.token_valid(): md5 = hashlib.md5() md5.update("{secret}api_key{key}permsdelete".format( secret=shared_secret, key=api_key)) api_sig = md5.hexdigest() generate_frob_url = _generate_frob_url(api_key, shared_secret) raise ValueError( "An invalid token was provided. Try generating a new frob in the browser by visiting {}" .format(generate_frob_url)) return api
def retrieve_words(request): frob = request.GET.get('frob') api = Rtm(settings.RTM_API_KEY, settings.RTM_API_SECRET, "read", None) api.retrieve_token(frob) if not api.token_valid(): raise ValueError("not a valid token") result = api.rtm.tasks.getList(list_id=settings.RTM_WORD_LIST_ID) flashcards = [] quotes = [] for tasklist in result.tasks: for taskseries in tasklist: parts = taskseries.name.split(':') if len(parts) == 1: quotes.append(''.join(parts)) if len(parts) > 1: flashcards.append((parts[0], ':'.join(parts[1:]))) context = { "rtw_data": json.dumps({ "flashcards": flashcards, "quotes": quotes }), "api_token": api.token, } return render(request, 'rtw.html', context=context)
def index(request): context = {"DEBUG": settings.DEBUG} api = Rtm(settings.RTM_API_KEY, settings.RTM_API_SECRET, "read", None) if not api.token_valid(): # use desktop-type authentication auth_url, frob = api.authenticate_desktop() # open webbrowser, wait until user authorized application context['auth_url'] = auth_url context['auth_frob'] = frob return render(request, 'index.html', context=context)
def retrieve_tasks(): print("Running job") # with open("config.yaml", 'r') as stream: # cfg = yaml.load(stream) with open('event.json') as data_file: cfg = json.load(data_file) api_key = cfg['rtm_api_key'] shared_secret = cfg['rtm_shared_secret'] token = cfg['rtm_token'] api = Rtm(api_key, shared_secret, "delete", token) # authenication block, see http://www.rememberthemilk.com/services/api/authentication.rtm # check for valid token if not api.token_valid(): print("got an invalid token", api) return # get all open tasks, see # http://www.rememberthemilk.com/services/api/methods/rtm.tasks.getList.rtm yesterdays_list = api.rtm.tasks.getList(filter="completed:yesterday") yesterdays = [] for tasklist in yesterdays_list.tasks: for taskseries in tasklist: print(taskseries.task.due, taskseries.name) yesterdays.append(taskseries) # for 3am tasks, may be an issue if it runs during the day yesterdays_extended_list = api.rtm.tasks.getList(filter="completed:today") for tasklist in yesterdays_extended_list.tasks: for taskseries in tasklist: print(taskseries.task.due, taskseries.name) yesterdays.append(taskseries) todays_list = api.rtm.tasks.getList(filter="dueBefore:tomorrow") todays = [] for tasklist in todays_list.tasks: for taskseries in tasklist: if taskseries.task.completed == "": print(taskseries.task.due, taskseries.name) todays.append(taskseries) process_tasks(todays, yesterdays)
def getTheCategoriesListStatically(apiKey, sharedSecret): ''' This method uses the RTM service by instantiating a new RTM object and tries to retrieve the list of listnames from the service. It can be run independently, as it uses an extra instance of the RTM object ''' listsNames = [] tokenManager = TokenManager() token = tokenManager.readTokenFromFile() if (token is None): # If the token doesn't exist, it won't work return listsNames rtm = Rtm(apiKey, sharedSecret, "read", token) if not rtm.token_valid(): # The token wasn't vaid return listsNames # Get the lists description, see http://www.rememberthemilk.com/services/api/methods/rtm.lists.getList.rtm listsList = rtm.rtm.lists.getList() # Get the name of each list for element in listsList.lists: listsNames.append(element.name) return listsNames
class RememberTheMilk(Entity): """Representation of an interface to Remember The Milk.""" def __init__(self, name, api_key, shared_secret, token, rtm_config): """Create new instance of Remember The Milk component.""" self._name = name self._api_key = api_key self._shared_secret = shared_secret self._token = token self._rtm_config = rtm_config self._rtm_api = Rtm(api_key, shared_secret, "delete", token) self._token_valid = None self._check_token() _LOGGER.debug("Instance created for account %s", self._name) def _check_token(self): """Check if the API token is still valid. If it is not valid any more, delete it from the configuration. This will trigger a new authentication process. """ valid = self._rtm_api.token_valid() if not valid: _LOGGER.error( "Token for account %s is invalid. You need to register again!", self.name, ) self._rtm_config.delete_token(self._name) self._token_valid = False else: self._token_valid = True return self._token_valid def create_task(self, call): """Create a new task on Remember The Milk. You can use the smart syntax to define the attributes of a new task, e.g. "my task #some_tag ^today" will add tag "some_tag" and set the due date to today. """ try: task_name = call.data.get(CONF_NAME) hass_id = call.data.get(CONF_ID) rtm_id = None if hass_id is not None: rtm_id = self._rtm_config.get_rtm_id(self._name, hass_id) result = self._rtm_api.rtm.timelines.create() timeline = result.timeline.value if hass_id is None or rtm_id is None: result = self._rtm_api.rtm.tasks.add( timeline=timeline, name=task_name, parse="1" ) _LOGGER.debug( "Created new task '%s' in account %s", task_name, self.name ) self._rtm_config.set_rtm_id( self._name, hass_id, result.list.id, result.list.taskseries.id, result.list.taskseries.task.id, ) else: self._rtm_api.rtm.tasks.setName( name=task_name, list_id=rtm_id[0], taskseries_id=rtm_id[1], task_id=rtm_id[2], timeline=timeline, ) _LOGGER.debug( "Updated task with id '%s' in account %s to name %s", hass_id, self.name, task_name, ) except RtmRequestFailedException as rtm_exception: _LOGGER.error( "Error creating new Remember The Milk task for account %s: %s", self._name, rtm_exception, ) return False return True def complete_task(self, call): """Complete a task that was previously created by this component.""" hass_id = call.data.get(CONF_ID) rtm_id = self._rtm_config.get_rtm_id(self._name, hass_id) if rtm_id is None: _LOGGER.error( "Could not find task with ID %s in account %s. " "So task could not be closed", hass_id, self._name, ) return False try: result = self._rtm_api.rtm.timelines.create() timeline = result.timeline.value self._rtm_api.rtm.tasks.complete( list_id=rtm_id[0], taskseries_id=rtm_id[1], task_id=rtm_id[2], timeline=timeline, ) self._rtm_config.delete_rtm_id(self._name, hass_id) _LOGGER.debug( "Completed task with id %s in account %s", hass_id, self._name ) except RtmRequestFailedException as rtm_exception: _LOGGER.error( "Error creating new Remember The Milk task for account %s: %s", self._name, rtm_exception, ) return True @property def name(self): """Return the name of the device.""" return self._name @property def state(self): """Return the state of the device.""" if not self._token_valid: return "API token invalid" return STATE_OK
import sys import webbrowser from rtmapi import Rtm if __name__ == '__main__': # call the program as `listtasks.py api_key shared_secret [optional: token]` # get those parameters from http://www.rememberthemilk.com/services/api/keys.rtm api_key, shared_secret = sys.argv[1:3] token = sys.argv[3] if len(sys.argv) >= 4 else None api = Rtm(api_key, shared_secret, "delete", token) # authenication block, see http://www.rememberthemilk.com/services/api/authentication.rtm # check for valid token if not api.token_valid(): # use desktop-type authentication url, frob = api.authenticate_desktop() # open webbrowser, wait until user authorized application webbrowser.open(url) raw_input("Continue?") # get the token for the frob api.retrieve_token(frob) # print out new token, should be used to initialize the Rtm object next time # (a real application should store the token somewhere) print "New token: %s" % api.token # get all open tasks, see http://www.rememberthemilk.com/services/api/methods/rtm.tasks.getList.rtm result = api.rtm.tasks.getList(filter="status:incomplete") for tasklist in result.tasks: for taskseries in tasklist: print taskseries.task.due, taskseries.name
def workhorse(): signal.signal(signal.SIGINT, quitter) # put the api token and secret in the credentials file (chmod 600) # get those parameters from http://www.rememberthemilk.com/services/api/keys.rtm debug = True if (len(sys.argv) > 1 and sys.argv[1] == 'debug') else False colourtest = True if (len(sys.argv) > 1 and sys.argv[1] == 'colourtest') else False config = configparser.ConfigParser() # test for file presence # if not there, exit telling user to rename template to file and get api key ## TODO: implement previous comment config.read_file(open('rtmstatus.conf')) # test for config items existing if (not config.has_option('main', 'api_key') or not config.has_option('main', 'shared_secret')): # without api_key or shared_secret, I cannot do anything, so exit and tell user to get an API key print ('You need to get a RTM API key and shared secret to use this script.') # exiting with an error code because the script cannot run sys.exit(1) # if token isn't there then launch API without it so we can get one and store it, else launch anyway. if config.has_option('main','token'): api = Rtm(config.get('main', 'api_key'), config.get('main', 'shared_secret'), 'read', config.get('main', 'token')) else: api = Rtm(config.get('main', 'api_key'), config.get('main', 'shared_secret'), 'read', None) # authentication block, see http://www.rememberthemilk.com/services/api/authentication.rtm # check for valid token if not api.token_valid(): # use desktop-type authentication url, frob = api.authenticate_desktop() # open webbrowser, wait until user authorized application webbrowser.open(url) input("Continue?") # get the token for the frob api.retrieve_token(frob) # If the token turns out to be invalid, we get a valid one and store it. config.set('main','token',api.token) with open('rtmstatus.conf', 'w') as configfile: config.write(configfile) # TODO test that this worked # reinitialize the Rtm object del api api = Rtm(config.get('main', 'api_key'), config.get('main', 'shared_secret'), 'read', config.get('main', 'token')) display.connect() display.display_on() print('Press Ctrl+C to quit') while True: backlight = config.get('main', 'defaultcolour') count = {} sections = config.sections() sections.sort(reverse=True) for section in sections: if section != 'main': count[section] = taskcounter(config.get(section, 'filter'), api) display.clear() for section in sections: if section != 'main': display.set_cursor_position(int(config.get(section,'x')),int(config.get(section,'y'))) if int(count[section]) < 10: display.write(config.get(section,'label') + ': ' + str(count[section])) else: display.write(config.get(section,'label') + ':' + str(count[section])) if (int(count[section]) > int(config.get(section,'threshold'))): backlight = config.get(section, 'colour') rgb = backlight.split(',') display.set_backlight_rgb(int(rgb[0]),int(rgb[1]),int(rgb[2])) time.sleep(float(config.get('main','polling_delay')))
# Grab just items due today and print them out # Written by Alan McNeil <*****@*****.**> # MIT license. from __future__ import print_function import rtm_const import sys import webbrowser from rtmapi import Rtm from Adafruit_Thermal import * if __name__ == '__main__': api = Rtm(rtm_const.api_key, rtm_const.shared_secret, "read", rtm_const.token) # authenication block, see http://www.rememberthemilk.com/services/api/authentication.rtm # check for valid token if not api.token_valid(): # use desktop-type authentication url, frob = api.authenticate_desktop() # open webbrowser, wait until user authorized application print ("URL you need to open: %s" % url) webbrowser.open(url) raw_input("Continue?") # get the token for the frob api.retrieve_token(frob) # print out new token, should be used to initialize the Rtm object next time print ("token: %s" % api.token) f1=open('./rtm_const', 'w+') f1.write("token: %s\n" % api.token) print ("You're going to need to remove the duplicate token line\n") f1.close
def main(raw_args=None): # Check the arguments passed to this script parser = argparse.ArgumentParser( description='Get a random TO DO from Remember the Milk!', prefix_chars='-/', epilog= 'Note that multiple flags are ANDed together making your search more specific. See docs for more info.' ) parser.add_argument('--loglevel', dest='loglevel', metavar='', choices=['debug'], type=str.lower, help="[optional] Set the log level (e.g. debug, etc.)") parser.add_argument( '-l', '--list', metavar='', help= "[optional] Select a specific list to search in. Use quotes if your list name has spaces in it." ) parser.add_argument( '-t', '--tag', metavar='', help="[optional] Select a specific tag to add to your search filter.") parser.add_argument( '-p', '--priority', metavar='', choices=['1', '2', '3', 'N'], help= "[optional] Select a specific priority to add to your search filter.") args = parser.parse_args(raw_args) # Set loglevel if --loglevel argument is used, otherwise set to INFO if args.loglevel is None: logging_num_level = 20 else: logging_num_level = getattr(logging, args.loglevel.upper()) LOG_FORMAT = "\n %(levelname)s: %(message)s" logging.basicConfig(level=logging_num_level, format=LOG_FORMAT) logging.debug("Args passed in are: " + str(args)) rtm_list = args.list rtm_tag = args.tag rtm_priority = args.priority # Look for a token in ~/.rtm_auth_token first user_home_dir = os.path.expanduser("~") rtm_auth_file = os.path.join(user_home_dir, '.rtm_auth_token') if os.path.exists(rtm_auth_file): with open(rtm_auth_file, "r") as f: token = f.readline() else: token = None # Create a class instance using the RtmAPI module api = Rtm(api_key, shared_secret, "read", token, api_version=2) # Authenication block, see http://www.rememberthemilk.com/services/api/authentication.rtm # Check for valid token. If none, open a browser so the user can authenticate. if not api.token_valid(): # use desktop-type authentication url, frob = api.authenticate_desktop() # open webbrowser, wait until user authorized application webbrowser.open(url) raw_input("Continue?") # get the token for the frob api.retrieve_token(frob) # print out new token, should be used to initialize the Rtm object next time # (a real application should store the token somewhere) logging.debug("New token: %s" % api.token) # Write out the token to the user's home directory f = open(rtm_auth_file, "w") f.write(api.token) f.close() # Get all incomplete tasks based on the constructed filter. # RTM filters: https://www.rememberthemilk.com/help/?ctx=basics.search.advanced filter = 'status:incomplete isSubtask:false' if rtm_list: filter = filter + ' list:"%s"' % rtm_list if rtm_tag: filter = filter + ' tag:"%s"' % rtm_tag if rtm_priority: filter = filter + ' priority:"%s"' % rtm_priority logging.debug("filter is now: " + filter) result = api.rtm.tasks.getList(filter="%s" % filter) list_of_tasks = [] # Use the RtmAPI tasks iter to put the filtered set of tasks into a list for tasklist in result.tasks: for taskseries in tasklist: list_of_tasks.append(taskseries.name) # If the total # of retrieved tasks is zero, print mesg & exit if not list_of_tasks: print "\n\tSorry, but your filter didn't find any to dos." print "\tPerhaps re-check your spelling and try again.\n" exit(0) # Pick out a random task name random_task_name = random.choice(list_of_tasks) logging.debug("Random task name is: " + random_task_name) # Use the random task's name to retrieve its full info result = "" result = api.rtm.tasks.getList(filter='name:"%s"' % random_task_name) logging.debug("results.tasks has a type of: " + str(type(result.tasks))) # Use the RtmAPI iterators to drill down to the taskseries & task info. # To better understand what's going on here, you'll need to read the # RtmAPI docs as well as how Remember The Milk's API returns queries. first_tasklist = iter(result.tasks).next() logging.debug("tasklist has a type of: " + str(type(tasklist))) first_taskseries = iter(first_tasklist).next() logging.debug("first_taskseries type is: " + str(type(first_taskseries))) spinner() # Cosmetic only ;-) print "\nTask Name: \t", COLORAMA_STYLE, COLORAMA_BG, COLORAMA_FG, first_taskseries.name, Style.RESET_ALL if "N" in first_taskseries.task.priority: print 'Priority: \t', COLORAMA_STYLE, COLORAMA_BG, COLORAMA_FG, 'None', Style.RESET_ALL else: print 'Priority: \t', COLORAMA_STYLE, COLORAMA_BG, COLORAMA_FG, first_taskseries.task.priority, Style.RESET_ALL if first_taskseries.task.due == '': print 'Due: \t\t -' else: formatted_date = strftime( strptime(first_taskseries.task.due, "%Y-%m-%dT%H:%M:%SZ"), "%d %b %Y") print 'Due: \t\t', COLORAMA_STYLE, COLORAMA_BG, COLORAMA_FG, formatted_date, Style.RESET_ALL # As a bonus, print the # of tasks in the user's search filter print "\nPS: The total # of tasks with your search filter is: ", COLORAMA_STYLE, \ COLORAMA_BG, COLORAMA_FG, len(list_of_tasks), Style.RESET_ALL, "\n"