Code Monkey home page Code Monkey logo

comrad's Introduction

Comrad

Comrad is a socialist network: encrypted, insurveillable, unmontizeable, and self-governing. Meet fellow comrades and message them securely, organize safely into self-moderated groups, plan demonstrations secretly and spontaneously – and help fight back against the police state and surveillance capitalism, both online and off.

Why another social network?

Is a 'socialist network' possible? Although the internet began with anarchic design principles, it quickly consolidated into the hands of a few of the largest corporations in the world. It has effectively recreated the capitalist mode of production within itself: the means of content production (social media platforms) are privatized while the work of production (posting) remains socially distributed. Exploitation inheres in that relation, whether in the industrial factory or the digital platform, because the value you produce is taken from you, concentrated and privatized.

But a digital network can be redesigned. The technology behind these social media platforms is actually quite simple. We can easily build our own social network, one which is secure, insurveillable, and unmonetizable—one which would give people the security they need to communicate about whatever they want, including protesting against capital and the state.

Core principles

Confidential

All of your data are strongly encrypted end-to-end: only you and those you write to can decrypt and read it. To anyone without the right decryption 'key', the data is nonsense.

Untraceable

All network traffic is routed through Tor, a "deep web" of computers so dense even the FBI can't follow you through it. Comrad's "Operator" or central server is accessible only from Tor. It's impossible to tell who is sending what to whom, or even who is using the app at all.

Unmonetizable

What's untraceable is also unmonetizable: your data can't be harvested by technology companies and used for advertising algorithms. You're protected from both surveillance capitalism and the surveillance state.

Democratized

Group accounts or 'collectives', like @portland or @socialists, grow as existing members 'vouch for' new ones, forming webs of trust. In order to join a group, at least one member must vouch for you; this minimum (or 'quorum') may grow as the group grows, or in accordance with a 'constitution' which the group votes upon.

(Semi-)decentralized

Data is deleted as soon as possible from Comrad. Comrad's "Operator" simply sorts and holds the mail temporarily: as soon as users log in to download their mail, the messages are deleted from the server and network forever.

Open-source

Information wants to be communist.

Anti-profit

Not just non-profit, we're anti-profit.

Social media features

We present a simplified set of social media features drawn from everything that's out there:

Profile

  • Curate a profile with photo and posts (~Twitter)
  • Show profile to world (~Twitter)
  • Show profile only to those you trust (~Facebook)

Posting

  • Post up to 1 image and/or 1000 characters
  • Post to the entire world (~Twitter) ✔
  • Post to those you trust (~Facebook)
  • Post to self-moderating groups (~Facebook)
  • Anonymously up-vote or down-vote posts (~Reddit)
  • Post with encrypted data over untraceable connection (~new?) ✔

Organizing

  • Host events and invite others (~Facebook)
  • Host events like protests anonymously (~new?)
  • Anonymously pin on a map sites of danger, like police (~Waze)

Messaging

  • Message securely with encrypted contents (~Signal) ✔
  • Message over untraceable connection (~Briar/new?) ✔

How is this different from ...?

See "Comparison of alternative social networks" on the wiki for an attempt at a systematic comparison. (And please help edit, if you can! The data there is a little incomplete and probably a little inaccurate.) But here are some imagined differences:

  • It's not (fully) decentralized. Who's afraid of a little central planning? In contrast to Secure Scuttlebutt and Cabal Chat, which are 100% decentralized, subsisting only through peer-to-peer connections, Comrad sticks with the old, client/server model. Why?

  • It is anonymous. Because P2P networks almost always expose your IP address: they privilege decentralization over anonymity -- and, potentially, safety. By contrast, lying hidden within the deep web of Tor, accessible only from this application and its built-in Tor client, Comrad will never reveal who is accessing it and its encrypted information. This is important for comrades organizing protests against the surveillance state, and to protect our social media traffic from being harvested and monetized by surveillance capitalism.

  • It's 100% end-to-end encrypted. Unlike Mastodon or Diaspora, direct messages between users and within groups remain encrypted 1:1 end-to-end among users. Posts to the public are encrypted to @Comrades, a special account which automatically re-encrypts its messages back to any key-registered requester of them.

  • It verifies identities. Comrad's server, "The Operator", keeps a permanent record of one thing only: every comrad's name and public key, and requires that new comrades choose a unique name. Whenever you send or receive mail, the Operator will make sure that the name and public key on the letter matches what it has on file, verifying the identity of both parties.

  • It's (semi-)ephemeral. Data, like all natural things, should not last forever. Direct messages auto-delete from the server as soon as they are downloaded. Group messages are sent as direct messages through the "web of trust" of the group membership network. Posts to the world auto-delete in however many days you specify. By contrast, data on both SSB and Matrix is undeletable.

  • It's easy to use. No invitation or server is needed on startup, unlike SSB, Mastodon, Diaspora, or Briar. It's basically a Twitter clone, but one where you can also post to a universal feed shared by the entire world (@Comrades), so that you can make yourself known, participate in general discussions, find new contacts, and organize new groups.

