├── __init__.py ├── tc ├── __init__.py ├── admin.py ├── basenencode.py ├── tests.py ├── urls.py ├── models.py └── views.py ├── .gitignore ├── static ├── favicon.png ├── tinycmd.png ├── tinycmd.xcf └── background.jpg ├── templates ├── command_list.html ├── command_string.html ├── register.html ├── base.html └── index.html ├── manage.py ├── contrib └── sh_version │ └── t ├── urls.py ├── README.md ├── settings.py └── t /__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tc/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.pyo 3 | database 4 | -------------------------------------------------------------------------------- /static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aruseni/tinycmd/HEAD/static/favicon.png -------------------------------------------------------------------------------- /static/tinycmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aruseni/tinycmd/HEAD/static/tinycmd.png -------------------------------------------------------------------------------- /static/tinycmd.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aruseni/tinycmd/HEAD/static/tinycmd.xcf -------------------------------------------------------------------------------- /static/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aruseni/tinycmd/HEAD/static/background.jpg -------------------------------------------------------------------------------- /tc/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from tc.models import CommandString 3 | 4 | class CommandStringAdmin(admin.ModelAdmin): 5 | list_display = ("string_id", "datetime_added") 6 | list_filter = ("datetime_added",) 7 | search_fields = ["string_id", "command_string"] 8 | 9 | admin.site.register(CommandString, CommandStringAdmin) 10 | -------------------------------------------------------------------------------- /templates/command_list.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | {% for cmd in cmdlist %} 5 |
6 |

{{ cmd.datetime_added }}

7 |

ID: {{ cmd.string_id }}

8 |

{{ cmd.command_string }}

9 |
10 | {% endfor %} 11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /templates/command_string.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 |
5 |

{{ command_string.datetime_added }}

6 |

To run this command, type: t {{ command_string.string_id }}

7 |

{{ command_string.command_string }}

8 |
9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /templates/register.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 |
5 |

Create an account

