LaunchKit - A set of web-based tools for mobile app developers, now open source!

Overview

LaunchKit

This repo contains an unbranded version of all the code that once powered LaunchKit. This notably includes Screenshot Builder, a web UI for creating App Store screenshots, and Review Monitor, which monitors Apple App Store review RSS feeds for new reviews and optionally notifies you about them.

DISCLAIMER This code was originally a subscription-supported consumer product, serving millions of web requests across many servers. If you are not technical, it will probably be difficult to make this work.

There's a bunch of other code in here for supporting the old LaunchKit SDK, in case you want to, for example, host a whitelabel in-app analytics platform or build a hosted server-configurable feature flags offering.

Overview

We have packaged things up to run easily with Vagrant and Ansible, so getting started running LaunchKit's services locally should be fairly straightforward in theory.

If anything in this guide is not accurate or if you run into any issues installing & running LaunchKit, please send us a pull request. No one is actively addressing bug reports, but we will happily review and integrate pull requests.

Getting Started

Getting your LK instance up and running is fairly simple. This process has been tested thoroughly on Mac OS 10.11, but should also work on other systems compatible with Vagrant, VirtualBox and Ansible.

STEP 1

(OS X only -- on Linux & other systems you might need various other build tools in order to install Vagrant/Ansible.)

Install Xcode dev tools if you don’t have them yet. Running cc from the command line on OS X Terminal should prompt you to install them.

$ cc

If the command complains about clang input, you're all set.

STEP 2

Install Vagrant. You can find the installer here: https://www.vagrantup.com/downloads.html

Once the installer finishes, you don't need to do anything else.

STEP 3

Install VirtualBox 5.0. You can find 5.0.x here: https://www.virtualbox.org/wiki/Download_Old_Builds_5_0 (The latest 5.1.x versions are not yet compatible for some reason, so use 5.0.x.)

Once the installer finishes, you don't need to open the VirtualBox app. (You can close it if it opens.)

STEP 4

Install ansible:

# You need pip and a newer version of setuptools to use ansible
$ sudo easy_install pip
$ pip install --upgrade setuptools --user python

# Install ansible globally
$ sudo pip install ansible

ansible should now work as a command:

$ ansible

