Django - Certain Py Module doesn't work in IIS - sql-server

This is my first time putting a question here. Some background, I started coding on Django this year and Python more than a year but less than 2 years so I don't much. This problem is a concern to my what I developing in at work. And my team working on it is novice or no experience on coding Python or Django or both.
The Problem
We have a web app based on Django 3.0.2 and use MSSQL for the db. Our company policy is to use Windows server and IIS as the prod and test server. We done a lot of work on it and all work well except for some python library and Django module that don't work, mainly Xlwings and Django-post-office. For XLwings, it doesn't run the code and Excel(we have valid license and latest Excel programme on the server).
code below;
filepath = BASE_DIR + '\\media\\Template.xlsm'
temp_path = BASE_DIR + '\\media\\' + '{}.{}'.format(uuid4().hex, 'xlsm')
shutil.copyfile(filepath, temp_path)
pythoncom.CoInitialize()
app1 = xw.App(visible=True)
wt = xw.Book(temp_path)
sht = wt.sheets['Cover']
sht.range('E5').value = request.POST.get('year')
sht.range('E6').value = request.POST.get('company')
sht.range('E7').value = companydata.employer_no
sht.range('E8').value = email
wt.save(temp_path)
app1.quit()
As for Django-post-office, we have a module using it that got it working but other modules using it doesn't work. Same code that is used except for the template and subject.
Code below;
plaintext = get_template('template.txt')
htmly = get_template('template.html')
mail.send(
[email],
NAME_EMAIL_DOMAIN,
message = plaintext.render(info),
html_message = htmly.render(info),
subject = f'Subject',
priority = 'now',
attachments = {
'RemunerationTemplate.xlsm': temp_path,
},
)
The bizarre thing is it work on CMD but it just doesn't work on IIS. We don't know why and how to rectify it. We ask the IT Support (department responsible for the servers) said that the test server is not restricted.
The Fail Fix
Try change IIS config, enviroment etc - No Dice
Change code - We are noobs, idk what's wrong but clearly doesn't work
Google it - too sparse for info
Ask the IT support guy if he has any idea - he doesn't care much on it and just say to me to piss off
So, I grateful if any help for this since we are nearing the deployment date and this issue is haunting me in my sleep for the past week already. Thank You

Related

Errors when retrieving request body in Mongoose WebServer

I'm working with an old version of mongoose (open source web server) in C, which did not provide native access to the requests payload. In order to support POST and PUT requests, I manually modified it: after mongoose reads the headers, I check if Content-Length is set and, if so, I read again from the socket for Content-Lenght characters.
findCL = strstr(conn->buf, "Content-Length:");
if (findCL)
{
// skip "Content-Length:" string
findCL += 15 * sizeof(char);
findCLEnd = (char*)strchr(findCL, delimiter);
sizeLen = findCLEnd - findCL;
strncpy(CLSize, findCL, sizeLen);
CLSize[sizeLen] = '\0';
size = strtoll(CLSize, NULL, 10);
if (size > 0)
{
conn->content_len = read_request(NULL, conn->client.sock, conn->ssl,
conn->buf, conn->buf_size, &conn->data_len);
conn->content_len = size;
perror("recv");
body = (char*)malloc(sizeof(char) * (size + 1));
strncpy(body, conn->buf + conn->request_len, size);
body[size] = '\0';
}
}
So far so good, even if the code is not that beautiful it does the dirty job. Problem is, while in debug the code works fine, but when the code runs as a simple background process the body is not parsed correctly: sometimes the resulting body is truncated, some other times it is just empty. It seems that the problem is caused by the fast queries from the clients.
Not a real answer, but that's how I solved.
The web server module started as a Mongoose web server; I ported it to Civetweb some months ago, hoping that the latest versions of the project also supported the parsing of the body. It was not so, and I had to implement it manually. After some times I discovered that Civetweb had issues in serving Javascript files to IE8 browsers (for some mysterious reason). I reverted to Mongoose and all worked, except the body parsing, which brought to the code above and the subsequent errors. I finally solved by reverting back to Civetweb, stable version 1.9.1, keeping the manual body parsing procedure. This solved both the truncated requests body and the truncated served javascript files. Probably the first version of Civetweb was a not-so-stable beta, although I wonder how did it manage to work for months.
I still haven't checked the diffs between the two versions, but I expect it to be something related to maximum response sizes depending on platform or request headers or whatever else.

NancyFx will not display images

