def project_upload(): ''' Upload project as ZIP archive ''' user_id = User().id f = request.POST.get("file") content = f.file.read() filename = f.filename title = filename.replace(".zip", "") path = "%s%i/" % (settings.PROJECTS_ROOT, user_id) if not os.path.exists(path + title): with zipfile.ZipFile(f.file, "r") as z: z.extractall(path) item = models.Project() item.user_id = User().id item.title = title item.save() return json.dumps(item.json(with_tree=True)) return json.dumps({"msg": "Directory exists!"})
def user_login(): ''' Auth user ''' user = User() if not user.authenticate( request.POST.getone('email'), request.POST.getone('password') ): redirect('/login/?msg=Incorrect username or password') return '<meta http-equiv="refresh" content="0;url=/" />'
def projects_list(): #response.set_header('Cache-Control', 'no-cache, must-revalidate') user = User() items = models.Project.find({"user_id": user.id}) return json.dumps([item.json() for item in items])
def files_list(): ''' Returns list of files in user top dir. E.g., files not assigned to any project. ''' user_id = User().id path = "%s%i/" % (settings.PROJECTS_ROOT, user_id) IGNORE_FILES = r'|'.join([fnmatch.translate(x) \ for x in settings.IGNORE_FILES]) or r'$.' f = {} for (dirpath, dirname, filenames) in os.walk(path): # TODO: consider to read content of file # File ID: uuid.uuid4().hex is one time ID for file # to make it possible to handle it in UI f = [ { "id": uuid.uuid4().hex, "title": x, "path": x, # this is files in user's ROOT so path is filename "dir": "" } for x in filenames if not re.match(IGNORE_FILES, x) ] break return json.dumps(f)
def user_signup(): ''' Writes new user to DB ''' if not settings.SIGNUP_ENABLED: return "Sign up disabled in app settings!" email = request.POST.get('email'), password = request.POST.get('password') user = User() if user.register(email[0], password): redirect('/') redirect('/signup/')
def project_downoad(): ''' ZIPs project and returns resulting archive ''' user = User() item = models.Project.find_one({"id": request.GET.get("id")}) if user.id != item.user_id: return "User ID not match with project ID!" filename = shutil.make_archive(item.title, "zip", item.abs_path()) try: fo = open(filename, "rb") content = fo.read() except: content = "Error reading file!" finally: fo.close() os.remove(filename) response.content_type = 'application/zip' response.headers[ 'Content-Disposition'] = 'attachment; filename="%s.zip"' % item.title return content
def folder_rename(): ''' Rename/Move folder ''' user_id = User().id path = "%s%i/" % (settings.PROJECTS_ROOT, user_id) file_path = request.POST.get("path") new_title = request.POST.get("new_title") rel_dir = request.POST.get("dir", "") new_dir = request.POST.get("new_dir") or rel_dir if not file_path: return json.dumps({"msg": "Specify folder name!"}) if (path + file_path != path + new_dir + "/" + new_title): if os.path.exists(path + new_dir + "/" + new_title): return json.dumps({"msg": "Destination folder exists!"}) try: os.rename(path + file_path, path + new_dir + "/" + new_title) except: return json.dumps({"msg": "Error renaming folder!"}) return "{}"
def project_build(): ''' Execute project `build` command from Settings and return output to UI ''' user_id = User().id item = models.Project.find_one({"id": request.GET.get("id")}) res = "" if user_id != item.user_id: return "User ID not match with project ID!" settings = item.get_settings() if not "build" in settings: return "Specify build system in Settings first!" p = subprocess.Popen((settings["build"]), cwd=item.abs_path(), stdout=subprocess.PIPE, stderr=subprocess.PIPE) output, errors = p.communicate() res += output + "\n" res += errors + "\n" res += 'process ended with return code %i' % p.returncode return res
def project_create(): ''' Adds new project for loggedin user. Created DB item and Directory on filesystem. ''' title = request.POST.get("title") # DB item = models.Project() item.user_id = User().id item.title = title if os.path.exists(item.abs_path()): return json.dumps({"msg": 'Directory "%s" already exists!' % title}) # DB save item.save() # FS os.makedirs(item.abs_path()) try: fo = open(item.abs_path() + "/.liveideproject", "wb") fo.write(json.dumps({"title": item.title})) finally: fo.close() return json.dumps(item.json(with_tree=True))
def user_logout(): ''' Sign out ''' User().logout() return '<meta http-equiv="refresh" content="0;url=/" />'
def tests(): ''' QTests ''' return { "user": User(), "static_url": settings.STATIC_URL }
def project_open(): ''' Loads project tree ''' user = User() item = models.Project.find_one({"id": request.GET.get("id")}) if user.id != item.user_id: return json.dumps({"msg": "User ID not match with project ID!"}) return json.dumps(item.get_files())
def file_create(): ''' Adds new file for loggedin user. Creates file on FS. File can be assigned to project or not assigned. ''' title = request.POST.get("title") content = request.POST.get("content", "") rel_dir = request.POST.get("dir", "") file_path = title if rel_dir: file_path = rel_dir + "/" + file_path user_id = User().id project_id = request.POST.get("project") path = "%s%i/" % (settings.PROJECTS_ROOT, user_id) if project_id: project = models.Project.find_one({"id": project_id}) if not os.path.exists(path): os.makedirs(path) if not os.path.exists(path + file_path): try: fo = open(path + file_path, "wb") fo.write(content) except: return json.dumps({"msg": "Error creating file!"}) finally: fo.close() # uuid.uuid4().hex is just one time ID for file, for UI usage only c = { "id": uuid.uuid4().hex, "title": title, "project": project_id, "content": content, "path": file_path, "dir": rel_dir, } return json.dumps(c) return json.dumps({"msg": "File exists!"})
def project_copy(): ''' Copy project dir and record in DB. ''' user = User() item = models.Project.find_one({"id": request.POST.get("id")}) if user.id != item.user_id: return json.dumps({"msg": "User ID not match with project ID!"}) new_title = request.POST.get("new_title") if not new_title: return json.dumps({"msg": "Specify new name for project!"}) # New item record in DB new_item = models.Project() new_item.user_id = user.id new_item.title = new_title try: path = "%s%i/" % (settings.PROJECTS_ROOT, item.user_id) shutil.copytree(item.abs_path(), path + new_title) except: return json.dumps({"msg": "Error copying project!"}) new_item.save() try: fo = open(new_item.abs_path() + "/.liveideproject", "r+") try: project_settings = json.loads(fo.read() or "{}") except: project_settings = {} project_settings["title"] = new_item.title fo.truncate(0) fo.write(json.dumps(project_settings)) finally: fo.close() return json.dumps(new_item.json(with_tree=True))
def file_save(): ''' Save / Save as... / Move file on FS ''' user_id = User().id path = "%s%i/" % (settings.PROJECTS_ROOT, user_id) file_path = request.POST.get("path") content = request.POST.get("content") # If specified `new_title` - Save as... new_title = request.POST.get("new_title") rel_dir = request.POST.get("dir", "") new_dir = request.POST.get("new_dir") or rel_dir if new_dir: new_dir += "/" if not file_path: return json.dumps({"msg": "Specify file name!"}) if content != None: try: fo = open(path + file_path, "wb") fo.write(content) except: return json.dumps({"msg": "Error writing file!"}) finally: fo.close() # Save as... / Move if (path + file_path != path + new_dir + new_title): if os.path.exists(path + new_dir + new_title): return json.dumps({"msg": "Destination file exists!"}) try: os.rename(path + file_path, path + new_dir + new_title) except: return json.dumps({"msg": "Error renaming file!"}) return "{}"
def folder_remove(): ''' Removes folder from FS. NOT REVERTABLE. ''' user_id = User().id path = "%s%i/" % (settings.PROJECTS_ROOT, user_id) file_path = request.POST.get("path") if not file_path: return json.dumps({"msg": "Specify folder name!"}) # Remove on FS if os.path.exists(path + file_path): try: shutil.rmtree(path + file_path) except: return json.dumps({"msg": "Removing on FS failed!"}) return "{}"
def project_settings(): ''' Saves project settings to `.liveideproject` file. ''' user = User() item = models.Project.find_one({"id": request.POST.get("id")}) if user.id != item.user_id: return json.dumps({"msg": "User ID not match with project ID!"}) project_settings = dict(request.POST) try: fo = open(item.abs_path() + "/.liveideproject", "r+") fo.truncate(0) fo.write(json.dumps(project_settings)) finally: fo.close() return json.dumps(project_settings)
def file_upload(): ''' Upload file ''' user_id = User().id f = request.POST.get("file") content = f.file.read() rel_dir = request.GET.get("dir") project_id = request.GET.get("project") file_path = f.filename if rel_dir: file_path = rel_dir + "/" + file_path path = "%s%i/" % (settings.PROJECTS_ROOT, user_id) if not os.path.exists(path + file_path): try: fo = open(path + file_path, "wb") fo.write(content) except: return json.dumps({"msg": "Error uploading file!"}) finally: fo.close() # uuid.uuid4().hex is just one time ID for file, for UI usage only c = { "id": uuid.uuid4().hex, "title": f.filename, "project": project_id, "content": content, "path": file_path, "dir": rel_dir, } return json.dumps(c) return json.dumps({"msg": "File exists!"})
def folder_create(): ''' Adds new folder into project. ''' user = User() project_id = request.POST.get("id") item = models.Project.find_one({"id": project_id}) if user.id != item.user_id: return json.dumps({"msg": "User ID not match with project ID!"}) title = request.POST.get("title") rel_dir = request.POST.get("dir") if not title: return json.dumps({"msg": "Specify name for folder!"}) path = "%s%i/" % (settings.PROJECTS_ROOT, item.user_id) if rel_dir: path += rel_dir + "/" if os.path.exists(path + title): return json.dumps({"msg": 'Directory "%s" already exists!' % title}) # FS os.makedirs(path + title) c = { "id": uuid.uuid4().hex, "is_folder": True, "title": title, "project": project_id, "path": models.join(rel_dir, title), "dir": rel_dir, "files": {} } return json.dumps(c)
def file_content(): ''' Reads file on FS ''' content = "" user_id = User().id path = "%s%i/" % (settings.PROJECTS_ROOT, user_id) file_path = request.GET.get("path") if not file_path: return "Specify file name!" try: fo = open(path + file_path, "rb") content = fo.read() except: content = "Error reading file!" finally: fo.close() return content
def file_run(): ''' Run file with interpreter and return output to UI ''' user_id = User().id path = "%s%i/" % (settings.PROJECTS_ROOT, user_id) file_path = request.GET.get("path") res = "" if not file_path: return "Specify file name!" p = subprocess.Popen(('python', '-u', path + file_path, 'x'), stdout=subprocess.PIPE, stderr=subprocess.PIPE) # while True: # nextline = p.stdout.readline() # if nextline == '' and p.poll() != None: # break # yield nextline # output = process.communicate()[0] # exitCode = process.returncode output, errors = p.communicate() res += output + "\n" res += errors + "\n" # while p.poll() == None: # data = p.stdout.readline() # if data: # res += data + "\n" res += 'process ended with return code %i' % p.returncode return res
def project_rename(): ''' Renames (move) project dir and record in DB. ''' user = User() item = models.Project.find_one({"id": request.POST.get("id")}) if user.id != item.user_id: return json.dumps({"msg": "User ID not match with project ID!"}) new_title = request.POST.get("new_title") if not new_title: return json.dumps({"msg": "Specify new name for project!"}) try: path = "%s%i/" % (settings.PROJECTS_ROOT, item.user_id) os.rename(item.abs_path(), path + new_title) except: return json.dumps({"msg": "Error renaming project!"}) item.title = new_title item.save() try: fo = open(item.abs_path() + "/.liveideproject", "r+") try: project_settings = json.loads(fo.read() or "{}") except: project_settings = {} project_settings["title"] = item.title fo.truncate(0) fo.write(json.dumps(project_settings)) finally: fo.close() return "{}"
def project_remove(): ''' Removes project dir and record in DB. NOT REVERTABLE. ''' user = User() item = models.Project.find_one({"id": request.POST.get("id")}) if user.id != item.user_id: return json.dumps({"msg": "User ID not match with project ID!"}) # Remove on FS if os.path.exists(item.abs_path()): try: shutil.rmtree(item.abs_path()) except: return json.dumps({"msg": "Removing on FS failed!"}) # Finally remove in DB item.delete() return "{}"
def file_downoad(): ''' Download file ''' user_id = User().id path = "%s%i/" % (settings.PROJECTS_ROOT, user_id) file_path = request.GET.get("path") filename = request.GET.get("filename") if not file_path: return "Specify file name!" try: fo = open(path + file_path, "rb") content = fo.read() except: content = "Error reading file!" finally: fo.close() response.content_type = 'text/text' response.headers[ 'Content-Disposition'] = 'attachment; filename="%s"' % filename return content
def validate_login(): ''' Relly on User class from `bottlepy-user-auth` ''' return User().loggedin
def index(): return {"user": User(), "static_url": settings.STATIC_URL}