Git Product home page Git Product logo

reportforce's People

Contributors

phelipetls avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

reportforce's Issues

Reports failing with more than two runs

I have a report that returns 8007 records.

As the package stands, it will add one filter for the id_column. There are two issues with this.

First, it seems that Salesforce understands filters better when the values are quoted.

Second, there is a limit in the length of each filter value. Salesforce throws a BAD_REQUEST error if you have a filter that's too long.

One more constraint: "A report can't have more than 20 filters".

I'm not entirely sure how to accommodate the two constraints and still return all rows of an arbitrarily large report, but I do have a patch that at least gets you to 8007.

Haven't tested it, but quotation marks will need to be escaped in that map lambda, and many value types should not be quoted. I was only testing with Id/Lookup fields

diff --git a/reportforce/helpers/generators.py b/reportforce/helpers/generators.py
index ff5bb22..566102f 100644
+++ a/reportforce/helpers/generators.py
--- b/reportforce/helpers/generators.py
@@ -31,13 +31,11 @@ def report_generator(get_report):
         df = pd.DataFrame(report_cells, index=indices, columns=columns)
         yield df
 
-        if id_column:
-            already_seen = ",".join(df[id_column].values)
-            set_filters([(id_column, "!=", already_seen)], metadata)
-
-            increment_logical_filter(metadata)
+        if id_column and len(df[id_column]):
+            inc = 2000
+            for ix in range(0, len(df[id_column]), inc):
+                already_seen = ",".join(map(lambda val: '"%s"' % val,
+                                            df[id_column][(ix*inc):inc+(ix*inc)]))
+                set_filters([(id_column, "!=", already_seen)], metadata)
+                increment_logical_filter(metadata)
 
             while not report["allData"]:
                 # getting what is needed to build the dataframe
@@ -49,10 +47,8 @@ def report_generator(get_report):
                 yield df
 
                 # filtering out already seen values for the next report
-                already_seen += ",".join(df[id_column].values)
-                update_filter(-1, "value", already_seen, metadata)
+                already_seen = ",".join(map(lambda val: '"%s"' % val,
+                                            df[id_column][(ix*inc):inc+(ix*inc)]))
+                set_filters([(id_column, "!=", already_seen)], metadata)
+                increment_logical_filter(metadata)
 
     @functools.wraps(get_report)
     def concat(*args, **kwargs):

XML escape in authentication

HI! Thanks for making such a useful package!

I found a few issues which I'll post as Issues here. Let me know if you're not up to maintaining this.

Username, Password and Security Token are not escaped in the SOAP auth, so if a password matches /[<>&]/g, the auth will fail.

There's an easy fix, but I'm relatively novice at python and don't know know how to test it well.

The fix is this:

diff --git a/reportforce/helpers/xml.py b/reportforce/helpers/xml.py
index b07e140..c305057 100644
--- a/reportforce/helpers/xml.py
+++ b/reportforce/helpers/xml.py
@@ -1,11 +1,15 @@
 import urllib
 import xml.etree.ElementTree as ET
+import xml.sax.saxutils
 
 namespace = {
     "soapenv": "http://schemas.xmlsoap.org/soap/envelope/",
     "urn": "urn:partner.soap.sforce.com",
 }
 
+def escape(s):
+    """escape a value for XML"""
+    return saxutils.escape(s)
 
 def read_successful_response(response):
     """Parse XML returned by SOAP API response in case of a successful login.
diff --git a/reportforce/login.py b/reportforce/login.py
index 7c47e4f..e4db73c 100644
--- a/reportforce/login.py
+++ b/reportforce/login.py
@@ -1,7 +1,7 @@
 import getpass
 import requests
 
-from .helpers.xml import read_failed_response, read_successful_response
+from .helpers.xml import read_failed_response, read_successful_response, escape
 
 DEFAULT_VERSION = "47.0"
 
@@ -111,9 +111,9 @@ def soap_login(username, password, security_token, version="47.0", domain="login
             </n1:login>
         </env:Body>
     </env:Envelope>""".format(
-        username=username,
-        password=password if password else getpass.getpass(),
-        token=security_token if security_token else getpass.getpass("Security Token: "),
+        username=escape(username),
+        password=escape(password) if password else escape(getpass.getpass()),
+        token=escape(security_token) if security_token else escape(getpass.getpass("Security Token: ")),
     )
 
     response = requests.post(soap_url, headers=soap_headers, data=soap_body)

setup.py should declare dependencies

pandas and requests are spec'ed out dependencies in requirements.txt, but unless they're declared in setup.py, pip won't install them. They should probably also come with a version.

is there any option for a conda installation?

Hi there, I like the idea for the package and want to try it out. My team uses the anaconda environment to keep us uniform. Pip install may break things for us. Is there a conda install option?

Cannot login to test domain

Although soap_login method allows setting a domain, __init__ doesn't allow you to pass in a non-production domain.

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.