Progress

Animations from mobile/desktop app

Registering and connecting through Tor

GIF animation

Navigating posts

GIF animation

Animations from terminal app

Connecting through Tor

GIF animation of Tor connection

"Meeting" (exchanging public keys)

GIF animation of meeting process

Messaging

GIF animation of messaging

Posting

GIF animation of posting

Usage

Install

...on Mac OSX

Download and run this installer.

...on Linux

Open a terminal in Linux, and copy and paste the following line into it:

bash <(curl -s https://comrad.app/run)

That's a shortcut to this auto-installer script. It installs Comrad in a virtual Python environment in the folder "comrad" in your home directory.

...on Windows

Unfortunately, Windows is not yet supported. We tried and tried, but cannot get everything to install correctly on either Mingw64 or Cygwin; and we also haven't yet been able to package a complete binary release with pyinstaller. If you are a developer, please lend a hand to support Windows. The current attempt at a windows installation is located here.

Run

...on Mac OSX

Install as above.

Run "Comrad.app" in your Applications folder.

...on Linux

Open a terminal in Linux, and type:

comrad-app

If that doesn't work, try:

~/comrad/code/bin/comrad-app

Running terminal client

For the terminal client (which may be broken at the moment), run:

comrad-cli   # or: ~/comrad/code/bin/comrad-cli

Running server (development only)

To run The Operator server (for development purposes only), run:

comrad-op   # or: ~/comrad/code/bin/comrad-op

Details

Frontend

Mobile/desktop

The mobile/desktop app is made with KivyMD, a variant of Kivy, a cross-platform app development framework in Python. Python is an easy and versatile progamming language to learn, which keeps the code accessible to as many people as possible. Code for the app is in comrad/app.

Terminal app

Vanilla Python. Code is in comrad/cli.

Backend

API

Plain old object-oriented code in Python. The root entity is a "Keymaker": anyone from @Telephone, to @Operator, to users, to groups, who has a public/private key pair. The database uses a simple file-based key-value store using the Redis protocol: rlite, via its rlite-py Python bindings. All code for backend/API is in comrad/backend.

Cryptography

We are using Themis, a high-level cross-platform cryptography library, for all cryptographic functions, rather than handling any primitives ourselves. Installing it from packages is tricky, so right now the auto-installer builds it from sources.

Crypto-related code is primarily in:

comrad's People

Contributors

marxzuckerburg avatar mcataford avatar quadrismegistus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

comrad's Issues

Conceptual Issue: Cryptocurrency? "Wages for Facebook"?

"And also, will this have a cryptocurrency? I don't really see the reason, unless it is some reward for hosting nodes (like LokiNet does) or it is needed for some PoW stuff, but anyways if it will, I would recommend forking ARRR since IMO it is the most promising anonymous crypto out there." -LJS

"This is really interesting. Touches on ideas like 'Wages For Facebook', built on that older Silvia Federici feminist argument of 'Wages For Housework'. It would be interested if posting -- contributing content, which benefits everyone, and which is a form of labor -- could somehow produce 'value' to the network that is then shared back with users, not necessarily according to who posted most but in dialogue with that. The currency ('points'? 'kudos'?) would of course be fake (custom made, costing nothing in real money), at least at first -- but if people donate to the entire network then maybe some cryptocurrency credits are partitioned out to people? Would love to keep thinking about that." -MZ

Any other thoughts on this, on the role of cryptocurrency in an alternative social(ist) network?

Conceptual Issue: How to have a public feed, @komrades, which is safe, encrypted, and not overrun with BS?

MZ, Sep 16: "Is writing to the entire world -- all @komrades, i.e. everyone who is using the app -- different from writing to a group? Is the social media 'public' just one big group chat? there's technical but also social implications to the question i think.

e.g. there's the technical challenge of how to combine end-to-end encryption (which is really about 1:1 communication between people who know each other) with group chats or feeds. There's a few workarounds to the problem, but the problem is always there, it seems. And that problem may be there even more if maybe especially if modeling something as big as the world. At that scale, is encryption even worth it anymore?

One idea would be to decentralize 'world' communication, and kind of combine the friend model with the follower model: all world-bound posts are sent end-to-end encrypted between any two people who have each other as contacts (each other's public keys). Posts intended for the world just never stop traveling through the contact networks until they've reached everyone. This is similar to how we're currently imagining group communication through a web of trust, except (a) posts intended for a specific group travel through network of X-vouched-for-Y, not X-is-a-contact-of-Y; and (b) posts to groups stop traveling once theyve reached eveeryone in the group, not everyone in the world.

There's still a lot to work out in how that 'traveling' would work out. But I like the idea of making something work for its 'virality'. Data isn't just stored unencrypted, accessible to anyone, in some giant database. Instead, a post is literally moving around between people who 'know' each other in some way. Copies of it would be everywhere, but none of them the same, because each is encrypted and locked away in a private language only 2 people can understand. Although the actual unencrypted post never exists as such in the data, a single post could still go 'viral' by moving around quickly, decrypting and reencrypting itself through the whole network."

Conceptual Issue: How to protect privacy and anonymity, but also not give shelter to nazis?

"How could we prevent nazis from occupying the platform? They tend to love resilient platforms where they can't be shutdown." - LJS

"One question I have is how to keep the network from being 'flooded' by agitators (white supremacists, QAnon, etc.). Will there be any moderation at all for messages?" -BM

These are good questions and ones I'm not sure we have an answer to.

We can imagine group moderation mechanisms (some of which discussed here), like flagging posts or accounts as offensive and holding group-wide votes or using some other self-governing mechanism.

In terms of who is posting to @komrades, the public channel, that's another and perhaps trickier question. Is there an app-wide moderation or voting mechanism?

More broadly, though, all the encryption design of the app prevents us from knowing what anyone is saying to anyone else; no record of the messages, or who wrote whom, is stored. There may be some inevitable sacrifice in this. At least, this is what the hardcore privacy folks at r/privacy think, in reply to a question about this. Personally I don't think there's a one-size-fits-all philosophical or technical solution to the question, which is why I think self-governance mechanisms may be the only way to remain flexible enough to threats and attacks. Is that an inner liberal in me? I'm not sure...

Conceptual Issue: How to have group chats/channels/feeds (like @portland) which are safe, encrypted, self-governing?

I've been thinking more about a 'web of trust' concept. Say I start a group account, @portland. I mark it as a group instead of an individual account, but this doesn't have much of an effect at first (I still choose a password, etc). But if I (@elon) want to invite @zuck to join @portland, I can 'vouch for' them. I simply write to my local hard drive that I vouch for @zuck and agree to forward all messages to @portland (which I the founder have access to) along to @zuck (and encrypt it me->him along the way). So, rather than ever ever transmit @portland's private ID, everything remains end-to-end encrypted between individuals, and no private IDs need to be sent over a network.

Rather than ever be stored in a centralized placed, then, group messages and data can simply trickle through the web of trust, encrypting themselves end-to-end each time between between different people in the network. This trust graph doesn't need to be 1:1 either. It's a directed graph, X --(vouches for) --> Y. But A, B, and C could also vouch for Y. In that case, any message Y sends to group G is actually sent to inboxes for X, A, B, and C.

But now say @zuck, vouched for by @elon, wants to invite @donald to join @portland, too. Instead of @zuck being able to do that immediately, @zuck could send a(n automatically composed?) message to the person who vouched for him (@elon), asking whether it's ok if he starts to pass on the mail to @portland (which @elon has been forwarding to him) along to @donald. If @elon agrees, @zuck writes to his hard drive his commitment to forward @portland's mail to @donald; and does that whenever @zuck logs in and receives mail to @portland from @elon. If @elon disagrees, then the app will prevent @zuck from writing to his hard drive that agreement; if @elon now suspects @zuck's judgment, @elon can withdraw his vouching for @zuck, and no longer forward mail to @portland along to @zuck in the first place.

Of course, you can't just engineer trust. After @zuck is vouched for by @elon to join @portland, there's nothing to stop him from just copy/pasting @portland's messages to @donald personally. I suppose in the end trust is just a social relation between humans.

Conceptual Issue: Liking? Up/downvoting? "Retweeting"?

Which you can best imagine for the platform?

I think there are a few axes to consider:

  1. Anonymity

    • Likes are generally non-anonymous (you can see who liked your post); up/down votes are generally anonymous.
    • There are some safety concerns here.
      • If non-anonymous, then if I continue to like the posts of my friends, it could become obvious to an external observer what my individual social network looks like, and therefore maybe even who I am -- even though I might not have chosen to associate or link my account on Comrad in any way to my other IRL or online identities.
      • If anonymous, these social networks might be obscured, but at the cost of a key feature of (a lot of) social networks: giving little cookies of affection and approval to people you follow.
  2. Liking vs. voting

    • Does this question really just turn on whether downvoting is incorporated? Is "like" just a non-anonymous upvote?
    • Downvoting?
      • Do we want this negativity?
      • Would it actually be useful for moderation purposes?
      • What are downsides or possibilities for abuse?
  3. Reposting?

    • Amplifying a post in some sense or other -- amplifying a post you like -- seems crucial.
      • That kind of amplification could be just a like or upvote (indirect effect).
      • Or it could be a more direct reblogging (retweeting, etc) of the content, in which you kind of claim or identify with it to the extent that you want to repeat it or echo it itself.
    • Reposting might also reveal individuals' social networks in problematic ways.

Thoughts? Anything else to consider?

AttributeError: 'MainApp' object has no attribute 'async_run'

I get this error when I try to run it with ./run.sh

I'm using arch linux and Python 3.8.5

Here is the entire error
User@Host ~/git/Komrade/app (git)-[master] % ./run.sh
[INFO ] [Logger ] Record log in /home/lr/.kivy/logs/kivy_20-08-29_3.txt
[INFO ] [Kivy ] v1.11.1
[INFO ] [Kivy ] Installed at "/usr/lib/python3.8/site-packages/kivy/__init__.py"
[INFO ] [Python ] v3.8.5 (default, Jul 27 2020, 08:42:51)
[GCC 10.1.0]
[INFO ] [Python ] Interpreter at "/usr/bin/python3"
[INFO ] [Factory ] 184 symbols loaded
[INFO ] [Image ] Providers: img_tex, img_dds, img_sdl2, img_pil, img_gif (img_ffpyplayer ignored)
[INFO ] [KivyMD ] v0.104.1
[INFO ] [Window ] Provider: sdl2(['window_egl_rpi'] ignored)
[INFO ] [GL ] Using the "OpenGL" graphics system
[INFO ] [GL ] Backend used <sdl2>
[INFO ] [GL ] OpenGL version <b'4.6 (Compatibility Profile) Mesa 20.1.6'>
[INFO ] [GL ] OpenGL vendor <b'Intel'>
[INFO ] [GL ] OpenGL renderer <b'Mesa Intel(R) UHD Graphics 620 (WHL GT2)'>
[INFO ] [GL ] OpenGL parsed version: 4, 6
[INFO ] [GL ] Shading version <b'4.60'>
[INFO ] [GL ] Texture max size <16384>
[INFO ] [GL ] Texture max units <32>
[INFO ] [Window ] auto add sdl2 input provider
[INFO ] [Window ] virtual keyboard not allowed, single mode, not docked
[INFO ] [Text ] Provider: sdl2(['text_pango'] ignored)
[INFO ] [GL ] NPOT texture support is availablelr
[2020-08-29 19:09:57,292]
connecting...
`[2020-08-29 19:09:57,294]` `starting server..`
[2020-08-29 19:09:57,294]
/home/lr/git/Komrade/app
`[2020-08-29 19:09:57,294]` `listening..`
[2020-08-29 19:09:57,294]
Node 420120771578343431675849077283393424863809941347 listening on 0.0.0.0:5639
`[2020-08-29 19:09:57,294]` `Refreshing routing table`
[2020-08-29 19:09:57,295]
bootstrapping server..
``
[2020-08-29 19:09:57,295]
` Attempting to bootstrap node with %i initial contacts 2`
`
` Traceback (most recent call last):`
` File "main.py", line 478, in `
` loop.run_until_complete(MainApp().app_func())`
` File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete`
` return future.result()`
` File "main.py", line 441, in run_wrapper`
` await self.async_run() #async_lib='asyncio')`
` AttributeError: 'MainApp' object has no attribute 'async_run'`

Sorry for the weird formation

Material Issue: Funding for programmer (not me) to continue work on this?

How could we raise money to hire a programmer, ideally an out-of-work/poc/queer/otherwise-marginalized programmer, to continue work on the app?

How do we raise money? Kickstarter? Some kind of cryptocurrency donation bin? I don't know the first thing about it. But starting October I need to take a step back from programming this and would like to think about how to start funding it long term.

I guess I can imagine two paths:

  1. We raise money to pay someone a stipend, like $1k or $2k, to do as much as they can with the app in the time they have to give it. Upside is that it's sensible and respectful and non-exploitative. Downside is, who picks the person? How do we find this person? etc.

  2. We grit our teeth and give in to the gig economy, and try one of these "bug bounty" platforms, where we can raise money as "bounties" for specific features and bugs and things we need done. Downside to this is it's kind of dystopic and deprives programmer of more creative input. Upside is it's probably easier to setup.

Thoughts?

[BUG] - ERROR: Could not find a version that satisfies the requirement as==0.1 (from versions: none)

`distlib-0.3.3 | 368 KB | ######################################################################################################################################################################## | 100%
libblas-3.9.0 | 12 KB | ######################################################################################################################################################################## | 100%
Preparing transaction: done
Verifying transaction: done
Executing transaction: | b''
done

To activate this environment, use

$ conda activate /home/marcos/comrad/code/venv

To deactivate an active environment, use

$ conda deactivate

Now using python (t2): /home/marcos/comrad/code/venv/bin/python
Requirement already satisfied: setuptools in ./code/venv/lib/python3.7/site-packages (58.0.4)
Collecting setuptools
Downloading setuptools-58.1.0-py3-none-any.whl (816 kB)
|████████████████████████████████| 816 kB 5.9 MB/s
Installing collected packages: setuptools
Attempting uninstall: setuptools
Found existing installation: setuptools 58.0.4
Uninstalling setuptools-58.0.4:
Successfully uninstalled setuptools-58.0.4
Successfully installed setuptools-58.1.0

Install python requirements

Collecting art==4.7
Downloading art-4.7-py2.py3-none-any.whl (547 kB)
|████████████████████████████████| 547 kB 5.2 MB/s
ERROR: Could not find a version that satisfies the requirement as==0.1 (from versions: none)
ERROR: No matching distribution found for as==0.1

Installing Themis, cryptography backend...

Checking for prerequisite libssl-dev: install ok installed
Building Themis...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 12.5M 0 12.5M 0 0 3184k 0 --:--:-- 0:00:04 --:--:-- 3185k
configuration written to build/configure.mk
compile build/obj/src/themis/secure_session_peer.c.o [OK]
compile build/obj/src/themis/secure_session_utils.c.o [OK]
compile build/obj/src/themis/secure_message.c.o [OK]
`

Conceptual Issue: Multiple accounts?

Will we allow users to have multiple accounts?

The only way to limit this would be to disallow multiple accounts from being stored on one device (by having app check if its hardware-only redis-like database already has a record for a user) -- since we don't want to store IPs or sessions or cookies: actually we can't, since users are coming to us via a different IP address each time via Tor.

Here are some pros and cons I can see.

Pros

  • It would allow people to make accounts with varying levels of anonymity.

    • If I want to create an account which links to my twitter, maybe I also want to create an account which doesn't?
  • Multiple accounts could share QRcodes of other accounts (their public keys) by simply having them stored on the same device. That allows your alter ego to message the people your normal ego can message. Maybe that's good and bad?

  • It would allow for bots.

Cons

  • The web of trust gets complicated: if multiple accounts share contacts, and if someone contacts you claiming to be the alter-ego of your friend, how do you know that's true? Your friend could also 'sign' the message, so that you could verify he had something to do with it. But then does that betray the point of anonymity in the first place?

  • It would allow for bots.

move from http to sockets?

This might be too hard for now and interfere with the tor proxy. Also not sure we need realtime communication with server. Can set in kivy event loop to check notifications every 60s or whatever.

Plan for moving to latourian framework (lol)

Plan for moving to combine uses and groups

Let's get a little Latourian. Everything is an @.

No need for channels, groups, users. Every entity has a private/public key. Why not call a 'user' or 'account' such entities?

Then you could write to earth as @earth, to @california, to @uk, etc.

Founders, elders, and eventual democratic vote structures could be built in for who shares the private key.

Re-add image support: avatars and images attached to posts

  • Avatars: can be directly exchanged between users (as e2ee) along with their public keys, when they go through "meeting" process?

    • This would mean, however, that users posting to all @komrades would, to readers who haven't met that user, show up without their avatar. How to resolve this?
  • Post images: binary data can be attached to encrypted post data. (Will file size create a problem here?)

Conceptual Issue: Bots?

As is, it's extremely easy to make a bot. Part of it is owing to the fact that currently you can easily create multiple accounts. Also because the API is directly accessible:

1) Initialize

source ~/comrad/code/bin/comrad-activate
cd ~/comrad/code
export COMRAD_SHOW_LOG=0    # (optional) to hide log output from screen
python

2) Use with python