(Output should be an error message about missing targets, that's fine.)

STEP 5

Get the LaunchKit code and configure your LK settings.

$ git clone https://github.com/LaunchKit/LaunchKit.git
$ cd LaunchKit

Edit your System Configuration according to the various configuration detailed in the next section. (If you do this after the server is started, you will have to reboot.)

STEP 6

Start LaunchKit (this might take awhile):

$ vagrant up --provision

After that command finishes, your LK instance should be up and running at http://localhost:9100/ — woohoo! (The instance might not be ready right away, check 30 seconds after provision is done.)

If you're all done using LaunchKit, you can stop the machine by running:

$ vagrant halt

If you're never going to use LaunchKit again, you can destroy the machine altogether:

$ vagrant destroy

System Configuration

LaunchKit will work largely out of the box, but each service has some external dependencies that you will need to configure if you wish the service to work properly.

We have moved the most common configuration bits for LaunchKit into LaunchKit/backend/settings.py so you can easily find and reconfigure your local instance. After changes are made to this file, you should restart your local instance using vagrant reload — changes will not be reflected immediately on a running system.

Global

If you want your LK instance to send emails, you will need to update the following settings:

  • EMAIL_SMTP_HOST → You can set up an account with a service like Sendgrid, and enter their SMTP endpoint here, eg. smtp.sendgrid.com. By default TLS on port 587 is used, this is editable further down in the file.
  • EMAIL_SMTP_USER and EMAIL_SMTP_PASSWORD → Your SMTP account credentials.
  • EMAIL_FROM_DOMAIN → This should be the email address you with to send email from, eg. yourdomain.com.

Screenshot Builder

Screenshot Builder runs locally and in your browser, but has one key dependency: in production environments, .zip files should be uploaded and hosted from Amazon S3, rather than the default local configuration.

In LaunchKit/backend/settings.py, update:

  • BUNDLES_S3_BUCKET_NAME → Set this to the name of your S3 bucket, eg. my-screenshot-bundles
  • READWRITE_S3_ACCESS_KEY_ID → Create an IAM role for a user with write access to your S3 bucket, and set the ID here.
  • READWRITE_S3_SECRET_ACCESS_KEY → ... and set the SECRET here.
  • READONLY_S3_ACCESS_KEY_ID → When serving bundles for download, you may wish to use a different IAM role if this server is public. Set this key to an IAM role with read access to your S3 bucket.
  • READONLY_S3_SECRET_ACCESS_KEY → ... and set the SECRET for that user here.

Review Monitor & Sales Monitor

If you would like Slack or Twitter integrations to work in your local instance, you must create a Slack App or Twitter App and enter the key pairs in backend/settings.py. The relevant keys are:

  • SLACK_CLIENT_ID and SLACK_CLIENT_SECRET → Credentials for your Slack App
  • TWITTER_APP_KEY and TWITTER_APP_SECRET → Credentials for your Twitter App

If you would like Twitter preview images to work properly, you will need to configure a URL2PNG account and set URL2PNG_URL_KEY and URL2PNG_SECRET_KEY.

App Websites

If you want to use App Websites to host an actual website, you will need to expose the hosted frontend webserver externally. This webserver is accessible locally on http://localhost:9105/ and works by loading the website configured for the current domain ("localhost" in this case) in order to render it.

To test it locally, you can create an App Website and set your domain to "localhost" — then your website should show up on http://localhost:9105/ just like how you made it. If you configure a domain for it, eg. hosted.yourdomain.com, you can use that domain as a CNAME endpoint to host many App Websites.

Super Users & Cloud Config

These products use our LaunchKit iOS SDK to send events to the backend. In order to use them, our API webserver — located at http://localhost:9101/ — must be accessible to the network your phone client is on. You can then update the iOS SDK to communicate with your instance of the API webserver, at whichever address you end up hosting it on.

Architecture Overview

LaunchKit spawns several different processes in order to work:

  • Skit frontend — http://localhost:9100/ → Renders all of our frontend HTML, JavaScript and CSS. This server communicates with our backend API over HTTP in order to load content, and does not access the database itself. Daemon: ansible/roles/lk-skit, code: LaunchKit/skit/...
  • API backend — http://localhost:9101/ → Authenticates users, loads content, renders JSON over a REST API for all services. Daemon: ansible/roles/lk-django/files/init.lk-django.conf, code: LaunchKit/backend/...
  • Celery task worker → Executes async tasks, spread throughout python codebase. Sends emails, fetches data from iTunes, creates Screenshot Bundles, etc. ansible/roles/lk-django/files/init.celery.conf, code: LaunchKit/backend/...
  • Review ingester → Loads reviews from iTunes periodically. ansible/roles/lk-review-ingester, code: LaunchKit/backend/review_ingester.py
  • Skit hosted frontend — http://localhost:9105/ → Loads and renders custom App Websites according to the current domain (provided in the Host: HTTP header) and is not used by the other products. Daemon: ansible/roles/lk-skit, code: LaunchKit/skit/lk/public_hosted/...
  • App Engine images host — http://localhost:9103/ → Our GAE server handles all image hosting, image uploading and image resizing for LaunchKit products. Daemon: ansible/roles/lk-google-app-engine, code: LaunchKit/gae/...
  • Dev proxy — http://localhost:9102/ → A hack to enable App Engine to work with CORS locally. Daemon: ansible/roles/lk-go-devproxy, code: LaunchKit/devproxy.go

Code Organization

LaunchKit is largely two codebases: a large python app called backend, and a large JavaScript app called skit. There are other parts that are less important, but those are the two primary codebases.

  • ansible → All configuration for this local runtime environment, which spawns all services and loads all dependencies.
  • backend → All python code, which is organized in a vaguely Django-like way, for our backend API and async task queues. This Django project has only one "app", called lk, which can be found in backend/lk/. Settings are in backend/settings.py.
  • backend/lk/views → Backend API HTTP handlers.
  • backend/lk/logic → Backend business logic for creating and managing various LK products.
  • backend/lk/models → Backend database models for storing everything in LaunchKit.
  • gae → A simple App Engine python application which handles all LaunchKit images. In production, Google App Engine's image service is simply incredible.
  • skit → Our frontend web app and hosted App Websites webservers, based on Skit.
  • skit/lk/library → Library code used throughout the LK frontend & hosted frontend.
  • skit/lk/public → Code for the public website, located at https://launchkit.io/
  • skit/lk/public_hosted → Code for the hosted App Website endpoint, located at http://domains.launchkit.io/
Comments
  • [DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user

    [DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user

    I'm not sure at what point this stops working...but the warnings say it will be removed in a future release.

    [DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo' (default). This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.

    opened by Herzogdb 13
  • vagrant up --provision stuck on 'Booting VM...'

    vagrant up --provision stuck on 'Booting VM...'

    Fought my way through the steps but can't seem to proceed past the booting VM. I gave it sufficient time of course. Is this a memory size issue?

    I tried reducing the memory size so that both fit on a 1GB server but still no luck.

    Server Info: 1 GB Memory / 20 GB Disk - Ubuntu 16.04.1 x64 vboxmanage --version : 5.0.26r108824 Vagrant 1.8.1

    screen shot 2016-07-28 at 9 28 55 pm
    opened by acegreen 9
  • Which LaunchKit functionalities require Xcode dev tools?

    Which LaunchKit functionalities require Xcode dev tools?

    I intended to install LaunchKit on a DigitalOcean server but was hindered from doing so at the very first installation step. Xcode Command Line tools are only available on macOS. It would be great to understand which functionality requires this and if we can proceed without it?

    opened by acegreen 6
  • Docker Support

    Docker Support

    Nowadays Docker is a widely adopted technology. And also VirtualBox support is currently limited.

    This merge request provides the support for Docker via docker-compose.

    opened by victorkifer 5
  • Setup LK on Amazone EC2

    Setup LK on Amazone EC2

    Anyone can make LK run on EC2? I want to use it on real server, not local. But when i try to install VirtualBox on Centos 7, it failed with error: "Running VirtualBox in a Xen environment is not supported"

    opened by dzungpv 5
  • Image uploads failing in browser for some reason

    Image uploads failing in browser for some reason

    I'm not really a Python/Django person so forgive my ignorance here, but I can't get beyond the screen(see below) in the screenshot builder on the local dev env. The directions don't really mention any setup to GAE. Is there additional config that needs to happen to make that work properly?

    screen shot 2016-08-04 at 11 56 46 pm
    opened by zzimbler 5
  • Provision fails with

    Provision fails with "fatal error: ffi.h: No such file or directory"

    I tried to install LaunchKit and it failed on me on Step 6.

    Running vagrant up --provision failed, resulting in the following error output:

    TASK [lk-django : install python requirements] *********************************
    fatal: [default]: FAILED! => {"changed": false, "cmd": "/usr/local/bin/pip install -r /vagrant/requirements.txt", "failed": true, "msg": "stdout: Requirement already satisfied (use --upgrade to upgrade): boto==2.38.0 in /usr/local/lib/python2.7/dist-packages (from -r /vagrant/requirements.txt (line 1))\nRequirement already satisfied (use --upgrade to upgrade): celery[redis]==3.1.17 in /usr/local/lib/python2.7/dist-packages (from -r /vagrant/requirements.txt (line 2))\nRequirement already satisfied (use --upgrade to upgrade): cssutils==1.0.1 in /usr/local/lib/python2.7/dist-packages (from -r /vagrant/requirements.txt (line 3))\nRequirement already satisfied (use --upgrade to upgrade): django-bitfield==1.7.1 in /usr/local/lib/python2.7/dist-packages (from -r /vagrant/requirements.txt (line 4))\nRequirement already satisfied (use --upgrade to upgrade): Django==1.7.3 in /usr/local/lib/python2.7/dist-packages (from -r /vagrant/requirements.txt (line 5))\nRequirement already satisfied (use --upgrade to upgrade): djorm-pgarray==1.2.0 in /usr/local/lib/python2.7/dist-packages (from -r /vagrant/requirements.txt (line 6))\nRequirement already satisfied (use --upgrade to upgrade): dnspython==1.12.0 in /usr/local/lib/python2.7/dist-packages (from -r /vagrant/requirements.txt (line 7))\nCollecting fabric==1.10.1 (from -r /vagrant/requirements.txt (line 8))\nCollecting hiredis==0.1.5 (from -r /vagrant/requirements.txt (line 9))\nCollecting Pillow==3.0.0 (from -r /vagrant/requirements.txt (line 10))\nCollecting premailer==1.3.0 (from -r /vagrant/requirements.txt (line 11))\n  Using cached premailer-1.3.0-py26-none-any.whl\nCollecting psycopg2==2.5.4 (from -r /vagrant/requirements.txt (line 12))\nRequirement already satisfied (use --upgrade to upgrade): pycrypto==2.6.1 in /usr/lib/python2.7/dist-packages (from -r /vagrant/requirements.txt (line 13))\nCollecting pylint==0.28.0 (from -r /vagrant/requirements.txt (line 14))\nCollecting python-memcached==1.53 (from -r /vagrant/requirements.txt (line 15))\nRequirement already satisfied (use --upgrade to upgrade): redis==2.10.3 in /usr/local/lib/python2.7/dist-packages (from -r /vagrant/requirements.txt (line 16))\nCollecting requests==2.5.3 (from -r /vagrant/requirements.txt (line 17))\n  Using cached requests-2.5.3-py2.py3-none-any.whl\nCollecting sqlalchemy==0.9.8 (from -r /vagrant/requirements.txt (line 18))\nCollecting tweepy==3.3.0 (from -r /vagrant/requirements.txt (line 19))\n  Using cached tweepy-3.3.0-py2.py3-none-any.whl\nCollecting ua-parser==0.3.6 (from -r /vagrant/requirements.txt (line 20))\nRequirement already satisfied (use --upgrade to upgrade): pytz>dev in /usr/local/lib/python2.7/dist-packages (from celery[redis]==3.1.17->-r /vagrant/requirements.txt (line 2))\nRequirement already satisfied (use --upgrade to upgrade): kombu<3.1,>=3.0.24 in /usr/local/lib/python2.7/dist-packages (from celery[redis]==3.1.17->-r /vagrant/requirements.txt (line 2))\nRequirement already satisfied (use --upgrade to upgrade): billiard<3.4,>=3.3.0.19 in /usr/local/lib/python2.7/dist-packages (from celery[redis]==3.1.17->-r /vagrant/requirements.txt (line 2))\nRequirement already satisfied (use --upgrade to upgrade): six in /usr/lib/python2.7/dist-packages (from django-bitfield==1.7.1->-r /vagrant/requirements.txt (line 4))\nCollecting paramiko>=1.10 (from fabric==1.10.1->-r /vagrant/requirements.txt (line 8))\n  Using cached paramiko-2.0.2-py2.py3-none-any.whl\nCollecting cssselect (from premailer==1.3.0->-r /vagrant/requirements.txt (line 11))\n  Using cached cssselect-0.9.2-py2.py3-none-any.whl\nRequirement already satisfied (use --upgrade to upgrade): lxml in /usr/lib/python2.7/dist-packages (from premailer==1.3.0->-r /vagrant/requirements.txt (line 11))\nCollecting logilab-astng>=0.24.3 (from pylint==0.28.0->-r /vagrant/requirements.txt (line 14))\nCollecting logilab-common>=0.53.0 (from pylint==0.28.0->-r /vagrant/requirements.txt (line 14))\nCollecting requests-oauthlib>=0.4.1 (from tweepy==3.3.0->-r /vagrant/requirements.txt (line 19))\n  Using cached requests_oauthlib-0.6.2-py2.py3-none-any.whl\nRequirement already satisfied (use --upgrade to upgrade): anyjson>=0.3.3 in /usr/local/lib/python2.7/dist-packages (from kombu<3.1,>=3.0.24->celery[redis]==3.1.17->-r /vagrant/requirements.txt (line 2))\nRequirement already satisfied (use --upgrade to upgrade): amqp<2.0,>=1.4.9 in /usr/local/lib/python2.7/dist-packages (from kombu<3.1,>=3.0.24->celery[redis]==3.1.17->-r /vagrant/requirements.txt (line 2))\nCollecting cryptography>=1.1 (from paramiko>=1.10->fabric==1.10.1->-r /vagrant/requirements.txt (line 8))\n  Using cached cryptography-1.5.tar.gz\nRequirement already satisfied (use --upgrade to upgrade): pyasn1>=0.1.7 in /usr/local/lib/python2.7/dist-packages (from paramiko>=1.10->fabric==1.10.1->-r /vagrant/requirements.txt (line 8))\nRequirement already satisfied (use --upgrade to upgrade): setuptools in /usr/lib/python2.7/dist-packages (from logilab-common>=0.53.0->pylint==0.28.0->-r /vagrant/requirements.txt (line 14))\nCollecting oauthlib>=0.6.2 (from requests-oauthlib>=0.4.1->tweepy==3.3.0->-r /vagrant/requirements.txt (line 19))\nRequirement already satisfied (use --upgrade to upgrade): idna>=2.0 in /usr/local/lib/python2.7/dist-packages (from cryptography>=1.1->paramiko>=1.10->fabric==1.10.1->-r /vagrant/requirements.txt (line 8))\nRequirement already satisfied (use --upgrade to upgrade): enum34 in /usr/local/lib/python2.7/dist-packages (from cryptography>=1.1->paramiko>=1.10->fabric==1.10.1->-r /vagrant/requirements.txt (line 8))\nRequirement already satisfied (use --upgrade to upgrade): ipaddress in /usr/local/lib/python2.7/dist-packages (from cryptography>=1.1->paramiko>=1.10->fabric==1.10.1->-r /vagrant/requirements.txt (line 8))\nCollecting cffi>=1.4.1 (from cryptography>=1.1->paramiko>=1.10->fabric==1.10.1->-r /vagrant/requirements.txt (line 8))\n  Using cached cffi-1.8.2.tar.gz\nRequirement already satisfied (use --upgrade to upgrade): pycparser in /usr/local/lib/python2.7/dist-packages (from cffi>=1.4.1->cryptography>=1.1->paramiko>=1.10->fabric==1.10.1->-r /vagrant/requirements.txt (line 8))\nBuilding wheels for collected packages: cryptography, cffi\n  Running setup.py bdist_wheel for cryptography: started\n  Running setup.py bdist_wheel for cryptography: finished with status 'error'\n  Complete output from command /usr/bin/python -u -c \"import setuptools, tokenize;__file__='/tmp/pip-build-037dd7/cryptography/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\\r\\n', '\\n'), __file__, 'exec'))\" bdist_wheel -d /tmp/tmpXoHdSKpip-wheel- --python-tag cp27:\n  c/_cffi_backend.c:15:17: fatal error: ffi.h: No such file or directory\n   #include <ffi.h>\n                   ^\n  compilation terminated.\n  Traceback (most recent call last):\n    File \"<string>\", line 1, in <module>\n    File \"/tmp/pip-build-037dd7/cryptography/setup.py\", line 334, in <module>\n      **keywords_with_side_effects(sys.argv)\n    File \"/usr/lib/python2.7/distutils/core.py\", line 111, in setup\n      _setup_distribution = dist = klass(attrs)\n    File \"/usr/lib/python2.7/dist-packages/setuptools/dist.py\", line 239, in __init__\n      self.fetch_build_eggs(attrs.pop('setup_requires'))\n    File \"/usr/lib/python2.7/dist-packages/setuptools/dist.py\", line 264, in fetch_build_eggs\n      replace_conflicting=True\n    File \"/usr/lib/python2.7/dist-packages/pkg_resources.py\", line 620, in resolve\n      dist = best[req.key] = env.best_match(req, ws, installer)\n    File \"/usr/lib/python2.7/dist-packages/pkg_resources.py\", line 858, in best_match\n      return self.obtain(req, installer) # try and download/install\n    File \"/usr/lib/python2.7/dist-packages/pkg_resources.py\", line 870, in obtain\n      return installer(requirement)\n    File \"/usr/lib/python2.7/dist-packages/setuptools/dist.py\", line 314, in fetch_build_egg\n      return cmd.easy_install(req)\n    File \"/usr/lib/python2.7/dist-packages/setuptools/command/easy_install.py\", line 616, in easy_install\n      return self.install_item(spec, dist.location, tmpdir, deps)\n    File \"/usr/lib/python2.7/dist-packages/setuptools/command/easy_install.py\", line 646, in install_item\n      dists = self.install_eggs(spec, download, tmpdir)\n    File \"/usr/lib/python2.7/dist-packages/setuptools/command/easy_install.py\", line 834, in install_eggs\n      return self.build_and_install(setup_script, setup_base)\n    File \"/usr/lib/python2.7/dist-packages/setuptools/command/easy_install.py\", line 1040, in build_and_install\n      self.run_setup(setup_script, setup_base, args)\n    File \"/usr/lib/python2.7/dist-packages/setuptools/command/easy_install.py\", line 1028, in run_setup\n      raise DistutilsError(\"Setup script exited with %s\" % (v.args[0],))\n  distutils.errors.DistutilsError: Setup script exited with error: command 'x86_64-linux-gnu-gcc' failed with exit status 1\n  \n  ----------------------------------------\n  Running setup.py clean for cryptography\n  Complete output from command /usr/bin/python -u -c \"import setuptools, tokenize;__file__='/tmp/pip-build-037dd7/cryptography/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\\r\\n', '\\n'), __file__, 'exec'))\" clean --all:\n  c/_cffi_backend.c:15:17: fatal error: ffi.h: No such file or directory\n   #include <ffi.h>\n                   ^\n  compilation terminated.\n  Traceback (most recent call last):\n    File \"<string>\", line 1, in <module>\n    File \"/tmp/pip-build-037dd7/cryptography/setup.py\", line 334, in <module>\n      **keywords_with_side_effects(sys.argv)\n    File \"/usr/lib/python2.7/distutils/core.py\", line 111, in setup\n      _setup_distribution = dist = klass(attrs)\n    File \"/usr/lib/python2.7/dist-packages/setuptools/dist.py\", line 239, in __init__\n      self.fetch_build_eggs(attrs.pop('setup_requires'))\n    File \"/usr/lib/python2.7/dist-packages/setuptools/dist.py\", line 264, in fetch_build_eggs\n      replace_conflicting=True\n    File \"/usr/lib/python2.7/dist-packages/pkg_resources.py\", line 620, in resolve\n      dist = best[req.key] = env.best_match(req, ws, installer)\n    File \"/usr/lib/python2.7/dist-packages/pkg_resources.py\", line 858, in best_match\n      return self.obtain(req, installer) # try and download/install\n    File \"/usr/lib/python2.7/dist-packages/pkg_resources.py\", line 870, in obtain\n      return installer(requirement)\n    File \"/usr/lib/python2.7/dist-packages/setuptools/dist.py\", line 314, in fetch_build_egg\n      return cmd.easy_install(req)\n    File \"/usr/lib/python2.7/dist-packages/setuptools/command/easy_install.py\", line 616, in easy_install\n      return self.install_item(spec, dist.location, tmpdir, deps)\n    File \"/usr/lib/python2.7/dist-packages/setuptools/command/easy_install.py\", line 646, in install_item\n      dists = self.install_eggs(spec, download, tmpdir)\n    File \"/usr/lib/python2.7/dist-packages/setuptools/command/easy_install.py\", line 834, in install_eggs\n      return self.build_and_install(setup_script, setup_base)\n    File \"/usr/lib/python2.7/dist-packages/setuptools/command/easy_install.py\", line 1040, in build_and_install\n      self.run_setup(setup_script, setup_base, args)\n    File \"/usr/lib/python2.7/dist-packages/setuptools/command/easy_install.py\", line 1028, in run_setup\n      raise DistutilsError(\"Setup script exited with %s\" % (v.args[0],))\n  distutils.errors.DistutilsError: Setup script exited with error: command 'x86_64-linux-gnu-gcc' failed with exit status 1\n  \n  ----------------------------------------\n  Running setup.py bdist_wheel for cffi: started\n  Running setup.py bdist_wheel for cffi: finished with status 'error'\n  Complete output from command /usr/bin/python -u -c \"import setuptools, tokenize;__file__='/tmp/pip-build-037dd7/cffi/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\\r\\n', '\\n'), __file__, 'exec'))\" bdist_wheel -d /tmp/tmpmlQBIFpip-wheel- --python-tag cp27:\n  running bdist_wheel\n  running build\n  running build_py\n  creating build\n  creating build/lib.linux-x86_64-2.7\n  creating build/lib.linux-x86_64-2.7/cffi\n  copying cffi/backend_ctypes.py -> build/lib.linux-x86_64-2.7/cffi\n  copying cffi/commontypes.py -> build/lib.linux-x86_64-2.7/cffi\n  copying cffi/setuptools_ext.py -> build/lib.linux-x86_64-2.7/cffi\n  copying cffi/api.py -> build/lib.linux-x86_64-2.7/cffi\n  copying cffi/__init__.py -> build/lib.linux-x86_64-2.7/cffi\n  copying cffi/model.py -> build/lib.linux-x86_64-2.7/cffi\n  copying cffi/verifier.py -> build/lib.linux-x86_64-2.7/cffi\n  copying cffi/cffi_opcode.py -> build/lib.linux-x86_64-2.7/cffi\n  copying cffi/ffiplatform.py -> build/lib.linux-x86_64-2.7/cffi\n  copying cffi/cparser.py -> build/lib.linux-x86_64-2.7/cffi\n  copying cffi/vengine_gen.py -> build/lib.linux-x86_64-2.7/cffi\n  copying cffi/recompiler.py -> build/lib.linux-x86_64-2.7/cffi\n  copying cffi/vengine_cpy.py -> build/lib.linux-x86_64-2.7/cffi\n  copying cffi/lock.py -> build/lib.linux-x86_64-2.7/cffi\n  copying cffi/_cffi_include.h -> build/lib.linux-x86_64-2.7/cffi\n  copying cffi/parse_c_type.h -> build/lib.linux-x86_64-2.7/cffi\n  copying cffi/_embedding.h -> build/lib.linux-x86_64-2.7/cffi\n  running build_ext\n  building '_cffi_backend' extension\n  creating build/temp.linux-x86_64-2.7\n  creating build/temp.linux-x86_64-2.7/c\n  x86_64-linux-gnu-gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DUSE__THREAD -I/usr/include/ffi -I/usr/include/libffi -I/usr/include/python2.7 -c c/_cffi_backend.c -o build/temp.linux-x86_64-2.7/c/_cffi_backend.o\n  c/_cffi_backend.c:15:17: fatal error: ffi.h: No such file or directory\n   #include <ffi.h>\n                   ^\n  compilation terminated.\n  error: command 'x86_64-linux-gnu-gcc' failed with exit status 1\n  \n  ----------------------------------------\n  Running setup.py clean for cffi\nFailed to build cryptography cffi\nInstalling collected packages: cffi, cryptography, paramiko, fabric, hiredis, Pillow, cssselect, premailer, psycopg2, logilab-common, logilab-astng, pylint, python-memcached, requests, sqlalchemy, oauthlib, requests-oauthlib, tweepy, ua-parser\n  Running setup.py install for cffi: started\n    Running setup.py install for cffi: finished with status 'error'\n    Complete output from command /usr/bin/python -u -c \"import setuptools, tokenize;__file__='/tmp/pip-build-037dd7/cffi/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\\r\\n', '\\n'), __file__, 'exec'))\" install --record /tmp/pip-sHYgnC-record/install-record.txt --single-version-externally-managed --compile:\n    running install\n    running build\n    running build_py\n    creating build\n    creating build/lib.linux-x86_64-2.7\n    creating build/lib.linux-x86_64-2.7/cffi\n    copying cffi/backend_ctypes.py -> build/lib.linux-x86_64-2.7/cffi\n    copying cffi/commontypes.py -> build/lib.linux-x86_64-2.7/cffi\n    copying cffi/setuptools_ext.py -> build/lib.linux-x86_64-2.7/cffi\n    copying cffi/api.py -> build/lib.linux-x86_64-2.7/cffi\n    copying cffi/__init__.py -> build/lib.linux-x86_64-2.7/cffi\n    copying cffi/model.py -> build/lib.linux-x86_64-2.7/cffi\n    copying cffi/verifier.py -> build/lib.linux-x86_64-2.7/cffi\n    copying cffi/cffi_opcode.py -> build/lib.linux-x86_64-2.7/cffi\n    copying cffi/ffiplatform.py -> build/lib.linux-x86_64-2.7/cffi\n    copying cffi/cparser.py -> build/lib.linux-x86_64-2.7/cffi\n    copying cffi/vengine_gen.py -> build/lib.linux-x86_64-2.7/cffi\n    copying cffi/recompiler.py -> build/lib.linux-x86_64-2.7/cffi\n    copying cffi/vengine_cpy.py -> build/lib.linux-x86_64-2.7/cffi\n    copying cffi/lock.py -> build/lib.linux-x86_64-2.7/cffi\n    copying cffi/_cffi_include.h -> build/lib.linux-x86_64-2.7/cffi\n    copying cffi/parse_c_type.h -> build/lib.linux-x86_64-2.7/cffi\n    copying cffi/_embedding.h -> build/lib.linux-x86_64-2.7/cffi\n    running build_ext\n    building '_cffi_backend' extension\n    creating build/temp.linux-x86_64-2.7\n    creating build/temp.linux-x86_64-2.7/c\n    x86_64-linux-gnu-gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DUSE__THREAD -I/usr/include/ffi -I/usr/include/libffi -I/usr/include/python2.7 -c c/_cffi_backend.c -o build/temp.linux-x86_64-2.7/c/_cffi_backend.o\n    c/_cffi_backend.c:15:17: fatal error: ffi.h: No such file or directory\n     #include <ffi.h>\n                     ^\n    compilation terminated.\n    error: command 'x86_64-linux-gnu-gcc' failed with exit status 1\n    \n    ----------------------------------------\n\n:stderr:   Failed building wheel for cryptography\n  Failed cleaning build dir for cryptography\n  Failed building wheel for cffi\nCommand \"/usr/bin/python -u -c \"import setuptools, tokenize;__file__='/tmp/pip-build-037dd7/cffi/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\\r\\n', '\\n'), __file__, 'exec'))\" install --record /tmp/pip-sHYgnC-record/install-record.txt --single-version-externally-managed --compile\" failed with error code 1 in /tmp/pip-build-037dd7/cffi/\n"}
    
    NO MORE HOSTS LEFT *************************************************************
        to retry, use: --limit @ansible/vagrant.retry
    
    PLAY RECAP *********************************************************************
    default                    : ok=23   changed=0    unreachable=0    failed=1
    
    Ansible failed to complete successfully. Any error output should be
    visible above. Please fix these errors and try again.
    

    Anyone knows what's going on?

    opened by gigi-mohemian 4
  • install google app engine failed to find handler for .zip

    install google app engine failed to find handler for .zip

    During vagrant --up provision, I get this error:

    TASK [lk-google-app-engine : install google app-engine] ************************ fatal: [default]: FAILED! => {"changed": false, "failed": true, "msg": "Failed to find handler for "/home/vagrant/google_appengine_1.9.27.zip". Make sure the required command to extract the file is installed.", "stat": {"exists": false}}

    It seems like my system cannot unzip the file properly. How can I fix this? I'm on OSX 10.11.3.

    opened by junhohong 4
  • Images broken in Preview

    Images broken in Preview

    I configure my app in the App Website Builder and upload my screen shots, they appear nicely after the upload while I am still editing the app, but after I save or click preview, the images is broken. It points to: https://launchkit-io.imgix.net/devices/iPhone6White.png?w=750&h=1334&mark=http%3A%2F%2Flocalhost%3A9102%2F_ah%2Fimg%2FQoLYZQTcSPAYIgeiBJkwUQ%3D%3D&markh=970&markalign=center%2Cmiddle

    I am running everything in localhost. Icon and Logo images are fine though.

    More info: the images that appear broken is the animation created from the screenshots!

    opened by erickva 3
  • Custom Website Builder hosting questions

    Custom Website Builder hosting questions

    1. If I want to remove some of the applications from the dashboard, which file would I be changing? (And in general how can I figure out which file to edit -- its not as simple as look at the html filename) I'm looking in skit/LK/public/dashboard . For example, say I want to deactivate or remove the website builder.

    2. Could you provide any suggestions on how to put this on a hosting platform and what type of hosting platform would be required? Would a regular linux host work where I currently have a regular html as well as a wordpress site?

    3. The app requires you to create a user on your own instance. Is there a way to access the backend somewhere to manage/delete/edit users?

    4. Some of the links point back to the LK blog. How do we find the right files to edit these links? For example, editing a website: Website Settings In order for other people to see your website, you'll need to set up a custom domain name. Read instructions here. Once you set things up, please remember that it can take up to 24 hours for your domain to activate.

    opened by Herzogdb 3
  • Last Step (5) Failed - HANDLER [redis : restart redis]

    Last Step (5) Failed - HANDLER [redis : restart redis]

    I got all the way to the last step 5 and it looks like everything worked except this. It still worked.

    RUNNING HANDLER [redis : restart redis] **************************************** fatal: [default]: FAILED! => {"changed": false, "failed": true, "msg": "no service or tool found for: redis"} ...ignoring

    opened by Herzogdb 3
  • Bump pillow from 3.0.0 to 9.3.0

    Bump pillow from 3.0.0 to 9.3.0

    Bumps pillow from 3.0.0 to 9.3.0.

    Release notes

    Sourced from pillow's releases.

    9.3.0

    https://pillow.readthedocs.io/en/stable/releasenotes/9.3.0.html

    Changes

    ... (truncated)

    Changelog

    Sourced from pillow's changelog.

    9.3.0 (2022-10-29)

    • Limit SAMPLESPERPIXEL to avoid runtime DOS #6700 [wiredfool]

    • Initialize libtiff buffer when saving #6699 [radarhere]

    • Inline fname2char to fix memory leak #6329 [nulano]

    • Fix memory leaks related to text features #6330 [nulano]

    • Use double quotes for version check on old CPython on Windows #6695 [hugovk]

    • Remove backup implementation of Round for Windows platforms #6693 [cgohlke]

    • Fixed set_variation_by_name offset #6445 [radarhere]

    • Fix malloc in _imagingft.c:font_setvaraxes #6690 [cgohlke]

    • Release Python GIL when converting images using matrix operations #6418 [hmaarrfk]

    • Added ExifTags enums #6630 [radarhere]

    • Do not modify previous frame when calculating delta in PNG #6683 [radarhere]

    • Added support for reading BMP images with RLE4 compression #6674 [npjg, radarhere]

    • Decode JPEG compressed BLP1 data in original mode #6678 [radarhere]

    • Added GPS TIFF tag info #6661 [radarhere]

    • Added conversion between RGB/RGBA/RGBX and LAB #6647 [radarhere]

    • Do not attempt normalization if mode is already normal #6644 [radarhere]

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies python 
    opened by dependabot[bot] 0
  • Bump django from 1.7.3 to 2.2.24

    Bump django from 1.7.3 to 2.2.24

    Bumps django from 1.7.3 to 2.2.24.

    Commits
    • 2da029d [2.2.x] Bumped version for 2.2.24 release.
    • f27c38a [2.2.x] Fixed CVE-2021-33571 -- Prevented leading zeros in IPv4 addresses.
    • 053cc95 [2.2.x] Fixed CVE-2021-33203 -- Fixed potential path-traversal via admindocs'...
    • 6229d87 [2.2.x] Confirmed release date for Django 2.2.24.
    • f163ad5 [2.2.x] Added stub release notes and date for Django 2.2.24.
    • bed1755 [2.2.x] Changed IRC references to Libera.Chat.
    • 63f0d7a [2.2.x] Refs #32718 -- Fixed file_storage.test_generate_filename and model_fi...
    • 5fe4970 [2.2.x] Post-release version bump.
    • 61f814f [2.2.x] Bumped version for 2.2.23 release.
    • b8ecb06 [2.2.x] Fixed #32718 -- Relaxed file name validation in FileField.
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies python 
    opened by dependabot[bot] 0
  • Bump minimist from 1.1.0 to 1.2.5 in /skit

    Bump minimist from 1.1.0 to 1.2.5 in /skit

    Bumps minimist from 1.1.0 to 1.2.5.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies javascript 
    opened by dependabot[bot] 0
  • Docker Support

    Docker Support

    Nowadays Docker is a widely adopted technology. And also VirtualBox support is currently limited.

    This merge request provides the support for Docker via docker-compose.

    opened by victorkifer 0
  • MacOS Mojave 10.14 doesn't support VirtualBox 5.1 and lower

    MacOS Mojave 10.14 doesn't support VirtualBox 5.1 and lower

    Hey everybody,

    as you already might have noticed there is a new update for MacOS (10.14). This update only supports Virtual Box 5.2 and newer and so you can't use LaunchKit anymore.

    I'm not into this project so I would have a hard time to fix this issue. Maybe anybody here has an idea how to fix it.

    Best, papsti7

    opened by sutefan1 1
  • Connection resets when trying to go to http://localhost:9100/

    Connection resets when trying to go to http://localhost:9100/

    Was able to successfully run vagrant up --provision (after getting Python dependencies installed via #43).

    However, when trying to go to http://localhost:9100/ in the browser, the connection resets. LaunchKit can't be used.

    This also happens when I run a curl command (curl 'http://localhost:9100') -- here's the output:

    curl: (56) Recv failure: Connection reset by peer
    

    I'll also note, however, that http://localhost:9102/ correctly redirects to launchkit.io.

    Has anyone been able to get LaunchKit working with localhost, or has been able to create a workaround?

    opened by sunweiyang 1
Owner
LaunchKit
LaunchKit
Appfiguratesdk - Appfigurate provides the ability to change configuration properties in iOS and watchOS, apps and app extensions, securely, at runtime.

Appfigurate™ Appfigurate provides the ability to change configuration properties in iOS and watchOS, apps and app extensions, securely, at runtime. Do

Electric Bolt 21 Dec 14, 2022
ScreenshotFramer - Create localized App Store screenshots

ScreenshotFramer With Screenshot Framer you can easily create nice-looking and localized App Store Images. How does it work? It's super simple: Screen

IdeasOnCanvas GmbH 699 Dec 16, 2022
Set of easy to use debugging tools for iOS developers & QA engineers.

DBDebugToolkit DBDebugToolkit is a debugging library written in Objective-C. It is meant to provide as many easily accessible tools as possible while

Dariusz Bukowski 1.2k Dec 30, 2022
This app has always been open source! It began with the Big Brain Hackathon and now during Hacktoberfest

Brain Marks This app has always been open source! It began with the Big Brain Hackathon and now during Hacktoberfest. It is available for free on the

Mikaela Caron 79 Jan 4, 2023
Switchboard - easy and super light weight A/B testing for your mobile iPhone or android app. This mobile A/B testing framework allows you with minimal servers to run large amounts of mobile users.

Switchboard - easy A/B testing for your mobile app What it does Switchboard is a simple way to remote control your mobile application even after you'v

Keepsafe 287 Nov 19, 2022
In-app console and debug tools for iOS developers.

LocalConsole Welcome to LocalConsole! This Swift Package makes on-device debugging easy with a convenient PiP-style console that can display items in

Duraid Abdul 650 Jan 4, 2023
In-app console and debug tools for iOS developers

LocalConsole Welcome to LocalConsole! This Swift Package makes on-device debugging easy with a convenient PiP-style console that can display items in

Duraid Abdul 650 Jan 1, 2023
adb-tools-mac is a macOS menu bar app written in SwiftUI for common adb tools.

adb-tools-mac is a macOS menu bar app written in SwiftUI for common adb tools.

Naman Dwivedi 930 Jan 2, 2023
Swiftline is a set of tools to help you create command line applications

Swiftline is a set of tools to help you create command line applications. Swiftline is inspired by highline Swiftline contains the following: Colorize

Omar Abdelhafith 1.2k Dec 29, 2022
A set of tools to trim, crop and select frames inside a video

PryntTrimmerView A set of tools written in swift to crop and trim videos. Example To run the example project, clone the repo, and run pod install from

Henry Huck 742 Jan 5, 2023
A Set of Tools To Extend UIKit (Classic iOS Framework)

RVS_UIKit_Toolbox A set of basic UIKit tools, for Swift iOS app development. Overview This package offers a few extensions of standard UIKit classes,

The Great Rift Valley Software Company 2 Jul 8, 2022
An open-source, privacy-enhancing web browser for iOS, utilizing the Tor anonymity network

Onion Browser Official Site | Support | Release History | Donate © 2012-2020, Tigas Ventures, LLC (Mike Tigas) This is the Onion Browser 2.X branch, b

Onion Browser 2k Dec 30, 2022
The one and only open source 4X MMO mid-core strategy game for iOS. Similar to Game of War and Mobile Strike

4X MMO Strategy Game for iOS I have spent 4 years of my life and a significant amount of money into completing this game and I hope you enjoy it. For

shankqr 69 Nov 16, 2022
Chat SDK iOS - Open Source Mobile Messenger

Chat SDK Open Source Messaging framework for iOS Chat SDK is a fully featured open source instant messaging framework for iOS. Chat SDK is fully featu

Chat SDK 879 Jan 6, 2023
AlphaWallet - Advanced, Open Source Ethereum Mobile Wallet & dApp Browser for iOS

AlphaWallet - Advanced, Open Source Ethereum Mobile Wallet & dApp Browser for iOS

AlphaWallet 475 Jan 5, 2023
Server-side Swift. The Perfect core toolset and framework for Swift Developers. (For mobile back-end development, website and API development, and more…)

Perfect: Server-Side Swift 简体中文 Perfect: Server-Side Swift Perfect is a complete and powerful toolbox, framework, and application server for Linux, iO

PerfectlySoft Inc. 13.9k Dec 29, 2022
Server-side Swift. The Perfect core toolset and framework for Swift Developers. (For mobile back-end development, website and API development, and more…)

Perfect: Server-Side Swift 简体中文 Perfect: Server-Side Swift Perfect is a complete and powerful toolbox, framework, and application server for Linux, iO

PerfectlySoft Inc. 13.9k Jan 6, 2023
Server-side Swift. The Perfect core toolset and framework for Swift Developers. (For mobile back-end development, website and API development, and more…)

Perfect: Server-Side Swift 简体中文 Perfect: Server-Side Swift Perfect is a complete and powerful toolbox, framework, and application server for Linux, iO

PerfectlySoft Inc. 13.9k Dec 29, 2022
A beautiful set of predefined colors and a set of color methods to make your iOS/OSX development life easier.

Installation Drag the included Colours.h and Colours.m files into your project. They are located in the top-level directory. You can see a demo of how

Ben Gordon 3.1k Dec 28, 2022
Px-mobile-sdk-demo-app - PerimeterX Mobile SDK - Demo App

About PerimeterX PerimeterX is the leading provider of application security solu

PerimeterX 1 Nov 20, 2022