6 |
7 | {% csrf_token %} 8 | 9 | {{ form.as_table }} 10 |
11 | 12 |
13 |
14 | {% endblock %} 15 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from django.core.management import execute_manager 3 | try: 4 | import settings # Assumed to be in the same directory. 5 | except ImportError: 6 | import sys 7 | sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) 8 | sys.exit(1) 9 | 10 | if __name__ == "__main__": 11 | execute_manager(settings) 12 | -------------------------------------------------------------------------------- /contrib/sh_version/t: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | [ ! -f /usr/bin/wget ] && { 4 | echo "wget not found. Please install wget first." 5 | exit 2 6 | } 7 | 8 | die() { 9 | echo "Usage: $0 [-s] code" >&2 10 | exit 1 11 | } 12 | 13 | show_cmd() { 14 | wget -q -O - http://tinycmd.alwaysdata.net/cs/$1/text/ 15 | } 16 | 17 | run_cmd() { 18 | CMD=`show_cmd $1` 19 | /bin/sh -c "$CMD" 20 | } 21 | 22 | [ $# -lt 1 -o $# -gt 2 ] && die 23 | [ $# -eq 2 -a "$1" != "-s" ] && die 24 | 25 | [ $# -eq 2 ] && { 26 | show_cmd $2 27 | echo 28 | } || { 29 | run_cmd $1 30 | } 31 | 32 | exit 0 33 | # vim: ts=4 et 34 | -------------------------------------------------------------------------------- /tc/basenencode.py: -------------------------------------------------------------------------------- 1 | def baseNencode(number, alphabet='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'): 2 | """Convert positive integer to a base N string.""" 3 | if not isinstance(number, (int, long)): 4 | raise TypeError('number must be an integer') 5 | 6 | # Special case for zero 7 | if number == 0: 8 | return '0' 9 | 10 | base36 = '' 11 | 12 | sign = '' 13 | if number < 0: 14 | sign = '-' 15 | number = - number 16 | 17 | while number != 0: 18 | number, i = divmod(number, len(alphabet)) 19 | base36 = alphabet[i] + base36 20 | 21 | return sign + base36 22 | -------------------------------------------------------------------------------- /urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls.defaults import * 2 | from django.conf import settings 3 | 4 | # Uncomment the next two lines to enable the admin: 5 | from django.contrib import admin 6 | admin.autodiscover() 7 | 8 | urlpatterns = patterns('', 9 | # Example: 10 | # (r'^tinycmd/', include('tinycmd.foo.urls')), 11 | 12 | # Uncomment the admin/doc line below to enable admin documentation: 13 | # (r'^admin/doc/', include('django.contrib.admindocs.urls')), 14 | 15 | # Uncomment the next line to enable the admin: 16 | (r'^admin/', include(admin.site.urls)), 17 | 18 | (r'^static/(?P.*)$', 'django.views.static.serve', 19 | {'document_root': settings.MEDIA_ROOT}), 20 | 21 | (r'^', include('tc.urls')), 22 | 23 | ) 24 | -------------------------------------------------------------------------------- /tc/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from django.conf import settings 3 | 4 | from tc.models import CommandString 5 | 6 | from tc.basenencode import baseNencode 7 | 8 | class TestCommandStringModel(TestCase): 9 | def setUp(self): 10 | self.cs = CommandString.objects.create() 11 | 12 | def test_string_id(self): 13 | """ 14 | Tests that the string_id is added to the object correctly. 15 | """ 16 | string_id = baseNencode(self.cs.id+settings.BASE_N_OFFSET, settings.BASE_N_ALPHABET) 17 | # Reload the object to get the string_id added by the save() method 18 | cs = CommandString.objects.get(id=self.cs.id) 19 | self.assertEqual(string_id, cs.string_id) 20 | 21 | def tearDown(self): 22 | self.cs.delete() 23 | -------------------------------------------------------------------------------- /tc/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls.defaults import * 2 | 3 | from django.views.generic.simple import redirect_to 4 | 5 | urlpatterns = patterns('tc.views', 6 | (r'^$', 'index'), 7 | (r'^post/$', 'add_command_string'), 8 | (r'^(?P[\w\d_]+)/cs/(?P\w+)/$', 9 | 'user_command_string_detail'), 10 | (r'^cs/(?P\w+)/$', 'command_string_detail'), 11 | (r'^(?P[\w\d_]+)/cs/(?P\w+)/text/$', 12 | 'user_command_string_text'), 13 | (r'^cs/(?P\w+)/text/$', 'command_string_text'), 14 | (r'^(?P[\w\d_]+)/cs/$', redirect_to, {'url': '/'}), 15 | (r'^cs/$', redirect_to, {'url': '/'}), 16 | (r'^accounts/login/$', 'login'), 17 | (r'^accounts/logout/$', 'logout'), 18 | (r'^accounts/register/$', 'register'), 19 | (r'^list/text/$', 'command_list_text'), 20 | (r'^list/$', 'command_list'), 21 | (r'^(?P[\w\d_]+)/list/text/$', 'user_command_list_text'), 22 | (r'^(?P[\w\d_]+)/list/$', 'user_command_list'), 23 | ) 24 | -------------------------------------------------------------------------------- /tc/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.conf import settings 3 | from django.contrib.auth.models import User 4 | from string import digits 5 | from basenencode import baseNencode 6 | 7 | # Create your models here. 8 | 9 | class CommandString(models.Model): 10 | command_string = models.TextField() 11 | datetime_added = models.DateTimeField(auto_now_add=True) 12 | user_added = models.ForeignKey(User, null=True, blank=True) 13 | votes = models.FloatField(default=0.0) 14 | # When the super() first saves the object, 15 | # it creates and gets an ID, but 16 | # it doesn't yet have a string_id 17 | # (so the field has blank set to True). 18 | # The object gets the string_id 19 | # after creation, as the save() 20 | # method next adds it. 21 | string_id = models.CharField(max_length=255, blank=True, editable=False) 22 | 23 | def save(self, only_num=False, *args, **kwargs): 24 | """ 25 | Check if a string_id is already set, and if it's not, 26 | convert the object id to a base N string and then 27 | update the string_id field with the returned value. 28 | 29 | As an ID is generated when a new command string is saved, 30 | it becomes possible to then change the ID generation scheme: 31 | for the new objects and still leave the old IDs working. 32 | """ 33 | super(CommandString, self).save(*args, **kwargs) # Call the "real" save() method. 34 | if not self.string_id: 35 | # TODO: Need new algorithm!!!!!!!!!!!!!!! 36 | string_id = baseNencode(self.id + settings.BASE_N_OFFSET, 37 | digits if only_num else settings.BASE_N_ALPHABET) 38 | CommandString.objects.filter(id=self.id).update(string_id=string_id) 39 | 40 | def __unicode__(self): 41 | return self.string_id 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Why use [tinycmd](http://tinycmd.alwaysdata.net/)? 2 | ============= 3 | 4 | Have you ever been in a situation where you wanted to **help a friend or relative** install or configure something on their computer over the phone or through Email, but they didn’t have a background in computers? 5 | 6 | If you have, then you know that in many cases, it is not easy to guide them through the graphical interface; as you have to imagine another person’s desktop, which can greatly vary on different computers. 7 | 8 | In these cases, it is much simpler to just ask the person to open up a terminal window and **type a command string**. However, will it be easy for the person without experience in computers to type what you say? 9 | 10 | If you use phone, it can be hard for them to find the **special characters** on the keyboard, and they can also put **whitespaces** in the wrong places of the command string. 11 | 12 | On the other hand, when using text, it might be necessary to first explain to them how the **clipboard** works. How they can copy the command string, and then find the command is not working correctly. (they can, for example, copy everything except the last character of the string). 13 | 14 | The solution is to use command string shortening — **tinycmd**. 15 | 16 | You can **simply save your command** right here. To run it (if tinycmd is installed on the computer), the person just needs to type this into the terminal and press return: 17 | 18 | t test 19 | 20 | Where `t` is the tinycmd command and `test` is an unique shortcut for the command. 21 | 22 | You can also use it for **presentations** and **master classes**, or if you need to use a piece of paper to write a manual for someone. 23 | 24 | Theoretical feature ideas 25 | ============= 26 | 27 | 1. Adding command strings from the command line, using the t command. 28 | 2. Viewing the command before execution, and canceling the execution 29 | in a short period of time (for example, 5 seconds before execution). 30 | 3. Commenting (maybe even with threads) the command strings on the website. 31 | -------------------------------------------------------------------------------- /templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | tinycmd — the command strings shortening service 6 | 7 | 121 | 122 | 123 |
tinycmd
124 |
125 | {% block content %} 126 | {% endblock %} 127 |
128 | 129 | 130 | -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 |
5 |

