To solve the given optimization problem, we first need to convert the natural language description into a symbolic representation. Let's denote the number of Package 1 sold as \(x_1\) and the number of Package 2 sold as \(x_2\).

The objective is to maximize profit. Given that the profit per package 1 is $50 and the profit per package 2 is $70, the objective function can be represented algebraically as:
\[ \text{Maximize: } 50x_1 + 70x_2 \]

The constraints are based on the availability of blue and red fabric. The factory has 10000 meters of blue fabric and 12000 meters of red fabric. Package 1 contains 20 meters of blue fabric and 30 meters of red fabric, while Package 2 contains 40 meters of blue fabric and 40 meters of red fabric. Therefore, the constraints can be represented as:
- For blue fabric: \(20x_1 + 40x_2 \leq 10000\)
- For red fabric: \(30x_1 + 40x_2 \leq 12000\)
Additionally, \(x_1\) and \(x_2\) must be non-negative since they represent the number of packages sold.

Thus, the symbolic representation of the problem is:
```json
{
    'sym_variables': [('x1', 'Number of Package 1 sold'), ('x2', 'Number of Package 2 sold')],
    'objective_function': '50*x1 + 70*x2',
    'constraints': [
        '20*x1 + 40*x2 <= 10000',
        '30*x1 + 40*x2 <= 12000',
        'x1 >= 0',
        'x2 >= 0'
    ]
}
```

Now, let's write the Gurobi code to solve this linear programming problem:
```python
from gurobipy import *

# Create a new model
m = Model("Fabric_Sales")

# Define variables
x1 = m.addVar(name="Package_1", vtype=GRB.CONTINUOUS, lb=0)
x2 = m.addVar(name="Package_2", vtype=GRB.CONTINUOUS, lb=0)

# Set the objective function
m.setObjective(50*x1 + 70*x2, GRB.MAXIMIZE)

# Add constraints
m.addConstr(20*x1 + 40*x2 <= 10000, name="Blue_Fabric_Constraint")
m.addConstr(30*x1 + 40*x2 <= 12000, name="Red_Fabric_Constraint")

# Optimize model
m.optimize()

# Print solution
if m.status == GRB.OPTIMAL:
    print("Optimal Solution:")
    print(f"Package 1: {x1.x}")
    print(f"Package 2: {x2.x}")
    print(f"Maximum Profit: {m.objVal}")
else:
    print("No optimal solution found")
```