{"action":"closed","issue":{"url":"https://api.github.com/repos/bmenendez/20up/issues/5","labels_url":"https://api.github.com/repos/bmenendez/20up/issues/5/labels{/name}","comments_url":"https://api.github.com/repos/bmenendez/20up/issues/5/comments","events_url":"https://api.github.com/repos/bmenendez/20up/issues/5/events","html_url":"https://github.com/bmenendez/20up/issues/5","id":103351520,"number":5,"title":"Compatibilidad con Python 3","user":{"login":"hecoding","id":7122387,"avatar_url":"https://avatars.githubusercontent.com/u/7122387?v=3","gravatar_id":"","url":"https://api.github.com/users/hecoding","html_url":"https://github.com/hecoding","followers_url":"https://api.github.com/users/hecoding/followers","following_url":"https://api.github.com/users/hecoding/following{/other_user}","gists_url":"https://api.github.com/users/hecoding/gists{/gist_id}","starred_url":"https://api.github.com/users/hecoding/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hecoding/subscriptions","organizations_url":"https://api.github.com/users/hecoding/orgs","repos_url":"https://api.github.com/users/hecoding/repos","events_url":"https://api.github.com/users/hecoding/events{/privacy}","received_events_url":"https://api.github.com/users/hecoding/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-08-26T19:55:08Z","updated_at":"2015-08-27T19:20:41Z","closed_at":"2015-08-27T19:20:41Z","body":"El script está hecho para Python 2 pero en sistemas como el mío se ejecuta automáticamente la versión 3.\r\nHe hecho un workaround para que me funcione, por no instalar librerías en 2.7.   \r\nSe puede trabajar sobre él para una versión \"más\" compatible o meter directamente, pero como el autor parece que ya no ve este proyecto me da pereza meter un pull request.\r\nAquí está el código:\r\n```python\r\n#! /usr/bin/python\r\n# -*- coding: utf-8 -*-\r\n\r\n\"\"\"\r\nCopyright (C) 2013 Borja Menendez Moreno\r\n\r\nThis program is free software: you can redistribute it and/or modify\r\nit under the terms of the GNU General Public License as published by\r\nthe Free Software Foundation, either version 3 of the License, or\r\nany later version.\r\n\r\nThis program is distributed in the hope that it will be useful,\r\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\r\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\nGNU General Public License for more details.\r\n\r\nYou should have received a copy of the GNU General Public License\r\nalong with this program. If not, see <http://www.gnu.org/licenses/>.\r\n\r\nAuthors: Borja Menéndez Moreno <tuentiup@gmail.com>\r\n\r\nProgram for the backup of Tuenti, a Spanish social network.\r\nThis program downloads all of the photos, comments, private messages and\r\nfriends' information of a specific user.\r\n\"\"\"\r\n\r\nimport os, requests, re, getpass, sys\r\nfrom time import sleep\r\n\r\nPATH = os.getcwd()\r\nBASEURI = \"https://m.tuenti.com/\"\r\ndirs = ['tagged', 'uploaded']\r\n\r\nversion = '2.0'\r\nweb = 'http://bmenendez.github.io/20up'\r\ntwitter = '@borjamonserrano'\r\nemail = 'tuentiup@gmail.com'\r\n\r\nWINDOWS = 'nt'\r\nseparatorLength = 60\r\n\r\ndef clearConsole():\r\n\treturn 'cls' if os.name == WINDOWS else 'clear'\r\n\r\ndef printWelcome():\r\n    os.system(clearConsole())\r\n    print('-' * separatorLength)\r\n    print('| 20up version ' + version)\r\n    print('|')\r\n    print('| Gracias por descargar esta aplicacion')\r\n    print('| Espero que te sea de gran utilidad :)')\r\n    print('| Si tienes alguna duda, tienes toda la info en:')\r\n    print('|')\r\n    print('|           ' + web)\r\n    print('|')\r\n    print('| Tambien puedes resolver tus dudas en twitter: ' + twitter)\r\n    print('| Asi como por e-mail a traves de: ' + email)\r\n    print('-' * separatorLength)\r\n    \r\ndef printGoodBye():\r\n    os.system(clearConsole())\r\n    print('-' * separatorLength)\r\n    print('| 20up version ' + version)\r\n    print('| Gracias por haber utilizado 20up ' + version)\r\n    print('| Espero que te haya sido de gran utilidad :)')\r\n    print('| Si tienes alguna duda, tienes toda la info en:')\r\n    print('|')\r\n    print('|           ' + web)\r\n    print('|')\r\n    print('| Tambien puedes resolver tus dudas en twitter: ' + twitter)\r\n    print('| Asi como por e-mail a traves de: ' + email)\r\n    print('-' * separatorLength)\r\n    \r\ndef printStarting(text):\r\n    os.system(clearConsole())\r\n    print('-' * separatorLength)\r\n    print('| 20up version ' + version)\r\n    print('|')\r\n    print('| Comenzando el backup de ' + text + '...')\r\n    print('-' * separatorLength)\r\n\r\ndef winGetpass(prompt='Password: ', stream=None):\r\n    \"\"\"Prompt for password with echo off, using Windows getch().\"\"\"\r\n    if sys.stdin is not sys.__stdin__:\r\n        return fallback_getpass(prompt, stream)\r\n    \r\n    import msvcrt\r\n    for c in prompt:\r\n        msvcrt.putch(c)\r\n    \r\n    pw = \"\"\r\n    while 1:\r\n        c = msvcrt.getch()\r\n        if c == '\\r' or c == '\\n':\r\n            break\r\n        if c == '\\003':\r\n            raise KeyboardInterrupt\r\n        if c == '\\b':\r\n            if pw == '':\r\n                pass\r\n            else:\r\n                pw = pw[:-1]\r\n                msvcrt.putch('\\b')\r\n                msvcrt.putch(\" \")\r\n                msvcrt.putch('\\b')\r\n        else:\r\n            pw = pw + c\r\n            msvcrt.putch(\"*\")\r\n    msvcrt.putch('\\r')\r\n    msvcrt.putch('\\n')\r\n    \r\n    return pw\r\n    \r\ndef getData():\r\n    os.system(clearConsole())\r\n    print('-' * separatorLength)\r\n    print('| Para poder hacer el backup necesito un poco mas')\r\n    print('| de informacion sobre tu cuenta de Tuenti...')\r\n    print('|')\r\n    print('| Esta informacion no se almacenara en ningun sitio')\r\n    print('| ni se enviara a ningun lado, solamente se requiere')\r\n    print('| para la conexion con tu cuenta de Tuenti :)')\r\n    print\r\n    email = input('E-mail: ')\r\n    while not re.match(r'[^@]+@[^@]+\\.[^@]+', email):\r\n        email = input('El e-mail no es valido, intenta de nuevo: ')\r\n    if os.name == WINDOWS:\r\n        password = winGetpass()\r\n    else:\r\n        password = getpass.getpass()\r\n    print('-' * separatorLength)\r\n    \r\n    return email, password \r\n    \r\ndef backupPhotos(email, password):\r\n    printStarting('fotos')\r\n    \r\n    s = requests.Session()\r\n\r\n    r = s.get(BASEURI + \"?m=Login\", verify=False)\r\n    csrf = re.findall('name=\"csrf\" value=\"(.*?)\"', r.text)[0]\r\n    data = {\r\n        \"csrf\": csrf,\r\n        \"tuentiemailaddress\": email,\r\n        \"password\": password,\r\n        \"remember\": 1}\r\n    r = s.post(BASEURI + \"?m=Login&f=process_login\", data)\r\n\r\n    if 'tuentiemail' in r.cookies:\r\n        return False\r\n\r\n    for i in range(1, 3):\r\n        r = s.get(BASEURI + \"?m=Profile&func=my_profile\", verify=False)\r\n        print('| Descargando fotos ' + dirs[i - 1] + '...')\r\n        album = BASEURI + \"?m=Albums&func=index&collection_key=%i-\" % i + \\\r\n            re.findall('key=%i-(.*?)&' % i, r.text)[0]\r\n\r\n        r = s.get(album, verify=False)\r\n        firstPic = BASEURI + \"?m=Photos&func=view_album_photo&collection_key=%i-\" % i + \\\r\n            re.findall('key=%i-(.*?)&' % i, r.text)[0]\r\n\r\n        r = s.get(firstPic, verify=False)\r\n        picQuantity = int(\r\n            re.findall('[of|de|\\/|sur|di|van|z]\\s(\\d+)\\)', r.text)[0])\r\n            \r\n        photoDownloadUrl = re.findall('img\\ssrc=\"(.*?)\"', r.text)[0]\r\n        if picQuantity > 1:\r\n            nextPhotoUrl = re.findall(\r\n                '\\)\\s\\<a href=\"(.*?)\"',\r\n                r.text)[0].replace(\"&amp;\",\r\n                                   \"&\")  # not loading a whole lib for one single entity\r\n        else:\r\n            nextPhotoUrl = None\r\n\r\n        for x in range(1, picQuantity + 1):\r\n            if x != 1:\r\n                r = s.get(\r\n                    nextPhotoUrl,\r\n                    cookies={\"screen\": \"1920-1080-1920-1040-1-20.74\"}, verify=False)\r\n                photoDownloadUrl = re.findall('img\\ssrc=\"(.*?)\"', r.text)[0]\r\n                if x != picQuantity:\r\n                    nextPhotoUrl = re.findall(\r\n                        '\\)\\s\\<a href=\"(.*?)\"',\r\n                        r.text)[0].replace(\"&amp;\", \"&\")\r\n                        \r\n            albumPath = os.path.join(PATH, dirs[i - 1])\r\n            \r\n            if not os.path.exists(albumPath):\r\n                os.makedirs(albumPath)\r\n                print(\"| Creado el directorio %s\" % dirs[i - 1])\r\n            \r\n            filename = os.path.join(albumPath, str(x) + '.jpg')\r\n            if not os.path.exists(filename):\r\n                with open(filename, \"wb\") as handle:\r\n                    r = s.get(photoDownloadUrl, verify=False)\r\n\r\n                    for block in r.iter_content(1024):\r\n                        if not block:\r\n                            break\r\n\r\n                        handle.write(block)\r\n\r\n                percent = (x * 100) / picQuantity\r\n                print('| %s.jpg descargada (%i%%)... (album %i/2)' % (x, percent, i))\r\n                sleep(0.5)  # avoid flooding\r\n\r\n    return True\r\n\r\ndef main():\r\n    done = False\r\n    while not done:\r\n        email, password = getData()\r\n        done = backupPhotos(email, password)\r\n        if not done:\r\n            print\r\n            print('| Ha habido algun error')\r\n            print('| Es posible que el usuario y/o la password sean incorrectos')\r\n            input('| Pulsa ENTER para continuar')\r\n    \r\n    printGoodBye()\r\n        \r\n    print('| Hasta pronto :)')\r\n\r\nif __name__ == '__main__':\r\n    printWelcome()\r\n    input('| Pulsa ENTER para continuar')\r\n    while True:\r\n        try:\r\n            main()\r\n            input()\r\n            break\r\n        except KeyboardInterrupt:\r\n            print\r\n            print('|')\r\n            print('| Cerrando aplicacion...')\r\n            print('|')\r\n            input()\r\n            break\r\n        except Exception:\r\n            print('|')\r\n            print('| Ha ocurrido un error inesperado:', e)\r\n            print('|')\r\n            input('| Pulsa ENTER para continuar')\r\n```"}}