Why use tinycmd?

6 | 7 |

Have you ever been in a situation where you wanted to help a friend or relative install or configure something on their computer over the phone or through Email, but they didn’t have a background in computers?

8 | 9 |

If you have, then you know that in many cases, it is not easy to guide them through the graphical interface; as you have to imagine another person’s desktop, which can greatly vary on different computers.

10 | 11 |

In these cases, it is much simpler to just ask the person to open up a terminal window and type a command string. However, will it be easy for the person without experience in computers to type what you say?

12 | 13 |

If you use phone, it can be hard for them to find the special characters on the keyboard, and they can also put whitespaces in the wrong places of the command string.

14 | 15 |

On the other hand, when using text, it might be necessary to first explain to them how the clipboard works. How they can copy the command string, and then find the command is not working correctly. (they can, for example, copy everything except the last character of the string).

16 | 17 |

The solution is to use command string shortening — tinycmd.

18 | 19 |

You can simply save your command right here. To run it (if tinycmd is installed on the computer), the person just needs to type this into the terminal and press return:

20 | 21 |

t test

22 | 23 |

Where t is the tinycmd command and test is an unique shortcut for the command.

24 | 25 |

You can also use it for presentations and master classes, or if you need to use a piece of paper to write a manual for someone.

26 |
27 |
28 |