# boot
from comrad import *
bot = Comrad('marxbot99')

# register
bot.register()

# post
bot.post('Hello world')

# msg
bot2 = Comrad('zuckbot66')
bot.msg(bot2, 'hello fellow bot')

# refresh data
bot.refresh()

# read posts
for post in bot.posts():
    # print nicely formatted    
    print(post)

    # print data dictionary
    print(post.msg_d)

# read DMs
for message in bot.messages():
    # print nicely formatted    
    print(message)

    # print data dictionary
    print(message.msg_d)

Do we want to disallow this way of interacting with the API? (I'm not sure we actually could, in any watertight way at least.) I kind of like the idea of leaving it open for people to play with. And then, some bots are good citizens and could be good comrads.

But there are of course dangers to bots. They can be used to abuse or attack people or groups. We don't want people raising bot armies here...

What do you guys think?

Add flatpak support

Opening this issue until the project gets a little more mature and also until we figure out how to create one.

AttributeError: 'MainApp' object has no attribute 'register'

I got the previous error solved but got a new one right after I entered the username, here's the entire error:

 Traceback (most recent call last):
   File "main.py", line 455, in <module>
     loop.run_until_complete(MainApp().app_func())
   File "/usr/local/lib/python3.7/asyncio/base_events.py", line 587, in run_until_complete
     return future.result()
   File "main.py", line 418, in run_wrapper
     await self.async_run() #async_lib='asyncio')
   File "/home/lr/git/Komrade/Komrade.venv/lib/python3.7/site-packages/kivy/app.py", line 962, in async_run
     await async_runTouchApp(async_lib=async_lib)
   File "/home/lr/git/Komrade/Komrade.venv/lib/python3.7/site-packages/kivy/base.py", line 595, in async_runTouchApp
     await EventLoop.async_mainloop()
   File "/home/lr/git/Komrade/Komrade.venv/lib/python3.7/site-packages/kivy/base.py", line 362, in async_mainloop
     await self.async_idle()
   File "/home/lr/git/Komrade/Komrade.venv/lib/python3.7/site-packages/kivy/base.py", line 424, in async_idle
     self.dispatch_input()
   File "/home/lr/git/Komrade/Komrade.venv/lib/python3.7/site-packages/kivy/base.py", line 342, in dispatch_input
     post_dispatch_input(*pop(0))
   File "/home/lr/git/Komrade/Komrade.venv/lib/python3.7/site-packages/kivy/base.py", line 308, in post_dispatch_input
     wid.dispatch('on_touch_up', me)
   File "kivy/_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
   File "/home/lr/git/Komrade/Komrade.venv/lib/python3.7/site-packages/kivymd/uix/behaviors/ripplebehavior.py", line 245, in on_touch_up
     return super().on_touch_up(touch)
   File "/home/lr/git/Komrade/Komrade.venv/lib/python3.7/site-packages/kivymd/uix/button.py", line 969, in on_touch_up
     return super().on_touch_up(touch)
   File "/home/lr/git/Komrade/Komrade.venv/lib/python3.7/site-packages/kivy/uix/behaviors/button.py", line 179, in on_touch_up
     self.dispatch('on_release')
   File "kivy/_event.pyx", line 705, in kivy._event.EventDispatcher.dispatch
   File "kivy/_event.pyx", line 1248, in kivy._event.EventObservers.dispatch
   File "kivy/_event.pyx", line 1132, in kivy._event.EventObservers._dispatch
   File "/home/lr/git/Komrade/Komrade.venv/lib/python3.7/site-packages/kivy/lang/builder.py", line 57, in custom_callback
     exec(__kvlang__.co_value, idmap)
   File "/home/lr/git/Komrade/app/screens/login/login.kv", line 123, in <module>
     on_release: self.register()
   File "/home/lr/git/Komrade/app/screens/login/login.py", line 21, in register
     app.register(un)
 AttributeError: 'MainApp' object has no attribute 'register'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.