my django-background-task does nothing, even if I just ask it to do something simple like printing a string.
I dont know what I am doing wrong though.
views.py:
from django.http import HttpResponse
from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import PasswordChangeForm
from django.contrib.auth import update_session_auth_hash
from .forms import UserRegistrationForm
from .models import Player, PlayerStats, TotalLevels
from django.core import management
from background_task import background
import random
# background task
#background(schedule=5)
def play_run():
print('it works!')
# management.call_command('runscript', 'runnerscript')
def random_logo():
logo = random.randint(1, 5)
logo_file = 'logo-nav'+str(logo)+'.png'
return logo_file
# Main website views
def home(request):
return render(request, template_name='main/home.html')
# bloxors website specific views
def homepage(request):
logo_file = random_logo()
return render(request, template_name='bloxors/homepage.html', context={'logo':logo_file})
# view in which background task is called
#login_required
def play_redirect(request):
play_run()
return HttpResponse('Please wait while we redirect you...')
Can someone help me by telling what is going wrong?
As always, I appreciate any and all answers!
While the server is running, open another terminal or command prompt with your virtual environment activated then run python manage.py process_tasks
https://django-background-tasks.readthedocs.io/en/latest/
Related
I am writing a view to create a user in project that has logged into another site. Whenever the user logins to that site he/she gets redirected to url:https://localhost:127.0.0.1:8000/auth/ad/reply/.
The site sends me an SAMLResponse from which I want to extract the email address, firstname & lastname for the user.
Following is my views.py and urls.py:
views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
# Create your views here.
#csrf_exempt
def ad_auth(request):
response = request.POST.get('SAMLResponse')
return HttpResponse(response)
urls.py
from django.urls import path
from .views import *
urlpatterns = [
path('auth/ad/reply/', ad_auth, name='ad_auth'),
]
Output:
PHNhbWxwOlJlc3BvbnNlIElEPSJfOTJmYjAyYTMtN2ZiMC00NjZlLTk0NGItNTQxMjhlOGI5NGM2IiBWZXJzaW9uPSIyLjAiIElzc3VlSW5zdGFudD0iMjAyMC0xMS0xMVQxNDowMDoxMi43NzlaIiBEZXN0aW5hdGlvbj0iaHR0cHM6Ly9sb2NhbGhvc3Q6ODAwMC9hdXRoL2FkL3JlcGx5LyIgeG1sbnM6c2FtbHA9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpwcm90b2NvbCI+PElzc3VlciB4bWxucz0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiI+aHR0cHM6Ly9zdHMud2luZG93cy5uZXQvYmYzODg4M2EtOGRlNi00NGFhLWJkYzktODFjMzAzY2YxMDMzLzwvSXNzdWVyPjxzYW1scDpTdGF0dXM+PHNhbWxwOlN0YXR1c0NvZGUgVmFsdWU9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpzdGF0dXM6U3VjY2VzcyIvPjwvc2FtbHA6U3RhdHVzPjxBc3NlcnRpb24gSUQ9Il8wYjExNzMwNi03YTI2LTQ2OGQtYTI5Yy1mYTZkMjk2MTQ3MDAiIElzc3VlSW5zdGFudD0iMjAyMC0xMS0xMVQxNDowMDoxMi43NjlaIiBWZXJzaW9uPSIyLjAiIHhtbG5zPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIj48SXNzdWVyPmh0dHBzOi8vc3RzLndpbmRvd3MubmV0L2JmMzg4ODNhLThkZTYtNDRhYS1iZGM5LTgxYzMwM2NmMTAzMy88L0lzc3Vlcj48U2lnbmF0dXJlIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj48U2lnbmVkSW5mbz48Q2Fub25pY2FsaXphdGlvbk1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIvPjxTaWduYXR1cmVNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNyc2Etc2hhMjU2Ii8+PFJlZmVyZW5jZSBVUkk9IiNfMGIxMTczMDYtN2EyNi00NjhkLWEyOWMtZmE2ZDI5NjE0NzAwIj48VHJhbnNmb3Jtcz48VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI2VudmVsb3BlZC1zaWduYXR1cmUiLz48VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PC9UcmFuc2Zvcm1zPjxEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGVuYyNzaGEyNTYiLz48RGlnZXN0VmFsdWU+YjdXZGtxd0d0VncyVGIxbG1ybklabHI3bXNDektFemkreGZrMVZTT2tMQT08L0RpZ2VzdFZhbHVlPjwvUmVmZXJlbmNlPjwvU2lnbmVkSW5mbz48U2lnbmF0dXJlVmFsdWU+aW9ldm5INHIyb05ra1QvaXhrelVSQ01sKzQ4enNVQUdFTFBmWmZDMXVsTmROWE5EcVVKelVFL2FYTzR6MzduWCtDY1htcGw4ZmZrRlNtNHFWNS9WaTV1TzkreFB5U3QvejhlWXV3WGg5THkvVGFsbmlCVTZ5L2JCMFF1NW9pb2pXczYxVWlIQlhGMTlGVy9WTXd2WVdlUnpXNGdKUU03cDNNdVE0MjV6Zk9PaHk2V2puNW1MU1RkOVNZT2pSOHkraWlOKzZDdHJNd2NVTk9LNXFMTFNSOGdpdUNkSVZyTUY2V2lIUkZWTjY1SlRsYXNKSVpuSWw0dldnUDdkaUJvdDB1cmtkR28wb1djMU4vQ3FOOWN1OENlTTJtTmc5SW5XS1RHWGJVaDhuZDNtcEwwa1RnZE9OOUpxMUhWTytsck94ZVcwZ0dacDB4VmVEMERnRlBHU0pBPT08L1NpZ25hdHVyZVZhbHVlPjxLZXlJbmZvPjxYNTA5RGF0YT48WDUwOUNlcnRpZmljYXRlPk1JSUM4RENDQWRpZ0F3SUJBZ0lRSk1TOWVpdVJQSVZCeVY5NW5TeDBhakFOQmdrcWhraUc5dzBCQVFzRkFEQTBNVEl3TUFZRFZRUURFeWxOYVdOeWIzTnZablFnUVhwMWNtVWdSbVZrWlhKaGRHVmtJRk5UVHlCRFpYSjBhV1pwWTJGMFpUQWVGdzB5TURFd01EWXdOVEkxTkRWYUZ3MHlNekV3TURZd05USTFORFZhTURReE1qQXdCZ05WQkFNVEtVMXBZM0p2YzI5bWRDQkJlblZ5WlNCR1pXUmxjbUYwWldRZ1UxTlBJRU5sY25ScFptbGpZWFJsTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF0WmZVZjQzNE1HeVI1ZzdPUzViMFhzV2tEUVYrYk9BWkpuZlROZTE2R1ZQV2U1ZnBhdW9XaDY1NUZjQVF3OXdEd3Z3eUJsa04vc1pqc1JnMTFLRmZyeGZkNmhkQk1Ka3FpKzN3MENMYTZzWDg5VzBmZzhnWXA3bDN4WVFBVG94RDI2MWhuT1dRaXE5em5nS2V4dVNWaW8wL25IdXNBeEdvZDdMV1A5ckRqWGh6bDRBWXQrcjZpVWt3QlNFQnoyeE41RU4rRnVPQjY5UlpaVFNGRzdUVVBCd1NseWlJZms4L3JpclhHOVFhMVk2SmFySVY4M1JSTjJKM1lpdU91Q3E2WWxseDFyNXlJVmlONlFSOG1zTlN0cmFaSS9hTGI5QjFaajJVaFBwNG8veXkwemFIQnV3Y0xjc1k4RDNSWFExblJLMVFSS041Y28rUUhkeEVrdmdicFFJREFRQUJNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUJxVHhkRTZxTHd2M0tmelNhZDU5NkJuNU9aNWVxakp5MW1vVGZoY0dHOVpBYnh5eDlDL1N6MFkyaW02dCs4YmQwdzdqUG51NHA1YWZjMGUyQ2tIL0IyZElldHBkcWpvdEdlSmZhUng3OVJJSTF6OU9LQUZQcDlkYzY5eGhndDNYN3RuZlJhVDNmeml3QSt3Z3VocjJ0YUpRUHVLOVkyL2w0VTI1N0JUNFkvMzd5S0EwM0lDakZTcXZTTzE4bmx5UkUzRVArbTEyR0tPTVYvVjZwTjJqTFRJV2I5cXIyc1E2VGl1alc3T2g0S0lyTk5pRWx2QnFRcWZyNE5OTEZuZCt1RHBWUFhHc0JYQ2NkOXZhQWswelJFUGxwMUdKQW0yOHZJMnNPLytWcjZ3cmVoR0gwVFNmOU5DQkY2cDUzVHN0RWNOVldCYUNHTkFwQlZrY0RKaGRYTDwvWDUwOUNlcnRpZmljYXRlPjwvWDUwOURhdGE+PC9LZXlJbmZvPjwvU2lnbmF0dXJlPjxTdWJqZWN0PjxOYW1lSUQgRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoxLjE6bmFtZWlkLWZvcm1hdDplbWFpbEFkZHJlc3MiPmxpbmdheWF0YWpheTI4MTBfZ21haWwuY29tI0VYVCNAa3Jpc3AxNTA2Z21haWwub25taWNyb3NvZnQuY29tPC9OYW1lSUQ+PFN1YmplY3RDb25maXJtYXRpb24gTWV0aG9kPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6Y206YmVhcmVyIj48U3ViamVjdENvbmZpcm1hdGlvbkRhdGEgTm90T25PckFmdGVyPSIyMDIwLTExLTExVDE1OjAwOjEyLjM4OFoiIFJlY2lwaWVudD0iaHR0cHM6Ly9sb2NhbGhvc3Q6ODAwMC9hdXRoL2FkL3JlcGx5LyIvPjwvU3ViamVjdENvbmZpcm1hdGlvbj48L1N1YmplY3Q+PENvbmRpdGlvbnMgTm90QmVmb3JlPSIyMDIwLTExLTExVDEzOjU1OjEyLjM4OFoiIE5vdE9uT3JBZnRlcj0iMjAyMC0xMS0xMVQxNTowMDoxMi4zODhaIj48QXVkaWVuY2VSZXN0cmljdGlvbj48QXVkaWVuY2U+RGVsbGNhbGNJRDwvQXVkaWVuY2U+PC9BdWRpZW5jZVJlc3RyaWN0aW9uPjwvQ29uZGl0aW9ucz48QXR0cmlidXRlU3RhdGVtZW50PjxBdHRyaWJ1dGUgTmFtZT0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9pZGVudGl0eS9jbGFpbXMvdGVuYW50aWQiPjxBdHRyaWJ1dGVWYWx1ZT5iZjM4ODgzYS04ZGU2LTQ0YWEtYmRjOS04MWMzMDNjZjEwMzM8L0F0dHJpYnV0ZVZhbHVlPjwvQXR0cmlidXRlPjxBdHRyaWJ1dGUgTmFtZT0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9pZGVudGl0eS9jbGFpbXMvb2JqZWN0aWRlbnRpZmllciI+PEF0dHJpYnV0ZVZhbHVlPjg0MjYwMmMxLWNhZDQtNDg2OC05Yzk5LWZjMDhmOTExNzk1MzwvQXR0cmlidXRlVmFsdWU+PC9BdHRyaWJ1dGU+PEF0dHJpYnV0ZSBOYW1lPSJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL2lkZW50aXR5L2NsYWltcy9kaXNwbGF5bmFtZSI+PEF0dHJpYnV0ZVZhbHVlPkFqYXkgTGluZ2F5YXQ8L0F0dHJpYnV0ZVZhbHVlPjwvQXR0cmlidXRlPjxBdHRyaWJ1dGUgTmFtZT0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9pZGVudGl0eS9jbGFpbXMvaWRlbnRpdHlwcm92aWRlciI+PEF0dHJpYnV0ZVZhbHVlPmxpdmUuY29tPC9BdHRyaWJ1dGVWYWx1ZT48L0F0dHJpYnV0ZT48QXR0cmlidXRlIE5hbWU9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vY2xhaW1zL2F1dGhubWV0aG9kc3JlZmVyZW5jZXMiPjxBdHRyaWJ1dGVWYWx1ZT5odHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvYXV0aGVudGljYXRpb25tZXRob2QvcGFzc3dvcmQ8L0F0dHJpYnV0ZVZhbHVlPjwvQXR0cmlidXRlPjxBdHRyaWJ1dGUgTmFtZT0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvZ2l2ZW5uYW1lIj48QXR0cmlidXRlVmFsdWU+QWpheTwvQXR0cmlidXRlVmFsdWU+PC9BdHRyaWJ1dGU+PEF0dHJpYnV0ZSBOYW1lPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9zdXJuYW1lIj48QXR0cmlidXRlVmFsdWU+TGluZ2F5YXQ8L0F0dHJpYnV0ZVZhbHVlPjwvQXR0cmlidXRlPjxBdHRyaWJ1dGUgTmFtZT0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvZW1haWxhZGRyZXNzIj48QXR0cmlidXRlVmFsdWU+bGluZ2F5YXRhamF5MjgxMEBnbWFpbC5jb208L0F0dHJpYnV0ZVZhbHVlPjwvQXR0cmlidXRlPjxBdHRyaWJ1dGUgTmFtZT0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZSI+PEF0dHJpYnV0ZVZhbHVlPmxpbmdheWF0YWpheTI4MTBfZ21haWwuY29tI0VYVCNAa3Jpc3AxNTA2Z21haWwub25taWNyb3NvZnQuY29tPC9BdHRyaWJ1dGVWYWx1ZT48L0F0dHJpYnV0ZT48L0F0dHJpYnV0ZVN0YXRlbWVudD48QXV0aG5TdGF0ZW1lbnQgQXV0aG5JbnN0YW50PSIyMDIwLTExLTExVDA3OjI4OjM1LjAwMFoiIFNlc3Npb25JbmRleD0iXzBiMTE3MzA2LTdhMjYtNDY4ZC1hMjljLWZhNmQyOTYxNDcwMCI+PEF1dGhuQ29udGV4dD48QXV0aG5Db250ZXh0Q2xhc3NSZWY+dXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFjOmNsYXNzZXM6UGFzc3dvcmQ8L0F1dGhuQ29udGV4dENsYXNzUmVmPjwvQXV0aG5Db250ZXh0PjwvQXV0aG5TdGF0ZW1lbnQ+PC9Bc3NlcnRpb24+PC9zYW1scDpSZXNwb25zZT4=
How do I extract information from the following SAMLResponse?
Thanks in Advance.
That is sending you a base64 encoded string.
Decode it and you will find it to be xml.
The email attribute will look something like this
<AttributeValue>xxxxxxxxx2810#gmail.com</AttributeValue>
Some sudo code to get you started
import base64
foo = base64.b64decode("PHNhbWxwOlJlc3BvbnN....") # put your entire string here
print(foo)
You can also use pysaml2 and djangosaml modules to decrypt the SAMLResponse.
I have a problem.
I needto implement a function that will be called cyclically
I have to call dashgenerate functions because it generates data records
this cron.py:
from django_cron import CronJobBase, Schedule
from django.shortcuts import get_object_or_404, render, redirect
from django.http import HttpResponse, HttpResponseRedirect, Http404
class MyCronJob(CronJobBase):
RUN_EVERY_MINS = 60
schedule = Schedule(run_every_mins=RUN_EVERY_MINS)
code = 'CRM.my_cron_job'
def do(self):
return redirect('dashboard/dashgenerate/')
dashgenerate is a def from another app in project:
def dashgenerate(request):
.....
I want the user not to navigate back once he is logged out. I used login_required(login_url = "/login/") before my definition of logout view in my views.py. I am still able to navigate back after logging out. How can I ask the user to log in again? Also, If I type URL for my home page (say localhost:8000/home) directly in the browser, I am able to access the page without login. How can I correct this issue?
I have cleared browser cache too and still, no use.
my views.py:
from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.contrib import auth
from django.views.decorators import csrf
from django.contrib.auth.decorators import login_required
def login(request):
c={}
# c.update(csrf(request))
return render(request,'login.html',c)
def auth_view(request):
username = request.POST.get('username','')
password = request.POST.get('password','')
user = auth.authenticate(username=username, password=password)
if user is not None:
auth.login(request, user)
return HttpResponseRedirect('/home')
#login_required(login_url='/login/')
def logout(request):
request.session.flush()
auth.logout(request)
return render(request,'logout.html')
If you want to protect your home page or other pages with login, you should decorate them with login_required decorator. For example,
#login_required(login_url='/login/')
def home(request):
# Your code goes here
I have successfully built a custom user registration system as one module and I have one other module named article. I want to display the user logged in from my custom user registeration module in the templates of article module.
I'm using {{if user.is_authenticated}} display {{user}} to display the username in my templates.
I am able to access it in custom user registration templates but not in the articles templates. I want to display the username on the navbar which is same for both the apps.
what should i do so that the username is accessible in the entire project, not just in the template rendered.
I'm using django 1.8 and i have also tried creating a session variable in my views.py file but it also works in the same app.
views.py of the project
from django.shortcuts import render, render_to_response, RequestContext
from django.http import HttpResponseRedirect
from django.contrib import auth
from django.core.context_processors import csrf
from custom_user.forms import CustomUserCreationForm
from django.utils import timezone
def login(request):
c = {}
c.update(csrf(request))
return render_to_response('login.html', c)
def auth_view(request):
username = request.POST.get('username', '')
password = request.POST.get('password', '')
user = auth.authenticate(username=username, password=password)
if user is not None:
auth.login(request, user)
request.session['user_id'] = user.id
request.session['user_email'] = user.email
return render(request, "loggedin.html", {},context_instance=RequestContext(request))
else:
return HttpResponseRedirect('/accounts/invalid')
def loggedin(request):
return render_to_response('loggedin.html', {})
def invalid_login(request):
return render_to_response('invalid_login.html')
template base.py
<ul class="nav navbar-nav navbar-right">
<li>Subscribe</li>
{% if user.is_authenticated %}
<li>{{user}}</li>
<li>Logout</li>
{% else %}
<li>Login</li>
{% endif %}
</ul>
views.py of article app
from django.shortcuts import render
from django.http import HttpResponse
from django.template import RequestContext
from django.template.loader import get_template
from django.shortcuts import render_to_response
from django.conf import settings
from article.models import Article, Comment, Subscribers
from forms import ArticleForm, CommentForm, SubscriptionForm, ActivateSubscriberForm
from django.http import HttpResponseRedirect
from django.core.context_processors import csrf
from django.utils import timezone
from django.core.mail import send_mail
from random import randrange
from signup.views import *
# from .forms import RegistrationForm
# Create your views here.
def articles(request):
return render_to_response('articles.html',
{'articles':Article.objects.all().order_by('-id'),'last':Article.objects.earliest('-pub_date')})
def article(request, article_id=1):
return render_to_response('article.html',
{'article':Article.objects.get(id=article_id)})
When user is authenticated then loggedin.html is rendered and there i have created a link to go to articles app which uses the same base.py template.
You will be able to access authentication data if you've got the 'django.contrib.auth.context_processors.auth' processor in TEMPLATE_CONTEXT_PROCESSORS.
However, it is present by default - perhaps you've removed it?
Finally, the documentation is very helpful on that subject: https://docs.djangoproject.com/en/1.8/topics/auth/default/#authentication-data-in-templates
You haven't actually shown any code, but the problem is almost certainly how you are rendering the template. As Marcanpilami points out, the user variable is automatically added by the template context processors; but context processors are only run if you use a RequestContext to render your template. That means, these days, ensuring that you use the render shortcut, rather than render_to_response.
(For completeness sake, you can use render_to_response as long as you pass it context_instance=RequestContext, but it's almost always easier to just use render).
Hi I'm siting with my custom storage system 1 day. And now when I'm trying import it it gives me this Error.
I put in file models.py
from FTPStorage import FTPStorage
import datetime
from django.db import models
fs=FTPStorage()
class Upload(models.Model):
"""Uploaded files."""
file = models.FileField(upload_to='uploads', store=fs)
timestamp = models.DateTimeField(default=datetime.datetime.now)
notes = models.CharField(max_length=255, blank=True)
class Meta:
ordering = ['-timestamp',]
def __unicode__(self):
return u"%s" % (self.file)
#property
def size(self):
return filesizeformat(self.file.size)
here is my views.py:
from forms import UploadForm
from models import Upload
import ftplib
import os
import datetime
from django.forms import save_instance
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.http import HttpResponse
from FTPStorage import FTPStorage
from django.core.files.storage import Storage
def initial(request):
data = {
'form': UploadForm(),
}
return render_to_response('upload.html', data, RequestContext(request))
def upload(request):
if request.method == 'POST':
form = UploadForm(request.POST, request.FILES)
if form.is_valid():
upload = Upload()
upload.timestamp = datetime.datetime.now()
save_instance(form, upload)
return HttpResponseRedirect(reverse('initial'))
and file custom storage system FTPStorage.py is in direectory app
I have this problem:
Request Method: GET
Request URL: http://localhost:2121/
Exception Type: ViewDoesNotExist
Exception Value:
Could not import app.views. Error was: cannot import name FTPStorage
Exception Location: C:\BitNami DjangoStack\apps\django\django\core\urlresolvers.py in _get_callback, line 134
Please help me. I confuse.
It seems to me that you need to update the PYTHONPATH for your runtime. Based on your error page I think you're using mod_python so try this setting in apache:
PythonPath "sys.path+['/mydir']"
Where /mydir is the full path to wherever the FTPStorage module resides.