Installation

29 | 30 |

Before using tinycmd, install it to your computer.

31 | 32 |

(Installation is required only for running commands. Saving them on this site is available without installation).

33 | 34 |

The installation is as simple as:

35 | 36 |

wget http://tinycmd.alwaysdata.net/t && chmod 755 t && sudo mv t /usr/local/bin/

37 |
38 | 39 | 51 |
52 |

Write a command string below, then press the “Save” button to create a shortcut.

53 |
54 | {% csrf_token %} 55 |

56 | {% if user.is_authenticated %} 57 | 58 | {% endif %} 59 |

60 |

61 |

List

62 |
63 |
64 | {% endblock %} 65 | -------------------------------------------------------------------------------- /settings.py: -------------------------------------------------------------------------------- 1 | # Django settings for tinycmd project. 2 | 3 | import os 4 | 5 | DEBUG = True 6 | TEMPLATE_DEBUG = DEBUG 7 | 8 | PROJECT_ROOT = os.path.abspath(os.path.dirname(__name__)) 9 | 10 | # A set of characters used for converting object IDs 11 | # to the base N strings 12 | BASE_N_ALPHABET = '0123456789abcdefghjkmnopqrstuvwxyz' 13 | 14 | # An offset which is added to an object ID 15 | # before converting it to a base N string 16 | BASE_N_OFFSET = 1200 17 | 18 | ADMINS = ( 19 | # ('Your Name', 'your_email@domain.com'), 20 | ) 21 | 22 | MANAGERS = ADMINS 23 | 24 | DATABASES = { 25 | 'default': { 26 | 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. 27 | 'NAME': 'database', # Or path to database file if using sqlite3. 28 | 'USER': '', # Not used with sqlite3. 29 | 'PASSWORD': '', # Not used with sqlite3. 30 | 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. 31 | 'PORT': '', # Set to empty string for default. Not used with sqlite3. 32 | } 33 | } 34 | 35 | # Local time zone for this installation. Choices can be found here: 36 | # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name 37 | # although not all choices may be available on all operating systems. 38 | # On Unix systems, a value of None will cause Django to use the same 39 | # timezone as the operating system. 40 | # If running in a Windows environment this must be set to the same as your 41 | # system time zone. 42 | TIME_ZONE = 'Europe/Podgorica' 43 | 44 | # Language code for this installation. All choices can be found here: 45 | # http://www.i18nguy.com/unicode/language-identifiers.html 46 | LANGUAGE_CODE = 'en-us' 47 | 48 | SITE_ID = 1 49 | 50 | # If you set this to False, Django will make some optimizations so as not 51 | # to load the internationalization machinery. 52 | USE_I18N = True 53 | 54 | # If you set this to False, Django will not format dates, numbers and 55 | # calendars according to the current locale 56 | USE_L10N = True 57 | 58 | # Absolute filesystem path to the directory that will hold user-uploaded files. 59 | # Example: "/home/media/media.lawrence.com/" 60 | MEDIA_ROOT = os.path.join(PROJECT_ROOT, 'static') 61 | 62 | # URL that handles the media served from MEDIA_ROOT. Make sure to use a 63 | # trailing slash if there is a path component (optional in other cases). 64 | # Examples: "http://media.lawrence.com", "http://example.com/media/" 65 | MEDIA_URL = '' 66 | 67 | # URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a 68 | # trailing slash. 69 | # Examples: "http://foo.com/media/", "/media/". 70 | ADMIN_MEDIA_PREFIX = '/media/' 71 | 72 | # Make this unique, and don't share it with anybody. 73 | SECRET_KEY = 'nrnj1*cdu4^66&3us@_e&3vm#%%$t1@(_umf_fudkvve*zrd&o' 74 | 75 | # List of callables that know how to import templates from various sources. 76 | TEMPLATE_LOADERS = ( 77 | 'django.template.loaders.filesystem.Loader', 78 | 'django.template.loaders.app_directories.Loader', 79 | # 'django.template.loaders.eggs.Loader', 80 | ) 81 | 82 | MIDDLEWARE_CLASSES = ( 83 | 'django.middleware.common.CommonMiddleware', 84 | 'django.contrib.sessions.middleware.SessionMiddleware', 85 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 86 | 'django.contrib.messages.middleware.MessageMiddleware', 87 | 'django.middleware.csrf.CsrfViewMiddleware', 88 | 'django.middleware.csrf.CsrfResponseMiddleware', 89 | ) 90 | 91 | ROOT_URLCONF = 'tinycmd.urls' 92 | 93 | TEMPLATE_DIRS = ( 94 | # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". 95 | # Always use forward slashes, even on Windows. 96 | # Don't forget to use absolute paths, not relative paths. 97 | os.path.join(PROJECT_ROOT, 'templates'), 98 | ) 99 | 100 | INSTALLED_APPS = ( 101 | 'django.contrib.auth', 102 | 'django.contrib.contenttypes', 103 | 'django.contrib.sessions', 104 | 'django.contrib.sites', 105 | 'django.contrib.messages', 106 | 'tc', 107 | # Uncomment the next line to enable the admin: 108 | 'django.contrib.admin', 109 | # Uncomment the next line to enable admin documentation: 110 | # 'django.contrib.admindocs', 111 | ) 112 | -------------------------------------------------------------------------------- /t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from __future__ import print_function 3 | 4 | 5 | # Config: 6 | tinycmd_host = "tinycmd.alwaysdata.net" # The web server host 7 | tinycmd_user = "" # user on tinycmd_host 8 | 9 | import os, sys 10 | import socket 11 | import optparse 12 | from getpass import getpass 13 | if sys.version_info[0] == 2: import httplib 14 | elif sys.version_info[0] == 3: from http import client as httplib 15 | else: 16 | print("Wrong version of Python") 17 | sys.exit(1) 18 | 19 | 20 | __prog__ = "tinycmd" 21 | __version__ = "0.2" 22 | __website__ = "http://tinycmd.alwaysdata.net/" 23 | __description__ = "The command string shortening service" 24 | __usage__ = "%prog [options] [command_string_id_list]" 25 | 26 | 27 | if __name__ == "__main__": 28 | 29 | opt = optparse.OptionParser(description=__description__, usage=__usage__, 30 | version = __prog__ + " v" + __version__, 31 | epilog="") 32 | opt.add_option("-r", "--run", help="Run without questions", 33 | dest="noquestions", action="store_true", default=False) 34 | opt.add_option("-s", "--showonly", help="Only show command, don't run", 35 | dest="showonly", action="store_true", default=False) 36 | opt.add_option("-u", "--user", dest="user", default=tinycmd_user, 37 | type="string", help="Run sript for this user of tinycmd") 38 | opt.add_option("--host", "--server", dest="host", default=tinycmd_host, 39 | type="string", help="adress of tinycmd-server", 40 | metavar="SERVER") 41 | opt.add_option("-a", "--addcmd", dest="addcmd", metavar="COMMAND", 42 | help="Add this command to tinycmd-server", type="string") 43 | opt.add_option("-f", "--addfile", dest="addfile", metavar="FILE", 44 | help="Add this script to tinycmd-server", type="string") 45 | opt.add_option("-l", "--listcmd", dest="listcmd", default=False, 46 | action="store_true", help="List commands for current user") 47 | opt.add_option("-n", "--nocache", dest="nocache", default=False, 48 | action="store_true", help="Don't use cache") 49 | (options, args) = opt.parse_args() 50 | 51 | # add command to server 52 | if options.addcmd or options.addfile: 53 | if len(args) > 1: 54 | opt.exit(1, "Wrong count of arguments") 55 | user = options.user 56 | pswd = getpass("User: " + user + "\nPassword: ") if user else "" 57 | # ============================= 58 | # add-command-code will be here 59 | # ============================= 60 | exit(0) 61 | 62 | # list of command for user 63 | if options.listcmd: 64 | if not options.user: 65 | opt.exit(1, "List of command may be showed only for concrete user") 66 | user = "/" + options.user if options.user else "" 67 | try: 68 | conn = httplib.HTTPConnection(options.host) 69 | conn.request("GET", user + "/list/text/") 70 | except (httplib.HTTPResponse, socket.error) as ex: 71 | opt.exit(1, "Unable to connect to the server:" + str(ex)) 72 | r1 = conn.getresponse() 73 | if r1.status == 404: 74 | print("Command string not found.") 75 | elif r1.status == 500: 76 | print("The server gives the 500 error. Please try again later.") 77 | elif r1.status == 200: 78 | print(r1.read()) 79 | conn.close() 80 | exit(0) 81 | 82 | if len(args) == 0: 83 | print("Wrong count of arguments\n") 84 | print(opt.get_usage()) 85 | print(opt.get_description(),"\n") 86 | print(opt.format_option_help()) 87 | exit(1) 88 | 89 | user = "/" + options.user if options.user else "" 90 | try: conn = httplib.HTTPConnection(options.host) 91 | except (httplib.HTTPResponse, socket.error) as ex: 92 | opt.exit(1, "Unable to connect to the server:" + str(ex)) 93 | 94 | cachedir = os.path.join(os.path.expanduser("~"), ".tinycmd" + options.user + "/") 95 | for arg in args: 96 | data = None 97 | cachefn = os.path.join(cachedir, arg) 98 | if os.path.exists(cachefn) and not options.nocache: 99 | data = open(cachefn).read() 100 | else: 101 | try: conn.request("GET", user + "/cs/" + arg + "/text/") 102 | except (httplib.HTTPResponse, socket.error) as ex: 103 | opt.exit(1, "Unable to connect to the server:" + str(ex)) 104 | r1 = conn.getresponse() 105 | if r1.status == 404: 106 | print("Command string not found.") 107 | elif r1.status == 500: 108 | print("The server gives the 500 error. Please try again later.") 109 | elif r1.status == 200: 110 | data = r1.read() 111 | if not options.nocache: 112 | if not os.path.exists(cachedir): os.makedirs(cachedir) 113 | with open(cachefn, "w+") as cachefile: cachefile.write(data) 114 | if data: 115 | print("Command: ") 116 | print(data) 117 | if options.showonly: 118 | exit(0) 119 | else: 120 | allow_run = True 121 | if not options.noquestions: 122 | answer = raw_input("You are really want run this command [y|n]? Answer: ") 123 | allow_run = answer[0].lower() == 'y' if answer else False 124 | if allow_run: 125 | os.system(data) 126 | 127 | conn.close() 128 | -------------------------------------------------------------------------------- /tc/views.py: -------------------------------------------------------------------------------- 1 | # Create your views here. 2 | 3 | 4 | from django.contrib import auth 5 | from django.contrib.auth.forms import UserCreationForm 6 | from django.contrib.auth.models import User 7 | from tc.models import CommandString 8 | from django import forms 9 | from django.shortcuts import render_to_response, get_object_or_404 10 | from django.template import RequestContext 11 | from django.http import HttpResponse, HttpResponseRedirect 12 | from django.core.urlresolvers import reverse 13 | 14 | 15 | def login(request): 16 | username = request.POST['username'] 17 | password = request.POST['password'] 18 | user = auth.authenticate(username=username, password=password) 19 | if user and user.is_active: 20 | auth.login(request, user) 21 | return HttpResponseRedirect("/") 22 | else: 23 | return HttpResponseRedirect("/") 24 | 25 | def logout(request): 26 | auth.logout(request) 27 | return HttpResponseRedirect("/") 28 | 29 | def register(request): 30 | if request.method == 'POST': 31 | form = UserCreationForm(request.POST) 32 | if form.is_valid(): 33 | username = request.POST['username'] 34 | password = request.POST['password1'] 35 | new_user = form.save() 36 | user = auth.authenticate(username=username, password=password) 37 | if user and user.is_active: auth.login(request, user) 38 | return HttpResponseRedirect("/") 39 | else: form = UserCreationForm() 40 | return render_to_response("register.html", {'form': form,}) 41 | 42 | def index(request): 43 | return render_to_response('index.html', {}, 44 | context_instance=RequestContext(request)) 45 | 46 | def command_string_detail(request, command_string_id): 47 | command_string = get_object_or_404(CommandString, string_id=command_string_id, 48 | user_added=None) 49 | return render_to_response('command_string.html', {'command_string': command_string}, 50 | context_instance=RequestContext(request)) 51 | 52 | def user_command_string_detail(request, username, command_string_id): 53 | command_string = get_object_or_404(CommandString, string_id=command_string_id, 54 | user_added=User.objects.get(username=username)) 55 | return render_to_response('command_string.html', {'command_string': command_string}, 56 | context_instance=RequestContext(request)) 57 | 58 | def command_string_text(request, command_string_id): 59 | command_string = get_object_or_404(CommandString, string_id=command_string_id, 60 | user_added=None) 61 | return HttpResponse(command_string.command_string, mimetype="text/plain") 62 | 63 | def user_command_string_text(request, username, command_string_id): 64 | command_string = get_object_or_404(CommandString, string_id=command_string_id, 65 | user_added=User.objects.get(username=username)) 66 | return HttpResponse(command_string.command_string, mimetype="text/plain") 67 | 68 | def add_command_string(request): 69 | command_string_string = request.POST.get('command', '') 70 | only_num = request.POST.get('only_num') 71 | try: 72 | command_string = CommandString.objects.get(command_string=command_string_string, 73 | user_added=request.user if \ 74 | request.user.is_authenticated() else None) 75 | except CommandString.DoesNotExist: 76 | cmdid = request.POST.get('cmdid', '') 77 | try: 78 | command_string = CommandString.objects.get(string_id=cmdid, 79 | user_added=request.user \ 80 | if request.user.is_authenticated() else None) 81 | except CommandString.DoesNotExist: 82 | if not command_string_string: 83 | return HttpResponseRedirect(reverse('tc.views.index')) 84 | command_string = CommandString() 85 | command_string.command_string = command_string_string 86 | if request.user.is_authenticated(): 87 | command_string.user_added = request.user 88 | command_string.string_id = cmdid 89 | command_string.save(only_num=only_num) 90 | # Reload the object to get the string_id added by the save() method 91 | command_string = CommandString.objects.get(id=command_string.id) 92 | if request.user.is_authenticated(): 93 | return HttpResponseRedirect(reverse('tc.views.user_command_string_detail', 94 | args=(request.user.username, 95 | command_string.string_id,))) 96 | else: 97 | return HttpResponseRedirect(reverse('tc.views.command_string_detail', 98 | args=(command_string.string_id,))) 99 | 100 | 101 | def command_list(request): 102 | cmdlist = CommandString.objects.order_by('-datetime_added') 103 | return render_to_response('command_list.html', {'cmdlist': cmdlist}, 104 | context_instance=RequestContext(request)) 105 | 106 | def user_command_list(request, username): 107 | user = User.objects.get(username=username) 108 | cmdlist = CommandString.objects.filter(user_added=user).order_by('-datetime_added') 109 | return render_to_response('command_list.html', {'cmdlist': cmdlist}, 110 | context_instance=RequestContext(request)) 111 | 112 | def command_list_text(request): 113 | cmdlist = CommandString.objects.order_by('-datetime_added') 114 | return HttpResponse('\n'.join(map(lambda s: s.string_id, cmdlist))) 115 | 116 | def user_command_list_text(request, username): 117 | user = User.objects.get(username=username) 118 | cmdlist = CommandString.objects.filter(user_added=user).order_by('-datetime_added') 119 | return HttpResponse('\n'.join(map(lambda s: s.string_id, cmdlist))) 120 | 121 | 122 | --------------------------------------------------------------------------------