import os
import requests

from django.core.management.base import BaseCommand

from readthedocs.projects.models import Project
from readthedocs.projects.constants import GITHUB_REGEXS, PROGRAMMING_LANGUAGES

PL_DICT = {}

for slug, name in PROGRAMMING_LANGUAGES:
    PL_DICT[name] = slug


class Command(BaseCommand):
    """
    Import a project's programming language from GitHub.

    This builds a basic management command that will set
    a projects language to the most used one in GitHub.

    Requies a ``GITHUB_AUTH_TOKEN`` to be set in the environment,
    which should contain a proper GitHub Oauth Token for rate limiting.
    """

    def handle(self, *args, **options):
        token = os.environ.get('GITHUB_AUTH_TOKEN')
        if not token:
            print 'Invalid GitHub token, exiting'
            return

        for project in Project.objects.filter(programming_language__in=['none', '', 'words']):
            user = repo = ''
            repo_url = project.repo
            for regex in GITHUB_REGEXS:
                match = regex.search(repo_url)
                if match:
                    user, repo = match.groups()
                    break

            if not user:
                print 'No GitHub repo for %s' % repo_url
                continue

            url = 'https://api.github.com/repos/{user}/{repo}/languages'.format(
                user=user,
                repo=repo,
            )
            # We need this to get around GitHub's rate limiting
            headers = {'Authorization': 'token {token}'.format(token=token)}
            resp = requests.get(url, headers=headers)
            languages = resp.json()
            if not languages:
                continue
            sorted_langs = sorted(languages.items(), key=lambda x: x[1], reverse=True)
            print 'Sorted langs: %s ' % sorted_langs
            top_lang = sorted_langs[0][0]
            if top_lang in PL_DICT:
                slug = PL_DICT[top_lang]
                print 'Setting %s to %s' % (repo_url, slug)
                Project.objects.filter(pk=project.pk).update(programming_language=slug)
            else:
                print 'Language unknown: %s' % top_lang

@@ -283,16 +283,28 @@
 = slug%0A%0A
+CACHE = %7B%7D%0A%0A
 %0Aclass C
@@ -881,16 +881,29 @@
 .filter(
+%0A            
 programm
@@ -940,16 +940,79 @@
 'words'%5D
+%0A        ).filter(%0A            repo__contains='github'%0A        
 ):%0A     
@@ -1367,16 +1367,146 @@
 ntinue%0A%0A
+            cache_key = '%25s-%25s' %25 (user, repo)%0A            top_lang = CACHE.get(cache_key, None)%0A            if not top_lang:%0A    
         
@@ -1590,24 +1590,28 @@
             
+    
 user=user,%0A 
@@ -1609,16 +1609,20 @@
 r=user,%0A
+    
         
@@ -1640,16 +1640,20 @@
 o=repo,%0A
+    
         
@@ -1670,16 +1670,20 @@
         
+    
 # We nee
@@ -1726,16 +1726,20 @@
 imiting%0A
+    
         
@@ -1819,16 +1819,20 @@
         
+    
 resp = r
@@ -1865,16 +1865,20 @@
 eaders)%0A
+    
         
@@ -1913,24 +1913,28 @@
             
+    
 if not langu
@@ -1947,32 +1947,36 @@
                 
+    
 continue%0A       
@@ -1968,16 +1968,20 @@
 ontinue%0A
+    
         
@@ -2059,16 +2059,20 @@
 e=True)%0A
+    
         
@@ -2120,32 +2120,36 @@
 ngs%0A            
+    
 top_lang = sorte
@@ -2162,16 +2162,89 @@
 s%5B0%5D%5B0%5D%0A
+            else:%0A                print 'Cached top_lang: %25s' %25 top_lang%0A
         

Add caching to repo language data