My last attempt: Don't even know what I'm doing anymore:
Get["/{any}/x.png"] = x => {
return Response.AsImage(Program.portal.ourRoot + "x.png");
};
Get["/{any}/{moreany}/x.png"] = x => {
return Response.AsImage(Program.portal.ourRoot + "x.png");
};
Get["/{any}/{moreany}/{extraany}/x.png"] = x => {
return Response.AsImage(Program.portal.ourRoot + "x.png");
};
What I currently have in my ConfigureConvetions (in the BootStrapper). I've tried a lot of permutations so far.
protected override void ConfigureConventions(NancyConventions conventions) {
//conventions.StaticContentsConventions.AddFile("x.png", ourRoot + "x.png");
conventions.StaticContentsConventions.Add(StaticContentConventionBuilder.AddFile("/portal/images/x.png", ourRoot + "x.png"));
conventions.StaticContentsConventions.Add(StaticContentConventionBuilder.AddDirectory("images", ourRoot, new string[] { "png" }));
conventions.StaticContentsConventions.Add(StaticContentConventionBuilder.AddDirectory("/portal/", ourRoot, new string[] { "png" }));
conventions.StaticContentsConventions.Add(StaticContentConventionBuilder.AddDirectory("/", ourRoot, new string[] { "png" }));
base.ConfigureConventions(conventions);
}
I have a CustomRootPathProvider that points to ourRoot (string, currently holds a direct C:\somepathstuffhere\ to a content directory).
I only need to serve a single image for my needs (at least, for now, things always tend to grow). I'm using the directory structure as variables, so I need to be able to serve this image from a very large amount of locations.
I have a copy of the image in my root folder, and in a directory called images (the "images" has had '/''s all over it, occasionally even through the middle). I am currently referencing the image with "/images/x.png", but I've tried from the root, just the name, and "images/x.png".
Thanks!
I will post back in the mean time if I figure it out (I'm assuming its something very simple.)
Solved: Worked Around? \ Non-Optimal
I changed my /images/x.png references to 'x.png', and then I dropped the extension reference to the following line.
conventions.StaticContentsConventions.Add(StaticContentConventionBuilder.AddDirectory("/", ourRoot));
Nancy started catching the 'x.png' image for the Root Page and the \Portal\ page. And then the 2nd Get /{any}/{moreany}/x.png started catching the rest of the 'x.png' requests (\Portal\Project).
I'm really not sure, why it started working all of a sudden. I've just been playing the permutation game.
The big non-optimal part, is every single directory's version of the image is treated as brand new. If anyone can solve this one for me, that'd be nice. If I figure out what to do to fix it myself, I will post back with my solution.
SOLVED
This solution won't interest anyone familiar with web programming. Its more of a new user pitfall situation. When I started setting up NancyFX I read the documentation fairly thoroughly (even if I didn't get it all on the first read). When I got to the web.config part, I first checked the Solution Explorer in VS and I didn't see one. So I just went into my project directory and created one (And there-in lies the problem). The one I made never applied settings to the project.
I figured it was a concept error, I just didn't know enough, to know where to look.\
Thx for the community's help! Hopefully my experience helps some other 1st time user out.

App Engine Instance ID

Is it possible to get info on what instance you're running on? I want to output just a simple identifier for which instance the code is currently running on for logging purposes.
Since there is no language tag, and seeing your profile history, I assume you are using GAE/J?
In that case, the instance ID information is embedded in one of the environment attributes that you could get via ApiProxy.getCurrentEnvironment() method. You could then extract the instance id from the resulting map using key BackendService.INSTANCE_ID_ENV_ATTRIBUTE.
Even though the key is stored in BackendService, this approach will also work for frontend instances. So in summary, the following code would fetch the instance ID for you:
String tInstanceId = ApiProxy.getCurrentEnvironment()
.getAttributes()
.get( BackendService.INSTANCE_ID_ENV_ATTRIBUTE )
.toString();
Please keep in mind that this approach is quite undocumented by Google, and might subject to change without warning in the future. But since your use case is only for logging, I think it would be sufficient for now.
With the advent of Modules, you can get the current instance id in a more elegant way:
ModulesServiceFactory.getModulesService().getCurrentInstanceId()
Even better, you should wrap the call in a try catch so that it will work correctly locally too.
Import this
import com.google.appengine.api.modules.ModulesException;
import com.google.appengine.api.modules.ModulesServiceFactory;
Then your method can run this
String instanceId = "unknown";
try{
instanceId = ModulesServiceFactory.getModulesService().getCurrentInstanceId();
} catch (ModulesException e){
instanceId = e.getMessage();
}
Without the try catch, you will get some nasty errors when running locally.
I have found this super useful for debugging when using endpoints mixed with pub-sub and other bits to try to determine why some things work differently and to determine if it is related to new instances.
Not sure about before, but today in 2021 the system environment variable GAE_INSTANCE appears to contain the instance id:
instanceId = System.getenv("GAE_INSTANCE")

chan->cdr no data after upgrade from Asterisk 1.4.21

I have a legacy Asterisk application in C which does authentication of users, routing and billing using MySQL. I have kept it with Asterisk 1.4.21 because none of the CDR data is returned in newer versions of Asterisk.
Apparently there have been some changes in 1.4.22 https://issues.asterisk.org/jira/browse/ASTERISK-13064 that have completely changed the way CDR-s are handled. Unfortunately no helpful information was given on how to properly migrate existing code.
They have changed the order of execution, the 'h' extension is called and the CDR data is reset.
My code:
ast_log(LOG_NOTICE,"Dialing string: '%s'\n", dialstr);
app = pbx_findapp("Dial");
if (app)
res = pbx_exec(chan, app, dialstr);
ast_log(LOG_NOTICE,"Return from pbx_exec '%i', Disposition: '%s'\n", res, ast_cdr_disp2str(chan->cdr->disposition));
Other parts of the code handle chan->cdr->billsec etc, but it always gives 0 values.
After a successful call I always get this log from CLI:
Return from pbx_exec '-1', Disposition: 'NO ANSWER' while the same code works fine on 1.4.21
One solution I heard is to use ast_reset() before Dial but I am not sure how to implement it.
Any help on how to adapt this application?
You can just get DIALSTATUS variable,that is enought for you application and will be supported in future releases.
pbx_builtin_getvar_helper(chan, "DIALSTATUS");

AppEngine: Get current serving application version

Is there a simple way to get the current serving application version in AppEngine?
os.environ['CURRENT_VERSION_ID']
String version = SystemProperty.version.get();
String applicationVersion = SystemProperty.applicationVersion.get();
This is the syntax:
public static final SystemProperty applicationVersion
The major version number for the currently running version of the application plus a timestamp at which it was deployed. Has the key, "com.google.appengine.application.version".
See here
PS. One puzzle still remains. What does timestamp next to version means and how to read it??
EDIT: Here is the key to the mystery.
Date UploadDate = new Date(Long.parseLong(
applicationVersion.substring(applicationVersion.lastIndexOf(‌​".")+1))
/ (2 << 27) * 1000);
For Python (GAE SDK release: "1.4.2")
version_id = self.request.environ["CURRENT_VERSION_ID"].split('.')[1]
timestamp = long(version_id) / pow(2,28)
version = datetime.datetime.fromtimestamp(timestamp).strftime("%d/%m/%y %X")
See http://groups.google.com/group/google-appengine-python/browse_thread/thread/f86010e7cf3c71b4
from google.appengine.api import modules
modules.get_current_version_name()
Source: https://cloud.google.com/appengine/docs/python/modules/functions
For nodejs, I am not sure if this is documented.
process.env.GAE_VERSION
You can also access the process' environment variables:
GAE_VERSION
which is available when you deploy (gcloud app deploy) using the flag --version
For those who want an update, environment variables set for a GAE instance as of September 2020:
GAE_VERSION is the one that seems to answer the original question.
Google doc:
https://cloud.google.com/appengine/docs/standard/python3/runtime#environment_variables
The following environment variables are set by the runtime:
Environment variable Description
GAE_APPLICATION The ID of your App Engine application. This ID is prefixed with 'region code~' such as 'e~' for applications deployed in Europe.
GAE_DEPLOYMENT_ID The ID of the current deployment.
GAE_ENV The App Engine environment. Set to standard.
GAE_INSTANCE The ID of the instance on which your service is currently running.
GAE_MEMORY_MB The amount of memory available to the application process, in MB.
GAE_RUNTIME The runtime specified in your app.yaml file.
GAE_SERVICE The service name specified in your app.yaml file. If no service name is specified, it is set to default.
GAE_VERSION The current version label of your service.
GOOGLE_CLOUD_PROJECT The Cloud project ID associated with your application.
PORT The port that receives HTTP requests.
Based on my experiments today, there are two os.environ variables that you can use to get the current app version:
os.environ['GAE_VERSION']: the version name only
os.environ['CURRENT_VERSION_ID']: a unique version identifier composed of {version name}.{deployment id}, which is equivalent to os.environ['GAE_VERSION'] + '.' + os.environ['GAE_DEPLOYMENT_ID']
It appears that the so-called "deployment id" can be right-shifted 28 bits to get a timestamp in epoch seconds (as other answers already described).
For example: I deployed version "101" of my app at 2021-03-04T00:17:12Z and I'm seeing the following values:
os.environ['GAE_VERSION']: '101'
os.environ['CURRENT_VERSION_ID']: '101.433474146608888597'
os.environ['GAE_DEPLOYMENT_ID']: '433474146608888597'
You can use the following code to get the version name and timestamp from os.environ['CURRENT_VERSION_ID']:
>>> import os
>>> import datetime
>>> version_id = os.environ['CURRENT_VERSION_ID'] # example: '101.433474146608888597'
>>> name, ts = version_id.split('.')
>>> dt = datetime.datetime.utcfromtimestamp(int(ts) >> 28))
>>> dt.isoformat()
'2021-03-04T00:17:12'
Disclaimer: Most of this functionality is undocumented and the deployment ID format may be subject to change.

Resources