{ "info": { "author": "Peter Odding", "author_email": "peter@peterodding.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Intended Audience :: Information Technology", "Intended Audience :: System Administrators", "License :: OSI Approved :: MIT License", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Topic :: Software Development", "Topic :: Software Development :: Libraries", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Text Processing", "Topic :: Text Processing :: Indexing" ], "description": "chat-archive: Easy to use offline chat archive\n==============================================\n\nThe Python_ program `chat-archive` provides a local archive of chat messages\nthat can be viewed and searched on the command line. Supported chat services\ninclude `Google Talk`_, `Google Hangouts`_, Slack_ and Telegram_. The program\nwas developed on Linux and currently assumes a UNIX command line environment,\nalthough this is not fundamental to the program's design (for example I could\nimagine someone building a GUI or web interface using the Python API).\n\nWhen you add a new account the initial synchronization will download your full\nconversation history from the chat service in question, this can take quite a\nwhile. Later synchronization runs will be much quicker because only updates\n(new messages and conversations) are downloaded.\n\nChat messages are downloaded as plain text and when possible also with\nformatting (encoded as HTML). When viewing chat messages on the terminal\nthe formatted text will be shown.\n\nPython 3.5+ is required due to the asynchronous nature of some of the backends.\n\n.. contents::\n :local:\n\nStatus\n------\n\nThis is very young software, developed in a couple of sprints in the summer of\n2018, so it's bound to be full of bugs! The fact that it doesn't have a test\nsuite doesn't help. However since creating this program I've started using it\non a daily basis, so I may very well be the first one to run into most if not\nall bugs \ud83d\ude07.\n\nThere's a lot of implementation details in the code base that I'm not proud of\nand there's a ton of features that I would like to add, for example right now\nthe command line is still rather bare bones (minimal). I've decided to\nnevertheless publish what I have right now, because in its current state this\nproject is already very useful for me, so it might be useful to others.\n\nI consider the first release to be representative of the functional goals I had\nin mind when I set out to build this, but I'd love to find the time to refactor\nthe code base once or twice more \ud83d\ude0b. Before publishing the first release I had\nalready gone through three or four complete rewrites and each of those rewrites\nimproved the quality of the code, yet I'm still not fully satisfied... Oh well,\nat least it seems to work \ud83d\ude09.\n\nInstallation\n------------\n\nThe `chat-archive` package is available on PyPI_ which means installation\nshould be as simple as:\n\n.. code-block:: sh\n\n $ pip3 install chat-archive\n\nMake sure you're using Python 3.5+ because this is required by dependencies of\nthe `chat-archive` program.\n\nThere's actually a multitude of ways to install Python packages (e.g. the `per\nuser site-packages directory`_, `virtual environments`_ or just installing\nsystem wide) and I have no intention of getting into that discussion here, so\nif this intimidates you then read up on your options before returning to these\ninstructions \ud83d\ude09.\n\nUsage\n-----\n\nThe command line interface is documented below. For more details about the\nPython API please refer to the API documentation available on `Read the\nDocs`_.\n\n.. contents::\n :local:\n\nCommand line\n~~~~~~~~~~~~\n\n.. A DRY solution to avoid duplication of the `chat-archive --help' text:\n..\n.. [[[cog\n.. from humanfriendly.usage import inject_usage\n.. inject_usage('chat_archive.cli')\n.. ]]]\n\n**Usage:** `chat-archive [OPTIONS] [COMMAND]`\n\nEasy to use offline chat archive that can gather chat message\nhistory from Google Talk, Google Hangouts, Slack and Telegram.\n\nSupported commands:\n\n- The 'sync' command downloads new chat messages from supported chat\n services and stores them in the local archive (an SQLite database).\n\n- The 'search' command searches the chat messages in the local archive\n for the given keyword(s) and lists matching messages.\n\n- The 'list' command lists all messages in the local archive.\n\n- The 'stats' command shows statistics about the local archive.\n\n- The 'unknown' command searches for conversations that contain messages from\n an unknown sender and allows you to enter the name of a new contact to\n associate with all of the messages from an unknown sender. Conversations\n involving multiple unknown sender are not supported.\n\n**Supported options:**\n\n.. csv-table::\n :header: Option, Description\n :widths: 30, 70\n\n\n \"``-C``, ``--context=COUNT``\",\"Print ``COUNT`` messages of output context during 'chat-archive search'. This\n works similarly to 'grep ``-C``'. The default value of ``COUNT`` is 3.\"\n \"``-f``, ``--force``\",\"Retry synchronization of conversations where errors were previously\n encountered. This option is currently only relevant to the Google Hangouts\n backend, because I kept getting server errors when synchronizing a few\n specific conversations and I didn't want to keep seeing each of those\n errors during every synchronization run :-).\"\n \"``-c``, ``--color=CHOICE,`` ``--colour=CHOICE``\",\"Specify whether ANSI escape sequences for text and background colors and\n text styles are to be used or not, depending on the value of ``CHOICE``:\n\n - The values 'always', 'true', 'yes' and '1' enable colors.\n - The values 'never', 'false', 'no' and '0' disable colors.\n - When the value is 'auto' (this is the default) then colors will\n only be enabled when an interactive terminal is detected.\"\n \"``-l``, ``--log-file=LOGFILE``\",\"Save logs at DEBUG verbosity to the filename given by ``LOGFILE``. This option\n was added to make it easy to capture the log output of an initial\n synchronization that will be downloading thousands of messages.\"\n \"``-p``, ``--profile=FILENAME``\",\"Enable profiling of the chat-archive application to make it possible to\n analyze performance problems. Python profiling data will be saved to\n ``FILENAME`` every time database changes are committed (making it possible to\n inspect the profile while the program is still running).\"\n \"``-v``, ``--verbose``\",Increase logging verbosity (can be repeated).\n \"``-q``, ``--quiet``\",Decrease logging verbosity (can be repeated).\n \"``-h``, ``--help``\",Show this message and exit.\n\n.. [[[end]]]\n\nThe 'sync' command\n++++++++++++++++++\n\nThe command ``chat-archive sync`` downloads new chat messages using the\nconfigured backends and stores the messages in the local SQLite database.\nPositional arguments can be used to synchronize specific backends or accounts.\nFor example I have two Telegram accounts, a personal account and a work\naccount. The following command will synchronize both of these accounts::\n\n $ chat-archive sync telegram\n\nWhen I'm only interested in a specific account I can instead do this::\n\n $ chat-archive sync telegram:personal\n\nYou can make this as complex as you want::\n\n $ chat-archive sync hangouts slack:work telegram:personal\n\nThe command above will synchronize all configured Google Hangouts accounts, the\nSlack work account and the Telegram personal account. The following table shows\nthe backend names you can use like this:\n\n============ ==================\nBackend name Chat service\n============ ==================\n``gtalk`` `Google Talk`_\n``hangouts`` `Google Hangouts`_\n``slack`` Slack_\n``telegram`` Telegram_\n============ ==================\n\nThe 'search' command\n++++++++++++++++++++\n\nThe command ``chat-archive search`` performs a keyword search through the chat\nmessages in the local SQLite database and renders the search results on the\nterminal. Keywords are provided as positional arguments to the ``search``\ncommand and trigger a case insensitive AND search through the following message\nmetadata:\n\n- The name of the backend (see the table above).\n- The name of the account (``default`` or a user defined name).\n- The name of the conversation (relevant for group conversations).\n- The full name of the contact that sent the message.\n- The email address of the contact that sent the message.\n- The timestamp of the message. Any prefix of the date format ``YYYY-MM-DD\n HH:MM:SS`` should work, judging by the date/time searches that I've tried so\n far. So for example the keyword ``2018`` will match all messages from that\n year, ``2018-08`` will match all messages in a specific month, etc.\n- The text of the message. The plain text chat message as well as the HTML\n formatted chat message (when available) are searched, this enables searching\n for semantically meaningful HTML data like hyperlink targets.\n\nThe search results reported on the terminal include surrounding chat messages\nfrom the matching conversations, to provide additional context. You can control\nhow many surrounding chat messages are rendered using the ``-C``, ``--context``\ncommand line option, the value 0 can be used to omit the context.\n\nThe 'list' command\n++++++++++++++++++\n\nThe command ``chat-archive list`` renders a listing of all chat messages in the\ndatabase on the terminal.\n\nDue to the gathering of context the ``chat-archive search`` command can be\nrather slow and this is why I added the ``chat-archive list`` command early in\nthe development of the project (it's faster because it doesn't have to gather\ncontext). Since then I've collected 226.941 chat messages, completely negating\nthe usefulness of the ``chat-archive list`` command \ud83d\ude07.\n\nIn any case this can be considered a very simple form of export functionality,\nso I've decided to keep the ``chat-archive list`` command for now, despite its\nlimited usefulness once one actively starts using the ``chat-archive`` program.\n\nThe 'stats' command\n+++++++++++++++++++\n\nThe command ``chat-archive stats`` reports some statistics about the contents\nof the local SQLite database. Here's what that looks like for me at the time of\nwriting::\n\n Statistics about ~/.local/share/chat-archive/database.sqlite3:\n\n - Number of contacts: 284\n - Number of conversations: 5803\n - Number of messages: 226941\n - Database file size: 90.81 MB\n - Size of 226941 plain text chat messages: 18.7 MB\n - Size of 13409 HTML formatted chat messages: 4.25 MB\n\nThe 'unknown' command\n+++++++++++++++++++++\n\nThe first time I synchronized the thousands of chat messages in my Google\nHangouts account I was very disappointed to find out that all metadata about\ncontacts whose accounts had since been deleted was lost (no names, no email\naddresses, nothing).\n\nThis is why I added the ``chat-archive unknown`` command. It searches the local\ndatabase for private conversations that contain messages from an unknown sender\nand prompts you to enter a name for the contact. When you enter a (nonempty)\nname a new contact is created and the messages in the conversation which have\nno sender are associated to the new contact.\n\nWeirdly enough the Google Mail archive of chat messages was able to show me\nnames for most of the contacts for which the Google Hangouts API no longer\nreported any useful information, this is how I was able to (manually)\nreconstruct this bit of history.\n\nIf the Google Mail archive had not provided me with this information I still\nwould have been able to reconstruct the senders of 90% of these conversations\nsimply by the fact that quite a few conversations start with \"Hi $name\" and I\nstill have \"client side chat archive backups\" (Pidgin) from 2011-2015.\n\nConfiguration files\n~~~~~~~~~~~~~~~~~~~\n\nIf you're going to be synchronizing your chat message history frequently you\ncan define credentials for the chat services that you are interested in using a\nconfiguration file.\n\n.. [[[cog\n.. from update_dotdee import inject_documentation\n.. inject_documentation(program_name='chat-archive')\n.. ]]]\n\nConfiguration files are text files in the subset of `ini syntax`_ supported by\nPython's configparser_ module. They can be located in the following places:\n\n========= ========================== ===============================\nDirectory Main configuration file Modular configuration files\n========= ========================== ===============================\n/etc /etc/chat-archive.ini /etc/chat-archive.d/\\*.ini\n~ ~/.chat-archive.ini ~/.chat-archive.d/\\*.ini\n~/.config ~/.config/chat-archive.ini ~/.config/chat-archive.d/\\*.ini\n========= ========================== ===============================\n\nThe available configuration files are loaded in the order given above, so that\nuser specific configuration files override system wide configuration files.\n\n.. _configparser: https://docs.python.org/3/library/configparser.html\n.. _ini syntax: https://en.wikipedia.org/wiki/INI_file\n\n.. [[[end]]]\n\nThe special configuration file section ``chat-archive`` defines general\noptions. Right now only the ``operator-name`` option is supported here. All\nother sections are specific to a chat account and encode the name of the\nbackend and the name of the account in the name of the section by delimiting\nthe two values with a colon. Here's an example based on my configuration, that\nshows the supported options:\n\n.. code-block:: ini\n\n [chat-archive]\n operator-name = ...\n\n [hangouts:work]\n email-address = ...\n password = ...\n # Alternatively:\n password-name = ...\n\n [slack:work]\n api-token = ...\n # Alternatively:\n api-token-name = ...\n\n [gtalk:work]\n email = ...\n password = ...\n # Alternatively:\n password-name = ...\n\n [telegram:personal]\n api-hash = ...\n api-id = ...\n phone-number = ...\n\n [telegram:work]\n api-hash = ...\n api-id = ...\n phone-number = ...\n # Alternatively:\n api-hash-name = ...\n api-id-name = ...\n\nWhen an account is configured but the configuration doesn't define a required\nsecret then you will be prompted to provide that secret every time you run the\n``chat-archive sync`` command.\n\nThe values of the ``api-token-name``, ``password-name``, ``api-hash-name`` and\n``api-id-name`` options identify secrets in ``~/.password-store`` to use, this\nprovides an alternative somewhere in between the following two extremes:\n\n- Always typing your secrets interactively (because you don't want them to be\n stored in the ``chat-archive`` configuration file, which is understandable\n from a security perspective of security).\n\n- Storing your secrets directly in the ``chat-archive`` configuration files (so\n you don't have to type secrets interactively) thereby exposing them to all\n software running on your computer.\n\nBecause pass_ can use gpg-agent_ you only have to type a single master password\nto unlock the secrets required to synchronize any number of chat accounts.\n\nThe local database\n------------------\n\nThe `chat-archive` program uses an SQLite_ database to store the chat messages\nthat it collects. Because the whole point of the program is to safeguard the\nlong term archival of chat messages, SQLAlchemy_ and Alembic_ are used to\nsupport database schema migrations. This is intended to ensure a reliable\nupgrade path for future enhancements without data loss.\n\nThere's one significant exception I can think of: The current version of the\n`chat-archive` program doesn't synchronize images and other multimedia files,\nonly text messages are stored in the local database. If support for images is\nadded in a later release (I'm not committing to this, but I am considering it)\nand collecting these is important to you then you may have to rebuild your\ndatabase if and when this support is added.\n\nYou can change the location of the SQLite database and other datafiles by\nsetting the environment variable ``$CHAT_ARCHIVE_DIRECTORY``. Making a backup\nof your chat archive is as simple as saving a copy of the database file\n``~/.local/share/chat-archive/database.sqlite3`` to another storage medium.\nPlease keep in mind that this database has the potential to contain a lot of\nsensitive data, so I strongly advise you to use disk encryption.\n\nSupported chat services\n-----------------------\n\nThe following backends are currently available:\n\n================== ===========================================================\nChat service Description\n================== ===========================================================\n`Google Talk`_ At one time this was the primary chat service of Google. It\n was based on (or at least cooperated well with) XMPP. My\n personal chat archive of Google Talk messages ends on\n 2013-12-12.\n`Google Hangouts`_ The successor to Google Talk. Interestingly enough my\n personal chat archive of Google Hangouts messages starts on\n 2013-10-30 (what's interesting to me is the overlap with\n the date above).\nSlack_ Love it or hate it, when all of your colleagues are using\n it you can't really get around it. Actually now that I\n write it down like that I can't help but think of WhatsApp_\n (where the \"peer pressure\" comes from family instead of\n colleagues).\nTelegram_ A popular alternative to WhatsApp_ from Russia, without the\n Facebook baggage \ud83d\ude07 (which is not to say that the company\n behind Telegram can't be just as evil).\n================== ===========================================================\n\nIn the future more backends may be added:\n\n- I've been contemplating scraping \"WhatsApp_ Web\" using something like\n Selenium. It would get ugly and nasty, the resulting backend would be fragile\n at best, but having those messages available might just be worth it...\n\n- I'm considering writing a chat log parser for the HTML chat logs that Pidgin\n generated ten years ago (circa 2008) because I have megabytes of such chat\n logs stored in backups \ud83d\ude42.\n\nHistory\n-------\n\nThe fragmented nature of digital communication, where messages come to you via\nnumerous channels (including multiple chat services), has bothered me for years\nnow. Finding things back can actually become a challenge \ud83d\ude07. Tangentially\nrelated is the realization that these chat services come and go, taking with\nthem years of chat history, lost forever. I'm looking at you Google \ud83d\ude09.\n\nGiven that I am a programmer by trade and heart, It's been itching for several\nyears now to try and solve both of these problems at the same time by creating\na computer program that downloads and stores the chat message history of\nmultiple chat services into a single local database, available for searching\nand trivially easy to back up.\n\nFor what it's worth I didn't start out with the goal of \"full fidelity\" chat\nhistory backup including images and other multimedia, although I may eventually\ndecide to implement it anyway. What I initially set out to build was a local,\nsearchable database of textual chat messages collected from multiple chat\nservices, with an easy way to add support for new chat services.\n\nContact\n-------\n\nThe latest version of `chat-archive` is available on PyPI_ and GitHub_. The\ndocumentation is hosted on `Read the Docs`_ and includes a changelog_. For bug\nreports please create an issue on GitHub_. If you have questions, suggestions,\netc. feel free to send me an e-mail at `peter@peterodding.com`_.\n\nLicense\n-------\n\nThis software is licensed under the `MIT license`_.\n\n\u00a9 2018 Peter Odding.\n\nHere's a quick overview of the licenses of the dependencies:\n\n============= =======================\nDependency License\n============= =======================\nAlembic_ MIT license\nemoji_ BSD license\nhangups_ MIT license\nSlacker_ Apache Software License\nSQLAlchemy_ MIT license\nTelethon_ MIT license\n============= =======================\n\nShortly before publishing this project I got worried that I had included a GPL\ndependency which (if I understand correctly) would require me to publish under\nGPL as well, even though I've been consistently publishing my open source\nprojects under the MIT license since 2010.\n\nAfter assembling the table above I can confidently say that this is not the\ncase \ud83d\ude07. The dependencies that are not listed in the table above are projects\nof mine, all of them published under the same MIT license as the `chat-archive`\nprogram (assuming I keep this up-to-date as new dependencies are added).\n\n.. External references:\n.. _Alembic: http://alembic.zzzcomputing.com/\n.. _changelog: https://chat-archive.readthedocs.io/en/latest/changelog.html\n.. _emoji: https://pypi.org/project/emoji/\n.. _GitHub: https://github.com/xolox/python-chat-archive\n.. _Google Hangouts: https://en.wikipedia.org/wiki/Google_Hangouts\n.. _Google Talk: https://en.wikipedia.org/wiki/Google_Talk\n.. _gpg-agent: https://manpages.debian.org/gpg-agent\n.. _hangups: https://pypi.org/project/hangups/\n.. _MIT license: http://en.wikipedia.org/wiki/MIT_License\n.. _pass: https://en.wikipedia.org/wiki/Pass_(software)\n.. _per user site-packages directory: https://www.python.org/dev/peps/pep-0370/\n.. _peter@peterodding.com: peter@peterodding.com\n.. _PyPI: https://pypi.python.org/pypi/chat-archive\n.. _Python: https://www.python.org/\n.. _Read the Docs: https://chat-archive.readthedocs.io/en/latest/\n.. _Slack: https://en.wikipedia.org/wiki/Slack_(software)\n.. _Slacker: https://pypi.org/project/slacker/\n.. _SQLAlchemy: https://www.sqlalchemy.org/\n.. _SQLite: https://sqlite.org/\n.. _Telegram: https://en.wikipedia.org/wiki/Telegram_(service)\n.. _Telethon: https://pypi.org/project/telethon/\n.. _virtual environments: http://docs.python-guide.org/en/latest/dev/virtualenvs/\n.. _WhatsApp: https://en.wikipedia.org/wiki/WhatsApp\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/xolox/python-chat-archive", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "chat-archive", "package_url": "https://pypi.org/project/chat-archive/", "platform": "", "project_url": "https://pypi.org/project/chat-archive/", "project_urls": { "Homepage": "https://github.com/xolox/python-chat-archive" }, "release_url": "https://pypi.org/project/chat-archive/4.0.2/", "requires_dist": [ "alembic (>=0.8.6)", "coloredlogs (>=10.0)", "emoji (>=0.5.0)", "hangups (>=0.4.6)", "humanfriendly (>=4.16.1)", "property-manager (>=2.3.1)", "qpass (>=2.2.1)", "slacker (>=0.9.65)", "sqlalchemy (>=1.2.8)", "telethon (>=1.0.2)", "update-dotdee (>=5.0)", "verboselogs (>=1.7)" ], "requires_python": "", "summary": "Easy to use offline chat archive", "version": "4.0.2" }, "last_serial": 4647109, "releases": { "4.0": [ { "comment_text": "", "digests": { "md5": "93d25d8d659bab3bf58eeab601515ba4", "sha256": "e8bd7243f1812ac5e534a48bb322900c9b8a82e89f4d4cfe6b8e1270729f7947" }, "downloads": -1, "filename": "chat_archive-4.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "93d25d8d659bab3bf58eeab601515ba4", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 64771, "upload_time": "2018-08-01T21:56:22", "url": "https://files.pythonhosted.org/packages/34/b3/7da78ffd067e83c7897e409e22a9a614eb91aaa2da12e32339db9c1a21f0/chat_archive-4.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "cf92de0193616557bd1e8c36607e1e8f", "sha256": "d5ea6b6fb2fa0897523d290cfdb2d792d492d7853e92c0f9c97615ea0f256d2d" }, "downloads": -1, "filename": "chat-archive-4.0.tar.gz", "has_sig": false, "md5_digest": "cf92de0193616557bd1e8c36607e1e8f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 57765, "upload_time": "2018-08-01T21:56:24", "url": "https://files.pythonhosted.org/packages/6b/54/2feefb3d5bbcb3a4eee8f44757f46d26c3a247f365ede4a61a920f7c3b0e/chat-archive-4.0.tar.gz" } ], "4.0.1": [ { "comment_text": "", "digests": { "md5": "7a890ab1e185dc85bbf592e2a88ec98d", "sha256": "180171359739d951ba7c10cc06d9c52222ddd3c9376d5e3144ee2ed57207dbc0" }, "downloads": -1, "filename": "chat_archive-4.0.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "7a890ab1e185dc85bbf592e2a88ec98d", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 64796, "upload_time": "2018-08-02T15:07:17", "url": "https://files.pythonhosted.org/packages/4f/b6/5e3dc60f15a9ce7cc6d0d08273363eb8f47323aa707228e3fc7bdbec3b81/chat_archive-4.0.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "309daeda2664a90d9569c6d28e47ce15", "sha256": "4ab7fc5a41ef1f4c56efb2c959a60627e54dfb6f4e7d1d6de7a2e7a2204cd893" }, "downloads": -1, "filename": "chat-archive-4.0.1.tar.gz", "has_sig": false, "md5_digest": "309daeda2664a90d9569c6d28e47ce15", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 58026, "upload_time": "2018-08-02T15:07:19", "url": "https://files.pythonhosted.org/packages/49/29/f7c2907be14362af6c2f6cd06d128028f314cc4aad4848abe7a9bc083579/chat-archive-4.0.1.tar.gz" } ], "4.0.2": [ { "comment_text": "", "digests": { "md5": "1ee7d80a05a7e92d447834360b8575ea", "sha256": "a865c42342ce9eb7e04e373b8f3023d650b9b178ae440d8f5618c3d51592eb81" }, "downloads": -1, "filename": "chat_archive-4.0.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "1ee7d80a05a7e92d447834360b8575ea", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 64914, "upload_time": "2018-12-30T23:24:10", "url": "https://files.pythonhosted.org/packages/1a/13/53adec51c04d861ceef52c34aa5a9129919610c50fc63063dd6d216da9e1/chat_archive-4.0.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "617d5177f3d9d077017a2eb20f2d9b91", "sha256": "efca96e8456f3127e5cff889ea5774a7f6d8cc38581331a9916f364a9ed6e39f" }, "downloads": -1, "filename": "chat-archive-4.0.2.tar.gz", "has_sig": false, "md5_digest": "617d5177f3d9d077017a2eb20f2d9b91", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 58390, "upload_time": "2018-12-30T23:24:12", "url": "https://files.pythonhosted.org/packages/a3/56/fcf67c3d56eab1fb96a255555fbdb9594e8ec1db8e3a4f5bf9a35b15e360/chat-archive-4.0.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "1ee7d80a05a7e92d447834360b8575ea", "sha256": "a865c42342ce9eb7e04e373b8f3023d650b9b178ae440d8f5618c3d51592eb81" }, "downloads": -1, "filename": "chat_archive-4.0.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "1ee7d80a05a7e92d447834360b8575ea", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 64914, "upload_time": "2018-12-30T23:24:10", "url": "https://files.pythonhosted.org/packages/1a/13/53adec51c04d861ceef52c34aa5a9129919610c50fc63063dd6d216da9e1/chat_archive-4.0.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "617d5177f3d9d077017a2eb20f2d9b91", "sha256": "efca96e8456f3127e5cff889ea5774a7f6d8cc38581331a9916f364a9ed6e39f" }, "downloads": -1, "filename": "chat-archive-4.0.2.tar.gz", "has_sig": false, "md5_digest": "617d5177f3d9d077017a2eb20f2d9b91", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 58390, "upload_time": "2018-12-30T23:24:12", "url": "https://files.pythonhosted.org/packages/a3/56/fcf67c3d56eab1fb96a255555fbdb9594e8ec1db8e3a4f5bf9a35b15e360/chat-archive-4.0.2.tar.gz" } ] }